static void CORONA_rf_init() { CC2500_Strobe(CC2500_SIDLE); for (u8 i = 0; i <= 0x2E; ++i) CC2500_WriteReg(i, CORONA_init_values[i]); CC2500_Strobe(CC2500_SCAL); // just duplicating stock tx CC2500_ReadReg(CC2500_25_FSCAL1); // just duplicating stock tx if (Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_V2) { CC2500_WriteReg(CC2500_0A_CHANNR, CORONA_BIND_CHANNEL_V2); CC2500_WriteReg(CC2500_0E_FREQ1, 0x80); CC2500_WriteReg(CC2500_0F_FREQ0, 0x00); CC2500_WriteReg(CC2500_15_DEVIATN, 0x50); CC2500_WriteReg(CC2500_17_MCSM1, 0x00); CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0x67); CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0xFB); CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xDC); } else if (Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_FDV3) { // Flydream receiver captures have deviation 50, tx captures show 47 CC2500_WriteReg(CC2500_15_DEVIATN, 0x50); } CC2500_WriteReg(CC2500_0C_FSCTRL0, Model.proto_opts[PROTO_OPTS_FREQFINE]); CC2500_SetTxRxMode(TX_EN); CC2500_SetPower(0); // min power for binding, set in build_packet for normal operation }
static void HITEC_CC2500_init() { const u8 HITEC_init_values[] = { /* 00 */ 0x2F, 0x2E, 0x2F, 0x07, 0xD3, 0x91, 0xFF, 0x04, /* 08 */ 0x45, 0x00, 0x00, 0x12, 0x00, 0x5C, 0x85, HITEC_FREQ0_VAL, /* 10 */ 0x3D, 0x3B, 0x73, 0x73, 0x7A, 0x01, 0x07, 0x30, /* 18 */ 0x08, 0x1D, 0x1C, 0xC7, 0x00, 0xB0, 0x87, 0x6B, /* 20 */ 0xF8, 0xB6, 0x10, 0xEA, 0x0A, 0x00, 0x11, }; CC2500_Strobe(CC2500_SIDLE); for (u8 i = 0; i < 39; ++i) CC2500_WriteReg(i, HITEC_init_values[i]); CC2500_SetTxRxMode(TX_EN); CC2500_SetPower(Model.tx_power); }
static u16 CORONA_build_packet(void) { CC2500_SetPower(Model.tx_power); // Update RF power if (state && (Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_V2)) { // Send identifier packet for 2.65sec. This is how the RX learns the hopping table after a bind. Why it's not part of the bind like V1 is a mistery... // Set channel CC2500_WriteReg(CC2500_0A_CHANNR, 0x00); state--; packet[0]=0x07; // 8 bytes to follow // Send hopping freq for(u8 i=0; i<CORONA_RF_NUM_CHANNELS; i++) packet[i+1]=hopping_frequency[i]; // Send TX ID for(u8 i=0; i<CORONA_ADDRESS_LENGTH; i++) packet[i+4]=rx_tx_addr[i]; packet[8]=0; return 6647; } // Flydream every fourth packet is identifier packet and is on channel number // that is last byte of rx_tx_addr if (fdv3_id_send) { fdv3_id_send = 0; CC2500_WriteReg(CC2500_0A_CHANNR, rx_tx_addr[CORONA_ADDRESS_LENGTH-1]); packet[0] = 0x07; // 8 bytes to follow // Send TX ID for(u8 i = 0; i < CORONA_ADDRESS_LENGTH; i++) packet[i+1] = rx_tx_addr[i]; // Send hopping freq for(u8 i = 0; i < CORONA_RF_NUM_CHANNELS; i++) packet[i+1+CORONA_ADDRESS_LENGTH] = hopping_frequency[i]; packet[8] = 0; return 2*FDV3_CHANNEL_PERIOD; // extra delay after id packet according to captures } // Set RF channel CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[hopping_frequency_no]); // Build packet packet[0] = 0x10; // 17 bytes to follow // Channels memset(packet+9, 0x00, 4); for (u8 i=0; i<8; i++) { // Channel values are packed u16 val=convert_channel_ppm(i); packet[i+1] = val; packet[9 + (i>>1)] |= (i&0x01)?(val>>4)&0xF0:(val>>8)&0x0F; } // TX ID for (u8 i=0; i < CORONA_ADDRESS_LENGTH; i++) packet[i+13] = rx_tx_addr[i]; packet[17] = 0x00; if (Model.proto_opts[PROTO_OPTS_FORMAT] != FORMAT_FDV3) { // Packet period is based on hopping switch (hopping_frequency_no) { case 0: packet_period = Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_V1 ? 4991 : 4248; break; case 1: packet_period = Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_V1 ? 4991 : 4345; break; case 2: packet_period = Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_V1 ? 12520 : 13468; if (Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_V2) packet[17] = 0x03; break; } } hopping_frequency_no++; if (Model.proto_opts[PROTO_OPTS_FORMAT] == FORMAT_FDV3) { if (hopping_frequency_no == CORONA_RF_NUM_CHANNELS) { fdv3_id_send = 1; packet_period = 6000; // extra delay before id packet according to captures } else { packet_period = FDV3_CHANNEL_PERIOD; } } hopping_frequency_no %= CORONA_RF_NUM_CHANNELS; return packet_period; }
static void frsky_init() { CC2500_Reset(); CC2500_WriteReg(CC2500_17_MCSM1, 0x0c); CC2500_WriteReg(CC2500_18_MCSM0, 0x18); CC2500_WriteReg(CC2500_06_PKTLEN, 0xff); CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x04); CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); CC2500_WriteReg(CC2500_3E_PATABLE, 0xfe); CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x08); CC2500_WriteReg(CC2500_0C_FSCTRL0, fine); CC2500_WriteReg(CC2500_0D_FREQ2, 0x5c); CC2500_WriteReg(CC2500_0E_FREQ1, 0x58); CC2500_WriteReg(CC2500_0F_FREQ0, 0x9d + course); CC2500_WriteReg(CC2500_10_MDMCFG4, 0xaa); CC2500_WriteReg(CC2500_11_MDMCFG3, 0x10); CC2500_WriteReg(CC2500_12_MDMCFG2, 0x93); CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); CC2500_WriteReg(CC2500_14_MDMCFG0, 0x7a); CC2500_WriteReg(CC2500_15_DEVIATN, 0x41); CC2500_WriteReg(CC2500_19_FOCCFG, 0x16); CC2500_WriteReg(CC2500_1A_BSCFG, 0x6c); CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0x43); CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x40); CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0x91); CC2500_WriteReg(CC2500_21_FREND1, 0x56); CC2500_WriteReg(CC2500_22_FREND0, 0x10); CC2500_WriteReg(CC2500_23_FSCAL3, 0xa9); CC2500_WriteReg(CC2500_24_FSCAL2, 0x0a); CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); CC2500_WriteReg(CC2500_29_FSTEST, 0x59); CC2500_WriteReg(CC2500_2C_TEST2, 0x88); CC2500_WriteReg(CC2500_2D_TEST1, 0x31); CC2500_WriteReg(CC2500_2E_TEST0, 0x0b); CC2500_WriteReg(CC2500_03_FIFOTHR, 0x07); CC2500_WriteReg(CC2500_09_ADDR, 0x00); CC2500_SetTxRxMode(TX_EN); CC2500_SetPower(Model.tx_power); CC2500_Strobe(CC2500_SIDLE); // Go to idle... //CC2500_WriteReg(CC2500_02_IOCFG0, 0x06); //CC2500_WriteReg(CC2500_0A_CHANNR, 0x06); #if 0 CC2500_WriteReg(CC2500_02_IOCFG0, 0x01); // reg 0x02: RX complete interrupt CC2500_WriteReg(CC2500_17_MCSM1, 0x0C); // reg 0x17: Stay in rx after packet complete CC2500_WriteReg(CC2500_18_MCSM0, 0x18); // reg 0x18: Calibrate when going from idle to rx or tx, po timeout count = 64 CC2500_WriteReg(CC2500_06_PKTLEN, 62); // Leave room for appended status bytes CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); // reg 0x08: CRC_EN = 1, Length_config = 1 (variable length) CC2500_WriteReg(CC2500_3E_PATABLE, 0xFF); CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x08); // reg 0x0B: 203 KHz IF CC2500_WriteReg(CC2500_0C_FSCTRL0, 0x00); // reg 0x0C // CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // reg 0x0D // CC2500_WriteReg(CC2500_0E_FREQ1, 0x76); // reg 0x0E // CC2500_WriteReg(CC2500_0F_FREQ0, 0x27); // reg 0x0F CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // reg 0x0D hack: Due to a bit high xtal we shift this down by around 70 khz CC2500_WriteReg(CC2500_0E_FREQ1, 0x75); // reg 0x0E CC2500_WriteReg(CC2500_0F_FREQ0, 0x6A); // reg 0x0F CC2500_WriteReg(CC2500_10_MDMCFG4, 0xAA); // reg 0x10 CC2500_WriteReg(CC2500_11_MDMCFG3, 0x39); // reg 0x11 CC2500_WriteReg(CC2500_12_MDMCFG2, 0x11); // reg 0x12 CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // reg 0x13 CC2500_WriteReg(CC2500_14_MDMCFG0, 0x7A); // reg 0x14 CC2500_WriteReg(CC2500_15_DEVIATN, 0x42); // reg 0x15 CC2500_WriteReg(CC2500_19_FOCCFG, 0x16); // reg 0x19 CC2500_WriteReg(CC2500_1A_BSCFG, 0x6C); // reg 0x1A CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0x03); // reg 0x1B CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x40); // reg 0x1C CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0x91); // reg 0x1D CC2500_WriteReg(CC2500_21_FREND1, 0x56); // reg 0x21: Default POR value CC2500_WriteReg(CC2500_22_FREND0, 0x10); // reg 0x22: Default POR value CC2500_WriteReg(CC2500_23_FSCAL3, 0xA9); // reg 0x23: Default POR value CC2500_WriteReg(CC2500_24_FSCAL2, 0x05); // reg 0x24: Default POR value CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // reg 0x25 CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // reg 0x26 CC2500_WriteReg(CC2500_29_FSTEST, 0x59); // reg 0x29 CC2500_WriteReg(CC2500_2C_TEST2, 0x88); // reg 0x2C CC2500_WriteReg(CC2500_2D_TEST1, 0x31); // reg 0x2D CC2500_WriteReg(CC2500_2E_TEST0, 0x0B); // reg 0x2E CC2500_WriteReg(CC2500_03_FIFOTHR, 0x0F); // reg 0x03: Use max rx fifo CC2500_WriteReg(CC2500_09_ADDR, 0x03); // reg 0x09: FrSky bind address is 0x0301 on channel 0 CC2500_Strobe(CC2500_SIDLE); // Go to idle... CC2500_WriteReg(CC2500_07_PKTCTRL1,0x0D); // reg 0x07 hack: Append status, filter by address, auto-flush on bad crc, PQT=0 CC2500_WriteReg(CC2500_0C_FSCTRL0, 0); // Frequency offset... CC2500_WriteReg(CC2500_0A_CHANNR, 0); #endif }