#if defined(FRSKYR9_SX1276_INO) #include "iface_sx1276.h" #define DISP_FREQ_TABLE #define FLEX_FREQ 29 #define FCC_FREQ 43 #define EU_FREQ 19 enum { FRSKYR9_FREQ=0, FRSKYR9_DATA, FRSKYR9_RX1, FRSKYR9_RX2, }; void FrSkyR9_set_frequency() { uint8_t data[3]; uint16_t num=0; hopping_frequency_no += FrSkyX_chanskip; switch(sub_protocol & 0xFD) { case R9_868: if(IS_BIND_DONE) // if bind is in progress use R9_915 instead { hopping_frequency_no %= FLEX_FREQ; num=hopping_frequency_no; if(hopping_frequency_no>=FLEX_FREQ-2) num+=FrSkyX_chanskip-FLEX_FREQ+2; // the last 2 values are FrSkyX_chanskip and FrSkyX_chanskip+1 num <<= 5; num += 0xD700; break; }//else use R9_915 case R9_915: hopping_frequency_no %= FLEX_FREQ; num=hopping_frequency_no; if(hopping_frequency_no>=FLEX_FREQ-2) num+=FrSkyX_chanskip-FLEX_FREQ+2; // the last 2 values are FrSkyX_chanskip and FrSkyX_chanskip+1 num <<= 5; num += 0xE4C0; break; case R9_FCC: hopping_frequency_no %= FCC_FREQ; num=hopping_frequency_no; num <<= 5; num += 0xE200; break; case R9_EU: hopping_frequency_no %= EU_FREQ; num=hopping_frequency_no; num <<= 4; num += 0xD7D0; break; } data[0] = num>>8; data[1] = num&0xFF; data[2] = 0x00; #ifdef DISP_FREQ_TABLE if(phase==0xFF) debugln("F%d=%02X%02X%02X=%lu", hopping_frequency_no, data[0], data[1], data[2], (uint32_t)((data[0]<<16)+(data[1]<<8)+data[2])*61); #endif SX1276_WriteRegisterMulti(SX1276_06_FRFMSB, data, 3); } static void __attribute__((unused)) FrSkyR9_build_packet() { //ID packet[0] = rx_tx_addr[1]; packet[1] = rx_tx_addr[2]; packet[2] = rx_tx_addr[3]; //Hopping packet[3] = hopping_frequency_no; // current channel index packet[4] = FrSkyX_chanskip; // step size and last 2 channels start index //RX number packet[5] = RX_num; // receiver number from OpenTX //Channels FrSkyX_channels(6); // Set packet[6]=failsafe, packet[7]=0?? and packet[8..19]=channels data //Bind if(IS_BIND_IN_PROGRESS) {// 915 0x01=CH1-8_TELEM_ON 0x41=CH1-8_TELEM_OFF 0xC1=CH9-16_TELEM_OFF 0x81=CH9-16_TELEM_ON packet[6] = 0x01; // bind indicator if(sub_protocol & 1) packet[6] |= 0x20; // 868 if(binding_idx&0x01) packet[6] |= 0x40; // telem OFF if(binding_idx&0x02) packet[6] |= 0x80; // ch9-16 } //Sequence and send SPort FrSkyX_seq_sport(20,23); //20=RX|TXseq, 21=bytes count, 22&23=data //CRC uint16_t crc = FrSkyX_crc(packet, 24); packet[24] = crc; // low byte packet[25] = crc >> 8; // high byte } static uint8_t __attribute__((unused)) FrSkyR9_CRC8(uint8_t *p, uint8_t l) { uint8_t crc = 0xFF; for (uint8_t i = 0; i < l; i++) { crc = crc ^ p[i]; for ( uint8_t j = 0; j < 8; j++ ) if ( crc & 0x80 ) { crc <<= 1; crc ^= 0x07; } else crc <<= 1; } return crc; } static void __attribute__((unused)) FrSkyR9_build_EU_packet() { //ID packet[0] = rx_tx_addr[1]; packet[1] = rx_tx_addr[2]; packet[2] = rx_tx_addr[3]; //Hopping packet[3] = FrSkyX_chanskip; // step size and last 2 channels start index //RX number packet[4] = RX_num; // receiver number from OpenTX //Channels //TODO FrSkyX_channels(5,4); // Set packet[5]=failsafe and packet[6..11]=4 channels data //Bind if(IS_BIND_IN_PROGRESS) { packet[5] = 0x01; // bind indicator if((sub_protocol & 2) == 0) packet[5] |= 0x10; // 16CH // if(sub_protocol & 1) // packet[5] |= 0x20; // 868 if(binding_idx&0x01) packet[5] |= 0x40; // telem OFF if(binding_idx&0x02) packet[5] |= 0x80; // ch9-16 } //Sequence and send SPort packet[12] = (FrSkyX_RX_Seq << 4)|0x08; //TX=8 at startup //CRC packet[13] = FrSkyR9_CRC8(packet, 13); } void FRSKYR9_init() { //Check frequencies #ifdef DISP_FREQ_TABLE phase=0xFF; FrSkyX_chanskip=1; hopping_frequency_no=0xFF; for(uint8_t i=0;i>2)+1; TX_RSSI=SX1276_ReadReg(SX1276_1A_PACKETRSSI)-157; for(uint8_t i=0;i<9;i++) packet[4+i]=packet_in[i]; // Adjust buffer to match FrSkyX frsky_process_telemetry(packet,len); // Process telemetry packet pps_counter++; if(TX_LQI==0) TX_LQI++; // Recover telemetry right away } } } if (millis() - pps_timer >= 1000) {//1 packet every 20ms pps_timer = millis(); debugln("%d pps", pps_counter); TX_LQI = pps_counter<<1; // Max=100% pps_counter = 0; } if(TX_LQI==0) FrSkyX_telem_init(); // Reset telemetry else telemetry_link=1; // Send telemetry out anyway phase=FRSKYR9_FREQ; break; #endif } return 1000; } #endif