@@ -107,104 +107,78 @@ void spi_reset(void) {
107
107
spi_clock_disable (ALL_CLOCKS & ~(never_reset_mask ));
108
108
}
109
109
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 ,
111
121
const mcu_pin_obj_t * sck , const mcu_pin_obj_t * mosi ,
112
122
const mcu_pin_obj_t * miso ) {
113
-
114
- //match pins to SPI objects
115
- SPI_TypeDef * SPIx ;
123
+ bool spi_taken = false;
116
124
117
125
uint8_t sck_len = MP_ARRAY_SIZE (mcu_spi_sck_list );
118
126
uint8_t mosi_len = MP_ARRAY_SIZE (mcu_spi_mosi_list );
119
127
uint8_t miso_len = MP_ARRAY_SIZE (mcu_spi_miso_list );
120
- bool spi_taken = false;
121
128
122
129
//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
123
139
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 ;
195
150
}
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 ;
196
167
}
197
168
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" ));
201
171
} 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" ));
207
173
}
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 ];
208
182
209
183
//Start GPIO for each pin
210
184
GPIO_InitTypeDef GPIO_InitStruct = {0 };
0 commit comments