From b574bb50480f15ec2d50fafb13753930add1a2ec Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:47:32 +0200 Subject: [PATCH 1/8] [STM32F4xx] Change SPI clock selection Update of STM32F4 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_STM32F4/spi_api.c | 273 ++++-------------- 1 file changed, 50 insertions(+), 223 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F4/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F4/spi_api.c index 728583e6eab..f2fae81534f 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F4/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F4/spi_api.c @@ -28,6 +28,7 @@ ******************************************************************************* */ #include "mbed_assert.h" +#include "mbed_error.h" #include "spi_api.h" #if DEVICE_SPI @@ -227,232 +228,58 @@ 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) { -#if defined(TARGET_STM32F401RE) || defined(TARGET_STM32F401VC) || defined(TARGET_STM32F407VG) - // Note: The frequencies are obtained with SPI1 clock = 84 MHz (APB2 clock) - if (hz < 600000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 330 kHz - } else if ((hz >= 600000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 656 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.3 MHz - } else if ((hz >= 2000000) && (hz < 5000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.6 MHz - } else if ((hz >= 5000000) && (hz < 10000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5.25 MHz - } else if ((hz >= 10000000) && (hz < 21000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10.5 MHz - } else if ((hz >= 21000000) && (hz < 42000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 21 MHz - } else { // >= 42000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 42 MHz - } -#elif defined(TARGET_STM32F405RG) - // Note: The frequencies are obtained with SPI1 clock = 48 MHz (APB2 clock) - if (obj->spi == SPI_1) { - if (hz < 375000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 187.5 kHz - } else if ((hz >= 375000) && (hz < 750000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz - } else if ((hz >= 750000) && (hz < 1500000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 0.75 MHz - } else if ((hz >= 1500000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz - } else if ((hz >= 12000000) && (hz < 24000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz - } else { // >= 24000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 MHz - } - // Note: The frequencies are obtained with SPI2/3 clock = 48 MHz (APB1 clock) - } else if ((obj->spi == SPI_2) || (obj->spi == SPI_3)) { - if (hz < 375000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 187.5 kHz - } else if ((hz >= 375000) && (hz < 750000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz - } else if ((hz >= 750000) && (hz < 1500000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 0.75 MHz - } else if ((hz >= 1500000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz - } else if ((hz >= 12000000) && (hz < 24000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz - } else { // >= 24000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 MHz - } - } -#elif defined(TARGET_STM32F411RE) || defined(TARGET_STM32F429ZI) - // Values depend of PCLK2: 100 MHz - if ((obj->spi == SPI_1) || (obj->spi == SPI_4) || (obj->spi == SPI_5)) { - if (hz < 700000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 391 kHz - } else if ((hz >= 700000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 781 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.56 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 3.13 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 6.25 MHz - } else if ((hz >= 12000000) && (hz < 25000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 12.5 MHz - } else if ((hz >= 25000000) && (hz < 50000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 25 MHz - } else { // >= 50000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 50 MHz - } - } - // Values depend of PCLK1: 50 MHz - if ((obj->spi == SPI_2) || (obj->spi == SPI_3)) { - if (hz < 400000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 195 kHz - } else if ((hz >= 400000) && (hz < 700000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 391 kHz - } else if ((hz >= 700000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 781 MHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.56 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3.13 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6.25 MHz - } else if ((hz >= 12000000) && (hz < 25000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12.5 MHz - } else { // >= 25000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 25 MHz - } - } -#elif defined(TARGET_STM32F446RE) - // Values depend of PCLK2: 90 MHz - if ((obj->spi == SPI_1) || (obj->spi == SPI_4)) { - if (hz < 700000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 352 kHz - } else if ((hz >= 700000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 703 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.41 MHz - } else if ((hz >= 3000000) && (hz < 5000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.81 MHz - } else if ((hz >= 5000000) && (hz < 11000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5.63 MHz - } else if ((hz >= 11000000) && (hz < 22000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 11.25 MHz - } else if ((hz >= 22000000) && (hz < 45000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 22.5 MHz - } else { // >= 45000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 45 MHz - } - } - // Values depend of PCLK1: 45 MHz - if ((obj->spi == SPI_2) || (obj->spi == SPI_3)) { - if (hz < 350000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 176 kHz - } else if ((hz >= 350000) && (hz < 700000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 352 kHz - } else if ((hz >= 700000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 703 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.41 MHz - } else if ((hz >= 3000000) && (hz < 5000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2.81 MHz - } else if ((hz >= 5000000) && (hz < 11000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 5.63 MHz - } else if ((hz >= 11000000) && (hz < 22000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 11.25 MHz - } else { // >= 22000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 22.5 MHz - } - } -#elif defined(TARGET_STM32F469NI) - // Values depend of PCLK2: 84 MHz - if ((obj->spi == SPI_1) || (obj->spi == SPI_4)) { - if (hz < 600000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 328 kHz - } else if ((hz >= 600000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 656 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.31 MHz - } else if ((hz >= 2000000) && (hz < 5000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.63 MHz - } else if ((hz >= 5000000) && (hz < 10000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5.25 MHz - } else if ((hz >= 10000000) && (hz < 20000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10.5 MHz - } else if ((hz >= 20000000) && (hz < 40000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 21 MHz - } else { // >= 40000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 42 MHz - } - } - // Values depend of PCLK1: 42 MHz - if ((obj->spi == SPI_2) || (obj->spi == SPI_3)) { - if (hz < 300000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 164 kHz - } else if ((hz >= 300000) && (hz < 600000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 328 kHz - } else if ((hz >= 600000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 656 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.31 MHz - } else if ((hz >= 2000000) && (hz < 5000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2.63 MHz - } else if ((hz >= 5000000) && (hz < 10000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 5.25 MHz - } else if ((hz >= 10000000) && (hz < 20000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 10.5 MHz - } else { // >= 20000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 21 MHz - } - } -#elif defined(TARGET_STM32F410RB) - // Values depend of PCLK2: 100 MHz - if ((obj->spi == SPI_1) || (obj->spi == SPI_5)) { - if (hz < 700000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 391 kHz - } else if ((hz >= 700000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 781 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.56 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 3.13 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 6.25 MHz - } else if ((hz >= 12000000) && (hz < 25000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 12.5 MHz - } else if ((hz >= 25000000) && (hz < 50000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 25 MHz - } else { // >= 50000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 50 MHz - } - } - // Values depend of PCLK1: 50 MHz - if (obj->spi == SPI_2) { - if (hz < 400000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 195 kHz - } else if ((hz >= 400000) && (hz < 700000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 391 kHz - } else if ((hz >= 700000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 781 MHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.56 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3.13 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6.25 MHz - } else if ((hz >= 12000000) && (hz < 25000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12.5 MHz - } else { // >= 25000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 25 MHz - } - } + int spi_hz = 0; + uint8_t prescaler_rank = 0; + + /* Get source clock depending on SPI instance */ + switch ((int)obj->spi) { + case SPI_1: +#if defined SPI4_BASE + case SPI_4: +#endif +#if defined SPI5_BASE + case SPI_5: +#endif +#if defined SPI6_BASE + case SPI_6: +#endif + /* SPI_1, SPI_4, SPI_5 and SPI_6. Source CLK is PCKL2 */ + spi_hz = HAL_RCC_GetPCLK2Freq(); + break; + case SPI_2: +#if defined SPI3_BASE + case SPI_3: #endif + /* SPI_2 and 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); } From 0739d31235c42fe66cbf6f3a5d50ef214d1bf591 Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:47:47 +0200 Subject: [PATCH 2/8] [STM32F0xx] Change SPI clock selection Update of STM32F0 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_STM32F0/spi_api.c | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/spi_api.c index cf055232d43..117a441ded0 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/spi_api.c @@ -28,6 +28,7 @@ ******************************************************************************* */ #include "mbed_assert.h" +#include "mbed_error.h" #include "spi_api.h" #if DEVICE_SPI @@ -168,25 +169,33 @@ 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) { - // Note: The frequencies are obtained with SPI clock = 48 MHz (APB clock) - if (hz < 375000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 188 kHz - } else if ((hz >= 375000) && (hz < 750000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz - } else if ((hz >= 750000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 750 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz - } else if ((hz >= 12000000) && (hz < 24000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz - } else { // >= 24000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 MHz - } + int spi_hz = 0; + uint8_t prescaler_rank = 0; + + /* SPI_1, SPI_2. Source CLK is PCKL1 */ + spi_hz = HAL_RCC_GetPCLK1Freq(); + + /* 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); } From 837cb78b39b684a529e02d750666574855d1c689 Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:49:35 +0200 Subject: [PATCH 3/8] [STM32F1xx] Change SPI clock selection Update of STM32F1 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_STM32F1/spi_api.c | 75 +++++++++---------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F1/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F1/spi_api.c index 90aa5cced23..198c29acb83 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F1/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F1/spi_api.c @@ -28,6 +28,7 @@ ******************************************************************************* */ #include "mbed_assert.h" +#include "mbed_error.h" #include "spi_api.h" #if DEVICE_SPI @@ -168,49 +169,45 @@ 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) { - if (obj->spi == SPI_1) { - // Values depend of PCLK2: 64 MHz if HSI is used, 72 MHz if HSE is used - if (hz < 500000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 281 kHz - } else if ((hz >= 500000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 563 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz - } else if ((hz >= 2000000) && (hz < 4000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz - } else if ((hz >= 4000000) && (hz < 8000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz - } else if ((hz >= 8000000) && (hz < 16000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz - } else if ((hz >= 16000000) && (hz < 32000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz - } else { // >= 32000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 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: + /* SPI_2. Source CLK is PCKL1 */ + spi_hz = HAL_RCC_GetPCLK1Freq(); + break; + default: + error("SPI instance not set"); } - if (obj->spi == SPI_2) { - // Values depend of PCLK1: 32 MHz if HSI is used, 36 MHz if HSE is used - if (hz < 250000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz - } else if ((hz >= 250000) && (hz < 500000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 281 kHz - } else if ((hz >= 500000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 563 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz - } else if ((hz >= 2000000) && (hz < 4000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz - } else if ((hz >= 4000000) && (hz < 8000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz - } else if ((hz >= 8000000) && (hz < 16000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz - } else { // >= 16000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz - } - } + /* 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); } From c87ff7872a188226a15fd35b7fe53b930b67c5d5 Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:51:58 +0200 Subject: [PATCH 4/8] [STM32F3xx] Change SPI clock selection Update of STM32F3 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 Signed-off-by: Erwan GOURIOU --- .../hal/TARGET_STM/TARGET_STM32F3/spi_api.c | 119 +++++++----------- 1 file changed, 43 insertions(+), 76 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/spi_api.c index cb3ccd4e139..d161679292e 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/spi_api.c @@ -28,6 +28,7 @@ ******************************************************************************* */ #include "mbed_assert.h" +#include "mbed_error.h" #include "spi_api.h" #if DEVICE_SPI @@ -195,86 +196,52 @@ 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) { -#if defined(TARGET_STM32F334C8) - // Values depend of APB2CLK : 64 MHz if HSI is used, 72 MHz if HSE is used - if (hz < 500000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 281 kHz - } else if ((hz >= 500000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 563 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz - } else if ((hz >= 2000000) && (hz < 4000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz - } else if ((hz >= 4000000) && (hz < 8000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz - } else if ((hz >= 8000000) && (hz < 16000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz - } else if ((hz >= 16000000) && (hz < 32000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz - } else { // >= 32000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 MHz - } -#elif defined(TARGET_STM32F302R8) - if (hz < 250000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz - } else if ((hz >= 250000) && (hz < 500000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 280 kHz - } else if ((hz >= 500000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 560 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz - } else if ((hz >= 2000000) && (hz < 4000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz - } else if ((hz >= 4000000) && (hz < 8000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz - } else if ((hz >= 8000000) && (hz < 16000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz - } else { // >= 16000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz + int spi_hz = 0; + uint8_t prescaler_rank = 0; + + /* Get source clock depending on SPI instance */ + switch ((int)obj->spi) { +#if defined SPI1_BASE + case SPI_1: + /* SPI_1. Source CLK is PCKL2 */ + spi_hz = HAL_RCC_GetPCLK2Freq(); + break; +#endif +#if defined SPI2_BASE + case SPI_2: +#endif +#if defined SPI3_BASE + case SPI_3: +#endif + /* SPI_2 and SPI_3. Source CLK is PCKL1 */ + spi_hz = HAL_RCC_GetPCLK1Freq(); + break; + default: + error("SPI instance not set"); } -#else - // Values depend of APB1CLK and APB2CLK : 32 MHz if HSI is used, 36 MHz if HSE is used - if (obj->spi == SPI_1) { - if (hz < 500000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 280 kHz - } else if ((hz >= 500000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 560 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz - } else if ((hz >= 2000000) && (hz < 4000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz - } else if ((hz >= 4000000) && (hz < 8000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz - } else if ((hz >= 8000000) && (hz < 16000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz - } else if ((hz >= 16000000) && (hz < 32000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz - } else { // >= 32000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 MHz - } - } else { - if (hz < 250000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz - } else if ((hz >= 250000) && (hz < 500000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 280 kHz - } else if ((hz >= 500000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 560 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz - } else if ((hz >= 2000000) && (hz < 4000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz - } else if ((hz >= 4000000) && (hz < 8000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz - } else if ((hz >= 8000000) && (hz < 16000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz - } else { // >= 16000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz - } - } -#endif + /* 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); } From e8103fbb941fae7570d3b7ecbbdad74623cd2101 Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:55:01 +0200 Subject: [PATCH 5/8] [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 --- .../hal/TARGET_STM/TARGET_STM32F7/spi_api.c | 91 +++++++++---------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c index 10f163a2713..255e03d38d1 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F7/spi_api.c @@ -28,6 +28,7 @@ ******************************************************************************* */ #include "mbed_assert.h" +#include "mbed_error.h" #include "spi_api.h" #if DEVICE_SPI @@ -212,58 +213,50 @@ 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) { - // The frequencies are obtained with: - // - SPI2/SPI3 clock = 54 MHz (APB1 clock) - // - SPI1/SPI4/SPI5/SPI6 clocks = 108 MHz (APB2 clock) - switch(obj->spi) { - case SPI_1: - case SPI_4: - case SPI_5: - case SPI_6: - if (hz < 800000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 422 kHz - } else if ((hz >= 800000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 844 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.69 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 3.38 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 6.75 MHz - } else if ((hz >= 12000000) && (hz < 24000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 13.5 MHz - } else if ((hz >= 24000000) && (hz < 54000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 27 MHz - } else { // >= 54000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 54 MHz - } - break; - case SPI_2: - case SPI_3: - if (hz < 400000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 211 kHz - } else if ((hz >= 400000) && (hz < 800000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 422 kHz - } else if ((hz >= 800000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 844 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.69 MHz - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3.38 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6.75 MHz - } else if ((hz >= 12000000) && (hz < 24000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 13.5 MHz - } else { // >= 24000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 27 MHz - } - break; - default: - return; + int spi_hz = 0; + uint8_t prescaler_rank = 0; + + /* Get source clock depending on SPI instance */ + switch ((int)obj->spi) { + case SPI_1: + case SPI_4: + case SPI_5: + case SPI_6: + /* SPI_1, SPI_4, SPI_5 and SPI_6. Source CLK is PCKL2 */ + spi_hz = HAL_RCC_GetPCLK2Freq(); + break; + case SPI_2: + case SPI_3: + /* SPI_2 and 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); } From b126d345d16f8dd98a10793f5376f9f379ae7218 Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:57:55 +0200 Subject: [PATCH 6/8] [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 --- .../hal/TARGET_STM/TARGET_STM32L0/spi_api.c | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32L0/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32L0/spi_api.c index c223e8649ad..bbd0838a1fb 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32L0/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32L0/spi_api.c @@ -28,6 +28,7 @@ ******************************************************************************* */ #include "mbed_assert.h" +#include "mbed_error.h" #include "spi_api.h" #if DEVICE_SPI @@ -176,27 +177,48 @@ 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) { - // Note: The frequencies are obtained with SPI1 clock = 32 MHz (APB2 clock) - 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 + 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; +#if defined(SPI2_BASE) + case SPI_2: + /* SPI_2. Source CLK is PCKL1 */ + spi_hz = HAL_RCC_GetPCLK1Freq(); + break; +#endif + 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); } From 67e6f729c74dfc6face1d11a47276448bad5baca Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:59:17 +0200 Subject: [PATCH 7/8] [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 a0429ac21d1..e312af1e4c7 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); } From bc086319315c4bf74352ddbee848863c47d67fe1 Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 16:04:15 +0200 Subject: [PATCH 8/8] [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 --- .../hal/TARGET_STM/TARGET_STM32L4/spi_api.c | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32L4/spi_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32L4/spi_api.c index 38fd01996bf..bf3a26ad3ff 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32L4/spi_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32L4/spi_api.c @@ -187,47 +187,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: 80 MHz if MSI or HSI is used, 48 MHz if HSE is used - if (SystemCoreClock == 80000000) { // MSI or HSI - if (hz < 600000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 313 kHz - } else if ((hz >= 600000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 625 kHz - } else if ((hz >= 1000000) && (hz < 2000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.25 MHz (default) - } else if ((hz >= 2000000) && (hz < 5000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.5 MHz - } else if ((hz >= 5000000) && (hz < 10000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5 MHz - } else if ((hz >= 10000000) && (hz < 20000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10 MHz - } else if ((hz >= 20000000) && (hz < 40000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 20 MHz - } else { // >= 40000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 40 MHz - } - } else { // 48 MHz - HSE - if (hz < 350000) { - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 188 kHz - } else if ((hz >= 350000) && (hz < 750000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz - } else if ((hz >= 750000) && (hz < 1000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 750 kHz - } else if ((hz >= 1000000) && (hz < 3000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz (default) - } else if ((hz >= 3000000) && (hz < 6000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz - } else if ((hz >= 6000000) && (hz < 12000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz - } else if ((hz >= 12000000) && (hz < 24000000)) { - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz - } else { // >= 24000000 - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 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); }