|
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
|
@@ -212,58 +213,50 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
212 | 213 | init_spi(obj);
|
213 | 214 | }
|
214 | 215 |
|
| 216 | +static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, |
| 217 | + SPI_BAUDRATEPRESCALER_4, |
| 218 | + SPI_BAUDRATEPRESCALER_8, |
| 219 | + SPI_BAUDRATEPRESCALER_16, |
| 220 | + SPI_BAUDRATEPRESCALER_32, |
| 221 | + SPI_BAUDRATEPRESCALER_64, |
| 222 | + SPI_BAUDRATEPRESCALER_128, |
| 223 | + SPI_BAUDRATEPRESCALER_256}; |
| 224 | + |
215 | 225 | void spi_frequency(spi_t *obj, int hz)
|
216 | 226 | {
|
217 |
| - // The frequencies are obtained with: |
218 |
| - // - SPI2/SPI3 clock = 54 MHz (APB1 clock) |
219 |
| - // - SPI1/SPI4/SPI5/SPI6 clocks = 108 MHz (APB2 clock) |
220 |
| - switch(obj->spi) { |
221 |
| - case SPI_1: |
222 |
| - case SPI_4: |
223 |
| - case SPI_5: |
224 |
| - case SPI_6: |
225 |
| - if (hz < 800000) { |
226 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 422 kHz |
227 |
| - } else if ((hz >= 800000) && (hz < 1000000)) { |
228 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 844 kHz |
229 |
| - } else if ((hz >= 1000000) && (hz < 3000000)) { |
230 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.69 MHz |
231 |
| - } else if ((hz >= 3000000) && (hz < 6000000)) { |
232 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 3.38 MHz |
233 |
| - } else if ((hz >= 6000000) && (hz < 12000000)) { |
234 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 6.75 MHz |
235 |
| - } else if ((hz >= 12000000) && (hz < 24000000)) { |
236 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 13.5 MHz |
237 |
| - } else if ((hz >= 24000000) && (hz < 54000000)) { |
238 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 27 MHz |
239 |
| - } else { // >= 54000000 |
240 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 54 MHz |
241 |
| - } |
242 |
| - break; |
243 |
| - case SPI_2: |
244 |
| - case SPI_3: |
245 |
| - if (hz < 400000) { |
246 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 211 kHz |
247 |
| - } else if ((hz >= 400000) && (hz < 800000)) { |
248 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 422 kHz |
249 |
| - } else if ((hz >= 800000) && (hz < 1000000)) { |
250 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 844 kHz |
251 |
| - } else if ((hz >= 1000000) && (hz < 3000000)) { |
252 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.69 MHz |
253 |
| - } else if ((hz >= 3000000) && (hz < 6000000)) { |
254 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3.38 MHz |
255 |
| - } else if ((hz >= 6000000) && (hz < 12000000)) { |
256 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6.75 MHz |
257 |
| - } else if ((hz >= 12000000) && (hz < 24000000)) { |
258 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 13.5 MHz |
259 |
| - } else { // >= 24000000 |
260 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 27 MHz |
261 |
| - } |
262 |
| - break; |
263 |
| - default: |
264 |
| - return; |
| 227 | + int spi_hz = 0; |
| 228 | + uint8_t prescaler_rank = 0; |
| 229 | + |
| 230 | + /* Get source clock depending on SPI instance */ |
| 231 | + switch ((int)obj->spi) { |
| 232 | + case SPI_1: |
| 233 | + case SPI_4: |
| 234 | + case SPI_5: |
| 235 | + case SPI_6: |
| 236 | + /* SPI_1, SPI_4, SPI_5 and SPI_6. Source CLK is PCKL2 */ |
| 237 | + spi_hz = HAL_RCC_GetPCLK2Freq(); |
| 238 | + break; |
| 239 | + case SPI_2: |
| 240 | + case SPI_3: |
| 241 | + /* SPI_2 and SPI_3. Source CLK is PCKL1 */ |
| 242 | + spi_hz = HAL_RCC_GetPCLK1Freq(); |
| 243 | + break; |
| 244 | + default: |
| 245 | + error("SPI instance not set"); |
265 | 246 | }
|
266 |
| - |
| 247 | + |
| 248 | + /* Define pre-scaler in order to get highest available frequency below requested frequency */ |
| 249 | + while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){ |
| 250 | + spi_hz = spi_hz / 2; |
| 251 | + prescaler_rank++; |
| 252 | + } |
| 253 | + |
| 254 | + if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) { |
| 255 | + obj->br_presc = baudrate_prescaler_table[prescaler_rank-1]; |
| 256 | + } else { |
| 257 | + error("Couldn't setup requested SPI frequency"); |
| 258 | + } |
| 259 | + |
267 | 260 | init_spi(obj);
|
268 | 261 | }
|
269 | 262 |
|
|
0 commit comments