Skip to content

Commit bc08631

Browse files
author
Erwan GOURIOU
committed
[STM32L4xx] Change SPI clock selection
Update of STM32L4 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 67e6f72 commit bc08631

File tree

1 file changed

+37
-37
lines changed
  • hal/targets/hal/TARGET_STM/TARGET_STM32L4

1 file changed

+37
-37
lines changed

hal/targets/hal/TARGET_STM/TARGET_STM32L4/spi_api.c

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -187,47 +187,47 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
187187
init_spi(obj);
188188
}
189189

190+
static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2,
191+
SPI_BAUDRATEPRESCALER_4,
192+
SPI_BAUDRATEPRESCALER_8,
193+
SPI_BAUDRATEPRESCALER_16,
194+
SPI_BAUDRATEPRESCALER_32,
195+
SPI_BAUDRATEPRESCALER_64,
196+
SPI_BAUDRATEPRESCALER_128,
197+
SPI_BAUDRATEPRESCALER_256};
198+
190199
void spi_frequency(spi_t *obj, int hz)
191200
{
192-
// Values depend of PCLK1 and PCLK2: 80 MHz if MSI or HSI is used, 48 MHz if HSE is used
193-
if (SystemCoreClock == 80000000) { // MSI or HSI
194-
if (hz < 600000) {
195-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 313 kHz
196-
} else if ((hz >= 600000) && (hz < 1000000)) {
197-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 625 kHz
198-
} else if ((hz >= 1000000) && (hz < 2000000)) {
199-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.25 MHz (default)
200-
} else if ((hz >= 2000000) && (hz < 5000000)) {
201-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.5 MHz
202-
} else if ((hz >= 5000000) && (hz < 10000000)) {
203-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5 MHz
204-
} else if ((hz >= 10000000) && (hz < 20000000)) {
205-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10 MHz
206-
} else if ((hz >= 20000000) && (hz < 40000000)) {
207-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 20 MHz
208-
} else { // >= 40000000
209-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 40 MHz
210-
}
211-
} else { // 48 MHz - HSE
212-
if (hz < 350000) {
213-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 188 kHz
214-
} else if ((hz >= 350000) && (hz < 750000)) {
215-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz
216-
} else if ((hz >= 750000) && (hz < 1000000)) {
217-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 750 kHz
218-
} else if ((hz >= 1000000) && (hz < 3000000)) {
219-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz (default)
220-
} else if ((hz >= 3000000) && (hz < 6000000)) {
221-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz
222-
} else if ((hz >= 6000000) && (hz < 12000000)) {
223-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz
224-
} else if ((hz >= 12000000) && (hz < 24000000)) {
225-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz
226-
} else { // >= 24000000
227-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 MHz
228-
}
201+
int spi_hz = 0;
202+
uint8_t prescaler_rank = 0;
203+
204+
/* Get source clock depending on SPI instance */
205+
switch ((int)obj->spi) {
206+
case SPI_1:
207+
/* SPI_1. Source CLK is PCKL2 */
208+
spi_hz = HAL_RCC_GetPCLK2Freq();
209+
break;
210+
case SPI_2:
211+
case SPI_3:
212+
/* SPI_2, SPI_3. Source CLK is PCKL1 */
213+
spi_hz = HAL_RCC_GetPCLK1Freq();
214+
break;
215+
default:
216+
error("SPI instance not set");
229217
}
230218

219+
/* Define pre-scaler in order to get highest available frequency below requested frequency */
220+
while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){
221+
spi_hz = spi_hz / 2;
222+
prescaler_rank++;
223+
}
224+
225+
if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) {
226+
obj->br_presc = baudrate_prescaler_table[prescaler_rank-1];
227+
} else {
228+
error("Couldn't setup requested SPI frequency");
229+
}
230+
231231
init_spi(obj);
232232
}
233233

0 commit comments

Comments
 (0)