Skip to content

Commit 16f9d7f

Browse files
iabdalkaderdpgeorge
authored andcommitted
alif/machine_spi: Improve transfer function to poll events.
Poll events during SPI transfer (USB fails during long transfers otherwise). And add a timeout for the blocking transfer. Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
1 parent 4a1edc4 commit 16f9d7f

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

ports/alif/machine_spi.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4445
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
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+
297311
static 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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy