aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorUnknown <dominik.lechner@hale.at>2018-07-12 13:58:45 +0200
committerDominik Lechner <dominik.lechner@hale.at>2018-07-12 15:01:44 +0200
commit6ac9e40dfa171c6093555f3f96c0116229c371ca (patch)
tree1080f2ac3890c40d74e11edba674d8e8d623ed56 /os
parentd86a300df4d3bcfb6e71fd480f9b4fa4663ad449 (diff)
downloadChibiOS-Contrib-6ac9e40dfa171c6093555f3f96c0116229c371ca.tar.gz
ChibiOS-Contrib-6ac9e40dfa171c6093555f3f96c0116229c371ca.tar.bz2
ChibiOS-Contrib-6ac9e40dfa171c6093555f3f96c0116229c371ca.zip
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
Diffstat (limited to 'os')
-rwxr-xr-xos/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.c20
-rw-r--r--os/hal/ports/STM32/LLD/CRCv1/hal_crc_lld.h6
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;