Update spi_api.c

Modified the spi_master_block_write() function yet again. SD related examples still read/erase/write the SD cards as expected and with these alterations the power consumption does not remain high after the SPI transaction has been finished. However i still only tested the SD functionality. Please test other SPI scenarios and different sensors as well to find out if this PR introduces unexpected bugs or not.

Changes:
- deleted the whole if (xfer.ui32NumBytes) condition as i did not find it logical (by that i mean xfer.ui32NumBytes was also true within the following else if (tx_length != rx_length){} block, so basically when the 2 buffers had different lengths an extra transfer has been done for nothing)
- removed the bool Rw = (rx_length >= tx_length) as the comparison >= has no sense anymore after if (tx_length == rx_length) on line 159.
pull/13861/head
Peter B 2020-10-28 23:28:34 +01:00 committed by GitHub
parent d56f942ae7
commit 02a12a8722
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 28 additions and 43 deletions

View File

@ -151,57 +151,42 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, cha
MBED_ASSERT(obj);
int chars_handled = 0;
uint32_t status = AM_HAL_STATUS_SUCCESS;
// perform a duplex xfer for the smaller of the two buffers
// always perform a duplex xfer
xfer.eDirection = AM_HAL_IOM_FULLDUPLEX;
xfer.ui32NumBytes = (tx_length > rx_length) ? rx_length : tx_length;
xfer.pui32RxBuffer = (uint32_t *)rx_buffer;
xfer.pui32TxBuffer = (uint32_t *)tx_buffer;
if (xfer.ui32NumBytes) {
uint32_t status = am_hal_iom_spi_blocking_fullduplex(obj->spi.iom_obj.iom.handle, &xfer);
if (AM_HAL_STATUS_SUCCESS != status) {
return 0;
}
chars_handled += xfer.ui32NumBytes;
if (tx_length == rx_length) {
xfer.pui32RxBuffer = (uint32_t *)rx_buffer;
xfer.pui32TxBuffer = (uint32_t *)tx_buffer;
xfer.ui32NumBytes = tx_length;
status = am_hal_iom_spi_blocking_fullduplex(obj->spi.iom_obj.iom.handle, &xfer);
}
// handle difference between buffers
else if (tx_length != rx_length) {
bool Rw = (rx_length >= tx_length);
// set up common config
xfer.eDirection = (Rw) ? AM_HAL_IOM_RX : AM_HAL_IOM_TX;
xfer.ui32NumBytes = (Rw) ? (rx_length - tx_length) : (tx_length - rx_length);
xfer.pui32RxBuffer = (Rw) ? (uint32_t *)(rx_buffer + chars_handled) : NULL;
xfer.pui32TxBuffer = (Rw) ? NULL : (uint32_t *)(tx_buffer + chars_handled);
uint32_t status = AM_HAL_STATUS_SUCCESS;
if (!Rw || (write_fill == SPI_FILL_CHAR)) {
// when transmitting (w) or reading with a zero fill just use a simplex transfer
uint8_t fill[xfer.ui32NumBytes];
memset(fill, write_fill, xfer.ui32NumBytes);
xfer.eDirection = AM_HAL_IOM_FULLDUPLEX;
xfer.pui32RxBuffer = (uint32_t *)&fill;
uint32_t status = am_hal_iom_spi_blocking_fullduplex(obj->spi.iom_obj.iom.handle, &xfer);
if (AM_HAL_STATUS_SUCCESS != status) {
return chars_handled;
}
chars_handled += xfer.ui32NumBytes;
} else {
// when reading with a nonzero fill use a duplex transfer
uint8_t fill[xfer.ui32NumBytes];
memset(fill, write_fill, xfer.ui32NumBytes);
xfer.eDirection = AM_HAL_IOM_FULLDUPLEX;
xfer.pui32TxBuffer = (uint32_t *)&fill;
uint32_t status = am_hal_iom_spi_blocking_fullduplex(obj->spi.iom_obj.iom.handle, &xfer);
if (AM_HAL_STATUS_SUCCESS != status) {
return chars_handled;
}
chars_handled += xfer.ui32NumBytes;
}
else if (tx_length < rx_length) {
xfer.pui32RxBuffer = (uint32_t *)rx_buffer;
xfer.ui32NumBytes = rx_length - tx_length;
uint8_t fill[xfer.ui32NumBytes];
memset(fill, write_fill, xfer.ui32NumBytes);
xfer.pui32TxBuffer = (uint32_t *)&fill;
status = am_hal_iom_spi_blocking_fullduplex(obj->spi.iom_obj.iom.handle, &xfer);
}
else {
xfer.pui32TxBuffer = (uint32_t *)tx_buffer;
xfer.ui32NumBytes = tx_length - rx_length;
uint8_t fill[xfer.ui32NumBytes];
memset(fill, write_fill, xfer.ui32NumBytes);
xfer.pui32RxBuffer = (uint32_t *)&fill;
status = am_hal_iom_spi_blocking_fullduplex(obj->spi.iom_obj.iom.handle, &xfer);
}
if (AM_HAL_STATUS_SUCCESS != status) {
return 0;
}
chars_handled += xfer.ui32NumBytes;
return chars_handled;
}