Skip to content

Commit e06dc72

Browse files
authored
Merge pull request #2307 from hierophect/stm32-spi-cleanup
STM32: SPI clock rate fix and cleanup
2 parents 372f22c + a96317d commit e06dc72

File tree

1 file changed

+85
-135
lines changed
  • ports/stm32f4/common-hal/busio

1 file changed

+85
-135
lines changed

ports/stm32f4/common-hal/busio/SPI.c

Lines changed: 85 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -36,46 +36,37 @@
3636
#include "supervisor/shared/translate.h"
3737
#include "common-hal/microcontroller/Pin.h"
3838

39-
STATIC bool reserved_spi[6];
40-
STATIC bool never_reset_spi[6];
39+
#define MAX_SPI 6 //TODO; replace this as part of periph cleanup
40+
#define ALL_CLOCKS 0xFF
4141

42-
void spi_reset(void) {
43-
#ifdef SPI1
44-
if(!never_reset_spi[0]) {
45-
reserved_spi[0] = false;
46-
__HAL_RCC_SPI1_CLK_DISABLE();
47-
}
48-
#endif
42+
//arrays use 0 based numbering: SPI1 is stored at index 0
43+
STATIC bool reserved_spi[MAX_SPI];
44+
STATIC bool never_reset_spi[MAX_SPI];
45+
46+
STATIC void spi_clock_enable(uint8_t mask);
47+
STATIC void spi_clock_disable(uint8_t mask);
48+
49+
STATIC uint32_t get_busclock(SPI_TypeDef * instance) {
50+
//SPI2 and 3 are on PCLK1, if they exist.
4951
#ifdef SPI2
50-
if(!never_reset_spi[1]) {
51-
reserved_spi[1] = false;
52-
__HAL_RCC_SPI2_CLK_DISABLE();
53-
}
52+
if(instance == SPI2) return HAL_RCC_GetPCLK1Freq();
5453
#endif
5554
#ifdef SPI3
56-
if(!never_reset_spi[2]) {
57-
reserved_spi[2] = false;
58-
__HAL_RCC_SPI3_CLK_DISABLE();
59-
}
60-
#endif
61-
#ifdef SPI4
62-
if(!never_reset_spi[3]) {
63-
reserved_spi[3] = false;
64-
__HAL_RCC_SPI4_CLK_DISABLE();
65-
}
66-
#endif
67-
#ifdef SPI5
68-
if(!never_reset_spi[4]) {
69-
reserved_spi[4] = false;
70-
__HAL_RCC_SPI5_CLK_DISABLE();
71-
}
55+
if(instance == SPI3) return HAL_RCC_GetPCLK1Freq();
7256
#endif
73-
#ifdef SPI6
74-
if(!never_reset_spi[5]) {
75-
reserved_spi[5] = false;
76-
__HAL_RCC_SPI6_CLK_DISABLE();
57+
return HAL_RCC_GetPCLK2Freq();
58+
}
59+
60+
void spi_reset(void) {
61+
uint16_t never_reset_mask = 0x00;
62+
for(int i=0;i<MAX_SPI;i++) {
63+
if (!never_reset_spi[i]) {
64+
reserved_spi[i] = 0x00;
65+
} else {
66+
never_reset_mask |= 1<<i;
67+
}
7768
}
78-
#endif
69+
spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
7970
}
8071

8172
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
@@ -152,42 +143,8 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
152143
GPIO_InitStruct.Alternate = self->miso->altfn_index;
153144
HAL_GPIO_Init(pin_port(miso->port), &GPIO_InitStruct);
154145

155-
#ifdef SPI1
156-
if(SPIx==SPI1) {
157-
reserved_spi[0] = true;
158-
__HAL_RCC_SPI1_CLK_ENABLE();
159-
}
160-
#endif
161-
#ifdef SPI2
162-
if(SPIx==SPI2) {
163-
reserved_spi[1] = true;
164-
__HAL_RCC_SPI2_CLK_ENABLE();
165-
}
166-
#endif
167-
#ifdef SPI3
168-
if(SPIx==SPI3) {
169-
reserved_spi[2] = true;
170-
__HAL_RCC_SPI3_CLK_ENABLE();
171-
}
172-
#endif
173-
#ifdef SPI4
174-
if(SPIx==SPI4) {
175-
reserved_spi[3] = true;
176-
__HAL_RCC_SPI4_CLK_ENABLE();
177-
}
178-
#endif
179-
#ifdef SPI5
180-
if(SPIx==SPI5) {
181-
reserved_spi[4] = true;
182-
__HAL_RCC_SPI5_CLK_ENABLE();
183-
}
184-
#endif
185-
#ifdef SPI6
186-
if(SPIx==SPI6) {
187-
reserved_spi[5] = true;
188-
__HAL_RCC_SPI6_CLK_ENABLE();
189-
}
190-
#endif
146+
spi_clock_enable(1<<(self->sck->spi_index - 1));
147+
reserved_spi[self->sck->spi_index - 1] = true;
191148

192149
self->handle.Instance = SPIx;
193150
self->handle.Init.Mode = SPI_MODE_MASTER;
@@ -205,7 +162,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
205162
{
206163
mp_raise_ValueError(translate("SPI Init Error"));
207164
}
208-
self->baudrate = (HAL_RCC_GetPCLK2Freq()/16);
165+
self->baudrate = (get_busclock(SPIx)/16);
209166
self->prescaler = 16;
210167
self->polarity = 0;
211168
self->phase = 1;
@@ -233,42 +190,9 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
233190
}
234191

235192
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
236-
#ifdef SPI1
237-
if(self->handle.Instance==SPI1) {
238-
reserved_spi[0] = false;
239-
__HAL_RCC_SPI1_CLK_DISABLE();
240-
}
241-
#endif
242-
#ifdef SPI2
243-
if(self->handle.Instance==SPI2) {
244-
reserved_spi[1] = false;
245-
__HAL_RCC_SPI2_CLK_DISABLE();
246-
}
247-
#endif
248-
#ifdef SPI3
249-
if(self->handle.Instance==SPI3) {
250-
reserved_spi[2] = false;
251-
__HAL_RCC_SPI3_CLK_DISABLE();
252-
}
253-
#endif
254-
#ifdef SPI4
255-
if(self->handle.Instance==SPI4) {
256-
reserved_spi[3] = false;
257-
__HAL_RCC_SPI4_CLK_DISABLE();
258-
}
259-
#endif
260-
#ifdef SPI5
261-
if(self->handle.Instance==SPI5) {
262-
reserved_spi[4] = false;
263-
__HAL_RCC_SPI5_CLK_DISABLE();
264-
}
265-
#endif
266-
#ifdef SPI6
267-
if(self->handle.Instance==SPI6) {
268-
reserved_spi[5] = false;
269-
__HAL_RCC_SPI6_CLK_DISABLE();
270-
}
271-
#endif
193+
spi_clock_disable(1<<(self->sck->spi_index - 1));
194+
reserved_spi[self->sck->spi_index - 1] = true;
195+
272196
reset_pin_number(self->sck->pin->port,self->sck->pin->number);
273197
reset_pin_number(self->mosi->pin->port,self->mosi->pin->number);
274198
reset_pin_number(self->miso->pin->port,self->miso->pin->number);
@@ -277,7 +201,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
277201
self->miso = mp_const_none;
278202
}
279203

280-
static uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler) {
204+
STATIC uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler, uint32_t busclock) {
281205
static const uint32_t baud_map[8][2] = {
282206
{2,SPI_BAUDRATEPRESCALER_2},
283207
{4,SPI_BAUDRATEPRESCALER_4},
@@ -292,7 +216,7 @@ static uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler) {
292216
uint16_t divisor;
293217
do {
294218
divisor = baud_map[i][0];
295-
if (baudrate >= (HAL_RCC_GetPCLK2Freq()/divisor)) {
219+
if (baudrate >= (busclock/divisor)) {
296220
*prescaler = divisor;
297221
return baud_map[i][1];
298222
}
@@ -312,28 +236,12 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
312236
//Deinit SPI
313237
HAL_SPI_DeInit(&self->handle);
314238

315-
if (bits == 8) {
316-
self->handle.Init.DataSize = SPI_DATASIZE_8BIT;
317-
} else if (bits == 16) {
318-
self->handle.Init.DataSize = SPI_DATASIZE_16BIT;
319-
} else {
320-
return false;
321-
}
322-
323-
if (polarity) {
324-
self->handle.Init.CLKPolarity = SPI_POLARITY_HIGH;
325-
} else {
326-
self->handle.Init.CLKPolarity = SPI_POLARITY_LOW;
327-
}
328-
329-
if (phase) {
330-
self->handle.Init.CLKPhase = SPI_PHASE_2EDGE;
331-
} else {
332-
self->handle.Init.CLKPhase = SPI_PHASE_1EDGE;
333-
}
334-
335-
self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler);
239+
self->handle.Init.DataSize = (bits == 16) ? SPI_DATASIZE_16BIT : SPI_DATASIZE_8BIT;
240+
self->handle.Init.CLKPolarity = (polarity) ? SPI_POLARITY_HIGH : SPI_POLARITY_LOW;
241+
self->handle.Init.CLKPhase = (phase) ? SPI_PHASE_2EDGE : SPI_PHASE_1EDGE;
336242

243+
self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler,
244+
get_busclock(self->handle.Instance));
337245
self->handle.Init.Mode = SPI_MODE_MASTER;
338246
self->handle.Init.Direction = SPI_DIRECTION_2LINES;
339247
self->handle.Init.NSS = SPI_NSS_SOFT;
@@ -362,10 +270,10 @@ bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) {
362270
// __disable_irq();
363271
// __DMB();
364272

365-
if (!self->has_lock) {
366-
grabbed_lock = true;
367-
self->has_lock = true;
368-
}
273+
if (!self->has_lock) {
274+
grabbed_lock = true;
275+
self->has_lock = true;
276+
}
369277

370278
// __DMB();
371279
// __set_PRIMASK(store_primask);
@@ -412,4 +320,46 @@ uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) {
412320

413321
uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) {
414322
return self->polarity;
415-
}
323+
}
324+
325+
STATIC void spi_clock_enable(uint8_t mask) {
326+
#ifdef SPI1
327+
if (mask & 1<<0) __HAL_RCC_SPI1_CLK_ENABLE();
328+
#endif
329+
#ifdef SPI2
330+
if (mask & 1<<1) __HAL_RCC_SPI2_CLK_ENABLE();
331+
#endif
332+
#ifdef SPI3
333+
if (mask & 1<<2) __HAL_RCC_SPI3_CLK_ENABLE();
334+
#endif
335+
#ifdef SPI4
336+
if (mask & 1<<3) __HAL_RCC_SPI4_CLK_ENABLE();
337+
#endif
338+
#ifdef SPI5
339+
if (mask & 1<<4) __HAL_RCC_SPI5_CLK_ENABLE();
340+
#endif
341+
#ifdef SPI6
342+
if (mask & 1<<5) __HAL_RCC_SPI6_CLK_ENABLE();
343+
#endif
344+
}
345+
346+
STATIC void spi_clock_disable(uint8_t mask) {
347+
#ifdef SPI1
348+
if (mask & 1<<0) __HAL_RCC_SPI1_CLK_DISABLE();
349+
#endif
350+
#ifdef SPI2
351+
if (mask & 1<<1) __HAL_RCC_SPI2_CLK_DISABLE();
352+
#endif
353+
#ifdef SPI3
354+
if (mask & 1<<2) __HAL_RCC_SPI3_CLK_DISABLE();
355+
#endif
356+
#ifdef SPI4
357+
if (mask & 1<<3) __HAL_RCC_SPI4_CLK_DISABLE();
358+
#endif
359+
#ifdef SPI5
360+
if (mask & 1<<4) __HAL_RCC_SPI5_CLK_DISABLE();
361+
#endif
362+
#ifdef SPI6
363+
if (mask & 1<<5) __HAL_RCC_SPI6_CLK_DISABLE();
364+
#endif
365+
}

0 commit comments

Comments
 (0)