Skip to content

Commit 3c232aa

Browse files
majbthrdfpistm
authored andcommitted
feat: add the STM32WL SUBGHZSPI to the SPI library
Signed-off-by: Peter Lawrence <12226419+majbthrd@users.noreply.github.com> Co-authored-by: Frederic Pillon <frederic.pillon@st.com> xlspi
1 parent 95ad137 commit 3c232aa

File tree

3 files changed

+181
-44
lines changed

3 files changed

+181
-44
lines changed

libraries/SPI/src/SPI.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,3 +421,78 @@ void SPIClass::detachInterrupt(void)
421421
{
422422
// Should be disableInterrupt()
423423
}
424+
425+
#if defined(SUBGHZSPI_BASE)
426+
void SUBGHZSPIClass::begin(uint8_t _pin)
427+
{
428+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
429+
LL_PWR_UnselectSUBGHZSPI_NSS();
430+
}
431+
SPIClass::begin(CS_PIN_CONTROLLED_BY_USER);
432+
}
433+
434+
void SUBGHZSPIClass::beginTransaction(uint8_t _pin, SPISettings settings)
435+
{
436+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
437+
LL_PWR_UnselectSUBGHZSPI_NSS();
438+
}
439+
SPIClass::beginTransaction(CS_PIN_CONTROLLED_BY_USER, settings);
440+
}
441+
442+
byte SUBGHZSPIClass::transfer(uint8_t _pin, uint8_t _data, SPITransferMode _mode)
443+
{
444+
byte res;
445+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
446+
LL_PWR_SelectSUBGHZSPI_NSS();
447+
}
448+
res = SPIClass::transfer(CS_PIN_CONTROLLED_BY_USER, _data, _mode);
449+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
450+
LL_PWR_UnselectSUBGHZSPI_NSS();
451+
}
452+
return res;
453+
}
454+
455+
uint16_t SUBGHZSPIClass::transfer16(uint8_t _pin, uint16_t _data, SPITransferMode _mode)
456+
{
457+
uint16_t rx_buffer = 0;
458+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
459+
LL_PWR_SelectSUBGHZSPI_NSS();
460+
}
461+
SPIClass::transfer16(CS_PIN_CONTROLLED_BY_USER, _data, _mode);
462+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
463+
LL_PWR_UnselectSUBGHZSPI_NSS();
464+
}
465+
return rx_buffer;
466+
}
467+
468+
void SUBGHZSPIClass::transfer(uint8_t _pin, void *_buf, size_t _count, SPITransferMode _mode)
469+
{
470+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
471+
LL_PWR_SelectSUBGHZSPI_NSS();
472+
}
473+
SPIClass::transfer(CS_PIN_CONTROLLED_BY_USER, _buf, _count, _mode);
474+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
475+
LL_PWR_UnselectSUBGHZSPI_NSS();
476+
}
477+
}
478+
479+
void SUBGHZSPIClass::transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode)
480+
{
481+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
482+
LL_PWR_SelectSUBGHZSPI_NSS();
483+
}
484+
SPIClass::transfer(CS_PIN_CONTROLLED_BY_USER, _bufout, _bufin, _count, _mode);
485+
if (_pin != CS_PIN_CONTROLLED_BY_USER) {
486+
LL_PWR_UnselectSUBGHZSPI_NSS();
487+
}
488+
}
489+
490+
void SUBGHZSPIClass::enableDebugPins(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
491+
{
492+
/* Configure SPI GPIO pins */
493+
pinmap_pinout(digitalPinToPinName(mosi), PinMap_SPI_MOSI);
494+
pinmap_pinout(digitalPinToPinName(miso), PinMap_SPI_MISO);
495+
pinmap_pinout(digitalPinToPinName(sclk), PinMap_SPI_SCLK);
496+
pinmap_pinout(digitalPinToPinName(ssel), PinMap_SPI_SSEL);
497+
}
498+
#endif

libraries/SPI/src/SPI.h

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,15 @@ class SPIClass {
151151
_spi.pin_ssel = (ssel);
152152
};
153153

154-
void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
154+
virtual void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
155155
void end(void);
156156

157157
/* This function should be used to configure the SPI instance in case you
158158
* don't use default parameters.
159159
* You can attach another CS pin to the SPI instance and each CS pin can be
160160
* attach with specific SPI settings.
161161
*/
162-
void beginTransaction(uint8_t pin, SPISettings settings);
162+
virtual void beginTransaction(uint8_t pin, SPISettings settings);
163163
void beginTransaction(SPISettings settings)
164164
{
165165
beginTransaction(CS_PIN_CONTROLLED_BY_USER, settings);
@@ -175,10 +175,10 @@ class SPIClass {
175175
* instance with begin() or beginTransaction().
176176
* You can specify the CS pin to use.
177177
*/
178-
byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
179-
uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
180-
void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
181-
void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
178+
virtual byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
179+
virtual uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
180+
virtual void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
181+
virtual void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
182182

183183
// Transfer functions when user controls himself the CS pin.
184184
byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST)
@@ -233,6 +233,10 @@ class SPIClass {
233233
return &(_spi.handle);
234234
}
235235

236+
protected:
237+
// spi instance
238+
spi_t _spi;
239+
236240
private:
237241
/* Contains various spiSettings for the same spi instance. Each spi spiSettings
238242
is associated to a CS pin. */
@@ -241,10 +245,6 @@ class SPIClass {
241245
// Use to know which configuration is selected.
242246
int16_t _CSPinConfig;
243247

244-
// spi instance
245-
spi_t _spi;
246-
247-
248248
typedef enum {
249249
GET_IDX = 0,
250250
ADD_NEW_PIN = 1
@@ -304,4 +304,23 @@ class SPIClass {
304304

305305
extern SPIClass SPI;
306306

307+
#if defined(SUBGHZSPI_BASE)
308+
class SUBGHZSPIClass : public SPIClass {
309+
public:
310+
SUBGHZSPIClass(): SPIClass{NC, NC, NC, NC}
311+
{
312+
_spi.spi = SUBGHZSPI;
313+
}
314+
315+
void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
316+
void beginTransaction(uint8_t pin, SPISettings settings);
317+
byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
318+
uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
319+
void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
320+
void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
321+
void enableDebugPins(uint32_t mosi = DEBUG_SUBGHZSPI_MOSI, uint32_t miso = DEBUG_SUBGHZSPI_MISO, uint32_t sclk = DEBUG_SUBGHZSPI_SCLK, uint32_t ssel = DEBUG_SUBGHZSPI_SS);
322+
};
323+
307324
#endif
325+
326+
#endif /* _SPI_H_INCLUDED */

libraries/SPI/src/utility/spi_com.c

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ uint32_t spi_getClkFreqInst(SPI_TypeDef *spi_inst)
159159
}
160160
}
161161
#endif // SPI6_BASE
162+
#if defined(SUBGHZSPI_BASE)
163+
if (spi_inst == SUBGHZSPI) {
164+
/* Source CLK is APB3 (PCLK3) is derived from AHB3 clock */
165+
spi_freq = HAL_RCC_GetHCLK3Freq();
166+
}
167+
#endif // SUBGHZSPI_BASE
162168
#endif
163169
}
164170
return spi_freq;
@@ -175,7 +181,14 @@ uint32_t spi_getClkFreq(spi_t *obj)
175181
uint32_t spi_freq = SystemCoreClock;
176182

177183
if (obj != NULL) {
178-
spi_inst = pinmap_peripheral(obj->pin_sclk, PinMap_SPI_SCLK);
184+
#if defined(SUBGHZSPI_BASE)
185+
if (obj->handle.Instance == SUBGHZSPI) {
186+
spi_inst = SUBGHZSPI;
187+
} else
188+
#endif
189+
{
190+
spi_inst = pinmap_peripheral(obj->pin_sclk, PinMap_SPI_SCLK);
191+
}
179192

180193
if (spi_inst != NP) {
181194
spi_freq = spi_getClkFreqInst(spi_inst);
@@ -224,41 +237,50 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
224237
uint32_t spi_freq = 0;
225238
uint32_t pull = 0;
226239

227-
// Determine the SPI to use
228-
SPI_TypeDef *spi_mosi = pinmap_peripheral(obj->pin_mosi, PinMap_SPI_MOSI);
229-
SPI_TypeDef *spi_miso = pinmap_peripheral(obj->pin_miso, PinMap_SPI_MISO);
230-
SPI_TypeDef *spi_sclk = pinmap_peripheral(obj->pin_sclk, PinMap_SPI_SCLK);
231-
SPI_TypeDef *spi_ssel = pinmap_peripheral(obj->pin_ssel, PinMap_SPI_SSEL);
240+
#if defined(SUBGHZSPI_BASE)
241+
if (handle->Instance != SUBGHZSPI) {
242+
#endif
243+
// Determine the SPI to use
244+
SPI_TypeDef *spi_mosi = pinmap_peripheral(obj->pin_mosi, PinMap_SPI_MOSI);
245+
SPI_TypeDef *spi_miso = pinmap_peripheral(obj->pin_miso, PinMap_SPI_MISO);
246+
SPI_TypeDef *spi_sclk = pinmap_peripheral(obj->pin_sclk, PinMap_SPI_SCLK);
247+
SPI_TypeDef *spi_ssel = pinmap_peripheral(obj->pin_ssel, PinMap_SPI_SSEL);
232248

233-
/* Pins MOSI/MISO/SCLK must not be NP. ssel can be NP. */
234-
if (spi_mosi == NP || spi_miso == NP || spi_sclk == NP) {
235-
core_debug("ERROR: at least one SPI pin has no peripheral\n");
236-
return;
237-
}
249+
/* Pins MOSI/MISO/SCLK must not be NP. ssel can be NP. */
250+
if (spi_mosi == NP || spi_miso == NP || spi_sclk == NP) {
251+
core_debug("ERROR: at least one SPI pin has no peripheral\n");
252+
return;
253+
}
238254

239-
SPI_TypeDef *spi_data = pinmap_merge_peripheral(spi_mosi, spi_miso);
240-
SPI_TypeDef *spi_cntl = pinmap_merge_peripheral(spi_sclk, spi_ssel);
255+
SPI_TypeDef *spi_data = pinmap_merge_peripheral(spi_mosi, spi_miso);
256+
SPI_TypeDef *spi_cntl = pinmap_merge_peripheral(spi_sclk, spi_ssel);
241257

242-
obj->spi = pinmap_merge_peripheral(spi_data, spi_cntl);
258+
obj->spi = pinmap_merge_peripheral(spi_data, spi_cntl);
243259

244-
// Are all pins connected to the same SPI instance?
245-
if (spi_data == NP || spi_cntl == NP || obj->spi == NP) {
246-
core_debug("ERROR: SPI pins mismatch\n");
247-
return;
248-
}
260+
// Are all pins connected to the same SPI instance?
261+
if (spi_data == NP || spi_cntl == NP || obj->spi == NP) {
262+
core_debug("ERROR: SPI pins mismatch\n");
263+
return;
264+
}
249265

250-
// Configure the SPI pins
251-
if (obj->pin_ssel != NC) {
252-
handle->Init.NSS = SPI_NSS_HARD_OUTPUT;
266+
// Configure the SPI pins
267+
if (obj->pin_ssel != NC) {
268+
handle->Init.NSS = SPI_NSS_HARD_OUTPUT;
269+
} else {
270+
handle->Init.NSS = SPI_NSS_SOFT;
271+
}
272+
#if defined(SUBGHZSPI_BASE)
253273
} else {
254274
handle->Init.NSS = SPI_NSS_SOFT;
255275
}
276+
#endif
256277

257278
/* Fill default value */
258279
handle->Instance = obj->spi;
259280
handle->Init.Mode = SPI_MODE_MASTER;
260281

261282
spi_freq = spi_getClkFreqInst(obj->spi);
283+
/* For SUBGHZSPI, 'SPI_BAUDRATEPRESCALER_*' == 'SUBGHZSPI_BAUDRATEPRESCALER_*' */
262284
if (speed >= (spi_freq / SPI_SPEED_CLOCK_DIV2_MHZ)) {
263285
handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
264286
} else if (speed >= (spi_freq / SPI_SPEED_CLOCK_DIV4_MHZ)) {
@@ -318,18 +340,23 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
318340
handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* Recommended setting to avoid glitches */
319341
#endif
320342

321-
/* Configure SPI GPIO pins */
322-
pinmap_pinout(obj->pin_mosi, PinMap_SPI_MOSI);
323-
pinmap_pinout(obj->pin_miso, PinMap_SPI_MISO);
324-
pinmap_pinout(obj->pin_sclk, PinMap_SPI_SCLK);
325-
/*
326-
* According the STM32 Datasheet for SPI peripheral we need to PULLDOWN
327-
* or PULLUP the SCK pin according the polarity used.
328-
*/
329-
pull = (handle->Init.CLKPolarity == SPI_POLARITY_LOW) ? GPIO_PULLDOWN : GPIO_PULLUP;
330-
pin_PullConfig(get_GPIO_Port(STM_PORT(obj->pin_sclk)), STM_LL_GPIO_PIN(obj->pin_sclk), pull);
331-
pinmap_pinout(obj->pin_ssel, PinMap_SPI_SSEL);
332-
343+
#if defined(SUBGHZSPI_BASE)
344+
if (handle->Instance != SUBGHZSPI) {
345+
#endif
346+
/* Configure SPI GPIO pins */
347+
pinmap_pinout(obj->pin_mosi, PinMap_SPI_MOSI);
348+
pinmap_pinout(obj->pin_miso, PinMap_SPI_MISO);
349+
pinmap_pinout(obj->pin_sclk, PinMap_SPI_SCLK);
350+
/*
351+
* According the STM32 Datasheet for SPI peripheral we need to PULLDOWN
352+
* or PULLUP the SCK pin according the polarity used.
353+
*/
354+
pull = (handle->Init.CLKPolarity == SPI_POLARITY_LOW) ? GPIO_PULLDOWN : GPIO_PULLUP;
355+
pin_PullConfig(get_GPIO_Port(STM_PORT(obj->pin_sclk)), STM_LL_GPIO_PIN(obj->pin_sclk), pull);
356+
pinmap_pinout(obj->pin_ssel, PinMap_SPI_SSEL);
357+
#if defined(SUBGHZSPI_BASE)
358+
}
359+
#endif
333360
#if defined SPI1_BASE
334361
// Enable SPI clock
335362
if (handle->Instance == SPI1) {
@@ -379,6 +406,14 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
379406
}
380407
#endif
381408

409+
#if defined SUBGHZSPI_BASE
410+
if (handle->Instance == SUBGHZSPI) {
411+
__HAL_RCC_SUBGHZSPI_CLK_ENABLE();
412+
__HAL_RCC_SUBGHZSPI_FORCE_RESET();
413+
__HAL_RCC_SUBGHZSPI_RELEASE_RESET();
414+
}
415+
#endif
416+
382417
HAL_SPI_Init(handle);
383418

384419
/* In order to set correctly the SPI polarity we need to enable the peripheral */
@@ -448,6 +483,14 @@ void spi_deinit(spi_t *obj)
448483
__HAL_RCC_SPI6_CLK_DISABLE();
449484
}
450485
#endif
486+
487+
#if defined SUBGHZSPI_BASE
488+
if (handle->Instance == SUBGHZSPI) {
489+
__HAL_RCC_SUBGHZSPI_FORCE_RESET();
490+
__HAL_RCC_SUBGHZSPI_RELEASE_RESET();
491+
__HAL_RCC_SUBGHZSPI_CLK_DISABLE();
492+
}
493+
#endif
451494
}
452495

453496
/**

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy