Files
MySensors/drivers/NRF5/Radio_ESB.h
T
d00616 726a20dad9 Add nrf5 platform (#830)
* Add NVRAM support

This is an EEPROM replacement based on MCU's internal Flash memory.
The NVRAM class is designed to be stateless. Each operation is
written to flash immediately.

The last 16k(nRF51)/32k(nRF52) of Flash memory are managed by the
VirtualPage class.  This class allows writing a single emulated 4k
page up 40,000 times.

The NVRAM class is a log based byte-wise storage allowing up to
40,000,000 writes depending on the number of used addresses.  Each
four allocated addresses from the beginning of the NVRAM reduce the
write log by one.

When first 256 bytes of the emulated storage are used, there is an
average writing capacity of 145,000 cycles per byte.

When the write log is full, the NVRAM is compressed into a new flash
page. After a new page is ready, the old page is released. This
process can take up to 4500 ms and cannot be interrupted.

The NVRAM functionality can easily be ported to ESP8266 or SAMD by
providing a Flash interface.

* Add NRF5 platform support

This is the support of the Nordic Semiconductor NRF51 (nrf51822,
nrf51422) and NRF52 (nrf52832) platform. Based on arduino-nRF5
(https://github.com/sandeepmistry/arduino-nRF5).

The included radio driver is compatible with the NRF24 devices.
Using a SoftDevice (BLE)is not supported and must be removed before
flashing MySensors with a "mass_erase" operation.
2017-05-14 11:53:01 +02:00

158 lines
4.9 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 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
#define NRF5_ESB_ARC (15)
// How often broadcast messages are send
#define NRF5_ESB_BC (1)
// 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;
#endif // __NRF5_H__