RSSI Telemetry for CABELL protocol

This commit is contained in:
Dennis 2017-04-15 21:06:57 -04:00
parent 8466d49a3a
commit 58a4be6979
4 changed files with 146 additions and 56 deletions

View File

@ -48,10 +48,12 @@ Multiprotocol is distributed in the hope that it will be useful,
typedef struct {
enum RxMode_t : uint8_t { // Note bit 8 is used to indicate if the packet is the first of 2 on the channel. Mask out this bit before using the enum
normal = 0,
bind = 1,
setFailSafe = 2,
unBind = 127
normal = 0,
bind = 1,
setFailSafe = 2,
normalWithTelemetry = 3,
telemetryResponse = 4,
unBind = 127
} RxMode;
uint8_t reserved = 0;
uint8_t option;
@ -94,9 +96,58 @@ static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[]
return (seqArraySize * nextBand) + seqArray[nextChannalSeqArrayPosition] + CABELL_RADIO_MIN_CHANNEL_NUM; // Add CABELL_RADIO_MIN_CHANNEL_NUM so we dont use channel 0 as it may bleed below 2.400 GHz
}
//-----------------------------------------------------------------------------------------
#if defined(TELEMETRY) && defined(HUB_TELEMETRY)
static void __attribute__((unused)) CABELL_get_telemetry()
{
static unsigned long telemetryProcessingTime = 50; // initial guess. This will get adjusted below once telemetry packts are recieved
// calculate TX rssi based on telemetry packets recieved per half second. Cannot use full second count because telemetry_counter is not large enough
state++;
if (state > (500000 / CABELL_PACKET_PERIOD))
{
//calculate telemetry reception RSSI - based on packet rape per 1000ms where 255 is 100%
state--; //This is the number of packets expected
TX_RSSI = constrain(((uint16_t)(((float)telemetry_counter / (float)state * (float)255))),0,255);
telemetry_counter = 0;
state = 0;
telemetry_lost=0;
// Serial.print(TX_RSSI);
// Serial.print(" ");
// Serial.println(RX_RSSI);
}
// Process incomming telementry packet of it was recieved
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { // data received from model
unsigned long telemetryProcessingStart = micros();
NRF24L01_ReadPayload(packet, 2);
if ((packet[0] & 0x7F) == CABELL_RxTxPacket_t::RxMode_t::telemetryResponse) // ignore first bit in compare becasue it toggles with each packet
{
RX_RSSI = packet[1];
telemetry_counter++;
if(telemetry_lost==0) telemetry_link=1;
telemetryProcessingTime = micros() - telemetryProcessingStart;
}
} else {
// If no telemetry packet was recieved then delay by the typical telemetry packet processing time
// This is done to try to keep the sendPacket process timing more consistent. Since the SPI payload read takes some time
delayMicroseconds(telemetryProcessingTime);
}
NRF24L01_SetTxRxMode(TX_EN);
NRF24L01_FlushRx();
}
#endif
//-----------------------------------------------------------------------------------------
static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
{
#if defined(TELEMETRY) && defined(HUB_TELEMETRY)
if (sub_protocol == CABELL_V3_TELEMETRY) { // check for incommimg packet and switch radio back to TX mode if we were listening for telemetry
CABELL_get_telemetry();
}
#endif
CABELL_RxTxPacket_t TxPacket;
uint8_t channelReduction = constrain((option & CABELL_OPTION_MASK_CHANNEL_REDUCTION),0,CABELL_NUM_CHANNELS-CABELL_MIN_CHANNELS); // Max 12 - cannot reduce below 4 channels
@ -113,7 +164,17 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
if (sub_protocol == CABELL_SET_FAIL_SAFE && !bindMode) {
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::setFailSafe;
} else {
TxPacket.RxMode = (bindMode) ? CABELL_RxTxPacket_t::RxMode_t::bind : CABELL_RxTxPacket_t::RxMode_t::normal;
if (bindMode) {
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::bind;
} else {
switch (sub_protocol) {
case CABELL_V3_TELEMETRY : TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::normalWithTelemetry;
break;
default : TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::normal;
break;
}
}
}
TxPacket.option = (bindMode) ? (option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION)) : option; //remove channel reduction if in bind mode
}
@ -143,11 +204,6 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
case 13 : holdValue = 1000 + rx_tx_addr[2]; break;
case 14 : holdValue = 1000 + rx_tx_addr[3]; break;
case 15 : holdValue = 1000 + rx_tx_addr[4]; break;
// case 11 : holdValue = 1000 + ((((uint64_t)CABELL_normal_addr)>>32) & 0x00000000000000FF); break;
// case 12 : holdValue = 1000 + ((((uint64_t)CABELL_normal_addr)>>24) & 0x00000000000000FF); break;
// case 13 : holdValue = 1000 + ((((uint64_t)CABELL_normal_addr)>>16) & 0x00000000000000FF); break;
// case 14 : holdValue = 1000 + ((((uint64_t)CABELL_normal_addr)>>8) & 0x00000000000000FF); break;
// case 15 : holdValue = 1000 + ((((uint64_t)CABELL_normal_addr)) & 0x00000000000000FF); break;
}
}
@ -181,6 +237,22 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
// This is a work around for a reported bug in clone NRF24L01 chips that mis-took this case for a re-transmit of the same packet.
NRF24L01_WritePayload((uint8_t*)&TxPacket, packetSize);
#if defined(TELEMETRY) && defined(HUB_TELEMETRY)
if (sub_protocol == CABELL_V3_TELEMETRY) { // switch radio to rx as soon as packet is sent
// calculate transmit time based on packet size and data rate of 1MB per sec
// This is done becasue polling the status register during xmit casued issues.
// The status register will still be chaecked after the delay to be sure xmit is complete
// bits = packstsize * 8 + 73 bits overhead
// at 1 MB per sec, one bit is 1 uS
// then add 150 uS which is 130 uS to begin the xmit and 10 uS fudge factor
delayMicroseconds(((unsigned long)packetSize * 8ul) + 73ul + 150ul) ;
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) delayMicroseconds(5);
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // RX mode with 16 bit CRC
}
#endif
CABELL_SetPower();
}
//-----------------------------------------------------------------------------------------
@ -263,7 +335,11 @@ static void __attribute__((unused)) CABELL_init()
{
NRF24L01_Initialize();
CABELL_SetPower();
NRF24L01_SetBitrate(NRF24L01_BR_250K);
if (sub_protocol == CABELL_V3_TELEMETRY) {
NRF24L01_SetBitrate(NRF24L01_BR_1M); // telemeetry needs higfher data rate for there to be time for the round trip in teh 3ms interval
} else {
NRF24L01_SetBitrate(NRF24L01_BR_250K); // slower data rate when not in telemetry mode gives better range/reliability
}
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement on all data pipes
NRF24L01_SetTxRxMode(TX_EN); //Power up and 16 bit CRC
@ -272,7 +348,7 @@ static void __attribute__((unused)) CABELL_init()
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x02);
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 0x20); // 32 byte packet length
NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, 0x20); // 32 byte packet length
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
@ -334,6 +410,11 @@ uint16_t initCABELL(void)
bind_counter = CABELL_BIND_COUNT;
}
CABELL_init();
#if defined(TELEMETRY) && defined(HUB_TELEMETRY)
init_frskyd_link_telemetry();
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
#endif
return CABELL_PACKET_PERIOD;
}

View File

@ -198,6 +198,7 @@ enum Q303
enum CABELL
{
CABELL_V3 = 0,
CABELL_V3_TELEMETRY = 1,
CABELL_SET_FAIL_SAFE = 6,
CABELL_UNBIND = 7
};
@ -590,9 +591,10 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
CX10D 2
CX10WD 3
sub_protocol==CABELL
CABELL_V3 0,
CABELL_V3 0,
CABELL_V3_TELEMETRY 1,
CABELL_SET_FAIL_SAFE 6,
CABELL_UNBIND 7
CABELL_UNBIND 7
Power value => 0x80 0=High/1=Low
Stream[3] = option_protocol;
@ -688,4 +690,4 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
data[0] = RSSI value
data[1-28] telemetry data
*/
*/

View File

@ -34,28 +34,28 @@
#endif
// Dial
#define MODE_DIAL1_pin 2
#define MODE_DIAL1_port PORTB
#define MODE_DIAL1_ipr PINB
#define MODE_DIAL2_pin 3
#define MODE_DIAL2_port PORTB
#define MODE_DIAL2_ipr PINB
#define MODE_DIAL3_pin 4
#define MODE_DIAL3_port PORTB
#define MODE_DIAL3_ipr PINB
#define MODE_DIAL4_pin 0
#define MODE_DIAL4_port PORTC
#define MODE_DIAL4_ipr PINC
#define MODE_DIAL1_pin 4 //D4 = PD4
#define MODE_DIAL1_port PORTD
#define MODE_DIAL1_ipr PIND
#define MODE_DIAL2_pin 5 //D5 = PD5
#define MODE_DIAL2_port PORTD
#define MODE_DIAL2_ipr PIND
#define MODE_DIAL3_pin 6 //D6 = PD6
#define MODE_DIAL3_port PORTD
#define MODE_DIAL3_ipr PIND
#define MODE_DIAL4_pin 7 //D7 = PD7
#define MODE_DIAL4_port PORTD
#define MODE_DIAL4_ipr PIND
// PPM
#define PPM_pin 3 //D3 = PD3
#define PPM_port PORTD
// SDIO
#define SDI_pin 5 //D5 = PD5
#define SDI_port PORTD
#define SDI_ipr PIND
#define SDI_ddr DDRD
#define SDI_pin 3 //D11 = PB3 = MOSI
#define SDI_port PORTB
#define SDI_ipr PINB
#define SDI_ddr DDRB
#ifdef ORANGE_TX
#define SDI_on SDI_port.OUTSET = _BV(SDI_pin)
#define SDI_off SDI_port.OUTCLR = _BV(SDI_pin)
@ -69,9 +69,9 @@
#define SDI_output SDI_ddr |= _BV(SDI_pin)
//SDO
#define SDO_pin 6 //D6 = PD6
#define SDO_port PORTD
#define SDO_ipr PIND
#define SDO_pin 4 //D12 = PB4 = MISO
#define SDO_port PORTB
#define SDO_ipr PINB
#ifdef ORANGE_TX
#define SDO_1 (SDO_port.IN & _BV(SDO_pin))
#define SDO_0 (SDO_port.IN & _BV(SDO_pin)) == 0x00
@ -81,14 +81,14 @@
#endif
// SCLK
#define SCLK_port PORTD
#define SCLK_ddr DDRD
#define SCLK_port PORTB
#define SCLK_ddr DDRB
#ifdef ORANGE_TX
#define SCLK_pin 7 //PD7
#define SCLK_pin 7 //PD7
#define SCLK_on SCLK_port.OUTSET = _BV(SCLK_pin)
#define SCLK_off SCLK_port.OUTCLR = _BV(SCLK_pin)
#else
#define SCLK_pin 4 //D4 = PD4
#define SCLK_pin 5 //D13 = PB5 = SCLK
#define SCLK_output SCLK_ddr |= _BV(SCLK_pin)
#define SCLK_on SCLK_port |= _BV(SCLK_pin)
#define SCLK_off SCLK_port &= ~_BV(SCLK_pin)
@ -103,22 +103,28 @@
#define A7105_CSN_off A7105_CSN_port &= ~_BV(A7105_CSN_pin)
// CC2500
#define CC25_CSN_pin 7 //D7 = PD7
#define CC25_CSN_port PORTD
#define CC25_CSN_ddr DDRD
#define CC25_CSN_pin 3 //A3 = PC3 = CSN
#define CC25_CSN_port PORTC
#define CC25_CSN_ddr DDRC
#define CC25_CSN_output CC25_CSN_ddr |= _BV(CC25_CSN_pin)
#define CC25_CSN_on CC25_CSN_port |= _BV(CC25_CSN_pin)
#define CC25_CSN_off CC25_CSN_port &= ~_BV(CC25_CSN_pin)
// NRF24L01
#define NRF_CSN_pin 0 //D8 = PB0
#define NRF_CSN_port PORTB
#define NRF_CSN_ddr DDRB
#define NRF_CSN_output NRF_CSN_ddr |= _BV(NRF_CSN_pin)
#define NRF_CSN_on NRF_CSN_port |= _BV(NRF_CSN_pin)
// pin D10 is CE which is set to HIGH in setup. In normal multi module not use as CE is hard wired
#define NRF_CE_pin 2 //D10 = PB2 = CE
#define NRF_CE_port PORTB
#define NRF_CE_ddr DDRB
#define NRF_CE_output NRF_CE_ddr |= _BV(NRF_CE_pin)
#define NRF_CE_on NRF_CE_port |= _BV(NRF_CE_pin)
#define NRF_CE_off NRF_CE_port &= ~_BV(NRF_CE_pin)
#define NRF_CSN_pin 0 //A0 = PC0 = CSN
#define NRF_CSN_port PORTC
#define NRF_CSN_ddr DDRC
#define NRF_CSN_output NRF_CSN_ddr |= _BV(NRF_CSN_pin) ; NRF_CE_output ; NRF_CE_on // Turn CE on so it stays on becasue it is not hard wired like the normal MULTI board
#define NRF_CSN_on NRF_CSN_port |= _BV(NRF_CSN_pin)
#define NRF_CSN_off NRF_CSN_port &= ~_BV(NRF_CSN_pin)
#define NRF_CE_on
#define NRF_CE_off
// CYRF6936
#ifdef ORANGE_TX
@ -156,7 +162,7 @@
#define PE2_on
#define PE2_off
#else
#define PE1_pin 1 //A1 = PC1
#define PE1_pin 4 //A4 = PC4
#define PE1_port PORTC
#define PE1_ddr DDRC
#define PE1_output PE1_ddr |= _BV(PE1_pin)
@ -182,9 +188,9 @@
#define LED_output LED_port.DIRSET = _BV(LED_pin)
#define IS_LED_on (LED_port.OUT & _BV(LED_pin))
#else
#define LED_pin 5 //D13 = PB5
#define LED_port PORTB
#define LED_ddr DDRB
#define LED_pin 1 //A1 = PC1
#define LED_port PORTC
#define LED_ddr DDRC
#define LED_on LED_port |= _BV(LED_pin)
#define LED_off LED_port &= ~_BV(LED_pin)
#define LED_toggle LED_port ^= _BV(LED_pin)
@ -198,10 +204,10 @@
#define BIND_port PORTD
#define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 )
#else
#define BIND_pin 5 //D13 = PB5
#define BIND_port PORTB
#define BIND_ipr PINB
#define BIND_ddr DDRB
#define BIND_pin 1 //A1 = PC1
#define BIND_port PORTC
#define BIND_ipr PINC
#define BIND_ddr DDRC
#define BIND_SET_INPUT BIND_ddr &= ~_BV(BIND_pin)
#define BIND_SET_OUTPUT BIND_ddr |= _BV(BIND_pin)
#define BIND_SET_PULLUP BIND_port |= _BV(BIND_pin)

View File

@ -342,6 +342,7 @@ const PPM_Parameters PPM_prot[15]= {
NONE
MODE_CABELL
CABELL_V3
CABELL_V3_TELEMETRY
CABELL_SET_FAIL_SAFE
CABELL_UNBIND
*/