diff --git a/Multiprotocol/XN297Dump_nrf24l01.ino b/Multiprotocol/XN297Dump_nrf24l01.ino index 7c07918..81aca45 100644 --- a/Multiprotocol/XN297Dump_nrf24l01.ino +++ b/Multiprotocol/XN297Dump_nrf24l01.ino @@ -33,6 +33,10 @@ uint8_t address_length; uint16_t timeH=0; boolean scramble; +boolean enhanced; +boolean ack; +uint8_t pid; +uint8_t bitrate; static void __attribute__((unused)) XN297Dump_init() { @@ -48,14 +52,14 @@ static void __attribute__((unused)) XN297Dump_init() NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\x55\x0F\x71", 3); // set up RX address to xn297 preamble NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, XN297DUMP_MAX_PACKET_LEN); // Enable rx pipe 0 - debug("XN297 dump, address length=%d, speed=",address_length); - switch(sub_protocol) + debug("XN297 dump, address length=%d, bitrate=",address_length); + switch(bitrate) { - case 0: + case XN297DUMP_250K: NRF24L01_SetBitrate(NRF24L01_BR_250K); debugln("250K"); break; - case 2: + case XN297DUMP_2M: NRF24L01_SetBitrate(NRF24L01_BR_2M); debugln("2M"); break; @@ -76,6 +80,7 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void) { uint16_t crcxored; uint8_t packet_sc[XN297DUMP_MAX_PACKET_LEN], packet_un[XN297DUMP_MAX_PACKET_LEN]; + enhanced=false; // init crc crc = 0xb5d2; @@ -142,17 +147,17 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void) } if(packet_length!=0) { // Found a valid CRC for the enhanced payload mode - debug("Enhanced "); + enhanced=true; //check selected address length if((packet_un[address_length]>>1)!=packet_length-address_length) { for(uint8_t i=3;i<=5;i++) if((packet_un[i]>>1)==packet_length-i) address_length=i; - debug("Wrong address length selected using %d ", address_length ) + debugln("Detected wrong address length, using %d intead", address_length ); } - debug("pid=%d ",((packet_un[address_length]&0x01)<<1)|(packet_un[address_length+1]>>7)); - debug("ack=%d ",(packet_un[address_length+1]>>6)&0x01); + pid=((packet_un[address_length]&0x01)<<1)|(packet_un[address_length+1]>>7); + ack=(packet_un[address_length+1]>>6)&0x01; // address for (uint8_t i = 0; i < address_length; i++) packet[address_length-1-i]=packet_un[i]; @@ -175,96 +180,449 @@ static void __attribute__((unused)) XN297Dump_overflow() } static uint16_t XN297Dump_callback() { - static uint32_t time=0; + static uint32_t time=0,*time_rf; //!!!Blocking mode protocol!!! TX_MAIN_PAUSE_off; tx_resume(); while(1) { - if(option==0xFF && bind_counter>XN297DUMP_PERIOD_SCAN) - { // Scan frequencies - hopping_frequency_no++; - bind_counter=0; - } - if(hopping_frequency_no!=rf_ch_num) - { // Channel has changed - if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL) - hopping_frequency_no=0; // Invalid channel 0 by default - rf_ch_num=hopping_frequency_no; - debugln("Channel=%d,0x%02X",hopping_frequency_no,hopping_frequency_no) - NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no); - // switch to RX mode - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC - | (1 << NRF24L01_00_CRCO) - | (1 << NRF24L01_00_PWR_UP) - | (1 << NRF24L01_00_PRIM_RX)); - phase=0; // init timer - } - XN297Dump_overflow(); - - if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) - { // RX fifo data ready - if(NRF24L01_ReadReg(NRF24L01_09_CD) || option != 0xFF) - { - NRF24L01_ReadPayload(packet,XN297DUMP_MAX_PACKET_LEN); - XN297Dump_overflow(); - uint16_t timeL=TCNT1; - if(TIMER2_BASE->SR & TIMER_SR_UIF) - {//timer just rolled over... - XN297Dump_overflow(); - timeL=0; - } - if(phase==0) - { - phase=1; - time=0; - } - else - time=(timeH<<16)+timeL-time; - debug("RX: %5luus C=%d ", time>>1 , hopping_frequency_no); - time=(timeH<<16)+timeL; - if(XN297Dump_process_packet()) - { // valid crc found - debug("S=%c A=",scramble?'Y':'N'); - for(uint8_t i=0; iXN297DUMP_PERIOD_SCAN) + { // Scan frequencies + hopping_frequency_no++; + bind_counter=0; } + if(hopping_frequency_no!=rf_ch_num) + { // Channel has changed + if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL) + hopping_frequency_no=0; // Invalid channel 0 by default + rf_ch_num=hopping_frequency_no; + debugln("Channel=%d,0x%02X",hopping_frequency_no,hopping_frequency_no); + NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no); + // switch to RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC + | (1 << NRF24L01_00_CRCO) + | (1 << NRF24L01_00_PWR_UP) + | (1 << NRF24L01_00_PRIM_RX)); + phase=0; // init timer + } + XN297Dump_overflow(); - XN297Dump_overflow(); - // restart RX mode - NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit - NRF24L01_SetTxRxMode(TXRX_OFF); - NRF24L01_SetTxRxMode(RX_EN); - NRF24L01_FlushRx(); - NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC - | (1 << NRF24L01_00_CRCO) - | (1 << NRF24L01_00_PWR_UP) - | (1 << NRF24L01_00_PRIM_RX)); - XN297Dump_overflow(); + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + { // RX fifo data ready + if(NRF24L01_ReadReg(NRF24L01_09_CD) || option != 0xFF) + { + NRF24L01_ReadPayload(packet,XN297DUMP_MAX_PACKET_LEN); + XN297Dump_overflow(); + uint16_t timeL=TCNT1; + if(TIMER2_BASE->SR & TIMER_SR_UIF) + {//timer just rolled over... + XN297Dump_overflow(); + timeL=0; + } + if((phase&0x01)==0) + { + phase=1; + time=0; + } + else + time=(timeH<<16)+timeL-time; + if(XN297Dump_process_packet()) + { // valid crc found + debug("RX: %5luus C=%d ", time>>1 , hopping_frequency_no); + time=(timeH<<16)+timeL; + if(enhanced) + { + debug("Enhanced "); + debug("pid=%d ",pid); + if(ack) debug("ack "); + } + debug("S=%c A=",scramble?'Y':'N'); + for(uint8_t i=0; i>1 , hopping_frequency_no); + } + } + + XN297Dump_overflow(); + // restart RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC + | (1 << NRF24L01_00_CRCO) + | (1 << NRF24L01_00_PWR_UP) + | (1 << NRF24L01_00_PRIM_RX)); + XN297Dump_overflow(); + } + } + else + { + switch(phase) + { + case 0: + debugln("------------------------"); + debugln("Detecting XN297 packets."); + XN297Dump_init(); + debug("Trying RF channel: 0"); + hopping_frequency_no=0; + bitrate=0; + phase++; + break; + case 1: + if(bind_counter>XN297DUMP_PERIOD_SCAN) + { // Scan frequencies + hopping_frequency_no++; + bind_counter=0; + if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL) + { + hopping_frequency_no=0; + bitrate++; + bitrate%=3; + debugln(""); + XN297Dump_init(); + debug("Trying RF channel: 0"); + } + if(hopping_frequency_no) + debug(",%d",hopping_frequency_no); + NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no); + // switch to RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC + | (1 << NRF24L01_00_CRCO) + | (1 << NRF24L01_00_PWR_UP) + | (1 << NRF24L01_00_PRIM_RX)); + } + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + { // RX fifo data ready + if(NRF24L01_ReadReg(NRF24L01_09_CD)) + { + NRF24L01_ReadPayload(packet,XN297DUMP_MAX_PACKET_LEN); + if(XN297Dump_process_packet()) + { // valid crc found + debug("\r\n\r\nPacket detected: bitrate="); + switch(bitrate) + { + case XN297DUMP_250K: + NRF24L01_SetBitrate(NRF24L01_BR_250K); + debug("250K"); + break; + case XN297DUMP_2M: + NRF24L01_SetBitrate(NRF24L01_BR_2M); + debug("2M"); + break; + default: + NRF24L01_SetBitrate(NRF24L01_BR_1M); + debug("1M"); + break; + + } + debug(" C=%d ", hopping_frequency_no); + if(enhanced) + { + debug("Enhanced "); + debug("pid=%d ",pid); + if(ack) debug("ack "); + } + debug("S=%c A=",scramble?'Y':'N'); + for(uint8_t i=0; iXN297DUMP_PERIOD_SCAN) + { // Scan frequencies + hopping_frequency_no++; + bind_counter=0; + if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL) + { + debug("\r\n\r\n%d RF channels identified:",rf_ch_num); + for(uint8_t i=0;iSR & TIMER_SR_UIF) + {//timer just rolled over... + XN297Dump_overflow(); + timeL=0; + } + time=(timeH<<16)+timeL; + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC + | (1 << NRF24L01_00_CRCO) + | (1 << NRF24L01_00_PWR_UP) + | (1 << NRF24L01_00_PRIM_RX)); + XN297Dump_overflow(); + break; + } + debug(",%d",hopping_frequency_no); + NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no); + // switch to RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + } + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + { // RX fifo data ready + if(NRF24L01_ReadReg(NRF24L01_09_CD)) + { + boolean res; + if(enhanced) + res=XN297_ReadEnhancedPayload(packet, packet_length); + else + res=XN297_ReadPayload(packet, packet_length); + if(res) + { // valid crc found + XN297Dump_overflow(); + uint16_t timeL=TCNT1; + if(TIMER2_BASE->SR & TIMER_SR_UIF) + {//timer just rolled over... + XN297Dump_overflow(); + timeL=0; + } + if(packet_count==0) + {//save channel + hopping_frequency[rf_ch_num]=hopping_frequency_no; + rf_ch_num++; + time=0; + } + else + time=(timeH<<16)+timeL-time; + debug("\r\nRX on channel: %d, Time: %5luus P:",hopping_frequency_no, time>>1); + time=(timeH<<16)+timeL; + for(uint8_t i=0;i5) + { + bind_counter=XN297DUMP_PERIOD_SCAN+1; + debug("\r\nTrying RF channel: "); + packet_count=0; + } + } + } + // restart RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + } + XN297Dump_overflow(); + break; + case 3: + if(bind_counter>XN297DUMP_PERIOD_SCAN) + { // Scan frequencies + hopping_frequency_no++; + bind_counter=0; + if(hopping_frequency_no>=rf_ch_num) + { + uint8_t next=0; + debugln("\r\n\r\nChannel order:"); + debugln("%d: 0us",hopping_frequency[0]); + uint8_t i=1; + do + { + time=time_rf[i]; + if(time!=-1) + { + next=i; + for(uint8_t j=2;jtime_rf[j]) + { + next=j; + time=time_rf[j]; + } + time_rf[next]=-1; + debugln("%d: %5luus",hopping_frequency[next],time); + i=0; + } + i++; + } + while(iSR & TIMER_SR_UIF) + {//timer just rolled over... + XN297Dump_overflow(); + timeL=0; + } + time=(timeH<<16)+timeL; + // switch to RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + } + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + { // RX fifo data ready + if(NRF24L01_ReadReg(NRF24L01_09_CD)) + { + boolean res; + if(enhanced) + res=XN297_ReadEnhancedPayload(packet, packet_length); + else + res=XN297_ReadPayload(packet, packet_length); + if(res) + { // valid crc found + XN297Dump_overflow(); + uint16_t timeL=TCNT1; + if(TIMER2_BASE->SR & TIMER_SR_UIF) + {//timer just rolled over... + XN297Dump_overflow(); + timeL=0; + } + if(packet_count&1) + { + time=(timeH<<16)+timeL-time; + if(time_rf[hopping_frequency_no] > (time>>1)) + time_rf[hopping_frequency_no]=time>>1; + debugln("Time: %5luus", time>>1); + NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]); + } + else + { + time=(timeH<<16)+timeL; + NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[hopping_frequency_no]); + } + packet_count++; + if(packet_count>6) + { + bind_counter=XN297DUMP_PERIOD_SCAN+1; + packet_count=0; + } + } + } + // restart RX mode + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_SetTxRxMode(TXRX_OFF); + NRF24L01_SetTxRxMode(RX_EN); + NRF24L01_FlushRx(); + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); + } + XN297Dump_overflow(); + break; + case 4: + if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) + { // RX fifo data ready + if(NRF24L01_ReadReg(NRF24L01_09_CD)) + { + boolean res; + if(enhanced) + res=XN297_ReadEnhancedPayload(packet, packet_length); + else + res=XN297_ReadPayload(packet, packet_length); + if(res) + { // valid crc found + if(memcmp(packet_in,packet,packet_length)) + { + debug("P:"); + for(uint8_t i=0;i5) address_length=5; //default @@ -285,7 +647,7 @@ uint16_t initXN297Dump(void) bind_counter=0; rf_ch_num=0xFF; prev_option=option^0x55; - phase=0; // init timer + phase=0; // init return XN297DUMP_INITIAL_WAIT; }