Skip to content

Commit 4ea1751

Browse files
authored
Merge pull request #1839 from fpistm/stm32wlspi
Add SUBGHZSPI support to SPI library.
2 parents 280efe1 + b192b02 commit 4ea1751

File tree

22 files changed

+904
-159
lines changed

22 files changed

+904
-159
lines changed

CI/update/stm32variant.py

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
uartrx_list = [] # ['PIN','name','UARTrx', ['af']]
3131
uartcts_list = [] # ['PIN','name','UARTcts', ['af']]
3232
uartrts_list = [] # ['PIN','name','UARTrts', ['af']]
33-
spimosi_list = [] # ['PIN','name','SPIMOSI', ['af']]
34-
spimiso_list = [] # ['PIN','name','SPIMISO', ['af']]
35-
spissel_list = [] # ['PIN','name','SPISSEL', ['af']]
36-
spisclk_list = [] # ['PIN','name','SPISCLK', ['af']]
33+
spimosi_list = [] # ['PIN','name','SPIMOSI', 'sort name', ['af']]
34+
spimiso_list = [] # ['PIN','name','SPIMISO', 'sort name', ['af']]
35+
spissel_list = [] # ['PIN','name','SPISSEL', 'sort name', ['af']]
36+
spisclk_list = [] # ['PIN','name','SPISCLK', 'sort name', ['af']]
3737
cantd_list = [] # ['PIN','name','CANTD', ['af']]
3838
canrd_list = [] # ['PIN','name','CANRD', ['af']]
3939
eth_list = [] # ['PIN','name','ETH', ['af']]
@@ -464,14 +464,14 @@ def store_uart(pin, name, signal):
464464

465465
# Store SPI pins
466466
def store_spi(pin, name, signal):
467-
if "_MISO" in signal:
468-
spimiso_list.append([pin, name, signal])
469-
if "_MOSI" in signal:
470-
spimosi_list.append([pin, name, signal])
471-
if "_SCK" in signal:
472-
spisclk_list.append([pin, name, signal])
473-
if "_NSS" in signal:
474-
spissel_list.append([pin, name, signal])
467+
if re.search("[-_]MISO", signal):
468+
spimiso_list.append([pin, name, signal, signal.removeprefix("DEBUG_")])
469+
if re.search("[-_]MOSI", signal):
470+
spimosi_list.append([pin, name, signal, signal.removeprefix("DEBUG_")])
471+
if re.search("[-_]SCK", signal):
472+
spisclk_list.append([pin, name, signal, signal.removeprefix("DEBUG_")])
473+
if re.search("[-_]NSS", signal):
474+
spissel_list.append([pin, name, signal, signal.removeprefix("DEBUG_")])
475475

476476

477477
# Store CAN pins
@@ -749,6 +749,7 @@ def spi_pinmap(lst):
749749
spi_pins_list = []
750750
winst = []
751751
wpin = []
752+
sp = re.compile(r"-|_")
752753
if lst == spimosi_list:
753754
aname = "SPI_MOSI"
754755
elif lst == spimiso_list:
@@ -759,16 +760,18 @@ def spi_pinmap(lst):
759760
aname = "SPI_SSEL"
760761
for p in lst:
761762
# 2nd element is the SPI_XXXX signal
762-
inst = p[2].split("_")[0]
763+
# but using 3rd which contains the stripped one
764+
# used to properly sort them
765+
inst = sp.split(p[3])[0]
763766
winst.append(len(inst))
764767
wpin.append(len(p[0]))
765768
spi_pins_list.append(
766769
{
767770
"pin": p[0],
768771
"inst": inst,
769772
"mode": "STM_MODE_AF_PP",
770-
"pull": "GPIO_PULLUP",
771-
"af": p[3],
773+
"pull": "GPIO_PULLUP" if inst != "SUBGHZSPI" else "GPIO_NOPULL",
774+
"af": p[4],
772775
}
773776
)
774777
return dict(
@@ -1278,6 +1281,36 @@ def timer_variant():
12781281
return dict(tone=tone, servo=servo)
12791282

12801283

1284+
def alias_definition():
1285+
# alias for STM32WL
1286+
alias_list = []
1287+
if mcu_family == "STM32WL":
1288+
mosi = [
1289+
mosi[0].replace("_", "", 1)
1290+
for mosi in spimosi_list
1291+
if "SUBGHZSPI" in mosi[2]
1292+
]
1293+
miso = [
1294+
miso[0].replace("_", "", 1)
1295+
for miso in spimiso_list
1296+
if "SUBGHZSPI" in miso[2]
1297+
]
1298+
sck = [
1299+
sck[0].replace("_", "", 1) for sck in spisclk_list if "SUBGHZSPI" in sck[2]
1300+
]
1301+
ssel = [
1302+
ssel[0].replace("_", "", 1)
1303+
for ssel in spissel_list
1304+
if "SUBGHZSPI" in ssel[2]
1305+
]
1306+
if mosi and miso and sck and ssel:
1307+
alias_list.append(("DEBUG_SUBGHZSPI_MOSI", mosi[0]))
1308+
alias_list.append(("DEBUG_SUBGHZSPI_MISO", miso[0]))
1309+
alias_list.append(("DEBUG_SUBGHZSPI_SCLK", sck[0]))
1310+
alias_list.append(("DEBUG_SUBGHZSPI_SS", ssel[0]))
1311+
return alias_list
1312+
1313+
12811314
def print_variant(generic_list, alt_syswkup_list):
12821315
variant_h_template = j2_env.get_template(variant_h_filename)
12831316
variant_cpp_template = j2_env.get_template(variant_cpp_filename)
@@ -1299,6 +1332,9 @@ def print_variant(generic_list, alt_syswkup_list):
12991332
# Timers definition
13001333
timer = timer_variant()
13011334

1335+
# Alias to ease some usage
1336+
alias_list = alias_definition()
1337+
13021338
# Manage all pins number, PinName and analog pins
13031339
analog_index = 0
13041340
pins_number_list = []
@@ -1379,6 +1415,7 @@ def print_variant(generic_list, alt_syswkup_list):
13791415
timer=timer,
13801416
serial=serial,
13811417
hal_modules_list=hal_modules_list,
1418+
alias_list=alias_list,
13821419
)
13831420
)
13841421

@@ -1536,6 +1573,10 @@ def natural_sortkey2(list_2_elem):
15361573
return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[2]))
15371574

15381575

1576+
def natural_sortkey3(list_2_elem):
1577+
return tuple(int(num) if num else alpha for num, alpha in tokenize(list_2_elem[3]))
1578+
1579+
15391580
def sort_my_lists():
15401581
io_list.sort(key=natural_sortkey)
15411582
dualpad_list.sort(key=natural_sortkey)
@@ -1550,9 +1591,13 @@ def sort_my_lists():
15501591
uartrx_list.sort(key=natural_sortkey)
15511592
uartcts_list.sort(key=natural_sortkey)
15521593
uartrts_list.sort(key=natural_sortkey)
1594+
spimosi_list.sort(key=natural_sortkey3)
15531595
spimosi_list.sort(key=natural_sortkey)
1596+
spimiso_list.sort(key=natural_sortkey3)
15541597
spimiso_list.sort(key=natural_sortkey)
1598+
spissel_list.sort(key=natural_sortkey3)
15551599
spissel_list.sort(key=natural_sortkey)
1600+
spisclk_list.sort(key=natural_sortkey3)
15561601
spisclk_list.sort(key=natural_sortkey)
15571602
cantd_list.sort(key=natural_sortkey)
15581603
canrd_list.sort(key=natural_sortkey)

CI/update/templates/variant_generic.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@
9999
#define PIN_SERIAL_TX {{serial.tx}}
100100
#endif
101101

102+
{% if alias_list %}
103+
// Alias
104+
{% for alias in alias_list %}
105+
#ifndef {{alias[0]}}
106+
#define {{"%-21s %s"|format(alias[0], alias[1])}}
107+
#endif
108+
{% endfor %}
109+
110+
{% endif %}
102111
{% if hal_modules_list %}
103112
// Extra HAL modules
104113
{% for hal_module in hal_modules_list %}

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: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -74,29 +74,26 @@ enum SPITransferMode {
7474

7575
class SPISettings {
7676
public:
77-
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE)
78-
{
79-
clk = clock;
80-
bOrder = bitOrder;
81-
noReceive = noRecv;
82-
83-
if (SPI_MODE0 == dataMode) {
84-
dMode = SPI_MODE_0;
85-
} else if (SPI_MODE1 == dataMode) {
86-
dMode = SPI_MODE_1;
87-
} else if (SPI_MODE2 == dataMode) {
88-
dMode = SPI_MODE_2;
89-
} else if (SPI_MODE3 == dataMode) {
90-
dMode = SPI_MODE_3;
91-
}
92-
}
93-
SPISettings()
94-
{
95-
pinCS = -1;
96-
clk = SPI_SPEED_CLOCK_DEFAULT;
97-
bOrder = MSBFIRST;
98-
dMode = SPI_MODE_0;
99-
}
77+
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE)
78+
: pinCS(-1),
79+
clk(clock),
80+
bOrder(bitOrder),
81+
dMode((spi_mode_e)(
82+
(SPI_MODE0 == dataMode) ? SPI_MODE_0 :
83+
(SPI_MODE1 == dataMode) ? SPI_MODE_1 :
84+
(SPI_MODE2 == dataMode) ? SPI_MODE_2 :
85+
(SPI_MODE3 == dataMode) ? SPI_MODE_3 :
86+
SPI_MODE0
87+
)),
88+
noReceive(noRecv)
89+
{ }
90+
constexpr SPISettings()
91+
: pinCS(-1),
92+
clk(SPI_SPEED_CLOCK_DEFAULT),
93+
bOrder(MSBFIRST),
94+
dMode(SPI_MODE_0),
95+
noReceive(SPI_TRANSMITRECEIVE)
96+
{ }
10097
private:
10198
int16_t pinCS; //CS pin associated to the configuration
10299
uint32_t clk; //specifies the spi bus maximum clock speed
@@ -151,15 +148,15 @@ class SPIClass {
151148
_spi.pin_ssel = (ssel);
152149
};
153150

154-
void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
151+
virtual void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
155152
void end(void);
156153

157154
/* This function should be used to configure the SPI instance in case you
158155
* don't use default parameters.
159156
* You can attach another CS pin to the SPI instance and each CS pin can be
160157
* attach with specific SPI settings.
161158
*/
162-
void beginTransaction(uint8_t pin, SPISettings settings);
159+
virtual void beginTransaction(uint8_t pin, SPISettings settings);
163160
void beginTransaction(SPISettings settings)
164161
{
165162
beginTransaction(CS_PIN_CONTROLLED_BY_USER, settings);
@@ -175,10 +172,10 @@ class SPIClass {
175172
* instance with begin() or beginTransaction().
176173
* You can specify the CS pin to use.
177174
*/
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);
175+
virtual byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
176+
virtual uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
177+
virtual void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
178+
virtual void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
182179

183180
// Transfer functions when user controls himself the CS pin.
184181
byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST)
@@ -233,6 +230,10 @@ class SPIClass {
233230
return &(_spi.handle);
234231
}
235232

233+
protected:
234+
// spi instance
235+
spi_t _spi;
236+
236237
private:
237238
/* Contains various spiSettings for the same spi instance. Each spi spiSettings
238239
is associated to a CS pin. */
@@ -241,10 +242,6 @@ class SPIClass {
241242
// Use to know which configuration is selected.
242243
int16_t _CSPinConfig;
243244

244-
// spi instance
245-
spi_t _spi;
246-
247-
248245
typedef enum {
249246
GET_IDX = 0,
250247
ADD_NEW_PIN = 1
@@ -304,4 +301,27 @@ class SPIClass {
304301

305302
extern SPIClass SPI;
306303

304+
#if defined(SUBGHZSPI_BASE)
305+
class SUBGHZSPIClass : public SPIClass {
306+
public:
307+
SUBGHZSPIClass(): SPIClass{NC, NC, NC, NC}
308+
{
309+
_spi.spi = SUBGHZSPI;
310+
}
311+
312+
void begin(uint8_t _pin = CS_PIN_CONTROLLED_BY_USER);
313+
void beginTransaction(uint8_t pin, SPISettings settings);
314+
byte transfer(uint8_t pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
315+
uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
316+
void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
317+
void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
318+
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);
319+
320+
using SPIClass::beginTransaction;
321+
using SPIClass::transfer;
322+
using SPIClass::transfer16;
323+
};
324+
307325
#endif
326+
327+
#endif /* _SPI_H_INCLUDED */

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