|
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
|
@@ -177,46 +178,47 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
|
177 | 178 | init_spi(obj);
|
178 | 179 | }
|
179 | 180 |
|
| 181 | +static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2, |
| 182 | + SPI_BAUDRATEPRESCALER_4, |
| 183 | + SPI_BAUDRATEPRESCALER_8, |
| 184 | + SPI_BAUDRATEPRESCALER_16, |
| 185 | + SPI_BAUDRATEPRESCALER_32, |
| 186 | + SPI_BAUDRATEPRESCALER_64, |
| 187 | + SPI_BAUDRATEPRESCALER_128, |
| 188 | + SPI_BAUDRATEPRESCALER_256}; |
| 189 | + |
180 | 190 | void spi_frequency(spi_t *obj, int hz)
|
181 | 191 | {
|
182 |
| - // Values depend of PCLK1 and PCLK2: 32 MHz if HSI is used, 24 MHz if HSE is used |
183 |
| - if (SystemCoreClock == 32000000) { // HSI |
184 |
| - if (hz < 250000) { |
185 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz |
186 |
| - } else if ((hz >= 250000) && (hz < 500000)) { |
187 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz |
188 |
| - } else if ((hz >= 500000) && (hz < 1000000)) { |
189 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz |
190 |
| - } else if ((hz >= 1000000) && (hz < 2000000)) { |
191 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz |
192 |
| - } else if ((hz >= 2000000) && (hz < 4000000)) { |
193 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz |
194 |
| - } else if ((hz >= 4000000) && (hz < 8000000)) { |
195 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz |
196 |
| - } else if ((hz >= 8000000) && (hz < 16000000)) { |
197 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz |
198 |
| - } else { // >= 16000000 |
199 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz |
200 |
| - } |
201 |
| - } else { // 24 MHz - HSE |
202 |
| - if (hz < 180000) { |
203 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 94 kHz |
204 |
| - } else if ((hz >= 180000) && (hz < 350000)) { |
205 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 188 kHz |
206 |
| - } else if ((hz >= 350000) && (hz < 750000)) { |
207 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 375 kHz |
208 |
| - } else if ((hz >= 750000) && (hz < 1000000)) { |
209 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 750 kHz |
210 |
| - } else if ((hz >= 1000000) && (hz < 3000000)) { |
211 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 1.5 MHz |
212 |
| - } else if ((hz >= 3000000) && (hz < 6000000)) { |
213 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 3 MHz |
214 |
| - } else if ((hz >= 6000000) && (hz < 12000000)) { |
215 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 6 MHz |
216 |
| - } else { // >= 12000000 |
217 |
| - obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 12 MHz |
218 |
| - } |
| 192 | + int spi_hz = 0; |
| 193 | + uint8_t prescaler_rank = 0; |
| 194 | + |
| 195 | + /* Get source clock depending on SPI instance */ |
| 196 | + switch ((int)obj->spi) { |
| 197 | + case SPI_1: |
| 198 | + /* SPI_1. Source CLK is PCKL2 */ |
| 199 | + spi_hz = HAL_RCC_GetPCLK2Freq(); |
| 200 | + break; |
| 201 | + case SPI_2: |
| 202 | + case SPI_3: |
| 203 | + /* SPI_2, SPI_3. Source CLK is PCKL1 */ |
| 204 | + spi_hz = HAL_RCC_GetPCLK1Freq(); |
| 205 | + break; |
| 206 | + default: |
| 207 | + error("SPI instance not set"); |
219 | 208 | }
|
| 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 | + |
220 | 222 | init_spi(obj);
|
221 | 223 | }
|
222 | 224 |
|
|
0 commit comments