Hi,
I have ported my already working nRF52840 SPI slave code to a nRF5340, but it doesnt seem to receive any data. I have verified the CS, SCK and MOSI signals, but no MISO from nRF5340.
. . static const struct spi_config spis_cfg = { .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_OP_MODE_SLAVE | SPI_MODE_CPOL | SPI_MODE_CPHA, .slave = 1, }; . . static void spi_slave_init(void) { spis_dev = DEVICE_DT_GET(MY_SPI_SLAVE); if (!device_is_ready(spis_dev)) { printk("SPI slave device not ready!\n"); } else LOG_INF ("SPI slave ready"); } . . static int spi_slave_check_for_message(void) { int signaled, result; k_poll_signal_check(&spi_slave_done_sig, &signaled, &result); if (signaled != 0){ slave_tx_buffer [0] = 0x01; // init slave tx buffer return 0; } else return -1; } . . static int spi_slave_wait_msg(uint8_t txlen, uint8_t rxlen) { const struct spi_buf s_tx_buf = { .buf = slave_tx_buffer, .len = txlen }; const struct spi_buf_set s_tx = { .buffers = &s_tx_buf, .count = 1 }; struct spi_buf s_rx_buf = { .buf = slave_rx_buffer, .len = rxlen }; const struct spi_buf_set s_rx = { .buffers = &s_rx_buf, .count = 1 }; // Reset signal - this flag the next msg check k_poll_signal_reset(&spi_slave_done_sig); // Start transaction int error = spi_transceive_signal(spis_dev, &spis_cfg, &s_tx, &s_rx, &spi_slave_done_sig); // once a cycle is complete, the 'spi_slave_done_sig' will get signelled if(error != 0){ LOG_ERR("SPI slave transceive error: %i\n", error); return error; } return 0; } . . static void spis_handler (struct k_work *item) { static uint8_t txlen, rxlen; int8_t i=0, loopCnt=0; static uint8_t startRec=0; uint16_t hostFWRev; if (spi_slave_check_for_message() == 0){ LOG_INF ("---- Received SPI msg -----"); switch (slave_rx_buffer [0]) { case 'V': // Feature 7 hostFWRev = EncVerString (); LOG_INF ("Host radio FW : %04x", hostFWRev); slave_tx_buffer[0] = 'A'; slave_tx_buffer[1] = (uint8_t)(hostFWRev >> 8); slave_tx_buffer[2] = (uint8_t)(hostFWRev & 0x00ff); txlen = 3; rxlen = 1; break; case 'A': // ACK/NAK request. This is the second byte send by host after the command. Only thing we need is to send the ACK/NAK of last command //LOG_INF ("ACK/NAK command"); break; default : LOG_ERR ("default %x, %c", slave_rx_buffer [0], slave_rx_buffer [0]); slave_tx_buffer[0] = 'K'; txlen = 1; rxlen = 1; } // Prepare the next SPI slave transaction - this means the ACK/NAK doesnt get send immediately, but in next rx cycle. // This means we have to either send same command twice or have a ACK/NAK request command, which is send after each command spi_slave_wait_msg(txlen, rxlen); } k_msleep (1); k_work_submit (item); } . . void main(void) { . . k_poll_signal_reset(&spi_slave_done_sig); spi_slave_init (); spi_slave_wait_msg (1, 1); // this starts the k_poll event to wait for next spi rx k_work_init(&spis_work, spis_handler); // spis handling is done in system queue to avoid issues with spi async transfers k_work_submit (&spis_work); . . }
I get 'SPI slave ready' as a result of invoking spi_slave_init () function.
I can see the spis_handler () is invoked repeatedly, but 'spi_slave_check_for_message() == 0' seems to fail all the time.
I use nordic SDK 2.9.0.
I saw in the nRF5340 user guide that there is a hardware semaphore for accessing spi buffers, which was not available in nRF52840. Is there anything I need to implement in the application level to do that?
I have tried all I can think of and need some help urgently.
Thanks,
Kaushalya