Skip to content

Commit 8b57670

Browse files
committed
cc2538: spi: Add support for dynamic clock frequency
This changes makes it possible to change the SPI clock frequency at runtime. Signed-off-by: Benoît Thébaudeau <benoit@wsystem.com>
1 parent c76b823 commit 8b57670

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

cpu/cc2538/dev/spi.c

+38-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "contiki.h"
4141
#include "reg.h"
4242
#include "spi-arch.h"
43+
#include "sys/cc.h"
4344
#include "dev/ioc.h"
4445
#include "dev/sys-ctrl.h"
4546
#include "dev/spi.h"
@@ -155,7 +156,12 @@
155156
#if (SPI1_CPRS_CPSDVSR & 1) == 1 || SPI1_CPRS_CPSDVSR < 2 || SPI1_CPRS_CPSDVSR > 254
156157
#error SPI1_CPRS_CPSDVSR must be an even number between 2 and 254
157158
#endif
158-
159+
/*---------------------------------------------------------------------------*/
160+
/*
161+
* Clock source from which the baud clock is determined for the SSI, according
162+
* to SSI_CC.CS.
163+
*/
164+
#define SSI_SYS_CLOCK SYS_CTRL_SYS_CLOCK
159165
/*---------------------------------------------------------------------------*/
160166
typedef struct {
161167
int8_t port;
@@ -314,6 +320,37 @@ spix_set_mode(uint8_t spi,
314320
}
315321
/*---------------------------------------------------------------------------*/
316322
void
323+
spix_set_clock_freq(uint8_t spi, uint32_t freq)
324+
{
325+
const spi_regs_t *regs;
326+
uint64_t div;
327+
uint32_t scr;
328+
329+
if(spi >= SSI_INSTANCE_COUNT) {
330+
return;
331+
}
332+
333+
regs = &spi_regs[spi];
334+
335+
/* Disable the SSI peripheral to configure it */
336+
REG(regs->base + SSI_CR1) = 0;
337+
338+
/* Configure the SSI serial clock rate */
339+
if(!freq) {
340+
scr = 255;
341+
} else {
342+
div = (uint64_t)regs->ssi_cprs_cpsdvsr * freq;
343+
scr = (SSI_SYS_CLOCK + div - 1) / div;
344+
scr = MIN(MAX(scr, 1), 256) - 1;
345+
}
346+
REG(regs->base + SSI_CR0) = (REG(regs->base + SSI_CR0) & ~SSI_CR0_SCR_M) |
347+
scr << SSI_CR0_SCR_S;
348+
349+
/* Re-enable the SSI */
350+
REG(regs->base + SSI_CR1) |= SSI_CR1_SSE;
351+
}
352+
/*---------------------------------------------------------------------------*/
353+
void
317354
spix_cs_init(uint8_t port, uint8_t pin)
318355
{
319356
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port),

cpu/cc2538/spi-arch.h

+8
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ void spix_set_mode(uint8_t spi, uint32_t frame_format,
197197
uint32_t clock_polarity, uint32_t clock_phase,
198198
uint32_t data_size);
199199

200+
/**
201+
* \brief Sets the SPI clock frequency of the given SSI instance.
202+
*
203+
* \param spi SSI instance
204+
* \param freq Frequency (Hz)
205+
*/
206+
void spix_set_clock_freq(uint8_t spi, uint32_t freq);
207+
200208
/**
201209
* \brief Configure a GPIO to be the chip select pin.
202210
*

0 commit comments

Comments
 (0)