* Fix NRF5_ESB_readMessage, allways enable radio
* NRF5: fixes and improvements
- Compiles with arduino core for nRF52 (primo)
MY_RADIO_NRF5_ESB stays unsupported with primo!
- Split ACK negation flag into
MY_NRF5_ESB_REVERSE_ACK_TX
MY_NRF5_ESB_REVERSE_ACK_RX
- MY_RADIO_NRF5_ESB changes to act more than NRF24
- MY_RADIO_NRF5_ESB better support for powerdown/standby
- Moved initialization from MyMainNRF5 to hwInit()
172 lines
5.3 KiB
C
172 lines
5.3 KiB
C
/**
|
|
* The MySensors Arduino library handles the wireless radio link and protocol
|
|
* between your home built sensors/actuators and HA controller of choice.
|
|
* The sensors forms a self healing radio network with optional repeaters. Each
|
|
* repeater and gateway builds a routing tables in EEPROM which keeps track of
|
|
* the
|
|
* network topology allowing messages to be routed to nodes.
|
|
*
|
|
* Created by Frank Holtz
|
|
* Copyright (C) 2017 Frank Holtz
|
|
* Full contributor list:
|
|
* https://github.com/mysensors/Arduino/graphs/contributors
|
|
*
|
|
* Documentation: http://www.mysensors.org
|
|
* Support Forum: http://forum.mysensors.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* version 2 as published by the Free Software Foundation.
|
|
*/
|
|
|
|
#ifndef __NRF5_ESB_H__
|
|
#define __NRF5_ESB_H__
|
|
|
|
#include "Radio.h"
|
|
#include <Arduino.h>
|
|
|
|
// Check SoftDevice presence
|
|
#if defined(SOFTDEVICE_PRESENT) && !defined(FORCE_RADIO_ESB_WITH_SD)
|
|
#error "NRF5 SoftDevice cannot be used with NRF5 Radio."
|
|
#endif
|
|
|
|
// Check maximum messae length
|
|
#if MAX_MESSAGE_LENGTH > (32)
|
|
#error "Unsupported message length. (MAX_MESSAGE_LENGTH)"
|
|
#endif
|
|
|
|
// check rx buffer size
|
|
#if MY_NRF5_ESB_RX_BUFFER_SIZE < (4)
|
|
#error "MY_NRF5_ESB_RX_BUFFER_SIZE must be greater than 3."
|
|
#endif
|
|
|
|
/** Wait for start of an ACK packet in us
|
|
* Calculation: ramp up time + packet header (57 Bit): round to 9 Byte
|
|
* If you don't receive ACK packages, you have to increase this value.
|
|
* My measured (Aurduino Uno+NRF24L01P) minimal timeouts:
|
|
* 250kbit 411us -> 182 us to ACK start
|
|
* 1MBit 205us -> 147 us
|
|
* 2MBit 173us -> 143 us
|
|
*/
|
|
#define NRF5_ESB_ACK_WAIT \
|
|
((NRF5_ESB_RAMP_UP_TIME << 1) + (9 << NRF5_ESB_byte_time()))
|
|
|
|
// auto retry delay in us, don't set this value < 1500us@250kbit
|
|
#define NRF5_ESB_ARD (1500)
|
|
|
|
// auto retry count with noACK is false
|
|
#define NRF5_ESB_ARC_ACK (15)
|
|
|
|
// auto retry count with noACK is true
|
|
#define NRF5_ESB_ARC_NOACK (15)
|
|
|
|
// How often broadcast messages are send
|
|
#define NRF5_ESB_BC_ARC (15)
|
|
|
|
// Node address index
|
|
#define NRF5_ESB_NODE_ADDR (0)
|
|
#define NRF5_ESB_NODE_ADDR_MSK (0xffffff00UL)
|
|
|
|
// TX address index
|
|
#define NRF5_ESB_TX_ADDR (4)
|
|
#define NRF5_ESB_TX_ADDR_MSK (0xffffff00UL)
|
|
|
|
// BC address index
|
|
#define NRF5_ESB_BC_ADDR (7)
|
|
#define NRF5_ESB_BC_ADDR_MSK (0xffffffffUL)
|
|
|
|
// Shorts for RX mode
|
|
#define NRF5_ESB_SHORTS_RX \
|
|
(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_START_Msk | \
|
|
RADIO_SHORTS_DISABLED_RXEN_Msk | RADIO_SHORTS_ADDRESS_BCSTART_Msk | \
|
|
RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk)
|
|
|
|
// Shorts for TX mode
|
|
#define NRF5_ESB_SHORTS_TX \
|
|
(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_START_Msk | \
|
|
RADIO_SHORTS_DISABLED_TXEN_Msk | RADIO_SHORTS_ADDRESS_BCSTART_Msk)
|
|
|
|
// Shorts to switch from RX to TX
|
|
#define NRF5_ESB_SHORTS_RX_TX \
|
|
(RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_TXEN_Msk | \
|
|
RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_ADDRESS_BCSTART_Msk)
|
|
|
|
// Shorts to switch from TX to RX
|
|
#define NRF5_ESB_SHORTS_TX_RX \
|
|
(RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk | \
|
|
RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_ADDRESS_BCSTART_Msk | \
|
|
RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk)
|
|
|
|
// PPI Channels
|
|
#define NRF5_ESB_PPI_TIMER_START 14
|
|
#define NRF5_ESB_PPI_TIMER_RADIO_DISABLE 15
|
|
#define NRF5_ESB_PPI_BITS \
|
|
((1 << NRF5_ESB_PPI_TIMER_START) | \
|
|
(1 << NRF5_ESB_PPI_TIMER_RADIO_DISABLE))
|
|
|
|
/** Bitcounter for Packet Control Field length
|
|
* 6 Bits address length + 3 Bits S1 (NOACK + PID)
|
|
*/
|
|
#define NRF5_ESB_BITCOUNTER (9)
|
|
|
|
/** ramp up time
|
|
* Time to activate radio TX or RX mode
|
|
*/
|
|
#define NRF5_ESB_RAMP_UP_TIME (130)
|
|
|
|
|
|
static bool NRF5_ESB_initialize();
|
|
static void NRF5_ESB_powerDown();
|
|
static void NRF5_ESB_powerUp();
|
|
static void NRF5_ESB_sleep();
|
|
static void NRF5_ESB_standBy();
|
|
static bool NRF5_ESB_sanityCheck();
|
|
|
|
static void NRF5_ESB_setNodeAddress(const uint8_t address);
|
|
static uint8_t NRF5_ESB_getNodeID();
|
|
|
|
static void NRF5_ESB_startListening();
|
|
static bool NRF5_ESB_isDataAvailable();
|
|
static uint8_t NRF5_ESB_readMessage(void *data);
|
|
|
|
static bool NRF5_ESB_sendMessage(uint8_t recipient, const void *buf, uint8_t len, const bool noACK);
|
|
|
|
static int16_t NRF5_ESB_getSendingRSSI();
|
|
static int16_t NRF5_ESB_getReceivingRSSI();
|
|
|
|
// Calculate time to transmit an byte in us as bit shift -> 2^X
|
|
static inline uint8_t NRF5_ESB_byte_time();
|
|
|
|
/** Structure of radio rackets
|
|
*/
|
|
typedef struct nrf5_radio_packet_s {
|
|
// structure written by radio unit
|
|
struct {
|
|
uint8_t len;
|
|
union {
|
|
uint8_t s1;
|
|
struct {
|
|
uint8_t noack : 1;
|
|
uint8_t pid : 2;
|
|
};
|
|
};
|
|
uint8_t data[MAX_MESSAGE_LENGTH];
|
|
int8_t rssi;
|
|
/** Debug data structure */
|
|
#ifdef MY_DEBUG_VERBOSE_NRF5_ESB
|
|
uint32_t rxmatch;
|
|
#endif
|
|
}
|
|
#ifndef DOXYGEN
|
|
__attribute__((packed));
|
|
#endif
|
|
} NRF5_ESB_Packet;
|
|
|
|
#ifdef MY_DEBUG_VERBOSE_NRF5_ESB
|
|
static uint32_t intcntr_bcmatch;
|
|
static uint32_t intcntr_ready;
|
|
static uint32_t intcntr_end;
|
|
#endif
|
|
|
|
#endif // __NRF5_H__
|