diff --git a/platform/plat_compat.h b/platform/plat_compat.h index 551e100..0b46caa 100644 --- a/platform/plat_compat.h +++ b/platform/plat_compat.h @@ -55,7 +55,7 @@ // platform name for the version string #define GEX_PLATFORM "STM32F103-Bluepill" - #define PLAT_AHB_CLOCK 72e6 + #define PLAT_AHB_MHZ 72 // feature flags #define PLAT_FLASHBANKS 1 @@ -106,7 +106,7 @@ // platform name for the version string #define GEX_PLATFORM "STM32F072-Discovery" - #define PLAT_AHB_CLOCK 48e6 + #define PLAT_AHB_MHZ 48 #include #include @@ -153,7 +153,7 @@ // platform name for the version string #define GEX_PLATFORM "STM32F303-Discovery" - #define PLAT_AHB_CLOCK 72e6 + #define PLAT_AHB_MHZ 72 #include #include @@ -203,7 +203,7 @@ // platform name for the version string #define GEX_PLATFORM "STM32F407-Discovery" - #define PLAT_AHB_CLOCK 168e6 + #define PLAT_AHB_MHZ 168 #define PLAT_USB_PHYCLOCK 1 #define PLAT_USB_OTGFS 1 diff --git a/units/neopixel/ws2812.c b/units/neopixel/ws2812.c index 9ecea62..00981ba 100644 --- a/units/neopixel/ws2812.c +++ b/units/neopixel/ws2812.c @@ -1,10 +1,12 @@ #include "platform.h" #include "ws2812.h" -#define PLAT_NEOPIXEL_SHORT (uint32_t)(800e-9*PLAT_AHB_CLOCK) -#define PLAT_NEOPIXEL_LONG (uint32_t)(400e-9*PLAT_AHB_CLOCK) +#define FREQ_STEP (PLAT_AHB_MHZ/20.0f) +#define NPX_DELAY_SHORT (uint32_t)(FREQ_STEP*1.5f) +#define NPX_DELAY_LONG (uint32_t)(FREQ_STEP*3.5f) +#define NPX_DELAY_SHOW (uint32_t)(FREQ_STEP*60) -static //inline __attribute__((always_inline)) +static inline __attribute__((always_inline)) void ws2812_byte(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t b) { for (register volatile uint8_t i = 0; i < 8; i++) { @@ -12,17 +14,13 @@ void ws2812_byte(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t b) // duty cycle determines bit value if (b & 0x80) { - __delay_cycles(PLAT_NEOPIXEL_LONG); - //for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); + __asm_loop(NPX_DELAY_LONG); LL_GPIO_ResetOutputPin(port, ll_pin); - //for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); - __delay_cycles(PLAT_NEOPIXEL_SHORT); + __asm_loop(NPX_DELAY_SHORT); } else { - __delay_cycles(PLAT_NEOPIXEL_SHORT); - //for(uint32_t _i = 0; _i < 5; _i++) asm volatile("nop"); + __asm_loop(NPX_DELAY_SHORT); LL_GPIO_ResetOutputPin(port, ll_pin); - __delay_cycles(PLAT_NEOPIXEL_LONG); - //for(uint32_t _i = 0; _i < 10; _i++) asm volatile("nop"); + __asm_loop(NPX_DELAY_LONG); } b <<= 1; // shift to next bit @@ -43,7 +41,11 @@ void ws2812_load_raw(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t *rgbs, uint32_ ws2812_byte(port, ll_pin, b); } vPortExitCritical(); - // TODO: Delay 50 us + __asm_loop(NPX_DELAY_SHOW); + + LL_GPIO_SetOutputPin(port, ll_pin); + __asm_loop(NPX_DELAY_SHORT); + LL_GPIO_ResetOutputPin(port, ll_pin); } /** Set many RGBs from uint32 stream */ @@ -69,7 +71,11 @@ void ws2812_load_sparse(GPIO_TypeDef *port, uint32_t ll_pin, uint8_t *rgbs, uint ws2812_byte(port, ll_pin, b); } vPortExitCritical(); - // TODO: Delay 50 us + __asm_loop(NPX_DELAY_SHOW); + + LL_GPIO_SetOutputPin(port, ll_pin); + __asm_loop(NPX_DELAY_SHORT); + LL_GPIO_ResetOutputPin(port, ll_pin); } /** Set many RGBs */ @@ -80,5 +86,9 @@ void ws2812_clear(GPIO_TypeDef *port, uint32_t ll_pin, uint32_t count) ws2812_byte(port, ll_pin, 0); } vPortExitCritical(); - // TODO: Delay 50 us + __asm_loop(NPX_DELAY_SHOW); + + LL_GPIO_SetOutputPin(port, ll_pin); + __asm_loop(NPX_DELAY_SHORT); + LL_GPIO_ResetOutputPin(port, ll_pin); } diff --git a/utils/cortex_utils.h b/utils/cortex_utils.h index d7ed7cd..a344e7d 100644 --- a/utils/cortex_utils.h +++ b/utils/cortex_utils.h @@ -23,10 +23,18 @@ static inline bool isDynAlloc(const void *obj) && ((uint32_t)obj < (uint32_t)__SP); } -static inline void __delay_cycles(uint32_t cycles) -{ - uint32_t l = cycles/3; - asm volatile( "0:" "sub %[count], #1;" "bne 0b;" :[count]"+r"(l) ); -} +/** Tight asm loop */ +#define __asm_loop(cycles) \ +do { \ + register uint32_t _count = cycles; \ + asm volatile( \ + ".syntax unified\n" \ + ".thumb\n" \ + "ldr r4, =%0\n" \ + "0:" \ + "subs r4, #1\n" \ + "bne 0b\n" \ + : /* no outputs */ : "g" (cycles) : "r4"); \ +} while(0) #endif //GEX_CORTEX_UTILS_H