From 67e6f729c74dfc6face1d11a47276448bad5baca Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:59:17 +0200 Subject: [PATCH] [STM32L1xx] Change SPI clock selection Update of STM32L1 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 --- .../hal/TARGET_STM/TARGET_STM32L1/spi_api.c | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32L1/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32L1/spi_api.c index a0429ac21d..e312af1e4c 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32L1/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32L1/spi_api.c @@ -28,6 +28,7 @@ ******************************************************************************* */ #include "mbed_assert.h" +#include "mbed_error.h" #include "spi_api.h" #if DEVICE_SPI @@ -177,46 +178,47 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) init_spi(obj); } +static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, + SPI_BAUDRATEPRESCALER_4, + SPI_BAUDRATEPRESCALER_8, + SPI_BAUDRATEPRESCALER_16, + SPI_BAUDRATEPRESCALER_32, + SPI_BAUDRATEPRESCALER_64, + SPI_BAUDRATEPRESCALER_128, + SPI_BAUDRATEPRESCALER_256}; + void spi_frequency(spi_t *obj, int hz) { - // Values depend of PCLK1 and PCLK2: 32 MHz if HSI is used, 24 MHz if HSE is used - if (SystemCoreClock == 32000000) { // HSI - if (hz < 250000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - } else if ((hz >= 250000) && (hz < 500000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - } else if ((hz >= 500000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - } else if ((hz >= 2000000) && (hz < 4000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - } else if ((hz >= 4000000) && (hz < 8000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - } else if ((hz >= 8000000) && (hz < 16000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - } else { // >= 16000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - } - } else { // 24 MHz - HSE - if (hz < 180000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 94 kHz - } else if ((hz >= 180000) && (hz < 350000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 188 kHz - } else if ((hz >= 350000) && (hz < 750000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 375 kHz - } else if ((hz >= 750000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 750 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 1.5 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 3 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 6 MHz - } else { // >= 12000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 12 MHz - } + int spi_hz = 0; + uint8_t prescaler_rank = 0; + + /* Get source clock depending on SPI instance */ + switch ((int)obj->spi) { + case SPI_1: + /* SPI_1. Source CLK is PCKL2 */ + spi_hz = HAL_RCC_GetPCLK2Freq(); + break; + case SPI_2: + case SPI_3: + /* SPI_2, SPI_3. Source CLK is PCKL1 */ + spi_hz = HAL_RCC_GetPCLK1Freq(); + break; + default: + error("SPI instance not set"); } + + /* Define pre-scaler in order to get highest available frequency below requested frequency */ + while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ + spi_hz = spi_hz / 2; + prescaler_rank++; + } + + if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { + obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; + } else { + error("Couldn't setup requested SPI frequency"); + } + init_spi(obj); }