diff options
| -rwxr-xr-x | Core/Inc/cs4272.h | 35 | ||||
| -rwxr-xr-x | Core/Inc/dma.h | 52 | ||||
| -rwxr-xr-x | Core/Inc/stm32h7xx_it.h | 2 | ||||
| -rwxr-xr-x | Core/Src/cs4272.c | 126 | ||||
| -rwxr-xr-x | Core/Src/dma.c | 58 | ||||
| -rwxr-xr-x | Core/Src/i2c.c | 12 | ||||
| -rwxr-xr-x | Core/Src/main.c | 48 | ||||
| -rwxr-xr-x | Core/Src/sai.c | 54 | ||||
| -rwxr-xr-x | Core/Src/stm32h7xx_it.c | 30 | ||||
| -rwxr-xr-x | README.md | 4 | ||||
| -rwxr-xr-x | STM32H750ZBTX_FLASH.ld | 10 | ||||
| -rwxr-xr-x | audio.ioc | 109 |
12 files changed, 500 insertions, 40 deletions
diff --git a/Core/Inc/cs4272.h b/Core/Inc/cs4272.h new file mode 100755 index 0000000..30e493a --- /dev/null +++ b/Core/Inc/cs4272.h @@ -0,0 +1,35 @@ +/*
+ * cs4272.h
+ *
+ * Created on: Aug 16, 2026
+ * Author: ozpv
+ */
+
+#ifndef INC_CS4272_H_
+#define INC_CS4272_H_
+
+// cs4272k-czzr 7. REGISTER QUICK REFERENCE
+#define MODE_CONTROL_1 0x01
+#define DAC_CONTROL 0x02
+#define DAC_VOLUME_AND_MIXING_CONTROL 0x03
+#define DAC_CH_A_VOLUME_CONTROL 0x04
+#define DAC_CH_B_VOLUME_CONTROL 0x05
+#define ADC_CONTROL 0x06
+#define MODE_CONTROL_2 0x07
+#define CHIP_ID 0x08
+
+#define CS4272_CHIP_ID 0x0
+
+// set by ncs/ad0 pin
+#define CS4272_I2C_ADDR (0b0010000 << 1)
+
+#define BUFFER_SIZE 512
+
+extern volatile int32_t rx_buffer[BUFFER_SIZE];
+extern volatile int32_t tx_buffer[BUFFER_SIZE];
+
+extern const uint8_t CS4272_CONFIG[7];
+
+uint8_t CS4272_Init();
+
+#endif /* INC_CS4272_H_ */
diff --git a/Core/Inc/dma.h b/Core/Inc/dma.h new file mode 100755 index 0000000..cbf3957 --- /dev/null +++ b/Core/Inc/dma.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file dma.h
+ * @brief This file contains all the function prototypes for
+ * the dma.c file
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2026 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __DMA_H__
+#define __DMA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* DMA memory to memory transfer handles -------------------------------------*/
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_DMA_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DMA_H__ */
+
diff --git a/Core/Inc/stm32h7xx_it.h b/Core/Inc/stm32h7xx_it.h index b176787..c630d61 100755 --- a/Core/Inc/stm32h7xx_it.h +++ b/Core/Inc/stm32h7xx_it.h @@ -55,6 +55,8 @@ void SVC_Handler(void); void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
+void DMA1_Stream0_IRQHandler(void);
+void DMA1_Stream1_IRQHandler(void);
void OTG_HS_EP1_OUT_IRQHandler(void);
void OTG_HS_EP1_IN_IRQHandler(void);
void OTG_HS_IRQHandler(void);
diff --git a/Core/Src/cs4272.c b/Core/Src/cs4272.c new file mode 100755 index 0000000..e7b639e --- /dev/null +++ b/Core/Src/cs4272.c @@ -0,0 +1,126 @@ +/*
+ * cs4272.c
+ *
+ * Created on: Aug 16, 2026
+ * Author: ozpv
+ */
+
+#include "i2c.h"
+#include "cs4272.h"
+
+volatile int32_t rx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers")));
+volatile int32_t tx_buffer[BUFFER_SIZE] __attribute__((section(".audio_buffers")));
+
+const uint8_t CS4272_CONFIG[7] = {
+ // MODE CONTROL 1
+ // single speed i2s slave
+ 0b00000001,
+ // DAC CONTROL
+ // no auto mute steep roll off interpolation 48 kHz de-emphasis
+ // Soft Ramp Up and Down and no polarity flipping
+ 0b00001100,
+ // DAC Volume & Mixing Control
+ // Channel B Volume = Channel A Volume Soft Ramp and Zero Cross
+ // a = L b = R
+ 0b01111001,
+ // Channel A volume
+ // 0 dB
+ // Binary Code Decimal Value Volume Setting
+ // 0000000 0 0 dB
+ // 0010100 20 -20 dB
+ // 0101000 40 -40 dB
+ // 0111100 60 -60 dB
+ // 1011010 90 -90 dB
+ 0b00000000,
+ // Channel B volume
+ 0b00000000,
+ // ADC control
+ // I2S up to 24-bit data High Pass filter on
+ // bits 3:2 adc channel mute
+ 0b00010000,
+ // MODE CONTROL 2
+ // power down OFF
+ 0b00000010,
+};
+
+HAL_StatusTypeDef CS4272_ReadRegister(uint8_t addr, uint8_t *data) {
+ return HAL_I2C_Mem_Read(&hi2c4, CS4272_I2C_ADDR, addr, I2C_MEMADD_SIZE_8BIT,
+ data, 1, HAL_MAX_DELAY);
+}
+
+HAL_StatusTypeDef CS4272_WriteRegister(uint8_t addr, uint8_t data) {
+ return HAL_I2C_Mem_Write(&hi2c4, CS4272_I2C_ADDR, addr,
+ I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY);
+}
+
+void CS4272_Reset() {
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
+
+ HAL_Delay(10);
+
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
+
+ HAL_Delay(10);
+}
+
+uint8_t CS4272_Init() {
+ CS4272_Reset();
+
+ if (HAL_I2C_IsDeviceReady(&hi2c4, CS4272_I2C_ADDR, 3, 1000) != HAL_OK) {
+ return HAL_ERROR;
+ }
+
+ // 5.2.1 Recommended Power-Up Sequence
+ // power down mode and control port enable
+ if (CS4272_WriteRegister(MODE_CONTROL_2, 0x03) != HAL_OK) {
+ return HAL_ERROR;
+ }
+
+ // check if device ID is correct
+ uint8_t id = 0;
+ if (CS4272_ReadRegister(CHIP_ID, &id) != HAL_OK) {
+ return HAL_ERROR;
+ }
+
+ if ((id >> 4) != CS4272_CHIP_ID) {
+ return 2;
+ }
+
+ // Configure
+ uint8_t cfg = 0;
+ for (uint8_t i = MODE_CONTROL_1; i < MODE_CONTROL_2; ++i) {
+ if (CS4272_WriteRegister(i, CS4272_CONFIG[i - 1]) != HAL_OK) {
+ return HAL_ERROR;
+ }
+
+ if (CS4272_ReadRegister(i, &cfg) != HAL_OK) {
+ return HAL_ERROR;
+ }
+
+ if (cfg != CS4272_CONFIG[i - 1]) {
+ return 2;
+ }
+ }
+
+ if (CS4272_WriteRegister(MODE_CONTROL_2, 0x02) != HAL_OK) {
+ return HAL_ERROR;
+ }
+
+ if (CS4272_ReadRegister(MODE_CONTROL_2, &cfg) != HAL_OK || cfg != 0x02) {
+ return 2;
+ }
+
+ return HAL_OK;
+}
+
+void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) {
+ for(int i = 0; i < BUFFER_SIZE / 2; i++) {
+ tx_buffer[i] = rx_buffer[i];
+ }
+}
+
+void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) {
+ for(int i = BUFFER_SIZE / 2; i < BUFFER_SIZE; i++) {
+ tx_buffer[i] = rx_buffer[i];
+ }
+}
diff --git a/Core/Src/dma.c b/Core/Src/dma.c new file mode 100755 index 0000000..86e2fa4 --- /dev/null +++ b/Core/Src/dma.c @@ -0,0 +1,58 @@ +/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file dma.c
+ * @brief This file provides code for the configuration
+ * of all the requested memory to memory DMA transfers.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2026 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "dma.h"
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/*----------------------------------------------------------------------------*/
+/* Configure DMA */
+/*----------------------------------------------------------------------------*/
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/**
+ * Enable DMA controller clock
+ */
+void MX_DMA_Init(void)
+{
+
+ /* DMA controller clock enable */
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ /* DMA interrupt init */
+ /* DMA1_Stream0_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
+ /* DMA1_Stream1_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
+
+}
+
+/* USER CODE BEGIN 2 */
+
+/* USER CODE END 2 */
+
diff --git a/Core/Src/i2c.c b/Core/Src/i2c.c index 6ebfe13..4f3b697 100755 --- a/Core/Src/i2c.c +++ b/Core/Src/i2c.c @@ -38,7 +38,7 @@ void MX_I2C4_Init(void) /* USER CODE END I2C4_Init 1 */
hi2c4.Instance = I2C4;
- hi2c4.Init.Timing = 0x00201E2D;
+ hi2c4.Init.Timing = 0x307075B1;
hi2c4.Init.OwnAddress1 = 0;
hi2c4.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c4.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
@@ -74,12 +74,22 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(i2cHandle->Instance==I2C4)
{
/* USER CODE BEGIN I2C4_MspInit 0 */
/* USER CODE END I2C4_MspInit 0 */
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C4;
+ PeriphClkInitStruct.I2c4ClockSelection = RCC_I2C4CLKSOURCE_D3PCLK1;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C4 GPIO Configuration
PB8 ------> I2C4_SCL
diff --git a/Core/Src/main.c b/Core/Src/main.c index 721e51c..574bba8 100755 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -18,6 +18,7 @@ /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
+#include "dma.h"
#include "i2c.h"
#include "quadspi.h"
#include "sai.h"
@@ -27,7 +28,7 @@ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
-
+#include "cs4272.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -102,7 +103,7 @@ int main(void) SystemClock_Config();
/* Configure the peripherals common clocks */
-// PeriphCommonClock_Config();
+ PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
@@ -110,13 +111,31 @@ int main(void) /* Initialize all configured peripherals */
MX_GPIO_Init();
+ MX_DMA_Init();
MX_FMC_Init();
MX_I2C4_Init();
MX_SAI1_Init();
MX_USB_DEVICE_Init();
-// MX_QUADSPI_Init();
+ //MX_QUADSPI_Init();
/* USER CODE BEGIN 2 */
+ __HAL_RCC_SAI1_CLK_ENABLE();
+ __HAL_SAI_ENABLE(&hsai_BlockA1);
+
+ HAL_Delay(10);
+
+ if (CS4272_Init() != HAL_OK) {
+ Error_Handler();
+ }
+
+ if (HAL_SAI_Receive_DMA(&hsai_BlockB1, (uint8_t *)rx_buffer, BUFFER_SIZE) != HAL_OK) {
+ Error_Handler();
+ }
+
+ if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)tx_buffer, BUFFER_SIZE) != HAL_OK) {
+ Error_Handler();
+ }
+
/* USER CODE END 2 */
/* Infinite loop */
@@ -126,13 +145,6 @@ int main(void) /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET);
-
- HAL_Delay(1000);
-
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET);
-
- HAL_Delay(1000);
}
/* USER CODE END 3 */
}
@@ -205,7 +217,7 @@ void PeriphCommonClock_Config(void) /** Initializes the peripherals clock
*/
- PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C4|RCC_PERIPHCLK_SAI1;
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
PeriphClkInitStruct.PLL3.PLL3M = 5;
PeriphClkInitStruct.PLL3.PLL3N = 49;
PeriphClkInitStruct.PLL3.PLL3P = 20;
@@ -215,7 +227,6 @@ void PeriphCommonClock_Config(void) PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
PeriphClkInitStruct.PLL3.PLL3FRACN = 1246;
PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL3;
- PeriphClkInitStruct.I2c4ClockSelection = RCC_I2C4CLKSOURCE_PLL3;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
@@ -250,8 +261,20 @@ void MPU_Config(void) MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
+
+ /** Initializes and configures the Region and the memory to be protected
+ */
+ MPU_InitStruct.Number = MPU_REGION_NUMBER1;
+ MPU_InitStruct.BaseAddress = 0x24000000 ;
+ MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
+ MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
+ MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
+ MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
+
+ HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
+
}
/**
@@ -262,7 +285,6 @@ void Error_Handler(void) {
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
- __disable_irq();
while (1)
{
}
diff --git a/Core/Src/sai.c b/Core/Src/sai.c index 9bd58d9..9601fc8 100755 --- a/Core/Src/sai.c +++ b/Core/Src/sai.c @@ -27,6 +27,8 @@ SAI_HandleTypeDef hsai_BlockA1;
SAI_HandleTypeDef hsai_BlockB1;
+DMA_HandleTypeDef hdma_sai1_b;
+DMA_HandleTypeDef hdma_sai1_a;
/* SAI1 init function */
void MX_SAI1_Init(void)
@@ -51,7 +53,7 @@ void MX_SAI1_Init(void) hsai_BlockA1.Init.NoDivider = SAI_MCK_OVERSAMPLING_DISABLE;
hsai_BlockA1.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
- hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_192K;
+ hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_48K;
hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
@@ -104,10 +106,31 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* saiHandle) GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SAI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+ /* Peripheral DMA init*/
+
+ hdma_sai1_a.Instance = DMA1_Stream1;
+ hdma_sai1_a.Init.Request = DMA_REQUEST_SAI1_A;
+ hdma_sai1_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_sai1_a.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai1_a.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai1_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_sai1_a.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_sai1_a.Init.Mode = DMA_CIRCULAR;
+ hdma_sai1_a.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai1_a.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ if (HAL_DMA_Init(&hdma_sai1_a) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /* Several peripheral DMA handle pointers point to the same DMA handle.
+ Be aware that there is only one channel to perform all the requested DMAs. */
+ __HAL_LINKDMA(saiHandle,hdmarx,hdma_sai1_a);
+ __HAL_LINKDMA(saiHandle,hdmatx,hdma_sai1_a);
}
if(saiHandle->Instance==SAI1_Block_B)
{
@@ -124,10 +147,31 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* saiHandle) GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SAI1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+ /* Peripheral DMA init*/
+
+ hdma_sai1_b.Instance = DMA1_Stream0;
+ hdma_sai1_b.Init.Request = DMA_REQUEST_SAI1_B;
+ hdma_sai1_b.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_sai1_b.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai1_b.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai1_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_sai1_b.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_sai1_b.Init.Mode = DMA_CIRCULAR;
+ hdma_sai1_b.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai1_b.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ if (HAL_DMA_Init(&hdma_sai1_b) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /* Several peripheral DMA handle pointers point to the same DMA handle.
+ Be aware that there is only one channel to perform all the requested DMAs. */
+ __HAL_LINKDMA(saiHandle,hdmarx,hdma_sai1_b);
+ __HAL_LINKDMA(saiHandle,hdmatx,hdma_sai1_b);
}
}
@@ -152,6 +196,8 @@ void HAL_SAI_MspDeInit(SAI_HandleTypeDef* saiHandle) */
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
+ HAL_DMA_DeInit(saiHandle->hdmarx);
+ HAL_DMA_DeInit(saiHandle->hdmatx);
}
if(saiHandle->Instance==SAI1_Block_B)
{
@@ -167,6 +213,8 @@ void HAL_SAI_MspDeInit(SAI_HandleTypeDef* saiHandle) */
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3);
+ HAL_DMA_DeInit(saiHandle->hdmarx);
+ HAL_DMA_DeInit(saiHandle->hdmatx);
}
}
diff --git a/Core/Src/stm32h7xx_it.c b/Core/Src/stm32h7xx_it.c index c4cb071..044e2b2 100755 --- a/Core/Src/stm32h7xx_it.c +++ b/Core/Src/stm32h7xx_it.c @@ -56,6 +56,8 @@ /* External variables --------------------------------------------------------*/
extern PCD_HandleTypeDef hpcd_USB_OTG_HS;
+extern DMA_HandleTypeDef hdma_sai1_b;
+extern DMA_HandleTypeDef hdma_sai1_a;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@@ -199,6 +201,34 @@ void SysTick_Handler(void) /******************************************************************************/
/**
+ * @brief This function handles DMA1 stream0 global interrupt.
+ */
+void DMA1_Stream0_IRQHandler(void)
+{
+ /* USER CODE BEGIN DMA1_Stream0_IRQn 0 */
+
+ /* USER CODE END DMA1_Stream0_IRQn 0 */
+ HAL_DMA_IRQHandler(&hdma_sai1_b);
+ /* USER CODE BEGIN DMA1_Stream0_IRQn 1 */
+
+ /* USER CODE END DMA1_Stream0_IRQn 1 */
+}
+
+/**
+ * @brief This function handles DMA1 stream1 global interrupt.
+ */
+void DMA1_Stream1_IRQHandler(void)
+{
+ /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */
+
+ /* USER CODE END DMA1_Stream1_IRQn 0 */
+ HAL_DMA_IRQHandler(&hdma_sai1_a);
+ /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */
+
+ /* USER CODE END DMA1_Stream1_IRQn 1 */
+}
+
+/**
* @brief This function handles USB On The Go HS End Point 1 Out global interrupt.
*/
void OTG_HS_EP1_OUT_IRQHandler(void)
@@ -1,2 +1,2 @@ -Note: Application will not work and get stuck in Reset_Handler with XIP when compiled with no optimization. Ensure you use -Os or -O2.
-QUADSPI should not be reinitalized. Only configure it in STM32CubeMX so the clocks are the same and comment out MX_QUADSPI_Init.
+Note: Application will not work and get stuck in Reset_Handler with XiP when compiled with no optimization. Ensure you use -Os or -O2.
+QUADSPI should not be reinitalized. Only configure it in STM32CubeMX so the clocks are the same and comment out MX_QUADSPI_Init.
\ No newline at end of file diff --git a/STM32H750ZBTX_FLASH.ld b/STM32H750ZBTX_FLASH.ld index 9645a88..972ca74 100755 --- a/STM32H750ZBTX_FLASH.ld +++ b/STM32H750ZBTX_FLASH.ld @@ -175,6 +175,16 @@ SECTIONS } .ARM.attributes 0 : { *(.ARM.attributes) } + + .audio_buffers (NOLOAD): + { + . = ALIGN(32); + _saudio_buffers = .; + *(.audio_buffers) + *(.audio_buffers*) + . = ALIGN(32); + _eaudio_buffers = .; + } >RAM_D1 } @@ -2,20 +2,65 @@ CAD.formats=
CAD.pinconfig=
CAD.provider=
+CORTEX_M7.AccessPermission_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=MPU_REGION_FULL_ACCESS
CORTEX_M7.AccessPermission_Spec=MPU_REGION_FULL_ACCESS
+CORTEX_M7.BaseAddress_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=0x24000000
CORTEX_M7.BaseAddress_Spec=0x90000000
CORTEX_M7.CPU_DCache=Enabled
CORTEX_M7.CPU_ICache=Enabled
+CORTEX_M7.DisableExec_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=MPU_INSTRUCTION_ACCESS_ENABLE
CORTEX_M7.DisableExec_Spec=MPU_INSTRUCTION_ACCESS_ENABLE
-CORTEX_M7.Enable_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=__NULL
-CORTEX_M7.IPParameters=default_mode_Activation,BaseAddress_Spec,Size_Spec,SubRegionDisable_Spec,AccessPermission_Spec,IsShareable_Spec,IsCacheable_Spec,IsBufferable_Spec,CPU_DCache,CPU_ICache,Enable_S-Cortex_Memory_Protection_Unit_Region1_Settings_S,DisableExec_Spec,TypeExtField_Spec
+CORTEX_M7.Enable_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=MPU_REGION_ENABLE
+CORTEX_M7.IPParameters=default_mode_Activation,BaseAddress_Spec,Size_Spec,SubRegionDisable_Spec,AccessPermission_Spec,IsShareable_Spec,IsCacheable_Spec,IsBufferable_Spec,CPU_DCache,CPU_ICache,Enable_S-Cortex_Memory_Protection_Unit_Region1_Settings_S,DisableExec_Spec,TypeExtField_Spec,BaseAddress_S-Cortex_Memory_Protection_Unit_Region1_Settings_S,Size_S-Cortex_Memory_Protection_Unit_Region1_Settings_S,TypeExtField_S-Cortex_Memory_Protection_Unit_Region1_Settings_S,AccessPermission_S-Cortex_Memory_Protection_Unit_Region1_Settings_S,DisableExec_S-Cortex_Memory_Protection_Unit_Region1_Settings_S,IsShareable_S-Cortex_Memory_Protection_Unit_Region1_Settings_S
CORTEX_M7.IsBufferable_Spec=MPU_ACCESS_BUFFERABLE
CORTEX_M7.IsCacheable_Spec=MPU_ACCESS_CACHEABLE
+CORTEX_M7.IsShareable_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=MPU_ACCESS_SHAREABLE
CORTEX_M7.IsShareable_Spec=MPU_ACCESS_NOT_SHAREABLE
+CORTEX_M7.Size_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=MPU_REGION_SIZE_512KB
CORTEX_M7.Size_Spec=MPU_REGION_SIZE_16MB
CORTEX_M7.SubRegionDisable_Spec=0x0
+CORTEX_M7.TypeExtField_S-Cortex_Memory_Protection_Unit_Region1_Settings_S=MPU_TEX_LEVEL1
CORTEX_M7.TypeExtField_Spec=MPU_TEX_LEVEL1
CORTEX_M7.default_mode_Activation=1
+Dma.Request0=SAI1_B
+Dma.Request1=SAI1_A
+Dma.RequestsNb=2
+Dma.SAI1_A.1.Direction=DMA_MEMORY_TO_PERIPH
+Dma.SAI1_A.1.EventEnable=DISABLE
+Dma.SAI1_A.1.FIFOMode=DMA_FIFOMODE_DISABLE
+Dma.SAI1_A.1.Instance=DMA1_Stream1
+Dma.SAI1_A.1.MemDataAlignment=DMA_MDATAALIGN_WORD
+Dma.SAI1_A.1.MemInc=DMA_MINC_ENABLE
+Dma.SAI1_A.1.Mode=DMA_CIRCULAR
+Dma.SAI1_A.1.PeriphDataAlignment=DMA_PDATAALIGN_WORD
+Dma.SAI1_A.1.PeriphInc=DMA_PINC_DISABLE
+Dma.SAI1_A.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
+Dma.SAI1_A.1.Priority=DMA_PRIORITY_HIGH
+Dma.SAI1_A.1.RequestNumber=1
+Dma.SAI1_A.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
+Dma.SAI1_A.1.SignalID=NONE
+Dma.SAI1_A.1.SyncEnable=DISABLE
+Dma.SAI1_A.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
+Dma.SAI1_A.1.SyncRequestNumber=1
+Dma.SAI1_A.1.SyncSignalID=NONE
+Dma.SAI1_B.0.Direction=DMA_PERIPH_TO_MEMORY
+Dma.SAI1_B.0.EventEnable=DISABLE
+Dma.SAI1_B.0.FIFOMode=DMA_FIFOMODE_DISABLE
+Dma.SAI1_B.0.Instance=DMA1_Stream0
+Dma.SAI1_B.0.MemDataAlignment=DMA_MDATAALIGN_WORD
+Dma.SAI1_B.0.MemInc=DMA_MINC_ENABLE
+Dma.SAI1_B.0.Mode=DMA_CIRCULAR
+Dma.SAI1_B.0.PeriphDataAlignment=DMA_PDATAALIGN_WORD
+Dma.SAI1_B.0.PeriphInc=DMA_PINC_DISABLE
+Dma.SAI1_B.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
+Dma.SAI1_B.0.Priority=DMA_PRIORITY_HIGH
+Dma.SAI1_B.0.RequestNumber=1
+Dma.SAI1_B.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
+Dma.SAI1_B.0.SignalID=NONE
+Dma.SAI1_B.0.SyncEnable=DISABLE
+Dma.SAI1_B.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
+Dma.SAI1_B.0.SyncRequestNumber=1
+Dma.SAI1_B.0.SyncSignalID=NONE
FMC.CASLatency1=FMC_SDRAM_CAS_LATENCY_2
FMC.ColumnBitsNumber1=FMC_SDRAM_COLUMN_BITS_NUM_9
FMC.ExitSelfRefreshDelay1=12
@@ -33,8 +78,9 @@ FMC.SDClockPeriod2=FMC_SDRAM_CLOCK_PERIOD_2 File.Version=6
GPIO.groupedBy=Group By Peripherals
I2C4.I2C_Speed_Mode=I2C_Standard
-I2C4.IPParameters=Timing,I2C_Speed_Mode
-I2C4.Timing=0x00201E2D
+I2C4.IPParameters=I2C_Speed_Mode,Speed,Timing
+I2C4.Speed=100
+I2C4.Timing=0x307075B1
KeepUserPlacement=false
MMTAppRegionsCount=0
MMTConfigApplied=false
@@ -43,17 +89,18 @@ Mcu.CPN=STM32H750ZBT6 Mcu.Family=STM32H7
Mcu.IP0=CORTEX_M7
Mcu.IP1=DEBUG
-Mcu.IP10=USB_DEVICE
-Mcu.IP11=USB_OTG_HS
-Mcu.IP2=FMC
-Mcu.IP3=I2C4
-Mcu.IP4=MEMORYMAP
-Mcu.IP5=NVIC
-Mcu.IP6=QUADSPI
-Mcu.IP7=RCC
-Mcu.IP8=SAI1
-Mcu.IP9=SYS
-Mcu.IPNb=12
+Mcu.IP10=SYS
+Mcu.IP11=USB_DEVICE
+Mcu.IP12=USB_OTG_HS
+Mcu.IP2=DMA
+Mcu.IP3=FMC
+Mcu.IP4=I2C4
+Mcu.IP5=MEMORYMAP
+Mcu.IP6=NVIC
+Mcu.IP7=QUADSPI
+Mcu.IP8=RCC
+Mcu.IP9=SAI1
+Mcu.IPNb=13
Mcu.Name=STM32H750ZBTx
Mcu.Package=LQFP144
Mcu.Pin0=PE2
@@ -153,6 +200,8 @@ Mcu.UserName=STM32H750ZBTx MxCube.Version=6.17.0
MxDb.Version=DB.6.0.170
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.DMA1_Stream0_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
+NVIC.DMA1_Stream1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
@@ -286,14 +335,29 @@ PE12.Signal=FMC_D9_DA9 PE13.Signal=FMC_D10_DA10
PE14.Signal=FMC_D11_DA11
PE15.Signal=FMC_D12_DA12
+PE2.GPIOParameters=GPIO_Speed,GPIO_Mode
+PE2.GPIO_Mode=GPIO_MODE_AF_PP
+PE2.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PE2.Mode=SAI_A_MasterWithClock
PE2.Signal=SAI1_MCLK_A
+PE3.GPIOParameters=GPIO_Speed,GPIO_Mode
+PE3.GPIO_Mode=GPIO_MODE_AF_PP
+PE3.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PE3.Mode=SAI_B_SyncSlave
PE3.Signal=SAI1_SD_B
+PE4.GPIOParameters=GPIO_Speed,GPIO_Mode
+PE4.GPIO_Mode=GPIO_MODE_AF_PP
+PE4.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PE4.Mode=SAI_A_MasterWithClock
PE4.Signal=SAI1_FS_A
+PE5.GPIOParameters=GPIO_Speed,GPIO_Mode
+PE5.GPIO_Mode=GPIO_MODE_AF_PP
+PE5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PE5.Mode=SAI_A_MasterWithClock
PE5.Signal=SAI1_SCK_A
+PE6.GPIOParameters=GPIO_Speed,GPIO_Mode
+PE6.GPIO_Mode=GPIO_MODE_AF_PP
+PE6.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PE6.Mode=SAI_A_MasterWithClock
PE6.Signal=SAI1_SD_A
PE7.Signal=FMC_D4_DA4
@@ -368,7 +432,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_FMC_Init-FMC-false-HAL-true,4-MX_I2C4_Init-I2C4-false-HAL-true,5-MX_SAI1_Init-SAI1-false-HAL-true,6-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,7-MX_QUADSPI_Init-QUADSPI-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_FMC_Init-FMC-false-HAL-true,5-MX_I2C4_Init-I2C4-false-HAL-true,6-MX_SAI1_Init-SAI1-false-HAL-true,7-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,8-MX_QUADSPI_Init-QUADSPI-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
QUADSPI.ClockPrescaler=2
QUADSPI.FifoThreshold=4
QUADSPI.FlashSize=23
@@ -423,9 +487,8 @@ RCC.HPRE=RCC_HCLK_DIV2 RCC.HRTIMFreq_Value=240000000
RCC.HSE_VALUE=25000000
RCC.I2C123Freq_Value=120000000
-RCC.I2C4CLockSelection=RCC_I2C4CLKSOURCE_PLL3
-RCC.I2C4Freq_Value=8192016.6015625
-RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVM3,DIVN1,DIVN2,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2,DIVR2Freq_Value,DIVR3,DIVR3Freq_Value,FDCANFreq_Value,FMCCLockSelection,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4CLockSelection,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,QSPICLockSelection,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1CLockSelection,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
+RCC.I2C4Freq_Value=120000000
+RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVM3,DIVN1,DIVN2,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2,DIVR2Freq_Value,DIVR3,DIVR3Freq_Value,FDCANFreq_Value,FMCCLockSelection,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,QSPICLockSelection,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1CLockSelection,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
RCC.LPTIM1Freq_Value=120000000
RCC.LPTIM2Freq_Value=120000000
RCC.LPTIM345Freq_Value=120000000
@@ -465,16 +528,20 @@ RCC.VCO3OutputFreq_Value=245760498.046875 RCC.VCOInput1Freq_Value=5000000
RCC.VCOInput2Freq_Value=12500000
RCC.VCOInput3Freq_Value=5000000
+SAI1.AudioFrequency-SAI_A_MasterWithClock=SAI_AUDIO_FREQUENCY_48K
SAI1.BasicDataSize-SAI_A_MasterWithClock=SAI_PROTOCOL_DATASIZE_24BIT
SAI1.BasicDataSize-SAI_B_SyncSlave=SAI_PROTOCOL_DATASIZE_24BIT
-SAI1.ErrorAudioFreq-SAI_A_MasterWithClock=-75.0 %
-SAI1.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,InitProtocol-SAI_A_MasterWithClock,VirtualProtocol-SAI_A_BASIC,Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,InitProtocol-SAI_B_SyncSlave,VirtualProtocol-SAI_B_BASIC,BasicDataSize-SAI_A_MasterWithClock,BasicDataSize-SAI_B_SyncSlave,NoDivider-SAI_A_MasterWithClock
+SAI1.ErrorAudioFreq-SAI_A_MasterWithClock=0.0 %
+SAI1.FIFOThreshold-SAI_A_MasterWithClock=SAI_FIFOTHRESHOLD_EMPTY
+SAI1.FIFOThreshold-SAI_B_SyncSlave=SAI_FIFOTHRESHOLD_EMPTY
+SAI1.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,InitProtocol-SAI_A_MasterWithClock,VirtualProtocol-SAI_A_BASIC,Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,BasicDataSize-SAI_A_MasterWithClock,NoDivider-SAI_A_MasterWithClock,AudioFrequency-SAI_A_MasterWithClock,OutputDrive-SAI_A_MasterWithClock,FIFOThreshold-SAI_A_MasterWithClock,FIFOThreshold-SAI_B_SyncSlave,InitProtocol-SAI_B_SyncSlave,VirtualProtocol-SAI_B_BASIC,BasicDataSize-SAI_B_SyncSlave
SAI1.InitProtocol-SAI_A_MasterWithClock=Enable
SAI1.InitProtocol-SAI_B_SyncSlave=Enable
SAI1.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A
SAI1.Instance-SAI_B_SyncSlave=SAI$Index_Block_B
SAI1.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE
SAI1.NoDivider-SAI_A_MasterWithClock=SAI_MCK_OVERSAMPLING_DISABLE
+SAI1.OutputDrive-SAI_A_MasterWithClock=SAI_OUTPUTDRIVE_DISABLE
SAI1.RealAudioFreq-SAI_A_MasterWithClock=48.0 KHz
SAI1.VirtualMode-SAI_A_MasterWithClock=VM_MASTER
SAI1.VirtualMode-SAI_B_SyncSlave=VM_SLAVE
|
