summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuuki NAGAO <wf.yn386@gmail.com>2025-07-22 20:14:14 +0900
committerDamien George <damien@micropython.org>2025-08-18 13:11:01 +1000
commit1b35116c920550ba7bfc0f06bd4bad7d20f33b21 (patch)
tree76b2e9767ecca3552ac86fef885a6006f3f9eb6a
parent1588c455c41b445bfd1c65b5055847ab63114c96 (diff)
stm32/dac: Fix 12-bit DAC issue on STM32H5.
For STM32H5, to use 12-bit DAC, the DMA parameter should set: - Actual DMA source datawidth to CTR1. - The length is the amount of data to be transferred from source to destination in bytes. Also, this commit modifies the (dummy) definition of DMA_CIRCULAR for STM32H5 to prevent conflict with data width specification. Signed-off-by: Yuuki NAGAO <wf.yn386@gmail.com>
-rw-r--r--ports/stm32/dac.c7
-rw-r--r--ports/stm32/dma.c4
-rw-r--r--ports/stm32/dma.h2
3 files changed, 8 insertions, 5 deletions
diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c
index 54d5acc6c..0be0fd930 100644
--- a/ports/stm32/dac.c
+++ b/ports/stm32/dac.c
@@ -174,7 +174,7 @@ static void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, ui
// For STM32G4, DAC registers have to be accessed by words (32-bit).
dma_align = DMA_MDATAALIGN_BYTE | DMA_PDATAALIGN_WORD;
#elif defined(STM32H5)
- dma_align = 0;
+ dma_align = DMA_SRC_DATAWIDTH_BYTE | DMA_DEST_DATAWIDTH_WORD;
#else
dma_align = DMA_MDATAALIGN_BYTE | DMA_PDATAALIGN_BYTE;
#endif
@@ -183,7 +183,7 @@ static void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, ui
// For STM32G4, DAC registers have to be accessed by words (32-bit).
dma_align = DMA_MDATAALIGN_HALFWORD | DMA_PDATAALIGN_WORD;
#elif defined(STM32H5)
- dma_align = 0;
+ dma_align = DMA_SRC_DATAWIDTH_HALFWORD | DMA_DEST_DATAWIDTH_WORD;
#else
dma_align = DMA_MDATAALIGN_HALFWORD | DMA_PDATAALIGN_HALFWORD;
#endif
@@ -490,7 +490,10 @@ mp_obj_t pyb_dac_write_timed(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
align = DAC_ALIGN_8B_R;
} else {
align = DAC_ALIGN_12B_R;
+ // For STM32H5, the length is the amount of data to be transferred from source to destination in bytes.
+ #if !defined(STM32H5)
bufinfo.len /= 2;
+ #endif
}
dac_start_dma(self->dac_channel, tx_dma_descr, args[2].u_int, self->bits, align, bufinfo.len, bufinfo.buf);
diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c
index c25277074..c2923f7ae 100644
--- a/ports/stm32/dma.c
+++ b/ports/stm32/dma.c
@@ -1737,10 +1737,10 @@ void dma_nohal_init(const dma_descr_t *descr, uint32_t config) {
dma->CCR = init->Priority;
uint32_t ctr1reg = 0;
- ctr1reg |= init->SrcDataWidth;
+ ctr1reg |= config & DMA_CTR1_SDW_LOG2_Msk;
ctr1reg |= init->SrcInc;
ctr1reg |= (((init->SrcBurstLength - 1) << DMA_CTR1_SBL_1_Pos)) & DMA_CTR1_SBL_1_Msk;
- ctr1reg |= init->DestDataWidth;
+ ctr1reg |= config & DMA_CTR1_DDW_LOG2_Msk;
ctr1reg |= init->DestInc;
ctr1reg |= (((init->DestBurstLength - 1) << DMA_CTR1_DBL_1_Pos)) & DMA_CTR1_DBL_1_Msk;
diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h
index f05b22b5d..75e007bc9 100644
--- a/ports/stm32/dma.h
+++ b/ports/stm32/dma.h
@@ -33,7 +33,7 @@ typedef struct _dma_descr_t dma_descr_t;
#if defined(STM32H5)
// STM32H5 GPDMA doesn't feature circular mode directly, so define doesn't exist in
// stm32 driver header. Define it here to make users like DAC driver happy.
-#define DMA_CIRCULAR 0x00000001
+#define DMA_CIRCULAR 0x20000000
#endif
#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7)