From de5a7e00c60c4ba9d52e270bd9480f2b25f3c48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= Date: Thu, 3 Dec 2015 13:10:28 +0100 Subject: [PATCH] drivers/nrf24l01p : dynamic ack and dynamic payload Add method for enabling/disable dynamic ack and dynamic payloads on nrf24l01+ devices. Also add function for reseting one or more interrupts. --- drivers/include/nrf24l01p.h | 32 ++++++ .../nrf24l01p/include/nrf24l01p_settings.h | 8 ++ drivers/nrf24l01p/nrf24l01p.c | 100 ++++++++++++++++++ 3 files changed, 140 insertions(+) diff --git a/drivers/include/nrf24l01p.h b/drivers/include/nrf24l01p.h index 934e8581e5..9bf5e98496 100644 --- a/drivers/include/nrf24l01p.h +++ b/drivers/include/nrf24l01p.h @@ -213,6 +213,27 @@ int nrf24l01p_read_payload(nrf24l01p_t *dev, char *answer, unsigned int size); */ void nrf24l01p_register(nrf24l01p_t *dev, unsigned int *pid); +/** +* @brief Enable dynamic payload for the pipe on give nrf24l01+ transceiver. +* +* @param[in] dev Transceiver device to use. +* @param[in] pipe RX pipe for which dynamic payload is enabled +* +* @return 0 on success. +* @return -1 on error. +*/ +int nrf24l01p_enable_dynamic_payload(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe); + +/** +* @brief Enable dynamic ack for the nrf24l01+ transceiver. +* +* @param[in] dev Transceiver device to use. +* +* @return 0 on success. +* @return -1 on error. +*/ +int nrf24l01p_enable_dynamic_ack(nrf24l01p_t *dev); + /** * @brief Unregister the nrf24l01+ transceiver from his ID. * @@ -458,6 +479,17 @@ int nrf24l01p_set_rxmode(nrf24l01p_t *dev); */ int nrf24l01p_reset_all_interrupts(nrf24l01p_t *dev); +/** +* @brief Reset interrupts on the nrf24l01+ transceiver. +* +* @param[in] dev Transceiver device to use. +* @param[in] intrs Interrupt mask to reset +* +* @return 1 on success. +* @return -1 on error. +*/ +int nrf24l01p_reset_interrupts(nrf24l01p_t *dev, char intrs); + /** * @brief Mask one interrupt on the nrf24l01+ transceiver. * diff --git a/drivers/nrf24l01p/include/nrf24l01p_settings.h b/drivers/nrf24l01p/include/nrf24l01p_settings.h index 4c265957d4..41ff3cdd0e 100644 --- a/drivers/nrf24l01p/include/nrf24l01p_settings.h +++ b/drivers/nrf24l01p/include/nrf24l01p_settings.h @@ -87,6 +87,14 @@ extern "C" { #define REG_DYNPD 0x1c #define REG_FEATURE 0x1d +/* Bits in EN_AA register */ +#define ENAA_P0 0x01 +#define ENAA_P1 0x02 +#define ENAA_P2 0x04 +#define ENAA_P3 0x08 +#define ENAA_P4 0x10 +#define ENAA_P5 0x20 + /* Bits in CONFIG register */ #define MASK_RX_DR 0x40 #define MASK_TX_DS 0x20 diff --git a/drivers/nrf24l01p/nrf24l01p.c b/drivers/nrf24l01p/nrf24l01p.c index 0decdee208..a73d81871e 100644 --- a/drivers/nrf24l01p/nrf24l01p.c +++ b/drivers/nrf24l01p/nrf24l01p.c @@ -11,6 +11,7 @@ * @{ * @author Peter Kietzmann * @author Joakim Nohlgård + * @author Marc Poulhiès * @} */ #include "nrf24l01p.h" @@ -743,6 +744,12 @@ int nrf24l01p_set_rxmode(nrf24l01p_t *dev) return status; } + +int nrf24l01p_reset_interrupts(nrf24l01p_t *dev, char intrs) +{ + return nrf24l01p_write_reg(dev, REG_STATUS, intrs); +} + int nrf24l01p_reset_all_interrupts(nrf24l01p_t *dev) { return nrf24l01p_write_reg(dev, REG_STATUS, ALL_INT_MASK); @@ -768,6 +775,81 @@ int nrf24l01p_unmask_interrupt(nrf24l01p_t *dev, char intr) return nrf24l01p_write_reg(dev, REG_CONFIG, conf); } +int nrf24l01p_enable_dynamic_payload(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe) +{ + char feature_val; + char en_aa_val; + char dynpd_val; + int pipe_mask = 0; + int dpl_mask = 0; + + if (nrf24l01p_read_reg(dev, REG_FEATURE, &feature_val) < 0) { + DEBUG("Can't read REG_FEATURE\n"); + return -1; + } + if (!(feature_val & FEATURE_EN_DPL)){ + feature_val |= FEATURE_EN_DPL; + if (nrf24l01p_write_reg(dev, REG_FEATURE, feature_val) < 0){ + DEBUG("Can't write REG_FEATURE\n"); + return -1; + } + } + + if (nrf24l01p_read_reg(dev, REG_EN_AA, &en_aa_val) < 0){ + DEBUG("Can't read REG_EN_AA\n"); + return -1; + } + switch (pipe){ + case NRF24L01P_PIPE0: + pipe_mask = ENAA_P0; + dpl_mask = DYNPD_DPL_P0; + break; + case NRF24L01P_PIPE1: + pipe_mask = ENAA_P1; + dpl_mask = DYNPD_DPL_P1; + break; + case NRF24L01P_PIPE2: + pipe_mask = ENAA_P2; + dpl_mask = DYNPD_DPL_P2; + break; + case NRF24L01P_PIPE3: + pipe_mask = ENAA_P3; + dpl_mask = DYNPD_DPL_P3; + break; + case NRF24L01P_PIPE4: + pipe_mask = ENAA_P4; + dpl_mask = DYNPD_DPL_P4; + break; + case NRF24L01P_PIPE5: + pipe_mask = ENAA_P5; + dpl_mask = DYNPD_DPL_P5; + break; + } + + if (!(en_aa_val & pipe_mask)){ + en_aa_val |= pipe_mask; + if (nrf24l01p_write_reg(dev, REG_EN_AA, en_aa_val) < 0){ + DEBUG("Can't write REG_EN_AA\n"); + return -1; + } + } + + if (nrf24l01p_read_reg(dev, REG_DYNPD, &dynpd_val) < 0){ + DEBUG("Can't read REG_DYNPD\n"); + return -1; + } + + if (!(dynpd_val & dpl_mask)){ + dynpd_val |= dpl_mask; + if (nrf24l01p_write_reg(dev, REG_DYNPD, dynpd_val) < 0){ + DEBUG("Can't write REG_DYNPD\n"); + return -1; + } + } + + return 0; +} + int nrf24l01p_enable_pipe(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe) { char pipe_conf; @@ -860,6 +942,24 @@ int nrf24l01p_setup_auto_ack(nrf24l01p_t *dev, nrf24l01p_rx_pipe_t pipe, nrf24l0 return nrf24l01p_write_reg(dev, REG_SETUP_RETR, ((delay_retrans << 4) | count_retrans)); } +int nrf24l01p_enable_dynamic_ack(nrf24l01p_t *dev) +{ + char feature; + + if (nrf24l01p_read_reg(dev, REG_FEATURE, &feature) < 0){ + DEBUG("Can't read FEATURE reg\n"); + return -1; + } + if (!(feature & FEATURE_EN_DYN_ACK)){ + feature |= FEATURE_EN_DYN_ACK; + if (nrf24l01p_write_reg(dev, REG_FEATURE, feature) < 0){ + DEBUG("Can't write FEATURE reg\n"); + return -1; + } + } + return 0; +} + int nrf24l01p_disable_all_auto_ack(nrf24l01p_t *dev) { return nrf24l01p_write_reg(dev, REG_EN_AA, 0x00);