@@ -39,6 +39,7 @@ typedef struct _machine_spi_obj_t {
39
39
uint8_t id ;
40
40
SPI_Type * inst ;
41
41
bool is_lp ;
42
+ uint32_t bits ;
42
43
} machine_spi_obj_t ;
43
44
44
45
static machine_spi_obj_t machine_spi_obj [] = {
@@ -246,6 +247,9 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
246
247
// Get static peripheral object.
247
248
machine_spi_obj_t * self = & machine_spi_obj [spi_id ];
248
249
250
+ // Set args
251
+ self -> bits = args [ARG_bits ].u_int ;
252
+
249
253
// here we would check the sck/mosi/miso pins and configure them, but it's not implemented
250
254
if (args [ARG_sck ].u_obj != MP_OBJ_NULL ||
251
255
args [ARG_mosi ].u_obj != MP_OBJ_NULL ||
@@ -294,22 +298,50 @@ static void machine_spi_deinit(mp_obj_base_t *self_in) {
294
298
}
295
299
}
296
300
301
+ static void machine_spi_poll_flag (SPI_Type * spi , uint32_t flag , uint32_t timeout ) {
302
+ mp_uint_t tick_start = mp_hal_ticks_ms ();
303
+ while (!(spi -> SPI_SR & flag )) {
304
+ if (mp_hal_ticks_ms () - tick_start >= timeout ) {
305
+ mp_raise_OSError (MP_ETIMEDOUT );
306
+ }
307
+ mp_event_handle_nowait ();
308
+ }
309
+ }
310
+
297
311
static void machine_spi_transfer (mp_obj_base_t * self_in , size_t len , const uint8_t * src , uint8_t * dest ) {
298
312
machine_spi_obj_t * self = (machine_spi_obj_t * )self_in ;
299
- spi_transfer_t spi_xfer = {
300
- .tx_buff = src ,
301
- .tx_total_cnt = len ,
302
- .rx_buff = dest ,
303
- .rx_total_cnt = len ,
304
- .tx_default_val = 0xFF ,
305
- .tx_default_enable = true,
306
- .mode = SPI_TMOD_TX_AND_RX ,
307
- };
308
- // TODO redo transfer_blocking to timeout and poll events.
309
- if (!self -> is_lp ) {
310
- spi_transfer_blocking (self -> inst , & spi_xfer );
311
- } else {
312
- lpspi_transfer_blocking (self -> inst , & spi_xfer );
313
+ volatile uint32_t * dr = self -> inst -> SPI_DR ;
314
+
315
+ spi_set_tmod (self -> inst , SPI_TMOD_TX_AND_RX );
316
+
317
+ for (size_t i = 0 ; i < len ; i ++ ) {
318
+ // Wait for space in the TX FIFO
319
+ machine_spi_poll_flag (self -> inst , SPI_SR_TFNF , 100 );
320
+
321
+ // Send data
322
+ if (src == NULL ) {
323
+ * dr = 0xFFFFFFFFU ;
324
+ } else if (self -> bits > 16 ) {
325
+ * dr = ((uint32_t * )src )[i ];
326
+ } else if (self -> bits > 8 ) {
327
+ * dr = ((uint16_t * )src )[i ];
328
+ } else {
329
+ * dr = ((uint8_t * )src )[i ];
330
+ }
331
+
332
+ // Wait for data in the RX FIFO
333
+ machine_spi_poll_flag (self -> inst , SPI_SR_RFNE , 100 );
334
+
335
+ // Recv data
336
+ if (dest == NULL ) {
337
+ (void )* dr ;
338
+ } else if (self -> bits > 16 ) {
339
+ ((uint32_t * )dest )[i ] = * dr ;
340
+ } else if (self -> bits > 8 ) {
341
+ ((uint16_t * )dest )[i ] = * dr ;
342
+ } else {
343
+ ((uint8_t * )dest )[i ] = * dr ;
344
+ }
313
345
}
314
346
}
315
347
0 commit comments