diff options
author | Fabien Poussin <fabien.poussin@gmail.com> | 2018-07-13 11:19:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-13 11:19:23 +0200 |
commit | fe95e90b80a28dd2f40bfee1ad90822b99519c6a (patch) | |
tree | 1080f2ac3890c40d74e11edba674d8e8d623ed56 | |
parent | d86a300df4d3bcfb6e71fd480f9b4fa4663ad449 (diff) | |
parent | 6ac9e40dfa171c6093555f3f96c0116229c371ca (diff) | |
download | ChibiOS-Contrib-fe95e90b80a28dd2f40bfee1ad90822b99519c6a.tar.gz ChibiOS-Contrib-fe95e90b80a28dd2f40bfee1ad90822b99519c6a.tar.bz2 ChibiOS-Contrib-fe95e90b80a28dd2f40bfee1ad90822b99519c6a.zip |
Merge pull request #165 from lechndo/bug_#161_STM32_CRC_DMA_size_limit
Fix #161: STM32 LLD CRCv1 large data bug in DMA mode
-rwxr-xr-x | os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c | 20 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h | 6 |
2 files changed, 21 insertions, 5 deletions
diff --git a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c index 701b87d..180a383 100755 --- a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c +++ b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c @@ -121,9 +121,14 @@ static void crc_lld_serve_interrupt(CRCDriver *crcp, uint32_t flags) { /* Stop everything.*/ dmaStreamDisable(crcp->dma); - /* 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); + if (crcp->rem_data_size) { + /* 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); + } } #endif @@ -308,12 +313,17 @@ uint32_t crc_lld_calc(CRCDriver *crcp, size_t n, const void *buf) { #if CRC_USE_DMA == TRUE 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); dmaStreamSetMemory0(crcp->dma, &crcp->crc->DR); #if STM32_CRC_PROGRAMMABLE == TRUE - dmaStreamSetTransactionSize(crcp->dma, n); + dmaStreamSetTransactionSize(crcp->dma, sz); #else - dmaStreamSetTransactionSize(crcp->dma, (n / 4)); + dmaStreamSetTransactionSize(crcp->dma, (sz / 4)); #endif dmaStreamSetMode(crcp->dma, crcp->dmamode); diff --git a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h index 213d346..e879103 100644 --- a/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h +++ b/os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h @@ -203,6 +203,12 @@ struct CRCDriver { */ 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 */ const stm32_dma_stream_t *dma; |