From a56115ad377e35f61326098f766c2a2748fe3279 Mon Sep 17 00:00:00 2001 From: bkleiner Date: Tue, 23 Jul 2024 01:29:55 +0200 Subject: [PATCH] dshot: centralize timer dma request --- src/driver/at32/motor_dshot.c | 39 +++-------------------- src/driver/at32/timer.c | 25 +++++++++++++++ src/driver/motor_dshot.c | 15 ++++++++- src/driver/motor_dshot.h | 2 +- src/driver/stm32/motor_dshot.c | 56 ++++------------------------------ src/driver/stm32/timer.c | 37 ++++++++++++++++++++++ src/driver/timer.h | 1 + 7 files changed, 89 insertions(+), 86 deletions(-) diff --git a/src/driver/at32/motor_dshot.c b/src/driver/at32/motor_dshot.c index 609ba41e4..815ad3539 100644 --- a/src/driver/at32/motor_dshot.c +++ b/src/driver/at32/motor_dshot.c @@ -18,20 +18,7 @@ extern dshot_pin_t dshot_pins[MOTOR_PIN_MAX]; extern motor_direction_t motor_dir; extern uint8_t dshot_gpio_port_count; -dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT] = { - { - .timer_channel = TMR_SELECT_CHANNEL_1, - .dma_device = DMA_DEVICE_TIM1_CH1, - }, - { - .timer_channel = TMR_SELECT_CHANNEL_3, - .dma_device = DMA_DEVICE_TIM1_CH3, - }, - { - .timer_channel = TMR_SELECT_CHANNEL_4, - .dma_device = DMA_DEVICE_TIM1_CH4, - }, -}; +extern dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT]; extern volatile DMA_RAM uint32_t port_dma_buffer[DSHOT_MAX_PORT_COUNT][DSHOT_DMA_BUFFER_SIZE]; @@ -47,8 +34,8 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { tim_oc_init.oc_idle_state = TRUE; tim_oc_init.oc_polarity = TMR_OUTPUT_ACTIVE_LOW; tim_oc_init.oc_output_state = TRUE; - tmr_output_channel_config(TMR1, port->timer_channel, &tim_oc_init); - tmr_output_channel_buffer_enable(TMR1, port->timer_channel, TRUE); + tmr_output_channel_config(TMR1, timer_channel_val(port->timer_channel), &tim_oc_init); + tmr_output_channel_buffer_enable(TMR1, timer_channel_val(port->timer_channel), TRUE); const dma_stream_def_t *dma = &dma_stream_defs[port->dma_device]; @@ -72,22 +59,6 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { interrupt_enable(dma->irq, DMA_PRIORITY); } -static void dshot_enable_dma_request(uint32_t timer_channel, confirm_state new_state) { - switch (timer_channel) { - case TMR_SELECT_CHANNEL_1: - tmr_dma_request_enable(TMR1, TMR_C1_DMA_REQUEST, new_state); - break; - case TMR_SELECT_CHANNEL_3: - tmr_dma_request_enable(TMR1, TMR_C3_DMA_REQUEST, new_state); - break; - case TMR_SELECT_CHANNEL_4: - tmr_dma_request_enable(TMR1, TMR_C4_DMA_REQUEST, new_state); - break; - default: - break; - } -} - void motor_dshot_init() { dshot_gpio_port_count = 0; @@ -128,7 +99,7 @@ void dshot_dma_setup_port(uint32_t index) { dma->channel->dtcnt = DSHOT_DMA_BUFFER_SIZE; dma_channel_enable(dma->channel, TRUE); - dshot_enable_dma_request(port->timer_channel, TRUE); + timer_enable_dma_request(TIMER1, port->timer_channel, true); } void motor_dshot_wait_for_ready() { @@ -142,7 +113,7 @@ void dshot_dma_isr(dma_device_t dev) { dma_channel_enable(dma->channel, FALSE); const dshot_gpio_port_t *port = dshot_gpio_for_device(dev); - dshot_enable_dma_request(port->timer_channel, FALSE); + timer_enable_dma_request(TIMER1, port->timer_channel, false); dshot_dma_phase--; } diff --git a/src/driver/at32/timer.c b/src/driver/at32/timer.c index 14bb24729..fd7ab6004 100644 --- a/src/driver/at32/timer.c +++ b/src/driver/at32/timer.c @@ -108,6 +108,31 @@ uint32_t timer_channel_val(timer_channel_t chan) { } } +void timer_enable_dma_request(timer_index_t tim, timer_channel_t chan, bool state) { + const timer_def_t *def = &timer_defs[tim]; + + switch (chan) { + case TIMER_CH1: + case TIMER_CH1N: + tmr_dma_request_enable(def->instance, TMR_C1_DMA_REQUEST, state); + break; + case TIMER_CH2: + case TIMER_CH2N: + tmr_dma_request_enable(def->instance, TMR_C2_DMA_REQUEST, state); + break; + case TIMER_CH3: + case TIMER_CH3N: + tmr_dma_request_enable(def->instance, TMR_C3_DMA_REQUEST, state); + break; + case TIMER_CH4: + case TIMER_CH4N: + tmr_dma_request_enable(def->instance, TMR_C4_DMA_REQUEST, state); + break; + default: + break; + } +} + static void timer_irq_handler() { extern void soft_serial_timer_irq_handler(); soft_serial_timer_irq_handler(); diff --git a/src/driver/motor_dshot.c b/src/driver/motor_dshot.c index 570cc9ed5..8f1df301f 100644 --- a/src/driver/motor_dshot.c +++ b/src/driver/motor_dshot.c @@ -23,7 +23,20 @@ uint16_t dshot_packet[MOTOR_PIN_MAX]; // 16bits dshot data for 4 motors dshot_pin_t dshot_pins[MOTOR_PIN_MAX]; uint8_t dshot_gpio_port_count = 0; -extern dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT]; +dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT] = { + { + .timer_channel = TIMER_CH1, + .dma_device = DMA_DEVICE_TIM1_CH1, + }, + { + .timer_channel = TIMER_CH3, + .dma_device = DMA_DEVICE_TIM1_CH3, + }, + { + .timer_channel = TIMER_CH4, + .dma_device = DMA_DEVICE_TIM1_CH4, + }, +}; motor_direction_t motor_dir = MOTOR_FORWARD; static bool dir_change_done = true; diff --git a/src/driver/motor_dshot.h b/src/driver/motor_dshot.h index 078d589b4..a034ad621 100644 --- a/src/driver/motor_dshot.h +++ b/src/driver/motor_dshot.h @@ -17,7 +17,7 @@ typedef struct { uint32_t port_low; // motor pins for BSRRL, for setting pins low uint32_t port_high; // motor pins for BSRRH, for setting pins high - uint32_t timer_channel; + timer_channel_t timer_channel; dma_device_t dma_device; } dshot_gpio_port_t; diff --git a/src/driver/stm32/motor_dshot.c b/src/driver/stm32/motor_dshot.c index c3c00f5e3..4c0db36e8 100644 --- a/src/driver/stm32/motor_dshot.c +++ b/src/driver/stm32/motor_dshot.c @@ -18,20 +18,8 @@ extern dshot_pin_t dshot_pins[MOTOR_PIN_MAX]; extern motor_direction_t motor_dir; extern uint8_t dshot_gpio_port_count; -dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT] = { - { - .timer_channel = LL_TIM_CHANNEL_CH1, - .dma_device = DMA_DEVICE_TIM1_CH1, - }, - { - .timer_channel = LL_TIM_CHANNEL_CH3, - .dma_device = DMA_DEVICE_TIM1_CH3, - }, - { - .timer_channel = LL_TIM_CHANNEL_CH4, - .dma_device = DMA_DEVICE_TIM1_CH4, - }, -}; +extern dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT]; + static volatile DMA_RAM uint32_t port_dma_buffer[DSHOT_MAX_PORT_COUNT][DSHOT_DMA_BUFFER_SIZE]; extern void dshot_init_motor_pin(uint32_t index); @@ -45,8 +33,8 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { tim_oc_init.OCState = LL_TIM_OCSTATE_ENABLE; tim_oc_init.OCPolarity = LL_TIM_OCPOLARITY_LOW; tim_oc_init.CompareValue = 10; - LL_TIM_OC_Init(TIM1, port->timer_channel, &tim_oc_init); - LL_TIM_OC_EnablePreload(TIM1, port->timer_channel); + LL_TIM_OC_Init(TIM1, timer_channel_val(port->timer_channel), &tim_oc_init); + LL_TIM_OC_EnablePreload(TIM1, timer_channel_val(port->timer_channel)); const dma_stream_def_t *dma = &dma_stream_defs[port->dma_device]; @@ -82,38 +70,6 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { LL_DMA_EnableIT_TC(dma->port, dma->stream_index); } -static void dshot_enable_dma_request(uint32_t timer_channel) { - switch (timer_channel) { - case LL_TIM_CHANNEL_CH1: - LL_TIM_EnableDMAReq_CC1(TIM1); - break; - case LL_TIM_CHANNEL_CH3: - LL_TIM_EnableDMAReq_CC3(TIM1); - break; - case LL_TIM_CHANNEL_CH4: - LL_TIM_EnableDMAReq_CC4(TIM1); - break; - default: - break; - } -} - -static void dshot_disable_dma_request(uint32_t timer_channel) { - switch (timer_channel) { - case LL_TIM_CHANNEL_CH1: - LL_TIM_DisableDMAReq_CC1(TIM1); - break; - case LL_TIM_CHANNEL_CH3: - LL_TIM_DisableDMAReq_CC3(TIM1); - break; - case LL_TIM_CHANNEL_CH4: - LL_TIM_DisableDMAReq_CC4(TIM1); - break; - default: - break; - } -} - void motor_dshot_init() { dshot_gpio_port_count = 0; @@ -159,7 +115,7 @@ void dshot_dma_setup_port(uint32_t index) { LL_DMA_SetDataLength(dma->port, dma->stream_index, DSHOT_DMA_BUFFER_SIZE); LL_DMA_EnableStream(dma->port, dma->stream_index); - dshot_enable_dma_request(port->timer_channel); + timer_enable_dma_request(TIMER1, port->timer_channel, true); } void motor_dshot_wait_for_ready() { @@ -173,7 +129,7 @@ void dshot_dma_isr(dma_device_t dev) { LL_DMA_DisableStream(dma->port, dma->stream_index); const dshot_gpio_port_t *port = dshot_gpio_for_device(dev); - dshot_disable_dma_request(port->timer_channel); + timer_enable_dma_request(TIMER1, port->timer_channel, false); dshot_dma_phase--; } diff --git a/src/driver/stm32/timer.c b/src/driver/stm32/timer.c index 5827fde3e..55596bbb1 100644 --- a/src/driver/stm32/timer.c +++ b/src/driver/stm32/timer.c @@ -81,6 +81,43 @@ uint32_t timer_channel_val(timer_channel_t chan) { } } +void timer_enable_dma_request(timer_index_t tim, timer_channel_t chan, bool state) { + const timer_def_t *def = &timer_defs[tim]; + + switch (chan) { + case TIMER_CH1: + case TIMER_CH1N: + if (state) + LL_TIM_EnableDMAReq_CC1(def->instance); + else + LL_TIM_DisableDMAReq_CC1(def->instance); + break; + case TIMER_CH2: + case TIMER_CH2N: + if (state) + LL_TIM_EnableDMAReq_CC2(def->instance); + else + LL_TIM_DisableDMAReq_CC2(def->instance); + break; + case TIMER_CH3: + case TIMER_CH3N: + if (state) + LL_TIM_EnableDMAReq_CC3(def->instance); + else + LL_TIM_DisableDMAReq_CC3(def->instance); + break; + case TIMER_CH4: + case TIMER_CH4N: + if (state) + LL_TIM_EnableDMAReq_CC4(def->instance); + else + LL_TIM_DisableDMAReq_CC4(def->instance); + break; + default: + break; + } +} + static void timer_irq_handler() { extern void soft_serial_timer_irq_handler(); soft_serial_timer_irq_handler(); diff --git a/src/driver/timer.h b/src/driver/timer.h index 843ba6d55..f5160ab4a 100644 --- a/src/driver/timer.h +++ b/src/driver/timer.h @@ -88,5 +88,6 @@ void timer_alloc_init(); bool timer_alloc_tag(timer_use_t use, resource_tag_t tag); resource_tag_t timer_alloc(timer_use_t use); uint32_t timer_channel_val(timer_channel_t chan); +void timer_enable_dma_request(timer_index_t tim, timer_channel_t chan, bool state); void timer_up_init(timer_index_t tim, uint16_t divider, uint32_t period); \ No newline at end of file