
AUDIO loopback with DISCO_H747I
Dependencies: BSP_DISCO_H747I
Building
hg clone https://mbed.org/teams/ST/code/DISCO_H747I_AUDIO_demo
cd DISCO_H747I_AUDIO_demo
mbed deploy
mbed compile -m DISCO_H747I -t <GCC_ARM/ARM/IAR> -f
Running
A single printf is done at main start
Audio is recorded from board micro (U21) next to joystick.
Audio output is the jack connector (CN11) (green one).
Warning
Audio configuration is not compatible with Ethernet HW patch
https://os.mbed.com/teams/ST/wiki/DISCO_H747I-modifications-for-Ethernet
main.cpp@0:78e37c7585e6, 2019-11-07 (annotated)
- Committer:
- Jerome Coutant
- Date:
- Thu Nov 07 11:33:58 2019 +0100
- Revision:
- 0:78e37c7585e6
First commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jerome Coutant
0:78e37c7585e6
|
1
|
#include "mbed.h"
|
|
Jerome Coutant
0:78e37c7585e6
|
2
|
#include "stm32h747i_discovery.h"
|
|
Jerome Coutant
0:78e37c7585e6
|
3
|
#include "stm32h747i_discovery_audio.h"
|
|
Jerome Coutant
0:78e37c7585e6
|
4
|
|
|
Jerome Coutant
0:78e37c7585e6
|
5
|
extern "C" {
|
|
Jerome Coutant
0:78e37c7585e6
|
6
|
|
|
Jerome Coutant
0:78e37c7585e6
|
7
|
/* Audio frequency */
|
|
Jerome Coutant
0:78e37c7585e6
|
8
|
#define AUDIO_FREQUENCY BSP_AUDIO_FREQUENCY_16K
|
|
Jerome Coutant
0:78e37c7585e6
|
9
|
#define AUDIO_IN_PDM_BUFFER_SIZE (uint32_t)(128*AUDIO_FREQUENCY/16000*DEFAULT_AUDIO_IN_CHANNEL_NBR)
|
|
Jerome Coutant
0:78e37c7585e6
|
10
|
|
|
Jerome Coutant
0:78e37c7585e6
|
11
|
/* Size of the recorder buffer */
|
|
Jerome Coutant
0:78e37c7585e6
|
12
|
#define RECORD_BUFFER_SIZE 4096
|
|
Jerome Coutant
0:78e37c7585e6
|
13
|
|
|
Jerome Coutant
0:78e37c7585e6
|
14
|
/* Define record Buf at D3SRAM @0x38000000 since the BDMA for SAI4 use only this memory */
|
|
Jerome Coutant
0:78e37c7585e6
|
15
|
#if defined (TOOLCHAIN_IAR) /* IAR */
|
|
Jerome Coutant
0:78e37c7585e6
|
16
|
/* No need to update linker script */
|
|
Jerome Coutant
0:78e37c7585e6
|
17
|
#pragma location=0x38000000
|
|
Jerome Coutant
0:78e37c7585e6
|
18
|
uint16_t recordPDMBuf[AUDIO_IN_PDM_BUFFER_SIZE];
|
|
Jerome Coutant
0:78e37c7585e6
|
19
|
#else /* GCC_ARM and ARM */
|
|
Jerome Coutant
0:78e37c7585e6
|
20
|
/* Linker scripts need to be updated to add RAM_D3 section */
|
|
Jerome Coutant
0:78e37c7585e6
|
21
|
ALIGN_32BYTES(uint16_t recordPDMBuf[AUDIO_IN_PDM_BUFFER_SIZE]) __attribute__((section(".RAM_D3")));
|
|
Jerome Coutant
0:78e37c7585e6
|
22
|
#endif
|
|
Jerome Coutant
0:78e37c7585e6
|
23
|
|
|
Jerome Coutant
0:78e37c7585e6
|
24
|
uint16_t playbackBuf[RECORD_BUFFER_SIZE * 2];
|
|
Jerome Coutant
0:78e37c7585e6
|
25
|
|
|
Jerome Coutant
0:78e37c7585e6
|
26
|
/* Pointer to record_data */
|
|
Jerome Coutant
0:78e37c7585e6
|
27
|
uint32_t playbackPtr;
|
|
Jerome Coutant
0:78e37c7585e6
|
28
|
|
|
Jerome Coutant
0:78e37c7585e6
|
29
|
extern SAI_HandleTypeDef haudio_out_sai;
|
|
Jerome Coutant
0:78e37c7585e6
|
30
|
extern SAI_HandleTypeDef haudio_in_sai;
|
|
Jerome Coutant
0:78e37c7585e6
|
31
|
|
|
Jerome Coutant
0:78e37c7585e6
|
32
|
|
|
Jerome Coutant
0:78e37c7585e6
|
33
|
/**
|
|
Jerome Coutant
0:78e37c7585e6
|
34
|
* @brief This function handles DMA2 Stream 1 interrupt request.
|
|
Jerome Coutant
0:78e37c7585e6
|
35
|
* @param None
|
|
Jerome Coutant
0:78e37c7585e6
|
36
|
* @retval None
|
|
Jerome Coutant
0:78e37c7585e6
|
37
|
*/
|
|
Jerome Coutant
0:78e37c7585e6
|
38
|
void AUDIO_OUT_SAIx_DMAx_IRQHandler(void)
|
|
Jerome Coutant
0:78e37c7585e6
|
39
|
/* DMA2_Stream1_IRQHandler redefinition in BSP_DISCO_H747I/STM32H747I-Discovery/stm32h747i_discovery_audio.h */
|
|
Jerome Coutant
0:78e37c7585e6
|
40
|
{
|
|
Jerome Coutant
0:78e37c7585e6
|
41
|
HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
|
|
Jerome Coutant
0:78e37c7585e6
|
42
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
43
|
|
|
Jerome Coutant
0:78e37c7585e6
|
44
|
|
|
Jerome Coutant
0:78e37c7585e6
|
45
|
/**
|
|
Jerome Coutant
0:78e37c7585e6
|
46
|
* @brief This function handles BDMA Channel 1 for SAI_PDM interrupt request.
|
|
Jerome Coutant
0:78e37c7585e6
|
47
|
* @param None
|
|
Jerome Coutant
0:78e37c7585e6
|
48
|
* @retval None
|
|
Jerome Coutant
0:78e37c7585e6
|
49
|
*/
|
|
Jerome Coutant
0:78e37c7585e6
|
50
|
void AUDIO_IN_SAI_PDMx_DMAx_IRQHandler(void)
|
|
Jerome Coutant
0:78e37c7585e6
|
51
|
/* BDMA_Channel1_IRQHandler redefinition in BSP_DISCO_H747I/STM32H747I-Discovery/stm32h747i_discovery_audio.h */
|
|
Jerome Coutant
0:78e37c7585e6
|
52
|
{
|
|
Jerome Coutant
0:78e37c7585e6
|
53
|
HAL_DMA_IRQHandler(haudio_in_sai.hdmarx);
|
|
Jerome Coutant
0:78e37c7585e6
|
54
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
55
|
|
|
Jerome Coutant
0:78e37c7585e6
|
56
|
|
|
Jerome Coutant
0:78e37c7585e6
|
57
|
/**
|
|
Jerome Coutant
0:78e37c7585e6
|
58
|
* @brief Calculates the remaining file size and new position of the pointer.
|
|
Jerome Coutant
0:78e37c7585e6
|
59
|
* @param None
|
|
Jerome Coutant
0:78e37c7585e6
|
60
|
* @retval None
|
|
Jerome Coutant
0:78e37c7585e6
|
61
|
*/
|
|
Jerome Coutant
0:78e37c7585e6
|
62
|
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
|
|
Jerome Coutant
0:78e37c7585e6
|
63
|
/* weak empty function in BSP_DISCO_H747I/STM32H747I-Discovery/stm32h747i_discovery_audio.c */
|
|
Jerome Coutant
0:78e37c7585e6
|
64
|
{
|
|
Jerome Coutant
0:78e37c7585e6
|
65
|
if (BSP_AUDIO_IN_GetInterface() == AUDIO_IN_INTERFACE_PDM) {
|
|
Jerome Coutant
0:78e37c7585e6
|
66
|
/* Invalidate Data Cache to get the updated content of the SRAM*/
|
|
Jerome Coutant
0:78e37c7585e6
|
67
|
SCB_InvalidateDCache_by_Addr((uint32_t *)&recordPDMBuf[AUDIO_IN_PDM_BUFFER_SIZE / 2], AUDIO_IN_PDM_BUFFER_SIZE * 2);
|
|
Jerome Coutant
0:78e37c7585e6
|
68
|
|
|
Jerome Coutant
0:78e37c7585e6
|
69
|
BSP_AUDIO_IN_PDMToPCM((uint16_t *)&recordPDMBuf[AUDIO_IN_PDM_BUFFER_SIZE / 2], &playbackBuf[playbackPtr]);
|
|
Jerome Coutant
0:78e37c7585e6
|
70
|
|
|
Jerome Coutant
0:78e37c7585e6
|
71
|
/* Clean Data Cache to update the content of the SRAM */
|
|
Jerome Coutant
0:78e37c7585e6
|
72
|
SCB_CleanDCache_by_Addr((uint32_t *)&playbackBuf[playbackPtr], AUDIO_IN_PDM_BUFFER_SIZE / 4);
|
|
Jerome Coutant
0:78e37c7585e6
|
73
|
|
|
Jerome Coutant
0:78e37c7585e6
|
74
|
playbackPtr += AUDIO_IN_PDM_BUFFER_SIZE / 4 / 2;
|
|
Jerome Coutant
0:78e37c7585e6
|
75
|
if (playbackPtr >= RECORD_BUFFER_SIZE) {
|
|
Jerome Coutant
0:78e37c7585e6
|
76
|
playbackPtr = 0;
|
|
Jerome Coutant
0:78e37c7585e6
|
77
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
78
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
79
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
80
|
|
|
Jerome Coutant
0:78e37c7585e6
|
81
|
|
|
Jerome Coutant
0:78e37c7585e6
|
82
|
/**
|
|
Jerome Coutant
0:78e37c7585e6
|
83
|
* @brief Manages the DMA Half Transfer complete interrupt.
|
|
Jerome Coutant
0:78e37c7585e6
|
84
|
* @param None
|
|
Jerome Coutant
0:78e37c7585e6
|
85
|
* @retval None
|
|
Jerome Coutant
0:78e37c7585e6
|
86
|
*/
|
|
Jerome Coutant
0:78e37c7585e6
|
87
|
void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
|
|
Jerome Coutant
0:78e37c7585e6
|
88
|
/* weak empty function in BSP_DISCO_H747I/STM32H747I-Discovery/stm32h747i_discovery_audio.c */
|
|
Jerome Coutant
0:78e37c7585e6
|
89
|
{
|
|
Jerome Coutant
0:78e37c7585e6
|
90
|
if (BSP_AUDIO_IN_GetInterface() == AUDIO_IN_INTERFACE_PDM) {
|
|
Jerome Coutant
0:78e37c7585e6
|
91
|
/* Invalidate Data Cache to get the updated content of the SRAM*/
|
|
Jerome Coutant
0:78e37c7585e6
|
92
|
SCB_InvalidateDCache_by_Addr((uint32_t *)&recordPDMBuf[0], AUDIO_IN_PDM_BUFFER_SIZE * 2);
|
|
Jerome Coutant
0:78e37c7585e6
|
93
|
|
|
Jerome Coutant
0:78e37c7585e6
|
94
|
BSP_AUDIO_IN_PDMToPCM((uint16_t *)&recordPDMBuf[0], &playbackBuf[playbackPtr]);
|
|
Jerome Coutant
0:78e37c7585e6
|
95
|
|
|
Jerome Coutant
0:78e37c7585e6
|
96
|
/* Clean Data Cache to update the content of the SRAM */
|
|
Jerome Coutant
0:78e37c7585e6
|
97
|
SCB_CleanDCache_by_Addr((uint32_t *)&playbackBuf[playbackPtr], AUDIO_IN_PDM_BUFFER_SIZE / 4);
|
|
Jerome Coutant
0:78e37c7585e6
|
98
|
|
|
Jerome Coutant
0:78e37c7585e6
|
99
|
playbackPtr += AUDIO_IN_PDM_BUFFER_SIZE / 4 / 2;
|
|
Jerome Coutant
0:78e37c7585e6
|
100
|
if (playbackPtr >= RECORD_BUFFER_SIZE) {
|
|
Jerome Coutant
0:78e37c7585e6
|
101
|
playbackPtr = 0;
|
|
Jerome Coutant
0:78e37c7585e6
|
102
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
103
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
104
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
105
|
|
|
Jerome Coutant
0:78e37c7585e6
|
106
|
|
|
Jerome Coutant
0:78e37c7585e6
|
107
|
/**
|
|
Jerome Coutant
0:78e37c7585e6
|
108
|
* @brief Audio IN Error callback function
|
|
Jerome Coutant
0:78e37c7585e6
|
109
|
* @param None
|
|
Jerome Coutant
0:78e37c7585e6
|
110
|
* @retval None
|
|
Jerome Coutant
0:78e37c7585e6
|
111
|
*/
|
|
Jerome Coutant
0:78e37c7585e6
|
112
|
void BSP_AUDIO_IN_Error_CallBack(void)
|
|
Jerome Coutant
0:78e37c7585e6
|
113
|
/* weak empty function in BSP_DISCO_H747I/STM32H747I-Discovery/stm32h747i_discovery_audio.c */
|
|
Jerome Coutant
0:78e37c7585e6
|
114
|
{
|
|
Jerome Coutant
0:78e37c7585e6
|
115
|
MBED_ASSERT(0);
|
|
Jerome Coutant
0:78e37c7585e6
|
116
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
117
|
|
|
Jerome Coutant
0:78e37c7585e6
|
118
|
} // extern C
|
|
Jerome Coutant
0:78e37c7585e6
|
119
|
|
|
Jerome Coutant
0:78e37c7585e6
|
120
|
|
|
Jerome Coutant
0:78e37c7585e6
|
121
|
int main()
|
|
Jerome Coutant
0:78e37c7585e6
|
122
|
{
|
|
Jerome Coutant
0:78e37c7585e6
|
123
|
printf("\n\nAUDIO LOOPBACK EXAMPLE WITH AUDIO PDM FOR DISCO-H747I\n");
|
|
Jerome Coutant
0:78e37c7585e6
|
124
|
|
|
Jerome Coutant
0:78e37c7585e6
|
125
|
/* Set audio input interface */
|
|
Jerome Coutant
0:78e37c7585e6
|
126
|
BSP_AUDIO_IN_SelectInterface(AUDIO_IN_INTERFACE_PDM);
|
|
Jerome Coutant
0:78e37c7585e6
|
127
|
|
|
Jerome Coutant
0:78e37c7585e6
|
128
|
/* Initialize audio IN at REC_FREQ*/
|
|
Jerome Coutant
0:78e37c7585e6
|
129
|
if (BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AUDIO_FREQUENCY, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) != AUDIO_OK) {
|
|
Jerome Coutant
0:78e37c7585e6
|
130
|
/* Record Error */
|
|
Jerome Coutant
0:78e37c7585e6
|
131
|
MBED_ASSERT(0);
|
|
Jerome Coutant
0:78e37c7585e6
|
132
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
133
|
|
|
Jerome Coutant
0:78e37c7585e6
|
134
|
/* Initialize audio OUT at REC_FREQ*/
|
|
Jerome Coutant
0:78e37c7585e6
|
135
|
if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, 50, AUDIO_FREQUENCY) != AUDIO_OK) {
|
|
Jerome Coutant
0:78e37c7585e6
|
136
|
/* Record Error */
|
|
Jerome Coutant
0:78e37c7585e6
|
137
|
MBED_ASSERT(0);
|
|
Jerome Coutant
0:78e37c7585e6
|
138
|
}
|
|
Jerome Coutant
0:78e37c7585e6
|
139
|
|
|
Jerome Coutant
0:78e37c7585e6
|
140
|
/* Set audio slot */
|
|
Jerome Coutant
0:78e37c7585e6
|
141
|
BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
|
|
Jerome Coutant
0:78e37c7585e6
|
142
|
|
|
Jerome Coutant
0:78e37c7585e6
|
143
|
/* Start the record */
|
|
Jerome Coutant
0:78e37c7585e6
|
144
|
BSP_AUDIO_IN_Record((uint16_t *)recordPDMBuf, AUDIO_IN_PDM_BUFFER_SIZE);
|
|
Jerome Coutant
0:78e37c7585e6
|
145
|
|
|
Jerome Coutant
0:78e37c7585e6
|
146
|
wait_us(1000); // 1 ms
|
|
Jerome Coutant
0:78e37c7585e6
|
147
|
|
|
Jerome Coutant
0:78e37c7585e6
|
148
|
/* Start audio output */
|
|
Jerome Coutant
0:78e37c7585e6
|
149
|
BSP_AUDIO_OUT_Play((uint16_t *)playbackBuf, RECORD_BUFFER_SIZE * 2);
|
|
Jerome Coutant
0:78e37c7585e6
|
150
|
}
|
|