SPIPWM the LEDs
This commit is contained in:
		
							
								
								
									
										80
									
								
								Core/Src/leds.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								Core/Src/leds.c
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user