dshot: update timer generation before DMA request

This reloads the timer configuration before triggering DMA. Without that,
in rare cases, there were 17 bits sent instead of 16.
The 1. bit (1. pulse) was always wrong (too much), the rest of the bits
were the correct DShot packet that was meant to be sent.
This commit is contained in:
Beat Küng 2019-09-08 11:42:04 +02:00
parent 7445c25fcc
commit d0a7490222
3 changed files with 8 additions and 0 deletions

View File

@ -383,6 +383,7 @@ void up_dshot_trigger(void)
uint32_t dshot_data_size = motors_number * ONE_MOTOR_BUFF_SIZE;
*rxIFCR |= dma_int_streamx_mask; //clear interrupt flags
*rSxNDTR = dshot_data_size;
io_timer_update_generation(timer);
*rSxCR |= DMA_SCR_EN; // Trigger DMA
}
}

View File

@ -143,6 +143,7 @@ __EXPORT int io_timer_free_channel(unsigned channel);
__EXPORT int io_timer_get_channel_mode(unsigned channel);
__EXPORT int io_timer_get_mode_channels(io_timer_channel_mode_t mode);
__EXPORT extern void io_timer_trigger(void);
__EXPORT void io_timer_update_generation(uint8_t timer);
__EXPORT extern int io_timer_set_dshot_mode(uint8_t timer, unsigned dshot_pwm_rate, uint8_t dma_burst_length);

View File

@ -492,6 +492,12 @@ static inline void io_timer_set_oneshot_mode(unsigned timer)
rEGR(timer) = GTIM_EGR_UG;
}
void io_timer_update_generation(uint8_t timer)
{
// Re-initialize the counter and generate an update of the registers
rEGR(timer) = ATIM_EGR_UG;
}
int io_timer_set_dshot_mode(uint8_t timer, unsigned dshot_pwm_freq, uint8_t dma_burst_length)
{
int ret_val = OK;