static u16 frsky_cb() { if (state < FRSKY_BIND_DONE) { build_bind_packet_1way(); CC2500_Strobe(CC2500_SIDLE); CC2500_WriteReg(CC2500_0A_CHANNR, 0x00); CC2500_WriteData(packet, packet[0]+1); state++; return 53460; } if (state == FRSKY_BIND_DONE) { state++; PROTOCOL_SetBindState(0); } if (state >= FRSKY_DATA1) { u8 chan = calc_channel(); CC2500_Strobe(CC2500_SIDLE); CC2500_WriteReg(CC2500_0A_CHANNR, chan * 5 + 6); build_data_packet_1way(); CC2500_WriteData(packet, packet[0]+1); state++; if (state > FRSKY_DATA5) state = FRSKY_DATA1; return 9006; } return 0; }
void CC2500_SetRecvAddr(CC2500_RECV_ADDR AddrMode,u8 SpecAddr) { CC2500_WriteReg(CCxxx0_ADDR,SpecAddr); CC2500_WriteReg(CCxxx0_PKTCTRL1,AddrMode);//地址检查寄存器 CC2500_SetRxd(); }
void CC2500_SetTxRxMode(enum TXRX_State mode) { // config-cc2500 = 0x01 for swapping GDO0 and GDO2. int R0 = CC2500_02_IOCFG0; int R2 = CC2500_00_IOCFG2; if (Transmitter.module_config[CC2500] == CC2500_REVERSE_GD02) { R0 = CC2500_00_IOCFG2; R2 = CC2500_02_IOCFG0; } if(mode == TX_EN) { #if RFX2401C CC2500_WriteReg(R0, 0x2F | 0x40); CC2500_WriteReg(R2, 0x2F); #else // non C version (RFX2401) needs CE signal high for both RX and TX CC2500_WriteReg(R0, 0x2F | 0x40); // TX/RXN CC2500_WriteReg(R2, 0x2F | 0x40); // CE #endif } else if (mode == RX_EN) { #if RFX2401C CC2500_WriteReg(R0, 0x2F); CC2500_WriteReg(R2, 0x2F | 0x40); #else CC2500_WriteReg(R0, 0x2F); // TX/RXN CC2500_WriteReg(R2, 0x2F | 0x40); // CE #endif } else { CC2500_WriteReg(R0, 0x2F); CC2500_WriteReg(R2, 0x2F); } }
// Initial register for WOR mode void CC2500_Init_WOR(void) { CC2500_SendSpiData(CCxxx0_SIDLE); CC2500_WriteReg(CCxxx0_WORCTRL, 0x08); // CC2500_WriteReg(CCxxx0_WOREVT1, 0x2b);//43B5 500ms, 28A0 300ms 1B15 200ms CC2500_WriteReg(CCxxx0_WOREVT0, 0x15);// 876B 1S CC2500_WriteReg(CCxxx0_MCSM2, 0x03); // RX_TIME // RX_TIME_RSSI= 1 RX_TIME_QUAL = 0 // 0:12.5%, 1:6.25%, 2:3.125%, 3:1.563%, 4:0.781% CC2500_WriteReg(CCxxx0_MCSM0, 0x38); // 频率校准方式,每4次从IDLE模式到RX模式进行一次频率合成器校准 CC2500_SendSpiData(CCxxx0_SWORRST); CC2500_SendSpiData(CCxxx0_SWOR); }
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); }
void CC2500_SetPower(int power) { const unsigned char patable[8]= { 0xC5, // -12dbm 0x97, // -10dbm 0x6E, // -8dbm 0x7F, // -6dbm 0xA9, // -4dbm 0xBB, // -2dbm 0xFE, // 0dbm 0xFF // 1.5dbm }; if (power > 7) power = 7; CC2500_WriteReg(CC2500_3E_PATABLE, patable[power]); }
void CC2500_SetTxRxMode(enum TXRX_State mode) { if(mode == TX_EN) { CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F | 0x40); CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F); } else if (mode == RX_EN) { CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F); CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F | 0x40); } else { CC2500_WriteReg(CC2500_02_IOCFG0, 0x2F); CC2500_WriteReg(CC2500_00_IOCFG2, 0x2F); } }
MODULE_CALLTYPE static u16 corona_cb() { // Tune frequency if it has been changed if (fine != (s8)Model.proto_opts[PROTO_OPTS_FREQFINE]) { fine = (s8)Model.proto_opts[PROTO_OPTS_FREQFINE]; CC2500_WriteReg(CC2500_0C_FSCTRL0, fine); } if (bind_counter) { if (bind_counter-- == 0) PROTOCOL_SetBindState(0); packet_period = CORONA_build_bind_pkt(); } else { packet_period = CORONA_build_packet(); } // Send packet CC2500_WriteData(packet, packet[0]+2); return packet_period; }
/* init stuff for normal RXing. */ void frsky_d8_rx_normal_init(void) { CC2500_WriteReg(CC2500_REG_ADDR, (uint8_t)m_config.frsky_d8_bind_info.bind_id); frsky_full_cal(); switch(m_config.rssi_injection_type) { default: num_frsky2way_channels = 8; break; case RSSI_INJECTION_AUTO: switch(m_config.frsky_d8_bind_info.bind_type) { default: case BIND_TYPE_D8: rssichan = 8; // inject on channel 9 by default. num_frsky2way_channels = 9; break; } break; case RSSI_INJECTION_NONE: switch(m_config.frsky_d8_bind_info.bind_type) { default: case BIND_TYPE_D8: num_frsky2way_channels = 8; break; } break; case RSSI_INJECTION_CHAN: rssichan = m_config.rssi_injection_chan; switch(m_config.frsky_d8_bind_info.bind_type) { default: case BIND_TYPE_D8: if (rssichan > 7) num_frsky2way_channels = rssichan + 1; break; } break; } }
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 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 }
void frsky_d8_rx_loop(void) { // TODO: disable LNA on high power rxing // TODO: rssi injection (and settings) //36ms loop. rx 3 times every 9ms. then ~2ms, then tx a packet (~6ms?). then wait for next packet, continue cycle. static uint8_t frsky_state = FRSKY_RX1; // can be derived from counter static uint8_t hopchan = 0; // can be derived from counter static uint8_t rx_state = STATE_WILL_RX; static uint8_t fail_state = STATE_SEARCH; static uint32_t lastPktTime = 0; // time last packet was received, used mainly for failasfe. static uint32_t nextPktTime = 200; // time of next expected incoming packet. default: approx. 200ms startup time, to not f**k shit up, this is still hacky and shitty tho static uint32_t lastHopTime = 0; // time of last hop, normally every 9ms, in searchmode every 45ms. telem txing places this in the middle of its packet frame for simplicity static uint32_t txStartTime = 0; // time when the tx packet should start, usually 2ms after an RX3 was received. static uint8_t gotFirstPkt = 0; static uint32_t failsafeBtnTime = 0; static uint8_t failsafeBtnSettingStatus = 0; uint32_t time = HAL_GetTick(); uint8_t freqoff_est; if (m_config.frsky_d8_bind_info.bind_type == BIND_TYPE_NONE) { /* do nothing if not bound. */ return; } switch (rx_state) { case STATE_WILL_RX: frsky_rx_enable(hopchan); rx_state = STATE_RXING; break; /* end STATE_WILL_RX */ case STATE_RXING: if (frsky_d8_rx_getpkt() != 0) { rx_state = STATE_RXD; break; } switch (fail_state) { case STATE_RUNNING: /* If we expected a packet and didn't get it, take action after a timeout. */ if (time > (nextPktTime + 2)) { /* Here we 'emulate' a packet RXing in order to prepare for the next action. */ /* lastHopTime is updated to the time the packet should have been received, which is the current nextPktTime. */ /* nextPktTime is updated to reflect the next anticipated packet, in 9 or 18ms. */ /* lastPktTime is untouched, as no real RXing was done. */ hopchan = (hopchan + 1) % D8_NUM_HOP_CHANNELS; frsky_state = (frsky_state + 1) % NUM_FRSKY_STATES; frsky_rx_toggle_ant(); lastHopTime = nextPktTime; if (frsky_state == FRSKY_TX_TELEM) { nextPktTime = nextPktTime + 18; rx_state = STATE_PREPARE_TX; } else { nextPktTime = nextPktTime + 9; rx_state = STATE_WILL_RX; } } /* if it has been a long time since the last valid packet, go to a different hop sequence in an attempt to find the tx's hop phase. */ /* TODO: make this timeout configurable, maybe */ if (time > (lastPktTime + 1000)) fail_state = STATE_SEARCH; break; /* end STATE_RUNNING */ case STATE_SEARCH: HAL_GPIO_WritePin(LED_RED_GPIO, LED_RED_PIN, LED_RED_STATE_ON); if (gotFirstPkt > 1) HAL_GPIO_WritePin(LED_GREEN_GPIO, LED_GREEN_PIN, LED_GREEN_STATE_OFF); /* hop every 45ms while looking for packets */ if (time > (lastHopTime + 45)) { hopchan = (hopchan + 1) % D8_NUM_HOP_CHANNELS; /* TODO: allow TXing while in failsafe. maybe? */ frsky_state = FRSKY_RX1; lastHopTime = HAL_GetTick(); frsky_rx_toggle_ant(); rx_state = STATE_WILL_RX; } break; /* end STATE_SEARCH */ } break; /* end STATE_RXING */ case STATE_RXD: /* lastPktTime and lastHopTime are both updated with the current time. */ /* nextPktTime is updated to reflect the next anticipated packet, in 9 or 18ms. */ lastPktTime = time; lastHopTime = time; hopchan = (rxmsg.packet[3] + 1) % D8_NUM_HOP_CHANNELS; frsky_state = (rxmsg.packet[3] + 1) % NUM_FRSKY_STATES; // sets up the next state fail_state = STATE_RUNNING; failsafeStatus = 0; HAL_GPIO_WritePin(LED_RED_GPIO, LED_RED_PIN, LED_RED_STATE_OFF); HAL_GPIO_WritePin(LED_GREEN_GPIO, LED_GREEN_PIN, LED_GREEN_STATE_ON); frsky_rx_toggle_ant(); frsky_rx_process_channels(); /* Read and process rssi. Do this after channels! */ rssi = CC2500_ReadReg(CC2500_REG_RSSI); // rssidbm = frsky_getrssidbm(rssi); if(rssichan != -1) { /* turn 0-255 into 988-2012 */ channelValues[rssichan] = ((uint16_t)rssi * 4) + 988; // TODO: fix ranges } /* read frequency drift estimation and write this value back to the cc2500 offset register. */ freqoff_est = CC2500_ReadReg(CC2500_REG_FREQEST); CC2500_WriteReg(CC2500_REG_FSCTRL0, freqoff_est); /* nextPktTime is the expected time of the next incoming packet * it is either 9ms or 18ms depending on if there is telem txing this cycle. */ if (frsky_state == FRSKY_TX_TELEM) { nextPktTime = lastPktTime + 18; rx_state = STATE_PREPARE_TX; } else { nextPktTime = lastPktTime + 9; rx_state = STATE_WILL_RX; } if (gotFirstPkt == 0) gotFirstPkt = 1; break; /* end STATE_RXD */ case STATE_PREPARE_TX: frsky2way_d8_build_telem_packet(); frsky_set_hopchan(hopchan); txStartTime = lastHopTime + 2; // set up time to activate txing. lastHopTime = lastHopTime + 9; // not actually lasthoptime, but keeps 9ms interval for simplicity. rx_state = STATE_WILL_TX; break; /* end STATE_PREPARE_TX */ case STATE_WILL_TX: /* TODO: disable-able telem txing in config. why? cuz. */ if (time > txStartTime) { CC2500_WriteTXData(txmsg.packet, txmsg.packet[0]+1); rx_state = STATE_TXING; } break; /* end STATE_WILL_TX */ case STATE_TXING: if (time > (txStartTime + 8)) // need to give enough time to tx entire packet. rx_state = STATE_TXD; break; /* end STATE_TXING */ case STATE_TXD: hopchan = (hopchan + 1) % D8_NUM_HOP_CHANNELS; frsky_state = FRSKY_RX1; rx_state = STATE_WILL_RX; break; /* end STATE_TXD */ default: rx_state = STATE_SEARCH; break; } /* end rx_state switch statement */ /* stuff to do once after first packet RXd, is there anything? TODO: */ if (gotFirstPkt == 1) { gotFirstPkt = 2; } /* detect and handle failsafe condition */ if ((gotFirstPkt >= 1) & ((time - lastPktTime) > m_config.failsafeDelay) & (failsafeStatus == 0)) { failsafeStatus = 1; uint8_t failtype; if (m_config.failsafeType == FAILSAFE_AUTODETECT) { if (m_config.failsafeValues[0] == 0) // failsafe values have not been set. failtype = FAILSAFE_STOPOUTPUT; else failtype = FAILSAFE_SAVEDVALUES; } else { failtype = m_config.failsafeType; } switch (failtype) { default: case FAILSAFE_STOPOUTPUT: output_handle_functions.outputStop(); break; case FAILSAFE_SAVEDVALUES: for (uint8_t i = 0; i < MAX_CHANNEL_OUTPUTS; i++) { channelValues[i] = m_config.failsafeValues[i]; } if(rssichan != -1) { channelValues[rssichan] = 988; // TODO: fix ranges } output_handle_functions.outputUpdate(); break; } } /* failsafe button handler */ /* we have a packet, we're not in failsafe, and we haven't already set failsafes this btnpress. */ if ((gotFirstPkt >= 1) & (failsafeStatus == 0) & (failsafeBtnSettingStatus == 0)) { if ((HAL_GPIO_ReadPin(BIND_FAIL_BUTTON_GPIO, BIND_FAIL_BUTTON_PIN) == GPIO_PIN_RESET) & (failsafeBtnTime == 0)) // pin is NO and pulled high { failsafeBtnTime = time; } else if ((HAL_GPIO_ReadPin(BIND_FAIL_BUTTON_GPIO, BIND_FAIL_BUTTON_PIN) == GPIO_PIN_RESET) & ((time - failsafeBtnTime) > 2000)) { HAL_GPIO_WritePin(LED_RED_GPIO, LED_RED_PIN, LED_RED_STATE_ON); failsafeBtnSettingStatus = 1; for (uint8_t i = 0; i < MAX_CHANNEL_OUTPUTS; i++) { m_config.failsafeValues[i] = channelValues[i]; } eeprom_write(); HAL_Delay(1000); HAL_GPIO_WritePin(LED_RED_GPIO, LED_RED_PIN, LED_RED_STATE_OFF); } } /* Reset failsafe button timer if button is released */ if (HAL_GPIO_ReadPin(BIND_FAIL_BUTTON_GPIO, BIND_FAIL_BUTTON_PIN) == GPIO_PIN_SET) { failsafeBtnTime = 0; failsafeBtnSettingStatus = 0; } }
void CC2500_RfSettings(void) { #if 1 CC2500_WriteReg(CCxxx0_FSCTRL1, 0x09); // 0x0c CC2500_WriteReg(CCxxx0_FSCTRL0, 0x00); CC2500_WriteReg(CCxxx0_FREQ2, 0x5D); CC2500_WriteReg(CCxxx0_FREQ1, 0x93); CC2500_WriteReg(CCxxx0_FREQ0, 0xB1); #ifdef _10k CC2500_WriteReg(CCxxx0_MDMCFG4, 0x78); //0x78-10k 0x86 CC2500_WriteReg(CCxxx0_MDMCFG3, 0x93); //0x93-10k 0x83 // CC2500_WriteReg(CCxxx0_MDMCFG2, 0x70); CC2500_WriteReg(CCxxx0_MDMCFG2, 0x03); //0x03-10k 0x03 CC2500_WriteReg(CCxxx0_MDMCFG1, 0x22); //0x22-10k CC2500_WriteReg(CCxxx0_MDMCFG0, 0xF8); //0xf8 0xf8 #else CC2500_WriteReg(CCxxx0_MDMCFG4, 0x2D); //0x78-10k 0x86 CC2500_WriteReg(CCxxx0_MDMCFG3, 0x3B); //0x93-10k 0x83 // CC2500_WriteReg(CCxxx0_MDMCFG2, 0x70); CC2500_WriteReg(CCxxx0_MDMCFG2, 0x73); //0x03-10k 0x03 CC2500_WriteReg(CCxxx0_MDMCFG1, 0xA2); //0x22-100 0x22 CC2500_WriteReg(CCxxx0_MDMCFG0, 0xF8); //0xf8 0xf8 #endif CC2500_WriteReg(CCxxx0_CHANNR, 0x00); CC2500_WriteReg(CCxxx0_DEVIATN, 0x01); //0x44 CC2500_WriteReg(CCxxx0_FREND1, 0x56); //0xB6 56错误机率减少 CC2500_WriteReg(CCxxx0_FREND0, 0x10); CC2500_WriteReg(CCxxx0_MCSM1, 0x00); // 0X00>NO CCA; 0X30>CCA ????? CC2500_WriteReg(CCxxx0_MCSM0, 0x18); CC2500_WriteReg(CCxxx0_FOCCFG, 0x15); // 0x1D 频率偏移补偿 CC2500_WriteReg(CCxxx0_BSCFG, 0x6C); // 0x1c 位同步配置 CC2500_WriteReg(CCxxx0_AGCCTRL2, 0x07); // 0xc3 增益控制 CC2500_WriteReg(CCxxx0_AGCCTRL1, 0x00); // cca=0x10 CC2500_WriteReg(CCxxx0_AGCCTRL0, 0x91); // 0xb2 CC2500_WriteReg(CCxxx0_FSCAL3, 0xEA); CC2500_WriteReg(CCxxx0_FSCAL2, 0x0A); //0x0a - 250k 0x06 --10k,0x08-2.4k CC2500_WriteReg(CCxxx0_FSCAL1, 0x00); // 增加频率同步校准 CC2500_WriteReg(CCxxx0_FSCAL0, 0x11); CC2500_WriteReg(CCxxx0_FSTEST, 0x59); CC2500_WriteReg(CCxxx0_TEST2, 0x8F); // 0x88 CC2500_WriteReg(CCxxx0_TEST1, 0x21); // 0x31 CC2500_WriteReg(CCxxx0_TEST0, 0x0B); CC2500_WriteReg(CCxxx0_IOCFG2, 0x06); //29// CCA=0x09:1=free ?????? CC2500_WriteReg(CCxxx0_IOCFG0, 0x06); // ????? CC2500_WriteReg(CCxxx0_PKTCTRL1, 0x00); //无地址检查 // ?????? CC2500_WriteReg(CCxxx0_PKTCTRL0, 0x04); //0x41 whiter+val CC2500_WriteReg(CCxxx0_ADDR, 0x00); CC2500_WriteReg(CCxxx0_PKTLEN, PACKET_LEN);// ?????? // CC2500_ReadReg(CCxxx0_MDMCFG1); #else CC2500_WriteReg(CCxxx0_IOCFG2,0x0B);//0x0B, // IOCFG2 GDO2 output pin configuration. CC2500_WriteReg(CCxxx0_IOCFG1,0x06); //IOCFG1 CC2500_WriteReg(CCxxx0_IOCFG0,0x06); // IOCFG0 GDO0 output pin configuration. CC2500_WriteReg(CCxxx0_FIFOTHR,0x07); //FIFOTHR CC2500_WriteReg(CCxxx0_SYNC1,0xD3); //SYNC1 MSB CC2500_WriteReg(CCxxx0_SYNC0,0x91); //SYNC0 LSB CC2500_WriteReg(CCxxx0_PKTLEN,64); // PKTLEN Packet length. CC2500_WriteReg(CCxxx0_PKTCTRL1,0x02); // PKTCTRL1 Packet automation control. CC2500_WriteReg(CCxxx0_PKTCTRL0,0x05); // PKTCTRL0 Packet automation control. CC2500_WriteReg(CCxxx0_ADDR,0x01); // ADDR Device address. CC2500_WriteReg(CCxxx0_CHANNR,0x00); // CHANNR Channel number. CC2500_WriteReg(CCxxx0_FSCTRL1,0x07); // FSCTRL1 Frequency synthesizer control. CC2500_WriteReg(CCxxx0_FSCTRL0,0x00); // FSCTRL0 Frequency synthesizer control. CC2500_WriteReg(CCxxx0_FREQ2,0x5D); // FREQ2 Frequency control word, high u8. CC2500_WriteReg(CCxxx0_FREQ1,0x93); // FREQ1 Frequency control word, middle u8. CC2500_WriteReg(CCxxx0_FREQ0,0xB1); // FREQ0 Frequency control word, low u8. CC2500_WriteReg(CCxxx0_MDMCFG4,0x2D); // MDMCFG4 Modem configuration. CC2500_WriteReg(CCxxx0_MDMCFG3,0x3B); // MDMCFG3 Modem configuration. CC2500_WriteReg(CCxxx0_MDMCFG2,0x73); // MDMCFG2 Modem configuration. CC2500_WriteReg(CCxxx0_MDMCFG1,0x22); // MDMCFG1 Modem configuration. CC2500_WriteReg(CCxxx0_MDMCFG0,0xF8); // MDMCFG0 Modem configuration. CC2500_WriteReg(CCxxx0_DEVIATN,0x47); // DEVIATN Modem deviation setting (when FSK modulation is enabled). CC2500_WriteReg(CCxxx0_MCSM2,0x00); // MCSM2 Main Radio Control State Machine configuration. CC2500_WriteReg(CCxxx0_MCSM1,0x02); // MCSM1 Main Radio Control State Machine configuration. CC2500_WriteReg(CCxxx0_MCSM0,0x18); // MCSM0 Main Radio Control State Machine configuration. CC2500_WriteReg(CCxxx0_FOCCFG,0x1D); // FOCCFG Frequency Offset Compensation Configuration. CC2500_WriteReg(CCxxx0_BSCFG,0x1C); // BSCFG Bit synchronization Configuration. CC2500_WriteReg(CCxxx0_AGCCTRL2,0xC7); // AGCCTRL2 AGC control. CC2500_WriteReg(CCxxx0_AGCCTRL1,0x00); // AGCCTRL1 AGC control. CC2500_WriteReg(CCxxx0_AGCCTRL0,0xB2); // AGCCTRL0 AGC control. CC2500_WriteReg(CCxxx0_WOREVT1,0x00); // WOREVT1 CC2500_WriteReg(CCxxx0_WOREVT0,0x00); // WOREVT0 CC2500_WriteReg(CCxxx0_WORCTRL,0x00); // WORCTRL CC2500_WriteReg(CCxxx0_FREND1,0xB6); // FREND1 Front end RX configuration. CC2500_WriteReg(CCxxx0_FREND0,0x10); // FREND0 Front end RX configuration. CC2500_WriteReg(CCxxx0_FSCAL3,0xEA); // FSCAL3 Frequency synthesizer calibration. CC2500_WriteReg(CCxxx0_FSCAL2,0x0A); // FSCAL2 Frequency synthesizer calibration. CC2500_WriteReg(CCxxx0_FSCAL1,0x00); // FSCAL1 Frequency synthesizer calibration. CC2500_WriteReg(CCxxx0_FSCAL0,0x11); // FSCAL0 Frequency synthesizer calibration. CC2500_WriteReg(CCxxx0_RCCTRL1,0x00); //RCCTRL1 CC2500_WriteReg(CCxxx0_RCCTRL0,0x00); //RCCTRL0 CC2500_WriteReg(CCxxx0_FSTEST,0x59); // FSTEST Frequency synthesizer calibration. CC2500_WriteReg(CCxxx0_PTEST,0x00); //PTEST //CC2500_WriteReg(CCxxx0_AGCTEST,0x00); //AGCTEST //CC2500_WriteReg(CCxxx0_TEST2,0x88); // TEST2 Various test settings. //CC2500_WriteReg(CCxxx0_TEST1,0x31); // TEST1 Various test settings. //CC2500_WriteReg(CCxxx0_TEST0,0x0B); // TEST0 Various test settings. #endif //for(i=0;i<=CCxxx0_TEST0;i++) //Debug("0x%x:0x%x\n\r",i,CC2500_ReadReg(i)); }