I have a NRF52840 Dev Kit and a ESP32-S3 Dev kit, I want to do a SPI communication between them. Here NRF works as SPI Master and ESP works as SPI Slave. I am using SDK-17.1 for development. For SPI Master code I have taken an example code and used the same pins which are given in that code. My work flow is to send a 32 Bytes of data from Master to Slave then Slave will respond on that . So as per the SPI I need to send two commands from Master to read the data from Slave. In first command '0x11', Slave will prepare the data on its side, then Master will send a dummy command '0x13' to read that data.
/** * Copyright (c) 2015 - 2021, Nordic Semiconductor ASA * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include "nrf_drv_spi.h" #include "app_util_platform.h" #include "nrf_gpio.h" #include "nrf_delay.h" #include "boards.h" #include "app_error.h" #include <string.h> #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #define SPI_INSTANCE 0 /**< SPI instance index. */ static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */ static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */ //uint8_t #define BUFFER_SIZE 32 static uint8_t m_tx_buf[BUFFER_SIZE] ={0}; static uint8_t m_rx_buf[BUFFER_SIZE]; /**< RX buffer. */ static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */ /** * @brief SPI user event handler. * @param event */ void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context) { spi_xfer_done = true; NRF_LOG_INFO("Transfer completed."); // if (m_rx_buf[0] != 0) // Check received data in SPI Rx buffer { NRF_LOG_INFO(" Received:"); NRF_LOG_HEXDUMP_INFO(m_rx_buf, sizeof(m_rx_buf)); } } bool toggle = 1; int main(void) { bsp_board_init(BSP_INIT_LEDS); APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); NRF_LOG_DEFAULT_BACKENDS_INIT(); nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; /* Note: 1, When you are controlling chip select by application firmware, it require to init chip select pin as NOT_USED while init spi driver. Else SPI driver will also control the same pin while communicating on SPI. */ spi_config.ss_pin = NRFX_SPIM_PIN_NOT_USED; // SPI_SS_PIN;//31 spi_config.miso_pin = SPI_MISO_PIN;//30 spi_config.mosi_pin = SPI_MOSI_PIN;//29 spi_config.sck_pin = SPI_SCK_PIN;//26 spi_config.frequency = NRF_DRV_SPI_FREQ_4M; APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL)); nrf_gpio_cfg_output(SPI_SS_PIN); nrf_gpio_pin_set(SPI_SS_PIN); NRF_LOG_INFO("SPI example started."); while (1) { // Reset rx buffer and transfer done flag memset(m_rx_buf, 0, m_length); if(toggle == 1){ m_tx_buf[0] = 0x11; m_tx_buf[1] = 0xfa; m_tx_buf[2] = 0xfb; for(uint8_t i =3;i<BUFFER_SIZE;i++){ m_tx_buf[i] = i; } nrf_gpio_pin_clear(SPI_SS_PIN); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf,1, NULL, 0)); nrf_gpio_pin_set(SPI_SS_PIN); } else{ m_tx_buf[0] = 0x13; for(uint8_t i =1;i<BUFFER_SIZE;i++){ m_tx_buf[i] = 0; } nrf_gpio_pin_clear(SPI_SS_PIN); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 1, NULL, 0)); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, NULL, 0, m_rx_buf, BUFFER_SIZE)); nrf_gpio_pin_set(SPI_SS_PIN); } toggle = ! toggle; nrf_delay_ms(200); } }
This is my main.c file for SPI master code.
Here I have uploaded the SPI slave code also, SPI slave code is working fine , I have tested it by communicating between two ESP32 as Master and Slave. I am facing issue in communication between ESP32-S3 and NRF 52840 only
While communication I am facing following issues
- When we send a single byte of data from SPI master and does not send ,or put zero in TX buffer of Slave - Then Slave receives correct data which is send by Master
- In above case Master does not receives any data.
- In other case When we send a single byte of data from SPI master and if we put non zero values in TX buffer of Slave - Then Slave receives incorrect data or garbage
- In above case also master does not receive any data
- When we send 32 Bytes of data from Master and put non zero values in TX buffer of slave - Then Master receives garbage values and Slave also receives garbage values
When NRF sending single byte and ESP send no data then
ESP side | NRF side |
![]() |
![]() |
When ESP send 0x01 , Here we can see that ESP side Rx buff receives an extra byte 80 even which is not send from Master side
![]() |
![]() |
When ESP send 0x01 and NRF send 32 Bytes of data , then ESP RX buffer receives all garbage after that but in this case Master receives a single bytes which is send by Slave
![]() |
![]() |
In all above cases when, I disconnect the MISO line from Master side Slave side , then Slave receives all 32 bytes correctly , but as MISO line is disconnected so Master does not receives any data.
My observation is, something is interfering with MISO line data . Even I have tested with different clock frequency also but nothing helps out. What would be the possible cause of issue and what I am doing wrong in this communication ?Please help me with that.