SPIPWM the LEDs

This commit is contained in:
2023-03-24 21:12:03 +01:00
parent 04b95a19d1
commit 3b2dac7240
13 changed files with 463 additions and 37 deletions

24
Core/Inc/leds.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef INC_LEDS_H
#define INC_LEDS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32h7xx_hal.h"
#define N_LEDS 9
#define PWM_CHANNEL_R TIM_CHANNEL_1
#define PWM_CHANNEL_G TIM_CHANNEL_2
#define PWM_CHANNEL_B TIM_CHANNEL_3
void led_init(SPI_HandleTypeDef *spi, TIM_HandleTypeDef *pwmtim);
void led_set(size_t idx, uint8_t r, uint8_t g, uint8_t b);
#ifdef __cplusplus
}
#endif
#endif // INC_LEDS_H

View File

@ -54,9 +54,11 @@ void UsageFault_Handler(void);
void DebugMon_Handler(void);
void EXTI3_IRQHandler(void);
void EXTI4_IRQHandler(void);
void DMA1_Stream0_IRQHandler(void);
void FDCAN1_IT0_IRQHandler(void);
void FDCAN1_IT1_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void SPI3_IRQHandler(void);
void TIM6_DAC_IRQHandler(void);
void LTDC_IRQHandler(void);
void TIM17_IRQHandler(void);

80
Core/Src/leds.c Normal file
View File

@ -0,0 +1,80 @@
#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;
}

View File

@ -26,6 +26,7 @@
#include "ft_logo_orange_rgb565.h"
#include "ft_logo_rainbow_rgb565.h"
#include "hx8357d.h"
#include "leds.h"
#include "shorttimer.h"
#include <stdint.h>
@ -61,6 +62,7 @@ LTDC_HandleTypeDef hltdc;
OSPI_HandleTypeDef hospi1;
SPI_HandleTypeDef hspi3;
DMA_HandleTypeDef hdma_spi3_tx;
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
@ -75,7 +77,7 @@ volatile int ltdc_cb_triggered;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA2D_Init(void);
static void MX_DMA_Init(void);
static void MX_FDCAN1_Init(void);
static void MX_LTDC_Init(void);
static void MX_JPEG_Init(void);
@ -86,6 +88,7 @@ static void MX_TIM2_Init(void);
static void MX_TIM4_Init(void);
static void MX_CRC_Init(void);
static void MX_TIM17_Init(void);
static void MX_DMA2D_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
@ -123,7 +126,7 @@ int main(void) {
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA2D_Init();
MX_DMA_Init();
MX_FDCAN1_Init();
MX_LTDC_Init();
MX_JPEG_Init();
@ -134,6 +137,7 @@ int main(void) {
MX_TIM4_Init();
MX_CRC_Init();
MX_TIM17_Init();
MX_DMA2D_Init();
/* Call PreOsInit function */
MX_TouchGFX_PreOSInit();
/* USER CODE BEGIN 2 */
@ -141,6 +145,7 @@ int main(void) {
Error_Handler();
}
shorttimer_init(htim_us);
led_init(&hspi3, &htim1);
HX8357D_Init();
@ -480,7 +485,7 @@ static void MX_SPI3_Init(void) {
hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
hspi3.Init.DataSize = SPI_DATASIZE_4BIT;
hspi3.Init.DataSize = SPI_DATASIZE_12BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
@ -715,6 +720,20 @@ static void MX_TIM17_Init(void) {
/* USER CODE END TIM17_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void) {
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
/**
* @brief GPIO Initialization Function
* @param None

View File

@ -23,6 +23,7 @@
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern DMA_HandleTypeDef hdma_spi3_tx;
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
@ -627,7 +628,15 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI3;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
PeriphClkInitStruct.PLL2.PLL2M = 2;
PeriphClkInitStruct.PLL2.PLL2N = 11;
PeriphClkInitStruct.PLL2.PLL2P = 66;
PeriphClkInitStruct.PLL2.PLL2Q = 3;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
@ -648,6 +657,28 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* SPI3 DMA Init */
/* SPI3_TX Init */
hdma_spi3_tx.Instance = DMA1_Stream0;
hdma_spi3_tx.Init.Request = DMA_REQUEST_SPI3_TX;
hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_spi3_tx.Init.Mode = DMA_NORMAL;
hdma_spi3_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi3_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hspi,hdmatx,hdma_spi3_tx);
/* SPI3 interrupt Init */
HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspInit 1 */
/* USER CODE END SPI3_MspInit 1 */
@ -677,6 +708,11 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
*/
HAL_GPIO_DeInit(GPIOC, LED_CP_Pin|LED_D_Pin);
/* SPI3 DMA DeInit */
HAL_DMA_DeInit(hspi->hdmatx);
/* SPI3 interrupt DeInit */
HAL_NVIC_DisableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspDeInit 1 */
/* USER CODE END SPI3_MspDeInit 1 */

View File

@ -57,6 +57,8 @@
/* External variables --------------------------------------------------------*/
extern FDCAN_HandleTypeDef hfdcan1;
extern LTDC_HandleTypeDef hltdc;
extern DMA_HandleTypeDef hdma_spi3_tx;
extern SPI_HandleTypeDef hspi3;
extern TIM_HandleTypeDef htim17;
extern TIM_HandleTypeDef htim6;
@ -190,6 +192,20 @@ void EXTI4_IRQHandler(void)
/* USER CODE END EXTI4_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream0 global interrupt.
*/
void DMA1_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream0_IRQn 0 */
/* USER CODE END DMA1_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi3_tx);
/* USER CODE BEGIN DMA1_Stream0_IRQn 1 */
/* USER CODE END DMA1_Stream0_IRQn 1 */
}
/**
* @brief This function handles FDCAN1 interrupt 0.
*/
@ -233,6 +249,20 @@ void EXTI9_5_IRQHandler(void)
/* USER CODE END EXTI9_5_IRQn 1 */
}
/**
* @brief This function handles SPI3 global interrupt.
*/
void SPI3_IRQHandler(void)
{
/* USER CODE BEGIN SPI3_IRQn 0 */
/* USER CODE END SPI3_IRQn 0 */
HAL_SPI_IRQHandler(&hspi3);
/* USER CODE BEGIN SPI3_IRQn 1 */
/* USER CODE END SPI3_IRQn 1 */
}
/**
* @brief This function handles TIM6 global interrupt, DAC1_CH1 and DAC1_CH2 underrun error interrupts.
*/