From 08308f8c901caa27aef35573f4b6ea8fac3f1344 Mon Sep 17 00:00:00 2001 From: imi415 Date: Tue, 30 Nov 2021 19:27:29 +0800 Subject: [PATCH] Added WS2812 demo. --- Core/Inc/stm32h7xx_it.h | 1 + Core/Src/main.c | 57 ++++++++++++++++++++++++++++++++---- Core/Src/stm32h7xx_hal_msp.c | 2 +- Core/Src/stm32h7xx_it.c | 14 +++++++++ STM32H750VB_Hello.ioc | 45 ++++++++++++++++++++++++---- 5 files changed, 107 insertions(+), 12 deletions(-) diff --git a/Core/Inc/stm32h7xx_it.h b/Core/Inc/stm32h7xx_it.h index 2c8cd99..e3928ad 100644 --- a/Core/Inc/stm32h7xx_it.h +++ b/Core/Inc/stm32h7xx_it.h @@ -64,6 +64,7 @@ void I2C1_EV_IRQHandler(void); void I2C1_ER_IRQHandler(void); void TIM7_IRQHandler(void); void FPU_IRQHandler(void); +void DMAMUX1_OVR_IRQHandler(void); void HSEM1_IRQHandler(void); /* USER CODE BEGIN EFP */ diff --git a/Core/Src/main.c b/Core/Src/main.c index 5b0b6ab..1906307 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -381,7 +381,7 @@ static void MX_TIM3_Init(void) Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; - sConfigOC.Pulse = 2; + sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) @@ -408,6 +408,9 @@ static void MX_DMA_Init(void) /* DMA1_Stream0_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); + /* DMAMUX1_OVR_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMAMUX1_OVR_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(DMAMUX1_OVR_IRQn); } @@ -515,6 +518,35 @@ static h3lis331dl_t accel = { static h3lis331dl_result_t accel_result; +#define WS2812_COUNT 8 +#define WS2812_TIM_T1H_CMP 7 +#define WS2812_TIM_T0H_CMP 2 + +static uint16_t s_ws2812_dma_buffer[24 * WS2812_COUNT + 1]; +static osSemaphoreId_t ws2812_dma_done_semphr; + +static void ws2812_dma_update(uint16_t *buf) { + SCB_CleanDCache_by_Addr((uint32_t *)buf, 24 * WS2812_COUNT + 1); + HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *)buf, 24 * WS2812_COUNT + 1); + osSemaphoreAcquire(ws2812_dma_done_semphr, osWaitForever); + HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_1); +} + +static void ws2812_write_color(uint32_t color, uint16_t *buf, uint8_t num_led) { + uint32_t byte_offset = num_led * 24; + for(uint8_t i = 0; i < 24; i++) { + if(color & (0x01 << i)) buf[byte_offset + (23 - i)] = WS2812_TIM_T1H_CMP; + else buf[byte_offset + (23 - i)] = WS2812_TIM_T0H_CMP; + } +} + +void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { + if(htim->Instance == TIM3) { + osSemaphoreRelease(ws2812_dma_done_semphr); + } +} + + /* USER CODE END 4 */ /* USER CODE BEGIN Header_StartDefaultTask */ @@ -529,15 +561,28 @@ void StartDefaultTask(void *argument) /* USER CODE BEGIN 5 */ /* Infinite loop */ - uint16_t dma_buffer[16]; - for(uint8_t i = 0; i < 16; i++) { - dma_buffer[i] = 0x02; + ws2812_dma_done_semphr = osSemaphoreNew(1U, 0U, NULL); + if(ws2812_dma_done_semphr == NULL) { + osThreadSuspend(defaultTaskHandle); } - HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *)dma_buffer, 16); + s_ws2812_dma_buffer[24 * WS2812_COUNT + 1] = 0U; + + uint32_t color_buf[8] = {0x00}; for(;;) { - osDelay(1000); + + for(uint8_t i = 0; i < 7; i++) { + color_buf[7 - i] = color_buf[6 - i]; + } + + color_buf[0] = osKernelGetTickCount(); + + for(uint8_t i = 0; i < 8; i++) { + ws2812_write_color(color_buf[i], s_ws2812_dma_buffer, i); + } + ws2812_dma_update(s_ws2812_dma_buffer); + osDelay(50); } h3lis_int1_semphr = osSemaphoreNew(1U, 0U, NULL); diff --git a/Core/Src/stm32h7xx_hal_msp.c b/Core/Src/stm32h7xx_hal_msp.c index 573e514..ebe3876 100644 --- a/Core/Src/stm32h7xx_hal_msp.c +++ b/Core/Src/stm32h7xx_hal_msp.c @@ -262,7 +262,7 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) hdma_tim3_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_tim3_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_tim3_ch1.Init.Mode = DMA_NORMAL; - hdma_tim3_ch1.Init.Priority = DMA_PRIORITY_LOW; + hdma_tim3_ch1.Init.Priority = DMA_PRIORITY_HIGH; hdma_tim3_ch1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_tim3_ch1) != HAL_OK) { diff --git a/Core/Src/stm32h7xx_it.c b/Core/Src/stm32h7xx_it.c index 445df2a..ec2b663 100644 --- a/Core/Src/stm32h7xx_it.c +++ b/Core/Src/stm32h7xx_it.c @@ -316,6 +316,20 @@ void FPU_IRQHandler(void) /* USER CODE END FPU_IRQn 1 */ } +/** + * @brief This function handles DMAMUX1 overrun interrupt. + */ +void DMAMUX1_OVR_IRQHandler(void) +{ + /* USER CODE BEGIN DMAMUX1_OVR_IRQn 0 */ + + /* USER CODE END DMAMUX1_OVR_IRQn 0 */ + + /* USER CODE BEGIN DMAMUX1_OVR_IRQn 1 */ + + /* USER CODE END DMAMUX1_OVR_IRQn 1 */ +} + /** * @brief This function handles HSEM1 global interrupt. */ diff --git a/STM32H750VB_Hello.ioc b/STM32H750VB_Hello.ioc index b354471..5673003 100644 --- a/STM32H750VB_Hello.ioc +++ b/STM32H750VB_Hello.ioc @@ -1,4 +1,34 @@ #MicroXplorer Configuration settings - do not modify +CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7.AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings=0x0 +CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings=0x24000000 +CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings=0x30000000 +CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings=0x08000000 +CORTEX_M7.CPU_DCache=Disabled +CORTEX_M7.CPU_ICache=Disabled +CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7.DisableExec-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE +CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_ENABLE +CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_ENABLE +CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_ENABLE +CORTEX_M7.IPParameters=CPU_ICache,CPU_DCache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings,Enable-Cortex_Memory_Protection_Unit_Region1_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings,Size-Cortex_Memory_Protection_Unit_Region1_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region1_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings,Enable-Cortex_Memory_Protection_Unit_Region2_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings,Size-Cortex_Memory_Protection_Unit_Region2_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region2_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region2_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings,Enable-Cortex_Memory_Protection_Unit_Region3_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings,Size-Cortex_Memory_Protection_Unit_Region3_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region3_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region3_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region3_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings +CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_BUFFERABLE +CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_ACCESS_BUFFERABLE +CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_CACHEABLE +CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_NOT_CACHEABLE +CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_ACCESS_CACHEABLE +CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_SHAREABLE +CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_SHAREABLE +CORTEX_M7.IsShareable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_ACCESS_SHAREABLE +CORTEX_M7.MPU_Control=__NULL +CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_4GB +CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_SIZE_512KB +CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_SIZE_512KB +CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_SIZE_128KB Dma.Request0=TIM3_CH1 Dma.RequestsNb=1 Dma.TIM3_CH1.0.Direction=DMA_MEMORY_TO_PERIPH @@ -11,7 +41,7 @@ Dma.TIM3_CH1.0.Mode=DMA_NORMAL Dma.TIM3_CH1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD Dma.TIM3_CH1.0.PeriphInc=DMA_PINC_DISABLE Dma.TIM3_CH1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING -Dma.TIM3_CH1.0.Priority=DMA_PRIORITY_LOW +Dma.TIM3_CH1.0.Priority=DMA_PRIORITY_HIGH Dma.TIM3_CH1.0.RequestNumber=1 Dma.TIM3_CH1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber Dma.TIM3_CH1.0.SignalID=NONE @@ -72,7 +102,7 @@ NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.EXTI0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.EXTI1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.FLASH_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true -NVIC.FPU_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:false +NVIC.FPU_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:false NVIC.ForceEnableDMAVector=true NVIC.HSEM1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false @@ -83,7 +113,7 @@ NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.PVD_AVD_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 -NVIC.RCC_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:false +NVIC.RCC_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:false NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false NVIC.SavedPendsvIrqHandlerGenerated=true NVIC.SavedSvcallIrqHandlerGenerated=true @@ -103,6 +133,8 @@ PA13\ (JTMS/SWDIO).Mode=Serial_Wire PA13\ (JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO PA14\ (JTCK/SWCLK).Mode=Serial_Wire PA14\ (JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK +PA6.GPIOParameters=GPIO_Speed +PA6.GPIO_Speed=GPIO_SPEED_FREQ_LOW PA6.Signal=S_TIM3_CH1 PB8.Locked=true PB8.Mode=I2C @@ -245,10 +277,13 @@ SH.GPXTI1.ConfNb=1 SH.S_TIM3_CH1.0=TIM3_CH1,PWM Generation1 CH1 SH.S_TIM3_CH1.ConfNb=1 TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 -TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Period,Pulse-PWM Generation1 CH1 +TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Period,Pulse-PWM Generation1 CH1,OC1Preload_PWM,OCFastMode_PWM-PWM Generation1 CH1,OCMode_PWM-PWM Generation1 CH1 +TIM3.OC1Preload_PWM=ENABLE +TIM3.OCFastMode_PWM-PWM\ Generation1\ CH1=TIM_OCFAST_DISABLE +TIM3.OCMode_PWM-PWM\ Generation1\ CH1=TIM_OCMODE_PWM1 TIM3.Period=10 - 1 TIM3.Prescaler=15 - 1 -TIM3.Pulse-PWM\ Generation1\ CH1=2 +TIM3.Pulse-PWM\ Generation1\ CH1=0 VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2 VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled