Skip to content

Commit c44ef02

Browse files
committed
Configure MCK_DIV according sampling frequency with fixed decimation factor
1 parent 0577728 commit c44ef02

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

libraries/PDM/src/stm32/audio.c

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ static PDM_Filter_Config_t PDM_FilterConfig[2];
2929
#define DMA_XFER_NONE (0x00U)
3030
#define DMA_XFER_HALF (0x01U)
3131
#define DMA_XFER_FULL (0x04U)
32+
33+
#define AUDIO_FREQUENCY_192K ((uint32_t)192000)
34+
#define AUDIO_FREQUENCY_96K ((uint32_t)96000)
35+
#define AUDIO_FREQUENCY_64K ((uint32_t)64000)
36+
#define AUDIO_FREQUENCY_48K ((uint32_t)48000)
37+
#define AUDIO_FREQUENCY_44K ((uint32_t)44100)
38+
#define AUDIO_FREQUENCY_32K ((uint32_t)32000)
39+
#define AUDIO_FREQUENCY_22K ((uint32_t)22050)
40+
#define AUDIO_FREQUENCY_16K ((uint32_t)16000)
41+
#define AUDIO_FREQUENCY_11K ((uint32_t)11025)
42+
#define AUDIO_FREQUENCY_8K ((uint32_t)8000)
43+
44+
3245
static volatile uint32_t xfer_status = 0;
3346

3447
// BDMA can only access D3 SRAM4 memory.
@@ -70,15 +83,21 @@ static uint32_t get_decimation_factor(uint32_t decimation)
7083
}
7184
}
7285

73-
#define AUDIO_FREQUENCY_192K ((uint32_t)192000)
74-
#define AUDIO_FREQUENCY_96K ((uint32_t)96000)
75-
#define AUDIO_FREQUENCY_48K ((uint32_t)48000)
76-
#define AUDIO_FREQUENCY_44K ((uint32_t)44100)
77-
#define AUDIO_FREQUENCY_32K ((uint32_t)32000)
78-
#define AUDIO_FREQUENCY_22K ((uint32_t)22050)
79-
#define AUDIO_FREQUENCY_16K ((uint32_t)16000)
80-
#define AUDIO_FREQUENCY_11K ((uint32_t)11025)
81-
#define AUDIO_FREQUENCY_8K ((uint32_t)8000)
86+
87+
static uint8_t get_mck_div(uint32_t frequency)
88+
{
89+
switch(frequency){
90+
case AUDIO_FREQUENCY_8K: return 48; //SCK_x = sai_x_ker_ck/48 = 1024KHz Ffs = SCK_x/64 = 16KHz stereo
91+
case AUDIO_FREQUENCY_16K: return 24; //SCK_x = sai_x_ker_ck/24 = 2048KHz Ffs = SCK_x/64 = 32KHz stereo
92+
case AUDIO_FREQUENCY_32K: return 12; //SCK_x = sai_x_ker_ck/12 = 4096KHz Ffs = SCK_x/64 = 64KHz stereo
93+
case AUDIO_FREQUENCY_48K: return 8; //SCK_x = sai_x_ker_ck/8 = 6144KHz Ffs = SCK_x/64 = 96KHz stereo
94+
case AUDIO_FREQUENCY_64K: return 6; //SCK_x = sai_x_ker_ck/6 = 8192KHz Ffs = SCK_x/64 = 128KHz stereo
95+
case AUDIO_FREQUENCY_96K: return 4; //SCK_x = sai_x_ker_ck/4 = 12288KHz Ffs = SCK_x/64 = 192KHz stereo
96+
case AUDIO_FREQUENCY_192K: return 2; //SCK_x = sai_x_ker_ck/2 = 24576KHz Ffs = SCK_x/64 = 384KHz stereo
97+
default: return 0; //Same as 1
98+
}
99+
}
100+
82101

83102
// TODO: this needs to become a library function
84103
bool isBoardRev2() {
@@ -124,30 +143,34 @@ int py_audio_init(size_t g_channels, uint32_t frequency, int gain_db, float high
124143
/* SAI clock config:
125144
PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
126145
PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
127-
SAI_CLK_x = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
128-
rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
129-
rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
146+
sai_x_ker_ck = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
147+
rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
148+
rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
130149
rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
131150
rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
132151
rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
133152
rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
134-
rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
135-
rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
136-
rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
153+
rcc_ex_clk_init_struct.PLL2.PLL2M = isBoardRev2() ? 25 : 27;
154+
137155
HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
138156

139157
sai_init();
140158

141159
// Sanity checks
142-
if (frequency < 16000 || frequency > 128000) {
160+
if ((frequency != AUDIO_FREQUENCY_8K) &&
161+
(frequency != AUDIO_FREQUENCY_16K) &&
162+
(frequency != AUDIO_FREQUENCY_32K) &&
163+
(frequency != AUDIO_FREQUENCY_48K) &&
164+
(frequency != AUDIO_FREQUENCY_64K) &&
165+
(frequency != AUDIO_FREQUENCY_96K)){
143166
return 0;
144167
}
145168

146169
if (g_channels != 1 && g_channels != 2) {
147170
return 0;
148171
}
149172

150-
uint32_t decimation_factor = AUDIO_SAI_FREQKHZ / (frequency / 1000);
173+
uint32_t decimation_factor = 64; // Fixed decimation factor
151174
uint32_t decimation_factor_const = get_decimation_factor(decimation_factor);
152175
if (decimation_factor_const == 0) {
153176
return 0;
@@ -171,8 +194,8 @@ int py_audio_init(size_t g_channels, uint32_t frequency, int gain_db, float high
171194
hsai.Init.TriState = SAI_OUTPUT_RELEASED;
172195

173196
// The master clock output (MCLK_x) is disabled and the SAI clock
174-
// is passed out to SCK_x bit clock. SCKx frequency = SAI_KER_CK / MCKDIV / 2
175-
hsai.Init.Mckdiv = AUDIO_SAI_MCKDIV; //2.048MHz
197+
// is passed out to SCK_x bit clock. SCKx frequency = SAI_KER_CK / MCKDIV
198+
hsai.Init.Mckdiv = get_mck_div(frequency);
176199
hsai.Init.MckOutput = SAI_MCK_OUTPUT_DISABLE;
177200
hsai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
178201

@@ -314,7 +337,7 @@ void py_audio_start_streaming()
314337

315338
// Start DMA transfer
316339
if (HAL_SAI_Receive_DMA(&hsai, (uint8_t*) PDM_BUFFER, PDM_BUFFER_SIZE / g_channels) != HAL_OK) {
317-
340+
318341
}
319342
}
320343

0 commit comments

Comments
 (0)