1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/nrf24l01p_ng/diagnostics.c
fabian18 f7a77ebb04 drivers/nrf24l01p_ng: netdev driver for nrf24l01+
The driver uses the netdev interface. Due to the limited
capabilities of the transceiver (32 byte FIFO and no source address in the layer2 frame),
it relies on 6LowPAN compression and adds the source address to the frame for that.
2021-01-24 20:49:39 +01:00

392 lines
14 KiB
C

/*
* Copyright (C) 2019 Otto-von-Guericke-Universität Magdeburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_nrf24l01p_ng
* @{
*
* @file
* @brief Functions to debug the NRF24L01+ (NG) transceiver
*
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
* @}
*/
#include <stdio.h>
#include <string.h>
#include "nrf24l01p_ng_registers.h"
#include "nrf24l01p_ng_communication.h"
#include "nrf24l01p_ng_diagnostics.h"
#if NRF24L01P_NG_ADDR_WIDTH == 3
#define ADDR_FMT "%02x%02x%02x"
#define ADDR_P0(dev) \
NRF24L01P_NG_ADDR_P0(dev)[0], \
NRF24L01P_NG_ADDR_P0(dev)[1], \
NRF24L01P_NG_ADDR_P0(dev)[2]
#define ADDR_P1(dev) \
NRF24L01P_NG_ADDR_P1(dev)[0], \
NRF24L01P_NG_ADDR_P1(dev)[1], \
NRF24L01P_NG_ADDR_P1(dev)[2]
#elif NRF24L01P_NG_ADDR_WIDTH == 4
#define ADDR_FMT "%02x%02x%02x%02x"
#define ADDR_P0(dev) \
NRF24L01P_NG_ADDR_P0(dev)[0], \
NRF24L01P_NG_ADDR_P0(dev)[1], \
NRF24L01P_NG_ADDR_P0(dev)[2], \
NRF24L01P_NG_ADDR_P0(dev)[3]
#define ADDR_P1(dev) \
NRF24L01P_NG_ADDR_P1(dev)[0], \
NRF24L01P_NG_ADDR_P1(dev)[1], \
NRF24L01P_NG_ADDR_P1(dev)[2], \
NRF24L01P_NG_ADDR_P1(dev)[3]
#else
#define ADDR_FMT "%02x%02x%02x%02x%02x"
#define ADDR_P0(dev) \
NRF24L01P_NG_ADDR_P0(dev)[0], \
NRF24L01P_NG_ADDR_P0(dev)[1], \
NRF24L01P_NG_ADDR_P0(dev)[2], \
NRF24L01P_NG_ADDR_P0(dev)[3], \
NRF24L01P_NG_ADDR_P0(dev)[4]
#define ADDR_P1(dev) \
NRF24L01P_NG_ADDR_P1(dev)[0], \
NRF24L01P_NG_ADDR_P1(dev)[1], \
NRF24L01P_NG_ADDR_P1(dev)[2], \
NRF24L01P_NG_ADDR_P1(dev)[3], \
NRF24L01P_NG_ADDR_P1(dev)[4]
#endif
const char *
nrf24l01p_ng_diagnostics_state_to_string(nrf24l01p_ng_state_t state)
{
if (state == NRF24L01P_NG_STATE_POWER_DOWN) {
return "POWER_DOWN";
}
if (state == NRF24L01P_NG_STATE_STANDBY_1) {
return "STANDBY_1";
}
if (state == NRF24L01P_NG_STATE_STANDBY_2) {
return "STANDBY_2";
}
if (state == NRF24L01P_NG_STATE_TX_MODE) {
return "TX_MODE";
}
if (state == NRF24L01P_NG_STATE_RX_MODE) {
return "RX_MODE";
}
return "UNDEFINED";
}
nrf24l01p_ng_state_t
nrf24l01p_ng_diagnostics_string_to_state(const char *sstate)
{
if (!strcmp(sstate, "POWER_DOWN")) {
return NRF24L01P_NG_STATE_POWER_DOWN;
}
if (!strcmp(sstate, "STANDBY_1")) {
return NRF24L01P_NG_STATE_STANDBY_1;
}
if (!strcmp(sstate, "STANDBY_2")) {
return NRF24L01P_NG_STATE_STANDBY_2;
}
if (!strcmp(sstate, "TX_MODE")) {
return NRF24L01P_NG_STATE_TX_MODE;
}
if (!strcmp(sstate, "RX_MODE")) {
return NRF24L01P_NG_STATE_RX_MODE;
}
return NRF24L01P_NG_STATE_UNDEFINED;
}
void nrf24l01p_ng_diagnostics_print_all_regs(const nrf24l01p_ng_t *dev)
{
uint8_t config;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_CONFIG, &config, 1);
puts("");
printf(
"CONFIG [MASK_RX_DR %u "
"MASK_TX_DS %u "
"MASK_MAX_RT %u "
"EN_CRC %u "
"CRCO %u "
"PWR_UP %u "
"PRIM_RX %u]\n",
(unsigned)NRF24L01P_NG_VAL_MASK_RX_DR(config),
(unsigned)NRF24L01P_NG_VAL_MASK_TX_DS(config),
(unsigned)NRF24L01P_NG_VAL_MAX_RT(config),
(unsigned)NRF24L01P_NG_VAL_EN_CRC(config),
(unsigned)NRF24L01P_NG_VAL_CRCO(config),
(unsigned)NRF24L01P_NG_VAL_PWR_UP(config),
(unsigned)NRF24L01P_NG_VAL_PRIM_RX(config)
);
uint8_t en_aa;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_EN_AA, &en_aa, 1);
printf(
"EN_AA [ENAA_P5 %u "
"ENAA_P4 %u "
"ENAA_P3 %u "
"ENAA_P2 %u "
"ENAA_P1 %u "
"ENAA_P0 %u]\n",
(unsigned)NRF24L01P_NG_VAL_ENAA_P5(en_aa),
(unsigned)NRF24L01P_NG_VAL_ENAA_P4(en_aa),
(unsigned)NRF24L01P_NG_VAL_ENAA_P3(en_aa),
(unsigned)NRF24L01P_NG_VAL_ENAA_P2(en_aa),
(unsigned)NRF24L01P_NG_VAL_ENAA_P1(en_aa),
(unsigned)NRF24L01P_NG_VAL_ENAA_P0(en_aa)
);
uint8_t en_rxaddr;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_EN_RXADDR, &en_rxaddr, 1);
printf(
"EN_RXADDR [ERX_P5 %u "
"ERX_P4 %u "
"ERX_P3 %u "
"ERX_P2 %u "
"ERX_P1 %u "
"ERX_P0 %u]\n",
(unsigned)NRF24L01P_NG_VAL_ERX_P5(en_rxaddr),
(unsigned)NRF24L01P_NG_VAL_ERX_P4(en_rxaddr),
(unsigned)NRF24L01P_NG_VAL_ERX_P3(en_rxaddr),
(unsigned)NRF24L01P_NG_VAL_ERX_P2(en_rxaddr),
(unsigned)NRF24L01P_NG_VAL_ERX_P1(en_rxaddr),
(unsigned)NRF24L01P_NG_VAL_ERX_P0(en_rxaddr)
);
uint8_t setup_aw;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_SETUP_AW, &setup_aw, 1);
printf(
"SETUP_AW [AW %u]\n",
(unsigned)NRF24L01P_NG_VAL_AW(setup_aw)
);
uint8_t setup_retr;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_SETUP_RETR, &setup_retr, 1);
printf(
"SETUP_RETR [ARD %u ARC %u]\n",
(unsigned)NRF24L01P_NG_VAL_ARD(setup_retr),
(unsigned)NRF24L01P_NG_VAL_ARC(setup_retr)
);
uint8_t rf_ch;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RF_CH, &rf_ch, 1);
printf(
"RF_CH [RF_CH %u]\n",
(unsigned)NRF24L01P_NG_VAL_RF_CH(rf_ch)
);
uint8_t rf_setup;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RF_SETUP, &rf_setup, 1);
printf(
"RF_SETUP [CONT_WAVE %u "
"RF_DR_LOW %u "
"PLL_LOCK %u "
"RF_DR_HIGH %u "
"RF_PWR %u]\n",
(unsigned)NRF24L01P_NG_VAL_CONT_WAVE(rf_setup),
(unsigned)NRF24L01P_NG_VAL_RF_DR_LOW(rf_setup),
(unsigned)NRF24L01P_NG_VAL_PLL_LOCK(rf_setup),
(unsigned)NRF24L01P_NG_VAL_RF_DR_HIGH(rf_setup),
(unsigned)NRF24L01P_NG_VAL_RF_PWR(rf_setup)
);
uint8_t status;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_STATUS, &status, 1);
printf(
"STATUS [RX_DR %u "
"TX_DS %u "
"MAX_RT %u "
"RX_P_NO %u "
"TX_FULL %u]\n",
(unsigned)NRF24L01P_NG_VAL_RX_DR(status),
(unsigned)NRF24L01P_NG_VAL_TX_DS(status),
(unsigned)NRF24L01P_NG_VAL_MAX_RT(status),
(unsigned)NRF24L01P_NG_VAL_RX_P_NO(status),
(unsigned)NRF24L01P_NG_VAL_TX_FULL(status)
);
uint8_t observe_tx;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_OBSERVE_TX, &observe_tx, 1);
printf(
"OBSERVE_TX [PLOS_CNT %u ARC_CNT %u]\n",
(unsigned)NRF24L01P_NG_VAL_PLOS_CNT(observe_tx),
(unsigned)NRF24L01P_NG_VAL_ARC_CNT(observe_tx)
);
uint8_t rpd;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RPD, &rpd, 1);
printf(
"RPD [RPD %u]\n",
(unsigned)NRF24L01P_NG_VAL_RPD(rpd)
);
uint8_t rx_addr_px_40[2][NRF24L01P_NG_MAX_ADDR_WIDTH]; /* Pipe 0/1 */
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_ADDR_P0, rx_addr_px_40[0],
NRF24L01P_NG_MAX_ADDR_WIDTH);
printf(
"RX_ADDR_P0 [RX_ADDR_P0 %02x:%02x:%02x:%02x:%02x]\n",
rx_addr_px_40[0][0],
rx_addr_px_40[0][1],
rx_addr_px_40[0][2],
rx_addr_px_40[0][3],
rx_addr_px_40[0][4]
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_ADDR_P1, rx_addr_px_40[1],
NRF24L01P_NG_MAX_ADDR_WIDTH);
printf(
"RX_ADDR_P1 [RX_ADDR_P1 %02x:%02x:%02x:%02x:%02x]\n",
rx_addr_px_40[1][0],
rx_addr_px_40[1][1],
rx_addr_px_40[1][2],
rx_addr_px_40[1][3],
rx_addr_px_40[1][4]
);
uint8_t rx_addr_px_8[4]; /* Pipe 2/3/4/5 */
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_ADDR_P2,
&rx_addr_px_8[0], 1);
printf(
"RX_ADDR_P2 [RX_ADDR_P2 %02x]\n",
rx_addr_px_8[0]
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_ADDR_P3,
&rx_addr_px_8[1], 1);
printf(
"RX_ADDR_P3 [RX_ADDR_P3 %02x]\n",
rx_addr_px_8[1]
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_ADDR_P4,
&rx_addr_px_8[2], 1);
printf(
"RX_ADDR_P4 [RX_ADDR_P4 %02x]\n",
rx_addr_px_8[2]
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_ADDR_P5,
&rx_addr_px_8[3], 1);
printf(
"RX_ADDR_P5 [RX_ADDR_P5 %02x]\n",
rx_addr_px_8[3]
);
uint8_t tx_addr[NRF24L01P_NG_MAX_ADDR_WIDTH];
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_TX_ADDR, tx_addr,
NRF24L01P_NG_MAX_ADDR_WIDTH);
printf(
"TX_ADDR [TX_ADDR %02x:%02x:%02x:%02x:%02x]\n",
tx_addr[0],
tx_addr[1],
tx_addr[2],
tx_addr[3],
tx_addr[4]
);
uint8_t rx_pw_px[6];
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_PW_P0, &rx_pw_px[0], 1);
printf(
"RX_PW_P0 [RX_PW_P0 %u]\n",
(unsigned)NRF24L01P_NG_VAL_RX_PW_PX(rx_pw_px[0])
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_PW_P1, &rx_pw_px[1], 1);
printf(
"RX_PW_P1 [RX_PW_P1 %u]\n",
(unsigned)NRF24L01P_NG_VAL_RX_PW_PX(rx_pw_px[1])
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_PW_P2, &rx_pw_px[2], 1);
printf(
"RX_PW_P2 [RX_PW_P2 %u]\n",
(unsigned)NRF24L01P_NG_VAL_RX_PW_PX(rx_pw_px[2])
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_PW_P3, &rx_pw_px[3], 1);
printf(
"RX_PW_P3 [RX_PW_P3 %u]\n",
(unsigned)NRF24L01P_NG_VAL_RX_PW_PX(rx_pw_px[3])
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_PW_P4, &rx_pw_px[4], 1);
printf(
"RX_PW_P4 [RX_PW_P4 %u]\n",
(unsigned)NRF24L01P_NG_VAL_RX_PW_PX(rx_pw_px[4])
);
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_RX_PW_P5, &rx_pw_px[5], 1);
printf(
"RX_PW_P5 [RX_PW_P5 %u]\n",
(unsigned)NRF24L01P_NG_VAL_RX_PW_PX(rx_pw_px[5])
);
uint8_t fifo_status;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_FIFO_STATUS, &fifo_status, 1);
printf(
"FIFO_STATUS [TX_REUSE %u "
"TX_FULL %u "
"TX_EMPTY %u "
"RX_FULL %u "
"RX_EMPTY %u]\n",
(unsigned)NRF24L01P_NG_VAL_TX_REUSE(fifo_status),
(unsigned)NRF24L01P_NG_VAL_TX_FULL_(fifo_status),
(unsigned)NRF24L01P_NG_VAL_TX_EMPTY(fifo_status),
(unsigned)NRF24L01P_NG_VAL_RX_FULL(fifo_status),
NRF24L01P_NG_VAL_RX_EMPTY(fifo_status)
);
uint8_t dynpd;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_DYNPD, &dynpd, 1);
printf(
"DYNDP [DPL_P5 %u "
"DPL_P4 %u "
"DPL_P3 %u "
"DPL_P2 %u "
"DPL_P1 %u "
"DPL_P0 %u]\n",
(unsigned)NRF24L01P_NG_VAL_DPL_P5(dynpd),
(unsigned)NRF24L01P_NG_VAL_DPL_P4(dynpd),
(unsigned)NRF24L01P_NG_VAL_DPL_P3(dynpd),
(unsigned)NRF24L01P_NG_VAL_DPL_P2(dynpd),
(unsigned)NRF24L01P_NG_VAL_DPL_P1(dynpd),
(unsigned)NRF24L01P_NG_VAL_DPL_P0(dynpd)
);
uint8_t features;
nrf24l01p_ng_read_reg(dev, NRF24L01P_NG_REG_FEATURES, &features, 1);
printf(
"FEATURES [EN_DPL %u EN_ACK_PAY %u DYN_ACK %u]\n",
(unsigned)NRF24L01P_NG_VAL_EN_DPL(features),
(unsigned)NRF24L01P_NG_VAL_EN_ACK_PAY(features),
(unsigned)NRF24L01P_NG_VAL_EN_DYN_ACK(features)
);
}
void nrf24l01p_ng_diagnostics_print_dev_info(const nrf24l01p_ng_t *dev)
{
printf("device: %p\n", (const void *)dev);
printf("address length: %u\n", (unsigned)NRF24L01P_NG_ADDR_WIDTH);
printf("device params:\n");
printf("\tChannel: %u\n",
dev->params.config.cfg_channel);
printf("\tCRC length: %u bytes\n",
(unsigned)nrf24l01p_ng_etoval_crc(dev->params.config.cfg_crc));
printf("\tData rate: %u kbps\n",
(unsigned)
nrf24l01p_ng_etoval_rfdr(dev->params.config.cfg_data_rate));
printf("\tMax. retransmissions: %u\n",
dev->params.config.cfg_max_retr);
printf("\tRetransmission delay: %u us\n",
(unsigned)
nrf24l01p_ng_etoval_ard(dev->params.config.cfg_retr_delay));
printf("\tTx power: %d dbm\n",
nrf24l01p_ng_etoval_tx_power(dev->params.config.cfg_tx_power));
printf("\tRx address p0: "ADDR_FMT"\n",
ADDR_P0(dev));
printf("\tRX address p1: "ADDR_FMT"\n",
ADDR_P1(dev));
printf("\tRX address p2: %02x\n",
NRF24L01P_NG_ADDR_PX_LSB(dev, NRF24L01P_NG_P2));
printf("\tRX address p3: %02x\n",
NRF24L01P_NG_ADDR_PX_LSB(dev, NRF24L01P_NG_P3));
printf("\tRX address p4: %02x\n",
NRF24L01P_NG_ADDR_PX_LSB(dev, NRF24L01P_NG_P4));
printf("\tRX address p5: %02x\n",
NRF24L01P_NG_ADDR_PX_LSB(dev, NRF24L01P_NG_P5));
printf("State: %s\n",
nrf24l01p_ng_diagnostics_state_to_string(dev->state));
}
void nrf24l01p_ng_diagnostics_print_frame(const nrf24l01p_ng_t *dev,
const void *frame, size_t len)
{
(void)dev;
puts("Rx frame");
for (uint8_t i = 0; i < len; i++) {
printf("0x%02X ", ((uint8_t *)frame)[i]);
}
puts("");
}