From 8d7ef7cf893d256a97d85bde674a0c7832c1e6e5 Mon Sep 17 00:00:00 2001 From: Comma Device Date: Wed, 13 Nov 2024 17:04:40 +0000 Subject: [PATCH 1/8] wip --- board/boards/cuatro.h | 10 ++++++---- board/config.h | 2 +- board/main.c | 4 ++++ board/stm32h7/peripherals.h | 2 ++ board/stm32h7/sound.h | 30 +++++++++++++++++++++++++++++- 5 files changed, 42 insertions(+), 6 deletions(-) diff --git a/board/boards/cuatro.h b/board/boards/cuatro.h index a8f6516f61..8a31c431f7 100644 --- a/board/boards/cuatro.h +++ b/board/boards/cuatro.h @@ -104,8 +104,9 @@ static void cuatro_init(void) { set_gpio_alternate(GPIOD, 13, GPIO_AF5_FDCAN3); // C2: SOM GPIO used as input (fan control at boot) - set_gpio_mode(GPIOC, 2, MODE_INPUT); - set_gpio_pullup(GPIOC, 2, PULL_DOWN); + // FIXME: repurposed as mic clock output + // set_gpio_mode(GPIOC, 2, MODE_INPUT); + // set_gpio_pullup(GPIOC, 2, PULL_DOWN); // SOM bootkick + reset lines cuatro_set_bootkick(BOOT_BOOTKICK); @@ -135,8 +136,9 @@ static void cuatro_init(void) { set_gpio_alternate(GPIOC, 0, GPIO_AF8_SAI4); // SAI4_FS_B set_gpio_alternate(GPIOD, 11, GPIO_AF10_SAI4); // SAI4_SD_A set_gpio_alternate(GPIOE, 3, GPIO_AF8_SAI4); // SAI4_SD_B - set_gpio_alternate(GPIOE, 4, GPIO_AF2_SAI1); // SAI1_D2 - set_gpio_alternate(GPIOE, 5, GPIO_AF2_SAI1); // SAI1_CK2 + set_gpio_alternate(GPIOE, 4, GPIO_AF3_DFSDM1); // DFSDM1_DATIN3 + set_gpio_alternate(GPIOC, 2, GPIO_AF6_DFSDM1); // DFSDM1_CKOUT + // set_gpio_alternate(GPIOE, 5, GPIO_AF2_SAI1); // SAI1_CK2 set_gpio_alternate(GPIOE, 6, GPIO_AF10_SAI4); // SAI4_MCLK_B sound_init(); } diff --git a/board/config.h b/board/config.h index 6fb95ada26..3171ff61b2 100644 --- a/board/config.h +++ b/board/config.h @@ -6,7 +6,7 @@ //#define DEBUG_UART //#define DEBUG_USB //#define DEBUG_SPI -//#define DEBUG_FAULTS +#define DEBUG_FAULTS //#define DEBUG_COMMS //#define DEBUG_FAN diff --git a/board/main.c b/board/main.c index de2a917213..d8edb2591a 100644 --- a/board/main.c +++ b/board/main.c @@ -171,6 +171,10 @@ static void tick_handler(void) { set_power_save_state(power_save_status); } + #ifdef STM32H7 + print("mic dat: "); puth(DFSDM1_Filter0->FLTRDATAR >> 8); print("\n"); + #endif + // decimated to 1Hz if (loop_counter == 0U) { can_live = pending_can_live; diff --git a/board/stm32h7/peripherals.h b/board/stm32h7/peripherals.h index db89a38ad3..df736f7d15 100644 --- a/board/stm32h7/peripherals.h +++ b/board/stm32h7/peripherals.h @@ -124,6 +124,8 @@ void peripherals_init(void) { RCC->APB1LENR |= RCC_APB1LENR_DAC12EN; // DAC // Audio + RCC->APB2ENR |= RCC_APB2ENR_DFSDM1EN; // D/S demodulator for mic + RCC->APB2ENR |= RCC_APB2ENR_SAI1EN; // SAI1 RCC->APB4ENR |= RCC_APB4ENR_SAI4EN; // SAI4 // Timers diff --git a/board/stm32h7/sound.h b/board/stm32h7/sound.h index 1400a6eae8..0b355446a1 100644 --- a/board/stm32h7/sound.h +++ b/board/stm32h7/sound.h @@ -1,8 +1,9 @@ #define SOUND_RX_BUF_SIZE 2000U #define SOUND_TX_BUF_SIZE (SOUND_RX_BUF_SIZE/2U) +#define MIC_RX_BUF_SIZE 1000U __attribute__((section(".sram4"))) static uint16_t sound_rx_buf[2][SOUND_RX_BUF_SIZE]; -__attribute__((section(".sram4"))) static uint16_t sound_tx_buf[2][SOUND_TX_BUF_SIZE]; +__attribute__((section(".sram4"))) static uint32_t mic_rx_buf[2][MIC_RX_BUF_SIZE]; static uint8_t sound_idle_count; @@ -78,6 +79,10 @@ void sound_init(void) { TIM5->CNT = 0U; TIM5->SR = 0U; TIM5->CR1 |= TIM_CR1_CEN; + // sync both SAIs + register_set(&SAI4->GCR, (0b10 << SAI_GCR_SYNCOUT_Pos), SAI_GCR_SYNCIN_Msk | SAI_GCR_SYNCOUT_Msk); + register_set(&SAI1->GCR, (3U << SAI_GCR_SYNCIN_Pos), SAI_GCR_SYNCIN_Msk | SAI_GCR_SYNCOUT_Msk); + // stereo audio in register_set(&SAI4_Block_B->CR1, SAI_xCR1_DMAEN | (0b00UL << SAI_xCR1_SYNCEN_Pos) | (0b100U << SAI_xCR1_DS_Pos) | (0b11U << SAI_xCR1_MODE_Pos), 0x0FFB3FEFU); register_set(&SAI4_Block_B->CR2, (0b001U << SAI_xCR2_FTH_Pos), 0xFFFBU); @@ -93,6 +98,29 @@ void sound_init(void) { register_set(&DMAMUX2_Channel0->CCR, 16U, DMAMUX_CxCR_DMAREQ_ID_Msk); // SAI4_B_DMA register_set_bits(&BDMA_Channel0->CCR, BDMA_CCR_EN); + // mic output + register_set(&SAI4_Block_A->CR1, SAI_xCR1_DMAEN | (0b01 << SAI_xCR1_SYNCEN_Pos) | (0b100 << SAI_xCR1_DS_Pos) | (0b10 << SAI_xCR1_MODE_Pos), 0x0FFB3FEFU); + register_set(&SAI4_Block_A->CR2, 0U, 0xFFFBU); + register_set(&SAI4_Block_A->FRCR, (31U << SAI_xFRCR_FRL_Pos), 0x7FFFFU); + register_set(&SAI4_Block_A->SLOTR, (0b11 << SAI_xSLOTR_SLOTEN_Pos) | (1U << SAI_xSLOTR_NBSLOT_Pos) | (0b01 << SAI_xSLOTR_SLOTSZ_Pos), 0xFFFF0FDFU); // NBSLOT definition is vague + + // init DFSDM for PDM mic + DFSDM1_Channel0->CHCFGR1 = (6U << DFSDM_CHCFGR1_CKOUTDIV_Pos) | DFSDM_CHCFGR1_CHEN; // CH0 controls the clock + DFSDM1_Channel0->CHCFGR1 |= DFSDM_CHCFGR1_DFSDMEN; + DFSDM1_Channel3->CHCFGR1 |= (0b01 << DFSDM_CHCFGR1_SPICKSEL_Pos) | (0b00U << DFSDM_CHCFGR1_SITP_Pos) | DFSDM_CHCFGR1_CHEN; // SITP determines sample edge + DFSDM1_Filter0->FLTFCR = (64U << DFSDM_FLTFCR_FOSR_Pos) | (4 << DFSDM_FLTFCR_FORD_Pos); + DFSDM1_Filter0->FLTCR1 = (3U << DFSDM_FLTCR1_RCH_Pos) | DFSDM_FLTCR1_RCONT | DFSDM_FLTCR1_DFEN; + DFSDM1_Filter0->FLTCR1 |= DFSDM_FLTCR1_RSWSTART; + + // init DMA for SAI output + DMA1_Stream0->CR = DMA_SxCR_DBM | (8 << DMA_SxCR_CHSEL_Pos) | DMA_SxCR_PL_1 | DMA_SxCR_MSIZE_1 | (0b10UL << DMA_SxCR_PSIZE_Pos) | DMA_SxCR_CIRC; + DMA1_Stream0->PAR = (uint32_t) &DFSDM1_Filter0->FLTRDATAR; + DMA1_Stream0->M0AR = (uint32_t)&mic_rx_buf[0]; + DMA1_Stream0->M1AR = (uint32_t)&mic_rx_buf[1]; + DMA1_Stream0->CR |= DMA_SxCR_EN; + DMAMUX1_Channel0->CC |= 101U; + DFSDM1_Filter0->FLTCR2 |= DFSDM_FLTCR2_DMAEN; + // enable all initted blocks register_set_bits(&SAI4_Block_B->CR1, SAI_xCR1_SAIEN); NVIC_EnableIRQ(BDMA_Channel0_IRQn); From 36a5d714fad2f49df55518fdad676b5c6814705d Mon Sep 17 00:00:00 2001 From: Comma Device Date: Thu, 14 Nov 2024 15:45:31 +0000 Subject: [PATCH 2/8] this works! --- board/main.c | 4 ---- board/stm32h7/clock.h | 2 ++ board/stm32h7/sound.h | 56 +++++++++++++++++++++++++++++++++---------- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/board/main.c b/board/main.c index d8edb2591a..de2a917213 100644 --- a/board/main.c +++ b/board/main.c @@ -171,10 +171,6 @@ static void tick_handler(void) { set_power_save_state(power_save_status); } - #ifdef STM32H7 - print("mic dat: "); puth(DFSDM1_Filter0->FLTRDATAR >> 8); print("\n"); - #endif - // decimated to 1Hz if (loop_counter == 0U) { can_live = pending_can_live; diff --git a/board/stm32h7/clock.h b/board/stm32h7/clock.h index 4a29d459b9..40ad06043e 100644 --- a/board/stm32h7/clock.h +++ b/board/stm32h7/clock.h @@ -109,6 +109,8 @@ void clock_init(void) { register_set(&(RCC->D2CCIP2R), RCC_D2CCIP2R_USBSEL_1 | RCC_D2CCIP2R_USBSEL_0, RCC_D2CCIP2R_USBSEL); // Configure clock source for FDCAN (PLL1Q at 80Mhz) register_set(&(RCC->D2CCIP1R), RCC_D2CCIP1R_FDCANSEL_0, RCC_D2CCIP1R_FDCANSEL); + // Configure clock source for DFSDM1 + register_set_bits(&(RCC->D2CCIP1R), RCC_D2CCIP1R_DFSDM1SEL); // Configure clock source for ADC1,2,3 (per_ck(currently HSE)) register_set(&(RCC->D3CCIPR), RCC_D3CCIPR_ADCSEL_1, RCC_D3CCIPR_ADCSEL); //Enable the Clock Security System diff --git a/board/stm32h7/sound.h b/board/stm32h7/sound.h index 0b355446a1..2b86b4b48f 100644 --- a/board/stm32h7/sound.h +++ b/board/stm32h7/sound.h @@ -1,12 +1,32 @@ #define SOUND_RX_BUF_SIZE 2000U #define SOUND_TX_BUF_SIZE (SOUND_RX_BUF_SIZE/2U) -#define MIC_RX_BUF_SIZE 1000U - +#define MIC_RX_BUF_SIZE 512U +#define MIC_TX_BUF_SIZE (MIC_RX_BUF_SIZE * 2U) __attribute__((section(".sram4"))) static uint16_t sound_rx_buf[2][SOUND_RX_BUF_SIZE]; __attribute__((section(".sram4"))) static uint32_t mic_rx_buf[2][MIC_RX_BUF_SIZE]; static uint8_t sound_idle_count; +// Recording processing +static void DMA1_Stream0_IRQ_Handler(void) { + __attribute__((section(".sram4"))) static uint16_t tx_buf[MIC_TX_BUF_SIZE]; + + DMA1->LIFCR |= 0x7D; // clear flags + + // process samples + uint8_t buf_idx = ((DMA1_Stream0->CR & DMA_SxCR_CT) >> DMA_SxCR_CT_Pos) == 1U ? 0U : 1U; + for (uint16_t i=0U; i < MIC_RX_BUF_SIZE; i++) { + tx_buf[2U*i] = ((mic_rx_buf[buf_idx][i] >> 16U) & 0xFFFF); + tx_buf[(2U*i)+1U] = tx_buf[2U*i]; + } + + BDMA->IFCR |= BDMA_IFCR_CGIF1; + BDMA_Channel1->CCR &= ~BDMA_CCR_EN; + register_set(&BDMA_Channel1->CM0AR, (uint32_t) tx_buf, 0xFFFFFFFFU); + BDMA_Channel1->CNDTR = MIC_TX_BUF_SIZE; + BDMA_Channel1->CCR |= BDMA_CCR_EN; +} + void sound_tick(void) { if (sound_idle_count > 0U) { sound_idle_count--; @@ -53,6 +73,7 @@ static void BDMA_Channel0_IRQ_Handler(void) { void sound_init(void) { REGISTER_INTERRUPT(BDMA_Channel0_IRQn, BDMA_Channel0_IRQ_Handler, 64U, FAULT_INTERRUPT_RATE_SOUND_DMA) + REGISTER_INTERRUPT(DMA1_Stream0_IRQn, DMA1_Stream0_IRQ_Handler, 128U, FAULT_INTERRUPT_RATE_SOUND_DMA) // Init DAC register_set(&DAC1->MCR, 0U, 0xFFFFFFFFU); @@ -105,23 +126,32 @@ void sound_init(void) { register_set(&SAI4_Block_A->SLOTR, (0b11 << SAI_xSLOTR_SLOTEN_Pos) | (1U << SAI_xSLOTR_NBSLOT_Pos) | (0b01 << SAI_xSLOTR_SLOTSZ_Pos), 0xFFFF0FDFU); // NBSLOT definition is vague // init DFSDM for PDM mic - DFSDM1_Channel0->CHCFGR1 = (6U << DFSDM_CHCFGR1_CKOUTDIV_Pos) | DFSDM_CHCFGR1_CHEN; // CH0 controls the clock - DFSDM1_Channel0->CHCFGR1 |= DFSDM_CHCFGR1_DFSDMEN; + DFSDM1_Channel0->CHCFGR1 = (76U << DFSDM_CHCFGR1_CKOUTDIV_Pos) | DFSDM_CHCFGR1_CHEN; // CH0 controls the clock DFSDM1_Channel3->CHCFGR1 |= (0b01 << DFSDM_CHCFGR1_SPICKSEL_Pos) | (0b00U << DFSDM_CHCFGR1_SITP_Pos) | DFSDM_CHCFGR1_CHEN; // SITP determines sample edge - DFSDM1_Filter0->FLTFCR = (64U << DFSDM_FLTFCR_FOSR_Pos) | (4 << DFSDM_FLTFCR_FORD_Pos); - DFSDM1_Filter0->FLTCR1 = (3U << DFSDM_FLTCR1_RCH_Pos) | DFSDM_FLTCR1_RCONT | DFSDM_FLTCR1_DFEN; + DFSDM1_Channel3->CHCFGR2 = (2U << DFSDM_CHCFGR2_DTRBS_Pos); + DFSDM1_Filter0->FLTFCR = (0U << DFSDM_FLTFCR_IOSR_Pos) | (64U << DFSDM_FLTFCR_FOSR_Pos) | (4U << DFSDM_FLTFCR_FORD_Pos); + DFSDM1_Filter0->FLTCR1 = DFSDM_FLTCR1_FAST | (3U << DFSDM_FLTCR1_RCH_Pos) | DFSDM_FLTCR1_RDMAEN | DFSDM_FLTCR1_RCONT | DFSDM_FLTCR1_DFEN; + DFSDM1_Channel0->CHCFGR1 |= DFSDM_CHCFGR1_DFSDMEN; DFSDM1_Filter0->FLTCR1 |= DFSDM_FLTCR1_RSWSTART; - // init DMA for SAI output - DMA1_Stream0->CR = DMA_SxCR_DBM | (8 << DMA_SxCR_CHSEL_Pos) | DMA_SxCR_PL_1 | DMA_SxCR_MSIZE_1 | (0b10UL << DMA_SxCR_PSIZE_Pos) | DMA_SxCR_CIRC; - DMA1_Stream0->PAR = (uint32_t) &DFSDM1_Filter0->FLTRDATAR; - DMA1_Stream0->M0AR = (uint32_t)&mic_rx_buf[0]; - DMA1_Stream0->M1AR = (uint32_t)&mic_rx_buf[1]; + // DMA (DFSDM1 -> memory) + DMA1_Stream0->PAR = (uint32_t)&DFSDM1_Filter0->FLTRDATAR; + DMA1_Stream0->M0AR = (uint32_t)mic_rx_buf[0]; + DMA1_Stream0->M1AR = (uint32_t)mic_rx_buf[1]; + DMA1_Stream0->NDTR = MIC_RX_BUF_SIZE; + DMA1_Stream0->CR = DMA_SxCR_DBM | (0b10UL << DMA_SxCR_MSIZE_Pos) | (0b10UL << DMA_SxCR_PSIZE_Pos) | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_TCIE; + register_set(&DMAMUX1_Channel0->CCR, 101U, DMAMUX_CxCR_DMAREQ_ID_Msk); // DFSDM1_DMA0 DMA1_Stream0->CR |= DMA_SxCR_EN; - DMAMUX1_Channel0->CC |= 101U; - DFSDM1_Filter0->FLTCR2 |= DFSDM_FLTCR2_DMAEN; + DMA1->LIFCR |= 0x7D; // clear flags + + // DMA (memory -> SAI4) + register_set(&BDMA_Channel1->CPAR, (uint32_t) &(SAI4_Block_A->DR), 0xFFFFFFFFU); + register_set(&BDMA_Channel1->CCR, (0b01 << BDMA_CCR_MSIZE_Pos) | (0b01 << BDMA_CCR_PSIZE_Pos) | BDMA_CCR_MINC | (0b1 << BDMA_CCR_DIR_Pos), 0xFFFEU); + register_set(&DMAMUX2_Channel1->CCR, 15U, DMAMUX_CxCR_DMAREQ_ID_Msk); // SAI4_A_DMA // enable all initted blocks + register_set_bits(&SAI4_Block_A->CR1, SAI_xCR1_SAIEN); register_set_bits(&SAI4_Block_B->CR1, SAI_xCR1_SAIEN); NVIC_EnableIRQ(BDMA_Channel0_IRQn); + NVIC_EnableIRQ(DMA1_Stream0_IRQn); } From e178491a4022550ed6e91f0ca808fe80422f79a5 Mon Sep 17 00:00:00 2001 From: Comma Device Date: Thu, 14 Nov 2024 15:49:50 +0000 Subject: [PATCH 3/8] pin todo --- board/boards/cuatro.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/board/boards/cuatro.h b/board/boards/cuatro.h index 8a31c431f7..932382bdbf 100644 --- a/board/boards/cuatro.h +++ b/board/boards/cuatro.h @@ -136,9 +136,8 @@ static void cuatro_init(void) { set_gpio_alternate(GPIOC, 0, GPIO_AF8_SAI4); // SAI4_FS_B set_gpio_alternate(GPIOD, 11, GPIO_AF10_SAI4); // SAI4_SD_A set_gpio_alternate(GPIOE, 3, GPIO_AF8_SAI4); // SAI4_SD_B - set_gpio_alternate(GPIOE, 4, GPIO_AF3_DFSDM1); // DFSDM1_DATIN3 + set_gpio_alternate(GPIOE, 4, GPIO_AF3_DFSDM1); // DFSDM1_DATIN3 TODO: move to other pin! set_gpio_alternate(GPIOC, 2, GPIO_AF6_DFSDM1); // DFSDM1_CKOUT - // set_gpio_alternate(GPIOE, 5, GPIO_AF2_SAI1); // SAI1_CK2 set_gpio_alternate(GPIOE, 6, GPIO_AF10_SAI4); // SAI4_MCLK_B sound_init(); } From 39f5bbe92cb828e9f162772b7ae7ba370375ae41 Mon Sep 17 00:00:00 2001 From: Comma Device Date: Thu, 14 Nov 2024 15:56:48 +0000 Subject: [PATCH 4/8] SAI1 isn't used --- board/stm32h7/peripherals.h | 1 - 1 file changed, 1 deletion(-) diff --git a/board/stm32h7/peripherals.h b/board/stm32h7/peripherals.h index df736f7d15..cae04652a4 100644 --- a/board/stm32h7/peripherals.h +++ b/board/stm32h7/peripherals.h @@ -125,7 +125,6 @@ void peripherals_init(void) { // Audio RCC->APB2ENR |= RCC_APB2ENR_DFSDM1EN; // D/S demodulator for mic - RCC->APB2ENR |= RCC_APB2ENR_SAI1EN; // SAI1 RCC->APB4ENR |= RCC_APB4ENR_SAI4EN; // SAI4 // Timers From 08d30c69b4805f10f5fdfe71caa47a4f6aac94ec Mon Sep 17 00:00:00 2001 From: Comma Device Date: Thu, 23 Jan 2025 12:22:04 +0000 Subject: [PATCH 5/8] make it compile after rebase --- board/stm32h7/sound.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/board/stm32h7/sound.h b/board/stm32h7/sound.h index 2b86b4b48f..c16b31e7e4 100644 --- a/board/stm32h7/sound.h +++ b/board/stm32h7/sound.h @@ -1,12 +1,23 @@ -#define SOUND_RX_BUF_SIZE 2000U +#define SOUND_RX_BUF_SIZE 1000U #define SOUND_TX_BUF_SIZE (SOUND_RX_BUF_SIZE/2U) #define MIC_RX_BUF_SIZE 512U #define MIC_TX_BUF_SIZE (MIC_RX_BUF_SIZE * 2U) __attribute__((section(".sram4"))) static uint16_t sound_rx_buf[2][SOUND_RX_BUF_SIZE]; +__attribute__((section(".sram4"))) static uint16_t sound_tx_buf[2][SOUND_TX_BUF_SIZE]; __attribute__((section(".sram4"))) static uint32_t mic_rx_buf[2][MIC_RX_BUF_SIZE]; static uint8_t sound_idle_count; +void sound_tick(void) { + if (sound_idle_count > 0U) { + sound_idle_count--; + if (sound_idle_count == 0U) { + current_board->set_amp_enabled(false); + register_clear_bits(&DMA1_Stream1->CR, DMA_SxCR_EN); + } + } +} + // Recording processing static void DMA1_Stream0_IRQ_Handler(void) { __attribute__((section(".sram4"))) static uint16_t tx_buf[MIC_TX_BUF_SIZE]; @@ -27,16 +38,6 @@ static void DMA1_Stream0_IRQ_Handler(void) { BDMA_Channel1->CCR |= BDMA_CCR_EN; } -void sound_tick(void) { - if (sound_idle_count > 0U) { - sound_idle_count--; - if (sound_idle_count == 0U) { - current_board->set_amp_enabled(false); - register_clear_bits(&DMA1_Stream1->CR, DMA_SxCR_EN); - } - } -} - // Playback processing static void BDMA_Channel0_IRQ_Handler(void) { BDMA->IFCR |= BDMA_IFCR_CGIF0; // clear flag From 2a66b62e72bd864cd6031d7da4452a80f703f09e Mon Sep 17 00:00:00 2001 From: Comma Device Date: Thu, 23 Jan 2025 12:42:13 +0000 Subject: [PATCH 6/8] fix gpio --- board/boards/cuatro.h | 21 ++++++++++----------- board/config.h | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/board/boards/cuatro.h b/board/boards/cuatro.h index 932382bdbf..3d630f022e 100644 --- a/board/boards/cuatro.h +++ b/board/boards/cuatro.h @@ -9,13 +9,13 @@ static void cuatro_set_led(uint8_t color, bool enabled) { switch (color) { case LED_RED: - set_gpio_output(GPIOD, 15, !enabled); + set_gpio_output(GPIOC, 6, !enabled); break; case LED_GREEN: - set_gpio_output(GPIOB, 2, !enabled); + set_gpio_output(GPIOC, 7, !enabled); break; case LED_BLUE: - set_gpio_output(GPIOE, 2, !enabled); + set_gpio_output(GPIOC, 9, !enabled); break; default: break; @@ -79,9 +79,9 @@ static void cuatro_init(void) { red_chiplet_init(); // init LEDs as open drain - set_gpio_output_type(GPIOE, 2, OUTPUT_TYPE_OPEN_DRAIN); - set_gpio_output_type(GPIOB, 2, OUTPUT_TYPE_OPEN_DRAIN); - set_gpio_output_type(GPIOD, 15, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOC, 6, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOC, 7, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOC, 9, OUTPUT_TYPE_OPEN_DRAIN); // more open drain set_gpio_output_type(GPIOD, 3, OUTPUT_TYPE_OPEN_DRAIN); // FAN_EN @@ -104,9 +104,8 @@ static void cuatro_init(void) { set_gpio_alternate(GPIOD, 13, GPIO_AF5_FDCAN3); // C2: SOM GPIO used as input (fan control at boot) - // FIXME: repurposed as mic clock output - // set_gpio_mode(GPIOC, 2, MODE_INPUT); - // set_gpio_pullup(GPIOC, 2, PULL_DOWN); + set_gpio_mode(GPIOC, 2, MODE_INPUT); + set_gpio_pullup(GPIOC, 2, PULL_DOWN); // SOM bootkick + reset lines cuatro_set_bootkick(BOOT_BOOTKICK); @@ -136,8 +135,8 @@ static void cuatro_init(void) { set_gpio_alternate(GPIOC, 0, GPIO_AF8_SAI4); // SAI4_FS_B set_gpio_alternate(GPIOD, 11, GPIO_AF10_SAI4); // SAI4_SD_A set_gpio_alternate(GPIOE, 3, GPIO_AF8_SAI4); // SAI4_SD_B - set_gpio_alternate(GPIOE, 4, GPIO_AF3_DFSDM1); // DFSDM1_DATIN3 TODO: move to other pin! - set_gpio_alternate(GPIOC, 2, GPIO_AF6_DFSDM1); // DFSDM1_CKOUT + set_gpio_alternate(GPIOE, 4, GPIO_AF3_DFSDM1); // DFSDM1_DATIN3 + set_gpio_alternate(GPIOE, 9, GPIO_AF3_DFSDM1); // DFSDM1_CKOUT set_gpio_alternate(GPIOE, 6, GPIO_AF10_SAI4); // SAI4_MCLK_B sound_init(); } diff --git a/board/config.h b/board/config.h index 3171ff61b2..6fb95ada26 100644 --- a/board/config.h +++ b/board/config.h @@ -6,7 +6,7 @@ //#define DEBUG_UART //#define DEBUG_USB //#define DEBUG_SPI -#define DEBUG_FAULTS +//#define DEBUG_FAULTS //#define DEBUG_COMMS //#define DEBUG_FAN From 86921a2c94ede7cf8b5e3220c2d05f3023f96f39 Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Fri, 24 Jan 2025 12:12:09 +0100 Subject: [PATCH 7/8] use register functions and clean up misra --- board/stm32h7/sound.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/board/stm32h7/sound.h b/board/stm32h7/sound.h index c16b31e7e4..ef02a6db29 100644 --- a/board/stm32h7/sound.h +++ b/board/stm32h7/sound.h @@ -25,9 +25,9 @@ static void DMA1_Stream0_IRQ_Handler(void) { DMA1->LIFCR |= 0x7D; // clear flags // process samples - uint8_t buf_idx = ((DMA1_Stream0->CR & DMA_SxCR_CT) >> DMA_SxCR_CT_Pos) == 1U ? 0U : 1U; + uint8_t buf_idx = (((DMA1_Stream0->CR & DMA_SxCR_CT) >> DMA_SxCR_CT_Pos) == 1U) ? 0U : 1U; for (uint16_t i=0U; i < MIC_RX_BUF_SIZE; i++) { - tx_buf[2U*i] = ((mic_rx_buf[buf_idx][i] >> 16U) & 0xFFFF); + tx_buf[2U*i] = ((mic_rx_buf[buf_idx][i] >> 16U) & 0xFFFFU); tx_buf[(2U*i)+1U] = tx_buf[2U*i]; } @@ -102,7 +102,7 @@ void sound_init(void) { TIM5->CR1 |= TIM_CR1_CEN; // sync both SAIs - register_set(&SAI4->GCR, (0b10 << SAI_GCR_SYNCOUT_Pos), SAI_GCR_SYNCIN_Msk | SAI_GCR_SYNCOUT_Msk); + register_set(&SAI4->GCR, (0b10UL << SAI_GCR_SYNCOUT_Pos), SAI_GCR_SYNCIN_Msk | SAI_GCR_SYNCOUT_Msk); register_set(&SAI1->GCR, (3U << SAI_GCR_SYNCIN_Pos), SAI_GCR_SYNCIN_Msk | SAI_GCR_SYNCOUT_Msk); // stereo audio in @@ -121,33 +121,33 @@ void sound_init(void) { register_set_bits(&BDMA_Channel0->CCR, BDMA_CCR_EN); // mic output - register_set(&SAI4_Block_A->CR1, SAI_xCR1_DMAEN | (0b01 << SAI_xCR1_SYNCEN_Pos) | (0b100 << SAI_xCR1_DS_Pos) | (0b10 << SAI_xCR1_MODE_Pos), 0x0FFB3FEFU); + register_set(&SAI4_Block_A->CR1, SAI_xCR1_DMAEN | (0b01UL << SAI_xCR1_SYNCEN_Pos) | (0b100UL << SAI_xCR1_DS_Pos) | (0b10UL << SAI_xCR1_MODE_Pos), 0x0FFB3FEFU); register_set(&SAI4_Block_A->CR2, 0U, 0xFFFBU); register_set(&SAI4_Block_A->FRCR, (31U << SAI_xFRCR_FRL_Pos), 0x7FFFFU); - register_set(&SAI4_Block_A->SLOTR, (0b11 << SAI_xSLOTR_SLOTEN_Pos) | (1U << SAI_xSLOTR_NBSLOT_Pos) | (0b01 << SAI_xSLOTR_SLOTSZ_Pos), 0xFFFF0FDFU); // NBSLOT definition is vague + register_set(&SAI4_Block_A->SLOTR, (0b11UL << SAI_xSLOTR_SLOTEN_Pos) | (1UL << SAI_xSLOTR_NBSLOT_Pos) | (0b01U << SAI_xSLOTR_SLOTSZ_Pos), 0xFFFF0FDFU); // NBSLOT definition is vague // init DFSDM for PDM mic - DFSDM1_Channel0->CHCFGR1 = (76U << DFSDM_CHCFGR1_CKOUTDIV_Pos) | DFSDM_CHCFGR1_CHEN; // CH0 controls the clock - DFSDM1_Channel3->CHCFGR1 |= (0b01 << DFSDM_CHCFGR1_SPICKSEL_Pos) | (0b00U << DFSDM_CHCFGR1_SITP_Pos) | DFSDM_CHCFGR1_CHEN; // SITP determines sample edge - DFSDM1_Channel3->CHCFGR2 = (2U << DFSDM_CHCFGR2_DTRBS_Pos); - DFSDM1_Filter0->FLTFCR = (0U << DFSDM_FLTFCR_IOSR_Pos) | (64U << DFSDM_FLTFCR_FOSR_Pos) | (4U << DFSDM_FLTFCR_FORD_Pos); - DFSDM1_Filter0->FLTCR1 = DFSDM_FLTCR1_FAST | (3U << DFSDM_FLTCR1_RCH_Pos) | DFSDM_FLTCR1_RDMAEN | DFSDM_FLTCR1_RCONT | DFSDM_FLTCR1_DFEN; - DFSDM1_Channel0->CHCFGR1 |= DFSDM_CHCFGR1_DFSDMEN; + register_set(&DFSDM1_Channel0->CHCFGR1, (76UL << DFSDM_CHCFGR1_CKOUTDIV_Pos) | DFSDM_CHCFGR1_CHEN, 0xC0FFF1EFU); // CH0 controls the clock + register_set(&DFSDM1_Channel3->CHCFGR1, (0b01UL << DFSDM_CHCFGR1_SPICKSEL_Pos) | (0b00U << DFSDM_CHCFGR1_SITP_Pos) | DFSDM_CHCFGR1_CHEN, 0x0000F1EFU); // SITP determines sample edge + register_set(&DFSDM1_Channel3->CHCFGR2, (2U << DFSDM_CHCFGR2_DTRBS_Pos), 0xFFFFFFF7U); + register_set(&DFSDM1_Filter0->FLTFCR, (0U << DFSDM_FLTFCR_IOSR_Pos) | (64UL << DFSDM_FLTFCR_FOSR_Pos) | (4UL << DFSDM_FLTFCR_FORD_Pos), 0xE3FF00FFU); + register_set(&DFSDM1_Filter0->FLTCR1, DFSDM_FLTCR1_FAST | (3UL << DFSDM_FLTCR1_RCH_Pos) | DFSDM_FLTCR1_RDMAEN | DFSDM_FLTCR1_RCONT | DFSDM_FLTCR1_DFEN, 0x672E7F3BU); + register_set_bits(&DFSDM1_Channel0->CHCFGR1, DFSDM_CHCFGR1_DFSDMEN); DFSDM1_Filter0->FLTCR1 |= DFSDM_FLTCR1_RSWSTART; // DMA (DFSDM1 -> memory) - DMA1_Stream0->PAR = (uint32_t)&DFSDM1_Filter0->FLTRDATAR; - DMA1_Stream0->M0AR = (uint32_t)mic_rx_buf[0]; - DMA1_Stream0->M1AR = (uint32_t)mic_rx_buf[1]; + register_set(&DMA1_Stream0->PAR, (uint32_t) &DFSDM1_Filter0->FLTRDATAR, 0xFFFFFFFFU); + register_set(&DMA1_Stream0->M0AR, (uint32_t)mic_rx_buf[0], 0xFFFFFFFFU); + register_set(&DMA1_Stream0->M1AR, (uint32_t)mic_rx_buf[1], 0xFFFFFFFFU); DMA1_Stream0->NDTR = MIC_RX_BUF_SIZE; - DMA1_Stream0->CR = DMA_SxCR_DBM | (0b10UL << DMA_SxCR_MSIZE_Pos) | (0b10UL << DMA_SxCR_PSIZE_Pos) | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_TCIE; + register_set(&DMA1_Stream0->CR, DMA_SxCR_DBM | (0b10UL << DMA_SxCR_MSIZE_Pos) | (0b10UL << DMA_SxCR_PSIZE_Pos) | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_TCIE, 0x01FFFFFFU); register_set(&DMAMUX1_Channel0->CCR, 101U, DMAMUX_CxCR_DMAREQ_ID_Msk); // DFSDM1_DMA0 - DMA1_Stream0->CR |= DMA_SxCR_EN; + register_set_bits(&DMA1_Stream0->CR, DMA_SxCR_EN); DMA1->LIFCR |= 0x7D; // clear flags // DMA (memory -> SAI4) register_set(&BDMA_Channel1->CPAR, (uint32_t) &(SAI4_Block_A->DR), 0xFFFFFFFFU); - register_set(&BDMA_Channel1->CCR, (0b01 << BDMA_CCR_MSIZE_Pos) | (0b01 << BDMA_CCR_PSIZE_Pos) | BDMA_CCR_MINC | (0b1 << BDMA_CCR_DIR_Pos), 0xFFFEU); + register_set(&BDMA_Channel1->CCR, (0b01UL << BDMA_CCR_MSIZE_Pos) | (0b01UL << BDMA_CCR_PSIZE_Pos) | BDMA_CCR_MINC | (0b1U << BDMA_CCR_DIR_Pos), 0xFFFEU); register_set(&DMAMUX2_Channel1->CCR, 15U, DMAMUX_CxCR_DMAREQ_ID_Msk); // SAI4_A_DMA // enable all initted blocks From 726dcab15d5e246ec2ee6eaf9f862fb310c585b8 Mon Sep 17 00:00:00 2001 From: Comma Device Date: Wed, 29 Jan 2025 15:43:15 +0000 Subject: [PATCH 8/8] add power management for mic --- board/stm32h7/sound.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/board/stm32h7/sound.h b/board/stm32h7/sound.h index ef02a6db29..5a5688b4b4 100644 --- a/board/stm32h7/sound.h +++ b/board/stm32h7/sound.h @@ -6,7 +6,9 @@ __attribute__((section(".sram4"))) static uint16_t sound_rx_buf[2][SOUND_RX_BUF_ __attribute__((section(".sram4"))) static uint16_t sound_tx_buf[2][SOUND_TX_BUF_SIZE]; __attribute__((section(".sram4"))) static uint32_t mic_rx_buf[2][MIC_RX_BUF_SIZE]; +#define SOUND_IDLE_TIMEOUT 4U static uint8_t sound_idle_count; +static uint8_t mic_idle_count; void sound_tick(void) { if (sound_idle_count > 0U) { @@ -16,6 +18,13 @@ void sound_tick(void) { register_clear_bits(&DMA1_Stream1->CR, DMA_SxCR_EN); } } + + if (mic_idle_count > 0U) { + mic_idle_count--; + if (mic_idle_count == 0U) { + register_clear_bits(&DFSDM1_Channel0->CHCFGR1, DFSDM_CHCFGR1_DFSDMEN); + } + } } // Recording processing @@ -67,8 +76,16 @@ static void BDMA_Channel0_IRQ_Handler(void) { register_set(&DMA1_Stream1->CR, (1UL - tx_buf_idx) << DMA_SxCR_CT_Pos, DMA_SxCR_CT_Msk); register_set_bits(&DMA1_Stream1->CR, DMA_SxCR_EN); } - sound_idle_count = 4U; + sound_idle_count = SOUND_IDLE_TIMEOUT; } + + // manage mic state + if (mic_idle_count == 0U) { + register_set_bits(&DFSDM1_Channel0->CHCFGR1, DFSDM_CHCFGR1_DFSDMEN); + DFSDM1_Filter0->FLTCR1 |= DFSDM_FLTCR1_RSWSTART; + } + mic_idle_count = SOUND_IDLE_TIMEOUT; + sound_tick(); } @@ -132,8 +149,6 @@ void sound_init(void) { register_set(&DFSDM1_Channel3->CHCFGR2, (2U << DFSDM_CHCFGR2_DTRBS_Pos), 0xFFFFFFF7U); register_set(&DFSDM1_Filter0->FLTFCR, (0U << DFSDM_FLTFCR_IOSR_Pos) | (64UL << DFSDM_FLTFCR_FOSR_Pos) | (4UL << DFSDM_FLTFCR_FORD_Pos), 0xE3FF00FFU); register_set(&DFSDM1_Filter0->FLTCR1, DFSDM_FLTCR1_FAST | (3UL << DFSDM_FLTCR1_RCH_Pos) | DFSDM_FLTCR1_RDMAEN | DFSDM_FLTCR1_RCONT | DFSDM_FLTCR1_DFEN, 0x672E7F3BU); - register_set_bits(&DFSDM1_Channel0->CHCFGR1, DFSDM_CHCFGR1_DFSDMEN); - DFSDM1_Filter0->FLTCR1 |= DFSDM_FLTCR1_RSWSTART; // DMA (DFSDM1 -> memory) register_set(&DMA1_Stream0->PAR, (uint32_t) &DFSDM1_Filter0->FLTRDATAR, 0xFFFFFFFFU);