From 8e38d02ced0ea5511e268fd677cc81378a4cf4c3 Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Thu, 11 Jan 2024 15:23:03 -0500 Subject: [PATCH] Fix issues with new async SPI changes that broke compiling for B_U585I_IOT2A (#204) * Fix issues with new async SPI changes that broke compiling for B_U585I_IOT2A * Few more incorrect nullptrs * Fix style --- .../COMPONENT_EMW3080B/EMW3080B_SPI.cpp | 21 ++++--- .../COMPONENT_EMW3080B/EMW3080B_SPI.h | 4 +- .../COMPONENT_EMW3080B/mx_wifi_mbed_os.cpp | 38 ++++++++++- .../COMPONENT_EMW3080B/mx_wifi_mbed_os.h | 63 ++++++++++--------- drivers/include/drivers/SPI.h | 18 +++--- 5 files changed, 94 insertions(+), 50 deletions(-) diff --git a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.cpp b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.cpp index 459bb928b7..87dcb60b0a 100644 --- a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.cpp +++ b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.cpp @@ -195,12 +195,12 @@ void EMW3080B_SPI::spi_handler(int event) } -int32_t EMW3080B_SPI::TransmitReceive(uint8_t *txdata, uint8_t *rxdata, uint32_t datalen, +int32_t EMW3080B_SPI::TransmitReceive(uint8_t *txdata, CacheAlignedBuffer &rxdata, uint32_t datalen, uint32_t timeout) { int32_t ret = 0; debug_if(_debug_level >= DEBUG_LOG, "EMW3080B_SPI : Spi Tx Rx %" PRIu32 "\n", datalen); - SPI::transfer((const uint8_t *) txdata, (int) datalen, rxdata, (int) datalen, callback(this, &EMW3080B_SPI::spi_handler), SPI_EVENT_COMPLETE); + SPI::transfer(txdata, (int) datalen, rxdata, (int) datalen, callback(this, &EMW3080B_SPI::spi_handler), SPI_EVENT_COMPLETE); if (SEM_WAIT(spi_transfer_done_sem, timeout, NULL) != SEM_OK) { debug_if(_debug_level >= DEBUG_WARNING, "EMW3080B_SPI : Timeout on TransmitReceive %d\n", spi_handler_count); ret = -1; @@ -210,11 +210,11 @@ int32_t EMW3080B_SPI::TransmitReceive(uint8_t *txdata, uint8_t *rxdata, uint32_t } -int32_t EMW3080B_SPI::Transmit(uint8_t *txdata, uint32_t datalen, uint32_t timeout) +int32_t EMW3080B_SPI::Transmit(uint8_t *const txdata, uint32_t datalen, uint32_t timeout) { int32_t ret = 0; debug_if(_debug_level >= DEBUG_LOG, "EMW3080B_SPI : Spi Tx %" PRIu32 "\n", datalen); - SPI::transfer((const uint8_t *) txdata, (int) datalen, (uint8_t *)NULL, (int) datalen, callback(this, &EMW3080B_SPI::spi_handler), SPI_EVENT_COMPLETE); + SPI::transfer(txdata, (int) datalen, nullptr, (int) datalen, callback(this, &EMW3080B_SPI::spi_handler), SPI_EVENT_COMPLETE); if (SEM_WAIT(spi_transfer_done_sem, timeout, NULL) != SEM_OK) { debug_if(_debug_level >= DEBUG_WARNING, "EMW3080B_SPI : Timeout on Transmit\n"); ret = -1; @@ -222,11 +222,11 @@ int32_t EMW3080B_SPI::Transmit(uint8_t *txdata, uint32_t datalen, uint32_t timeo return ret; } -int32_t EMW3080B_SPI::Receive(uint8_t *rxdata, uint32_t datalen, uint32_t timeout) +int32_t EMW3080B_SPI::Receive(CacheAlignedBuffer &rxdata, uint32_t datalen, uint32_t timeout) { int32_t ret = 0; debug_if(_debug_level >= DEBUG_LOG, "EMW3080B_SPI : Spi Rx %" PRIu32 "\n", datalen); - SPI::transfer((const uint8_t *) NULL, (int) datalen, rxdata, (int) datalen, callback(this, &EMW3080B_SPI::spi_handler), SPI_EVENT_COMPLETE); + SPI::transfer(nullptr, (int) datalen, rxdata, (int) datalen, callback(this, &EMW3080B_SPI::spi_handler), SPI_EVENT_COMPLETE); if (SEM_WAIT(spi_transfer_done_sem, timeout, NULL) != SEM_OK) { debug_if(_debug_level >= DEBUG_WARNING, "EMW3080B_SPI : Timeout on Receive\n"); ret = -1; @@ -291,10 +291,13 @@ void EMW3080B_SPI::process_txrx_poll(uint32_t timeout) sheader.type = 0; sheader.len = 0; - if (TransmitReceive((uint8_t *)&mheader, (uint8_t *)&sheader, sizeof(mheader), SPI_MAX_TRANSMIT_DURATION)) { + StaticCacheAlignedBuffer rxBuffer; + if (TransmitReceive((uint8_t *)&mheader, rxBuffer, sizeof(mheader), SPI_MAX_TRANSMIT_DURATION)) { MX_WIFI_SPI_CS_HIGH(); debug_if(_debug_level >= DEBUG_WARNING, "EMW3080B_SPI : Send mheader error\r\n"); } + memcpy(&sheader, rxBuffer.data(), sizeof(mheader)); + if (sheader.type != SPI_READ) { MX_WIFI_SPI_CS_HIGH(); debug_if(_debug_level >= DEBUG_WARNING, "EMW3080B_SPI : Invalid SPI type %02x\r\n", sheader.type); @@ -342,12 +345,12 @@ void EMW3080B_SPI::process_txrx_poll(uint32_t timeout) spi_tx_data = NULL; spi_tx_len = 0; if (NULL != p) { - ret = TransmitReceive(txdata, p, datalen, SPI_MAX_TRANSMIT_DURATION); + ret = TransmitReceive(txdata, netb->buffer, datalen, SPI_MAX_TRANSMIT_DURATION); } else { ret = Transmit(txdata, datalen, SPI_MAX_TRANSMIT_DURATION); } } else { - ret = Receive(p, datalen, SPI_MAX_TRANSMIT_DURATION); + ret = Receive(netb->buffer, datalen, SPI_MAX_TRANSMIT_DURATION); } if (ret) { diff --git a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.h b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.h index f7c00fe158..6aa1c14240 100644 --- a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.h +++ b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/EMW3080B_SPI.h @@ -61,9 +61,9 @@ private: uint8_t *spi_tx_data = NULL; uint16_t spi_tx_len = 0; - int32_t TransmitReceive(uint8_t *txdata, uint8_t *rxdata, uint32_t datalen, uint32_t timeout); + int32_t TransmitReceive(uint8_t *txdata, CacheAlignedBuffer &rxdata, uint32_t datalen, uint32_t timeout); int32_t Transmit(uint8_t *txdata, uint32_t datalen, uint32_t timeout); - int32_t Receive(uint8_t *rxdata, uint32_t datalen, uint32_t timeout); + int32_t Receive(CacheAlignedBuffer &rxdata, uint32_t datalen, uint32_t timeout); void spi_handler(int event); int8_t mx_wifi_spi_txrx_start(void); diff --git a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.cpp b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.cpp index 579158bfb1..ae60567d0a 100644 --- a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.cpp +++ b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.cpp @@ -20,7 +20,43 @@ extern "C" { -#if BASIC_MALLOC == 0 +#if BASIC_MALLOC + + +// CacheAlignedBuffer-based implementation + +mx_buf_t *mx_buf_alloc(uint32_t len) +{ + return new mx_buf_t(len); +} + +void mx_buf_free(mx_buf_t *p) +{ + delete p; +} + +void mx_buf_hide_header(mx_buf_t *p, int32_t n) +{ + p->header_len += n; +} + +uint8_t *mx_buf_payload(mx_buf_t *p) +{ + return p->buffer.data() + p->header_len; +} + +uint32_t mx_buf_get_size(mx_buf_t *p) +{ + return p->len; +} + +void mx_buf_set_size(mx_buf_t *p, int32_t n) +{ + p->len = n; +} + +#else + // Memory manager implementation mx_buf_t *mx_buf_alloc(uint32_t len) { diff --git a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.h b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.h index e621fab5d0..51c79a4b99 100644 --- a/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.h +++ b/connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.h @@ -15,6 +15,10 @@ #ifndef MX_WIFI_CMSIS_OS_H #define MX_WIFI_CMSIS_OS_H +#ifdef __cplusplus +#include "CacheAlignedBuffer.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -34,46 +38,50 @@ extern "C" { #define MX_WIFI_FREE free #endif /* MX_WIFI_FREE */ +// Set to 1 to use basic memory allocation (new and delete). +// Set to 0 to use emac3080b_global_memory_manager for memory allocations. #define BASIC_MALLOC 1 -/* Assume that OS is not used when bypass is disabled */ #if BASIC_MALLOC -typedef struct mx_buf { - uint32_t len; - uint32_t header_len; - uint8_t data[1]; -} mx_buf_t; -static inline mx_buf_t *mx_buf_alloc(uint32_t len) +#ifdef __cplusplus + +/** + * Structure for an MX wifi buffer. + * Only visible to C++ files -- to C files, it is an opaque void pointer. + */ +struct mx_buf { - mx_buf_t *p = (mx_buf_t *) MX_WIFI_MALLOC(len + sizeof(mx_buf_t) -1U); - if (NULL != p) { - p->len = len; - p->header_len = 0; - } - return p; + DynamicCacheAlignedBuffer buffer; + uint32_t header_len = 0; + uint32_t len; -} + mx_buf(size_t max_len): + buffer(max_len), + len(max_len) + {} +}; +typedef mx_buf mx_buf_t; + +#else + +typedef void mx_buf_t; + +#endif + +#else /* BASIC_MALLOC */ + +typedef void mx_buf_t; + +#endif /* BASIC_MALLOC */ #define MX_NET_BUFFER_ALLOC(len) mx_buf_alloc(len) -#define MX_NET_BUFFER_FREE(p) MX_WIFI_FREE(p) -#define MX_NET_BUFFER_HIDE_HEADER(p, n) (p)->header_len += (n) -#define MX_NET_BUFFER_PAYLOAD(p) &(p)->data[(p)->header_len] -#define MX_NET_BUFFER_SET_PAYLOAD_SIZE(p, size) (p)->len = (size) -#define MX_NET_BUFFER_GET_PAYLOAD_SIZE(p) (p)->len - -#else /* BASIC_ALLOC */ - -#define MX_NET_BUFFER_ALLOC(len) mx_buf_alloc((len)) #define MX_NET_BUFFER_FREE(p) mx_buf_free((p)) #define MX_NET_BUFFER_HIDE_HEADER(p, n) mx_buf_hide_header((p),(n)) #define MX_NET_BUFFER_PAYLOAD(p) mx_buf_payload((p)) #define MX_NET_BUFFER_SET_PAYLOAD_SIZE(p, size) mx_buf_set_size((p),(size)) #define MX_NET_BUFFER_GET_PAYLOAD_SIZE(p) mx_buf_get_size((p)) - -typedef void mx_buf_t; - mx_buf_t *mx_buf_alloc(uint32_t len); void mx_buf_free(mx_buf_t *p); void mx_buf_hide_header(mx_buf_t *p, int32_t n); @@ -81,9 +89,6 @@ uint8_t *mx_buf_payload(mx_buf_t *p); uint32_t mx_buf_get_size(mx_buf_t *p); void mx_buf_set_size(mx_buf_t *p, int32_t n); -#endif /* BASIC_ALLOC */ - - void mbed_delay(uint32_t delay); void *mbed_mutex_new(void); void mbed_mutex_delete(void *); diff --git a/drivers/include/drivers/SPI.h b/drivers/include/drivers/SPI.h index 58e79f9f16..c6944061a8 100644 --- a/drivers/include/drivers/SPI.h +++ b/drivers/include/drivers/SPI.h @@ -390,16 +390,16 @@ public: // Overloads of the above to support passing nullptr template typename std::enable_if::value, int>::type - write(const std::nullptr_t *tx_buffer, int tx_length, WordT *rx_buffer, int rx_length) + write(const std::nullptr_t tx_buffer, int tx_length, WordT *rx_buffer, int rx_length) { - return write_internal(reinterpret_cast(tx_buffer), tx_length, reinterpret_cast(rx_buffer), rx_length); + return write_internal(tx_buffer, tx_length, reinterpret_cast(rx_buffer), rx_length); } template typename std::enable_if::value, int>::type - write(const WordT *tx_buffer, int tx_length, std::nullptr_t *rx_buffer, int rx_length) + write(const WordT *tx_buffer, int tx_length, std::nullptr_t rx_buffer, int rx_length) { - return write_internal(reinterpret_cast(tx_buffer), tx_length, reinterpret_cast(rx_buffer), rx_length); + return write_internal(reinterpret_cast(tx_buffer), tx_length, rx_buffer, rx_length); } /** @@ -487,14 +487,14 @@ public: // Overloads of the above to support passing nullptr template typename std::enable_if::value, int>::type - transfer(const std::nullptr_t *tx_buffer, int tx_length, CacheAlignedBuffer &rx_buffer, int rx_length, const event_callback_t &callback, int event = SPI_EVENT_COMPLETE) + transfer(const std::nullptr_t tx_buffer, int tx_length, CacheAlignedBuffer &rx_buffer, int rx_length, const event_callback_t &callback, int event = SPI_EVENT_COMPLETE) { MBED_ASSERT(rx_length <= static_cast(rx_buffer.capacity())); - return transfer_internal(tx_buffer, tx_length, rx_buffer, rx_length, callback, event); + return transfer_internal(tx_buffer, tx_length, rx_buffer.data(), rx_length, callback, event); } template typename std::enable_if::value, int>::type - transfer(const WordT *tx_buffer, int tx_length, std::nullptr_t *rx_buffer, int rx_length, const event_callback_t &callback, int event = SPI_EVENT_COMPLETE) + transfer(const WordT *tx_buffer, int tx_length, std::nullptr_t rx_buffer, int rx_length, const event_callback_t &callback, int event = SPI_EVENT_COMPLETE) { return transfer_internal(tx_buffer, tx_length, rx_buffer, rx_length, callback, event); } @@ -535,14 +535,14 @@ public: // Overloads of the above to support passing nullptr template typename std::enable_if::value, int>::type - transfer_and_wait(const std::nullptr_t *tx_buffer, int tx_length, CacheAlignedBuffer &rx_buffer, int rx_length, rtos::Kernel::Clock::duration_u32 timeout = rtos::Kernel::wait_for_u32_forever) + transfer_and_wait(const std::nullptr_t tx_buffer, int tx_length, CacheAlignedBuffer &rx_buffer, int rx_length, rtos::Kernel::Clock::duration_u32 timeout = rtos::Kernel::wait_for_u32_forever) { MBED_ASSERT(rx_length <= static_cast(rx_buffer.capacity())); return transfer_and_wait_internal(tx_buffer, tx_length, rx_buffer.data(), rx_length, timeout); } template typename std::enable_if::value, int>::type - transfer_and_wait(const WordT *tx_buffer, int tx_length, std::nullptr_t *rx_buffer, int rx_length, rtos::Kernel::Clock::duration_u32 timeout = rtos::Kernel::wait_for_u32_forever) + transfer_and_wait(const WordT *tx_buffer, int tx_length, std::nullptr_t rx_buffer, int rx_length, rtos::Kernel::Clock::duration_u32 timeout = rtos::Kernel::wait_for_u32_forever) { return transfer_and_wait_internal(tx_buffer, tx_length, rx_buffer, rx_length, timeout); }