8000 stmhal/spi: Factor out SPI transfer code to a single function. · danni/micropython@9b64d19 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9b64d19

Browse files
stmhal/spi: Factor out SPI transfer code to a single function.
1 parent 3be8b68 commit 9b64d19

File tree

1 file changed

+77
-70
lines changed

1 file changed

+77
-70
lines changed

stmhal/spi.c

Lines changed: 77 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,79 @@ STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t
327327
return HAL_OK;
328328
}
329329

330+
STATIC void spi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf, uint32_t timeout) {
331+
// Note: there seems to be a problem sending 1 byte using DMA the first
332+
// time directly after the SPI/DMA is initialised. The cause of this is
333+
// unknown but we sidestep the issue by using polling for 1 byte transfer.
334+
335+
pyb_spi_obj_t *self = (pyb_spi_obj_t*)self_in;
336+
HAL_StatusTypeDef status;
337+
338+
if (dest_len == 0) {
339+
// send only
340+
if (src_len == 1 || query_irq() == IRQ_STATE_DISABLED) {
341+
status = HAL_SPI_Transmit(self->spi, (uint8_t*)src_buf, src_len, timeout);
342+
} else {
343+
DMA_HandleTypeDef tx_dma;
344+
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
345+
self->spi->hdmatx = &tx_dma;
346+
self->spi->hdmarx = NULL;
347+
status = HAL_SPI_Transmit_DMA(self->spi, (uint8_t*)src_buf, src_len);
348+
if (status == HAL_OK) {
349+
status = spi_wait_dma_finished(self->spi, timeout);
350+
}
351+
dma_deinit(self->tx_dma_descr);
352+
}
353+
} else if (src_len == 0) {
354+
// receive only
355+
if (dest_len == 1 || query_irq() == IRQ_STATE_DISABLED) {
356+
status = HAL_SPI_Receive(self->spi, dest_buf, dest_len, timeout);
357+
} else {
358+
DMA_HandleTypeDef tx_dma, rx_dma;
359+
if (self->spi->Init.Mode == SPI_MODE_MASTER) {
360+
// in master mode the HAL actually does a TransmitReceive call
361+
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
362+
self->spi->hdmatx = &tx_dma;
363+
} else {
364+
self->spi->hdmatx = NULL;
365+
}
366+
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
367+
self->spi->hdmarx = &rx_dma;
368+
369+
status = HAL_SPI_Receive_DMA(self->spi, dest_buf, dest_len);
370+
if (status == HAL_OK) {
371+
status = spi_wait_dma_finished(self->spi, timeout);
372+
}
373+
if (self->spi->hdmatx != NULL) {
374+
dma_deinit(self->tx_dma_descr);
375+
}
376+
dma_deinit(self->rx_dma_descr);
377+
}
378+
} else {
379+
// send and receive
380+
// requires src_len==dest_len
381+
if (src_len == 1 || query_irq() == IRQ_STATE_DISABLED) {
382+
status = HAL_SPI_TransmitReceive(self->spi, (uint8_t*)src_buf, dest_buf, src_len, timeout);
383+
} else {
384+
DMA_HandleTypeDef tx_dma, rx_dma;
385+
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
386+
self->spi->hdmatx = &tx_dma;
387+
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
388+
self->spi->hdmarx = &rx_dma;
389+
status = HAL_SPI_TransmitReceive_DMA(self->spi, (uint8_t*)src_buf, dest_buf, src_len);
390+
if (status == HAL_OK) {
391+
status = spi_wait_dma_finished(self->spi, timeout);
392+
}
393+
dma_deinit(self->tx_dma_descr);
394+
dma_deinit(self->rx_dma_descr);
395+
}
396+
}
397+
398+
if (status != HAL_OK) {
399+
mp_hal_raise(status);
400+
}
401+
}
402+
330403
/******************************************************************************/
331404
/* Micro Python bindings */
332405

@@ -556,27 +629,7 @@ STATIC mp_obj_t pyb_spi_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
556629
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
557630

558631
// send the data
559-
// Note: there seems to be a problem sending 1 byte using DMA the first
560-
// time directly after the SPI/DMA is initialised. The cause of this is
561-
// unknown but we sidestep the issue by using polling for 1 byte transfer.
562-
HAL_StatusTypeDef status;
563-
if (bufinfo.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
564-
status = HAL_SPI_Transmit(self->spi, bufinfo.buf, bufinfo.len, args[1].u_int);
565-
} else {
566-
DMA_HandleTypeDef tx_dma;
567-
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
568-
self->spi->hdmatx = &tx_dma;
569-
self->spi->hdmarx = NULL;
570-
status = HAL_SPI_Transmit_DMA(self->spi, bufinfo.buf, bufinfo.len);
571-
if (status == HAL_OK) {
572-
status = spi_wait_dma_finished(self->spi, args[1].u_int);
573-
}
574-
dma_deinit(self->tx_dma_descr);
575-
}
576-
577-
if (status != HAL_OK) {
578-
mp_hal_raise(status);
579-
}
632+
spi_transfer((mp_obj_base_t*)self, bufinfo.len, bufinfo.buf, 0, NULL, args[1].u_int);
580633

581634
return mp_const_none;
582635
}
@@ -610,34 +663,7 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
610663
mp_obj_t o_ret = pyb_buf_get_for_recv(args[0].u_obj, &vstr);
611664

612665
// receive the data
613-
HAL_StatusTypeDef status;
614-
if (vstr.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
615-
status = HAL_SPI_Receive(self->spi, (uint8_t*)vstr.buf, vstr.len, args[1].u_int);
616-
} else {
617-
DMA_HandleTypeDef tx_dma, rx_dma;
618-
if (self->spi->Init.Mode == SPI_MODE_MASTER) {
619-
// in master mode the HAL actually does a TransmitReceive call
620-
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
621-
self->spi->hdmatx = &tx_dma;
622-
} else {
623-
self->spi->hdmatx = NULL;
624-
}
625-
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
626-
self->spi->hdmarx = &rx_dma;
627-
628-
status = HAL_SPI_Receive_DMA(self->spi, (uint8_t*)vstr.buf, vstr.len);
629-
if (status == HAL_OK) {
630-
status = spi_wait_dma_finished(self->spi, args[1].u_int);
631-
}
632-
if (self->spi->hdmatx != NULL) {
633-
dma_deinit(self->tx_dma_descr);
634-
}
635-
dma_deinit(self->rx_dma_descr);
636-
}
637-
638-
if (status != HAL_OK) {
639-
mp_hal_raise(status);
640-
}
666+
spi_transfer((mp_obj_base_t*)self, 0, NULL, vstr.len, (uint8_t*)vstr.buf, args[1].u_int);
641667

642668
// return the received data
643669
if (o_ret != MP_OBJ_NULL) {
@@ -706,27 +732,8 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp
706732
}
707733
}
708734

709-
// send and receive the data
710-
HAL_StatusTypeDef status;
711-
if (bufinfo_send.len == 1 || query_irq() == IRQ_STATE_DISABLED) {
712-
status = HAL_SPI_TransmitReceive(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len, args[2].u_int);
713-
} else {
714-
DMA_HandleTypeDef tx_dma, rx_dma;
715-
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
716-
self->spi->hdmatx = &tx_dma;
717-
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
718-
self->spi->hdmarx = &rx_dma;
719-
status = HAL_SPI_TransmitReceive_DMA(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len);
720-
if (status == HAL_OK) {
721-
status = spi_wait_dma_finished(self->spi, args[2].u_int);
722-
}
723-
dma_deinit(self->tx_dma_descr);
724-
dma_deinit(self->rx_dma_descr);
725-
}
726-
727-
if (status != HAL_OK) {
728-
mp_hal_raise(status);
729-
}
735+
// do the transfer
736+
spi_transfer((mp_obj_base_t*)self, bufinfo_send.len, bufinfo_send.buf, bufinfo_recv.len, bufinfo_recv.buf, args[2].u_int);
730737

731738
// return the received data
732739
if (o_ret != MP_OBJ_NULL) {

0 commit comments

Comments
 (0)
0