Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#include <TimerOne.h>
- /*
- 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.
- Deviation 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 Deviation. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "TimerOne.h"
- #include "iface_nrf24l01.h"
- #define ER9X
- #define DEBUG
- //PINOUT
- #define PPM_pin 3//PPM -D3
- #define SDI_pin 5 //SDIO-D5 /MOSI
- #define SCLK_pin 4 //SCK-D4
- #define NRF_CSN_pin 2 //D2/CS
- #define SDO_pin 6//D6 MISO
- #define CE_pin 7//D7//CE pin
- //
- #define NRF_CSN_on PORTD |= 0x04 //D2
- #define NRF_CSN_off PORTD &= 0xFB //D2
- //
- #define SCK_on PORTD |= 0x10//D4
- #define SCK_off PORTD &= 0xEF//D4
- #define SDI_on PORTD |= 0x20 //D5
- #define SDI_off PORTD &= 0xDF //D5
- //
- #define CE_off PORTD &=0x7F//D7
- #define CE_on PORTD |=0x80;//D7
- //
- //
- #define SDI_1 (PIND & 0x20) == 0x20 //D5
- #define SDI_0 (PIND & 0x20) == 0x00 //D5
- #define SDO_1 (PIND & 0x40) == 0x40//D6
- #define SDO_0 (PIND & 0x40) == 0x00//
- //
- #define RED_LED_pin A3//C3
- #define LED_ON PORTC |= _BV(3);
- #define LED_OFF PORTC &= ~_BV(3);
- //
- #define NOP() __asm__ __volatile__("nop")
- #define PPM_MAX 2000
- #define PPM_MIN 1000
- #define PPM_THROW 1000//PPM max-PPMmin
- /*
- http://www.deviationtx.com/
- TX address Channel Sequence
- S1 3B B6 00 00 A2 15 35 1D 3D
- */
- #define SYMAX_BIND_COUNT 345 // 1.5 seconds
- #define FIRST_PACKET_DELAY 12000
- #define PACKET_PERIOD 4000 // Timeout for callback in uSec
- #define SYMAX_INITIAL_WAIT 500
- #define SYMAX_FLAG_FLIP 0x01
- //#define SYMAX_FLAG_RATES 0x02
- #define SYMAX_FLAG_VIDEO 0x02
- #define SYMAX_FLAG_PICTURE 0x04
- #define SYMAX_PAYLOADSIZE 10 // receive data pipes set to this size, but unused
- #define MAX_PACKET_SIZE 16 // X11,X12,X5C-1 10-byte, X5C 16-byte
- static uint8_t packet[MAX_PACKET_SIZE];
- static uint8_t packet_size;
- static uint16_t counter;
- static uint32_t packet_counter;
- //static uint8_t tx_power;
- static uint8_t throttle, rudder, elevator, aileron, flags;
- static uint8_t rx_tx_addr[5];
- static uint8_t multimedia = 0;
- const uint8_t VideoBit = 7;
- const uint8_t PictureBit = 7;
- volatile uint16_t Servo_data[8];
- uint8_t mode_select = 0;
- byte scale;
- enum {
- MOODE_SYMAX11,
- MODE_SYMAX5C
- };
- #if defined(ER9X)
- #define PPM_MAX 255//2000//TURNIGY/ER9x
- #define PPM_MIN 0 //1000
- #define PPM_THROW 1000//PPM max-PPMmin
- enum chan_order {
- AILERON = 0,
- ELEVATOR,
- THROTTLE,
- RUDDER,
- AUX1,
- AUX2,
- AUX3,
- AUX4
- };
- #endif
- // frequency channel management
- #define MAX_RF_CHANNELS 17
- static uint8_t current_chan;
- static uint8_t chans[MAX_RF_CHANNELS];
- static uint8_t num_rf_channels;
- static uint8_t phase;
- bool partial_read = false;
- int index = 0;
- enum {
- SYMAX_INIT1 = 0,
- SYMAX_BIND2,
- SYMAX_BIND3,
- SYMAX_DATA
- };
- uint8_t data_rx_tx_addr[] = {0x3b,0xb6,0x00,0x00,0xa2};//<<--- is ok
- //uint8_t data_rx_tx_addr[] = {0x3b,0xb6,0x00,0x00,0xa2};//<<--- is ok
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x00,0x00,0xa2};
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x03,0x00,0xa2};//<<---- is ok
- //uint8_t data_rx_tx_addr[] = {0x46,0x18,0x00,0x00,0xa2};
- //-------------
- //uint8_t data_rx_tx_addr[] = {0x3b,0xb6,0x00,0x00,0xa2};//<<--- is ok COM9 //#6
- //uint8_t data_rx_tx_addr[] = {0x3b,0xb6,0x03,0x00,0xa2};//<<--- is ok COM11//#3
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x02,0x00,0xa2};//<<--- is ok 90% COM12-com5 //#1
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x00,0x00,0xa2};//<<--- is ok 100% COM10
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x05,0x00,0xa2};//<<--- is ok 90% //#4
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x04,0x00,0xa2};//<<--- is ok 90%
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x07,0x00,0xa2};//<<--- is ok 90%//
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x03,0x00,0xa2};//<<---- is ok
- //uint8_t data_rx_tx_addr[] = {0x46,0x18,0x01,0x00,0xa2};//<<--- is ok family 2 90% COM3 //#5
- //uint8_t data_rx_tx_addr[] = {0x46,0x18,0x03,0x00,0xa2};//<<--- is ok family 2 90% COM6
- //uint8_t data_rx_tx_addr[] = {0x46,0x18,0x04,0x00,0xa2};//<<--- is ok family 2 90% COM7 //#2
- //
- //uint8_t data_rx_tx_addr[] = {0x9A,0xe9,0x07,0x00,0xa2};//<<--- is ok 90%
- // Bit vector from bit position
- #define BV(bit) (1 << bit)
- unsigned long wait_until = 0;
- unsigned long lastWait = 0;
- void setup()
- {
- mode_select = MODE_SYMAX5C; //MODE_SYMAX5C;
- pinMode(RED_LED_pin, OUTPUT);
- //RF module pins
- pinMode(PPM_pin, INPUT);//PPM input
- pinMode(SDI_pin, OUTPUT);//MOSI
- pinMode(SDO_pin, INPUT); //MISO
- pinMode(SCLK_pin, OUTPUT);//SCLK
- //pinMode(CS_pin, OUTPUT);//CS
- pinMode(CE_pin, OUTPUT); //CE
- pinMode(NRF_CSN_pin, OUTPUT);
- pinMode (11, OUTPUT);
- digitalWrite(11, LOW);
- pinMode (12, OUTPUT); //Yes
- pinMode(13, OUTPUT); //No
- digitalWrite(13, HIGH);
- //CS_on;//start CS high
- NRF_CSN_on;
- SDI_on;//start SDIO high
- SCK_off;//start sck low
- CE_on;
- //
- for (int i = 0; i < 8; i++) {
- Servo_data[i] = 0 ; //1500;
- }
- Servo_data[THROTTLE] = 255 ; // -127 in sign and magnitude format
- //
- #if F_CPU == 16000000
- scale = 2;
- #elif F_CPU == 8000000
- scale = 1;
- #endif
- #if defined(DEBUG) || defined(DEBUG2)
- Serial.begin(115200); // For debuging//115200
- //Serial.println("Midelic's nRF24L01");
- //Serial.print("Testing SPI to NRF24L01+ ");
- //if(NRF24L01_ReadReg(NRF24L01_0F_RX_ADDR_P5) == 0xC6) Serial.println(" ... passed");
- //else Serial.println(" ... FAILED");
- //NRF24L01_spi_test(); // 10 minute spi test.
- #endif
- packet_counter = 0;
- flags = 0;
- symax_init();
- phase = SYMAX_INIT1;//phase =0
- //PROTOCOL_SetBindState(BIND_COUNT * PACKET_PERIOD / 1000);
- //CLOCK_StartTimer(INITIAL_WAIT, symax_callback);
- delayMicroseconds(SYMAX_INITIAL_WAIT);
- //_delay_ms(SYMAX_INITIAL_WAIT);
- Timer1.initialize( 4000 );
- Timer1.attachInterrupt( read_serial);//read_ppm );
- wait_until = 0;
- }
- void loop() {
- //call actual function & take care of delays
- while (micros() < wait_until);
- wait_until = micros() + symax_callback();
- //Serial.println(wait_until-lastWait);
- lastWait = wait_until;
- }
- uint16_t symax_callback()
- {
- switch (phase) {
- case SYMAX_INIT1:
- symax_init1();
- phase = SYMAX_BIND2;
- //
- return FIRST_PACKET_DELAY;
- break;
- case SYMAX_BIND2:
- counter = SYMAX_BIND_COUNT;
- phase = SYMAX_BIND3;
- SYMAX_send_packet(1);
- break;
- case SYMAX_BIND3:
- if (counter == 0) {
- symax_init2();
- phase = SYMAX_DATA;
- //PROTOCOL_SetBindState(0);
- //MUSIC_Play(MUSIC_DONE_BINDING);
- LED_ON;
- } else {
- SYMAX_send_packet(1);
- counter -= 1;
- }
- break;
- case SYMAX_DATA:
- SYMAX_send_packet(0);
- //return SYMAX_INITIAL_WAIT;
- break;
- }
- return PACKET_PERIOD;
- }
- static uint8_t checksum(uint8_t *data)
- {
- uint8_t sum = data[0];
- for (int i = 1; i < packet_size - 1; i++)
- if (mode_select == MODE_SYMAX5C)
- sum += data[i];
- else
- sum ^= data[i];
- return sum + (mode_select == MODE_SYMAX5C ? 0 : 0x55);
- }
- //#define BABS(X) (((X) < 0) ? -(uint8_t)(X) : (X))
- // Channel values are sign + magnitude 8bit values
- /*
- static uint8_t SYMAX_convert_channel(uint8_t num)
- {
- //s32 ch = Channels[num];
- //if (ch < CHAN_MIN_VALUE) {
- // ch = CHAN_MIN_VALUE;
- ///} else if (ch > CHAN_MAX_VALUE) {
- // ch = CHAN_MAX_VALUE;
- /// }
- //return (uint8_t) ((ch < 0 ? 0x80 : 0) | BABS(ch * 127 / CHAN_MAX_VALUE));
- return (uint8_t) (map(Servo_data[num],PPM_MIN,PPM_MAX,0,255));
- }
- */
- static void SYMAX_read_controls(uint8_t* throttle, uint8_t* rudder, uint8_t* elevator, uint8_t* aileron, uint8_t* flags)
- {
- // Protocol is registered AETRF, that is
- // Aileron is channel 1, Elevator - 2, Throttle - 3, Rudder - 4, Flip control - 5
- *aileron = convert_channel(AILERON); //rool
- *elevator = convert_channel(ELEVATOR);//pitch
- *throttle = convert_channel(THROTTLE);
- *throttle = *throttle & 0x80 ? 0xff - *throttle : 0x80 + *throttle;
- *rudder = convert_channel(RUDDER);//yaw
- // Channel 5
- if (Servo_data[AUX1] <= 1500)
- *flags &= ~SYMAX_FLAG_FLIP;
- else
- *flags |= SYMAX_FLAG_FLIP;
- // Channel 6
- //if (Servo_data[AUX2] <= 1500)
- // *flags &= ~SYMAX_FLAG_RATES;
- // else
- // *flags |= SYMAX_FLAG_RATES;
- // Channel 6
- if (Servo_data[AUX2] <= 128)
- // *flags &= ~SYMAX_FLAG_PICTURE;
- *flags &= ~SYMAX_FLAG_PICTURE;
- else
- *flags |= SYMAX_FLAG_PICTURE;
- // Channel 7
- if (Servo_data[AUX3] <= 128)
- *flags &= ~SYMAX_FLAG_VIDEO;
- else
- *flags |= SYMAX_FLAG_VIDEO;
- // dbgprintf("ail %5d, ele %5d, thr %5d, rud %5d, flags 0x%x\n",
- // *aileron, *elevator, *throttle, *rudder, *flags);
- }
- #define X5C_CHAN2TRIM(X) ((((X) & 0x80 ? 0xff - (X) : 0x80 + (X)) >> 2) + 0x20)
- static void build_packet_x5c(uint8_t bind)
- {
- if (bind) {
- memset(packet, 0, packet_size);
- packet[7] = 0xae;
- packet[8] = 0xa9;
- packet[14] = 0xc0;
- packet[15] = 0x17;
- } else {
- SYMAX_read_controls(&throttle, &rudder, &elevator, &aileron, &flags);
- packet[0] = throttle;
- packet[1] = rudder;
- packet[2] = elevator ^ 0x80; // reversed from default
- packet[3] = aileron;
- packet[4] = X5C_CHAN2TRIM(rudder ^ 0x80);// drive trims for extra control range
- packet[5] = X5C_CHAN2TRIM(elevator);
- packet[6] = X5C_CHAN2TRIM(aileron ^ 0x80);
- packet[7] = 0xae;
- packet[8] = 0xa9;
- packet[9] = 0x00;
- packet[10] = 0x00;
- packet[11] = 0x00;
- packet[12] = 0x00;
- packet[13] = 0x00;
- packet[14] = (flags & SYMAX_FLAG_VIDEO ? 0x10 : 0x00)
- | (flags & SYMAX_FLAG_PICTURE ? 0x08 : 0x00)
- | (flags & SYMAX_FLAG_FLIP ? 0x01 : 0x00)
- | 0x04;// (flags & SYMAX_FLAG_RATES ? 0x04 : 0x00);
- packet[15] = checksum(packet);
- }
- }
- static void build_packet(uint8_t bind) {
- if (bind) {
- packet[0] = rx_tx_addr[4];
- packet[1] = rx_tx_addr[3];
- packet[2] = rx_tx_addr[2];
- packet[3] = rx_tx_addr[1];
- packet[4] = rx_tx_addr[0];
- packet[5] = 0xaa;
- packet[6] = 0xaa;
- packet[7] = 0xaa;
- packet[8] = 0x00;
- // packet[9] = 0xda;
- packet[9] = checksum(packet);
- } else {
- SYMAX_read_controls(&throttle, &rudder, &elevator, &aileron, &flags);
- if (flags & SYMAX_FLAG_PICTURE)
- digitalWrite(12, HIGH);
- else
- digitalWrite(12, LOW);
- //Serial.println(throttle);
- packet[0] = throttle;
- packet[1] = elevator;
- packet[2] = rudder;
- packet[3] = aileron;
- packet[4] = (flags & SYMAX_FLAG_VIDEO ? 0x80 : 0x00) | (flags & SYMAX_FLAG_PICTURE ? 0x40 : 0x00);
- packet[5] = (elevator >> 2) | 0xc0; //always high rates (bit 7 is rate control) (flags & SYMAX_FLAG_RATES ? 0x80 : 0x00) | 0x40; // use trims to extend controls
- packet[6] = (rudder >> 2) | (flags & SYMAX_FLAG_FLIP ? 0x40 : 0x00);
- packet[7] = aileron >> 2;
- packet[8] = 0x00;
- packet[9] = checksum(packet);
- }
- }
- static void SYMAX_send_packet(uint8_t bind)
- {
- if (mode_select == MODE_SYMAX5C)
- build_packet_x5c(bind);
- else
- build_packet(bind);
- // clear packet status bits and TX FIFO
- NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
- NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x2e);
- NRF24L01_WriteReg(NRF24L01_05_RF_CH, chans[current_chan]);
- NRF24L01_FlushTx();
- NRF24L01_WritePayload(packet, packet_size);
- if (packet_counter++ % 2) { // use each channel twice
- current_chan = (current_chan + 1) % num_rf_channels;
- }
- // Check and adjust transmission power. We do this after
- // transmission to not bother with timeout after power
- // settings change - we have plenty of time until next
- // packet.
- NRF24L01_SetPower(7);
- }
- static void symax_init()
- {
- byte SYMAX_bind_rx_tx_addr[] = {0xab, 0xac, 0xad, 0xae, 0xaf};
- byte bind_rx_tx_addr_x5c[] = {0x6d, 0x6a, 0x73, 0x73, 0x73};
- NRF24L01_Initialize();
- NRF24L01_ReadReg(NRF24L01_07_STATUS);
- NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO));
- NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
- NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes (even though not used?)
- NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
- NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xff); // 4mS retransmit t/o, 15 tries (retries w/o AA?)
- NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x08);
- if (mode_select == MODE_SYMAX5C) {
- NRF24L01_SetBitrate(NRF24L01_BR_1M);
- packet_size = 16;
- } else {
- NRF24L01_SetBitrate(NRF24L01_BR_250K);
- packet_size = 10;
- }
- NRF24L01_SetPower(4);
- NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
- NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00);
- NRF24L01_WriteReg(NRF24L01_09_CD, 0x00);
- NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address
- NRF24L01_WriteReg(NRF24L01_0D_RX_ADDR_P3, 0xC4);
- NRF24L01_WriteReg(NRF24L01_0E_RX_ADDR_P4, 0xC5);
- NRF24L01_WriteReg(NRF24L01_0F_RX_ADDR_P5, 0xC6);
- NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, SYMAX_PAYLOADSIZE); // bytes of data payload for pipe 1
- NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, SYMAX_PAYLOADSIZE);
- NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, SYMAX_PAYLOADSIZE);
- NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, SYMAX_PAYLOADSIZE);
- NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, SYMAX_PAYLOADSIZE);
- NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, SYMAX_PAYLOADSIZE);
- NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here
- NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, mode_select == MODE_SYMAX5C ? bind_rx_tx_addr_x5c : SYMAX_bind_rx_tx_addr, 5);
- NRF24L01_ReadReg(NRF24L01_07_STATUS);
- // Check for Beken BK2421/BK2423 chip
- // It is done by using Beken specific activate code, 0x53
- // and checking that status register changed appropriately
- // There is no harm to run it on nRF24L01 because following
- // closing activate command changes state back even if it
- // does something on nRF24L01
- NRF24L01_Activate(0x53); // magic for BK2421 bank switch
- //dbgprintf("Trying to switch banks\n");
- if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & 0x80) {
- //dbgprintf("BK2421 detected\n");
- // Beken registers don't have such nice names, so we just mention
- // them by their numbers
- // It's all magic, eavesdropped from real transfer and not even from the
- // data sheet - it has slightly different values
- NRF24L01_WriteRegisterMulti(0x00, (uint8_t *) "\x40\x4B\x01\xE2", 4);
- NRF24L01_WriteRegisterMulti(0x01, (uint8_t *) "\xC0\x4B\x00\x00", 4);
- NRF24L01_WriteRegisterMulti(0x02, (uint8_t *) "\xD0\xFC\x8C\x02", 4);
- NRF24L01_WriteRegisterMulti(0x03, (uint8_t *) "\x99\x00\x39\x21", 4);
- NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xF9\x96\x82\x1B", 4);
- NRF24L01_WriteRegisterMulti(0x05, (uint8_t *) "\x24\x06\x7F\xA6", 4);
- NRF24L01_WriteRegisterMulti(0x06, (uint8_t *) "\x00\x00\x00\x00", 4);
- NRF24L01_WriteRegisterMulti(0x07, (uint8_t *) "\x00\x00\x00\x00", 4);
- NRF24L01_WriteRegisterMulti(0x08, (uint8_t *) "\x00\x00\x00\x00", 4);
- NRF24L01_WriteRegisterMulti(0x09, (uint8_t *) "\x00\x00\x00\x00", 4);
- NRF24L01_WriteRegisterMulti(0x0A, (uint8_t *) "\x00\x00\x00\x00", 4);
- NRF24L01_WriteRegisterMulti(0x0B, (uint8_t *) "\x00\x00\x00\x00", 4);
- NRF24L01_WriteRegisterMulti(0x0C, (uint8_t *) "\x00\x12\x73\x00", 4);
- NRF24L01_WriteRegisterMulti(0x0D, (uint8_t *) "\x46\xB4\x80\x00", 4);
- NRF24L01_WriteRegisterMulti(0x0E, (uint8_t *) "\x41\x10\x04\x82\x20\x08\x08\xF2\x7D\xEF\xFF", 11);
- NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xFF\x96\x82\x1B", 4);
- NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xF9\x96\x82\x1B", 4);
- } else {
- //dbgprintf("nRF24L01 detected\n");
- }
- NRF24L01_Activate(0x53); // switch bank back
- NRF24L01_FlushTx();
- NRF24L01_ReadReg(NRF24L01_07_STATUS);
- NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x0e);
- // NRF24L01_WriteReg(NRF24L01_07_STATUS,0x0e| (1 << NRF24L01_07_RX_DR) | (1 << NRF24L01_07_TX_DS) );// //reset the flag(s)| (1 << NRF24L01_07_MAX_RT)
- NRF24L01_ReadReg(NRF24L01_00_CONFIG);
- NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0c);
- NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0e); // power on
- }
- static void symax_init1()
- {
- // write a strange first packet to RF channel 8 ...
- uint8_t first_packet[] = {0xf9, 0x96, 0x82, 0x1b, 0x20, 0x08, 0x08, 0xf2, 0x7d, 0xef, 0xff, 0x00, 0x00, 0x00, 0x00};
- uint8_t chans_bind[] = {0x4b, 0x30, 0x40, 0x2e};
- uint8_t chans_bind_x5c[] = {0x27, 0x1b, 0x39, 0x28, 0x24, 0x22, 0x2e, 0x36,
- 0x19, 0x21, 0x29, 0x14, 0x1e, 0x12, 0x2d, 0x18
- };
- //Serial.println("symax_init1");
- NRF24L01_FlushTx();
- NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x08);
- NRF24L01_WritePayload(first_packet, 15);
- if (mode_select == MODE_SYMAX5C) {
- num_rf_channels = sizeof(chans_bind_x5c);
- memcpy(chans, chans_bind_x5c, num_rf_channels);
- } else {
- //initialize_rx_tx_addr(); // make info available for bind packets
- memcpy(rx_tx_addr, data_rx_tx_addr, 5); // make info available for bind packets
- num_rf_channels = sizeof(chans_bind);
- memcpy(chans, chans_bind, num_rf_channels);
- }
- current_chan = 0;
- packet_counter = 0;
- }
- static void initialize_rx_tx_addr()
- {
- //u32 lfsr = 0xb2c54a2ful;
- /*
- if (Model_fixed_id) {
- for (u8 i = 0, j = 0; i < sizeof(Model_fixed_id); ++i, j += 8)
- rand32_r(&lfsr, (Model.fixed_id >> j) & 0xff);
- }
- */
- /*
- // Pump zero bytes for LFSR to diverge more
- for (u8 i = 0; i < sizeof(lfsr); ++i) rand32_r(&lfsr, 0);
- rx_tx_addr[4] = 0xa2;
- for (u8 i = 0; i < sizeof(rx_tx_addr)-1; ++i) {
- rx_tx_addr[i] = lfsr & 0xff;
- rand32_r(&lfsr, i);
- }
- */
- }
- /*
- TX address Channel Sequence
- S1 3B B6 00 00 A2 15 35 1D 3D
- D1 9A E9 02 00 A2 14 34 1C 3C
- D2 46 18 00 00 A2 11 21 31 41
- */
- // channels determined by last byte of tx address
- static void set_channels(uint8_t address) {
- static const uint8_t start_chans_1[] = {0x0a, 0x1a, 0x2a, 0x3a};
- static const uint8_t start_chans_2[] = {0x2a, 0x0a, 0x42, 0x22};
- static const uint8_t start_chans_3[] = {0x1a, 0x3a, 0x12, 0x32};
- static const uint8_t start_chans_4[] = {0x15, 0x35, 0x1d, 0x3d};
- static const uint8_t start_chans_5[] = {0x14, 0x34, 0x1c, 0x3c};
- static const uint8_t start_chans_6[] = {0x11, 0x21, 0x31, 0x41};
- uint8_t laddress = address & 0x1f;
- Serial.print("laddress:"); Serial.println(laddress);
- uint8_t i;
- uint32_t *pchans = (uint32_t *)chans; // avoid compiler warning
- num_rf_channels = 4;
- if (laddress < 0x10) {
- if (laddress == 6) laddress = 7;
- for (i = 0; i < num_rf_channels; i++) {
- //Serial.println("start_chans_1");
- chans[i] = start_chans_1[i] + laddress;
- // chans[i] = start_chans_6[i] + laddress;
- }
- } else if (laddress < 0x18) {
- for (i = 0; i < num_rf_channels; i++) {
- //Serial.println("start_chans_2");
- chans[i] = start_chans_2[i] + (laddress & 0x07);
- }
- if (laddress == 0x16) {
- chans[0] += 1;
- chans[1] += 1;
- }
- } else if (laddress < 0x1e) {
- //Serial.println("start_chans_3");
- for (i = 0; i < num_rf_channels; i++) {
- chans[i] = start_chans_3[i] + (laddress & 0x07);
- //chans[i] = start_chans_5[i] ;
- //Serial.println(chans[i]);
- }
- } else if (laddress == 0x1e) {
- *pchans = 0x38184121;
- } else {
- *pchans = 0x39194121;
- }
- }
- static void symax_init2()
- {
- // uint8_t chans_data[] = {0x1d, 0x3d, 0x15, 0x35};
- uint8_t chans_data_x5c[] = {0x1d, 0x2f, 0x26, 0x3d, 0x15, 0x2b, 0x25, 0x24,
- 0x27, 0x2c, 0x1c, 0x3e, 0x39, 0x2d, 0x22
- };
- //Serial.println("symax_init2");
- if (mode_select == MODE_SYMAX5C) {
- num_rf_channels = sizeof(chans_data_x5c);
- memcpy(chans, chans_data_x5c, num_rf_channels);
- } else {
- //num_rf_channels = sizeof(chans_data);
- //memcpy(chans, chans_data, num_rf_channels);
- set_channels(rx_tx_addr[0]);
- NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
- }
- current_chan = 0;
- packet_counter = 0;
- }
- uint8_t convert_channel(uint8_t num) {
- if (Servo_data[num] < PPM_MIN) {
- Servo_data[num] = PPM_MIN;
- } else if (Servo_data[num] > PPM_MAX) {
- Servo_data[num] = PPM_MAX;
- }
- return (uint8_t) (map(Servo_data[num], PPM_MIN, PPM_MAX, 0, 255));
- }
- void read_ppm() {
- //Serial.println("read_ppm");
- static unsigned int pulse;
- static unsigned long counterPPM;
- static byte chan;
- counterPPM = TCNT1;
- //TCNT1 = 0;
- if (counterPPM < 510 * scale) {
- pulse = counterPPM;
- }
- else if (counterPPM > 1910 * scale) {
- chan = 0;
- }
- else {
- Servo_data[chan] = (counterPPM + pulse) / scale;
- Servo_data[chan] = constrain(Servo_data[chan], PPM_MIN, PPM_MAX);
- chan++;
- }
- }
- /*
- serial_sync = Serial.read();
- if (serial_sync == SYNC_BYTE)
- {
- for (int i = 0; i < NUM_ACTIVE_CHANNELS; i++)
- {
- while (!Serial.available())
- ;
- input_byte = Serial.read();
- input_value = CALC_CHANNEL_VALUE(input_byte);
- frame_sync += (channel_ppm[i] - input_value);
- channel_ppm[i] = input_value;
- }
- }
- */
- void read_serial()
- {
- // Serial.println("read");
- int result = 0;
- while (Serial.available() >= 8)
- {
- digitalWrite(12, HIGH);
- result == 4;
- int input_value;
- // Serial.print("received: ");
- byte number = Serial.read();
- if (number == 255 ) {
- result == 3;
- for (int i = 0; i < 7; i++) {
- // while (!Serial.available())
- // {delayMicroseconds(10);}
- number = Serial.read();
- Servo_data[i] = number;
- // Serial.print(Servo_data[i]);
- // Serial.print('\n');
- }
- // Serial.print("===\n");
- }
- }
- digitalWrite(12, LOW);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement