Skip to content

Commit

Permalink
dshot: centralize timer dma request
Browse files Browse the repository at this point in the history
  • Loading branch information
bkleiner authored and bkleiner committed Jul 25, 2024
1 parent e1c645e commit a56115a
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 86 deletions.
39 changes: 5 additions & 34 deletions src/driver/at32/motor_dshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand All @@ -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];

Expand All @@ -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;

Expand Down Expand Up @@ -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() {
Expand All @@ -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--;
}
Expand Down
25 changes: 25 additions & 0 deletions src/driver/at32/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
15 changes: 14 additions & 1 deletion src/driver/motor_dshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/driver/motor_dshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
56 changes: 6 additions & 50 deletions src/driver/stm32/motor_dshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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];

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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() {
Expand All @@ -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--;
}
Expand Down
37 changes: 37 additions & 0 deletions src/driver/stm32/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions src/driver/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit a56115a

Please sign in to comment.