summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2020-07-08 11:32:26 -0700
committerGitHub <noreply@github.com>2020-07-08 11:32:26 -0700
commitdcf80e39dc6a0c7293226ff16defbe95b07c5ff9 (patch)
tree39ff3608d01066bb370931bd0156528ddd3e07fd
parent9b4b655b031c82dd319803ecf66bd0994edc200e (diff)
parent959b4da9bbaf48e10707b1a5859f7cc4c5ee0b84 (diff)
Merge pull request #3067 from jepler/stm-spi-pin-search
STM32: revamp SPI pin search code
-rw-r--r--locale/circuitpython.pot6
-rw-r--r--ports/stm/common-hal/busio/SPI.c142
2 files changed, 63 insertions, 85 deletions
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index 6e32ebab9..f3c9d0411 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-07-02 15:29+0200\n"
+"POT-Creation-Date: 2020-07-07 14:38-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1092,6 +1092,10 @@ msgstr ""
msgid "Must provide MISO or MOSI pin"
msgstr ""
+#: ports/stm/common-hal/busio/SPI.c
+msgid "Must provide SCK pin"
+msgstr ""
+
#: shared-bindings/rgbmatrix/RGBMatrix.c
#, c-format
msgid "Must use a multiple of 6 rgb pins, not %d"
diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c
index c76705cd8..d4dd6cb3f 100644
--- a/ports/stm/common-hal/busio/SPI.c
+++ b/ports/stm/common-hal/busio/SPI.c
@@ -107,104 +107,78 @@ void spi_reset(void) {
spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
}
-void common_hal_busio_spi_construct(busio_spi_obj_t *self,
+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) {
+ for(size_t i = 0; i<sz; i++, table++) {
+ if(periph_index == table->periph_index && pin == table->pin ) {
+ return table;
+ }
+ }
+ return NULL;
+}
+
+//match pins to SPI objects
+STATIC int check_pins(busio_spi_obj_t *self,
const mcu_pin_obj_t * sck, const mcu_pin_obj_t * mosi,
const mcu_pin_obj_t * miso) {
-
- //match pins to SPI objects
- SPI_TypeDef * SPIx;
+ bool spi_taken = false;
uint8_t sck_len = MP_ARRAY_SIZE(mcu_spi_sck_list);
uint8_t mosi_len = MP_ARRAY_SIZE(mcu_spi_mosi_list);
uint8_t miso_len = MP_ARRAY_SIZE(mcu_spi_miso_list);
- bool spi_taken = false;
//SCK is not optional. MOSI and MISO are
+ if (!sck) {
+ mp_raise_ValueError(translate("Must provide SCK pin"));
+ }
+
+ if (!miso && !mosi) {
+ mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
+ }
+
+ // Loop over each possibility for SCK. Check whether MISO and/or MOSI can be used on the same peripheral
for (uint i = 0; i < sck_len; i++) {
- if (mcu_spi_sck_list[i].pin == sck) {
- //if both MOSI and MISO exist, loop search normally
- if ((mosi != NULL) && (miso != NULL)) {
- //MOSI
- for (uint j = 0; j < mosi_len; j++) {
- if (mcu_spi_mosi_list[j].pin == mosi) {
- //MISO
- for (uint k = 0; k < miso_len; k++) {
- if ((mcu_spi_miso_list[k].pin == miso) //everything needs the same index
- && (mcu_spi_sck_list[i].periph_index == mcu_spi_mosi_list[j].periph_index)
- && (mcu_spi_sck_list[i].periph_index == mcu_spi_miso_list[k].periph_index)) {
- //keep looking if the SPI is taken, edge case
- if (reserved_spi[mcu_spi_sck_list[i].periph_index - 1]) {
- spi_taken = true;
- continue;
- }
- //store pins if not
- self->sck = &mcu_spi_sck_list[i];
- self->mosi = &mcu_spi_mosi_list[j];
- self->miso = &mcu_spi_miso_list[k];
- break;
- }
- }
- if (self->sck != NULL) {
- break; // Multi-level break to pick lowest peripheral
- }
- }
- }
- if (self->sck != NULL) {
- break;
- }
- // if just MISO, reduce search
- } else if (miso != NULL) {
- for (uint j = 0; j < miso_len; j++) {
- if ((mcu_spi_miso_list[j].pin == miso) //only SCK and MISO need the same index
- && (mcu_spi_sck_list[i].periph_index == mcu_spi_miso_list[j].periph_index)) {
- if (reserved_spi[mcu_spi_sck_list[i].periph_index - 1]) {
- spi_taken = true;
- continue;
- }
- self->sck = &mcu_spi_sck_list[i];
- self->mosi = NULL;
- self->miso = &mcu_spi_miso_list[j];
- break;
- }
- }
- if (self->sck != NULL) {
- break;
- }
- // if just MOSI, reduce search
- } else if (mosi != NULL) {
- for (uint j = 0; j < mosi_len; j++) {
- if ((mcu_spi_mosi_list[j].pin == mosi) //only SCK and MOSI need the same index
- && (mcu_spi_sck_list[i].periph_index == mcu_spi_mosi_list[j].periph_index)) {
- if (reserved_spi[mcu_spi_sck_list[i].periph_index - 1]) {
- spi_taken = true;
- continue;
- }
- self->sck = &mcu_spi_sck_list[i];
- self->mosi = &mcu_spi_mosi_list[j];
- self->miso = NULL;
- break;
- }
- }
- if (self->sck != NULL) {
- break;
- }
- } else {
- //throw an error immediately
- mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
- }
+ const mcu_periph_obj_t *mcu_spi_sck = &mcu_spi_sck_list[i];
+ if (mcu_spi_sck->pin != sck) {
+ continue;
+ }
+
+ int periph_index = mcu_spi_sck->periph_index;
+
+ const mcu_periph_obj_t *mcu_spi_miso = NULL;
+ if (miso && !(mcu_spi_miso = find_pin_function(mcu_spi_miso_list, miso_len, miso, periph_index))) {
+ continue;
}
+
+ const mcu_periph_obj_t *mcu_spi_mosi = NULL;
+ if (mosi && !(mcu_spi_mosi = find_pin_function(mcu_spi_mosi_list, mosi_len, mosi, periph_index))) {
+ continue;
+ }
+
+ if (reserved_spi[periph_index-1]) {
+ spi_taken = true;
+ continue;
+ }
+
+ self->sck = mcu_spi_sck;
+ self->mosi = mcu_spi_mosi;
+ self->miso = mcu_spi_miso;
+
+ return periph_index;
}
- //handle typedef selection, errors
- if (self->sck != NULL && (self->mosi != NULL || self->miso != NULL)) {
- SPIx = mcu_spi_banks[self->sck->periph_index - 1];
+ if (spi_taken) {
+ mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
} else {
- if (spi_taken) {
- mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
- } else {
- mp_raise_ValueError(translate("Invalid SPI pin selection"));
- }
+ mp_raise_ValueError(translate("Invalid SPI pin selection"));
}
+}
+
+void common_hal_busio_spi_construct(busio_spi_obj_t *self,
+ const mcu_pin_obj_t * sck, const mcu_pin_obj_t * mosi,
+ const mcu_pin_obj_t * miso) {
+
+ int periph_index = check_pins(self, sck, mosi, miso);
+ SPI_TypeDef * SPIx = mcu_spi_banks[periph_index - 1];
//Start GPIO for each pin
GPIO_InitTypeDef GPIO_InitStruct = {0};