[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
pull/2013/head
Erwan GOURIOU 2016-06-22 14:57:55 +02:00
parent e8103fbb94
commit b126d345d1
1 changed files with 39 additions and 17 deletions

View File

@ -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);
}