2 This project is free software: you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation, either version 3 of the License, or
5 (at your option) any later version.
7 Multiprotocol is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
16 #if defined(NCC1701_NRF24L01_INO)
18 #include "iface_nrf24l01.h"
20 #define NCC_WRITE_WAIT 2000
21 #define NCC_PACKET_INTERVAL 10333
22 #define NCC_TX_PACKET_LEN 16
23 #define NCC_RX_PACKET_LEN 13
34 static void __attribute__((unused)) NCC_RF_init()
36 NRF24L01_Initialize();
38 NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\xE7\xE7\xC7\xD7\x67",5);
39 NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\xE7\xE7\xC7\xD7\x67",5);
41 NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, NCC_RX_PACKET_LEN); // Enable rx pipe 0
42 NRF24L01_SetBitrate(NRF24L01_BR_250K); // NRF24L01_BR_1M, NRF24L01_BR_2M, NRF24L01_BR_250K
43 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to TX mode and disable CRC
44 | (1 << NRF24L01_00_CRCO)
45 | (1 << NRF24L01_00_PWR_UP)
46 | (0 << NRF24L01_00_PRIM_RX));
49 const uint8_t NCC_xor[]={0x80, 0x44, 0x64, 0x75, 0x6C, 0x71, 0x2A, 0x36, 0x7C, 0xF1, 0x6E, 0x52, 0x09, 0x9D};
50 static void __attribute__((unused)) NCC_Crypt_Packet()
53 for(uint8_t i=0; i< NCC_TX_PACKET_LEN-2; i++)
55 packet[i]^=NCC_xor[i];
56 crc16_update(packet[i], 8);
59 packet[NCC_TX_PACKET_LEN-2]=crc>>8;
60 packet[NCC_TX_PACKET_LEN-1]=crc;
62 static boolean __attribute__((unused)) NCC_Decrypt_Packet()
66 for(uint8_t i=0; i< NCC_RX_PACKET_LEN-2; i++)
68 crc16_update( packet[i], 8);
69 packet[i]^=NCC_xor[i];
70 debug("%02X ",packet[i]);
73 if( (crc>>8)==packet[NCC_RX_PACKET_LEN-2] && (crc&0xFF)==packet[NCC_RX_PACKET_LEN-1] )
82 static void __attribute__((unused)) NCC_Write_Packet()
85 packet[1]=rx_tx_addr[0];
86 packet[2]=rx_tx_addr[1];
89 packet[5]=convert_channel_8b(THROTTLE)>>2; // 00-3D
90 packet[6]=convert_channel_8b(ELEVATOR); // original: 61-80-9F but works with 00-80-FF
91 packet[7]=convert_channel_8b(AILERON ); // original: 61-80-9F but works with 00-80-FF
92 packet[8]=convert_channel_8b(RUDDER ); // original: 61-80-9F but works with 00-80-FF
96 packet[12]=GET_FLAG(CH5_SW, 0x02); // Warp:0x00 -> 0x02
97 packet[13]=packet[5]+packet[6]+packet[7]+packet[8]+packet[12];
98 if(phase==NCC_BIND_TX1)
102 packet[6]=rx_tx_addr[2];
103 memset((void *)(packet+7),0x55,7);
104 hopping_frequency_no^=1;
108 hopping_frequency_no++;
109 if(hopping_frequency_no>2) hopping_frequency_no=0;
112 NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
113 // switch to TX mode and disable CRC
114 NRF24L01_SetTxRxMode(TXRX_OFF);
115 NRF24L01_SetTxRxMode(TX_EN);
116 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC)
117 | (1 << NRF24L01_00_CRCO)
118 | (1 << NRF24L01_00_PWR_UP)
119 | (0 << NRF24L01_00_PRIM_RX));
120 // clear packet status bits and TX FIFO
121 NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
125 NRF24L01_WritePayload(packet,NCC_TX_PACKET_LEN);
129 uint16_t NCC_callback()
134 if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
135 { // RX fifo data ready
136 NRF24L01_ReadPayload(packet, NCC_RX_PACKET_LEN);
137 if(NCC_Decrypt_Packet() && packet[1]==rx_tx_addr[0] && packet[2]==rx_tx_addr[1])
142 NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
144 return NCC_PACKET_INTERVAL;
148 phase = NCC_BIND_RX1;
149 return NCC_WRITE_WAIT;
151 // switch to RX mode and disable CRC
152 NRF24L01_SetTxRxMode(TXRX_OFF);
153 NRF24L01_SetTxRxMode(RX_EN);
154 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC)
155 | (1 << NRF24L01_00_CRCO)
156 | (1 << NRF24L01_00_PWR_UP)
157 | (1 << NRF24L01_00_PRIM_RX));
159 phase = NCC_BIND_TX1;
160 return NCC_PACKET_INTERVAL - NCC_WRITE_WAIT;
162 if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
163 { // RX fifo data ready
164 NRF24L01_ReadPayload(packet, NCC_RX_PACKET_LEN);
165 if(NCC_Decrypt_Packet() && packet[1]==rx_tx_addr[0] && packet[2]==rx_tx_addr[1] && packet[3]==rx_id[0] && packet[4]==rx_id[1])
170 NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
173 return NCC_PACKET_INTERVAL;
177 phase = NCC_BIND_RX2;
178 return NCC_WRITE_WAIT;
180 // switch to RX mode and disable CRC
181 NRF24L01_SetTxRxMode(TXRX_OFF);
182 NRF24L01_SetTxRxMode(RX_EN);
183 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC)
184 | (1 << NRF24L01_00_CRCO)
185 | (1 << NRF24L01_00_PWR_UP)
186 | (1 << NRF24L01_00_PRIM_RX));
188 phase = NCC_BIND_TX2;
189 return NCC_PACKET_INTERVAL - NCC_WRITE_WAIT;
192 telemetry_set_input_sync(NCC_PACKET_INTERVAL);
194 if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
195 { // RX fifo data ready
196 NRF24L01_ReadPayload(packet, NCC_RX_PACKET_LEN);
197 if(NCC_Decrypt_Packet() && packet[1]==rx_tx_addr[0] && packet[2]==rx_tx_addr[1] && packet[3]==rx_id[0] && packet[4]==rx_id[1])
200 //packet[5] and packet[7] roll angle
201 //packet[6] crash detect: 0x00 no crash, 0x02 crash
202 #ifdef NCC1701_HUB_TELEMETRY
203 v_lipo1 = packet[6]?0xFF:0x00; // Crash indication
205 RX_RSSI = 0x7F; // Dummy RSSI
206 TX_RSSI = 0x7F; // Dummy RSSI
213 return NCC_WRITE_WAIT;
215 // switch to RX mode and disable CRC
216 NRF24L01_SetTxRxMode(TXRX_OFF);
217 NRF24L01_SetTxRxMode(RX_EN);
218 NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC)
219 | (1 << NRF24L01_00_CRCO)
220 | (1 << NRF24L01_00_PWR_UP)
221 | (1 << NRF24L01_00_PRIM_RX));
224 return NCC_PACKET_INTERVAL - NCC_WRITE_WAIT;
229 const uint8_t PROGMEM NCC_TX_DATA[][6]= {
230 { 0x6D, 0x97, 0x04, 0x48, 0x43, 0x26 },
231 { 0x35, 0x4B, 0x80, 0x44, 0x4C, 0x0B },
232 { 0x50, 0xE2, 0x32, 0x2D, 0x4B, 0x0A },
233 { 0xBF, 0x34, 0xF3, 0x45, 0x4D, 0x0D },
234 { 0xDD, 0x7D, 0x5A, 0x46, 0x28, 0x23 },
235 { 0xED, 0x19, 0x06, 0x2C, 0x4A, 0x09 },
236 { 0xE9, 0xA8, 0x91, 0x2B, 0x49, 0x07 },
237 { 0x66, 0x17, 0x7D, 0x48, 0x43, 0x26 },
238 { 0xC2, 0x93, 0x55, 0x44, 0x4C, 0x0B },
243 BIND_IN_PROGRESS; // autobind protocol
246 uint8_t rand=rx_tx_addr[3]%9;
247 for(uint8_t i=0; i<3; i++)
249 rx_tx_addr[i]=pgm_read_byte_near(&NCC_TX_DATA[rand][i]);
250 hopping_frequency[i]=pgm_read_byte_near(&NCC_TX_DATA[rand][i+3]);
253 // RX data is acquired during bind
260 hopping_frequency[4]=0x08; // bind channel 1
261 hopping_frequency[5]=0x2A; // bind channel 2
262 hopping_frequency_no=4; // start with bind