mirror of https://github.com/ARMmbed/mbed-os.git
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.pull/2852/head
parent
bcf7ee2e51
commit
9323ad204a
|
@ -433,7 +433,7 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
|
||||||
NVIC_EnableIRQ(irq_n);
|
NVIC_EnableIRQ(irq_n);
|
||||||
|
|
||||||
// enable the right hal transfer
|
// enable the right hal transfer
|
||||||
static uint16_t sink;
|
//static uint16_t sink;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
switch(transfer_type) {
|
switch(transfer_type) {
|
||||||
case SPI_TRANSFER_TYPE_TXRX:
|
case SPI_TRANSFER_TYPE_TXRX:
|
||||||
|
@ -442,9 +442,9 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
|
||||||
case SPI_TRANSFER_TYPE_TX:
|
case SPI_TRANSFER_TYPE_TX:
|
||||||
// TODO: we do not use `HAL_SPI_Transmit_IT`, since it has some unknown bug
|
// TODO: we do not use `HAL_SPI_Transmit_IT`, since it has some unknown bug
|
||||||
// and makes the HAL keep some state and then that fails successive transfers
|
// and makes the HAL keep some state and then that fails successive transfers
|
||||||
// rc = HAL_SPI_Transmit_IT(handle, (uint8_t*)tx, words);
|
rc = HAL_SPI_Transmit_IT(handle, (uint8_t*)tx, words);
|
||||||
rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t*)tx, (uint8_t*)&sink, 1);
|
//rc = HAL_SPI_TransmitReceive_IT(handle, (uint8_t*)tx, (uint8_t*)&sink, 1);
|
||||||
length = is16bit ? 2 : 1;
|
//length = is16bit ? 2 : 1;
|
||||||
break;
|
break;
|
||||||
case SPI_TRANSFER_TYPE_RX:
|
case SPI_TRANSFER_TYPE_RX:
|
||||||
// the receive function also "transmits" the receive buffer so in order
|
// 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,
|
||||||
|
|
||||||
// enable the right hal transfer
|
// enable the right hal transfer
|
||||||
if (use_tx && use_rx) {
|
if (use_tx && use_rx) {
|
||||||
// transfer with the min(tx, rx), then later either transmit _or_ receive the remainder
|
// we cannot manage different rx / tx sizes, let's use smaller one
|
||||||
size_t size = (tx_length < rx_length)? tx_length : rx_length;
|
size_t size = (tx_length < rx_length)? tx_length : rx_length;
|
||||||
|
if(tx_length != rx_length) {
|
||||||
|
DEBUG_PRINTF("SPI: Full duplex transfer only 1 size: %d\n", size);
|
||||||
|
obj->tx_buff.length = size;
|
||||||
|
obj->rx_buff.length = size;
|
||||||
|
}
|
||||||
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TXRX, tx, rx, size);
|
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TXRX, tx, rx, size);
|
||||||
} else if (use_tx) {
|
} else if (use_tx) {
|
||||||
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX, tx, NULL, tx_length);
|
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)
|
||||||
HAL_SPI_IRQHandler(handle);
|
HAL_SPI_IRQHandler(handle);
|
||||||
|
|
||||||
if (HAL_SPI_GetState(handle) == HAL_SPI_STATE_READY) {
|
if (HAL_SPI_GetState(handle) == HAL_SPI_STATE_READY) {
|
||||||
// adjust buffer positions
|
// When HAL SPI is back to READY state, check if there was an error
|
||||||
size_t tx_size = (handle->TxXferSize - handle->TxXferCount);
|
|
||||||
size_t rx_size = (handle->RxXferSize - handle->RxXferCount);
|
|
||||||
// 16 bit transfers need to be doubled to get bytes
|
|
||||||
if (handle->Init.DataSize == SPI_DATASIZE_16BIT) {
|
|
||||||
tx_size *= 2;
|
|
||||||
rx_size *= 2;
|
|
||||||
}
|
|
||||||
// adjust buffer positions
|
|
||||||
if (obj->spi.transfer_type != SPI_TRANSFER_TYPE_RX) {
|
|
||||||
obj->tx_buff.pos += tx_size;
|
|
||||||
}
|
|
||||||
if (obj->spi.transfer_type != SPI_TRANSFER_TYPE_TX) {
|
|
||||||
obj->rx_buff.pos += rx_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle->TxXferCount > 0) {DEBUG_PRINTF("SPI: TxXferCount: %u\n", handle->TxXferCount);}
|
|
||||||
if (handle->RxXferCount > 0) {DEBUG_PRINTF("SPI: RxXferCount: %u\n", handle->RxXferCount);}
|
|
||||||
|
|
||||||
int error = HAL_SPI_GetError(handle);
|
int error = HAL_SPI_GetError(handle);
|
||||||
if(error != HAL_SPI_ERROR_NONE) {
|
if(error != HAL_SPI_ERROR_NONE) {
|
||||||
// something went wrong and the transfer has definitely completed
|
// something went wrong and the transfer has definitely completed
|
||||||
|
@ -553,26 +540,8 @@ uint32_t spi_irq_handler_asynch(spi_t *obj)
|
||||||
event |= SPI_EVENT_RX_OVERFLOW;
|
event |= SPI_EVENT_RX_OVERFLOW;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// figure out if we need to transfer more data:
|
// else we're done
|
||||||
if (obj->tx_buff.pos < obj->tx_buff.length) {
|
|
||||||
//DEBUG_PRINTF("t%u ", obj->tx_buff.pos);
|
|
||||||
// we need to transfer more data
|
|
||||||
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_TX,
|
|
||||||
obj->tx_buff.buffer + obj->tx_buff.pos, // offset the initial buffer by the position
|
|
||||||
NULL, // there is no receive buffer
|
|
||||||
obj->tx_buff.length - obj->tx_buff.pos); // transfer the remaining bytes only
|
|
||||||
} else if (obj->rx_buff.pos < obj->rx_buff.length) {
|
|
||||||
//DEBUG_PRINTF("r%u ", obj->rx_buff.pos);
|
|
||||||
// we need to receive more data
|
|
||||||
spi_master_start_asynch_transfer(obj, SPI_TRANSFER_TYPE_RX,
|
|
||||||
NULL, // there is no transmit buffer
|
|
||||||
obj->rx_buff.buffer + obj->rx_buff.pos, // offset the initial buffer by the position
|
|
||||||
obj->rx_buff.length - obj->rx_buff.pos); // transfer one byte at a time, until we received everything
|
|
||||||
} else {
|
|
||||||
// everything is ok, nothing else needs to be transferred
|
|
||||||
event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
|
event = SPI_EVENT_COMPLETE | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE;
|
||||||
DEBUG_PRINTF("SPI: Done: %u, %u\n", obj->tx_buff.pos, obj->rx_buff.pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue