From f2198528885f0aa5bbbda3c3ebecc7c530dfa246 Mon Sep 17 00:00:00 2001 From: Sami Korhonen Date: Sat, 6 May 2017 09:39:53 +0300 Subject: [PATCH] HAL ledstrip N channel support --- src/main/drivers/light_ws2811strip_hal.c | 62 +++++++++++++----------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/main/drivers/light_ws2811strip_hal.c b/src/main/drivers/light_ws2811strip_hal.c index 10930142b..2fb155fbd 100644 --- a/src/main/drivers/light_ws2811strip_hal.c +++ b/src/main/drivers/light_ws2811strip_hal.c @@ -36,11 +36,11 @@ bool ws2811Initialised = false; static TIM_HandleTypeDef TimHandle; static uint16_t timerChannel = 0; +static bool timerNChannel = false; void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { - if(htim->Instance == TimHandle.Instance) - { + if(htim->Instance == TimHandle.Instance) { //HAL_TIM_PWM_Stop_DMA(&TimHandle,WS2811_TIMER_CHANNEL); ws2811LedDataTransferInProgress = 0; } @@ -72,18 +72,17 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) BIT_COMPARE_1 = period / 3 * 2; BIT_COMPARE_0 = period / 3; - + TimHandle.Init.Prescaler = prescaler; TimHandle.Init.Period = period; // 800kHz TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; - if(HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) - { + if(HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) { /* Initialization Error */ return; } - static DMA_HandleTypeDef hdma_tim; + static DMA_HandleTypeDef hdma_tim; ws2811IO = IOGetByTag(ioTag); IOInit(ws2811IO, OWNER_LED_STRIP, 0); @@ -92,12 +91,12 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) __DMA1_CLK_ENABLE(); /* Set the parameters to be configured */ - hdma_tim.Init.Channel = timerHardware->dmaChannel; + hdma_tim.Init.Channel = timerHardware->dmaChannel; hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE; hdma_tim.Init.MemInc = DMA_MINC_ENABLE; - hdma_tim.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD ; - hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD ; + hdma_tim.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + hdma_tim.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_tim.Init.Mode = DMA_NORMAL; hdma_tim.Init.Priority = DMA_PRIORITY_HIGH; hdma_tim.Init.FIFOMode = DMA_FIFOMODE_DISABLE; @@ -117,8 +116,7 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, dmaSource); /* Initialize TIMx DMA handle */ - if(HAL_DMA_Init(TimHandle.hdma[dmaSource]) != HAL_OK) - { + if(HAL_DMA_Init(TimHandle.hdma[dmaSource]) != HAL_OK) { /* Initialization Error */ return; } @@ -127,15 +125,21 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM1; + if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) { + timerNChannel = true; + TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_RESET; + TIM_OCInitStructure.OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPOLARITY_HIGH: TIM_OCPOLARITY_LOW; + TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET; + TIM_OCInitStructure.OCNPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPOLARITY_HIGH : TIM_OCNPOLARITY_LOW; + } else { + TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_RESET; + TIM_OCInitStructure.OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPOLARITY_LOW : TIM_OCPOLARITY_HIGH; + TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET; + TIM_OCInitStructure.OCNPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPOLARITY_LOW : TIM_OCNPOLARITY_HIGH; + } TIM_OCInitStructure.Pulse = 0; - TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH; - TIM_OCInitStructure.OCNPolarity = TIM_OCPOLARITY_HIGH; - TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_RESET; - TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET; TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE; - - if(HAL_TIM_PWM_ConfigChannel(&TimHandle, &TIM_OCInitStructure, timerChannel) != HAL_OK) - { + if(HAL_TIM_PWM_ConfigChannel(&TimHandle, &TIM_OCInitStructure, timerChannel) != HAL_OK) { /* Configuration Error */ return; } @@ -143,21 +147,25 @@ void ws2811LedStripHardwareInit(ioTag_t ioTag) ws2811Initialised = true; } - void ws2811LedStripDMAEnable(void) { - if (!ws2811Initialised) - { + if (!ws2811Initialised) { ws2811LedDataTransferInProgress = 0; return; } - if (HAL_TIM_PWM_Start_DMA(&TimHandle, timerChannel, ledStripDMABuffer, WS2811_DMA_BUFFER_SIZE) != HAL_OK) - { - /* Starting PWM generation Error */ - ws2811LedDataTransferInProgress = 0; - return; + if(timerNChannel) { + if(HAL_TIMEx_PWMN_Start_DMA(&TimHandle, timerChannel, ledStripDMABuffer, WS2811_DMA_BUFFER_SIZE) != HAL_OK) { + /* Starting PWM generation Error */ + ws2811LedDataTransferInProgress = 0; + return; + } + } else { + if (HAL_TIM_PWM_Start_DMA(&TimHandle, timerChannel, ledStripDMABuffer, WS2811_DMA_BUFFER_SIZE) != HAL_OK) { + /* Starting PWM generation Error */ + ws2811LedDataTransferInProgress = 0; + return; + } } - } #endif