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.