1 | DMA_HandleTypeDef hdma_sai2_Input;
|
2 | DMA_HandleTypeDef hdma_sai2_Output;
|
3 | static uint32_t SAI2_client =0;
|
4 |
|
5 | void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
|
6 | {
|
7 | GPIO_InitTypeDef GPIO_InitStruct;
|
8 | /* SAI2 */
|
9 | if(hsai->Instance==SAI2_Block_A)
|
10 | {
|
11 | /* Peripheral clock enable */
|
12 | if (SAI2_client == 0)
|
13 | {
|
14 | __HAL_RCC_SAI2_CLK_ENABLE();
|
15 | }
|
16 | SAI2_client ++;
|
17 |
|
18 | /**SAI2_A_Block_A GPIO Configuration
|
19 | PD11 ------> SAI2_SD_A
|
20 | */
|
21 | GPIO_InitStruct.Pin = GPIO_PIN_11;
|
22 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
23 | GPIO_InitStruct.Pull = GPIO_NOPULL;
|
24 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
25 | GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
|
26 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
27 |
|
28 | /* Peripheral DMA init*/
|
29 | hdma_sai2_Input.Instance = DMA2_Stream4;
|
30 | hdma_sai2_Input.Init.Channel = DMA_CHANNEL_3;
|
31 | hdma_sai2_Input.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
32 | hdma_sai2_Input.Init.PeriphInc = DMA_PINC_DISABLE;
|
33 | hdma_sai2_Input.Init.MemInc = DMA_MINC_ENABLE;
|
34 | hdma_sai2_Input.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
35 | hdma_sai2_Input.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
36 | hdma_sai2_Input.Init.Mode = DMA_CIRCULAR;
|
37 | hdma_sai2_Input.Init.Priority = DMA_PRIORITY_HIGH;
|
38 | hdma_sai2_Input.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
39 | hdma_sai2_Input.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
|
40 | hdma_sai2_Input.Init.MemBurst = DMA_MBURST_SINGLE;
|
41 | hdma_sai2_Input.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
42 |
|
43 | if (HAL_DMA_Init(&hdma_sai2_Input) != HAL_OK)
|
44 | {
|
45 | Error_Handler();
|
46 | }
|
47 |
|
48 | /* Several peripheral DMA handle pointers point to the same DMA handle.
|
49 | Be aware that there is only one stream to perform all the requested DMAs. */
|
50 | __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_Input);
|
51 | __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_Input);
|
52 |
|
53 | }
|
54 | if(hsai->Instance==SAI2_Block_B)
|
55 | {
|
56 | /* Peripheral clock enable */
|
57 | if (SAI2_client == 0)
|
58 | {
|
59 | __HAL_RCC_SAI2_CLK_ENABLE();
|
60 | }
|
61 | SAI2_client ++;
|
62 |
|
63 | /**SAI2_B_Block_B GPIO Configuration
|
64 | PC0 ------> SAI2_FS_B
|
65 | PA0/WKUP ------> SAI2_SD_B
|
66 | PE12 ------> SAI2_SCK_B
|
67 | PE14 ------> SAI2_MCLK_B
|
68 | */
|
69 | GPIO_InitStruct.Pin = GPIO_PIN_0;
|
70 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
71 | GPIO_InitStruct.Pull = GPIO_NOPULL;
|
72 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
73 | GPIO_InitStruct.Alternate = GPIO_AF8_SAI2;
|
74 | HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
75 |
|
76 | GPIO_InitStruct.Pin = GPIO_PIN_0;
|
77 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
78 | GPIO_InitStruct.Pull = GPIO_NOPULL;
|
79 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
80 | GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
|
81 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
82 |
|
83 | GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_14;
|
84 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
85 | GPIO_InitStruct.Pull = GPIO_NOPULL;
|
86 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
87 | GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
|
88 | HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
89 |
|
90 | /* Peripheral DMA init*/
|
91 | hdma_sai2_Output.Instance = DMA2_Stream6;
|
92 | hdma_sai2_Output.Init.Channel = DMA_CHANNEL_3;
|
93 | hdma_sai2_Output.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
94 | hdma_sai2_Output.Init.PeriphInc = DMA_PINC_DISABLE;
|
95 | hdma_sai2_Output.Init.MemInc = DMA_MINC_ENABLE;
|
96 | hdma_sai2_Output.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
97 | hdma_sai2_Output.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
98 | hdma_sai2_Output.Init.Mode = DMA_CIRCULAR;
|
99 | hdma_sai2_Output.Init.Priority = DMA_PRIORITY_HIGH;
|
100 | hdma_sai2_Output.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
101 | hdma_sai2_Output.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
|
102 | hdma_sai2_Output.Init.MemBurst = DMA_MBURST_SINGLE;
|
103 | hdma_sai2_Output.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
104 | if (HAL_DMA_Init(&hdma_sai2_Output) != HAL_OK)
|
105 | {
|
106 | Error_Handler();
|
107 | }
|
108 |
|
109 | /* Several peripheral DMA handle pointers point to the same DMA handle.
|
110 | Be aware that there is only one stream to perform all the requested DMAs. */
|
111 | __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_Output);
|
112 | __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_Output);
|
113 | }
|
114 | }
|
115 |
|
116 |
|
117 | static void MX_SAI2_Init(void)
|
118 | {
|
119 | // output
|
120 | hsai_output.Instance = SAI2_Block_B;
|
121 | hsai_output.Init.AudioMode = SAI_MODEMASTER_TX;
|
122 | hsai_output.Init.Synchro = SAI_ASYNCHRONOUS;
|
123 | hsai_output.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
|
124 |
|
125 | hsai_output.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
|
126 | hsai_output.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_FULL;
|
127 | hsai_output.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_8K;
|
128 | hsai_output.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
|
129 | hsai_output.Init.MonoStereoMode = SAI_STEREOMODE;
|
130 | hsai_output.Init.CompandingMode = SAI_NOCOMPANDING;
|
131 | hsai_output.Init.TriState = SAI_OUTPUT_NOTRELEASED;
|
132 |
|
133 | if (HAL_SAI_InitProtocol(&hsai_output, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
|
134 | {
|
135 | Error_Handler();
|
136 | }
|
137 | // input
|
138 | hsai_input.Instance = SAI2_Block_A;
|
139 | hsai_input.Init.AudioMode = SAI_MODESLAVE_RX;
|
140 | hsai_input.Init.Synchro = SAI_SYNCHRONOUS;
|
141 | hsai_input.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
|
142 |
|
143 | // hsai_input.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
|
144 | hsai_input.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_FULL;
|
145 | /// hsai_input.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_8K;
|
146 | hsai_input.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
|
147 | hsai_input.Init.MonoStereoMode = SAI_STEREOMODE;
|
148 | hsai_input.Init.CompandingMode = SAI_NOCOMPANDING;
|
149 | hsai_input.Init.TriState = SAI_OUTPUT_RELEASED;
|
150 |
|
151 | if (HAL_SAI_InitProtocol(&hsai_input, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
|
152 | {
|
153 | Error_Handler();
|
154 | }
|
155 |
|
156 | }
|
157 |
|
158 | static void MX_DMA_Init(void)
|
159 | {
|
160 | /* DMA controller clock enable */
|
161 | __HAL_RCC_DMA2_CLK_ENABLE();
|
162 |
|
163 | /* DMA interrupt init */
|
164 | /* DMA2_Stream4_IRQn interrupt configuration */
|
165 | HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, MEDIA_AL_IRQ_PREPRIO , MEDIA_AL_IRQ_SUBRIO);
|
166 | HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);
|
167 |
|
168 | /* DMA2_Stream6_IRQn interrupt configuration */
|
169 | HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, MEDIA_AL_IRQ_PREPRIO , MEDIA_AL_IRQ_SUBRIO);
|
170 | HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
|
171 | }
|
172 |
|
173 | void DMA2_Stream4_IRQHandler(void)
|
174 | {
|
175 | HAL_DMA_IRQHandler( hsai_input.hdmarx );
|
176 | }
|
177 |
|
178 | void DMA2_Stream6_IRQHandler(void)
|
179 | {
|
180 | HAL_DMA_IRQHandler( hsai_output.hdmatx );
|
181 | }
|
182 |
|
183 | static void Start_Stream( uint8_t* Play, uint8_t* Record, uint32_t Size ){
|
184 | HAL_SAI_Transmit_DMA( &hsai_output, (uint8_t *)Play , Size );
|
185 | HAL_SAI_Receive_DMA( &hsai_input , (uint8_t *)Record , Size );
|
186 | }
|
187 |
|
188 |
|
189 | //PLAYBACK
|
190 | void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
|
191 | {
|
192 | if( hsai->Instance == SAI2_Block_B ){
|
193 | }else if( hsai->Instance == SAI2_Block_A ){
|
194 |
|
195 | }
|
196 | }
|
197 | void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
|
198 | {
|
199 | if( hsai->Instance == SAI2_Block_B ){
|
200 | }else if( hsai->Instance == SAI2_Block_A ){
|
201 |
|
202 | }
|
203 | }
|
204 |
|
205 | //RECORD
|
206 | void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
|
207 | {
|
208 | if( hsai->Instance == SAI2_Block_B ){
|
209 | }else if( hsai->Instance == SAI2_Block_A ){
|
210 | }
|
211 | }
|
212 | void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
|
213 | {
|
214 | if( hsai->Instance == SAI2_Block_B ){
|
215 | }else if( hsai->Instance == SAI2_Block_A ){
|
216 | }
|
217 | }
|
218 |
|
219 | void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
|
220 | {
|
221 | if( hsai->Instance == SAI2_Block_B ){
|
222 | }else if( hsai->Instance == SAI2_Block_A ){
|
223 | }
|
224 | }
|