Skip to content

Commit dcf80e3

Browse files
authored
Merge pull request #3067 from jepler/stm-spi-pin-search
STM32: revamp SPI pin search code
2 parents 9b4b655 + 959b4da commit dcf80e3

File tree

2 files changed

+63
-85
lines changed

2 files changed

+63
-85
lines changed

locale/circuitpython.pot

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: PACKAGE VERSION\n"
1010
"Report-Msgid-Bugs-To: \n"
11-
"POT-Creation-Date: 2020-07-02 15:29+0200\n"
11+
"POT-Creation-Date: 2020-07-07 14:38-0500\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414
"Language-Team: LANGUAGE <[email protected]>\n"
@@ -1092,6 +1092,10 @@ msgstr ""
10921092
msgid "Must provide MISO or MOSI pin"
10931093
msgstr ""
10941094

1095+
#: ports/stm/common-hal/busio/SPI.c
1096+
msgid "Must provide SCK pin"
1097+
msgstr ""
1098+
10951099
#: shared-bindings/rgbmatrix/RGBMatrix.c
10961100
#, c-format
10971101
msgid "Must use a multiple of 6 rgb pins, not %d"

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

Lines changed: 58 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -107,104 +107,78 @@ void spi_reset(void) {
107107
spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
108108
}
109109

110-
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
110+
STATIC const mcu_periph_obj_t *find_pin_function(const mcu_periph_obj_t *table, size_t sz, const mcu_pin_obj_t *pin, int periph_index) {
111+
for(size_t i = 0; i<sz; i++, table++) {
112+
if(periph_index == table->periph_index && pin == table->pin ) {
113+
return table;
114+
}
115+
}
116+
return NULL;
117+
}
118+
119+
//match pins to SPI objects
120+
STATIC int check_pins(busio_spi_obj_t *self,
111121
const mcu_pin_obj_t * sck, const mcu_pin_obj_t * mosi,
112122
const mcu_pin_obj_t * miso) {
113-
114-
//match pins to SPI objects
115-
SPI_TypeDef * SPIx;
123+
bool spi_taken = false;
116124

117125
uint8_t sck_len = MP_ARRAY_SIZE(mcu_spi_sck_list);
118126
uint8_t mosi_len = MP_ARRAY_SIZE(mcu_spi_mosi_list);
119127
uint8_t miso_len = MP_ARRAY_SIZE(mcu_spi_miso_list);
120-
bool spi_taken = false;
121128

122129
//SCK is not optional. MOSI and MISO are
130+
if (!sck) {
131+
mp_raise_ValueError(translate("Must provide SCK pin"));
132+
}
133+
134+
if (!miso && !mosi) {
135+
mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
136+
}
137+
138+
// Loop over each possibility for SCK. Check whether MISO and/or MOSI can be used on the same peripheral
123139
for (uint i = 0; i < sck_len; i++) {
124-
if (mcu_spi_sck_list[i].pin == sck) {
125-
//if both MOSI and MISO exist, loop search normally
126-
if ((mosi != NULL) && (miso != NULL)) {
127-
//MOSI
128-
for (uint j = 0; j < mosi_len; j++) {
129-
if (mcu_spi_mosi_list[j].pin == mosi) {
130-
//MISO
131-
for (uint k = 0; k < miso_len; k++) {
132-
if ((mcu_spi_miso_list[k].pin == miso) //everything needs the same index
133-
&& (mcu_spi_sck_list[i].periph_index == mcu_spi_mosi_list[j].periph_index)
134-
&& (mcu_spi_sck_list[i].periph_index == mcu_spi_miso_list[k].periph_index)) {
135-
//keep looking if the SPI is taken, edge case
136-
if (reserved_spi[mcu_spi_sck_list[i].periph_index - 1]) {
137-
spi_taken = true;
138-
continue;
139-
}
140-
//store pins if not
141-
self->sck = &mcu_spi_sck_list[i];
142-
self->mosi = &mcu_spi_mosi_list[j];
143-
self->miso = &mcu_spi_miso_list[k];
144-
break;
145-
}
146-
}
147-
if (self->sck != NULL) {
148-
break; // Multi-level break to pick lowest peripheral
149-
}
150-
}
151-
}
152-
if (self->sck != NULL) {
153-
break;
154-
}
155-
// if just MISO, reduce search
156-
} else if (miso != NULL) {
157-
for (uint j = 0; j < miso_len; j++) {
158-
if ((mcu_spi_miso_list[j].pin == miso) //only SCK and MISO need the same index
159-
&& (mcu_spi_sck_list[i].periph_index == mcu_spi_miso_list[j].periph_index)) {
160-
if (reserved_spi[mcu_spi_sck_list[i].periph_index - 1]) {
161-
spi_taken = true;
162-
continue;
163-
}
164-
self->sck = &mcu_spi_sck_list[i];
165-
self->mosi = NULL;
166-
self->miso = &mcu_spi_miso_list[j];
167-
break;
168-
}
169-
}
170-
if (self->sck != NULL) {
171-
break;
172-
}
173-
// if just MOSI, reduce search
174-
} else if (mosi != NULL) {
175-
for (uint j = 0; j < mosi_len; j++) {
176-
if ((mcu_spi_mosi_list[j].pin == mosi) //only SCK and MOSI need the same index
177-
&& (mcu_spi_sck_list[i].periph_index == mcu_spi_mosi_list[j].periph_index)) {
178-
if (reserved_spi[mcu_spi_sck_list[i].periph_index - 1]) {
179-
spi_taken = true;
180-
continue;
181-
}
182-
self->sck = &mcu_spi_sck_list[i];
183-
self->mosi = &mcu_spi_mosi_list[j];
184-
self->miso = NULL;
185-
break;
186-
}
187-
}
188-
if (self->sck != NULL) {
189-
break;
190-
}
191-
} else {
192-
//throw an error immediately
193-
mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
194-
}
140+
const mcu_periph_obj_t *mcu_spi_sck = &mcu_spi_sck_list[i];
141+
if (mcu_spi_sck->pin != sck) {
142+
continue;
143+
}
144+
145+
int periph_index = mcu_spi_sck->periph_index;
146+
147+
const mcu_periph_obj_t *mcu_spi_miso = NULL;
148+
if (miso && !(mcu_spi_miso = find_pin_function(mcu_spi_miso_list, miso_len, miso, periph_index))) {
149+
continue;
195150
}
151+
152+
const mcu_periph_obj_t *mcu_spi_mosi = NULL;
153+
if (mosi && !(mcu_spi_mosi = find_pin_function(mcu_spi_mosi_list, mosi_len, mosi, periph_index))) {
154+
continue;
155+
}
156+
157+
if (reserved_spi[periph_index-1]) {
158+
spi_taken = true;
159+
continue;
160+
}
161+
162+
self->sck = mcu_spi_sck;
163+
self->mosi = mcu_spi_mosi;
164+
self->miso = mcu_spi_miso;
165+
166+
return periph_index;
196167
}
197168

198-
//handle typedef selection, errors
199-
if (self->sck != NULL && (self->mosi != NULL || self->miso != NULL)) {
200-
SPIx = mcu_spi_banks[self->sck->periph_index - 1];
169+
if (spi_taken) {
170+
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
201171
} else {
202-
if (spi_taken) {
203-
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
204-
} else {
205-
mp_raise_ValueError(translate("Invalid SPI pin selection"));
206-
}
172+
mp_raise_ValueError(translate("Invalid SPI pin selection"));
207173
}
174+
}
175+
176+
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
177+
const mcu_pin_obj_t * sck, const mcu_pin_obj_t * mosi,
178+
const mcu_pin_obj_t * miso) {
179+
180+
int periph_index = check_pins(self, sck, mosi, miso);
181+
SPI_TypeDef * SPIx = mcu_spi_banks[periph_index - 1];
208182

209183
//Start GPIO for each pin
210184
GPIO_InitTypeDef GPIO_InitStruct = {0};

0 commit comments

Comments
 (0)