7#include "porting_assistant.h"
15#define BENCHMARK_ADDR_START 0x80100000
19#define BULK_RW_PACKET_LEN_BYTES (1496)
22#define BENCHMARK_WAIT_MS (2500)
26const struct chip_cfg *probed_chip_cfg;
35static bool validate_chip_id(uint32_t chip_id,
const struct chip_cfg *
chip_cfg)
49static volatile uint8_t irq_counter = 0;
55static void test_hal_irq_handle(
void)
69 return TEST_NO_RESULT;
84 return TEST_NO_RESULT;
103 "SDIO/SPI controller hardware error. Possible causes:\n"
104 " - SDIO/SPI controller not configured correctly\n"
105 " - SDIO/SPI controller clock not enabled\n\n");
110 "Timeout while executing an SDIO command. Possible causes:\n"
111 " - SDIO/SPI pins not set to correct function (e.g., output instead of alternative)\n"
112 " - SPI chip select not being asserted\n"
113 " - MM chip not powered on\n\n");
118 "CRC error in command or response while executing an SDIO command. Possible causes:\n"
119 " - Noise on SPI/SDIO lines\n"
120 " - Wrong SPI device selected\n\n");
125 "Timeout while transferring data. Possible causes:\n"
126 " - Communication errors due to noise on SPI/SDIO lines\n"
127 " - SPI/SDIO clock rate too low\n"
128 " - SPI/SDIO data timeout to aggressive\n\n");
133 "Data underflow. Possible causes:\n"
134 " - DMA incorrectly configured\n"
135 " - Data being fed into the SPI/SDIO controller FIFO too slowly\n\n");
140 "Data overrun. Possible causes:\n"
141 " - DMA incorrectly configured\n"
142 " - Data being read from the SPI/SDIO controller FIFO too slowly\n\n");
147 "An unspecified error occurred. This may be due to communications or other isuses.\n"
148 "Possible causes may include:\n"
149 " - SDIO/SPI controller not configured correctly\n"
150 " - Communication errors due to noise on SPI/SDIO lines\n\n");
177 for (chip_cfg_idx = 0; chip_cfg_idx < n_chip_cfgs; chip_cfg_idx++)
181 for (ii = 0; ii < 3; ii++)
183 ret = sdio_spi_read_le32(chip_cfgs[chip_cfg_idx].
reg_chip_id, &data);
192 if (validate_chip_id(data, &chip_cfgs[chip_cfg_idx]))
194 probed_chip_cfg = &chip_cfgs[chip_cfg_idx];
211 "Failed to read chip id due to a command timeout. Possible causes:\n"
212 " - SPI/SDIO controller not configured correctly\n"
213 " - SPI/SDIO pins not set to correct function (e.g., output instead of alternative)\n"
214 " - SPI Chip Select not being asserted (should be low during the transfer)\n"
215 " - MM chip not powered on\n\n");
219 TEST_LOG_APPEND(
"Failed to validate CRC for recieved data. Possible causes:\n"
220 " - Error in reading data from SPI/SDIO peripheral\n"
221 " - Possible noise on the SPI/SDIO lines causing corruption\n\n");
225 TEST_LOG_APPEND(
"Failed to match a valid chip ID\n");
229 TEST_LOG_APPEND(
"Failed to read chip ID due to an unknown error\n\n");
247bool process_sdio_spi_multi_byte_return(
int ret,
char *log_buf,
size_t log_buf_len)
259 "Failed to read chip ID due to the timeout. Possible causes:\n"
260 " - SPI/SDIO controller not configured correctly\n"
261 " - SPI/SDIO pins not set to correct function (e.g., output instead of alternative)\n"
262 " - SPI Chip Select not being asserted (should be low during the transfer)\n"
263 " - MM chip not powered on\n\n");
267 TEST_LOG_APPEND(
"Failed to validate CRC for recieved data. Possible causes:\n"
268 " - Error in reading data from SPI peripheral\n"
269 " - Possible noise on the SPI lines causing corruption\n\n");
274 TEST_LOG_APPEND(
"Invalid input was given to sdio_spi_read_le32().\n"
275 "Likely a NULL pointer for the data variable\n\n");
279 TEST_LOG_APPEND(
"Failed multi byte operation due to an unknown error\n\n");
291void populate_buffer(uint8_t *data, uint32_t length)
294 for (cnt = 0; cnt < length; cnt++)
309bool valid_buffer(uint8_t *data, uint32_t length, uint32_t offset)
311 uint8_t value = offset;
313 for (cnt = 0; cnt < length; cnt++)
315 if (data[cnt] != value++)
317 printf(
"\nInvalid data at %lu (offset=%lu, expect %02x got %02x)\n",
318 cnt, offset, value, data[cnt]);
329 enum test_result result = TEST_PASSED;
331 uint8_t *tx_data = (uint8_t *)
mmosal_malloc(BULK_RW_PACKET_LEN_BYTES);
332 uint8_t *rx_data = (uint8_t *)
mmosal_malloc(BULK_RW_PACKET_LEN_BYTES);
333 if ((tx_data == NULL) || (rx_data == NULL))
335 TEST_LOG_APPEND(
"Failed to allocate write/read buffers. Is there enough heap allocated?");
336 result = TEST_FAILED;
340 populate_buffer(tx_data, BULK_RW_PACKET_LEN_BYTES);
342 ret = sdio_spi_write_multi_byte(BENCHMARK_ADDR_START, tx_data, BULK_RW_PACKET_LEN_BYTES);
343 ok = process_sdio_spi_multi_byte_return(ret, log_buf, log_buf_len);
346 TEST_LOG_APPEND(
"Failure during sdio_spi_write_multi_byte\n");
347 result = TEST_FAILED;
351 ret = sdio_spi_read_multi_byte(BENCHMARK_ADDR_START, rx_data, BULK_RW_PACKET_LEN_BYTES);
352 ok = process_sdio_spi_multi_byte_return(ret, log_buf, log_buf_len);
355 TEST_LOG_APPEND(
"Failure during sdio_spi_read_multi_byte\n");
356 result = TEST_FAILED;
360 if (!valid_buffer(rx_data, BULK_RW_PACKET_LEN_BYTES, 0))
362 TEST_LOG_APPEND(
"Data read from the MM chip does not match the data written.\n");
363 result = TEST_FAILED;
393 enum test_result result = TEST_PASSED;
397 uint32_t time_taken_ms;
398 uint32_t benchmark_end_time;
399 uint32_t transaction_count = 0;
401 uint8_t *tx_data = (uint8_t *)
mmosal_malloc(BULK_RW_PACKET_LEN_BYTES + 16);
402 uint8_t *rx_data = (uint8_t *)
mmosal_malloc(BULK_RW_PACKET_LEN_BYTES);
403 if ((tx_data == NULL) || (rx_data == NULL))
405 TEST_LOG_APPEND(
"Failed to allocate write/read buffers. Is there enough heap allocated?");
406 result = TEST_FAILED;
410 populate_buffer(tx_data, BULK_RW_PACKET_LEN_BYTES + 16);
413 benchmark_end_time = start_time + BENCHMARK_WAIT_MS;
417 ret = sdio_spi_write_multi_byte(BENCHMARK_ADDR_START, tx_data + (offset & 15),
418 BULK_RW_PACKET_LEN_BYTES);
419 ok = process_sdio_spi_multi_byte_return(ret, log_buf, log_buf_len);
422 TEST_LOG_APPEND(
"Failure during sdio_spi_write_multi_byte\n");
423 result = TEST_FAILED;
427 ret = sdio_spi_read_multi_byte(BENCHMARK_ADDR_START, rx_data,
428 BULK_RW_PACKET_LEN_BYTES);
429 ok = process_sdio_spi_multi_byte_return(ret, log_buf, log_buf_len);
432 TEST_LOG_APPEND(
"Failure during sdio_spi_read_multi_byte\n");
433 result = TEST_FAILED;
444 if (!valid_buffer(rx_data, BULK_RW_PACKET_LEN_BYTES, offset & 15))
446 TEST_LOG_APPEND(
"Data read from the MM chip does not match the data written.\n");
447 result = TEST_FAILED;
451 time_taken_ms = end_time - start_time;
452 TEST_LOG_APPEND(
"Note: This will not be the final WLAN TPUT. See test step for more info.\n");
453 TEST_LOG_APPEND(
"\tTime spent (ms): %lu\n", time_taken_ms);
454 TEST_LOG_APPEND(
"\tTransaction count: %lu\n", transaction_count);
455 TEST_LOG_APPEND(
"\tBytes xferred: %lu\n", transaction_count * 2 * BULK_RW_PACKET_LEN_BYTES);
456 TEST_LOG_APPEND(
"\tRaw TPUT (kbit/s): %lu\n\n",
457 (transaction_count * 2 * BULK_RW_PACKET_LEN_BYTES * 8) / time_taken_ms);
477 enum test_result result = TEST_PASSED;
488 for (i = 0; i < 2; i++)
494 TEST_LOG_APPEND(
"BUSY pin set HIGH but mmhal_wlan_busy_is_asserted() returned false "
495 "(expected true)\n\n");
496 result = TEST_FAILED;
503 TEST_LOG_APPEND(
"BUSY pin is set LOW but mmhal_wlan_busy_is_asserted() returned true "
504 "(expected false)\n\n");
505 result = TEST_FAILED;
509 if (irq_counter != 2)
511 TEST_LOG_APPEND(
"BUSY pin IRQ hander was not called as expected. Expected 2 invocations, "
512 "but was invoked %u times\n\n",
514 result = TEST_FAILED;
519 for (i = 0; i < 2; i++)
528 TEST_LOG_APPEND(
"Busy IRQ is still enabled.\n\n");
529 result = TEST_FAILED;
int mmhal_wlan_sdio_startup(void)
Perform transport specific startup.
@ MMHAL_SDIO_INVALID_ARGUMENT
Invalid argument given (e.g., incorrect buffer alignment).
@ MMHAL_SDIO_HW_ERROR
Local hardware error (e.g., issue with SDIO controller).
@ MMHAL_SDIO_CMD_CRC_ERROR
CRC error executing SDIO command.
@ MMHAL_SDIO_DATA_OVERRUN
Overflow reading from SDIO controller FIFO.
@ MMHAL_SDIO_DATA_UNDERFLOW
Underflow filling SDIO controller FIFO.
@ MMHAL_SDIO_OTHER_ERROR
Another error not covered by the above error codes.
@ MMHAL_SDIO_DATA_TIMEOUT
Timeout transferring data.
@ MMHAL_SDIO_CMD_TIMEOUT
Timeout executing SDIO command.
void mmhal_wlan_hard_reset(void)
Hard reset the chip by asserting and then releasing the reset pin.
void mmhal_wlan_register_busy_irq_handler(mmhal_irq_handler_t handler)
Register a handler for busy interrupts.
void mmhal_wlan_set_busy_irq_enabled(bool enabled)
Sets whether the busy interrupt is enabled.
bool mmhal_wlan_busy_is_asserted(void)
Tests whether the busy pin is currently asserted.
void mmhal_wlan_init(void)
Initialize the WLAN HAL.
#define mmosal_malloc(size)
Allocate memory of the given size and return a pointer to it (malloc).
void mmosal_free(void *p)
Free the given memory allocation.
void mmosal_task_sleep(uint32_t duration_ms)
Sleep for a period of time, yielding during that time.
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
static bool mmosal_time_le(uint32_t a, uint32_t b)
Check if time a is less than or equal to time b, taking into account wrapping.
#define MM_UNUSED(_x)
Casts the given expression to void to avoid "unused" warnings from the compiler.
const struct test_step test_step_read_chip_id
Test definition.
const struct test_step test_step_verify_busy_pin
Test definition.
const struct test_step test_step_mmhal_wlan_sdio_startup
Test definition.
const struct test_step test_step_raw_tput
Test definition.
const struct test_step test_step_bulk_write_read
Test definition.
const struct test_step test_step_mmhal_wlan_hard_reset
Test definition.
const struct test_step test_step_mmhal_wlan_init
Test definition.
Chip configuration data structure.
const uint32_t * valid_chip_ids
List of valid chip IDs for this configuration.
int(* gpio_set_value)(uint8_t gpio_num, bool value)
Function to set GPIO value.
int(* gpio_set_oe)(uint8_t gpio_num, bool oe)
Function to set GPIO output enable.
size_t n_valid_chip_ids
Number of valid chip IDs in valid_chip_ids.
uint8_t busy_gpio_num
Busy GPIO number.
uint32_t reg_chip_id
Address of the chip ID register.