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