From f28cb609f3cca613c79d955581efdddad9a87adc Mon Sep 17 00:00:00 2001 From: Dennis Date: Mon, 19 Dec 2016 12:34:19 -0500 Subject: [PATCH 01/26] Added CABELL Protocol --- Multiprotocol/CABELL_nrf224l01.ino | 321 +++++++++++++++++++++++++++++ Multiprotocol/Multiprotocol.h | 10 + Multiprotocol/Multiprotocol.ino | 8 +- Multiprotocol/Validate.h | 1 + 4 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 Multiprotocol/CABELL_nrf224l01.ino diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino new file mode 100644 index 0000000..3faac6f --- /dev/null +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -0,0 +1,321 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + +Multiprotocol is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Multiprotocol. If not, see . + */ +// +// My own personal protocol + +#if defined(CABELL_NRF24L01_INO) + +#include "iface_nrf24l01.h" + +#define CABELL_BIND_COUNT 2000 // At least 2000 so that if TX toggles the serial bind flag then bind mode is never exited +#define CABELL_PACKET_PERIOD 3000 // Do not set too low or else next packet may not be finished transmitting before the channel is changed next time around +#define CABELL_NUM_CHANNELS 16 +#define CABELL_MIN_CHANNELS 4 +#define CABELL_PAYLOAD_BYTES 24 // 12 bits per value +#define CABELL_BIND_RADIO_ADDR 0xA4B7C123F7LL + +#define CABELL_OPTION_MASK_CHANNEL_REDUCTION 0x0F +#define CABELL_OPTION_MASK_RECIEVER_OUTPUT_MODE 0x70 +#define CABELL_OPTION_SHIFT_RECIEVER_OUTPUT_MODE 4 +#define CABELL_OPTION_MASK_MAX_POWER_OVERRIDE 0x80 + +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, + unBind = 127 + } RxMode; + uint8_t reserved = 0; + uint8_t option; + /* mask 0x0F : Channel reduction. The number of channels to not send (subtracted frim the 16 max channels) at least 4 are always sent + * mask 0x70>>4 : Reciever outout mode + * 1 = Single PPM on individual pins for each channel + * 2 = SUM PPM on channel 1 pin + * mask 0x80>>7 Unused by RX. Contains max power override flag + */ + uint8_t modelNum; + uint16_t checkSum; + uint8_t payloadValue [CABELL_PAYLOAD_BYTES] = {0}; //12 bits per channel value, unsigned +} CABELL_RxTxPacket_t; + +//----------------------------------------------------------------------------------------- +static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[], uint8_t seqArraySize, uint8_t prevChannel) { + /* Possible channels are in 5 bands, each band comprised of seqArraySize channels + * seqArray contains seqArraySize elements in the relative order in which we should progress through the band + * + * Each time the channel is changes, bands change in a way so that the next channel will be in a + * different non-adjacent band. Both the band changes and the index in seqArray is incremented. + */ + prevChannel = constrain(prevChannel,1,seqArraySize * 5); // Constain the values just in case something bogus was sent in. + prevChannel--; // Subtract one becasue 1 was added to the return value + + uint8_t currBand = prevChannel / seqArraySize; + uint8_t nextBand = (currBand + 3) % 5; + + uint8_t prevChannalSeqArrayValue = prevChannel % seqArraySize; + uint8_t prevChannalSeqArrayPosition = 0; + for (int x = 0; x < seqArraySize; x++) { // Find the position of the previous channel in the array + if (seqArray[x] == prevChannalSeqArrayValue) { + prevChannalSeqArrayPosition = x; + } + } + uint8_t nextChannalSeqArrayPosition = prevChannalSeqArrayPosition + 1; + if (nextChannalSeqArrayPosition >= seqArraySize) nextChannalSeqArrayPosition = 0; + + return (seqArraySize * nextBand) + seqArray[nextChannalSeqArrayPosition] + 1; // Add one so we dont use channel 0 as it may bleed below 2.400 GHz +} + +//----------------------------------------------------------------------------------------- +static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) +{ + CABELL_RxTxPacket_t TxPacket; + static uint8_t currentChannel = 0; + uint8_t maskFirstPacketOnChannelBit = 0x80; + + uint8_t channelReduction = constrain((option & CABELL_OPTION_MASK_CHANNEL_REDUCTION),0,CABELL_NUM_CHANNELS-CABELL_MIN_CHANNELS); // Max 12 - cannot reduce below 4 channels + if (bindMode) { + channelReduction = 0; // Send full packet to bind as higher channels will contain bind info + } + uint8_t packetSize = sizeof(TxPacket) - ((((channelReduction - (channelReduction%2))/ 2)) * 3); // reduce 3 bytes per 2 channels, but not last channel if it is odd + uint8_t maxPayloadValueIndex = sizeof(TxPacket.payloadValue) - (sizeof(TxPacket) - packetSize); + + if (sub_protocol == CABELL_UNBIND) { + TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::unBind; + TxPacket.option = option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION); //remove channel reduction if in unBind mode + } else { + TxPacket.RxMode = (bindMode) ? CABELL_RxTxPacket_t::RxMode_t::bind : CABELL_RxTxPacket_t::RxMode_t::normal; + TxPacket.option = (bindMode) ? (option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION)) : option; //remove channel reduction if in bind mode + } + TxPacket.reserved = 0; + TxPacket.modelNum = RX_num; + TxPacket.checkSum = TxPacket.modelNum + TxPacket.option + TxPacket.RxMode + TxPacket.reserved; // Start Calculate checksum + + int adjusted_x; + int payloadIndex = 0; + uint16_t holdValue; + + for (int x = 0;(x < CABELL_NUM_CHANNELS - channelReduction); x++) { + switch (x) { + case 0 : adjusted_x = ELEVATOR; break; + case 1 : adjusted_x = AILERON; break; + case 2 : adjusted_x = RUDDER; break; + case 3 : adjusted_x = THROTTLE; break; + default : adjusted_x = x; break; + } + holdValue = map(limit_channel_100(adjusted_x),servo_min_100,servo_max_100,1000,2000); // valid channel values are 1000 to 2000 + if (bindMode) { + switch (adjusted_x) { + case THROTTLE : holdValue = 1000; break; // always set throttle to off when binding for safety + //tx address sent for bind + case 11 : holdValue = 1000 + rx_tx_addr[0]; break; + case 12 : holdValue = 1000 + rx_tx_addr[1]; break; + 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; + } + } + + // use 12 bits per value + if (x % 2) { //output channel number is ODD + holdValue = holdValue<<4; + payloadIndex--; + } else { + holdValue &= 0x0FFF; + } + TxPacket.payloadValue[payloadIndex] |= (uint8_t)(holdValue & 0x00FF); + payloadIndex++; + TxPacket.payloadValue[payloadIndex] |= (uint8_t)((holdValue>>8) & 0x00FF); + payloadIndex++; + } + + for(int x = 0; x < maxPayloadValueIndex ; x++) { + TxPacket.checkSum = TxPacket.checkSum + TxPacket.payloadValue[x]; // Finish Calculate checksum + } + + // Set channel for next transmission + rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_NUM_CHANNELS, rf_ch_num); + NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num); + + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); //just in case things got hung up + + uint8_t* p = reinterpret_cast(&TxPacket.RxMode); + *p &= 0x7F; // Make sure 8th bit is clear + *p |= (packet_count++)<<7; // This causes the 8th bit of the first byte to toggle with each xmit so consecrutive payloads are not identical. + // 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); +} + +//----------------------------------------------------------------------------------------- +static void __attribute__((unused)) CABELL_getChannelSequence (uint8_t outArray[], uint8_t numChannels, uint64_t permutation) { + /* This procedure initializes an array with the sequence progression of channels. + * This is not the actual channels itself, but the sequence base to be used within bands of + * channels. + * + * There are numChannels! permutations for arranging the channels + * one of these permutations will be calculated based on the permutation input + * permutation should be between 1 and numChannels! but the routine will constrain it + * if these bounds are exceeded. Typically the radio's unique TX ID shouldbe used. + * + * The maximum numChannels is 20. Anything larget than this will cause the uint64_t + * variables to overflow, yielding unknown resutls (possibly infinate loop?). Therefor + * this routine constrains the value. + */ + uint64_t i; //iterator counts numChannels + uint64_t indexOfNextSequenceValue; + uint64_t numChannelsFactorial=1; + uint8_t sequenceValue; + + numChannels = constrain(numChannels,1,20); + + for (i = 1; i <= numChannels;i++) { + numChannelsFactorial *= i; // Calculate n! + outArray[i-1] = i-1; // Initialize array with the sequence + } + + permutation = constrain(permutation,1,numChannelsFactorial); // k must be between 1 and n! or this algorithm will infinate loop + + //Rearrange the array elements based on the permutation selected + for (i=0, permutation--; i i; indexOfNextSequenceValue--) { + outArray[indexOfNextSequenceValue] = outArray[indexOfNextSequenceValue-1]; + } + // Copy the selected value into it's new array slot + outArray[i] = sequenceValue; + } +} + +//----------------------------------------------------------------------------------------- +static void __attribute__((unused)) CABELL_setAddress() +{ + uint64_t CABELL_addr; + +// Serial.print("NORM ID: ");Serial.print((uint32_t)(CABELL_normal_addr>>32)); Serial.print(" ");Serial.println((uint32_t)((CABELL_normal_addr<<32)>>32)); + + if (IS_BIND_DONE_on) { + CABELL_addr = (((uint64_t)rx_tx_addr[0]) << 32) + + (((uint64_t)rx_tx_addr[1]) << 24) + + (((uint64_t)rx_tx_addr[2]) << 16) + + (((uint64_t)rx_tx_addr[3]) << 8) + + (((uint64_t)rx_tx_addr[4])); // Address to use after binding + } + else { + CABELL_addr = CABELL_BIND_RADIO_ADDR; //static addr for binding + } + + CABELL_getChannelSequence(hopping_frequency,CABELL_NUM_CHANNELS,CABELL_addr); // Get the sequence for hopping through channels + rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_NUM_CHANNELS, 1); // initialize the channel sequence + + packet_count=0; + + NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, reinterpret_cast(&CABELL_addr), 5); + NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, reinterpret_cast(&CABELL_addr), 5); + NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, reinterpret_cast(&CABELL_addr), 5); +} + +//----------------------------------------------------------------------------------------- +static void __attribute__((unused)) CABELL_init() +{ + NRF24L01_Initialize(); + CABELL_SetPower(); + NRF24L01_SetBitrate(NRF24L01_BR_250K); + NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement on all data pipes + NRF24L01_SetTxRxMode(TX_EN); //Power up and 16 bit CRC + + CABELL_setAddress(); + + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x02); + 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); + NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x5F); // no retransmits + NRF24L01_Activate(0x73); // Activate feature register + NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes + NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x04); // Enable dynamic Payload Length + NRF24L01_Activate(0x73); +} + +//----------------------------------------------------------------------------------------- +static void CABELL_SetPower() // This over-ride the standard Set Power to allow an flag in option to indicate max power setting + // Note that on many modules max power may actually be worse than the normal high power setting + // test and only use max if it helps the range +{ + if(IS_BIND_DONE_on && !IS_RANGE_FLAG_on && (option & CABELL_OPTION_MASK_MAX_POWER_OVERRIDE)) { // If we are not in range or bind mode and power setting override is in effect, then set max power, else standard pawer logic + if(prev_power != NRF_POWER_3) // prev_power is global variable for NRF24L01; NRF_POWER_3 is max power + { + uint8_t rf_setup = NRF24L01_ReadReg(NRF24L01_06_RF_SETUP); + rf_setup = (rf_setup & 0xF9) | (NRF_POWER_3 << 1); + NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup); + prev_power=NRF_POWER_3; + } + } + else { + NRF24L01_SetPower(); + } +} + +//----------------------------------------------------------------------------------------- +uint16_t CABELL_callback() +{ + if(IS_BIND_DONE_on) + CABELL_send_packet(0); + else + { + if (bind_counter == 0) + { + BIND_DONE; + CABELL_init(); // non-bind address + } + else + { + CABELL_send_packet(1); + bind_counter--; + } + } + return CABELL_PACKET_PERIOD; +} + +//----------------------------------------------------------------------------------------- +uint16_t initCABELL(void) +{ + if (IS_BIND_DONE_on) { + bind_counter = 0; + } + else + { + bind_counter = CABELL_BIND_COUNT; + } + CABELL_init(); + return CABELL_PACKET_PERIOD; +} + +#endif diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 5354123..e3481a5 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -55,6 +55,7 @@ enum PROTOCOLS MODE_OPENLRS = 27, // =>OpenLRS hardware MODE_AFHDS2A = 28, // =>A7105 MODE_Q2X2 = 29, // =>NRF24L01, extension of CX-10 protocol + MODE_CABELL = 30, // =>NRF24L01 }; enum Flysky @@ -173,6 +174,11 @@ enum FY326 FY326 = 0, FY319 = 1, }; +enum CABELL +{ + CABELL_V3 = 0, + CABELL_UNBIND = 7 +}; #define NONE 0 #define P_HIGH 1 @@ -442,6 +448,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- OpenLRS 27 AFHDS2A 28 Q2X2 29 + CABELL 30 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -529,6 +536,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- sub_protocol==FY326 FY326 0 FY319 1 + sub_protocol==CABELL + CABELL_V3 0, + CABELL_UNBIND 7 Power value => 0x80 0=High/1=Low Stream[3] = option_protocol; diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 2a051aa..04e0234 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -852,7 +852,13 @@ static void protocol_init() remote_callback = HONTAI_callback; break; #endif - #endif + #if defined(CABELL_NRF24L01_INO) + case MODE_CABELL: + next_callback=initCABELL(); + remote_callback = CABELL_callback; + break; + #endif + #endif } if(next_callback>32000) diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index 6fbd9e3..dcacc1b 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -64,6 +64,7 @@ #undef FQ777_NRF24L01_INO #undef ASSAN_NRF24L01_INO #undef HONTAI_NRF24L01_INO + #undef CABELL_NRF24L01_INO #endif //Make sure telemetry is selected correctly From a00bc9956a155a1a73dbbcd21fd19633d6d121ff Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 21 Dec 2016 14:59:46 -0500 Subject: [PATCH 02/26] Added additional disclaimer to license. --- Multiprotocol/CABELL_nrf224l01.ino | 8 +++ Multiprotocol/Pins.h | 88 ++++++++++++++++-------------- Multiprotocol/_Config.h | 14 +++-- 3 files changed, 64 insertions(+), 46 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 3faac6f..c84d580 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -1,4 +1,12 @@ /* + To use this software, you must adhere to the license terms described below, and assume all responsibility for the use + of the software. The user is responsible for all consequences or damage that may result from using this software. + The user is responsible for ensuring that the hardware used to run this software complies with local regulations and that + any radio signal generated from use of this software is legal for that user to generate. The author(s) of this software + assume no liability whatsoever. The author(s) of this software is not responsible for legal or civil consequences of + using this software, including, but not limited to, any damages cause by lost control of a vehicle using this software. + If this software is copied or modified, this disclaimer must accompany all copies. + This project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or diff --git a/Multiprotocol/Pins.h b/Multiprotocol/Pins.h index 9850055..ff47296 100644 --- a/Multiprotocol/Pins.h +++ b/Multiprotocol/Pins.h @@ -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) diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index d40966c..3fc4bf8 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -49,9 +49,9 @@ //If a chip is not installed all associated protocols are disabled. //4-in-1 modules have all RF chips installed //!!!If a RF chip is present it MUST be marked as installed!!! or weird things will happen you have been warned. -#define A7105_INSTALLED -#define CYRF6936_INSTALLED -#define CC2500_INSTALLED +//#define A7105_INSTALLED +//#define CYRF6936_INSTALLED +//#define CC2500_INSTALLED #define NRF24L01_INSTALLED @@ -95,7 +95,8 @@ #define FY326_NRF24L01_INO #define FQ777_NRF24L01_INO #define ASSAN_NRF24L01_INO -#define HONTAI_NRF24L01_INO +#define HONTAI_NRF24L01_INO +#define CABELL_NRF24L01_INO /**************************/ @@ -139,7 +140,7 @@ /*************************/ //In this section you can configure all details about PPM. //If you do not plan to use the PPM mode comment this line using "//" to save Flash space, you don't need to configure anything below in this case -#define ENABLE_PPM +//#define ENABLE_PPM /*** TX END POINTS ***/ //It is important for the module to know the endpoints of your radio. @@ -288,6 +289,9 @@ const PPM_Parameters PPM_prot[15]= { PPM_IBUS PWM_SBUS PPM_SBUS + MODE_CABELL + CABELL_V3 + CABELL_UNBIND */ // RX_Num is used for model match. Using RX_Num values different for each receiver will prevent starting a model with the false config loaded... From 4fa0b94abcf1c11e7daa938a8eb0d44ad4ec3922 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 21 Dec 2016 15:00:08 -0500 Subject: [PATCH 03/26] Revert "Added additional disclaimer to license." This reverts commit a00bc9956a155a1a73dbbcd21fd19633d6d121ff. --- Multiprotocol/CABELL_nrf224l01.ino | 8 --- Multiprotocol/Pins.h | 88 ++++++++++++++---------------- Multiprotocol/_Config.h | 14 ++--- 3 files changed, 46 insertions(+), 64 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index c84d580..3faac6f 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -1,12 +1,4 @@ /* - To use this software, you must adhere to the license terms described below, and assume all responsibility for the use - of the software. The user is responsible for all consequences or damage that may result from using this software. - The user is responsible for ensuring that the hardware used to run this software complies with local regulations and that - any radio signal generated from use of this software is legal for that user to generate. The author(s) of this software - assume no liability whatsoever. The author(s) of this software is not responsible for legal or civil consequences of - using this software, including, but not limited to, any damages cause by lost control of a vehicle using this software. - If this software is copied or modified, this disclaimer must accompany all copies. - This project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or diff --git a/Multiprotocol/Pins.h b/Multiprotocol/Pins.h index ff47296..9850055 100644 --- a/Multiprotocol/Pins.h +++ b/Multiprotocol/Pins.h @@ -34,28 +34,28 @@ #endif // Dial - #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 + #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 // PPM #define PPM_pin 3 //D3 = PD3 #define PPM_port PORTD // SDIO - #define SDI_pin 3 //D11 = PB3 = MOSI - #define SDI_port PORTB - #define SDI_ipr PINB - #define SDI_ddr DDRB + #define SDI_pin 5 //D5 = PD5 + #define SDI_port PORTD + #define SDI_ipr PIND + #define SDI_ddr DDRD #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 4 //D12 = PB4 = MISO - #define SDO_port PORTB - #define SDO_ipr PINB + #define SDO_pin 6 //D6 = PD6 + #define SDO_port PORTD + #define SDO_ipr PIND #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 PORTB - #define SCLK_ddr DDRB + #define SCLK_port PORTD + #define SCLK_ddr DDRD #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 5 //D13 = PB5 = SCLK + #define SCLK_pin 4 //D4 = PD4 #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,28 +103,22 @@ #define A7105_CSN_off A7105_CSN_port &= ~_BV(A7105_CSN_pin) // CC2500 - #define CC25_CSN_pin 3 //A3 = PC3 = CSN - #define CC25_CSN_port PORTC - #define CC25_CSN_ddr DDRC + #define CC25_CSN_pin 7 //D7 = PD7 + #define CC25_CSN_port PORTD + #define CC25_CSN_ddr DDRD #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 - // 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_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) #define NRF_CSN_off NRF_CSN_port &= ~_BV(NRF_CSN_pin) + #define NRF_CE_on + #define NRF_CE_off // CYRF6936 #ifdef ORANGE_TX @@ -162,7 +156,7 @@ #define PE2_on #define PE2_off #else - #define PE1_pin 4 //A4 = PC4 + #define PE1_pin 1 //A1 = PC1 #define PE1_port PORTC #define PE1_ddr DDRC #define PE1_output PE1_ddr |= _BV(PE1_pin) @@ -188,9 +182,9 @@ #define LED_output LED_port.DIRSET = _BV(LED_pin) #define IS_LED_on (LED_port.OUT & _BV(LED_pin)) #else - #define LED_pin 1 //A1 = PC1 - #define LED_port PORTC - #define LED_ddr DDRC + #define LED_pin 5 //D13 = PB5 + #define LED_port PORTB + #define LED_ddr DDRB #define LED_on LED_port |= _BV(LED_pin) #define LED_off LED_port &= ~_BV(LED_pin) #define LED_toggle LED_port ^= _BV(LED_pin) @@ -204,10 +198,10 @@ #define BIND_port PORTD #define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 ) #else - #define BIND_pin 1 //A1 = PC1 - #define BIND_port PORTC - #define BIND_ipr PINC - #define BIND_ddr DDRC + #define BIND_pin 5 //D13 = PB5 + #define BIND_port PORTB + #define BIND_ipr PINB + #define BIND_ddr DDRB #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) diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 3fc4bf8..d40966c 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -49,9 +49,9 @@ //If a chip is not installed all associated protocols are disabled. //4-in-1 modules have all RF chips installed //!!!If a RF chip is present it MUST be marked as installed!!! or weird things will happen you have been warned. -//#define A7105_INSTALLED -//#define CYRF6936_INSTALLED -//#define CC2500_INSTALLED +#define A7105_INSTALLED +#define CYRF6936_INSTALLED +#define CC2500_INSTALLED #define NRF24L01_INSTALLED @@ -95,8 +95,7 @@ #define FY326_NRF24L01_INO #define FQ777_NRF24L01_INO #define ASSAN_NRF24L01_INO -#define HONTAI_NRF24L01_INO -#define CABELL_NRF24L01_INO +#define HONTAI_NRF24L01_INO /**************************/ @@ -140,7 +139,7 @@ /*************************/ //In this section you can configure all details about PPM. //If you do not plan to use the PPM mode comment this line using "//" to save Flash space, you don't need to configure anything below in this case -//#define ENABLE_PPM +#define ENABLE_PPM /*** TX END POINTS ***/ //It is important for the module to know the endpoints of your radio. @@ -289,9 +288,6 @@ const PPM_Parameters PPM_prot[15]= { PPM_IBUS PWM_SBUS PPM_SBUS - MODE_CABELL - CABELL_V3 - CABELL_UNBIND */ // RX_Num is used for model match. Using RX_Num values different for each receiver will prevent starting a model with the false config loaded... From 15f4e8263d1da0fbf7a43b3bc0c7c26fffec463c Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 21 Dec 2016 15:01:58 -0500 Subject: [PATCH 04/26] Added additional disclaimer --- Multiprotocol/CABELL_nrf224l01.ino | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 3faac6f..c84d580 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -1,4 +1,12 @@ /* + To use this software, you must adhere to the license terms described below, and assume all responsibility for the use + of the software. The user is responsible for all consequences or damage that may result from using this software. + The user is responsible for ensuring that the hardware used to run this software complies with local regulations and that + any radio signal generated from use of this software is legal for that user to generate. The author(s) of this software + assume no liability whatsoever. The author(s) of this software is not responsible for legal or civil consequences of + using this software, including, but not limited to, any damages cause by lost control of a vehicle using this software. + If this software is copied or modified, this disclaimer must accompany all copies. + This project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or From cf6c6585f2464ec66dbfd517c48524b713c2b120 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 21 Dec 2016 15:05:43 -0500 Subject: [PATCH 05/26] Added CABELL_NRF24L01_INO define to config --- Multiprotocol/_Config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index d40966c..e7cd177 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -96,6 +96,7 @@ #define FQ777_NRF24L01_INO #define ASSAN_NRF24L01_INO #define HONTAI_NRF24L01_INO +#define CABELL_NRF24L01_INO /**************************/ From 9e5c24746717358907470d10fab3e13c29390d20 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 21 Dec 2016 15:14:12 -0500 Subject: [PATCH 06/26] Updated available protocol list Added CABELL protocol --- Multiprotocol/_Config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index e7cd177..4b0f7bd 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -289,6 +289,9 @@ const PPM_Parameters PPM_prot[15]= { PPM_IBUS PWM_SBUS PPM_SBUS + MODE_CABELL + CABELL_V3 + CABELL_UNBIND */ // RX_Num is used for model match. Using RX_Num values different for each receiver will prevent starting a model with the false config loaded... From b57e8140b0ba8c888e429c0399fa6af93843f146 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 4 Jan 2017 18:58:38 -0500 Subject: [PATCH 07/26] Removed unused variables --- Multiprotocol/CABELL_nrf224l01.ino | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index c84d580..a7f7b99 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -89,8 +89,6 @@ static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[] static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) { CABELL_RxTxPacket_t TxPacket; - static uint8_t currentChannel = 0; - uint8_t maskFirstPacketOnChannelBit = 0x80; uint8_t channelReduction = constrain((option & CABELL_OPTION_MASK_CHANNEL_REDUCTION),0,CABELL_NUM_CHANNELS-CABELL_MIN_CHANNELS); // Max 12 - cannot reduce below 4 channels if (bindMode) { @@ -161,8 +159,8 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_NUM_CHANNELS, rf_ch_num); NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); //just in case things got hung up + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); uint8_t* p = reinterpret_cast(&TxPacket.RxMode); *p &= 0x7F; // Make sure 8th bit is clear From 022c94c561ede9f8347d9c80ed7033caedb246c4 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sat, 25 Feb 2017 10:34:05 -0500 Subject: [PATCH 08/26] Changed changel range to 45 channels that comply with USA FCC part 97 rules. This change allows licenced HAMs to operate under part 97 rules instead of part 15. These channels are still in the ISM band, but overlap with the part 97 amateur portion of the band. --- Multiprotocol/CABELL_nrf224l01.ino | 35 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index a7f7b99..1affef1 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -1,8 +1,11 @@ /* + Protocol by Dennis Cabell, 2017 + KE8FZX + To use this software, you must adhere to the license terms described below, and assume all responsibility for the use of the software. The user is responsible for all consequences or damage that may result from using this software. The user is responsible for ensuring that the hardware used to run this software complies with local regulations and that - any radio signal generated from use of this software is legal for that user to generate. The author(s) of this software + any radio signal generated or recieved from use of this software is legal for that user to generate. The author(s) of this software assume no liability whatsoever. The author(s) of this software is not responsible for legal or civil consequences of using this software, including, but not limited to, any damages cause by lost control of a vehicle using this software. If this software is copied or modified, this disclaimer must accompany all copies. @@ -20,18 +23,22 @@ Multiprotocol is distributed in the hope that it will be useful, You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -// -// My own personal protocol + #if defined(CABELL_NRF24L01_INO) #include "iface_nrf24l01.h" -#define CABELL_BIND_COUNT 2000 // At least 2000 so that if TX toggles the serial bind flag then bind mode is never exited -#define CABELL_PACKET_PERIOD 3000 // Do not set too low or else next packet may not be finished transmitting before the channel is changed next time around -#define CABELL_NUM_CHANNELS 16 -#define CABELL_MIN_CHANNELS 4 -#define CABELL_PAYLOAD_BYTES 24 // 12 bits per value +#define CABELL_BIND_COUNT 2000 // At least 2000 so that if TX toggles the serial bind flag then bind mode is never exited +#define CABELL_PACKET_PERIOD 3000 // Do not set too low or else next packet may not be finished transmitting before the channel is changed next time around + +#define CABELL_NUM_CHANNELS 16 // The maximum number of RC channels that can be sent in one packet +#define CABELL_MIN_CHANNELS 4 // The minimum number of channels that must be included in a packet, the number of channels cannot be reduced any further than this +#define CABELL_PAYLOAD_BYTES 24 // 12 bits per value * 16 channels + +#define CABELL_RADIO_CHANNELS 9 // This is 1/5 of the total number of radio channels used for FHSS +#define CABELL_RADIO_MIN_CHANNEL_NUM 3 // Channel 0 is right on the boarder of allowed frequency range, so move up to avoid bleeding over + #define CABELL_BIND_RADIO_ADDR 0xA4B7C123F7LL #define CABELL_OPTION_MASK_CHANNEL_REDUCTION 0x0F @@ -66,8 +73,8 @@ static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[] * Each time the channel is changes, bands change in a way so that the next channel will be in a * different non-adjacent band. Both the band changes and the index in seqArray is incremented. */ - prevChannel = constrain(prevChannel,1,seqArraySize * 5); // Constain the values just in case something bogus was sent in. - prevChannel--; // Subtract one becasue 1 was added to the return value + prevChannel -= CABELL_RADIO_MIN_CHANNEL_NUM; // Subtract CABELL_RADIO_MIN_CHANNEL_NUM becasue it was added to the return value + prevChannel = constrain(prevChannel,0,(seqArraySize * 5) ); // Constrain the values just in case something bogus was sent in. uint8_t currBand = prevChannel / seqArraySize; uint8_t nextBand = (currBand + 3) % 5; @@ -82,7 +89,7 @@ static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[] uint8_t nextChannalSeqArrayPosition = prevChannalSeqArrayPosition + 1; if (nextChannalSeqArrayPosition >= seqArraySize) nextChannalSeqArrayPosition = 0; - return (seqArraySize * nextBand) + seqArray[nextChannalSeqArrayPosition] + 1; // Add one so we dont use channel 0 as it may bleed below 2.400 GHz + 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 } //----------------------------------------------------------------------------------------- @@ -156,7 +163,7 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) } // Set channel for next transmission - rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_NUM_CHANNELS, rf_ch_num); + rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_RADIO_CHANNELS, rf_ch_num); NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num); NRF24L01_FlushTx(); //just in case things got hung up @@ -235,8 +242,8 @@ static void __attribute__((unused)) CABELL_setAddress() CABELL_addr = CABELL_BIND_RADIO_ADDR; //static addr for binding } - CABELL_getChannelSequence(hopping_frequency,CABELL_NUM_CHANNELS,CABELL_addr); // Get the sequence for hopping through channels - rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_NUM_CHANNELS, 1); // initialize the channel sequence + CABELL_getChannelSequence(hopping_frequency,CABELL_RADIO_CHANNELS,CABELL_addr); // Get the sequence for hopping through channels + rf_ch_num = CABELL_RADIO_MIN_CHANNEL_NUM; // initialize the channel sequence packet_count=0; From e5b508c72b920047db8eb052063ca4b13d91f7a6 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sun, 26 Feb 2017 15:00:01 -0500 Subject: [PATCH 09/26] Changed protocol number to 33 Was previously 30, but the main branch has now allocated up to 32, so changing to 33 --- Multiprotocol/Multiprotocol.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index e3481a5..1c9f35d 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -55,7 +55,7 @@ enum PROTOCOLS MODE_OPENLRS = 27, // =>OpenLRS hardware MODE_AFHDS2A = 28, // =>A7105 MODE_Q2X2 = 29, // =>NRF24L01, extension of CX-10 protocol - MODE_CABELL = 30, // =>NRF24L01 + MODE_CABELL = 33, // =>NRF24L01 }; enum Flysky @@ -448,7 +448,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- OpenLRS 27 AFHDS2A 28 Q2X2 29 - CABELL 30 + CABELL 33 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No From b67e0ec6a75b0ded97cba36e91ad1da9557eb571 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sat, 11 Mar 2017 12:57:16 -0500 Subject: [PATCH 10/26] Corrected permutation calculation --- Multiprotocol/CABELL_nrf224l01.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 1affef1..92baf8c 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -204,7 +204,7 @@ static void __attribute__((unused)) CABELL_getChannelSequence (uint8_t outArray[ outArray[i-1] = i-1; // Initialize array with the sequence } - permutation = constrain(permutation,1,numChannelsFactorial); // k must be between 1 and n! or this algorithm will infinate loop + permutation = (permutation % numChannelsFactorial) + 1; // permutation must be between 1 and n! or this algorithm will infinate loop //Rearrange the array elements based on the permutation selected for (i=0, permutation--; i Date: Sat, 11 Mar 2017 13:03:22 -0500 Subject: [PATCH 11/26] Added sub-protocol for setting failsafe values --- Multiprotocol/CABELL_nrf224l01.ino | 7 ++++++- Multiprotocol/Multiprotocol.h | 10 ++++++---- Multiprotocol/_Config.h | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 92baf8c..20db173 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -50,6 +50,7 @@ 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 } RxMode; uint8_t reserved = 0; @@ -108,7 +109,11 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::unBind; TxPacket.option = option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION); //remove channel reduction if in unBind mode } else { - TxPacket.RxMode = (bindMode) ? CABELL_RxTxPacket_t::RxMode_t::bind : CABELL_RxTxPacket_t::RxMode_t::normal; + if (sub_protocol == CABELL_SET_FAIL_SAFE) { + TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::setFailSafe; + } else { + TxPacket.RxMode = (bindMode) ? CABELL_RxTxPacket_t::RxMode_t::bind : CABELL_RxTxPacket_t::RxMode_t::normal; + } TxPacket.option = (bindMode) ? (option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION)) : option; //remove channel reduction if in bind mode } TxPacket.reserved = 0; diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 1c9f35d..3453e94 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -176,8 +176,9 @@ enum FY326 }; enum CABELL { - CABELL_V3 = 0, - CABELL_UNBIND = 7 + CABELL_V3 = 0, + CABELL_SET_FAIL_SAFE = 6, + CABELL_UNBIND = 7 }; #define NONE 0 @@ -537,8 +538,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- FY326 0 FY319 1 sub_protocol==CABELL - CABELL_V3 0, - CABELL_UNBIND 7 + CABELL_V3 0, + CABELL_SET_FAIL_SAFE 6, + CABELL_UNBIND 7 Power value => 0x80 0=High/1=Low Stream[3] = option_protocol; diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 4b0f7bd..4832acb 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -291,6 +291,7 @@ const PPM_Parameters PPM_prot[15]= { PPM_SBUS MODE_CABELL CABELL_V3 + CABELL_SET_FAIL_SAFE CABELL_UNBIND */ From 8b8b26e67597249e4ce14667e7b9c3880534d680 Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 14 Mar 2017 20:50:50 -0400 Subject: [PATCH 12/26] Opened up a free bit in the option byte for future use --- Multiprotocol/CABELL_nrf224l01.ino | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 20db173..9e29ae6 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -42,7 +42,7 @@ Multiprotocol is distributed in the hope that it will be useful, #define CABELL_BIND_RADIO_ADDR 0xA4B7C123F7LL #define CABELL_OPTION_MASK_CHANNEL_REDUCTION 0x0F -#define CABELL_OPTION_MASK_RECIEVER_OUTPUT_MODE 0x70 +#define CABELL_OPTION_MASK_RECIEVER_OUTPUT_MODE 0x30 #define CABELL_OPTION_SHIFT_RECIEVER_OUTPUT_MODE 4 #define CABELL_OPTION_MASK_MAX_POWER_OVERRIDE 0x80 @@ -56,10 +56,11 @@ typedef struct { uint8_t reserved = 0; uint8_t option; /* mask 0x0F : Channel reduction. The number of channels to not send (subtracted frim the 16 max channels) at least 4 are always sent - * mask 0x70>>4 : Reciever outout mode - * 1 = Single PPM on individual pins for each channel - * 2 = SUM PPM on channel 1 pin - * mask 0x80>>7 Unused by RX. Contains max power override flag + * mask 0x30>>4 : Reciever outout mode + * 0 = Single PPM on individual pins for each channel + * 1 = SUM PPM on channel 1 pin + * mask 0x40>>7 Unused + * mask 0x80>>7 Unused by RX. Contains max power override flag for Multiprotocol T module */ uint8_t modelNum; uint16_t checkSum; From 8466d49a3a340334645f01f6b1bfb821276d247b Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 14 Mar 2017 20:52:16 -0400 Subject: [PATCH 13/26] Fixed packet errors when trying to unbind when in bind mode This use case didn't really make any sense, but it should not cause packet errors, so fixed it. --- Multiprotocol/CABELL_nrf224l01.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 9e29ae6..a1f4027 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -106,11 +106,11 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) uint8_t packetSize = sizeof(TxPacket) - ((((channelReduction - (channelReduction%2))/ 2)) * 3); // reduce 3 bytes per 2 channels, but not last channel if it is odd uint8_t maxPayloadValueIndex = sizeof(TxPacket.payloadValue) - (sizeof(TxPacket) - packetSize); - if (sub_protocol == CABELL_UNBIND) { + if ((sub_protocol == CABELL_UNBIND) && !bindMode) { TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::unBind; - TxPacket.option = option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION); //remove channel reduction if in unBind mode + TxPacket.option = option; } else { - if (sub_protocol == CABELL_SET_FAIL_SAFE) { + 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; From 58a4be6979eb810e730c5aedcd630abe2c57e94f Mon Sep 17 00:00:00 2001 From: Dennis Date: Sat, 15 Apr 2017 21:06:57 -0400 Subject: [PATCH 14/26] RSSI Telemetry for CABELL protocol --- Multiprotocol/CABELL_nrf224l01.ino | 105 +++++++++++++++++++++++++---- Multiprotocol/Multiprotocol.h | 8 ++- Multiprotocol/Pins.h | 88 +++++++++++++----------- Multiprotocol/_Config.h | 1 + 4 files changed, 146 insertions(+), 56 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index a1f4027..965f550 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -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; } diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index e7d2cf6..e694f05 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -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 -*/ \ No newline at end of file +*/ diff --git a/Multiprotocol/Pins.h b/Multiprotocol/Pins.h index 9850055..ff47296 100644 --- a/Multiprotocol/Pins.h +++ b/Multiprotocol/Pins.h @@ -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) diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index fad0f50..41d8633 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -342,6 +342,7 @@ const PPM_Parameters PPM_prot[15]= { NONE MODE_CABELL CABELL_V3 + CABELL_V3_TELEMETRY CABELL_SET_FAIL_SAFE CABELL_UNBIND */ From f1089ad2685c6d9d4c083f289ad2e50734af431d Mon Sep 17 00:00:00 2001 From: Dennis Date: Sat, 15 Apr 2017 21:11:13 -0400 Subject: [PATCH 15/26] Pins back to stock configuration --- Multiprotocol/Pins.h | 92 ++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 50 deletions(-) diff --git a/Multiprotocol/Pins.h b/Multiprotocol/Pins.h index ff47296..97765e5 100644 --- a/Multiprotocol/Pins.h +++ b/Multiprotocol/Pins.h @@ -3,12 +3,10 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Multiprotocol is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ @@ -34,28 +32,28 @@ #endif // Dial - #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 + #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 // PPM #define PPM_pin 3 //D3 = PD3 #define PPM_port PORTD // SDIO - #define SDI_pin 3 //D11 = PB3 = MOSI - #define SDI_port PORTB - #define SDI_ipr PINB - #define SDI_ddr DDRB + #define SDI_pin 5 //D5 = PD5 + #define SDI_port PORTD + #define SDI_ipr PIND + #define SDI_ddr DDRD #ifdef ORANGE_TX #define SDI_on SDI_port.OUTSET = _BV(SDI_pin) #define SDI_off SDI_port.OUTCLR = _BV(SDI_pin) @@ -69,9 +67,9 @@ #define SDI_output SDI_ddr |= _BV(SDI_pin) //SDO - #define SDO_pin 4 //D12 = PB4 = MISO - #define SDO_port PORTB - #define SDO_ipr PINB + #define SDO_pin 6 //D6 = PD6 + #define SDO_port PORTD + #define SDO_ipr PIND #ifdef ORANGE_TX #define SDO_1 (SDO_port.IN & _BV(SDO_pin)) #define SDO_0 (SDO_port.IN & _BV(SDO_pin)) == 0x00 @@ -81,14 +79,14 @@ #endif // SCLK - #define SCLK_port PORTB - #define SCLK_ddr DDRB + #define SCLK_port PORTD + #define SCLK_ddr DDRD #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 5 //D13 = PB5 = SCLK + #define SCLK_pin 4 //D4 = PD4 #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,28 +101,22 @@ #define A7105_CSN_off A7105_CSN_port &= ~_BV(A7105_CSN_pin) // CC2500 - #define CC25_CSN_pin 3 //A3 = PC3 = CSN - #define CC25_CSN_port PORTC - #define CC25_CSN_ddr DDRC + #define CC25_CSN_pin 7 //D7 = PD7 + #define CC25_CSN_port PORTD + #define CC25_CSN_ddr DDRD #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 - // 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_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) #define NRF_CSN_off NRF_CSN_port &= ~_BV(NRF_CSN_pin) + #define NRF_CE_on + #define NRF_CE_off // CYRF6936 #ifdef ORANGE_TX @@ -162,7 +154,7 @@ #define PE2_on #define PE2_off #else - #define PE1_pin 4 //A4 = PC4 + #define PE1_pin 1 //A1 = PC1 #define PE1_port PORTC #define PE1_ddr DDRC #define PE1_output PE1_ddr |= _BV(PE1_pin) @@ -188,9 +180,9 @@ #define LED_output LED_port.DIRSET = _BV(LED_pin) #define IS_LED_on (LED_port.OUT & _BV(LED_pin)) #else - #define LED_pin 1 //A1 = PC1 - #define LED_port PORTC - #define LED_ddr DDRC + #define LED_pin 5 //D13 = PB5 + #define LED_port PORTB + #define LED_ddr DDRB #define LED_on LED_port |= _BV(LED_pin) #define LED_off LED_port &= ~_BV(LED_pin) #define LED_toggle LED_port ^= _BV(LED_pin) @@ -204,10 +196,10 @@ #define BIND_port PORTD #define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 ) #else - #define BIND_pin 1 //A1 = PC1 - #define BIND_port PORTC - #define BIND_ipr PINC - #define BIND_ddr DDRC + #define BIND_pin 5 //D13 = PB5 + #define BIND_port PORTB + #define BIND_ipr PINB + #define BIND_ddr DDRB #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) @@ -340,4 +332,4 @@ #define eeprom_read_byte EEPROM.read #else #define EE_ADDR uint8_t* -#endif +#endif \ No newline at end of file From 255353a0544bfb71368165459cea9f0e4afc9ba5 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 19 Apr 2017 18:25:44 -0400 Subject: [PATCH 16/26] Split checksum into MSB and LSB fields to avoid endian issue --- Multiprotocol/CABELL_nrf224l01.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 965f550..2ac1d19 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -65,7 +65,6 @@ typedef struct { * mask 0x80>>7 Unused by RX. Contains max power override flag for Multiprotocol T module */ uint8_t modelNum; - uint16_t checkSum; uint8_t payloadValue [CABELL_PAYLOAD_BYTES] = {0}; //12 bits per channel value, unsigned } CABELL_RxTxPacket_t; @@ -180,7 +179,7 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) } TxPacket.reserved = 0; TxPacket.modelNum = RX_num; - TxPacket.checkSum = TxPacket.modelNum + TxPacket.option + TxPacket.RxMode + TxPacket.reserved; // Start Calculate checksum + uint16_t checkSum = TxPacket.modelNum + TxPacket.option + TxPacket.RxMode + TxPacket.reserved; // Start Calculate checksum int adjusted_x; int payloadIndex = 0; @@ -221,9 +220,12 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) } for(int x = 0; x < maxPayloadValueIndex ; x++) { - TxPacket.checkSum = TxPacket.checkSum + TxPacket.payloadValue[x]; // Finish Calculate checksum + checkSum += TxPacket.payloadValue[x]; // Finish Calculate checksum } + TxPacket.checkSum_MSB = checkSum >> 8; + TxPacket.checkSum_LSB = checkSum & 0x00FF; + // Set channel for next transmission rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_RADIO_CHANNELS, rf_ch_num); NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num); From 76f1ec65f0dc6e556f4f8d76b9d78426c7b99a40 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 19 Apr 2017 18:26:19 -0400 Subject: [PATCH 17/26] struct change for checksum --- Multiprotocol/CABELL_nrf224l01.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 2ac1d19..d77bd5b 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -65,6 +65,8 @@ typedef struct { * mask 0x80>>7 Unused by RX. Contains max power override flag for Multiprotocol T module */ uint8_t modelNum; + uint8_t checkSum_LSB; + uint8_t checkSum_MSB; uint8_t payloadValue [CABELL_PAYLOAD_BYTES] = {0}; //12 bits per channel value, unsigned } CABELL_RxTxPacket_t; From 8a56be3d231ed87fbbd0cbfdb0102e28c27283e0 Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 19 Apr 2017 18:27:29 -0400 Subject: [PATCH 18/26] Added analog values to telemetry packet that could be used for LIPO voltage --- Multiprotocol/CABELL_nrf224l01.ino | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index d77bd5b..fb4119c 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -36,8 +36,9 @@ Multiprotocol is distributed in the hope that it will be useful, #define CABELL_MIN_CHANNELS 4 // The minimum number of channels that must be included in a packet, the number of channels cannot be reduced any further than this #define CABELL_PAYLOAD_BYTES 24 // 12 bits per value * 16 channels -#define CABELL_RADIO_CHANNELS 9 // This is 1/5 of the total number of radio channels used for FHSS -#define CABELL_RADIO_MIN_CHANNEL_NUM 3 // Channel 0 is right on the boarder of allowed frequency range, so move up to avoid bleeding over +#define CABELL_RADIO_CHANNELS 9 // This is 1/5 of the total number of radio channels used for FHSS +#define CABELL_RADIO_MIN_CHANNEL_NUM 3 // Channel 0 is right on the boarder of allowed frequency range, so move up to avoid bleeding over +#define CABELL_TELEMETRY_PACKET_LENGTH 4 #define CABELL_BIND_RADIO_ADDR 0xA4B7C123F7LL @@ -121,10 +122,12 @@ static void __attribute__((unused)) CABELL_get_telemetry() // 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); + NRF24L01_ReadPayload(packet, CABELL_TELEMETRY_PACKET_LENGTH); 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]; + RX_RSSI = packet[1]; // Packet rate 0 to 255 where 255 is 100% packet rate + v_lipo1 = packet[2]; // Directly from analog input of reciever, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the reciever. + v_lipo2 = packet[3]; // Directly from analog input of reciever, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the reciever. telemetry_counter++; if(telemetry_lost==0) telemetry_link=1; telemetryProcessingTime = micros() - telemetryProcessingStart; From f78447e146bdd96e897ee4e9505323de6542e96b Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 19 Apr 2017 18:28:54 -0400 Subject: [PATCH 19/26] Added MODE_CABELL to frsk_link_frame --- Multiprotocol/Telemetry.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index 947b118..be17659 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -247,7 +247,7 @@ void frsky_link_frame() telemetry_link |= 2 ; // Send hub if available } else - if (protocol==MODE_HUBSAN||protocol==MODE_AFHDS2A||protocol==MODE_BAYANG) + if (protocol==MODE_HUBSAN||protocol==MODE_AFHDS2A||protocol==MODE_BAYANG||protocol==MODE_CABELL) { frame[1] = v_lipo1; frame[2] = v_lipo2; From 354770d13697721d98bd5bf628c362115331dc4b Mon Sep 17 00:00:00 2001 From: Dennis Date: Thu, 20 Apr 2017 20:25:17 -0400 Subject: [PATCH 20/26] Updated packet layout comments --- Multiprotocol/CABELL_nrf224l01.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index fb4119c..43b2585 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -62,14 +62,14 @@ typedef struct { * mask 0x30>>4 : Reciever outout mode * 0 = Single PPM on individual pins for each channel * 1 = SUM PPM on channel 1 pin - * mask 0x40>>7 Unused + * mask 0x40>>6 Unused * mask 0x80>>7 Unused by RX. Contains max power override flag for Multiprotocol T module */ uint8_t modelNum; uint8_t checkSum_LSB; uint8_t checkSum_MSB; uint8_t payloadValue [CABELL_PAYLOAD_BYTES] = {0}; //12 bits per channel value, unsigned -} CABELL_RxTxPacket_t; +} CABELL_RxTxPacket_t; //----------------------------------------------------------------------------------------- static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[], uint8_t seqArraySize, uint8_t prevChannel) { From 810b8a07ac4ed61743e4902d2e2336cb9694bd0b Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 2 May 2017 00:15:12 -0400 Subject: [PATCH 21/26] Fixed telemetry conditional compiles in CABELL protocol --- Multiprotocol/CABELL_nrf224l01.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 43b2585..92fd4bf 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -99,7 +99,7 @@ static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[] } //----------------------------------------------------------------------------------------- -#if defined(TELEMETRY) && defined(HUB_TELEMETRY) +#if defined 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 @@ -108,7 +108,7 @@ static void __attribute__((unused)) CABELL_get_telemetry() state++; if (state > (500000 / CABELL_PACKET_PERIOD)) { - //calculate telemetry reception RSSI - based on packet rape per 1000ms where 255 is 100% + //calculate telemetry reception RSSI - based on packet rate 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; @@ -146,7 +146,7 @@ static void __attribute__((unused)) CABELL_get_telemetry() //----------------------------------------------------------------------------------------- static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) { - #if defined(TELEMETRY) && defined(HUB_TELEMETRY) + #if defined 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(); } @@ -245,7 +245,7 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) NRF24L01_WritePayload((uint8_t*)&TxPacket, packetSize); - #if defined(TELEMETRY) && defined(HUB_TELEMETRY) + #if defined 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. @@ -417,7 +417,7 @@ uint16_t initCABELL(void) bind_counter = CABELL_BIND_COUNT; } CABELL_init(); - #if defined(TELEMETRY) && defined(HUB_TELEMETRY) + #if defined 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 From d26404ca85e995f1972a2e28d38f1b5fedea1f62 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sun, 7 May 2017 19:10:02 -0400 Subject: [PATCH 22/26] Telemetry working; moved power override bit --- Multiprotocol/CABELL_nrf224l01.ino | 17 ++++++++++------- Multiprotocol/Multiprotocol.ino | 2 +- Multiprotocol/NRF24l01_SPI.ino | 3 ++- Multiprotocol/Telemetry.ino | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 92fd4bf..3bed9cd 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -45,7 +45,7 @@ Multiprotocol is distributed in the hope that it will be useful, #define CABELL_OPTION_MASK_CHANNEL_REDUCTION 0x0F #define CABELL_OPTION_MASK_RECIEVER_OUTPUT_MODE 0x30 #define CABELL_OPTION_SHIFT_RECIEVER_OUTPUT_MODE 4 -#define CABELL_OPTION_MASK_MAX_POWER_OVERRIDE 0x80 +#define CABELL_OPTION_MASK_MAX_POWER_OVERRIDE 0x40 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 @@ -60,10 +60,12 @@ typedef struct { uint8_t option; /* mask 0x0F : Channel reduction. The number of channels to not send (subtracted frim the 16 max channels) at least 4 are always sent * mask 0x30>>4 : Reciever outout mode - * 0 = Single PPM on individual pins for each channel - * 1 = SUM PPM on channel 1 pin - * mask 0x40>>6 Unused - * mask 0x80>>7 Unused by RX. Contains max power override flag for Multiprotocol T module + * 0 (00) = Single PPM on individual pins for each channel + * 1 (01) = SUM PPM on channel 1 pin + * 2 (10) = Future use. Reserved for SBUS output + * 3 (11) = Unused + * mask 0x40>>6 Contains max power override flag for Multiprotocol TX module. Also sent to RX + * mask 0x80>>7 Unused */ uint8_t modelNum; uint8_t checkSum_LSB; @@ -258,8 +260,8 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // RX mode with 16 bit CRC } #endif - CABELL_SetPower(); + } //----------------------------------------------------------------------------------------- @@ -364,6 +366,7 @@ static void __attribute__((unused)) CABELL_init() NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x04); // Enable dynamic Payload Length NRF24L01_Activate(0x73); + prev_power = NRF_POWER_0; } //----------------------------------------------------------------------------------------- @@ -371,7 +374,7 @@ static void CABELL_SetPower() // This over-ride the standard Set Power to all // Note that on many modules max power may actually be worse than the normal high power setting // test and only use max if it helps the range { - if(IS_BIND_DONE_on && !IS_RANGE_FLAG_on && (option & CABELL_OPTION_MASK_MAX_POWER_OVERRIDE)) { // If we are not in range or bind mode and power setting override is in effect, then set max power, else standard pawer logic + if(IS_BIND_DONE_on && !IS_RANGE_FLAG_on && ((option & CABELL_OPTION_MASK_MAX_POWER_OVERRIDE) != 0)) { // If we are not in range or bind mode and power setting override is in effect, then set max power, else standard pawer logic if(prev_power != NRF_POWER_3) // prev_power is global variable for NRF24L01; NRF_POWER_3 is max power { uint8_t rf_setup = NRF24L01_ReadReg(NRF24L01_06_RF_SETUP); diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 2c8ec95..af9d47b 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -505,7 +505,7 @@ uint8_t Update_All() update_led_status(); #if defined(TELEMETRY) #if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) ) - if((protocol==MODE_FRSKYD) || (protocol==MODE_BAYANG) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) ) + if((protocol==MODE_FRSKYD) || (protocol==MODE_BAYANG) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) || (protocol==MODE_CABELL) ) #endif TelemetryUpdate(); #endif diff --git a/Multiprotocol/NRF24l01_SPI.ino b/Multiprotocol/NRF24l01_SPI.ino index 32a12fc..c4ef76f 100644 --- a/Multiprotocol/NRF24l01_SPI.ino +++ b/Multiprotocol/NRF24l01_SPI.ino @@ -134,6 +134,7 @@ void NRF24L01_SetBitrate(uint8_t bitrate) // Bit 0 goes to RF_DR_HIGH, bit 1 - to RF_DR_LOW rf_setup = (rf_setup & 0xD7) | ((bitrate & 0x02) << 4) | ((bitrate & 0x01) << 3); NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup); + prev_power = NRF_POWER_0; // Power setting was just reset. This will get updated in the next call to SetPower } /* @@ -681,4 +682,4 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len) NRF24L01_WritePayload(LT8900_buffer+LT8900_buffer_start,pos_final+pos-LT8900_buffer_start); } // End of LT8900 emulation -#endif \ No newline at end of file +#endif diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index be17659..4bc9153 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -608,7 +608,7 @@ void TelemetryUpdate() #endif if((telemetry_link & 1 )&& protocol != MODE_FRSKYX) - { // FrSkyD + Hubsan + AFHDS2A + Bayang + { // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell frsky_link_frame(); return; } From 4f880ec083d910182eb6b0f5f04b7cfb10f12c65 Mon Sep 17 00:00:00 2001 From: Dennis Date: Mon, 29 May 2017 16:22:18 -0400 Subject: [PATCH 23/26] Changed telemetry to 250 kbps and adjustable packet period - imporves reliability/range --- Multiprotocol/CABELL_nrf224l01.ino | 72 +++++++++++++----------------- Multiprotocol/Multiprotocol.ino | 2 +- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 3bed9cd..3816e73 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -104,42 +104,32 @@ static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[] #if defined 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 + // calculate TX rssi based on past 250 expected telemetry packets. Cannot use full second count because telemetry_counter is not large enough state++; - if (state > (500000 / CABELL_PACKET_PERIOD)) + if (state > 250) { - //calculate telemetry reception RSSI - based on packet rate 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); + TX_RSSI = telemetry_counter; 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, CABELL_TELEMETRY_PACKET_LENGTH); - if ((packet[0] & 0x7F) == CABELL_RxTxPacket_t::RxMode_t::telemetryResponse) // ignore first bit in compare becasue it toggles with each packet + if ((packet[0] & 0x7F) == CABELL_RxTxPacket_t::RxMode_t::telemetryResponse) // ignore high order bit in compare becasue it toggles with each packet { RX_RSSI = packet[1]; // Packet rate 0 to 255 where 255 is 100% packet rate v_lipo1 = packet[2]; // Directly from analog input of reciever, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the reciever. v_lipo2 = packet[3]; // Directly from analog input of reciever, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the reciever. 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); + delayMicroseconds(50); } - NRF24L01_SetTxRxMode(TX_EN); NRF24L01_FlushRx(); } @@ -149,7 +139,7 @@ static void __attribute__((unused)) CABELL_get_telemetry() static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) { #if defined TELEMETRY - if (sub_protocol == CABELL_V3_TELEMETRY) { // check for incommimg packet and switch radio back to TX mode if we were listening for telemetry + if (!bindMode && (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 @@ -237,31 +227,30 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_RADIO_CHANNELS, rf_ch_num); NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num); - NRF24L01_FlushTx(); //just in case things got hung up - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + //NRF24L01_FlushTx(); //just in case things got hung up + //NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); uint8_t* p = reinterpret_cast(&TxPacket.RxMode); *p &= 0x7F; // Make sure 8th bit is clear *p |= (packet_count++)<<7; // This causes the 8th bit of the first byte to toggle with each xmit so consecrutive payloads are not identical. // 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. + CABELL_SetPower(); NRF24L01_WritePayload((uint8_t*)&TxPacket, packetSize); #if defined TELEMETRY - if (sub_protocol == CABELL_V3_TELEMETRY) { // switch radio to rx as soon as packet is sent + if (!bindMode && (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); + // at 250 Kbs per sec, one bit is 4 uS + // then add 140 uS which is 130 uS to begin the xmit and 10 uS fudge factor + delayMicroseconds(((((unsigned long)packetSize * 8ul) + 73ul) * 4ul) + 140ul) ; + packet_period = CABELL_PACKET_PERIOD + (constrain(((int16_t)(CABELL_NUM_CHANNELS - channelReduction) - (int16_t)6 ),(int16_t)0 ,(int16_t)10 ) * (int16_t)100); // increase packet period by 100 us for each channel over 6 NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // RX mode with 16 bit CRC - } + } else #endif - CABELL_SetPower(); - + packet_period = CABELL_PACKET_PERIOD; // Standard packet period when not in telemetry mode. } //----------------------------------------------------------------------------------------- @@ -333,9 +322,11 @@ static void __attribute__((unused)) CABELL_setAddress() rf_ch_num = CABELL_RADIO_MIN_CHANNEL_NUM; // initialize the channel sequence packet_count=0; - - NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, reinterpret_cast(&CABELL_addr), 5); - NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, reinterpret_cast(&CABELL_addr), 5); + + uint64_t CABELL_Telemetry_addr = ~CABELL_addr; // Invert bits for reading so that telemetry packets have a different address. + + NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, reinterpret_cast(&CABELL_Telemetry_addr), 5); + NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, reinterpret_cast(&CABELL_Telemetry_addr), 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, reinterpret_cast(&CABELL_addr), 5); } @@ -344,11 +335,7 @@ static void __attribute__((unused)) CABELL_init() { NRF24L01_Initialize(); CABELL_SetPower(); - 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_SetBitrate(NRF24L01_BR_250K); // slower data rate 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 @@ -391,8 +378,11 @@ static void CABELL_SetPower() // This over-ride the standard Set Power to all //----------------------------------------------------------------------------------------- uint16_t CABELL_callback() { - if(IS_BIND_DONE_on) - CABELL_send_packet(0); + + if (IS_BIND_DONE_on) { + CABELL_send_packet(0); // packet_period is set/adjusted in CABELL_send_packet + return packet_period; + } else { if (bind_counter == 0) @@ -405,8 +395,8 @@ uint16_t CABELL_callback() CABELL_send_packet(1); bind_counter--; } + return CABELL_PACKET_PERIOD; } - return CABELL_PACKET_PERIOD; } //----------------------------------------------------------------------------------------- @@ -424,8 +414,10 @@ uint16_t initCABELL(void) 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; + + packet_period = CABELL_PACKET_PERIOD; + + return packet_period; } #endif diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index af9d47b..28252c6 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -1128,7 +1128,7 @@ void Mprotocol_serial_init() #if defined(TELEMETRY) void PPM_Telemetry_serial_init() { - if( (protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_BAYANG) ) + if( (protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_BAYANG) || (protocol==MODE_CABELL) ) initTXSerial( SPEED_9600 ) ; if(protocol==MODE_FRSKYX) initTXSerial( SPEED_57600 ) ; From 37337b427b924669f7230b00d68b77fec5476186 Mon Sep 17 00:00:00 2001 From: Dennis Date: Sun, 18 Jun 2017 16:09:37 -0400 Subject: [PATCH 24/26] Changed CABELL protocol number to 34 --- Multiprotocol/Multiprotocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index e694f05..117e95d 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -58,7 +58,7 @@ enum PROTOCOLS MODE_WK2x01 = 30, // =>CYRF6936 MODE_Q303 = 31, // =>NRF24L01 MODE_GW008 = 32, // =>NRF24L01 - MODE_CABELL = 33, // =>NRF24L01 + MODE_CABELL = 34, // =>NRF24L01 }; enum Flysky From c6efd0f87afe671fcc9d47562c8636aaa3259354 Mon Sep 17 00:00:00 2001 From: Dennis Date: Thu, 10 Aug 2017 08:12:59 -0400 Subject: [PATCH 25/26] Fixed typos in comments --- Multiprotocol/CABELL_nrf224l01.ino | 42 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/Multiprotocol/CABELL_nrf224l01.ino b/Multiprotocol/CABELL_nrf224l01.ino index 3816e73..2f95b80 100644 --- a/Multiprotocol/CABELL_nrf224l01.ino +++ b/Multiprotocol/CABELL_nrf224l01.ino @@ -5,7 +5,7 @@ To use this software, you must adhere to the license terms described below, and assume all responsibility for the use of the software. The user is responsible for all consequences or damage that may result from using this software. The user is responsible for ensuring that the hardware used to run this software complies with local regulations and that - any radio signal generated or recieved from use of this software is legal for that user to generate. The author(s) of this software + any radio signal generated or received from use of this software is legal for that user to generate. The author(s) of this software assume no liability whatsoever. The author(s) of this software is not responsible for legal or civil consequences of using this software, including, but not limited to, any damages cause by lost control of a vehicle using this software. If this software is copied or modified, this disclaimer must accompany all copies. @@ -23,6 +23,8 @@ Multiprotocol is distributed in the hope that it will be useful, You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ + + // The Receiver for this protocol is available at: https://github.com/soligen2010/RC_RX_CABELL_V3_FHSS #if defined(CABELL_NRF24L01_INO) @@ -58,13 +60,13 @@ typedef struct { } RxMode; uint8_t reserved = 0; uint8_t option; - /* mask 0x0F : Channel reduction. The number of channels to not send (subtracted frim the 16 max channels) at least 4 are always sent - * mask 0x30>>4 : Reciever outout mode + /* mask 0x0F : Channel reduction. The number of channels to not send (subtracted from the 16 max channels) at least 4 are always sent + * mask 0x30>>4 : Receiver output mode * 0 (00) = Single PPM on individual pins for each channel * 1 (01) = SUM PPM on channel 1 pin * 2 (10) = Future use. Reserved for SBUS output * 3 (11) = Unused - * mask 0x40>>6 Contains max power override flag for Multiprotocol TX module. Also sent to RX + * mask 0x40>>6 Contains max power override flag for Multi-protocol TX module. Also sent to RX * mask 0x80>>7 Unused */ uint8_t modelNum; @@ -81,7 +83,7 @@ static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[] * Each time the channel is changes, bands change in a way so that the next channel will be in a * different non-adjacent band. Both the band changes and the index in seqArray is incremented. */ - prevChannel -= CABELL_RADIO_MIN_CHANNEL_NUM; // Subtract CABELL_RADIO_MIN_CHANNEL_NUM becasue it was added to the return value + prevChannel -= CABELL_RADIO_MIN_CHANNEL_NUM; // Subtract CABELL_RADIO_MIN_CHANNEL_NUM because it was added to the return value prevChannel = constrain(prevChannel,0,(seqArraySize * 5) ); // Constrain the values just in case something bogus was sent in. uint8_t currBand = prevChannel / seqArraySize; @@ -114,19 +116,19 @@ static void __attribute__((unused)) CABELL_get_telemetry() telemetry_lost=0; } - // Process incomming telementry packet of it was recieved + // Process incoming telemetry packet of it was received if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { // data received from model NRF24L01_ReadPayload(packet, CABELL_TELEMETRY_PACKET_LENGTH); - if ((packet[0] & 0x7F) == CABELL_RxTxPacket_t::RxMode_t::telemetryResponse) // ignore high order bit in compare becasue it toggles with each packet + if ((packet[0] & 0x7F) == CABELL_RxTxPacket_t::RxMode_t::telemetryResponse) // ignore high order bit in compare because it toggles with each packet { RX_RSSI = packet[1]; // Packet rate 0 to 255 where 255 is 100% packet rate - v_lipo1 = packet[2]; // Directly from analog input of reciever, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the reciever. - v_lipo2 = packet[3]; // Directly from analog input of reciever, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the reciever. + v_lipo1 = packet[2]; // Directly from analog input of receiver, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the receiver. + v_lipo2 = packet[3]; // Directly from analog input of receiver, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the receiver. telemetry_counter++; if(telemetry_lost==0) telemetry_link=1; } } else { - // If no telemetry packet was recieved then delay by the typical telemetry packet processing time + // If no telemetry packet was received 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(50); } @@ -139,7 +141,7 @@ static void __attribute__((unused)) CABELL_get_telemetry() static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) { #if defined TELEMETRY - if (!bindMode && (sub_protocol == CABELL_V3_TELEMETRY)) { // check for incommimg packet and switch radio back to TX mode if we were listening for telemetry + if (!bindMode && (sub_protocol == CABELL_V3_TELEMETRY)) { // check for incoming packet and switch radio back to TX mode if we were listening for telemetry CABELL_get_telemetry(); } #endif @@ -232,7 +234,7 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) uint8_t* p = reinterpret_cast(&TxPacket.RxMode); *p &= 0x7F; // Make sure 8th bit is clear - *p |= (packet_count++)<<7; // This causes the 8th bit of the first byte to toggle with each xmit so consecrutive payloads are not identical. + *p |= (packet_count++)<<7; // This causes the 8th bit of the first byte to toggle with each xmit so consecutive payloads are not identical. // 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. CABELL_SetPower(); @@ -241,8 +243,8 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode) #if defined TELEMETRY if (!bindMode && (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. - // bits = packstsize * 8 + 73 bits overhead + // This is done because polling the status register during xmit caused issues. + // bits = packst_size * 8 + 73 bits overhead // at 250 Kbs per sec, one bit is 4 uS // then add 140 uS which is 130 uS to begin the xmit and 10 uS fudge factor delayMicroseconds(((((unsigned long)packetSize * 8ul) + 73ul) * 4ul) + 140ul) ; @@ -262,10 +264,10 @@ static void __attribute__((unused)) CABELL_getChannelSequence (uint8_t outArray[ * There are numChannels! permutations for arranging the channels * one of these permutations will be calculated based on the permutation input * permutation should be between 1 and numChannels! but the routine will constrain it - * if these bounds are exceeded. Typically the radio's unique TX ID shouldbe used. + * if these bounds are exceeded. Typically the radio's unique TX ID should be used. * - * The maximum numChannels is 20. Anything larget than this will cause the uint64_t - * variables to overflow, yielding unknown resutls (possibly infinate loop?). Therefor + * The maximum numChannels is 20. Anything larger than this will cause the uint64_t + * variables to overflow, yielding unknown results (possibly infinite loop?). Therefor * this routine constrains the value. */ uint64_t i; //iterator counts numChannels @@ -280,7 +282,7 @@ static void __attribute__((unused)) CABELL_getChannelSequence (uint8_t outArray[ outArray[i-1] = i-1; // Initialize array with the sequence } - permutation = (permutation % numChannelsFactorial) + 1; // permutation must be between 1 and n! or this algorithm will infinate loop + permutation = (permutation % numChannelsFactorial) + 1; // permutation must be between 1 and n! or this algorithm will infinite loop //Rearrange the array elements based on the permutation selected for (i=0, permutation--; i Date: Sat, 25 Nov 2017 19:53:15 -0500 Subject: [PATCH 26/26] Fix ATMEGA BASH_SERIAL buffer overrun Changed the compare to TXBUFFER_SIZE to >= If next wasn't set to zero until > TXBUFFER_SIZE then the next time the routines get called the the array index references outside the buffer (e.g tail+1) --- Multiprotocol/Telemetry.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index 52af18a..9b8d9bf 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -975,7 +975,7 @@ void Serial_write( uint8_t byte ) byte |= 1 ; // Start bit #endif uint8_t next = SerialControl.head + 2; - if(next>TXBUFFER_SIZE) + if(next>=TXBUFFER_SIZE) next=0; if ( next != SerialControl.tail ) { @@ -1069,7 +1069,7 @@ ISR(TIMER0_COMPB_vect) GPIOR0 = ptr->data[ptr->tail] ; GPIOR2 = ptr->data[ptr->tail+1] ; uint8_t nextTail = ptr->tail + 2 ; - if ( nextTail > TXBUFFER_SIZE ) + if ( nextTail >= TXBUFFER_SIZE ) nextTail = 0 ; ptr->tail = nextTail ; GPIOR1 = 8 ; @@ -1112,7 +1112,7 @@ ISR(TIMER0_OVF_vect) GPIOR0 = ptr->data[ptr->tail] ; GPIOR2 = ptr->data[ptr->tail+1] ; uint8_t nextTail = ptr->tail + 2 ; - if ( nextTail > TXBUFFER_SIZE ) + if ( nextTail >= TXBUFFER_SIZE ) nextTail = 0 ; ptr->tail = nextTail ; GPIOR1 = 10 ;