I hate to be a squeaky wheel on this but I've found some strange behavior when trying to use the SPI Manager to schedule a transfer where the .p_tx_data address is a constant. I've had no trouble scheduling transactions from RAM. What I want to be able to do is schedule a transfer that will send a large block of memory declared as a constant. Something like this:
#define GIANT_BUFER_SIZE 4096 const uint8_t giant_buffer[GIANT_BUFER_SIZE];
When I try to schedule a transfer like this the SPI Manager just stop dead and skips over it. The transaction still reports a success, the CS line goes low, but nothing is transmitted. The transaction/transfer that follows, if it's from RAM, works perfect. I don't see any error log messages generated.
Here's an example test to show what happens (I've reduced the code to a more simple form):
Two small buffers are defined here. TEST_DATA is in RAM, CONST_TEST_DATA is declared as const. The transfer has a NULL address which is setup later.
uint8_t TEST_DATA[] = {0x02, 0x03}; const uint8_t CONST_TEST_DATA[] = {0x07, 0x08}; nrf_spi_mngr_transfer_t TEST_TRANSFER = NRF_SPI_MNGR_TRANSFER(NULL, 0, NULL, 0);
Setup the SPI config and the SPI Manager:
// SPI CONFIG nrf_drv_spi_config_t const m_disp_ILI9341_spi_config = { .sck_pin = SPI_SCK_PIN, .mosi_pin = SPI_MOSI_PIN, .miso_pin = SPI_MISO_PIN, .ss_pin = DISP_CS, .irq_priority = APP_IRQ_PRIORITY_LOWEST, .orc = 0xFF, .frequency = NRF_DRV_SPI_FREQ_8M, .mode = NRF_DRV_SPI_MODE_3, .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST }; //SPI Manager Instance NRF_SPI_MNGR_DEF(m_nrf_spi_mngr, 15, 0); nrf_spi_mngr_init(&m_nrf_spi_mngr, &m_master_spi_config);
Setup up the transaction:
nrf_spi_mngr_transaction_t TEST_DATA_TRANSACTION = { .begin_callback = NULL, .end_callback = NULL, .p_user_data = (void *)&ILI9341_DATA, .p_transfers = &TEST_TRANSFER, .number_of_transfers = 1, .p_required_spi_cfg = &m_disp_ILI9341_spi_config };
Finally, three transactions are scheduled. First from RAM, then from a const buffer, then from RAM again:
// Schedule the TEST transactions TEST_TRANSFER.p_tx_data = TEST_DATA; TEST_TRANSFER.tx_length = sizeof(TEST_DATA); ret_val = nrf_spi_mngr_schedule(&m_nrf_spi_mngr, &TEST_DATA_TRANSACTION); TEST_TRANSFER.p_tx_data = CONST_TEST_DATA; TEST_TRANSFER.tx_length = sizeof(CONST_TEST_DATA); ret_val = nrf_spi_mngr_schedule(&m_nrf_spi_mngr, &TEST_DATA_TRANSACTION); TEST_TRANSFER.p_tx_data = TEST_DATA; TEST_TRANSFER.tx_length = sizeof(TEST_DATA); ret_val = nrf_spi_mngr_schedule(&m_nrf_spi_mngr, &TEST_DATA_TRANSACTION);
On the scope you can see that the RAM buffer transactions work but the one from const buffer doesn't transmit anything. The chip select goes low but nothing else happens.
I made it wide so all three transactions are visible at once. In the middle (~21us) you can see the chip select go low but no other activity. It stays low until the third transaction starts. I've removed the code that checks the return values just for the example. All of the calls to nrf_spi_mngr_schedule return NRF_SUCCESS.
All the examples I find only transmit from RAM. Can anyone comment on why the transfers from a const fail or the correct way to do it?
Thanks
.