Hello,
I am working on a project which requires radio transmitter and receiver to work in sync with the SPI. So the setup is as follows the Transmitter transmits a signal to the receiver and the receiver sends the RSSI(Received Signal Strength Indicator) to the transmitter using SPI. I have merged the two codes for the radio transmitter-receiver and the spi, spis code from the SDK 12.3. When I run the two codes in two different development kits, they are transmitting and receiving the rssi but when I connect the two Development kits with the (using male to male wires)SPI connection i.e SCK - SCK, MISO- MISO, MOSI- MOSI, SS-SS pins of the two development kit, It no longer transmits and receives any signal. I know that it is receiving the signal because it glows the leds. Also, the log is not working for this code and I have no idea why I have also included the following code in the sdk_config file:-
#ifdef NRF_LOG_ENABLED #define NRF_LOG_ENABLED 1 #endif
The transmitter code :-
/** * Copyright (c) 2015 - 2017, 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 <stdint.h> #include <stdbool.h> #include <stdio.h> #include "radio_config.h" #include "app_timer.h" #include "bsp.h" #include "nrf_gpio.h" #include "sdk_config.h" #include "nrf_drv_spis.h" #include "nrf_gpio.h" #include "boards.h" #include "app_error.h" #include "nordic_common.h" #include "nrf_error.h" #include <string.h> #define NRF_LOG_MODULE_NAME "APP" #include "nrf_log.h" #include "nrf_log_ctrl.h" #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ #define APP_TIMER_OP_QUEUE_SIZE 2 /**< Size of timer operation queues. */ static uint32_t packet; /**< Packet to transmit. */ #define SPIS_INSTANCE 1 /**< SPIS instance index. */ static const nrf_drv_spis_t spis = NRF_DRV_SPIS_INSTANCE(SPIS_INSTANCE);/**< SPIS instance. */ #define TEST_STRING "Nordic" static uint8_t m_tx_buf[] = TEST_STRING; /**< TX buffer. */ static uint8_t m_rx_buf[sizeof(TEST_STRING) + 1]; /**< RX buffer. */ static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */ static volatile bool spis_xfer_done; /**< Flag used to indicate that SPIS instance completed the transfer. */ /**@brief Function for sending packet. */ void send_packet() { // send the packet: NRF_RADIO->EVENTS_READY = 0U; NRF_RADIO->TASKS_TXEN = 1; while (NRF_RADIO->EVENTS_READY == 0U) { // wait } NRF_RADIO->EVENTS_END = 0U; NRF_RADIO->TASKS_START = 1U; while (NRF_RADIO->EVENTS_END == 0U) { // wait } uint32_t err_code = bsp_indication_set(BSP_INDICATE_SENT_OK); NRF_LOG_INFO("The packet was sent\r\n"); APP_ERROR_CHECK(err_code); NRF_RADIO->EVENTS_DISABLED = 0U; // Disable radio NRF_RADIO->TASKS_DISABLE = 1U; while (NRF_RADIO->EVENTS_DISABLED == 0U) { // wait } } /**@brief Function for handling bsp events. */ void bsp_evt_handler(bsp_event_t evt) { uint32_t prep_packet = 0; switch (evt) { case BSP_EVENT_KEY_0: /* Fall through. */ case BSP_EVENT_KEY_1: /* Fall through. */ case BSP_EVENT_KEY_2: /* Fall through. */ case BSP_EVENT_KEY_3: /* Fall through. */ case BSP_EVENT_KEY_4: /* Fall through. */ case BSP_EVENT_KEY_5: /* Fall through. */ case BSP_EVENT_KEY_6: /* Fall through. */ case BSP_EVENT_KEY_7: /* Get actual button state. */ for (int i = 0; i < BUTTONS_NUMBER; i++) { prep_packet |= (bsp_board_button_state_get(i) ? (1 << i) : 0); } break; default: /* No implementation needed. */ break; } packet = prep_packet; } /**@brief Function for initialization oscillators. */ void clock_initialization() { /* Start 16 MHz crystal oscillator */ NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; /* Wait for the external oscillator to start up */ while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { // Do nothing. } /* Start low frequency crystal oscillator for app_timer(used by bsp)*/ NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->TASKS_LFCLKSTART = 1; while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { // Do nothing. } } /** * @brief SPIS user event handler. * * @param event */ void spis_event_handler(nrf_drv_spis_event_t event) { if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) { spis_xfer_done = true; NRF_LOG_INFO(" Transfer completed. Received: %s\r\n",(uint32_t)m_rx_buf); } } int main(void) { uint32_t err_code = NRF_SUCCESS; clock_initialization(); APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL); err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), bsp_evt_handler); APP_ERROR_CHECK(err_code); // Set radio configuration parameters radio_configure(); // Set payload pointer NRF_RADIO->PACKETPTR = (uint32_t)&packet; err_code = bsp_indication_set(BSP_INDICATE_USER_STATE_OFF); NRF_LOG_INFO("Press Any Button\r\n"); APP_ERROR_CHECK(err_code); // Enable the constant latency sub power mode to minimize the time it takes // for the SPIS peripheral to become active after the CSN line is asserted // (when the CPU is in sleep mode). NRF_POWER->TASKS_CONSTLAT = 1; bsp_board_leds_init(); APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); NRF_LOG_INFO("SPIS example\r\n"); nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG; spis_config.csn_pin = APP_SPIS_CS_PIN; spis_config.miso_pin = APP_SPIS_MISO_PIN; spis_config.mosi_pin = APP_SPIS_MOSI_PIN; spis_config.sck_pin = APP_SPIS_SCK_PIN; APP_ERROR_CHECK(nrf_drv_spis_init(&spis, &spis_config, spis_event_handler)); while (1) { if (packet != 0) { send_packet(); NRF_LOG_INFO("The contents of the package was %u\r\n", (unsigned int)packet); packet = 0; } //NRF_LOG_FLUSH(); //__WFE(); memset(m_rx_buf, 0, m_length); spis_xfer_done = false; APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, m_tx_buf, m_length, m_rx_buf, m_length)); while (!spis_xfer_done) { __WFE(); } //NRF_LOG_FLUSH(); bsp_board_led_invert(BSP_BOARD_LED_2); } }
The receiver code:-
/** * Copyright (c) 2015 - 2017, 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 <stdint.h> #include <stdbool.h> #include <stdio.h> #include "radio_config.h" #include "nrf_drv_spi.h" #include "bsp.h" #include "app_timer.h" #include "nordic_common.h" #include "nrf_error.h" #include "app_util_platform.h" #include "nrf_gpio.h" #include "nrf_delay.h" #include "boards.h" #include "app_error.h" #include <string.h> #define NRF_LOG_MODULE_NAME "APP" #include "nrf_log.h" #include "nrf_log_ctrl.h" #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ #define APP_TIMER_OP_QUEUE_SIZE 2 /**< Size of timer operation queues. */ static uint32_t packet; /**< Packet to transmit. */ uint32_t rssi; #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. */ #define TEST_STRING "Nordic" static uint8_t m_tx_buf[] = TEST_STRING; /**< TX buffer. */ static uint8_t m_rx_buf[sizeof(TEST_STRING) + 1]; /**< RX buffer. */ static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */ /**@brief Function for initialization oscillators. */ void clock_initialization() { /* Start 16 MHz crystal oscillator */ NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; /* Wait for the external oscillator to start up */ while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { // Do nothing. } /* Start low frequency crystal oscillator for app_timer(used by bsp)*/ NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->TASKS_LFCLKSTART = 1; while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { // Do nothing. } } /**@brief Function for reading packet. */ uint32_t read_packet() { NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_RSSISTART_Msk; NRF_RADIO->INTENSET = RADIO_INTENSET_READY_Msk | RADIO_INTENSET_END_Msk | RADIO_INTENSET_DISABLED_Msk; uint32_t result = 0; NRF_RADIO->EVENTS_READY = 0U; // Enable radio and wait for ready NRF_RADIO->TASKS_RXEN = 1U; while (NRF_RADIO->EVENTS_READY == 0U) { // wait } NRF_RADIO->EVENTS_END = 0U; // Start listening and wait for address received event NRF_RADIO->TASKS_START = 1U; // Wait for end of packet or buttons state changed while (NRF_RADIO->EVENTS_END == 0U) { // wait } if (NRF_RADIO->CRCSTATUS == 1U) { result = packet; rssi = NRF_RADIO->RSSISAMPLE; } NRF_RADIO->EVENTS_DISABLED = 0U; // Disable radio NRF_RADIO->TASKS_DISABLE = 1U; while (NRF_RADIO->EVENTS_DISABLED == 0U) { // wait } return result; } /** * @brief SPI user event handler. * @param event */ void spi_event_handler(nrf_drv_spi_evt_t const * p_event) { spi_xfer_done = true; NRF_LOG_INFO("Transfer completed.\r\n"); if (m_rx_buf[0] != 0) { NRF_LOG_INFO(" Received: \r\n"); NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf)); } } int main(void) { uint32_t err_code = NRF_SUCCESS; nrf_gpio_range_cfg_output(21, 24); clock_initialization(); APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL); err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); err_code = bsp_init(BSP_INIT_LED, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL); APP_ERROR_CHECK(err_code); // Set radio configuration parameters radio_configure(); NRF_RADIO->PACKETPTR = (uint32_t)&packet; err_code = bsp_indication_set(BSP_INDICATE_USER_STATE_OFF); NRF_LOG_INFO("Wait for first packet\r\n"); APP_ERROR_CHECK(err_code); //bsp_board_leds_init(); APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); NRF_LOG_INFO("SPI example\r\n"); nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi_config.ss_pin = SPI_SS_PIN; spi_config.miso_pin = SPI_MISO_PIN; spi_config.mosi_pin = SPI_MOSI_PIN; spi_config.sck_pin = SPI_SCK_PIN; APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler)); NRF_LOG_FLUSH(); while (1) { uint32_t received = read_packet(); err_code = bsp_indication_set(BSP_INDICATE_RCV_OK); NRF_LOG_INFO("Packet was received\r\n"); APP_ERROR_CHECK(err_code); NRF_LOG_INFO("The contents of the package is %u\r\n", (unsigned int)received); NRF_LOG_INFO("The RSSI of the package is %u\r\n", (unsigned int)rssi); if(rssi>40 && rssi<50) { nrf_gpio_pin_write(21, 0); nrf_gpio_pin_write(22, 0); nrf_gpio_pin_write(23, 0); nrf_gpio_pin_write(24, 0); } if(rssi>50 && rssi<60) { nrf_gpio_pin_write(21, 1); nrf_gpio_pin_write(22, 0); nrf_gpio_pin_write(23, 0); nrf_gpio_pin_write(24, 0); } if(rssi>60 && rssi<70) { nrf_gpio_pin_write(21, 1); nrf_gpio_pin_write(22, 1); nrf_gpio_pin_write(23, 0); nrf_gpio_pin_write(24, 0); } if(rssi>70 && rssi<80) { nrf_gpio_pin_write(21, 1); nrf_gpio_pin_write(22, 1); nrf_gpio_pin_write(23, 1); nrf_gpio_pin_write(24, 0); } // Reset rx buffer and transfer done flag memset(m_rx_buf, 0, m_length); spi_xfer_done = false; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length)); while (!spi_xfer_done) { __WFE(); spi_xfer_done = true; } //NRF_LOG_FLUSH(); bsp_board_led_invert(BSP_BOARD_LED_0); nrf_delay_ms(200); } }
I would really appreciate if you could help me run this code properly.
Thank You.