Merge pull request #2648 from dhalbert/malloc-nrf-neopixel-write
cached heap buffer for neopixel_write
This commit is contained in:
commit
bd9572c8a4
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include "py/mphal.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "shared-bindings/neopixel_write/__init__.h"
|
||||
#include "nrf_pwm.h"
|
||||
|
||||
|
@ -97,6 +98,13 @@ static NRF_PWM_Type* find_free_pwm (void) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static size_t pixels_pattern_heap_size = 0;
|
||||
// Called during reset_port() to free the pattern buffer
|
||||
void neopixel_write_reset(void) {
|
||||
MP_STATE_VM(pixels_pattern_heap) = NULL;
|
||||
pixels_pattern_heap_size = 0;
|
||||
}
|
||||
|
||||
uint64_t next_start_tick_ms = 0;
|
||||
uint32_t next_start_tick_us = 1000;
|
||||
|
||||
|
@ -119,10 +127,8 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout
|
|||
// We need space for at least 10 pixels for Circuit Playground, but let's choose 24
|
||||
// to handle larger NeoPixel rings without malloc'ing.
|
||||
#define STACK_PIXELS 24
|
||||
|
||||
uint32_t pattern_size = PATTERN_SIZE(numBytes);
|
||||
uint16_t* pixels_pattern = NULL;
|
||||
bool pattern_on_heap = false;
|
||||
|
||||
// Use the stack to store STACK_PIXEL's worth of PWM data. uint32_t to ensure alignment.
|
||||
// It is 3*STACK_PIXELS to handle RGB.
|
||||
|
@ -138,16 +144,34 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout
|
|||
} else {
|
||||
uint8_t sd_en = 0;
|
||||
(void) sd_softdevice_is_enabled(&sd_en);
|
||||
if (sd_en) {
|
||||
// If the soft device is enabled then we must use PWM to
|
||||
// transmit. This takes a bunch of memory to do so raise an
|
||||
// exception if we can't.
|
||||
pixels_pattern = (uint16_t *) m_malloc(pattern_size, false);
|
||||
} else {
|
||||
pixels_pattern = (uint16_t *) m_malloc_maybe(pattern_size, false);
|
||||
}
|
||||
|
||||
pattern_on_heap = true;
|
||||
if (pixels_pattern_heap_size < pattern_size) {
|
||||
// Current heap buffer is too small.
|
||||
if (MP_STATE_VM(pixels_pattern_heap)) {
|
||||
// Old pixels_pattern_heap will be gc'd; don't free it.
|
||||
pixels_pattern = NULL;
|
||||
pixels_pattern_heap_size = 0;
|
||||
}
|
||||
|
||||
// realloc routines fall back to a plain malloc if the incoming ptr is NULL.
|
||||
if (sd_en) {
|
||||
// If the soft device is enabled then we must use PWM to
|
||||
// transmit. This takes a bunch of memory to do so raise an
|
||||
// exception if we can't.
|
||||
MP_STATE_VM(pixels_pattern_heap) =
|
||||
(uint16_t *) m_realloc(MP_STATE_VM(pixels_pattern_heap), pattern_size);
|
||||
} else {
|
||||
// Might return NULL.
|
||||
MP_STATE_VM(pixels_pattern_heap) =
|
||||
// true means move if necessary.
|
||||
(uint16_t *) m_realloc_maybe(MP_STATE_VM(pixels_pattern_heap), pattern_size, true);
|
||||
}
|
||||
if (MP_STATE_VM(pixels_pattern_heap)) {
|
||||
pixels_pattern_heap_size = pattern_size;
|
||||
}
|
||||
}
|
||||
// Might be NULL, which means we failed to allocate.
|
||||
pixels_pattern = MP_STATE_VM(pixels_pattern_heap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +179,7 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout
|
|||
wait_until(next_start_tick_ms, next_start_tick_us);
|
||||
|
||||
// Use the identified device to choose the implementation
|
||||
// If a PWM device is available use DMA
|
||||
// If a PWM device is available and we have a buffer, use DMA.
|
||||
if ( (pixels_pattern != NULL) && (pwm != NULL) ) {
|
||||
uint16_t pos = 0; // bit position
|
||||
|
||||
|
@ -229,10 +253,6 @@ void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout
|
|||
nrf_pwm_disable(pwm);
|
||||
nrf_pwm_pins_set(pwm, (uint32_t[]) {0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL} );
|
||||
|
||||
if (pattern_on_heap) {
|
||||
m_free(pixels_pattern);
|
||||
}
|
||||
|
||||
} // End of DMA implementation
|
||||
// ---------------------------------------------------------------------
|
||||
else {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_NEOPIXEL_WRITE_INIT_H
|
||||
#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_NEOPIXEL_WRITE_INIT_H
|
||||
|
||||
void neopixel_write_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_NEOPIXEL_WRITE_INIT_H
|
|
@ -164,6 +164,7 @@
|
|||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
CIRCUITPY_COMMON_ROOT_POINTERS \
|
||||
uint16_t* pixels_pattern_heap; \
|
||||
ble_drv_evt_handler_entry_t* ble_drv_evt_handler_entries; \
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "common-hal/pulseio/PulseOut.h"
|
||||
#include "common-hal/pulseio/PulseIn.h"
|
||||
#include "common-hal/rtc/RTC.h"
|
||||
#include "common-hal/neopixel_write/__init__.h"
|
||||
#include "tick.h"
|
||||
|
||||
#include "shared-bindings/rtc/__init__.h"
|
||||
|
@ -103,6 +104,7 @@ void reset_port(void) {
|
|||
i2c_reset();
|
||||
spi_reset();
|
||||
uart_reset();
|
||||
neopixel_write_reset();
|
||||
|
||||
#if CIRCUITPY_AUDIOBUSIO
|
||||
i2s_reset();
|
||||
|
|
Loading…
Reference in New Issue