Skip to content

Commit 8b2ab03

Browse files
committed
Fix SPI clock freq definition
Signed-off-by: Frederic.Pillon <[email protected]>
1 parent 44f340f commit 8b2ab03

File tree

4 files changed

+99
-61
lines changed

4 files changed

+99
-61
lines changed

cores/arduino/stm32/spi_com.c

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,71 @@ static PinName g_pin_ssel = NC;
106106
/** @addtogroup STM32F4xx_System_Private_Functions
107107
* @{
108108
*/
109+
/**
110+
* @brief return clock freq of an SPI instance
111+
* @param spi_inst : SPI instance
112+
* @retval clock freq of the instance else SystemCoreClock
113+
*/
114+
uint32_t spi_getClkFreqInst(SPI_TypeDef * spi_inst)
115+
{
116+
uint32_t spi_freq = SystemCoreClock;
117+
118+
#ifdef STM32F0xx
119+
/* SPIx source CLK is PCKL1 */
120+
spi_freq = HAL_RCC_GetPCLK1Freq();
121+
#else
122+
if(spi_inst != (SPI_TypeDef *)NC) {
123+
/* Get source clock depending on SPI instance */
124+
switch ((uint32_t)spi_inst) {
125+
case (uint32_t)SPI1:
126+
#if defined SPI4_BASE
127+
case (uint32_t)SPI4:
128+
#endif
129+
#if defined SPI5_BASE
130+
case (uint32_t)SPI5:
131+
#endif
132+
#if defined SPI6_BASE
133+
case (uint32_t)SPI6:
134+
#endif
135+
/* SPI1, SPI4, SPI5 and SPI6. Source CLK is PCKL2 */
136+
spi_freq = HAL_RCC_GetPCLK2Freq();
137+
break;
138+
case (uint32_t)SPI2:
139+
#if defined SPI3_BASE
140+
case (uint32_t)SPI3:
141+
#endif
142+
/* SPI_2 and SPI_3. Source CLK is PCKL1 */
143+
spi_freq = HAL_RCC_GetPCLK1Freq();
144+
break;
145+
default:
146+
printf("CLK: SPI instance not set");
147+
break;
148+
}
149+
}
150+
#endif
151+
return spi_freq;
152+
}
153+
154+
/**
155+
* @brief return clock freq of an SPI instance
156+
* @param obj : pointer to spi_t structure
157+
* @retval clock freq of the instance else SystemCoreClock
158+
*/
159+
uint32_t spi_getClkFreq(spi_t *obj)
160+
{
161+
uint32_t spi_inst = NC;
162+
uint32_t spi_freq = SystemCoreClock;
163+
164+
if(obj != NULL) {
165+
spi_inst = pinmap_peripheral(obj->pin_sclk, PinMap_SPI_SCLK);
166+
167+
if(spi_inst != NC) {
168+
spi_freq = spi_getClkFreqInst(spi_inst);
169+
}
170+
}
171+
return spi_freq;
172+
}
173+
109174
/**
110175
* @brief SPI initialization function
111176
* @param obj : pointer to spi_t structure
@@ -120,6 +185,7 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
120185
return;
121186

122187
SPI_HandleTypeDef *handle = &(obj->handle);
188+
uint32_t spi_freq = 0;
123189

124190
// Determine the SPI to use
125191
uint32_t spi_mosi = pinmap_peripheral(obj->pin_mosi, PinMap_SPI_MOSI);
@@ -153,21 +219,22 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
153219
handle->Instance = obj->spi;
154220
handle->Init.Mode = SPI_MODE_MASTER;
155221

156-
if(speed >= SPI_SPEED_CLOCK_DIV2_MHZ) {
222+
spi_freq = spi_getClkFreqInst(obj->spi);
223+
if(speed >= (spi_freq/SPI_SPEED_CLOCK_DIV2_MHZ)) {
157224
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
158-
} else if(speed >= SPI_SPEED_CLOCK_DIV4_MHZ) {
225+
} else if(speed >= (spi_freq/SPI_SPEED_CLOCK_DIV4_MHZ)) {
159226
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
160-
} else if (speed >= SPI_SPEED_CLOCK_DIV8_MHZ) {
227+
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV8_MHZ)) {
161228
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
162-
} else if (speed >= SPI_SPEED_CLOCK_DIV16_MHZ) {
229+
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV16_MHZ)) {
163230
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
164-
} else if (speed >= SPI_SPEED_CLOCK_DIV32_MHZ) {
231+
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV32_MHZ)) {
165232
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
166-
} else if (speed >= SPI_SPEED_CLOCK_DIV64_MHZ) {
233+
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV64_MHZ)) {
167234
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
168-
} else if (speed >= SPI_SPEED_CLOCK_DIV128_MHZ) {
235+
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV128_MHZ)) {
169236
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
170-
} else if (speed >= SPI_SPEED_CLOCK_DIV256_MHZ) {
237+
} else if (speed >= (spi_freq/SPI_SPEED_CLOCK_DIV256_MHZ)) {
171238
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
172239
} else {
173240
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

cores/arduino/stm32/spi_com.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,16 @@ typedef struct spi_s spi_t;
6262

6363

6464
///@brief specifies the SPI speed bus in HZ.
65-
#define SPI_SPEED_CLOCK_DIV2_MHZ ((uint32_t)(SystemCoreClock/2))
66-
#define SPI_SPEED_CLOCK_DIV4_MHZ ((uint32_t)(SystemCoreClock/4))
67-
#define SPI_SPEED_CLOCK_DIV8_MHZ ((uint32_t)(SystemCoreClock/8))
68-
#define SPI_SPEED_CLOCK_DIV16_MHZ ((uint32_t)(SystemCoreClock/16))
69-
#define SPI_SPEED_CLOCK_DIV32_MHZ ((uint32_t)(SystemCoreClock/32))
70-
#define SPI_SPEED_CLOCK_DIV64_MHZ ((uint32_t)(SystemCoreClock/64))
71-
#define SPI_SPEED_CLOCK_DIV128_MHZ ((uint32_t)(SystemCoreClock/128))
72-
#define SPI_SPEED_CLOCK_DIV256_MHZ ((uint32_t)(SystemCoreClock/256))
65+
#define SPI_SPEED_CLOCK_DEFAULT 4000000
66+
67+
#define SPI_SPEED_CLOCK_DIV2_MHZ ((uint32_t)2)
68+
#define SPI_SPEED_CLOCK_DIV4_MHZ ((uint32_t)4)
69+
#define SPI_SPEED_CLOCK_DIV8_MHZ ((uint32_t)8)
70+
#define SPI_SPEED_CLOCK_DIV16_MHZ ((uint32_t)16)
71+
#define SPI_SPEED_CLOCK_DIV32_MHZ ((uint32_t)32)
72+
#define SPI_SPEED_CLOCK_DIV64_MHZ ((uint32_t)64)
73+
#define SPI_SPEED_CLOCK_DIV128_MHZ ((uint32_t)128)
74+
#define SPI_SPEED_CLOCK_DIV256_MHZ ((uint32_t)256)
7375

7476
///@brief speficies the SPI mode to use
7577
//Mode Clock Polarity (CPOL) Clock Phase (CPHA)
@@ -101,6 +103,7 @@ void spi_deinit(spi_t *obj);
101103
spi_status_e spi_send(spi_t *obj, uint8_t *Data, uint16_t len, uint32_t Timeout);
102104
spi_status_e spi_transfer(spi_t *obj, uint8_t * tx_buffer,
103105
uint8_t * rx_buffer, uint16_t len, uint32_t Timeout);
106+
uint32_t spi_getClkFreq(spi_t *obj);
104107

105108
#ifdef __cplusplus
106109
}

libraries/SPI/SPI.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -129,39 +129,30 @@ void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode)
129129
g_active_id = _pin;
130130
}
131131

132+
/*
133+
* This function should not be used in new projects.
134+
* Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
135+
*/
132136
void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider)
133137
{
134138
if(_pin > SPI_CHANNELS_NUM)
135139
return;
136140

141+
/* Get clk freq of the SPI instance */
142+
uint32_t spiClkFreq = spi_getClkFreq(&_spi);
143+
137144
switch(_divider) {
138145
case (SPI_CLOCK_DIV2) :
139-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV2_MHZ;
140-
break;
141146
case (SPI_CLOCK_DIV4) :
142-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV4_MHZ;
143-
break;
144147
case (SPI_CLOCK_DIV8) :
145-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV8_MHZ;
146-
break;
147148
case (SPI_CLOCK_DIV16) :
148-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV16_MHZ;
149-
break;
150149
case (SPI_CLOCK_DIV32) :
151-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV32_MHZ;
152-
break;
153150
case (SPI_CLOCK_DIV64) :
154-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV64_MHZ;
155-
break;
156151
case (SPI_CLOCK_DIV128) :
157-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV128_MHZ;
152+
spiSettings[_pin].clk = spiClkFreq/_divider;
158153
break;
159154
default:
160-
#if defined (STM32F0xx) || defined (STM32F3xx) || defined (STM32L0xx)
161-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV64_MHZ;
162-
#else
163-
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DIV16_MHZ;
164-
#endif
155+
spiSettings[_pin].clk = SPI_SPEED_CLOCK_DEFAULT;
165156
break;
166157
}
167158

libraries/SPI/SPI.h

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535

3636
// For compatibility with sketches designed for AVR @ 16 MHz
3737
// need to go from 64MHz to 16 (/4)
38-
// New programs should use SPI.beginTransaction to set the SPI clock
38+
// This function should not be used in new projects.
39+
// Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
3940
#define SPI_CLOCK_DIV2 2
4041
#define SPI_CLOCK_DIV4 4
4142
#define SPI_CLOCK_DIV8 8
@@ -57,27 +58,7 @@ enum SPITransferMode {
5758
class SPISettings {
5859
public:
5960
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
60-
if(clock >= SPI_SPEED_CLOCK_DIV2_MHZ) {
61-
clk = SPI_SPEED_CLOCK_DIV2_MHZ;
62-
} else if (clock >= SPI_SPEED_CLOCK_DIV4_MHZ) {
63-
clk = SPI_SPEED_CLOCK_DIV4_MHZ;
64-
} else if (clock >= SPI_SPEED_CLOCK_DIV8_MHZ) {
65-
clk = SPI_SPEED_CLOCK_DIV8_MHZ;
66-
} else if (clock >= SPI_SPEED_CLOCK_DIV16_MHZ) {
67-
clk = SPI_SPEED_CLOCK_DIV16_MHZ;
68-
} else if (clock >= SPI_SPEED_CLOCK_DIV32_MHZ) {
69-
clk = SPI_SPEED_CLOCK_DIV32_MHZ;
70-
} else if (clock >= SPI_SPEED_CLOCK_DIV64_MHZ) {
71-
clk = SPI_SPEED_CLOCK_DIV64_MHZ;
72-
} else if (clock >= SPI_SPEED_CLOCK_DIV128_MHZ) {
73-
clk = SPI_SPEED_CLOCK_DIV128_MHZ;
74-
} else {
75-
#if defined (STM32F0xx) || defined(STM32F3xx) || defined(STM32L0xx)
76-
clk = SPI_SPEED_CLOCK_DIV256_MHZ;
77-
#else
78-
clk = SPI_SPEED_CLOCK_DIV16_MHZ;
79-
#endif
80-
}
61+
clk = clock;
8162

8263
if(bitOrder == MSBFIRST) {
8364
msb = 1;
@@ -98,11 +79,7 @@ class SPISettings {
9879

9980
}
10081
SPISettings() {
101-
#if defined (STM32F0xx) || defined(STM32F3xx)
102-
clk = SPI_SPEED_CLOCK_DIV64_MHZ;
103-
#else
104-
clk = SPI_SPEED_CLOCK_DIV16_MHZ;
105-
#endif
82+
clk = SPI_SPEED_CLOCK_DEFAULT;
10683
bOrder = MSBFIRST;
10784
msb = 1;
10885
dMode = SPI_MODE_0;

0 commit comments

Comments
 (0)