1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/nrf24l01p_ng/nrf24l01p_ng_states.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

121 lines
4.0 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 Implementation of state transition procedures
* for the NRF24L01+ (NG) transceiver
*
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
* @}
*/
#include <assert.h>
#include <string.h>
#define ENABLE_DEBUG (0)
#include "debug.h"
#include "xtimer.h"
#include "net/netopt.h"
#include "nrf24l01p_ng_registers.h"
#include "nrf24l01p_ng_communication.h"
#include "nrf24l01p_ng_states.h"
static void _restore_address_p0(const nrf24l01p_ng_t *dev)
{
uint8_t addr_buffer[NRF24L01P_NG_ADDR_WIDTH];
memcpy(addr_buffer, NRF24L01P_NG_ADDR_P0(dev), NRF24L01P_NG_ADDR_WIDTH);
nrf24l01p_ng_write_reg(dev, NRF24L01P_NG_REG_RX_ADDR_P0, addr_buffer,
NRF24L01P_NG_ADDR_WIDTH);
nrf24l01p_ng_reg8_write(dev, NRF24L01P_NG_REG_SETUP_AW,
NRF24L01P_NG_FLG_AW(nrf24l01p_ng_valtoe_aw(NRF24L01P_NG_ADDR_WIDTH)));
}
void nrf24l01p_ng_transition_to_power_down(nrf24l01p_ng_t *dev)
{
DEBUG_PUTS("[nrf24l01p_ng] transition to POWER_DOWN");
assert(dev->state & NRF24L01P_NG_TRANSITION_TO_POWER_DOWN);
uint8_t config = NRF24L01P_NG_FLG_PWR_UP;
nrf24l01p_ng_reg8_clear(dev, NRF24L01P_NG_REG_CONFIG, &config);
dev->state = NRF24L01P_NG_STATE_POWER_DOWN;
}
void nrf24l01p_ng_transition_to_standby_1(nrf24l01p_ng_t *dev)
{
DEBUG_PUTS("[nrf24l01p_ng] transition to STANDBY_1");
assert(dev->state & NRF24L01P_NG_TRANSITION_TO_STANDBY_1);
switch (dev->state) {
case NRF24L01P_NG_STATE_POWER_DOWN:
gpio_clear(dev->params.pin_ce);
uint8_t config = NRF24L01P_NG_FLG_PWR_UP;
nrf24l01p_ng_reg8_set(dev, NRF24L01P_NG_REG_CONFIG, &config);
xtimer_usleep(NRF24L01P_NG_DELAY_US_START_UP);
break;
case NRF24L01P_NG_STATE_RX_MODE:
gpio_clear(dev->params.pin_ce);
break;
case NRF24L01P_NG_STATE_STANDBY_2:
case NRF24L01P_NG_STATE_TX_MODE:
gpio_clear(dev->params.pin_ce);
_restore_address_p0(dev);
/* TX finished with one packet */
break;
default:
return;
}
dev->state = NRF24L01P_NG_STATE_STANDBY_1;
}
void nrf24l01p_ng_transition_to_standby_2(nrf24l01p_ng_t *dev)
{
DEBUG_PUTS("[nrf24l01p_ng] transition to STANDBY_2");
assert(dev->state & NRF24L01P_NG_TRANSITION_TO_STANDBY_2);
switch (dev->state) {
case NRF24L01P_NG_STATE_STANDBY_1:;
/* TX FIFO empty */
uint8_t config = NRF24L01P_NG_FLG_PRIM_RX;
nrf24l01p_ng_reg8_clear(dev, NRF24L01P_NG_REG_CONFIG, &config);
gpio_set(dev->params.pin_ce);
break;
case NRF24L01P_NG_STATE_TX_MODE:
gpio_set(dev->params.pin_ce);
break;
default:
return;
}
dev->state = NRF24L01P_NG_STATE_STANDBY_2;
}
void nrf24l01p_ng_transition_to_rx_mode(nrf24l01p_ng_t *dev)
{
DEBUG_PUTS("[nrf24l01p_ng] transition to RX_MODE");
assert(dev->state & NRF24L01P_NG_TRANSITION_TO_RX_MODE);
if (nrf24l01p_ng_reg8_read(dev, NRF24L01P_NG_REG_FIFO_STATUS) &
NRF24L01P_NG_FLG_RX_FULL) {
nrf24l01p_ng_flush_rx(dev);
}
uint8_t config = NRF24L01P_NG_FLG_PRIM_RX;
nrf24l01p_ng_reg8_set(dev, NRF24L01P_NG_REG_CONFIG, &config);
gpio_set(dev->params.pin_ce);
xtimer_usleep(NRF24L01P_NG_DELAY_US_RX_SETTLING);
dev->state = NRF24L01P_NG_STATE_RX_MODE;
}
void nrf24l01p_ng_transition_to_tx_mode(nrf24l01p_ng_t *dev)
{
DEBUG_PUTS("[nrf24l01p_ng] transition to TX_MODE");
assert(dev->state & NRF24L01P_NG_TRANSITION_TO_TX_MODE);
/* TX FIFI not empty */
uint8_t config = NRF24L01P_NG_FLG_PRIM_RX;
nrf24l01p_ng_reg8_clear(dev, NRF24L01P_NG_REG_CONFIG, &config);
dev->state = NRF24L01P_NG_STATE_TX_MODE;
}