@@ -39,6 +39,7 @@ typedef struct _machine_spi_obj_t {
3939 uint8_t id ;
4040 SPI_Type * inst ;
4141 bool is_lp ;
42+ uint32_t bits ;
4243} machine_spi_obj_t ;
4344
4445static 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
246247 // Get static peripheral object.
247248 machine_spi_obj_t * self = & machine_spi_obj [spi_id ];
248249
250+ // Set args
251+ self -> bits = args [ARG_bits ].u_int ;
252+
249253 // here we would check the sck/mosi/miso pins and configure them, but it's not implemented
250254 if (args [ARG_sck ].u_obj != MP_OBJ_NULL ||
251255 args [ARG_mosi ].u_obj != MP_OBJ_NULL ||
@@ -294,22 +298,50 @@ static void machine_spi_deinit(mp_obj_base_t *self_in) {
294298 }
295299}
296300
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+
297311static void machine_spi_transfer (mp_obj_base_t * self_in , size_t len , const uint8_t * src , uint8_t * dest ) {
298312 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+ }
313345 }
314346}
315347
0 commit comments