Skip to content

Commit b126d34

Browse files
author
Erwan GOURIOU
committed
[STM32L0xx] Change SPI clock selection
Update of STM32L0 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 e8103fb commit b126d34

File tree

1 file changed

+39
-17
lines changed
  • hal/targets/hal/TARGET_STM/TARGET_STM32L0

1 file changed

+39
-17
lines changed

hal/targets/hal/TARGET_STM/TARGET_STM32L0/spi_api.c

Lines changed: 39 additions & 17 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
@@ -176,27 +177,48 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
176177
init_spi(obj);
177178
}
178179

180+
static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2,
181+
SPI_BAUDRATEPRESCALER_4,
182+
SPI_BAUDRATEPRESCALER_8,
183+
SPI_BAUDRATEPRESCALER_16,
184+
SPI_BAUDRATEPRESCALER_32,
185+
SPI_BAUDRATEPRESCALER_64,
186+
SPI_BAUDRATEPRESCALER_128,
187+
SPI_BAUDRATEPRESCALER_256};
188+
179189
void spi_frequency(spi_t *obj, int hz)
180190
{
181-
// Note: The frequencies are obtained with SPI1 clock = 32 MHz (APB2 clock)
182-
if (hz < 250000) {
183-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz
184-
} else if ((hz >= 250000) && (hz < 500000)) {
185-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz
186-
} else if ((hz >= 500000) && (hz < 1000000)) {
187-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz
188-
} else if ((hz >= 1000000) && (hz < 2000000)) {
189-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz
190-
} else if ((hz >= 2000000) && (hz < 4000000)) {
191-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz
192-
} else if ((hz >= 4000000) && (hz < 8000000)) {
193-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz
194-
} else if ((hz >= 8000000) && (hz < 16000000)) {
195-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz
196-
} else { // >= 16000000
197-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz
191+
int spi_hz = 0;
192+
uint8_t prescaler_rank = 0;
193+
194+
/* Get source clock depending on SPI instance */
195+
switch ((int)obj->spi) {
196+
case SPI_1:
197+
/* SPI_1. Source CLK is PCKL2 */
198+
spi_hz = HAL_RCC_GetPCLK2Freq();
199+
break;
200+
#if defined(SPI2_BASE)
201+
case SPI_2:
202+
/* SPI_2. Source CLK is PCKL1 */
203+
spi_hz = HAL_RCC_GetPCLK1Freq();
204+
break;
205+
#endif
206+
default:
207+
error("SPI instance not set");
198208
}
199209

210+
/* Define pre-scaler in order to get highest available frequency below requested frequency */
211+
while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){
212+
spi_hz = spi_hz / 2;
213+
prescaler_rank++;
214+
}
215+
216+
if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) {
217+
obj->br_presc = baudrate_prescaler_table[prescaler_rank-1];
218+
} else {
219+
error("Couldn't setup requested SPI frequency");
220+
}
221+
200222
init_spi(obj);
201223
}
202224

0 commit comments

Comments
 (0)