@@ -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