Skip to content

Commit a773b63

Browse files
authored
Merge pull request #2013 from egostm/spi_freq_selection
Spi freq selection
2 parents a6f640c + bc08631 commit a773b63

File tree

8 files changed

+313
-496
lines changed

8 files changed

+313
-496
lines changed

hal/targets/hal/TARGET_STM/TARGET_STM32F0/spi_api.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
*******************************************************************************
2929
*/
3030
#include "mbed_assert.h"
31+
#include "mbed_error.h"
3132
#include "spi_api.h"
3233

3334
#if DEVICE_SPI
@@ -168,25 +169,33 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
168169
init_spi(obj);
169170
}
170171

172+
static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2,
173+
SPI_BAUDRATEPRESCALER_4,
174+
SPI_BAUDRATEPRESCALER_8,
175+
SPI_BAUDRATEPRESCALER_16,
176+
SPI_BAUDRATEPRESCALER_32,
177+
SPI_BAUDRATEPRESCALER_64,
178+
SPI_BAUDRATEPRESCALER_128,
179+
SPI_BAUDRATEPRESCALER_256};
180+
171181
void spi_frequency(spi_t *obj, int hz) {
172-
// Note: The frequencies are obtained with SPI clock = 48 MHz (APB clock)
173-
if (hz < 375000) {
174-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 188 kHz
175-
} else if ((hz >= 375000) && (hz < 750000)) {
176-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 375 kHz
177-
} else if ((hz >= 750000) && (hz < 1000000)) {
178-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 750 kHz
179-
} else if ((hz >= 1000000) && (hz < 3000000)) {
180-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1.5 MHz
181-
} else if ((hz >= 3000000) && (hz < 6000000)) {
182-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 3 MHz
183-
} else if ((hz >= 6000000) && (hz < 12000000)) {
184-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 6 MHz
185-
} else if ((hz >= 12000000) && (hz < 24000000)) {
186-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 12 MHz
187-
} else { // >= 24000000
188-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 24 MHz
189-
}
182+
int spi_hz = 0;
183+
uint8_t prescaler_rank = 0;
184+
185+
/* SPI_1, SPI_2. Source CLK is PCKL1 */
186+
spi_hz = HAL_RCC_GetPCLK1Freq();
187+
188+
/* Define pre-scaler in order to get highest available frequency below requested frequency */
189+
while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){
190+
spi_hz = spi_hz / 2;
191+
prescaler_rank++;
192+
}
193+
194+
if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) {
195+
obj->br_presc = baudrate_prescaler_table[prescaler_rank-1];
196+
} else {
197+
error("Couldn't setup requested SPI frequency");
198+
}
190199

191200
init_spi(obj);
192201
}

hal/targets/hal/TARGET_STM/TARGET_STM32F1/spi_api.c

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
*******************************************************************************
2929
*/
3030
#include "mbed_assert.h"
31+
#include "mbed_error.h"
3132
#include "spi_api.h"
3233

3334
#if DEVICE_SPI
@@ -168,49 +169,45 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
168169
init_spi(obj);
169170
}
170171

172+
static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2,
173+
SPI_BAUDRATEPRESCALER_4,
174+
SPI_BAUDRATEPRESCALER_8,
175+
SPI_BAUDRATEPRESCALER_16,
176+
SPI_BAUDRATEPRESCALER_32,
177+
SPI_BAUDRATEPRESCALER_64,
178+
SPI_BAUDRATEPRESCALER_128,
179+
SPI_BAUDRATEPRESCALER_256};
180+
171181
void spi_frequency(spi_t *obj, int hz)
172182
{
173-
if (obj->spi == SPI_1) {
174-
// Values depend of PCLK2: 64 MHz if HSI is used, 72 MHz if HSE is used
175-
if (hz < 500000) {
176-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 281 kHz
177-
} else if ((hz >= 500000) && (hz < 1000000)) {
178-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 563 kHz
179-
} else if ((hz >= 1000000) && (hz < 2000000)) {
180-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz
181-
} else if ((hz >= 2000000) && (hz < 4000000)) {
182-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz
183-
} else if ((hz >= 4000000) && (hz < 8000000)) {
184-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz
185-
} else if ((hz >= 8000000) && (hz < 16000000)) {
186-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz
187-
} else if ((hz >= 16000000) && (hz < 32000000)) {
188-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz
189-
} else { // >= 32000000
190-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 MHz
191-
}
183+
int spi_hz = 0;
184+
uint8_t prescaler_rank = 0;
185+
186+
/* Get source clock depending on SPI instance */
187+
switch ((int)obj->spi) {
188+
case SPI_1:
189+
/* SPI_1. Source CLK is PCKL2 */
190+
spi_hz = HAL_RCC_GetPCLK2Freq();
191+
break;
192+
case SPI_2:
193+
/* SPI_2. Source CLK is PCKL1 */
194+
spi_hz = HAL_RCC_GetPCLK1Freq();
195+
break;
196+
default:
197+
error("SPI instance not set");
192198
}
193199

194-
if (obj->spi == SPI_2) {
195-
// Values depend of PCLK1: 32 MHz if HSI is used, 36 MHz if HSE is used
196-
if (hz < 250000) {
197-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz
198-
} else if ((hz >= 250000) && (hz < 500000)) {
199-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 281 kHz
200-
} else if ((hz >= 500000) && (hz < 1000000)) {
201-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 563 kHz
202-
} else if ((hz >= 1000000) && (hz < 2000000)) {
203-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz
204-
} else if ((hz >= 2000000) && (hz < 4000000)) {
205-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz
206-
} else if ((hz >= 4000000) && (hz < 8000000)) {
207-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz
208-
} else if ((hz >= 8000000) && (hz < 16000000)) {
209-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz
210-
} else { // >= 16000000
211-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz
212-
}
213-
}
200+
/* Define pre-scaler in order to get highest available frequency below requested frequency */
201+
while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){
202+
spi_hz = spi_hz / 2;
203+
prescaler_rank++;
204+
}
205+
206+
if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) {
207+
obj->br_presc = baudrate_prescaler_table[prescaler_rank-1];
208+
} else {
209+
error("Couldn't setup requested SPI frequency");
210+
}
214211

215212
init_spi(obj);
216213
}

hal/targets/hal/TARGET_STM/TARGET_STM32F3/spi_api.c

Lines changed: 43 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
*******************************************************************************
2929
*/
3030
#include "mbed_assert.h"
31+
#include "mbed_error.h"
3132
#include "spi_api.h"
3233

3334
#if DEVICE_SPI
@@ -195,86 +196,52 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
195196
init_spi(obj);
196197
}
197198

199+
static const uint16_t baudrate_prescaler_table[] = {SPI_BAUDRATEPRESCALER_2,
200+
SPI_BAUDRATEPRESCALER_4,
201+
SPI_BAUDRATEPRESCALER_8,
202+
SPI_BAUDRATEPRESCALER_16,
203+
SPI_BAUDRATEPRESCALER_32,
204+
SPI_BAUDRATEPRESCALER_64,
205+
SPI_BAUDRATEPRESCALER_128,
206+
SPI_BAUDRATEPRESCALER_256};
207+
198208
void spi_frequency(spi_t *obj, int hz)
199209
{
200-
#if defined(TARGET_STM32F334C8)
201-
// Values depend of APB2CLK : 64 MHz if HSI is used, 72 MHz if HSE is used
202-
if (hz < 500000) {
203-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 281 kHz
204-
} else if ((hz >= 500000) && (hz < 1000000)) {
205-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 563 kHz
206-
} else if ((hz >= 1000000) && (hz < 2000000)) {
207-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz
208-
} else if ((hz >= 2000000) && (hz < 4000000)) {
209-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz
210-
} else if ((hz >= 4000000) && (hz < 8000000)) {
211-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz
212-
} else if ((hz >= 8000000) && (hz < 16000000)) {
213-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz
214-
} else if ((hz >= 16000000) && (hz < 32000000)) {
215-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz
216-
} else { // >= 32000000
217-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 MHz
218-
}
219-
#elif defined(TARGET_STM32F302R8)
220-
if (hz < 250000) {
221-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz
222-
} else if ((hz >= 250000) && (hz < 500000)) {
223-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 280 kHz
224-
} else if ((hz >= 500000) && (hz < 1000000)) {
225-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 560 kHz
226-
} else if ((hz >= 1000000) && (hz < 2000000)) {
227-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz
228-
} else if ((hz >= 2000000) && (hz < 4000000)) {
229-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz
230-
} else if ((hz >= 4000000) && (hz < 8000000)) {
231-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz
232-
} else if ((hz >= 8000000) && (hz < 16000000)) {
233-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz
234-
} else { // >= 16000000
235-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz
210+
int spi_hz = 0;
211+
uint8_t prescaler_rank = 0;
212+
213+
/* Get source clock depending on SPI instance */
214+
switch ((int)obj->spi) {
215+
#if defined SPI1_BASE
216+
case SPI_1:
217+
/* SPI_1. Source CLK is PCKL2 */
218+
spi_hz = HAL_RCC_GetPCLK2Freq();
219+
break;
220+
#endif
221+
#if defined SPI2_BASE
222+
case SPI_2:
223+
#endif
224+
#if defined SPI3_BASE
225+
case SPI_3:
226+
#endif
227+
/* SPI_2 and SPI_3. Source CLK is PCKL1 */
228+
spi_hz = HAL_RCC_GetPCLK1Freq();
229+
break;
230+
default:
231+
error("SPI instance not set");
236232
}
237233

238-
#else
239-
// Values depend of APB1CLK and APB2CLK : 32 MHz if HSI is used, 36 MHz if HSE is used
240-
if (obj->spi == SPI_1) {
241-
if (hz < 500000) {
242-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 280 kHz
243-
} else if ((hz >= 500000) && (hz < 1000000)) {
244-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 560 kHz
245-
} else if ((hz >= 1000000) && (hz < 2000000)) {
246-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz
247-
} else if ((hz >= 2000000) && (hz < 4000000)) {
248-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz
249-
} else if ((hz >= 4000000) && (hz < 8000000)) {
250-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz
251-
} else if ((hz >= 8000000) && (hz < 16000000)) {
252-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz
253-
} else if ((hz >= 16000000) && (hz < 32000000)) {
254-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz
255-
} else { // >= 32000000
256-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 MHz
257-
}
258-
} else {
259-
if (hz < 250000) {
260-
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz
261-
} else if ((hz >= 250000) && (hz < 500000)) {
262-
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 280 kHz
263-
} else if ((hz >= 500000) && (hz < 1000000)) {
264-
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 560 kHz
265-
} else if ((hz >= 1000000) && (hz < 2000000)) {
266-
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz
267-
} else if ((hz >= 2000000) && (hz < 4000000)) {
268-
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz
269-
} else if ((hz >= 4000000) && (hz < 8000000)) {
270-
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz
271-
} else if ((hz >= 8000000) && (hz < 16000000)) {
272-
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz
273-
} else { // >= 16000000
274-
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz
275-
}
276-
}
277-
#endif
234+
/* Define pre-scaler in order to get highest available frequency below requested frequency */
235+
while ((spi_hz > hz) && (prescaler_rank < sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0]))){
236+
spi_hz = spi_hz / 2;
237+
prescaler_rank++;
238+
}
239+
240+
if (prescaler_rank <= sizeof(baudrate_prescaler_table)/sizeof(baudrate_prescaler_table[0])) {
241+
obj->br_presc = baudrate_prescaler_table[prescaler_rank-1];
242+
} else {
243+
error("Couldn't setup requested SPI frequency");
244+
}
278245

279246
init_spi(obj);
280247
}

0 commit comments

Comments
 (0)