|
| 1 | +/* |
| 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. |
| 6 | +
|
| 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. |
| 11 | +
|
| 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/>. |
| 14 | + */ |
| 15 | +#if defined(MOULDKG_NRF24L01_INO) |
| 16 | + |
| 17 | +#include "iface_xn297.h" |
| 18 | + |
| 19 | +//#define FORCE_MOULDKG_ORIGINAL_ID |
| 20 | + |
| 21 | +#define MOULDKG_PACKET_PERIOD 5000 |
| 22 | +#define MOULDKG_BIND_PACKET_PERIOD 12000 |
| 23 | +#define MOULDKG_TX_BIND_CHANNEL 11 |
| 24 | +#define MOULDKG_RX_BIND_CHANNEL 76 |
| 25 | +#define MOULDKG_PAYLOAD_SIZE 5 |
| 26 | +#define MOULDKG_BIND_PAYLOAD_SIZE 7 |
| 27 | +#define MOULDKG_BIND_COUNT 300 |
| 28 | +#define MOULDKG_RF_NUM_CHANNELS 4 |
| 29 | + |
| 30 | +enum { |
| 31 | + MOULDKG_BINDTX=0, |
| 32 | + MOULDKG_BINDRX, |
| 33 | + MOULDKG_DATA, |
| 34 | +}; |
| 35 | + |
| 36 | +static void __attribute__((unused)) MOULDKG_send_packet() |
| 37 | +{ |
| 38 | + memcpy(&packet[1],rx_tx_addr,3); |
| 39 | + if(IS_BIND_IN_PROGRESS) |
| 40 | + { |
| 41 | + packet[0] = 0xC0; |
| 42 | + memset(&packet[4], 0x00, 3); |
| 43 | + } |
| 44 | + else |
| 45 | + { |
| 46 | + XN297_RFChannel(hopping_frequency[(packet_count>>1)&0x03]); |
| 47 | + |
| 48 | + uint8_t val=0; |
| 49 | + if(packet_count&1) |
| 50 | + { |
| 51 | + packet[0] = 0x31; |
| 52 | + //Button B |
| 53 | + if(Channel_data[CH2]>CHANNEL_MAX_COMMAND) val |= 0x40; |
| 54 | + else if(Channel_data[CH2]<CHANNEL_MIN_COMMAND) val |= 0x80; |
| 55 | + //Button C |
| 56 | + if(Channel_data[CH3]>CHANNEL_MAX_COMMAND) val |= 0x10; |
| 57 | + else if(Channel_data[CH3]<CHANNEL_MIN_COMMAND) val |= 0x20; |
| 58 | + } |
| 59 | + else |
| 60 | + { |
| 61 | + packet[0] = 0x30; |
| 62 | + val = 0x60 |
| 63 | + | GET_FLAG(CH5_SW, 0x80) // Button E |
| 64 | + | GET_FLAG(CH6_SW, 0x10); // Button F |
| 65 | + } |
| 66 | + //Button A |
| 67 | + if(Channel_data[CH1]>CHANNEL_MAX_COMMAND) val |= 0x01; |
| 68 | + else if(Channel_data[CH1]<CHANNEL_MIN_COMMAND) val |= 0x02; |
| 69 | + //Button D |
| 70 | + if(Channel_data[CH4]>CHANNEL_MAX_COMMAND) val |= 0x04; |
| 71 | + else if(Channel_data[CH4]<CHANNEL_MIN_COMMAND) val |= 0x08; |
| 72 | + packet[4]= val; |
| 73 | + |
| 74 | + packet_count++; |
| 75 | + } |
| 76 | + |
| 77 | + // Send |
| 78 | + XN297_SetPower(); |
| 79 | + XN297_SetTxRxMode(TX_EN); |
| 80 | + XN297_WritePayload(packet, IS_BIND_IN_PROGRESS?MOULDKG_BIND_PAYLOAD_SIZE:MOULDKG_PAYLOAD_SIZE); |
| 81 | + #if 0 |
| 82 | + uint8_t len = IS_BIND_IN_PROGRESS?MOULDKG_BIND_PAYLOAD_SIZE:MOULDKG_PAYLOAD_SIZE; |
| 83 | + for(uint8_t i=0; i < len; i++) |
| 84 | + debug("%02X ", packet[i]); |
| 85 | + debugln(); |
| 86 | + #endif |
| 87 | +} |
| 88 | + |
| 89 | +static void __attribute__((unused)) MOULDKG_initialize_txid() |
| 90 | +{ |
| 91 | + rx_tx_addr[0]=rx_tx_addr[3]; // Use RX_num; |
| 92 | + #ifdef FORCE_MOULDKG_ORIGINAL_ID |
| 93 | + rx_tx_addr[0]=0x57; |
| 94 | + rx_tx_addr[1]=0x1B; |
| 95 | + rx_tx_addr[2]=0xF8; |
| 96 | + #endif |
| 97 | + //Are the frequencies constant??? If not where are they coming from??? |
| 98 | + memcpy(hopping_frequency,(uint8_t*)"\x0F\x1C\x39\x3C", MOULDKG_RF_NUM_CHANNELS); // 15,28,57,60 |
| 99 | +} |
| 100 | + |
| 101 | +static void __attribute__((unused)) MOULDKG_RF_init() |
| 102 | +{ |
| 103 | + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); |
| 104 | + XN297_SetTXAddr((uint8_t*)"KDH", 3); |
| 105 | + XN297_SetRXAddr((uint8_t*)"KDH", MOULDKG_BIND_PAYLOAD_SIZE); |
| 106 | +} |
| 107 | + |
| 108 | +uint16_t MOULDKG_callback() |
| 109 | +{ |
| 110 | + switch(phase) |
| 111 | + { |
| 112 | + case MOULDKG_BINDTX: |
| 113 | + if(XN297_IsRX()) |
| 114 | + { |
| 115 | + //Example: TX: C=11 S=Y A= 4B 44 48 P(7)= C0 37 02 4F 00 00 00 |
| 116 | + // RX: C=76 S=Y A= 4B 44 48 P(7)= 5A 37 02 4F 03 0D 8E |
| 117 | + XN297_ReadPayload(packet_in, MOULDKG_BIND_PAYLOAD_SIZE); |
| 118 | + for(uint8_t i=0; i < MOULDKG_BIND_PAYLOAD_SIZE; i++) |
| 119 | + debug("%02X ", packet_in[i]); |
| 120 | + debugln(); |
| 121 | + //Not sure if I should test packet_in[0] |
| 122 | + if(memcmp(&packet_in[1],&packet[1],3)==0) |
| 123 | + {//TX ID match, use RX ID to transmit normal packets |
| 124 | + XN297_SetTXAddr(&packet_in[4], 3); |
| 125 | + XN297_SetTxRxMode(TXRX_OFF); |
| 126 | + BIND_DONE; |
| 127 | + } |
| 128 | + } |
| 129 | + XN297_RFChannel(MOULDKG_TX_BIND_CHANNEL); // Set TX bind channel |
| 130 | + XN297_SetTxRxMode(TXRX_OFF); |
| 131 | + MOULDKG_send_packet(); |
| 132 | + phase++; |
| 133 | + return 500; |
| 134 | + case MOULDKG_BINDRX: |
| 135 | + //Wait for the packet transmission to finish |
| 136 | + while(XN297_IsPacketSent()==false); |
| 137 | + //Switch to RX |
| 138 | + XN297_SetTxRxMode(TXRX_OFF); |
| 139 | + XN297_RFChannel(MOULDKG_RX_BIND_CHANNEL); // Set RX bind channel |
| 140 | + XN297_SetTxRxMode(RX_EN); |
| 141 | + phase = MOULDKG_BINDTX; |
| 142 | + return MOULDKG_BIND_PACKET_PERIOD-500; |
| 143 | + case MOULDKG_DATA: |
| 144 | + #ifdef MULTI_SYNC |
| 145 | + telemetry_set_input_sync(MOULDKG_PACKET_PERIOD); |
| 146 | + #endif |
| 147 | + MOULDKG_send_packet(); |
| 148 | + break; |
| 149 | + } |
| 150 | + return MOULDKG_PACKET_PERIOD; |
| 151 | +} |
| 152 | + |
| 153 | +void MOULDKG_init() |
| 154 | +{ |
| 155 | + BIND_IN_PROGRESS; // autobind protocol |
| 156 | + MOULDKG_initialize_txid(); |
| 157 | + MOULDKG_RF_init(); |
| 158 | + bind_counter = MOULDKG_BIND_COUNT; |
| 159 | + packet_count = 0; |
| 160 | +} |
| 161 | + |
| 162 | +#endif |
0 commit comments