static uint16_t esky150_init() { uint8_t rx_addr[ADDR_SIZE] = { 0x73, 0x73, 0x74, 0x63 }; uint8_t tx_addr[ADDR_SIZE] = { 0x71, 0x0A, 0x31, 0xF4 }; NRF24L01_Initialize(); NRF24L01_WriteReg(NRF24L01_00_CONFIG, CRC_CONFIG); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, ADDR_SIZE-2); // 4-byte RX/TX address NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0); // Disable retransmit NRF24L01_SetPower(Model.tx_power); NRF24L01_SetBitrate(NRF24L01_BR_2M); NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_addr, ADDR_SIZE); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, tx_addr, ADDR_SIZE); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, PAYLOADSIZE); // bytes of data payload for pipe 0 NRF24L01_Activate(0x73); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0 // Enable: Dynamic Payload Length, Payload with ACK , W_TX_PAYLOAD_NOACK NRF24L01_WriteReg(NRF24L01_1D_FEATURE, BV(NRF2401_1D_EN_DPL) | BV(NRF2401_1D_EN_ACK_PAY) | BV(NRF2401_1D_EN_DYN_ACK)); // Check for Beken BK2421/BK2423 chip // It is done by using Beken specific activate code, 0x53 // and checking that status register changed appropriately // There is no harm to run it on nRF24L01 because following // closing activate command changes state back even if it // does something on nRF24L01 NRF24L01_Activate(0x53); // magic for BK2421 bank switch printf("Trying to switch banks\n"); if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & 0x80) { printf("BK2421 detected\n"); // long nul = 0; // Beken registers don't have such nice names, so we just mention // them by their numbers // It's all magic, eavesdropped from real transfer and not even from the // data sheet - it has slightly different values NRF24L01_WriteRegisterMulti(0x00, (uint8_t *) "\x40\x4B\x01\xE2", 4); NRF24L01_WriteRegisterMulti(0x01, (uint8_t *) "\xC0\x4B\x00\x00", 4); NRF24L01_WriteRegisterMulti(0x02, (uint8_t *) "\xD0\xFC\x8C\x02", 4); NRF24L01_WriteRegisterMulti(0x03, (uint8_t *) "\xF9\x00\x39\x21", 4); NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xC1\x96\x9A\x1B", 4); NRF24L01_WriteRegisterMulti(0x05, (uint8_t *) "\x24\x06\x7F\xA6", 4); NRF24L01_WriteRegisterMulti(0x0C, (uint8_t *) "\x00\x12\x73\x00", 4); NRF24L01_WriteRegisterMulti(0x0D, (uint8_t *) "\x46\xB4\x80\x00", 4); NRF24L01_WriteRegisterMulti(0x0E, (uint8_t *) "\x41\x10\x04\x82\x20\x08\x08\xF2\x7D\xEF\xFF", 11); NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xC7\x96\x9A\x1B", 4); NRF24L01_WriteRegisterMulti(0x04, (uint8_t *) "\xC1\x96\x9A\x1B", 4); } else { printf("nRF24L01 detected\n"); } NRF24L01_Activate(0x53); // switch bank back // Delay 50 ms return 50000u; }
static void esky_init(u8 bind) { NRF24L01_Initialize(); // 2-bytes CRC, radio off NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 if (bind) { set_bind_address(); } else { set_data_address(); } NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0); // No auto retransmission NRF24L01_WriteReg(NRF24L01_05_RF_CH, 50); // Channel 50 for bind packets NRF24L01_SetBitrate(0); // 1Mbps NRF24L01_SetPower(Model.tx_power); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit // NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00); // no write bits in this field // NRF24L01_WriteReg(NRF24L01_00_CD, 0x00); // same // NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address // NRF24L01_WriteReg(NRF24L01_0D_RX_ADDR_P3, 0xC4); // NRF24L01_WriteReg(NRF24L01_0E_RX_ADDR_P4, 0xC5); // NRF24L01_WriteReg(NRF24L01_0F_RX_ADDR_P5, 0xC6); NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, PAYLOADSIZE); // bytes of data payload for pipe 0 NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here }
void send_packet() { u32 temp; for(u8 ch=0;ch<8;ch++) { temp=((s32)Channels[ch] * 0x1f1 / CHAN_MAX_VALUE + 0x5d9)<<3; packet[2*ch]=temp>>8; packet[2*ch+1]=temp; } for(u8 i=0; i<ADDRESS_LENGTH; i++) packet[16+i]=packet[23-i]; NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_FlushTx(); NRF24L01_WritePayload(packet, PACKET_SIZE); // Check and adjust transmission power. We do this after // transmission to not bother with timeout after power // settings change - we have plenty of time until next // packet. if (tx_power != Model.tx_power) { //Keep transmit power updated tx_power = Model.tx_power; NRF24L01_SetPower(tx_power); } }
static int cflie_init() { NRF24L01_Initialize(); // CRC, radio on NRF24L01_SetTxRxMode(TX_EN); NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); // Auto Acknowledgement for data pipe 0 NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, TX_ADDR_SIZE-2); // 5-byte RX/TX address NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x13); // 3 retransmits, 500us delay NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channel); // Defined by model id NRF24L01_SetBitrate(data_rate); // Defined by model id NRF24L01_SetPower(Model.tx_power); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, TX_ADDR_SIZE); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, TX_ADDR_SIZE); // this sequence necessary for module from stock tx NRF24L01_ReadReg(NRF24L01_1D_FEATURE); NRF24L01_Activate(0x73); // Activate feature register NRF24L01_ReadReg(NRF24L01_1D_FEATURE); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x01); // Enable Dynamic Payload Length on pipe 0 NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x06); // Enable Dynamic Payload Length, enable Payload with ACK // 50ms delay in callback return 50000; }
void initrx(void) { NRF24L01_Initialize(); reset_beken(); // 2-bytes CRC, radio off uint8_t config = BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PRIM_RX); NRF24L01_WriteReg(NRF24L01_00_CONFIG, config); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xFF); // 4ms retransmit t/o, 15 tries // NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x08); // Channel 8 - bind //NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps NRF24L01_SetBitrate(NRF24L01_BR_250K); //250k for longer range. NRF24L01_SetPower(TXPOWER_100mW); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, V2X2_PAYLOAD_SIZE); // bytes of data payload for pipe 0 NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here uint8_t rx_tx_addr[] = {0x66, 0x88, 0x68, 0x68, 0x68}; // uint8_t rx_p1_addr[] = {0x88, 0x66, 0x86, 0x86, 0x86}; NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5); // NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, rx_p1_addr, 5); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5); initialize_beken(); lib_timers_delaymilliseconds(50); NRF24L01_FlushTx(); NRF24L01_FlushRx(); rf_ch_num = 0; // Turn radio power on config |= BV(NRF24L01_00_PWR_UP); NRF24L01_WriteReg(NRF24L01_00_CONFIG, config); // delayMicroseconds(150); lib_timers_delaymilliseconds(1); // 6 times more than needed valid_packets = missed_packets = bad_packets = 0; if (usersettings.boundprotocol == PROTO_NONE) { bind_phase = PHASE_NOT_BOUND; prepare_to_bind(); } else { // Prepare to listen to bound protocol, if fails // try to bind bind_phase = PHASE_JUST_BOUND; set_bound(); } switch_channel(); }
void init() { NRF24L01_Initialize(); NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4 bytes rx/tx address NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (u8 *)"\x80\x80\x80\xB8", ADDRESS_LENGTH); // Bind address NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (u8 *)"\x80\x80\x80\xB8", ADDRESS_LENGTH); // Bind address NRF24L01_FlushTx(); NRF24L01_FlushRx(); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, PACKET_SIZE); NRF24L01_SetPower(Model.tx_power); }
static void DM002_init() { NRF24L01_Initialize(); NRF24L01_SetTxRxMode(TX_EN); XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", DM002_ADDRESS_SIZE); NRF24L01_FlushTx(); NRF24L01_FlushRx(); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps NRF24L01_SetPower(Model.tx_power); // Check for Beken BK2421/BK2423 chip // It is done by using Beken specific activate code, 0x53 // and checking that status register changed appropriately // There is no harm to run it on nRF24L01 because following // closing activate command changes state back even if it // does something on nRF24L01 NRF24L01_Activate(0x53); // magic for BK2421 bank switch dbgprintf("Trying to switch banks\n"); if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & 0x80) { dbgprintf("BK2421 detected\n"); // Beken registers don't have such nice names, so we just mention // them by their numbers // It's all magic, eavesdropped from real transfer and not even from the // data sheet - it has slightly different values NRF24L01_WriteRegisterMulti(0x00, (u8 *) "\x40\x4B\x01\xE2", 4); NRF24L01_WriteRegisterMulti(0x01, (u8 *) "\xC0\x4B\x00\x00", 4); NRF24L01_WriteRegisterMulti(0x02, (u8 *) "\xD0\xFC\x8C\x02", 4); NRF24L01_WriteRegisterMulti(0x03, (u8 *) "\x99\x00\x39\x21", 4); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xD9\x96\x82\x1B", 4); NRF24L01_WriteRegisterMulti(0x05, (u8 *) "\x24\x06\x7F\xA6", 4); NRF24L01_WriteRegisterMulti(0x0C, (u8 *) "\x00\x12\x73\x00", 4); NRF24L01_WriteRegisterMulti(0x0D, (u8 *) "\x46\xB4\x80\x00", 4); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xDF\x96\x82\x1B", 4); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xD9\x96\x82\x1B", 4); } else { dbgprintf("nRF24L01 detected\n"); } NRF24L01_Activate(0x53); // switch bank back }
// Helper for sending a packet // Assumes packet data has been put in tx_packet // and tx_payload_len has been set correctly static void send_packet() { // clear packet status bits and Tx/Rx FIFOs NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))); NRF24L01_FlushTx(); NRF24L01_FlushRx(); // Transmit the payload NRF24L01_WritePayload(tx_packet, tx_payload_len); ++packet_counter; // Check and adjust transmission power. We do this after // transmission to not bother with timeout after power // settings change - we have plenty of time until next // packet. if (tx_power != Model.tx_power) { //Keep transmit power updated tx_power = Model.tx_power; NRF24L01_SetPower(tx_power); } }
static void send_packet(u8 bind) { union { u16 value; struct { u8 lsb; u8 msb; } bytes; } chanval; if (bind) { if (telemetry) packet[0] = 0xa3; else packet[0] = 0xa4; memcpy(&packet[1], rx_tx_addr, 5); memcpy(&packet[6], rf_channels, 4); switch (Model.proto_opts[PROTOOPTS_FORMAT]) { case FORMAT_REGULAR: packet[10] = txid[0]; packet[11] = txid[1]; break; case FORMAT_X16_AH: packet[10] = 0x00; packet[11] = 0x00; break; case FORMAT_IRDRONE: packet[10] = 0x30; packet[11] = 0x01; break; } } else { switch (Model.proto_opts[PROTOOPTS_FORMAT]) { case FORMAT_REGULAR: packet[0] = 0xa5; break; case FORMAT_X16_AH: case FORMAT_IRDRONE: packet[0] = 0xa6; break; } packet[1] = 0xfa; // normal mode is 0xf7, expert 0xfa packet[2] = GET_FLAG(CHANNEL_FLIP, 0x08) | GET_FLAG(CHANNEL_HEADLESS, 0x02) | GET_FLAG(CHANNEL_RTH, 0x01) | GET_FLAG(CHANNEL_VIDEO, 0x10) | GET_FLAG(CHANNEL_PICTURE, 0x20); packet[3] = GET_FLAG(CHANNEL_INVERTED, 0x80) | GET_FLAG(CHANNEL_TO, 0x20) | GET_FLAG(CHANNEL_EMGSTOP, 0x04); chanval.value = scale_channel(CHANNEL1, 0x3ff, 0); // aileron packet[4] = chanval.bytes.msb + DYNTRIM(chanval.value); packet[5] = chanval.bytes.lsb; chanval.value = scale_channel(CHANNEL2, 0, 0x3ff); // elevator packet[6] = chanval.bytes.msb + DYNTRIM(chanval.value); packet[7] = chanval.bytes.lsb; chanval.value = scale_channel(CHANNEL3, 0, 0x3ff); // throttle packet[8] = chanval.bytes.msb + 0x7c; packet[9] = chanval.bytes.lsb; chanval.value = scale_channel(CHANNEL4, 0x3ff, 0); // rudder packet[10] = chanval.bytes.msb + DYNTRIM(chanval.value); packet[11] = chanval.bytes.lsb; } switch (Model.proto_opts[PROTOOPTS_FORMAT]) { case FORMAT_REGULAR: packet[12] = txid[2]; packet[13] = 0x0a; break; case FORMAT_X16_AH: packet[12] = 0x00; packet[13] = 0x00; break; case FORMAT_IRDRONE: packet[12] = 0xe0; packet[13] = 0x2e; break; } packet[14] = checksum(); NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? bind_chan : rf_channels[rf_chan++]); rf_chan %= sizeof(rf_channels); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); XN297_WritePayload(packet, PACKET_SIZE); NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); // 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 (telemetry) { // switch radio to rx, no crc NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03); } // Check and adjust transmission power. We do this after // transmission to not bother with timeout after power // settings change - we have plenty of time until next // packet. if (tx_power != Model.tx_power) { //Keep transmit power updated tx_power = Model.tx_power; NRF24L01_SetPower(tx_power); } #ifdef EMULATOR dbgprintf("next chan 0x%02x, bind %d, data %02x", bind ? bind_chan : rf_channels[rf_chan], bind, packet[0]); for (int i = 1; i < PACKET_SIZE; i++) dbgprintf(" %02x", packet[i]); dbgprintf("\n"); #endif }
static int cflie_init() { NRF24L01_Initialize(); // CRC, radio on NRF24L01_SetTxRxMode(TX_EN); NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO) | BV(NRF24L01_00_PWR_UP)); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); // Auto Acknowledgement for data pipe 0 NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, TX_ADDR_SIZE-2); // 5-byte RX/TX address NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x13); // 3 retransmits, 500us delay NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_channel); // Defined by model id NRF24L01_SetBitrate(data_rate); // Defined by model id NRF24L01_SetPower(Model.tx_power); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, TX_ADDR_SIZE); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, TX_ADDR_SIZE); // this sequence necessary for module from stock tx NRF24L01_ReadReg(NRF24L01_1D_FEATURE); NRF24L01_Activate(0x73); // Activate feature register NRF24L01_ReadReg(NRF24L01_1D_FEATURE); NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x01); // Enable Dynamic Payload Length on pipe 0 NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x06); // Enable Dynamic Payload Length, enable Payload with ACK // Check for Beken BK2421/BK2423 chip // It is done by using Beken specific activate code, 0x53 // and checking that status register changed appropriately // There is no harm to run it on nRF24L01 because following // closing activate command changes state back even if it // does something on nRF24L01 NRF24L01_Activate(0x53); // magic for BK2421 bank switch dbgprintf("Trying to switch banks\n"); if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & 0x80) { dbgprintf("BK2421 detected\n"); long nul = 0; // Beken registers don't have such nice names, so we just mention // them by their numbers // It's all magic, eavesdropped from real transfer and not even from the // data sheet - it has slightly different values NRF24L01_WriteRegisterMulti(0x00, (u8 *) "\x40\x4B\x01\xE2", 4); NRF24L01_WriteRegisterMulti(0x01, (u8 *) "\xC0\x4B\x00\x00", 4); NRF24L01_WriteRegisterMulti(0x02, (u8 *) "\xD0\xFC\x8C\x02", 4); NRF24L01_WriteRegisterMulti(0x03, (u8 *) "\xF9\x00\x39\x21", 4); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xC1\x96\x9A\x1B", 4); NRF24L01_WriteRegisterMulti(0x05, (u8 *) "\x24\x06\x7F\xA6", 4); NRF24L01_WriteRegisterMulti(0x06, (u8 *) &nul, 4); NRF24L01_WriteRegisterMulti(0x07, (u8 *) &nul, 4); NRF24L01_WriteRegisterMulti(0x08, (u8 *) &nul, 4); NRF24L01_WriteRegisterMulti(0x09, (u8 *) &nul, 4); NRF24L01_WriteRegisterMulti(0x0A, (u8 *) &nul, 4); NRF24L01_WriteRegisterMulti(0x0B, (u8 *) &nul, 4); NRF24L01_WriteRegisterMulti(0x0C, (u8 *) "\x00\x12\x73\x00", 4); NRF24L01_WriteRegisterMulti(0x0D, (u8 *) "\x46\xB4\x80\x00", 4); NRF24L01_WriteRegisterMulti(0x0E, (u8 *) "\x41\x10\x04\x82\x20\x08\x08\xF2\x7D\xEF\xFF", 11); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xC7\x96\x9A\x1B", 4); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xC1\x96\x9A\x1B", 4); } else { dbgprintf("nRF24L01 detected\n"); } NRF24L01_Activate(0x53); // switch bank back // 50ms delay in callback return 50000; }
static void esky_init(u8 bind) { NRF24L01_Initialize(); // 2-bytes CRC, radio off NRF24L01_WriteReg(NRF24L01_00_CONFIG, BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)); NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 if (bind) { set_bind_address(); } else { set_data_address(); } NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0); // No auto retransmission NRF24L01_WriteReg(NRF24L01_05_RF_CH, 50); // Channel 50 for bind packets NRF24L01_SetBitrate(0); // 1Mbps NRF24L01_SetPower(Model.tx_power); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit // NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00); // no write bits in this field // NRF24L01_WriteReg(NRF24L01_00_CD, 0x00); // same // NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address // NRF24L01_WriteReg(NRF24L01_0D_RX_ADDR_P3, 0xC4); // NRF24L01_WriteReg(NRF24L01_0E_RX_ADDR_P4, 0xC5); // NRF24L01_WriteReg(NRF24L01_0F_RX_ADDR_P5, 0xC6); NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, PAYLOADSIZE); // bytes of data payload for pipe 0 NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, PAYLOADSIZE); NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here // Check for Beken BK2421/BK2423 chip // It is done by using Beken specific activate code, 0x53 // and checking that status register changed appropriately // There is no harm to run it on nRF24L01 because following // closing activate command changes state back even if it // does something on nRF24L01 NRF24L01_Activate(0x53); // magic for BK2421 bank switch printf("Trying to switch banks\n"); if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & 0x80) { printf("BK2421 detected\n"); // Beken registers don't have such nice names, so we just mention // them by their numbers // It's all magic, eavesdropped from real transfer and not even from the // data sheet - it has slightly different values NRF24L01_WriteRegisterMulti(0x00, (u8 *) "\x40\x4B\x01\xE2", 4); NRF24L01_WriteRegisterMulti(0x01, (u8 *) "\xC0\x4B\x00\x00", 4); NRF24L01_WriteRegisterMulti(0x02, (u8 *) "\xD0\xFC\x8C\x02", 4); NRF24L01_WriteRegisterMulti(0x03, (u8 *) "\xF9\x00\x39\x21", 4); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xC1\x96\x9A\x1B", 4); NRF24L01_WriteRegisterMulti(0x05, (u8 *) "\x24\x06\x7F\xA6", 4); NRF24L01_WriteRegisterMulti(0x0C, (u8 *) "\x00\x12\x73\x00", 4); NRF24L01_WriteRegisterMulti(0x0D, (u8 *) "\x46\xB4\x80\x00", 4); NRF24L01_WriteRegisterMulti(0x0E, (u8 *) "\x41\x10\x04\x82\x20\x08\x08\xF2\x7D\xEF\xFF", 11); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xC7\x96\x9A\x1B", 4); NRF24L01_WriteRegisterMulti(0x04, (u8 *) "\xC1\x96\x9A\x1B", 4); } else { printf("nRF24L01 detected\n"); } NRF24L01_Activate(0x53); // switch bank back // Implicit delay in callback // delay(50); }
static void DM002_send_packet(u8 bind) { memcpy(&packet[5],(uint8_t *)"\x00\x7F\x7F\x7F\x00\x00\x00",7); if(bind) { packet[0] = 0xAA; packet[1] = rx_tx_addr[0]; packet[2] = rx_tx_addr[1]; packet[3] = rx_tx_addr[2]; packet[4] = rx_tx_addr[3]; } else { packet[0]=0x55; // Throttle : 0 .. 200 packet[1]=scale_channel(CHANNEL3,0,200); // Other channels min 0x57, mid 0x7F, max 0xA7 packet[2] = scale_channel(CHANNEL4,0xA7,0x57); // rudder packet[3] = scale_channel(CHANNEL1, 0xA7,0x57); // aileron packet[4] = scale_channel(CHANNEL2, 0xA7, 0x57); // elevator // Features packet[9] = DM002_FLAG_HIGH // high rate | GET_FLAG(CHANNEL_FLIP, DM002_FLAG_FLIP) | GET_FLAG_INV(CHANNEL_LED, DM002_FLAG_LED) | GET_FLAG(CHANNEL_CAMERA1, DM002_FLAG_CAMERA1) | GET_FLAG(CHANNEL_CAMERA2, DM002_FLAG_CAMERA2) | GET_FLAG(CHANNEL_HEADLESS,DM002_FLAG_HEADLESS) | GET_FLAG(CHANNEL_RTH, DM002_FLAG_RTH); // Packet counter if(packet_count&0x03) { packet_count++; hopping_frequency_no++; hopping_frequency_no&=4; } packet_count&=0x0F; packet[10] = packet_count; packet_count++; } //CRC for(uint8_t i=0;i<DM002_PACKET_SIZE-1;i++) packet[11]+=packet[i]; // 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, DM002_RF_BIND_CHANNEL); else NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); // clear packet status bits and TX FIFO NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); XN297_WritePayload(packet, DM002_PACKET_SIZE); if (tx_power != Model.tx_power) { //Keep transmit power updated tx_power = Model.tx_power; NRF24L01_SetPower(tx_power); } }