diff --git a/Multiprotocol/Bayang_nrf24l01.ino b/Multiprotocol/Bayang_nrf24l01.ino index 7d010d4..cc1af3d 100644 --- a/Multiprotocol/Bayang_nrf24l01.ino +++ b/Multiprotocol/Bayang_nrf24l01.ino @@ -16,9 +16,14 @@ Multiprotocol is distributed in the hope that it will be useful, // Last sync with hexfet new_protocols/bayang_nrf24l01.c dated 2015-12-22 #if defined(BAYANG_NRF24L01_INO) - #include "iface_nrf24l01.h" +#ifdef ENABLE_BAYANG_TELEMETRY + #define BAYANG_PACKET_PERIOD_TELEM 3200 + uint32_t bayang_telemetry_last_rx = 0; +#endif + + #define BAYANG_BIND_COUNT 1000 #define BAYANG_PACKET_PERIOD 2000 #define BAYANG_INITIAL_WAIT 500 @@ -28,14 +33,27 @@ Multiprotocol is distributed in the hope that it will be useful, #define BAYANG_ADDRESS_LENGTH 5 enum BAYANG_FLAGS { - // flags going to packet[2] - BAYANG_FLAG_RTH = 0x01, - BAYANG_FLAG_HEADLESS = 0x02, - BAYANG_FLAG_FLIP = 0x08, - BAYANG_FLAG_VIDEO = 0x10, - BAYANG_FLAG_PICTURE = 0x20, - // flags going to packet[3] - BAYANG_FLAG_INVERTED = 0x80 // inverted flight on Floureon H101 + // flags going to packet[2] + BAYANG_FLAG_RTH = 0x01, + BAYANG_FLAG_HEADLESS = 0x02, +#ifdef ENABLE_BAYANG_TELEMETRY + BAYANG_FLAG_TELEMETRY = 0x04, +#endif + BAYANG_FLAG_FLIP = 0x08, + BAYANG_FLAG_VIDEO = 0x10, + BAYANG_FLAG_PICTURE = 0x20, + // flags going to packet[3] + BAYANG_FLAG_INVERTED = 0x80, // inverted flight on Floureon H101 +#ifdef ENABLE_BAYANG_TELEMETRY + BAYANG_FLAG_FLIGHT_MODE0 = 0x01, + BAYANG_FLAG_FLIGHT_MODE1 = 0x02, + BAYANG_FLAG_DATA_SELECT0 = 0x04, + BAYANG_FLAG_DATA_SELECT1 = 0x08, + BAYANG_FLAG_DATA_SELECT2 = 0x10, + BAYANG_FLAG_DATA_ADJUST0 = 0x20, + BAYANG_FLAG_DATA_ADJUST1 = 0x40, +#endif + }; static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) @@ -53,6 +71,12 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) } else { + + int telem_enabled = 0; +#ifdef ENABLE_BAYANG_TELEMETRY + telem_enabled = (sub_protocol == BAYANG_TELEM); + // telem_enabled &= Servo_AUX8; // enable telem with a switch +#endif uint16_t val; packet[0] = 0xA5; packet[1] = 0xFA; // normal mode is 0xf7, expert 0xfa @@ -69,11 +93,111 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) packet[2] |= BAYANG_FLAG_VIDEO; if(Servo_AUX5) packet[2] |= BAYANG_FLAG_HEADLESS; + +#ifdef ENABLE_BAYANG_TELEMETRY + if (telem_enabled) + { + packet[2] |= BAYANG_FLAG_TELEMETRY; + } +#endif + + //Flags packet[3] packet[3] = 0x00; if(Servo_AUX6) packet[3] = BAYANG_FLAG_INVERTED; +#ifdef ENABLE_BAYANG_TELEMETRY + if (telem_enabled) + { + static uint8_t dataselect = 2; + uint8_t dataselect_old = dataselect; + uint16_t partitions[4] ={1200,1400,1600,1800}; // 5 options (previous data set, data 1, data 2, data 3, next data set) + for (uint8_t i = 0; i < 4; ++i) + { + int16_t hysteresis = 0; + if (dataselect_old*2 == (i*2+1) - 1) + { + hysteresis = 25; + } + else if (dataselect_old*2 == (i*2+1) + 1) + { + hysteresis = -25; + } + + if (Servo_data[AUX7] <= partitions[i] + hysteresis) + { + dataselect = i; + break; + } + else + { + dataselect = i+1; + } + } + + // data adjust 1333 1666 - aux 6 + static uint8_t dataadjust = 1; + uint8_t dataadjust_old = dataadjust; + partitions[0] = 1333; // three options (decreaes, do nothing, increase) + partitions[1] = 1666; + for (uint8_t i = 0; i < 2; ++i) + { + int16_t hysteresis = 0; + if (dataadjust_old*2 == (i*2+1) - 1) + { + hysteresis = 25; + } + else if (dataadjust_old*2 == (i*2+1) + 1) + { + hysteresis = -25; + } + + if (Servo_data[AUX8] <= partitions[i] + hysteresis) + { + dataadjust = i; + break; + } + else + { + dataadjust = i+1; + } + } + + static uint8_t flightmode = 0; + // flight mode 1250 1500 1750 - aux 1 + uint8_t flightmode_old = flightmode; + partitions[0] = 1250; // 4 flight modes + partitions[1] = 1500; + partitions[2] = 1750; + for (uint8_t i = 0; i < 3; ++i) + { + int16_t hysteresis = 0; + if (flightmode_old*2 == (i*2+1) - 1) + { + hysteresis = 25; + } + else if (flightmode_old*2 == (i*2+1) + 1) + { + hysteresis = -25; + } + + if (Servo_data[AUX9] <= partitions[i] + hysteresis) + { + flightmode = i; + break; + } + else + { + flightmode = i+1; + } + } + packet[3] |= (flightmode & 0x3); + packet[3] |= (dataselect & 0x7) << 2; + packet[3] |= (dataadjust & 0x3) << 5; + } +#endif + //Aileron val = convert_channel_10b(AILERON); packet[4] = (val>>8) + ((val>>2) & 0xFC); @@ -94,7 +218,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) packet[12] = rx_tx_addr[2]; // txid[2] packet[13] = 0x0A; packet[14] = 0; - for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++) + for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++) packet[14] += packet[i]; // Power on, TX mode, 2byte CRC @@ -121,22 +245,45 @@ static void __attribute__((unused)) BAYANG_init() NRF24L01_FlushTx(); NRF24L01_FlushRx(); - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes - NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only - NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps - NRF24L01_SetPower(); + + NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_PACKET_SIZE); // rx pipe 0 + NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only + NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); + NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits + NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps + NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes + NRF24L01_SetPower(); + } uint16_t BAYANG_callback() { if(IS_BIND_DONE_on) - BAYANG_send_packet(0); + { +#ifdef ENABLE_BAYANG_TELEMETRY + if(sub_protocol == BAYANG_TELEM) + { + Bayang_process(); + // Return 0 here so that Bayang_process is called as often as possible + // to check for the incomming telemetry data. When telemetry is enabled + // the packet period is handled in the Bayang_process function. + return 0; + } + else +#endif + { + BAYANG_send_packet(0); + } + } else { if (bind_counter == 0) { XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH); + XN297_SetRXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH); + BIND_DONE; } else @@ -161,10 +308,153 @@ static void __attribute__((unused)) BAYANG_initialize_txid() uint16_t initBAYANG(void) { BIND_IN_PROGRESS; // autobind protocol - bind_counter = BAYANG_BIND_COUNT; + bind_counter = BAYANG_BIND_COUNT; BAYANG_initialize_txid(); BAYANG_init(); return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD; } -#endif \ No newline at end of file + +#ifdef ENABLE_BAYANG_TELEMETRY + extern float telemetry_voltage; + extern uint8_t telemetry_rx_rssi; + extern uint8_t telemetry_tx_rssi; + extern uint8_t telemetry_datamode; + extern float telemetry_data[3]; // pids + extern uint8_t telemetry_dataitem; + extern uint16_t telemetry_uptime; + extern uint16_t telemetry_flighttime; + extern uint8_t telemetry_flightmode; + + uint8_t telemetry_tx_rssi_count; + uint8_t telemetry_tx_rssi_next; + + + uint8_t BAYANG_recv_packet() { + uint8_t received = 0; + if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { + int sum = 0; + uint16_t roll, pitch, yaw, throttle; + + XN297_ReadPayload(packet, BAYANG_PACKET_SIZE); + + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushRx(); + + if (packet[0] == 0xA9) { + //serialDebug.print("data packet"); + for (int i = 0; i < 14; i++) { + sum += packet[i]; + } + if ( (sum & 0xFF) == packet[14] ) { + typedef union { + uint16_t v; + uint8_t bytes[2]; + } val; + val v; + + v.bytes[0] = packet[1]; + v.bytes[1] = packet[2]; + telemetry_voltage = v.v / 100.f; + + telemetry_rx_rssi = packet[3]; + + + v.bytes[0] = packet[4]; + v.bytes[1] = (packet[6] & 0x0F); // 12 bit # shared with flighttime + telemetry_uptime = v.v; + + v.bytes[0] = packet[5]; + v.bytes[1] = (packet[6] >> 4); + telemetry_flighttime = v.v; + + telemetry_flightmode = packet[7] & 0x3; // 0 = level, 1 = acro, + telemetry_datamode = (packet[7] >> 2) & 0xF; // (0=acro yaw, 1=acro roll/acro pitch, 2=level roll/pitch) + telemetry_dataitem = (packet[7] >> 6) & 0x3; // (0=acro yaw, 1=acro roll/acro pitch, 2=level roll/pitch) + + v.bytes[0] = packet[8]; + v.bytes[1] = packet[9]; + telemetry_data[0] = v.v/1000.f; + + v.bytes[0] = packet[10]; + v.bytes[1] = packet[11]; + telemetry_data[1] = v.v/1000.f; + + v.bytes[0] = packet[12]; + v.bytes[1] = packet[13]; + telemetry_data[2] = v.v/1000.f; + } + } + received = 1; + } + return received; + } + + + typedef enum + { + BAYANG_STATE_IDLE, + BAYANG_STATE_TRANSMITTING, + BAYANG_STATE_RECEIEVING, + } BayangState; + + BayangState Bayang_state = BAYANG_STATE_IDLE; + uint32_t Bayang_next_send = 0; + + void Bayang_process() { + uint32_t time_micros = micros(); + + if (BAYANG_STATE_TRANSMITTING == Bayang_state) { + if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) { + // send finished, switch to rx to receive telemetry + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); + NRF24L01_FlushRx(); + + telemetry_tx_rssi_count++; + + Bayang_state = BAYANG_STATE_RECEIEVING; + } + } + else if (BAYANG_STATE_RECEIEVING == Bayang_state) { + // 250us is about the time it takes to read a packet over spi + if (time_micros > (Bayang_next_send-250)) { + // didnt receive telemetry in time + Bayang_state = BAYANG_STATE_IDLE; + + // if it's been a while since receiving telemetry data, + // stop sending the telemetry data to the transmitter + if (millis() - bayang_telemetry_last_rx > 1000) + telemetry_lost = 1; + } + else if (BAYANG_recv_packet()) { + telemetry_tx_rssi_next++; + // received telemetry packet + telemetry_lost = 0; + bayang_telemetry_last_rx = millis(); + } + else + { + return; + } + + if (100 == telemetry_tx_rssi_count) + { + telemetry_tx_rssi = telemetry_tx_rssi_next; + telemetry_tx_rssi_next = 0; + telemetry_tx_rssi_count = 0; + } + + Bayang_state = BAYANG_STATE_IDLE; + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + NRF24L01_FlushRx(); + } + else if (time_micros > Bayang_next_send) { + BAYANG_send_packet(0); + Bayang_state = BAYANG_STATE_TRANSMITTING; + Bayang_next_send = time_micros + BAYANG_PACKET_PERIOD_TELEM; + } + } +#endif //ENABLE_BAYANG_TELEMETRY +#endif diff --git a/Multiprotocol/CX10_nrf24l01.ino b/Multiprotocol/CX10_nrf24l01.ino index f836e02..2c649b4 100644 --- a/Multiprotocol/CX10_nrf24l01.ino +++ b/Multiprotocol/CX10_nrf24l01.ino @@ -22,7 +22,7 @@ #define CX10_BIND_COUNT 4360 // 6 seconds #define CX10_PACKET_SIZE 15 #define CX10A_PACKET_SIZE 19 // CX10 blue board packets have 19-byte payload -#define Q282_PACKET_SIZE 21 +#define Q2X2_PACKET_SIZE 21 #define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec #define CX10A_PACKET_PERIOD 6000 @@ -57,21 +57,14 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) packet[3] = rx_tx_addr[2]; packet[4] = rx_tx_addr[3]; // packet[5] to [8] (aircraft id) is filled during bind for blue board - packet[5+offset] = lowByte(Servo_data[AILERON]); - packet[6+offset]= highByte(Servo_data[AILERON]); - packet[7+offset]= lowByte(Servo_data[ELEVATOR]); - packet[8+offset]= highByte(Servo_data[ELEVATOR]); + uint16_t aileron=Servo_data[AILERON]; + uint16_t elevator=3000-Servo_data[ELEVATOR]; + uint16_t rudder=3000-Servo_data[RUDDER]; packet[9+offset]= lowByte(Servo_data[THROTTLE]); packet[10+offset]= highByte(Servo_data[THROTTLE]); - packet[11+offset]= lowByte(Servo_data[RUDDER]); - packet[12+offset]= highByte(Servo_data[RUDDER]); - - // Channel 5 - flip flag - if(Servo_AUX1) - packet[12+offset] |= CX10_FLAG_FLIP; // flip flag - //flags=0; // packet 13 - uint8_t flags2=0; // packet 14 + // Channel 5 - flip flag + packet[12+offset] = GET_FLAG(Servo_AUX1,CX10_FLAG_FLIP); // flip flag applied on rudder // Channel 6 - rate mode is 2 lsb of packet 13 if(Servo_data[AUX2] > PPM_MAX_COMMAND) // rate 3 / headless on CX-10A @@ -81,6 +74,7 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) flags = 0x00; // rate 1 else flags = 0x01; // rate 2 + uint8_t flags2=0; // packet 14 uint8_t video_state=packet[14] & 0x21; switch(sub_protocol) @@ -91,6 +85,9 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) break; case Q282: case Q242: + case Q222: + aileron = 3000 - aileron; + rudder = 3000 - rudder; memcpy(&packet[15], "\x10\x10\xaa\xaa\x00\x00", 6); //FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL flags2 = GET_FLAG(Servo_AUX1, 0x80) // Channel 5 - FLIP @@ -111,7 +108,7 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) flags2 |= video_state |GET_FLAG(Servo_AUX3,0x10); // Channel 7 - picture } - else + else if(sub_protocol==Q242) { flags=2; flags2|= GET_FLAG(Servo_AUX3,0x01) // Channel 7 - picture @@ -119,15 +116,22 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) packet[17]=0x00; packet[18]=0x00; } + else + { // Q222 + flags=0; + } if(Servo_AUX6) flags |=0x80; // Channel 10 - RTH break; case DM007: + aileron = 3000 - aileron; //FLIP|MODE|PICTURE|VIDEO|HEADLESS flags2= GET_FLAG(Servo_AUX3,CX10_FLAG_SNAPSHOT) // Channel 7 - picture |GET_FLAG(Servo_AUX4,CX10_FLAG_VIDEO); // Channel 8 - video if(Servo_AUX5) flags |= CX10_FLAG_HEADLESS; // Channel 9 - headless break; case JC3015_2: + aileron = 3000 - aileron; + elevator = 3000 - elevator; //FLIP|MODE|LED|DFLIP if(Servo_AUX4) packet[12] &= ~CX10_FLAG_FLIP; case JC3015_1: @@ -136,6 +140,7 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) |GET_FLAG(Servo_AUX4,_BV(4)); // Channel 8 break; case MK33041: + elevator = 3000 - elevator; //FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH flags|=GET_FLAG(Servo_AUX3,_BV(7)) // Channel 7 - picture |GET_FLAG(Servo_AUX6,_BV(2)); // Channel 10 - rth @@ -143,9 +148,15 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind) |GET_FLAG(Servo_AUX5,_BV(5)); // Channel 9 - headless break; } + packet[5+offset] = lowByte(aileron); + packet[6+offset]= highByte(aileron); + packet[7+offset]= lowByte(elevator); + packet[8+offset]= highByte(elevator); + packet[11+offset]= lowByte(rudder); + packet[12+offset]|= highByte(rudder); packet[13+offset]=flags; packet[14+offset]=flags2; - + // Power on, TX mode, 2byte CRC // Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); @@ -233,28 +244,23 @@ uint16_t CX10_callback() static void __attribute__((unused)) CX10_initialize_txid() { rx_tx_addr[1]%= 0x30; - if(sub_protocol==Q282) + if(sub_protocol&0x08) //Q2X2 protocols { - hopping_frequency[0] = 0x46; - hopping_frequency[1] = 0x48; - hopping_frequency[2] = 0x4a; - hopping_frequency[3] = 0x4c; + uint8_t offset=0; //Q282 + if(sub_protocol==Q242) + offset=2; + if(sub_protocol==Q222) + offset=3; + for(uint8_t i=0;i<4;i++) + hopping_frequency[i]=0x46+2*i+offset; } else - if(sub_protocol==Q242) - { - hopping_frequency[0] = 0x48; - hopping_frequency[1] = 0x4a; - hopping_frequency[2] = 0x4c; - hopping_frequency[3] = 0x4e; - } - else - { - hopping_frequency[0] = 0x03 + (rx_tx_addr[0] & 0x0F); - hopping_frequency[1] = 0x16 + (rx_tx_addr[0] >> 4); - hopping_frequency[2] = 0x2D + (rx_tx_addr[1] & 0x0F); - hopping_frequency[3] = 0x40 + (rx_tx_addr[1] >> 4); - } + { + hopping_frequency[0] = 0x03 + (rx_tx_addr[0] & 0x0F); + hopping_frequency[1] = 0x16 + (rx_tx_addr[0] >> 4); + hopping_frequency[2] = 0x2D + (rx_tx_addr[1] & 0x0F); + hopping_frequency[3] = 0x40 + (rx_tx_addr[1] >> 4); + } } uint16_t initCX10(void) @@ -272,8 +278,8 @@ uint16_t initCX10(void) } else { - if(sub_protocol==Q282||sub_protocol==Q242) - packet_length = Q282_PACKET_SIZE; + if(sub_protocol&0x08) //Q2X2 protocols + packet_length = Q2X2_PACKET_SIZE; else packet_length = CX10_PACKET_SIZE; packet_period = CX10_PACKET_PERIOD; diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 94ca4f4..cbaebb2 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -54,7 +54,7 @@ //Global constants/variables uint32_t MProtocol_id;//tx id, uint32_t MProtocol_id_master; -uint32_t blink=0; +uint32_t blink=0,last_signal=0; // uint16_t counter; uint8_t channel; @@ -482,7 +482,11 @@ void Update_All() } #endif //ENABLE_PPM #if defined(TELEMETRY) - if((protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) ) + if((protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) + #ifdef ENABLE_BAYANG_TELEMETRY + || (protocol==MODE_BAYANG) + #endif + ) TelemetryUpdate(); #endif update_led_status(); @@ -848,6 +852,8 @@ static void protocol_init() break; #endif #if defined(CX10_NRF24L01_INO) + case MODE_Q2X2: + sub_protocol|=0x08; // Increase the number of sub_protocols for CX-10 case MODE_CX10: next_callback=initCX10(); remote_callback = CX10_callback; @@ -1069,7 +1075,11 @@ void Mprotocol_serial_init() { if( (protocol==MODE_FRSKYD) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) ) initTXSerial( SPEED_9600 ) ; - if(protocol==MODE_FRSKYX) + if(protocol==MODE_FRSKYX + #ifdef ENABLE_BAYANG_TELEMETRY + || protocol==MODE_BAYANG + #endif + ) initTXSerial( SPEED_57600 ) ; if(protocol==MODE_DSM) initTXSerial( SPEED_125K ) ; diff --git a/Multiprotocol/Nrf24l01_q303.ino b/Multiprotocol/Nrf24l01_q303.ino index 729373b..6d9c90d 100644 --- a/Multiprotocol/Nrf24l01_q303.ino +++ b/Multiprotocol/Nrf24l01_q303.ino @@ -2,7 +2,7 @@ #include "iface_nrf24l01.h" -#define Q303_BIND_COUNT 1200 +#define Q303_BIND_COUNT 2335 #define Q303_PACKET_SIZE 10 #define Q303_PACKET_PERIOD 1500 // Timeout for callback in uSec @@ -12,6 +12,15 @@ static uint8_t tx_addr[5]; static uint8_t current_chan; +/* +static const struct { + u8 txid[sizeof(txid)]; + u8 rfchan[NUM_RF_CHANNELS]; +} q303_tx_rf_map[] = { + {{0xb8, 0x69, 0x64, 0x67}, {0x48, 0x4a, 0x4c, 0x46}}, // tx2 + {{0xAE, 0x89, 0x97, 0x87}, {0x4A, 0x4C, 0x4E, 0x48}} +}; // tx1 +*/ uint8_t txid[4] = {0xAE, 0x89, 0x97, 0x87}; static uint8_t rf_chans[4] = {0x4A, 0x4C, 0x4E, 0x48}; @@ -44,10 +53,10 @@ static void send_packet(uint8_t bind) memset(&packet[5], 0, 5); } else { - aileron = map(Servo_data[AILERON], 1000, 2000, 0, 1000); + aileron = 1000 - map(Servo_data[AILERON], 1000, 2000, 0, 1000); elevator = 1000 - map(Servo_data[ELEVATOR], 1000, 2000, 0, 1000); throttle = map(Servo_data[THROTTLE], 1000, 2000, 0, 1000); - rudder = 1000 - map(Servo_data[RUDDER], 1000, 2000, 0, 1000); + rudder = map(Servo_data[RUDDER], 1000, 2000, 0, 1000); packet[0] = 0x55; packet[1] = aileron >> 2 ; // 8 bits @@ -125,20 +134,21 @@ static uint16_t q303_init() NRF24L01_Initialize(); NRF24L01_SetTxRxMode(TX_EN); + XN297_SetScrambledMode(XN297_UNSCRAMBLED); XN297_SetTXAddr((uint8_t *) "\xCC\xCC\xCC\xCC\xCC", 5); NRF24L01_FlushTx(); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes - NRF24L01_WriteReg(NRF24L01_05_RF_CH, Q303_RF_BIND_CHANNEL); - NRF24L01_SetBitrate(NRF24L01_BR_250K); + NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); + NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); + NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits NRF24L01_SetBitrate(NRF24L01_BR_250K); NRF24L01_SetPower(); - // this sequence necessary for module from stock tx - NRF24L01_ReadReg(NRF24L01_1D_FEATURE); NRF24L01_Activate(0x73); // Activate feature register - NRF24L01_ReadReg(NRF24L01_1D_FEATURE); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes - NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00); // Set feature bits on + NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits on + NRF24L01_Activate(0x73); + NRF24L01_Activate(0x53); // switch bank back BIND_IN_PROGRESS; diff --git a/Multiprotocol/SLT_nrf24l01.ino b/Multiprotocol/SLT_nrf24l01.ino index 9778d3c..89eb0dc 100644 --- a/Multiprotocol/SLT_nrf24l01.ino +++ b/Multiprotocol/SLT_nrf24l01.ino @@ -20,15 +20,20 @@ // For code readability #define SLT_PAYLOADSIZE 7 +#define SLT_VISTA_PAYLOADSIZE 11 #define SLT_NFREQCHANNELS 15 #define SLT_TXID_SIZE 4 enum { - SLT_BUILD=0, - SLT_DATA1, - SLT_DATA2, - SLT_DATA3, - SLT_BIND + // flags going to packet[6] + SLT_VISTA_FLAG_FLIP = 0x04, + SLT_VISTA_FLAG_MODE = 0x20 +}; + +enum { + SLT_BIND=0, + SLT_BUILD, + SLT_DATA, }; static void __attribute__((unused)) SLT_init() @@ -103,24 +108,37 @@ static void __attribute__((unused)) SLT_send_data(uint8_t *data, uint8_t len) static void __attribute__((unused)) SLT_build_packet() { - // Set radio channel - once per packet batch - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); - if (++hopping_frequency_no >= SLT_NFREQCHANNELS) - hopping_frequency_no = 0; - - // aileron, elevator, throttle, rudder, gear, pitch + // aileron, elevator, throttle, rudder, gear, pitch uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed for (uint8_t i = 0; i < 4; ++i) { uint16_t v = convert_channel_10b(CH_AETR[i]); + if(sub_protocol==VISTA && CH_AETR[i]==THROTTLE) + v = (uint16_t) map(limit_channel_100(THROTTLE),servo_min_100,servo_max_100,850,150); // Throttel is between 850=0% and 150=100% packet[i] = v; e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0); } // Extra bits for AETR packet[4] = e; - // 8-bit channels - packet[5] = convert_channel_8b(AUX1); - packet[6] = convert_channel_8b(AUX2); + if(sub_protocol==SLT) + { + // 8-bit channels + packet[5] = convert_channel_8b(AUX1); + packet[6] = convert_channel_8b(AUX2); + } + else + { // VISTA + packet[5] = 0xA6; + packet[6] = 0x00; + if(Servo_AUX1) + packet[6] = SLT_VISTA_FLAG_FLIP; + if(Servo_AUX2) + packet[6] |= SLT_VISTA_FLAG_MODE; + packet[7] = 0x00; + packet[8] = 0x7F; + packet[9] = 0xAA; + packet[10] = 0x00; + } } static void __attribute__((unused)) SLT_send_bind_packet() @@ -144,47 +162,83 @@ uint16_t SLT_callback() { switch (phase) { - case SLT_BUILD: - SLT_build_packet(); - phase++; - return 1000; - case SLT_DATA1: - SLT_send_data(packet, SLT_PAYLOADSIZE); - phase++; - return 1000; - case SLT_DATA2: - SLT_send_data(packet, SLT_PAYLOADSIZE); - phase++; - return 1000; - case SLT_DATA3: - SLT_send_data(packet, SLT_PAYLOADSIZE); - if (++packet_count >= 100) + case SLT_BIND: + bind_phase = 0; + SLT_send_bind_packet(); + if(sub_protocol == VISTA) { - packet_count = 0; - phase++; + phase=SLT_DATA; return 1000; } - else - { + phase++; // SLT_BUILD + return 18000; + case SLT_BUILD: + if(sub_protocol==SLT) + { // Set radio channel - once per packet batch + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); + if (++hopping_frequency_no >= SLT_NFREQCHANNELS) + hopping_frequency_no = 0; + } + SLT_build_packet(); + packet_count=0; + phase++; // SLT_DATA + return 1000; + case SLT_DATA: + if(sub_protocol==VISTA) + { // Change radio channel every 9 packets + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); + rf_ch_num++; + if(rf_ch_num>=9) + { + if (++hopping_frequency_no >= SLT_NFREQCHANNELS) + hopping_frequency_no = 0; + rf_ch_num=0; + } + } + SLT_send_data(packet, sub_protocol == VISTA?SLT_VISTA_PAYLOADSIZE:SLT_PAYLOADSIZE); + packet_count++; + if(packet_count >= (sub_protocol == VISTA?5:3)) + { // repeat the same data packet 3(SLT) or 5(VISTA) times + bind_phase++; NRF24L01_SetPower(); // Set tx_power - phase = SLT_BUILD; + phase = SLT_BUILD; // Refresh data + if(sub_protocol == VISTA) + return 1000; + else + if(bind_phase>=100) + { //SLT sends bind packet every 2.2s + phase=SLT_BIND; + return 1000; + } return 19000; } - case SLT_BIND: - SLT_send_bind_packet(); - phase = SLT_BUILD; - return 18000; + if(sub_protocol == VISTA) + { //VISTA sends bind packet every 1.5s + if(bind_phase>=150) + phase=SLT_BIND; + else + return 2000; + } + return 1000; } - return 19000; + return 1000; } uint16_t initSLT() { packet_count = 0; packet_sent = 0; + rf_ch_num=0; hopping_frequency_no = 0; - SLT_set_freq(); + if(sub_protocol == VISTA) + { + memcpy(rx_tx_addr,"\x00\x00\x23\x00",SLT_TXID_SIZE); + memcpy(hopping_frequency,"\x03\x0A\x11\x18\x1F\x26\x13\x0F\x0B\x10\x08\x16\x1D\x24\x06",15); + } + else + SLT_set_freq(); SLT_init(); + SLT_build_packet(); phase = SLT_BIND; return 50000; } diff --git a/Multiprotocol/Telemetry.ino b/Multiprotocol/Telemetry.ino index de2808e..295bb73 100644 --- a/Multiprotocol/Telemetry.ino +++ b/Multiprotocol/Telemetry.ino @@ -18,12 +18,21 @@ #if defined TELEMETRY #if defined SPORT_TELEMETRY + float telemetry_voltage = 0.f; + uint8_t telemetry_rx_rssi = 100; + #ifdef ENABLE_BAYANG_TELEMETRY + uint8_t telemetry_tx_rssi = 100; + uint8_t telemetry_datamode = 0; + uint8_t telemetry_dataitem = 0; + float telemetry_data[3] = {0}; + uint16_t telemetry_uptime = 0; + uint16_t telemetry_flighttime = 0; + uint8_t telemetry_flightmode = 0; + #endif #define SPORT_TIME 12000 #define FRSKY_SPORT_PACKET_SIZE 8 uint32_t last = 0; uint8_t sport_counter=0; - uint8_t RxBt = 0; - uint8_t rssi; uint8_t sport = 0; #endif #if defined HUB_TELEMETRY @@ -319,51 +328,183 @@ void sportIdle() void sportSendFrame() { uint8_t i; +#ifdef ENABLE_BAYANG_TELEMETRY + uint32_t temp; + uint16_t temp16; + uint8_t* bytes; +#endif + sport_counter = (sport_counter + 1) %36; if(telemetry_lost) { sportIdle(); return; } - if(sport_counter<6) + + uint8_t num_frames = 6; + #ifdef ENABLE_BAYANG_TELEMETRY + if (protocol == MODE_BAYANG) { num_frames = 14; } + #endif + if(sport_counterNRF24L01 MODE_OPENLRS = 27, // =>OpenLRS hardware MODE_AFHDS2A = 28, // =>A7105 + MODE_Q2X2 = 29, // =>NRF24L01, extension of CX-10 protocol }; enum Flysky { @@ -110,16 +111,25 @@ enum SYMAX SYMAX=0, SYMAX5C=1 }; +enum SLT +{ + SLT = 0, + VISTA = 1 +}; enum CX10 { CX10_GREEN = 0, CX10_BLUE=1, // also compatible with CX10-A, CX12 DM007=2, - Q282=3, JC3015_1=4, JC3015_2=5, MK33041=6, - Q242=7 +}; +enum Q2X2 +{ + Q222 = 8, + Q242 = 9, + Q282 = 10, }; enum CG023 { @@ -156,6 +166,11 @@ enum HONTAI FORMAT_FQ777 = 3 }; +enum BAYANG +{ + BAYANG = 0, + BAYANG_TELEM = 1 +}; enum HUBSAN { H107 = 0, @@ -448,6 +463,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- HONTAI 26 OpenLRS 27 AFHDS2A 28 + Q2X2 29 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -484,11 +500,17 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- CX10_GREEN 0 CX10_BLUE 1 // also compatible with CX10-A, CX12 DM007 2 - Q282 3 + --- 3 JC3015_1 4 JC3015_2 5 MK33041 6 - Q242 7 + sub_protocol==Q2X2 + Q222 0 + Q242 1 + Q282 2 + sub_protocol==SLT + SLT 0 + VISTA 1 sub_protocol==CG023 CG023 0 YD829 1 @@ -515,6 +537,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- FORMAT_JJRCX1 1 FORMAT_X5C1 2 FQ777-521 3 + sub_protocol==BAYANG + BAYANG 0 + BAYANG_TELEM 1 sub_protocol==AFHDS2A PWM_IBUS 0 PPM_IBUS 1 diff --git a/Multiprotocol/sync.ffs_db b/Multiprotocol/sync.ffs_db index ef0ab5b..e3801e8 100644 Binary files a/Multiprotocol/sync.ffs_db and b/Multiprotocol/sync.ffs_db differ