From 0729b21e674f308ca434fb0270bdc6ad083ab5b7 Mon Sep 17 00:00:00 2001 From: pascallanger Date: Sun, 10 Jan 2016 16:10:27 +0100 Subject: [PATCH] H8_3D protocol addition --- Multiprotocol/CG023_nrf24l01.ino | 226 ++++++++++++++++++++++--------- Multiprotocol/CYRF6936_SPI.ino | 22 +-- Multiprotocol/DSM2_cyrf6936.ino | 12 +- Multiprotocol/multiprotocol.h | 59 ++++---- 4 files changed, 214 insertions(+), 105 deletions(-) diff --git a/Multiprotocol/CG023_nrf24l01.ino b/Multiprotocol/CG023_nrf24l01.ino index 62de5c198..1490ca186 100644 --- a/Multiprotocol/CG023_nrf24l01.ino +++ b/Multiprotocol/CG023_nrf24l01.ino @@ -12,7 +12,8 @@ You should have received a copy of the GNU General Public License along with Multiprotocol. If not, see . */ -// compatible with EAchine 3D X4, CG023/CG031, Attop YD-822/YD-829/YD-829C +// Merged CG023 and H8_3D protocols +// compatible with EAchine 3D X4, CG023/CG031, Attop YD-822/YD-829/YD-829C and H8_3D/JJRC H20 #if defined(CG023_NRF24L01_INO) @@ -22,8 +23,12 @@ #define CG023_INITIAL_WAIT 500 #define CG023_PACKET_SIZE 15 // packets have 15-byte payload #define CG023_RF_BIND_CHANNEL 0x2D -#define CG023_BIND_COUNT 800 // 6 seconds +#define CG023_BIND_COUNT 1000 // 8 seconds #define YD829_PACKET_PERIOD 4100 // Timeout for callback in uSec +#define H8_3D_PACKET_PERIOD 1800 // Timeout for callback in uSec +#define H8_3D_PACKET_SIZE 20 +#define H8_3D_RF_NUM_CHANNELS 4 + enum CG023_FLAGS { // flags going to packet[13] @@ -48,6 +53,20 @@ enum YD829_FLAGS { YD829_FLAG_STILL = 0x80, }; +enum H8_3D_FLAGS { + // flags going to packet[17] + H8_3D_FLAG_FLIP = 0x01, + H8_3D_FLAG_RATE_MID = 0x02, + H8_3D_FLAG_RATE_HIGH = 0x04, + H8_3D_FLAG_HEADLESS = 0x10, // RTH + headless on H8, headless on JJRC H20 + H8_3D_FLAG_RTH = 0x40, // 360 flip mode on H8 3D, RTH on JJRC H20 +}; + +enum H8_3D_FLAGS_2 { + // flags going to packet[18] + H8_3D_FLAG_CALIBRATE = 0x20, // accelerometer calibration +}; + enum CG023_PHASES { CG023_BIND = 0, CG023_DATA @@ -55,75 +74,135 @@ enum CG023_PHASES { void CG023_send_packet(uint8_t bind) { - if (bind) - packet[0]= 0xaa; - else - packet[0]= 0x55; - // transmitter id - packet[1] = rx_tx_addr[0]; - packet[2] = rx_tx_addr[1]; - // unknown - packet[3] = 0x00; - packet[4] = 0x00; // throttle : 0x00 - 0xFF - packet[5] = convert_channel_8b(THROTTLE); + throttle=convert_channel_8b(THROTTLE); // rudder - packet[6] = convert_channel_8b_scale(RUDDER,0x44,0xBC); // yaw right : 0x80 (neutral) - 0xBC (right) - if (packet[6]<=0x80) - packet[6]=0x80-packet[6]; // yaw left : 0x00 (neutral) - 0x3C (left) + rudder = convert_channel_8b_scale(RUDDER,0x44,0xBC); // yaw right : 0x80 (neutral) - 0xBC (right) + if (rudder<=0x80) + rudder=0x80-rudder; // yaw left : 0x00 (neutral) - 0x3C (left) // elevator : 0xBB - 0x7F - 0x43 - packet[7] = convert_channel_8b_scale(ELEVATOR, 0x43, 0xBB); + elevator = convert_channel_8b_scale(ELEVATOR, 0x43, 0xBB); // aileron : 0x43 - 0x7F - 0xBB - packet[8] = convert_channel_8b_scale(AILERON, 0x43, 0xBB); - // throttle trim : 0x30 - 0x20 - 0x10 - packet[9] = 0x20; // neutral - // neutral trims - packet[10] = 0x20; - packet[11] = 0x40; - packet[12] = 0x40; - if(sub_protocol==CG023) + aileron = convert_channel_8b_scale(AILERON, 0x43, 0xBB); + + packet[1] = rx_tx_addr[0]; + packet[2] = rx_tx_addr[1]; + if(sub_protocol==H8_3D) { - // rate - packet[13] = CG023_FLAG_RATE_HIGH; - // flags - if(Servo_data[AUX1] > PPM_SWITCH) - packet[13] |= CG023_FLAG_FLIP; - if(Servo_data[AUX2] > PPM_SWITCH) - packet[13] |= CG023_FLAG_LED_OFF; - if(Servo_data[AUX3] > PPM_SWITCH) - packet[13] |= CG023_FLAG_STILL; - if(Servo_data[AUX4] > PPM_SWITCH) - packet[13] |= CG023_FLAG_VIDEO; - if(Servo_data[AUX5] > PPM_SWITCH) - packet[13] |= CG023_FLAG_EASY; + packet[0] = 0x13; + packet[3] = rx_tx_addr[2]; + packet[4] = rx_tx_addr[3]; + packet[8] = (rx_tx_addr[0]+rx_tx_addr[1]+rx_tx_addr[2]+rx_tx_addr[3]) & 0xff; // txid checksum + memset(&packet[9], 0, 10); + if (bind) + { + packet[5] = 0x00; + packet[6] = 0x00; + packet[7] = 0x01; + } + else + { + packet[5] = hopping_frequency_no; + packet[6] = 0x08; + packet[7] = 0x03; + packet[9] = throttle; + packet[10] = rudder; + packet[11] = elevator; + packet[12] = aileron; + // neutral trims + packet[13] = 0x20; + packet[14] = 0x20; + packet[15] = 0x20; + packet[16] = 0x20; + packet[17] = H8_3D_FLAG_RATE_HIGH; + if(Servo_data[AUX1] > PPM_SWITCH) + packet[17] |= H8_3D_FLAG_FLIP; + if(Servo_data[AUX2] > PPM_SWITCH) + packet[17] |= H8_3D_FLAG_HEADLESS; + if(Servo_data[AUX3] > PPM_SWITCH) + packet[17] |= H8_3D_FLAG_RTH; // 180/360 flip mode on H8 3D + + // both sticks bottom left: calibrate acc + if(packet[9] <= 0x05 && packet[10] >= 0xa7 && packet[11] <= 0x57 && packet[12] >= 0xa7) + packet[18] = H8_3D_FLAG_CALIBRATE; + } + uint8_t sum = packet[9]; + for (uint8_t i=10; i < H8_3D_PACKET_SIZE-1; i++) + sum += packet[i]; + packet[19] = sum; // data checksum } else - {// YD829 - // rate - packet[13] = YD829_FLAG_RATE_HIGH; - // flags - if(Servo_data[AUX1] > PPM_SWITCH) - packet[13] |= YD829_FLAG_FLIP; - if(Servo_data[AUX3] > PPM_SWITCH) - packet[13] |= YD829_FLAG_STILL; - if(Servo_data[AUX4] > PPM_SWITCH) - packet[13] |= YD829_FLAG_VIDEO; - if(Servo_data[AUX5] > PPM_SWITCH) - packet[13] |= YD829_FLAG_HEADLESS; + { // CG023 and YD829 + if (bind) + packet[0]= 0xaa; + else + packet[0]= 0x55; + // transmitter id + // unknown + packet[3] = 0x00; + packet[4] = 0x00; + packet[5] = throttle; + packet[6] = rudder; + packet[7] = elevator; + packet[8] = aileron; + // throttle trim : 0x30 - 0x20 - 0x10 + packet[9] = 0x20; // neutral + // neutral trims + packet[10] = 0x20; + packet[11] = 0x40; + packet[12] = 0x40; + if(sub_protocol==CG023) + { + // rate + packet[13] = CG023_FLAG_RATE_HIGH; + // flags + if(Servo_data[AUX1] > PPM_SWITCH) + packet[13] |= CG023_FLAG_FLIP; + if(Servo_data[AUX2] > PPM_SWITCH) + packet[13] |= CG023_FLAG_LED_OFF; + if(Servo_data[AUX3] > PPM_SWITCH) + packet[13] |= CG023_FLAG_STILL; + if(Servo_data[AUX4] > PPM_SWITCH) + packet[13] |= CG023_FLAG_VIDEO; + if(Servo_data[AUX5] > PPM_SWITCH) + packet[13] |= CG023_FLAG_EASY; + } + else + {// YD829 + // rate + packet[13] = YD829_FLAG_RATE_HIGH; + // flags + if(Servo_data[AUX1] > PPM_SWITCH) + packet[13] |= YD829_FLAG_FLIP; + if(Servo_data[AUX3] > PPM_SWITCH) + packet[13] |= YD829_FLAG_STILL; + if(Servo_data[AUX4] > PPM_SWITCH) + packet[13] |= YD829_FLAG_VIDEO; + if(Servo_data[AUX5] > PPM_SWITCH) + packet[13] |= YD829_FLAG_HEADLESS; + } + packet[14] = 0; } - packet[14] = 0; - + // 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)); if (bind) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, CG023_RF_BIND_CHANNEL); + NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol==H8_3D?hopping_frequency[0]:CG023_RF_BIND_CHANNEL); else - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); + { + if(sub_protocol==H8_3D) + { + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]); + hopping_frequency_no %= H8_3D_RF_NUM_CHANNELS; + } + else // CG023 and YD829 + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); + } // clear packet status bits and TX FIFO NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); - XN297_WritePayload(packet, CG023_PACKET_SIZE); + XN297_WritePayload(packet, sub_protocol==H8_3D ? H8_3D_PACKET_SIZE:CG023_PACKET_SIZE); NRF24L01_SetPower(); // Set tx_power } @@ -132,7 +211,10 @@ void CG023_init() { NRF24L01_Initialize(); NRF24L01_SetTxRxMode(TX_EN); - XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5); + if(sub_protocol==H8_3D) + XN297_SetTXAddr((uint8_t *)"\xC4\x57\x09\x65\x21", 5); + else // CG023 and YD829 + XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5); NRF24L01_FlushTx(); NRF24L01_FlushRx(); @@ -166,16 +248,32 @@ uint16_t CG023_callback() if(sub_protocol==CG023) return CG023_PACKET_PERIOD; else - return YD829_PACKET_PERIOD; + if(sub_protocol==YD829) + return YD829_PACKET_PERIOD; + return H8_3D_PACKET_PERIOD; } void CG023_initialize_txid() { - rx_tx_addr[0]= 0x80 | (rx_tx_addr[0] % 0x40); - if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel - rx_tx_addr[0] ++; - - hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets + if(sub_protocol==H8_3D) + { + rx_tx_addr[0] = 0xa0 + (rx_tx_addr[0] % 0x10); + rx_tx_addr[1] = 0xb0 + (rx_tx_addr[1] % 0x20); + rx_tx_addr[2] = rx_tx_addr[2] % 0x20; + rx_tx_addr[3] = rx_tx_addr[3] % 0x11; + + hopping_frequency[0] = 0x06 + (((rx_tx_addr[0]>>8) + (rx_tx_addr[0]&0x0f)) % 0x0f); + hopping_frequency[1] = 0x15 + (((rx_tx_addr[1]>>8) + (rx_tx_addr[1]&0x0f)) % 0x0f); + hopping_frequency[2] = 0x24 + (((rx_tx_addr[2]>>8) + (rx_tx_addr[2]&0x0f)) % 0x0f); + hopping_frequency[3] = 0x33 + (((rx_tx_addr[3]>>8) + (rx_tx_addr[3]&0x0f)) % 0x0f); + } + else + { // CG023 and YD829 + rx_tx_addr[0]= 0x80 | (rx_tx_addr[0] % 0x40); + if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel + rx_tx_addr[0] ++; + hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets + } } uint16_t initCG023(void) @@ -188,7 +286,9 @@ uint16_t initCG023(void) if(sub_protocol==CG023) return CG023_INITIAL_WAIT+CG023_PACKET_PERIOD; else - return CG023_INITIAL_WAIT+YD829_PACKET_PERIOD; + if(sub_protocol==YD829) + return CG023_INITIAL_WAIT+YD829_PACKET_PERIOD; + return CG023_INITIAL_WAIT+H8_3D_PACKET_PERIOD; } #endif diff --git a/Multiprotocol/CYRF6936_SPI.ino b/Multiprotocol/CYRF6936_SPI.ino index 1722ac8b7..a45101d2f 100644 --- a/Multiprotocol/CYRF6936_SPI.ino +++ b/Multiprotocol/CYRF6936_SPI.ino @@ -107,10 +107,6 @@ uint8_t CYRF_Reset() return (CYRF_ReadRegister(CYRF_10_FRAMING_CFG) == 0xa5);//return if reset } -uint8_t CYRF_MaxPower() -{ - return (*((uint8_t*)0x08001007) == 0) ? CYRF_PWR_100MW : CYRF_PWR_10MW; -} /* * */ @@ -130,12 +126,20 @@ void CYRF_GetMfgData(uint8_t data[]) */ void CYRF_SetTxRxMode(uint8_t mode) { - //Set the post tx/rx state - CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x28 : 0x2C); //was 0x2C:0x28 but reversed in last deviation - if(mode == TX_EN) - CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x80); + if(mode==TXRX_OFF) + { + CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); // 4=IDLE, 8=TX, C=RX + CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x00); // XOUT=0 PACTL=0 + } else - CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x20); + { + //Set the post tx/rx state + CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x28 : 0x2C); // 4=IDLE, 8=TX, C=RX + if(mode == TX_EN) + CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x80); // XOUT=1, PACTL=0 + else + CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x20); // XOUT=0, PACTL=1 + } } /* * diff --git a/Multiprotocol/DSM2_cyrf6936.ino b/Multiprotocol/DSM2_cyrf6936.ino index 676f3ccdc..fd4e0f9c7 100644 --- a/Multiprotocol/DSM2_cyrf6936.ino +++ b/Multiprotocol/DSM2_cyrf6936.ino @@ -282,17 +282,17 @@ const uint8_t init_vals[][2] = { {CYRF_06_RX_CFG, 0x4A}, {CYRF_1B_TX_OFFSET_LSB, 0x55}, {CYRF_1C_TX_OFFSET_MSB, 0x05}, - {CYRF_0F_XACT_CFG, 0x24}, - {CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, + {CYRF_0F_XACT_CFG, 0x24}, // Force Idle + {CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode {CYRF_12_DATA64_THOLD, 0x0a}, - {CYRF_0F_XACT_CFG, 0x04}, + {CYRF_0F_XACT_CFG, 0x04}, // Idle {CYRF_39_ANALOG_CTRL, 0x01}, {CYRF_0F_XACT_CFG, 0x24}, //Force IDLE {CYRF_29_RX_ABORT, 0x00}, //Clear RX abort {CYRF_12_DATA64_THOLD, 0x0a}, //set pn correlation threshold {CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold {CYRF_29_RX_ABORT, 0x0f}, //Clear RX abort? - {CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDE mode, was max-power but replaced by low power + {CYRF_03_TX_CFG, 0x38 | CYRF_BIND_POWER}, //Set 64chip, SDR mode {CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold {CYRF_1F_TX_OVERRIDE, 0x04}, //disable tx CRC {CYRF_1E_RX_OVERRIDE, 0x14}, //disable rx crc @@ -329,11 +329,11 @@ const uint8_t data_vals[][2] = { {CYRF_29_RX_ABORT, 0x20}, {CYRF_0F_XACT_CFG, 0x24}, {CYRF_29_RX_ABORT, 0x00}, - {CYRF_03_TX_CFG, 0x08 | 7}, + {CYRF_03_TX_CFG, 0x08 | CYRF_HIGH_POWER}, {CYRF_10_FRAMING_CFG, 0xea}, {CYRF_1F_TX_OVERRIDE, 0x00}, {CYRF_1E_RX_OVERRIDE, 0x00}, - {CYRF_03_TX_CFG, 0x28 | 7}, + {CYRF_03_TX_CFG, 0x28 | CYRF_HIGH_POWER}, {CYRF_12_DATA64_THOLD, 0x3f}, {CYRF_10_FRAMING_CFG, 0xff}, {CYRF_0F_XACT_CFG, 0x24}, //Switch from reading RSSI to Writing diff --git a/Multiprotocol/multiprotocol.h b/Multiprotocol/multiprotocol.h index 5ec67e954..69bd2bf3b 100644 --- a/Multiprotocol/multiprotocol.h +++ b/Multiprotocol/multiprotocol.h @@ -71,26 +71,14 @@ enum CX10 { enum CG023 { CG023 = 0, - YD829 = 1 + YD829 = 1, + H8_3D = 2 }; #define PPM_MIN_COMMAND 1250 #define PPM_SWITCH 1550 #define PPM_MAX_COMMAND 1750 -enum TXRX_State { - TXRX_OFF, - TX_EN, - RX_EN -}; - -// Packet ack status values -enum { - PKT_PENDING = 0, - PKT_ACKED, - PKT_TIMEOUT -}; - //******************* //*** Pinouts *** //******************* @@ -250,11 +238,11 @@ enum CC2500_POWER { CC2500_POWER_0 = 0xC5, // -12dbm CC2500_POWER_1 = 0x97, // -10dbm - CC2500_POWER_2 = 0x6E, // -8dbm - CC2500_POWER_3 = 0x7F, // -6dbm - CC2500_POWER_4 = 0xA9, // -4dbm - CC2500_POWER_5 = 0xBB, // -2dbm - CC2500_POWER_6 = 0xFE, // 0dbm + CC2500_POWER_2 = 0x6E, // -8dbm + CC2500_POWER_3 = 0x7F, // -6dbm + CC2500_POWER_4 = 0xA9, // -4dbm + CC2500_POWER_5 = 0xBB, // -2dbm + CC2500_POWER_6 = 0xFE, // 0dbm CC2500_POWER_7 = 0xFF // 1.5dbm }; #define CC2500_HIGH_POWER CC2500_POWER_6 @@ -265,20 +253,33 @@ enum CC2500_POWER // CYRF power enum CYRF_POWER { - CYRF_POWER_0 = 0x00, // - CYRF_POWER_1 = 0x01, // - CYRF_POWER_2 = 0x02, // - CYRF_POWER_3 = 0x03, // - CYRF_POWER_4 = 0x04, // - CYRF_POWER_5 = 0x05, // - CYRF_POWER_6 = 0x06, // - CYRF_POWER_7 = 0x07 // + CYRF_POWER_0 = 0x00, // -35dbm + CYRF_POWER_1 = 0x01, // -30dbm + CYRF_POWER_2 = 0x02, // -24dbm + CYRF_POWER_3 = 0x03, // -18dbm + CYRF_POWER_4 = 0x04, // -13dbm + CYRF_POWER_5 = 0x05, // -5dbm + CYRF_POWER_6 = 0x06, // 0dbm + CYRF_POWER_7 = 0x07 // +4dbm }; #define CYRF_HIGH_POWER CYRF_POWER_7 #define CYRF_LOW_POWER CYRF_POWER_3 #define CYRF_BIND_POWER CYRF_POWER_0 #define CYRF_RANGE_POWER CYRF_POWER_0 +enum TXRX_State { + TXRX_OFF, + TX_EN, + RX_EN +}; + +// Packet ack status values +enum { + PKT_PENDING = 0, + PKT_ACKED, + PKT_TIMEOUT +}; + //******************* //*** CRC Table *** //******************* @@ -347,6 +348,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- CX10 12 CG023 13 Bayang 14 + FrskyX 15 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -380,6 +382,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- sub_protocol==CG023 CG023 0 YD829 1 + H8_3D 2 Power value => 0x80 0=High/1=Low Stream[3] = option_protocol; option_protocol value is -127..127 @@ -422,6 +425,7 @@ Serial: 125000 Baud 8n1 _ xxxx xxxx - --- CX10 12 CG023 13 Bayang 14 + FrskyX 15 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -455,6 +459,7 @@ Serial: 125000 Baud 8n1 _ xxxx xxxx - --- sub_protocol==CG023 CG023 0 YD829 1 + H8_3D 2 Power value => 0x80 0=High/1=Low Stream[2] = option_protocol; option_protocol value is -127..127