Fix STM32 LLD CRCv1 large data bug in DMA mode

* STM32 DMA can only handle 65535 bytes per transfer so larger data sets
   have to split up to be correctly handled when using DMA
This commit is contained in:
Unknown 2018-07-12 13:58:45 +02:00 committed by Dominik Lechner
parent d86a300df4
commit 6ac9e40dfa
2 changed files with 21 additions and 5 deletions

View File

@ -121,10 +121,15 @@ static void crc_lld_serve_interrupt(CRCDriver *crcp, uint32_t flags) {
/* Stop everything.*/ /* Stop everything.*/
dmaStreamDisable(crcp->dma); dmaStreamDisable(crcp->dma);
/* Portable CRC ISR code defined in the high level driver, note, it is if (crcp->rem_data_size) {
a macro.*/ /* Start DMA follow up transfer for next data chunk */
crc_lld_start_calc(crcp, crcp->rem_data_size,
(const void *)crcp->dma->channel->CPAR+0xffff);
} else {
/* Portable CRC ISR code defined in the high level driver, note, it is a macro.*/
_crc_isr_code(crcp, crcp->crc->DR ^ crcp->config->final_val); _crc_isr_code(crcp, crcp->crc->DR ^ crcp->config->final_val);
} }
}
#endif #endif
/*===========================================================================*/ /*===========================================================================*/
@ -308,12 +313,17 @@ uint32_t crc_lld_calc(CRCDriver *crcp, size_t n, const void *buf) {
#if CRC_USE_DMA == TRUE #if CRC_USE_DMA == TRUE
void crc_lld_start_calc(CRCDriver *crcp, size_t n, const void *buf) { void crc_lld_start_calc(CRCDriver *crcp, size_t n, const void *buf) {
/* The STM32 DMA can only handle max 65535 bytes per transfer
* because it's data count register has only 16 bit. */
size_t sz = (n > 0xffff) ? 0xffff : n;
crcp->rem_data_size = n-sz;
dmaStreamSetPeripheral(crcp->dma, buf); dmaStreamSetPeripheral(crcp->dma, buf);
dmaStreamSetMemory0(crcp->dma, &crcp->crc->DR); dmaStreamSetMemory0(crcp->dma, &crcp->crc->DR);
#if STM32_CRC_PROGRAMMABLE == TRUE #if STM32_CRC_PROGRAMMABLE == TRUE
dmaStreamSetTransactionSize(crcp->dma, n); dmaStreamSetTransactionSize(crcp->dma, sz);
#else #else
dmaStreamSetTransactionSize(crcp->dma, (n / 4)); dmaStreamSetTransactionSize(crcp->dma, (sz / 4));
#endif #endif
dmaStreamSetMode(crcp->dma, crcp->dmamode); dmaStreamSetMode(crcp->dma, crcp->dmamode);

View File

@ -202,6 +202,12 @@ struct CRCDriver {
* @brief Waiting thread. * @brief Waiting thread.
*/ */
thread_reference_t thread; thread_reference_t thread;
/**
* @brief Remaining data size.
* @note The DMA can handle only 65535 bytes per transfer because
* it's data count register is only 16 bits wide.
*/
size_t rem_data_size;
/** /**
* @brief CRC DMA stream * @brief CRC DMA stream
*/ */