nRF5340 SPI slave doesnt seem to receive

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

Parents
  • Hello,

    I suggest to look at the driver test examples for spi, which also include spis:
    \zephyr\tests\drivers\spi\spi_controller_peripheral\src\main.c

    By default I can see there is no overlay for nRF5340, but I would expect you can rename nrf52840dk_nrf52840.overlay to nrf5340dk_nrf5340_cpuapp.overlay, and update the pins used for spi and spis, and then it should work.

    Kenneth

Reply
  • Hello,

    I suggest to look at the driver test examples for spi, which also include spis:
    \zephyr\tests\drivers\spi\spi_controller_peripheral\src\main.c

    By default I can see there is no overlay for nRF5340, but I would expect you can rename nrf52840dk_nrf52840.overlay to nrf5340dk_nrf5340_cpuapp.overlay, and update the pins used for spi and spis, and then it should work.

    Kenneth

Children
  • Hi Kenneth, I accidently closed this thread, apologies about that.

    I tried importing my nRF5340 overlay, but I am getting the following error, for which I cant work out the reason.

    fatal error: opening dependency file secure_fw\partitions\crypto\mbedcrypto\nrf_security_src\CMakeFiles\crypto_service_mbedcrypto.dir\C_\ncs\v2.9.0\modules\crypto\mbedtls\library\memory_buffer_alloc.o.d: No such file or directory

    My overlay file is zmhostradio.overlay

    Can you help to sort it out?

    Thanks,

    Kaushalya

  • We are using 4 pins of NORA B126 for SPI, which is a classified as SPIM4. This is bit confusing as we can assign these pins to any SPI function vie PSEL registers. At the moment we have assigned them to SPI2. Is there any issue here?

  • Also I can see that there is a hardware semaphore that you got to acquire before any spi slave comms can happen. But I havent seen anywhere a sample code on how to do this. Could you also elaborate on how to do that? 

  • Hi,

    We need some help urgently as we are stuck at this point.

    After refering bit more on NORA B1 user guide, I come across this.

    "SPIM4: For the fastest SPI mode, the special purpose GPIO pins are enabled using the Peripheral setting of the MCUSEL pin of the PIN_CNF register. When activated, the SPIM PSEL settings are ignored, and the dedicated pins are used. The GPIO must use the extra high drive E0E1 configuration in the DRIVE field of the PIN_CNF GPIO register."

    I tried setting the MCUSEL to peripheral as follows.

    	#define SPIM4_SCK  NRF_GPIO_PIN_MAP(0,8)
    	#define SPIM4_MOSI NRF_GPIO_PIN_MAP(0,9)
    	#define SPIM4_MISO NRF_GPIO_PIN_MAP(0,10)
    
    	nrf_gpio_cfg(SPIM4_SCK, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
    	nrf_gpio_cfg(SPIM4_MOSI, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
    	nrf_gpio_cfg(SPIM4_MISO, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
    
    	nrf_gpio_pin_control_select(SPIM4_SCK, NRF_GPIO_PIN_SEL_PERIPHERAL);
    	nrf_gpio_pin_control_select(SPIM4_MOSI, NRF_GPIO_PIN_SEL_PERIPHERAL);
    	nrf_gpio_pin_control_select(SPIM4_MISO, NRF_GPIO_PIN_SEL_PERIPHERAL);

    But when I debug and check register at GPIO0-Pin 8, I see it is still set as APPMCU.

    So I have following questions.

    1. Can P0.8, P0.9 and P0.10 only be used as SPI4 in master mode, not as a slave?

    2. If SPI4 on the above pins can be used as a slave, how to do it?

    Cheers,

    Kaushalya

  • Hello,

    The driver should handle everything, so as long as you use the driver in the same way as the test examples that is all you need to do.

    The SPIM4 do not share hardware resources with other instances, ref:
    https://docs.nordicsemi.com/bundle/ps_nrf5340/page/chapters/memory/appmem.html#ariaid-title3 

    spim3 share with spis3, twim3, twis3 and uart3:

    spim4 don't share with other functionality:

    The pin assignment tables show recommended usage:
    https://docs.nordicsemi.com/bundle/ps_nrf5340/page/chapters/pin.html 

    If there is no specific recommended usage for a pin, then it can be used for anything. The spi pins can use those pins that have labeled qspi usage, if qspi is not used.

    Edit: I can see that you write P0.9 and P0.10, make sure that these pins are not configured to nfc by using:
    CONFIG_NFCT_PINS_AS_GPIOS=y (that might be deprecated, you may need to use in devicetree &uicr { nfct-pins-as-gpios; };.

    Kenneth

Related