diff --git a/Inc/targets.h b/Inc/targets.h index baa84774..01756367 100644 --- a/Inc/targets.h +++ b/Inc/targets.h @@ -91,9 +91,13 @@ #define DEAD_TIME 45 #define HARDWARE_GROUP_L4_B #define TARGET_VOLTAGE_DIVIDER 94 -#define MILLIVOLT_PER_AMP 100 +#define MILLIVOLT_PER_AMP 30 +#define CURRENT_OFFSET 110 #define USE_SERIAL_TELEMETRY #define EEPROM_START_ADD (uint32_t)0x0800F800 +#define USE_LED_STRIP +#define WS2812_PORT GPIOB +#define WS2812_PIN LL_GPIO_PIN_3 #endif #ifdef VIMDRONES_L431_CAN @@ -106,6 +110,9 @@ #define MILLIVOLT_PER_AMP 30 #define CURRENT_OFFSET 110 #define USE_SERIAL_TELEMETRY +#define USE_LED_STRIP +#define WS2812_PORT GPIOB +#define WS2812_PIN LL_GPIO_PIN_3 #endif #ifdef VIMDRONES_NANO_L431 @@ -3408,8 +3415,6 @@ #define PHASE_B_COMP LL_COMP_INPUT_MINUS_IO5 // pa5 #define PHASE_C_COMP LL_COMP_INPUT_MINUS_IO4 // pa4 #define COMMON_COMP LL_COMP_INPUT_PLUS_IO1 -//#define USE_LED_STRIP -//#define WS2812_PIN LL_GPIO_PIN_3 #define CURRENT_ADC_CHANNEL LL_ADC_CHANNEL_8 #define VOLTAGE_ADC_CHANNEL LL_ADC_CHANNEL_11 diff --git a/Mcu/l431/Inc/WS2812.h b/Mcu/l431/Inc/WS2812.h new file mode 100644 index 00000000..83adcc4c --- /dev/null +++ b/Mcu/l431/Inc/WS2812.h @@ -0,0 +1,10 @@ +#ifndef INC_WS2812_H_ +#define INC_WS2812_H_ + +#include "main.h" +#include + +void WS2812_Init(void); +void send_LED_RGB(uint8_t red, uint8_t green, uint8_t blue); + +#endif /* INC_WS2812_H_ */ \ No newline at end of file diff --git a/Mcu/l431/Src/WS2812.c b/Mcu/l431/Src/WS2812.c new file mode 100644 index 00000000..be8eeaef --- /dev/null +++ b/Mcu/l431/Src/WS2812.c @@ -0,0 +1,70 @@ +#include "WS2812.h" + +#include "targets.h" + +#ifdef USE_LED_STRIP + +#ifndef WS2812_PORT + #error "WS2812_PORT is not defined" +#endif + +#ifndef WS2812_PIN + #error "WS2812_PIN is not defined" +#endif + +static void enableDWT_CycleCounter(void) +{ + // Enable TRCENA in the DEMCR (Debug Exception and Monitor Control Register) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + // Enable the cycle counter + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + // Reset the cycle counter + DWT->CYCCNT = 0; +} + +static void disableDWT_CycleCounter(void) +{ + // Disable the cycle counter + DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; + // Disable TRCENA in the DEMCR + CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; +} + +static void waitClockCycles(uint16_t cycles) +{ + DWT->CYCCNT = 0; // Reset the cycle counter + while (DWT->CYCCNT < cycles) { + // Wait until the specified number of cycles has passed + } +} + +static void sendBit(uint8_t inbit) +{ + WS2812_PORT->BSRR = WS2812_PIN; + waitClockCycles(CPU_FREQUENCY_MHZ >> (2 - inbit)); + WS2812_PORT->BRR = WS2812_PIN; + waitClockCycles(CPU_FREQUENCY_MHZ >> (1 + inbit)); +} + +void send_LED_RGB(uint8_t red, uint8_t green, uint8_t blue) +{ + __disable_irq(); + enableDWT_CycleCounter(); + uint32_t twenty_four_bit_color_number = green << 16 | red << 8 | blue; + for (int i = 0; i < 24; i++) { + sendBit((twenty_four_bit_color_number >> (23 - i)) & 1); + } + WS2812_PORT->BSRR = (1 << (WS2812_PIN + 16)); // Set pin low by writing to BSRR high half + disableDWT_CycleCounter(); + __enable_irq(); +} + +void WS2812_Init(void) +{ + LL_GPIO_SetPinMode(WS2812_PORT, WS2812_PIN, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinSpeed(WS2812_PORT, WS2812_PIN, LL_GPIO_SPEED_FREQ_HIGH); + LL_GPIO_SetPinOutputType(WS2812_PORT, WS2812_PIN, LL_GPIO_OUTPUT_PUSHPULL); + LL_GPIO_SetPinPull(WS2812_PORT, WS2812_PIN, LL_GPIO_PULL_NO); +} + +#endif \ No newline at end of file diff --git a/Mcu/l431/Src/peripherals.c b/Mcu/l431/Src/peripherals.c index 7c096ace..eb9f8852 100644 --- a/Mcu/l431/Src/peripherals.c +++ b/Mcu/l431/Src/peripherals.c @@ -12,6 +12,9 @@ #include "ADC.h" #include "serial_telemetry.h" #include "targets.h" +#ifdef USE_LED_STRIP +#include "WS2812.h" +#endif extern char bemf_timeout; @@ -679,6 +682,7 @@ void enableCorePeripherals() #endif #ifdef USE_LED_STRIP + WS2812_Init(); send_LED_RGB(255, 0, 0); #endif