diff options
| author | Hierophect <hierophect@gmail.com> | 2019-11-15 12:28:16 -0500 |
|---|---|---|
| committer | Hierophect <hierophect@gmail.com> | 2019-11-15 12:28:16 -0500 |
| commit | 6cce2d6d145896e02e78fffa26edb60f7d0d6a69 (patch) | |
| tree | 9e2d889304000abc528973251d51e8c80dce5e31 | |
| parent | 6e96b1945e611ae1fc746ac35e6adbd4545620a1 (diff) | |
Implement Neopixel write, add defaults to f405
| -rw-r--r-- | ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h | 2 | ||||
| -rw-r--r-- | ports/stm32f4/boards/feather_stm32f405_express/pins.c | 1 | ||||
| -rw-r--r-- | ports/stm32f4/common-hal/microcontroller/Pin.h | 4 | ||||
| -rw-r--r-- | ports/stm32f4/common-hal/neopixel_write/__init__.c | 89 | ||||
| -rw-r--r-- | ports/stm32f4/mpconfigport.mk | 1 |
5 files changed, 97 insertions, 0 deletions
diff --git a/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h index 67ddc885a..e2295dc5e 100644 --- a/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h +++ b/ports/stm32f4/boards/feather_stm32f405_express/mpconfigboard.h @@ -35,6 +35,8 @@ #define AUTORESET_DELAY_MS 500 #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000) +#define MICROPY_HW_NEOPIXEL &pin_PC00 + // On-board flash #define SPI_FLASH_MOSI_PIN &pin_PB05 #define SPI_FLASH_MISO_PIN &pin_PB04 diff --git a/ports/stm32f4/boards/feather_stm32f405_express/pins.c b/ports/stm32f4/boards/feather_stm32f405_express/pins.c index 4aa1f362a..180fdd093 100644 --- a/ports/stm32f4/boards/feather_stm32f405_express/pins.c +++ b/ports/stm32f4/boards/feather_stm32f405_express/pins.c @@ -26,6 +26,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB10) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PC00) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/stm32f4/common-hal/microcontroller/Pin.h b/ports/stm32f4/common-hal/microcontroller/Pin.h index 0c3fb375f..c42b0801f 100644 --- a/ports/stm32f4/common-hal/microcontroller/Pin.h +++ b/ports/stm32f4/common-hal/microcontroller/Pin.h @@ -31,6 +31,10 @@ #include "peripherals/stm32f4/pins.h" +#ifdef MICROPY_HW_NEOPIXEL +extern bool neopixel_in_use; +#endif + void reset_all_pins(void); // reset_pin_number takes the pin number instead of the pointer so that objects don't // need to store a full pointer. diff --git a/ports/stm32f4/common-hal/neopixel_write/__init__.c b/ports/stm32f4/common-hal/neopixel_write/__init__.c new file mode 100644 index 000000000..c5d810ae9 --- /dev/null +++ b/ports/stm32f4/common-hal/neopixel_write/__init__.c @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#include "py/mphal.h" +#include "shared-bindings/neopixel_write/__init__.h" + +#include "tick.h" +#include "common-hal/microcontroller/Pin.h" +#include "stm32f4xx_hal.h" +#include "stm32f4xx_ll_gpio.h" + +uint64_t next_start_tick_ms = 0; +uint32_t next_start_tick_us = 1000; + +void common_hal_neopixel_write (const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, + uint32_t numBytes) { + uint8_t *p = pixels, *end = p + numBytes, pix = *p++, mask = 0x80; + uint32_t start = 0; + uint32_t cyc = 0; + + //assumes 800_000Hz frequency + uint32_t sys_freq = HAL_RCC_GetSysClockFreq(); + uint32_t interval = sys_freq/800000; // cycles per interval (1.25 us). 210@168MHz + uint32_t t0 = interval - (sys_freq/2500000); // 0.4 us + uint32_t t1 = interval - (sys_freq/1250000); // 0.8 us + + // This must be called while interrupts are on in case we're waiting for a + // future ms tick. + wait_until(next_start_tick_ms, next_start_tick_us); + + __disable_irq(); + // Enable DWT in debug core. Useable when interrupts disabled, as opposed to Systick->VAL + //ITM->LAR = 0xC5ACCE55; //is this required? + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + DWT->CYCCNT = 0; + + GPIO_TypeDef * p_port = pin_port(digitalinout->pin->port); + uint32_t p_mask = pin_mask(digitalinout->pin->number); + + for(;;) { + LL_GPIO_SetOutputPin(p_port, p_mask); + cyc = (pix & mask) ? t1 : t0; + start = DWT->CYCCNT; + while(DWT->CYCCNT - start < cyc); + LL_GPIO_ResetOutputPin(p_port, p_mask); + if(!(mask >>= 1)) { //max has shifted all the way + if(p >= end) break; + pix = *p++; + mask = 0x80; + } + while(DWT->CYCCNT - start < interval); //wait for interval to finish + } + + // Enable interrupts again + __enable_irq(); + + // Update the next start. + current_tick(&next_start_tick_ms, &next_start_tick_us); + if (next_start_tick_us < 100) { + next_start_tick_ms += 1; + next_start_tick_us = 100 - next_start_tick_us; + } else { + next_start_tick_us -= 100; + } +} diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk index bce68f99f..928d53e67 100644 --- a/ports/stm32f4/mpconfigport.mk +++ b/ports/stm32f4/mpconfigport.mk @@ -26,6 +26,7 @@ CIRCUITPY_STORAGE = 1 CIRCUITPY_RANDOM = 1 CIRCUITPY_USB_HID = 1 CIRCUITPY_USB_MIDI = 1 +CIRCUITPY_NEOPIXEL_WRITE = 1 #ifeq ($(MCU_SUB_VARIANT), stm32f412zx) #endif |
