|
28 | 28 | *******************************************************************************
|
29 | 29 | */
|
30 | 30 | #include "mbed_assert.h"
|
| 31 | +#include "mbed_error.h" |
31 | 32 | #include "spi_api.h"
|
32 | 33 |
|
33 | 34 | #if DEVICE_SPI
|
@@ -176,27 +177,48 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
176 | 177 | init_spi(obj);
|
177 | 178 | }
|
178 | 179 |
|
| 180 | +static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, |
| 181 | + SPI_BAUDRATEPRESCALER_4, |
| 182 | + SPI_BAUDRATEPRESCALER_8, |
| 183 | + SPI_BAUDRATEPRESCALER_16, |
| 184 | + SPI_BAUDRATEPRESCALER_32, |
| 185 | + SPI_BAUDRATEPRESCALER_64, |
| 186 | + SPI_BAUDRATEPRESCALER_128, |
| 187 | + SPI_BAUDRATEPRESCALER_256}; |
| 188 | + |
179 | 189 | void spi_frequency(spi_t *obj, int hz)
|
180 | 190 | {
|
181 |
| - // Note: The frequencies are obtained with SPI1 clock = 32 MHz (APB2 clock) |
182 |
| - if (hz < 250000) { |
183 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz |
184 |
| - } else if ((hz >= 250000) && (hz < 500000)) { |
185 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz |
186 |
| - } else if ((hz >= 500000) && (hz < 1000000)) { |
187 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz |
188 |
| - } else if ((hz >= 1000000) && (hz < 2000000)) { |
189 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz |
190 |
| - } else if ((hz >= 2000000) && (hz < 4000000)) { |
191 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz |
192 |
| - } else if ((hz >= 4000000) && (hz < 8000000)) { |
193 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz |
194 |
| - } else if ((hz >= 8000000) && (hz < 16000000)) { |
195 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz |
196 |
| - } else { // >= 16000000 |
197 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz |
| 191 | + int spi_hz = 0; |
| 192 | + uint8_t prescaler_rank = 0; |
| 193 | + |
| 194 | + /* Get source clock depending on SPI instance */ |
| 195 | + switch ((int)obj->spi) { |
| 196 | + case SPI_1: |
| 197 | + /* SPI_1. Source CLK is PCKL2 */ |
| 198 | + spi_hz = HAL_RCC_GetPCLK2Freq(); |
| 199 | + break; |
| 200 | +#if defined(SPI2_BASE) |
| 201 | + case SPI_2: |
| 202 | + /* SPI_2. Source CLK is PCKL1 */ |
| 203 | + spi_hz = HAL_RCC_GetPCLK1Freq(); |
| 204 | + break; |
| 205 | +#endif |
| 206 | + default: |
| 207 | + error("SPI instance not set"); |
198 | 208 | }
|
199 | 209 |
|
| 210 | + /* Define pre-scaler in order to get highest available frequency below requested frequency */ |
| 211 | + while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ |
| 212 | + spi_hz = spi_hz / 2; |
| 213 | + prescaler_rank++; |
| 214 | + } |
| 215 | + |
| 216 | + if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { |
| 217 | + obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; |
| 218 | + } else { |
| 219 | + error("Couldn't setup requested SPI frequency"); |
| 220 | + } |
| 221 | + |
200 | 222 | init_spi(obj);
|
201 | 223 | }
|
202 | 224 |
|
|
0 commit comments