Skip to content

Commit e8103fb

Browse files
author
Erwan GOURIOU
committed
[STM32F7xx] Change SPI clock selection
Update of STM32F7 family CPI clock selection algo. Maximum SPI clock is obtained from APB domain clock (based on HAL API). Then algo sets maximum frequency available below requested frequency
1 parent c87ff78 commit e8103fb

File tree

1 file changed

+42
-49
lines changed
  • hal/targets/hal/TARGET_STM/TARGET_STM32F7

1 file changed

+42
-49
lines changed

hal/targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c

Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
*******************************************************************************
2929
*/
3030
#include "mbed_assert.h"
31+
#include "mbed_error.h"
3132
#include "spi_api.h"
3233

3334
#if DEVICE_SPI
@@ -212,58 +213,50 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
212213
init_spi(obj);
213214
}
214215

216+
static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2,
217+
SPI_BAUDRATEPRESCALER_4,
218+
SPI_BAUDRATEPRESCALER_8,
219+
SPI_BAUDRATEPRESCALER_16,
220+
SPI_BAUDRATEPRESCALER_32,
221+
SPI_BAUDRATEPRESCALER_64,
222+
SPI_BAUDRATEPRESCALER_128,
223+
SPI_BAUDRATEPRESCALER_256};
224+
215225
void spi_frequency(spi_t *obj, int hz)
216226
{
217-
// The frequencies are obtained with:
218-
// - SPI2/SPI3 clock = 54 MHz (APB1 clock)
219-
// - SPI1/SPI4/SPI5/SPI6 clocks = 108 MHz (APB2 clock)
220-
switch(obj->spi) {
221-
case SPI_1:
222-
case SPI_4:
223-
case SPI_5:
224-
case SPI_6:
225-
if (hz < 800000) {
226-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 422 kHz
227-
} else if ((hz >= 800000) && (hz < 1000000)) {
228-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 844 kHz
229-
} else if ((hz >= 1000000) && (hz < 3000000)) {
230-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.69 MHz
231-
} else if ((hz >= 3000000) && (hz < 6000000)) {
232-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 3.38 MHz
233-
} else if ((hz >= 6000000) && (hz < 12000000)) {
234-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 6.75 MHz
235-
} else if ((hz >= 12000000) && (hz < 24000000)) {
236-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 13.5 MHz
237-
} else if ((hz >= 24000000) && (hz < 54000000)) {
238-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 27 MHz
239-
} else { // >= 54000000
240-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 54 MHz
241-
}
242-
break;
243-
case SPI_2:
244-
case SPI_3:
245-
if (hz < 400000) {
246-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 211 kHz
247-
} else if ((hz >= 400000) && (hz < 800000)) {
248-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 422 kHz
249-
} else if ((hz >= 800000) && (hz < 1000000)) {
250-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 844 kHz
251-
} else if ((hz >= 1000000) && (hz < 3000000)) {
252-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.69 MHz
253-
} else if ((hz >= 3000000) && (hz < 6000000)) {
254-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3.38 MHz
255-
} else if ((hz >= 6000000) && (hz < 12000000)) {
256-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6.75 MHz
257-
} else if ((hz >= 12000000) && (hz < 24000000)) {
258-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 13.5 MHz
259-
} else { // >= 24000000
260-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 27 MHz
261-
}
262-
break;
263-
default:
264-
return;
227+
int spi_hz = 0;
228+
uint8_t prescaler_rank = 0;
229+
230+
/* Get source clock depending on SPI instance */
231+
switch ((int)obj->spi) {
232+
case SPI_1:
233+
case SPI_4:
234+
case SPI_5:
235+
case SPI_6:
236+
/* SPI_1, SPI_4, SPI_5 and SPI_6. Source CLK is PCKL2 */
237+
spi_hz = HAL_RCC_GetPCLK2Freq();
238+
break;
239+
case SPI_2:
240+
case SPI_3:
241+
/* SPI_2 and SPI_3. Source CLK is PCKL1 */
242+
spi_hz = HAL_RCC_GetPCLK1Freq();
243+
break;
244+
default:
245+
error("SPI instance not set");
265246
}
266-
247+
248+
/* Define pre-scaler in order to get highest available frequency below requested frequency */
249+
while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){
250+
spi_hz = spi_hz / 2;
251+
prescaler_rank++;
252+
}
253+
254+
if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) {
255+
obj->br_presc = baudrate_prescaler_table[prescaler_rank-1];
256+
} else {
257+
error("Couldn't setup requested SPI frequency");
258+
}
259+
267260
init_spi(obj);
268261
}
269262

0 commit comments

Comments
 (0)