[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 <frq07517@st.com>
pull/2013/head
Erwan GOURIOU 2016-06-22 14:51:58 +02:00
parent 837cb78b39
commit c87ff7872a
1 changed files with 43 additions and 76 deletions

View File

@ -28,6 +28,7 @@
******************************************************************************* *******************************************************************************
*/ */
#include "mbed_assert.h" #include "mbed_assert.h"
#include "mbed_error.h"
#include "spi_api.h" #include "spi_api.h"
#if DEVICE_SPI #if DEVICE_SPI
@ -195,86 +196,52 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
init_spi(obj); 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) void spi_frequency(spi_t *obj, int hz)
{ {
#if defined(TARGET_STM32F334C8) int spi_hz = 0;
// Values depend of APB2CLK : 64 MHz if HSI is used, 72 MHz if HSE is used uint8_t prescaler_rank = 0;
if (hz < 500000) {
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 281 kHz /* Get source clock depending on SPI instance */
} else if ((hz >= 500000) && (hz < 1000000)) { switch ((int)obj->spi) {
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 563 kHz #if defined SPI1_BASE
} else if ((hz >= 1000000) && (hz < 2000000)) { case SPI_1:
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz /* SPI_1. Source CLK is PCKL2 */
} else if ((hz >= 2000000) && (hz < 4000000)) { spi_hz = HAL_RCC_GetPCLK2Freq();
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz break;
} else if ((hz >= 4000000) && (hz < 8000000)) { #endif
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz #if defined SPI2_BASE
} else if ((hz >= 8000000) && (hz < 16000000)) { case SPI_2:
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz #endif
} else if ((hz >= 16000000) && (hz < 32000000)) { #if defined SPI3_BASE
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz case SPI_3:
} else { // >= 32000000 #endif
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 MHz /* SPI_2 and SPI_3. Source CLK is PCKL1 */
} spi_hz = HAL_RCC_GetPCLK1Freq();
#elif defined(TARGET_STM32F302R8) break;
if (hz < 250000) { default:
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz error("SPI instance not set");
} 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
} }
#else /* Define pre-scaler in order to get highest available frequency below requested frequency */
// Values depend of APB1CLK and APB2CLK : 32 MHz if HSI is used, 36 MHz if HSE is used while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){
if (obj->spi == SPI_1) { spi_hz = spi_hz / 2;
if (hz < 500000) { prescaler_rank++;
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 if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) {
} else if ((hz >= 1000000) && (hz < 2000000)) { obj->br_presc = baudrate_prescaler_table[prescaler_rank-1];
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz } else {
} else if ((hz >= 2000000) && (hz < 4000000)) { error("Couldn't setup requested SPI frequency");
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
init_spi(obj); init_spi(obj);
} }