From e8103fbb941fae7570d3b7ecbbdad74623cd2101 Mon Sep 17 00:00:00 2001 From: Erwan GOURIOU Date: Wed, 22 Jun 2016 14:55:01 +0200 Subject: [PATCH] [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 10f163a271..255e03d38d 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); }