static void initGetBind(void) { cc2500Strobe(CC2500_SIDLE); cc2500WriteReg(CC2500_23_FSCAL3, calData[0][0]); cc2500WriteReg(CC2500_24_FSCAL2, calData[0][1]); cc2500WriteReg(CC2500_25_FSCAL1, calData[0][2]); cc2500WriteReg(CC2500_0A_CHANNR, 0); cc2500Strobe(CC2500_SFRX); delayMicroseconds(20); // waiting flush FIFO cc2500Strobe(CC2500_SRX); listLength = 0; bindIdx = 0x05; }
static void initTuneRx(void) { cc2500WriteReg(CC2500_19_FOCCFG, 0x14); timeTunedMs = millis(); bindOffset = -126; cc2500WriteReg(CC2500_0C_FSCTRL0, (uint8_t)bindOffset); cc2500WriteReg(CC2500_07_PKTCTRL1, 0x0C); cc2500WriteReg(CC2500_18_MCSM0, 0x8); cc2500Strobe(CC2500_SIDLE); cc2500WriteReg(CC2500_23_FSCAL3, calData[0][0]); cc2500WriteReg(CC2500_24_FSCAL2, calData[0][1]); cc2500WriteReg(CC2500_25_FSCAL1, calData[0][2]); cc2500WriteReg(CC2500_0A_CHANNR, 0); cc2500Strobe(CC2500_SFRX); cc2500Strobe(CC2500_SRX); }
void nextChannel(uint8_t skip) { static uint8_t channr = 0; channr += skip; while (channr >= listLength) { channr -= listLength; } cc2500Strobe(CC2500_SIDLE); cc2500WriteReg(CC2500_23_FSCAL3, calData[rxCc2500SpiConfig()->bindHopData[channr]][0]); cc2500WriteReg(CC2500_24_FSCAL2, calData[rxCc2500SpiConfig()->bindHopData[channr]][1]); cc2500WriteReg(CC2500_25_FSCAL1, calData[rxCc2500SpiConfig()->bindHopData[channr]][2]); cc2500WriteReg(CC2500_0A_CHANNR, rxCc2500SpiConfig()->bindHopData[channr]); if (spiProtocol == RX_SPI_FRSKY_D) { cc2500Strobe(CC2500_SFRX); } }
rx_spi_received_e frSkyDHandlePacket(uint8_t * const packet, uint8_t * const protocolState) { static timeUs_t lastPacketReceivedTime = 0; static timeUs_t telemetryTimeUs; rx_spi_received_e ret = RX_SPI_RECEIVED_NONE; const timeUs_t currentPacketReceivedTime = micros(); switch (*protocolState) { case STATE_STARTING: listLength = 47; initialiseData(0); *protocolState = STATE_UPDATE; nextChannel(1); cc2500Strobe(CC2500_SRX); break; case STATE_UPDATE: lastPacketReceivedTime = currentPacketReceivedTime; *protocolState = STATE_DATA; if (rxSpiCheckBindRequested(false)) { lastPacketReceivedTime = 0; timeoutUs = 50; missingPackets = 0; *protocolState = STATE_INIT; break; } FALLTHROUGH; //!!TODO -check this fall through is correct // here FS code could be case STATE_DATA: if (cc2500getGdo()) { uint8_t ccLen = cc2500ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F; if (ccLen >= 20) { cc2500ReadFifo(packet, 20); if (packet[19] & 0x80) { missingPackets = 0; timeoutUs = 1; if (packet[0] == 0x11) { if ((packet[1] == rxFrSkySpiConfig()->bindTxId[0]) && (packet[2] == rxFrSkySpiConfig()->bindTxId[1])) { rxSpiLedOn(); nextChannel(1); cc2500setRssiDbm(packet[18]); #if defined(USE_RX_FRSKY_SPI_TELEMETRY) if ((packet[3] % 4) == 2) { telemetryTimeUs = micros(); buildTelemetryFrame(packet); *protocolState = STATE_TELEMETRY; } else #endif { cc2500Strobe(CC2500_SRX); *protocolState = STATE_UPDATE; } ret = RX_SPI_RECEIVED_DATA; lastPacketReceivedTime = currentPacketReceivedTime; } } } } } if (cmpTimeUs(currentPacketReceivedTime, lastPacketReceivedTime) > (timeoutUs * SYNC_DELAY_MAX)) { #if defined(USE_RX_CC2500_SPI_PA_LNA) cc2500TxDisable(); #endif if (timeoutUs == 1) { #if defined(USE_RX_CC2500_SPI_PA_LNA) && defined(USE_RX_CC2500_SPI_DIVERSITY) // SE4311 chip if (missingPackets >= 2) { cc2500switchAntennae(); } #endif if (missingPackets > MAX_MISSING_PKT) { timeoutUs = 50; setRssiDirect(0, RSSI_SOURCE_RX_PROTOCOL); } missingPackets++; nextChannel(1); } else { rxSpiLedToggle(); setRssi(0, RSSI_SOURCE_RX_PROTOCOL); nextChannel(13); } cc2500Strobe(CC2500_SRX); *protocolState = STATE_UPDATE; } break; #if defined(USE_RX_FRSKY_SPI_TELEMETRY) case STATE_TELEMETRY: if (cmpTimeUs(micros(), telemetryTimeUs) >= 1380) { cc2500Strobe(CC2500_SIDLE); cc2500SetPower(6); cc2500Strobe(CC2500_SFRX); #if defined(USE_RX_CC2500_SPI_PA_LNA) cc2500TxEnable(); #endif cc2500Strobe(CC2500_SIDLE); cc2500WriteFifo(frame, frame[0] + 1); *protocolState = STATE_DATA; ret = RX_SPI_RECEIVED_DATA; lastPacketReceivedTime = currentPacketReceivedTime; } break; #endif } return ret; }
static void initialise() { cc2500Reset(); cc2500WriteReg(CC2500_02_IOCFG0, 0x01); cc2500WriteReg(CC2500_18_MCSM0, 0x18); cc2500WriteReg(CC2500_07_PKTCTRL1, 0x04); cc2500WriteReg(CC2500_3E_PATABLE, 0xFF); cc2500WriteReg(CC2500_0C_FSCTRL0, 0x00); cc2500WriteReg(CC2500_0D_FREQ2, 0x5C); cc2500WriteReg(CC2500_13_MDMCFG1, 0x23); cc2500WriteReg(CC2500_14_MDMCFG0, 0x7A); cc2500WriteReg(CC2500_19_FOCCFG, 0x16); cc2500WriteReg(CC2500_1A_BSCFG, 0x6C); cc2500WriteReg(CC2500_1B_AGCCTRL2, 0x03); cc2500WriteReg(CC2500_1C_AGCCTRL1, 0x40); cc2500WriteReg(CC2500_1D_AGCCTRL0, 0x91); cc2500WriteReg(CC2500_21_FREND1, 0x56); cc2500WriteReg(CC2500_22_FREND0, 0x10); cc2500WriteReg(CC2500_23_FSCAL3, 0xA9); cc2500WriteReg(CC2500_24_FSCAL2, 0x0A); cc2500WriteReg(CC2500_25_FSCAL1, 0x00); cc2500WriteReg(CC2500_26_FSCAL0, 0x11); cc2500WriteReg(CC2500_29_FSTEST, 0x59); cc2500WriteReg(CC2500_2C_TEST2, 0x88); cc2500WriteReg(CC2500_2D_TEST1, 0x31); cc2500WriteReg(CC2500_2E_TEST0, 0x0B); cc2500WriteReg(CC2500_03_FIFOTHR, 0x07); cc2500WriteReg(CC2500_09_ADDR, 0x00); switch (spiProtocol) { case RX_SPI_FRSKY_D: cc2500WriteReg(CC2500_17_MCSM1, 0x0C); cc2500WriteReg(CC2500_0E_FREQ1, 0x76); cc2500WriteReg(CC2500_0F_FREQ0, 0x27); cc2500WriteReg(CC2500_06_PKTLEN, 0x19); cc2500WriteReg(CC2500_08_PKTCTRL0, 0x05); cc2500WriteReg(CC2500_0B_FSCTRL1, 0x08); cc2500WriteReg(CC2500_10_MDMCFG4, 0xAA); cc2500WriteReg(CC2500_11_MDMCFG3, 0x39); cc2500WriteReg(CC2500_12_MDMCFG2, 0x11); cc2500WriteReg(CC2500_15_DEVIATN, 0x42); break; case RX_SPI_FRSKY_X: cc2500WriteReg(CC2500_17_MCSM1, 0x0C); cc2500WriteReg(CC2500_0E_FREQ1, 0x76); cc2500WriteReg(CC2500_0F_FREQ0, 0x27); cc2500WriteReg(CC2500_06_PKTLEN, 0x1E); cc2500WriteReg(CC2500_08_PKTCTRL0, 0x01); cc2500WriteReg(CC2500_0B_FSCTRL1, 0x0A); cc2500WriteReg(CC2500_10_MDMCFG4, 0x7B); cc2500WriteReg(CC2500_11_MDMCFG3, 0x61); cc2500WriteReg(CC2500_12_MDMCFG2, 0x13); cc2500WriteReg(CC2500_15_DEVIATN, 0x51); break; case RX_SPI_FRSKY_X_LBT: cc2500WriteReg(CC2500_17_MCSM1, 0x0E); cc2500WriteReg(CC2500_0E_FREQ1, 0x80); cc2500WriteReg(CC2500_0F_FREQ0, 0x00); cc2500WriteReg(CC2500_06_PKTLEN, 0x23); cc2500WriteReg(CC2500_08_PKTCTRL0, 0x01); cc2500WriteReg(CC2500_0B_FSCTRL1, 0x08); cc2500WriteReg(CC2500_10_MDMCFG4, 0x7B); cc2500WriteReg(CC2500_11_MDMCFG3, 0xF8); cc2500WriteReg(CC2500_12_MDMCFG2, 0x03); cc2500WriteReg(CC2500_15_DEVIATN, 0x53); break; default: break; } for(unsigned c = 0;c < 0xFF; c++) { //calibrate all channels cc2500Strobe(CC2500_SIDLE); cc2500WriteReg(CC2500_0A_CHANNR, c); cc2500Strobe(CC2500_SCAL); delayMicroseconds(900); // calData[c][0] = cc2500ReadReg(CC2500_23_FSCAL3); calData[c][1] = cc2500ReadReg(CC2500_24_FSCAL2); calData[c][2] = cc2500ReadReg(CC2500_25_FSCAL1); } }
rx_spi_received_e frSkySpiDataReceived(uint8_t *packet) { rx_spi_received_e ret = RX_SPI_RECEIVED_NONE; switch (protocolState) { case STATE_INIT: if ((millis() - start_time) > 10) { initialise(); protocolState = STATE_BIND; } break; case STATE_BIND: if (rxSpiCheckBindRequested(true) || rxCc2500SpiConfig()->autoBind) { rxSpiLedOn(); initTuneRx(); protocolState = STATE_BIND_TUNING; } else { protocolState = STATE_STARTING; } break; case STATE_BIND_TUNING: if (tuneRx(packet)) { initGetBind(); initialiseData(1); protocolState = STATE_BIND_BINDING1; } break; case STATE_BIND_BINDING1: if (getBind1(packet)) { protocolState = STATE_BIND_BINDING2; } break; case STATE_BIND_BINDING2: if (getBind2(packet)) { cc2500Strobe(CC2500_SIDLE); protocolState = STATE_BIND_COMPLETE; } break; case STATE_BIND_COMPLETE: if (!rxCc2500SpiConfig()->autoBind) { writeEEPROM(); } else { uint8_t ctr = 80; while (ctr--) { rxSpiLedToggle(); delay(50); } } ret = RX_SPI_RECEIVED_BIND; protocolState = STATE_STARTING; break; default: ret = handlePacket(packet, &protocolState); break; } return ret; }