Skip to content

Commit 00086a6

Browse files
author
Laurent MEUNIER
committed
[STM32F4] Simplify spi Asynch transfer implementation
Following discussion on: it seems now clear that the transfer API is meant to be used either with only Rx, or only Tx or Rx and Tx with the same lenth. Therefore we're removing support of transfers of Rx and Tx with different lenghts - this makes porting to HAL more direct and simpler.
1 parent e68b550 commit 00086a6

File tree

1 file changed

+14
-45
lines changed
  • hal/targets/hal/TARGET_STM/TARGET_STM32F4

1 file changed

+14
-45
lines changed

hal/targets/hal/TARGET_STM/TARGET_STM32F4/spi_api.c

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
433433
NVIC_EnableIRQ(irq_n);
434434

435435
// enable the right hal transfer
436-
static uint16_t sink;
436+
//static uint16_t sink;
437437
int rc = 0;
438438
switch(transfer_type) {
439439
case SPI_TRANSFER_TYPE_TXRX:
@@ -442,9 +442,9 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
442442
case SPI_TRANSFER_TYPE_TX:
443443
// TODO: we do not use `HAL_SPI_Transmit_IT`, since it has some unknown bug
444444
// and makes the HAL keep some state and then that fails successive transfers
445-
// rc = HAL_SPI_Transmit_IT(handle, (uint8_t*)tx, words);
446-
rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t*)tx, (uint8_t*)&sink, 1);
447-
length = is16bit ? 2 : 1;
445+
rc = HAL_SPI_Transmit_IT(handle, (uint8_t*)tx, words);
446+
//rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t*)tx, (uint8_t*)&sink, 1);
447+
//length = is16bit ? 2 : 1;
448448
break;
449449
case SPI_TRANSFER_TYPE_RX:
450450
// the receive function also "transmits" the receive buffer so in order
@@ -503,8 +503,13 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
503503

504504
// enable the right hal transfer
505505
if (use_tx && use_rx) {
506-
// transfer with the min(tx, rx), then later either transmit _or_ receive the remainder
506+
// we cannot manage different rx / tx sizes, let's use smaller one
507507
size_t size = (tx_length < rx_length)? tx_length : rx_length;
508+
if(tx_length != rx_length) {
509+
DEBUG_PRINTF("SPI: Full duplex transfer only 1 size: %d\n", size);
510+
obj->tx_buff.length = size;
511+
obj->rx_buff.length = size;
512+
}
508513
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TXRX, tx, rx, size);
509514
} else if (use_tx) {
510515
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX, tx, NULL, tx_length);
@@ -524,25 +529,7 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
524529
HAL_SPI_IRQHandler(handle);
525530

526531
if (HAL_SPI_GetState(handle) == HAL_SPI_STATE_READY) {
527-
// adjust buffer positions
528-
size_t tx_size = (handle->TxXferSize - handle->TxXferCount);
529-
size_t rx_size = (handle->RxXferSize - handle->RxXferCount);
530-
// 16 bit transfers need to be doubled to get bytes
531-
if (handle->Init.DataSize == SPI_DATASIZE_16BIT) {
532-
tx_size *= 2;
533-
rx_size *= 2;
534-
}
535-
// adjust buffer positions
536-
if (obj->spi.transfer_type != SPI_TRANSFER_TYPE_RX) {
537-
obj->tx_buff.pos += tx_size;
538-
}
539-
if (obj->spi.transfer_type != SPI_TRANSFER_TYPE_TX) {
540-
obj->rx_buff.pos += rx_size;
541-
}
542-
543-
if (handle->TxXferCount > 0) {DEBUG_PRINTF("SPI: TxXferCount: %u\n", handle->TxXferCount);}
544-
if (handle->RxXferCount > 0) {DEBUG_PRINTF("SPI: RxXferCount: %u\n", handle->RxXferCount);}
545-
532+
// When HAL SPI is back to READY state, check if there was an error
546533
int error = HAL_SPI_GetError(handle);
547534
if(error != HAL_SPI_ERROR_NONE) {
548535
// something went wrong and the transfer has definitely completed
@@ -553,27 +540,9 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
553540
event |= SPI_EVENT_RX_OVERFLOW;
554541
}
555542
} else {
556-
// figure out if we need to transfer more data:
557-
if (obj->tx_buff.pos < obj->tx_buff.length) {
558-
//DEBUG_PRINTF("t%u ", obj->tx_buff.pos);
559-
// we need to transfer more data
560-
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX,
561-
obj->tx_buff.buffer + obj->tx_buff.pos, // offset the initial buffer by the position
562-
NULL, // there is no receive buffer
563-
obj->tx_buff.length - obj->tx_buff.pos); // transfer the remaining bytes only
564-
} else if (obj->rx_buff.pos < obj->rx_buff.length) {
565-
//DEBUG_PRINTF("r%u ", obj->rx_buff.pos);
566-
// we need to receive more data
567-
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_RX,
568-
NULL, // there is no transmit buffer
569-
obj->rx_buff.buffer + obj->rx_buff.pos, // offset the initial buffer by the position
570-
obj->rx_buff.length - obj->rx_buff.pos); // transfer one byte at a time, until we received everything
571-
} else {
572-
// everything is ok, nothing else needs to be transferred
573-
event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
574-
DEBUG_PRINTF("SPI: Done: %u, %u\n", obj->tx_buff.pos, obj->rx_buff.pos);
575-
}
576-
}
543+
// else we're done
544+
event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
545+
}
577546
}
578547

579548
if (event) DEBUG_PRINTF("SPI: Event: 0x%x\n", event);

0 commit comments

Comments
 (0)