steering-wheel/Core/Src/leds.c

81 lines
2.0 KiB
C

#include "leds.h"
#include "main.h"
#include "stm32h7xx_hal_dma.h"
#include "stm32h7xx_hal_gpio.h"
#include "stm32h7xx_hal_spi.h"
#include "stm32h7xx_hal_tim.h"
SPI_HandleTypeDef *hspi;
TIM_HandleTypeDef *htim;
extern uint16_t led_buf[256][3];
static size_t led_buf_idx = 0;
void led_init(SPI_HandleTypeDef *spi, TIM_HandleTypeDef *pwmtim) {
hspi = spi;
htim = pwmtim;
HAL_GPIO_WritePin(LED_LE_GPIO_Port, LED_LE_Pin, GPIO_PIN_RESET);
memset(led_buf, 0, sizeof(led_buf));
if (HAL_SPI_Transmit_DMA(hspi, (const uint8_t *)&led_buf[led_buf_idx], 3) !=
HAL_OK) {
Error_Handler();
}
__HAL_TIM_SET_COMPARE(htim, PWM_CHANNEL_R, 0x3FFF);
__HAL_TIM_SET_COMPARE(htim, PWM_CHANNEL_G, 0x13FF);
__HAL_TIM_SET_COMPARE(htim, PWM_CHANNEL_B, 0x1FFF);
if (HAL_TIM_PWM_Start(htim, PWM_CHANNEL_R) != HAL_OK) {
Error_Handler();
}
if (HAL_TIM_PWM_Start(htim, PWM_CHANNEL_G) != HAL_OK) {
Error_Handler();
}
if (HAL_TIM_PWM_Start(htim, PWM_CHANNEL_B) != HAL_OK) {
Error_Handler();
}
}
void led_set(size_t idx, uint8_t r, uint8_t g, uint8_t b) {
uint16_t led_set = (1 << idx);
uint16_t led_unset = ~led_set;
uint8_t rgb[] = {b, g, r};
for (size_t time = 0; time < 256; time++) {
// TODO: Shouldn't time only go up to 254?
for (size_t i = 0; i < 3; i++) {
if (time < rgb[i]) {
led_buf[time][i] |= led_set;
} else {
led_buf[time][i] &= led_unset;
}
}
}
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *handle) {
if (handle != hspi) {
return;
}
led_buf_idx = (led_buf_idx + 1) % 256;
HAL_GPIO_WritePin(LED_LE_GPIO_Port, LED_LE_Pin, GPIO_PIN_SET);
for (size_t i = 0; i < 10; i++) {
asm("nop" ::: "memory");
}
HAL_GPIO_WritePin(LED_LE_GPIO_Port, LED_LE_Pin, GPIO_PIN_RESET);
for (size_t i = 0; i < 10; i++) {
asm("nop" ::: "memory");
}
HAL_SPI_Transmit_DMA(hspi, (const uint8_t *)&led_buf[led_buf_idx], 3);
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *handle) {
if (handle != hspi) {
return;
}
volatile uint32_t err = HAL_DMA_GetError(hspi->hdmatx);
err = err;
}