|
| 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(PINECONE_CCNRF_INO) |
| 16 | + |
| 17 | +#include "iface_xn297.h" |
| 18 | + |
| 19 | +#define FORCE_PINECONE_ORIGINAL_ID |
| 20 | + |
| 21 | +#define PINECONE_PAYLOAD_SIZE 15 |
| 22 | +#define PINECONE_RF_NUM_CHANNELS 4 |
| 23 | +#define PINECONE_PACKET_PERIOD 9000 |
| 24 | +#define PINECONE_BIND_COUNT 2000 |
| 25 | +#define PINECONE_WRITE_TIME 1500 |
| 26 | + |
| 27 | +enum { |
| 28 | + PINECONE_DATA=0, |
| 29 | + PINECONE_RX, |
| 30 | +}; |
| 31 | + |
| 32 | +static void __attribute__((unused)) PINECONE_send_packet() |
| 33 | +{ |
| 34 | + if(rf_ch_num==0) |
| 35 | + { |
| 36 | + XN297_Hopping(hopping_frequency_no); |
| 37 | + debug("H %d ",hopping_frequency_no); |
| 38 | + hopping_frequency_no++; |
| 39 | + hopping_frequency_no &= 3; |
| 40 | + } |
| 41 | + |
| 42 | + if(bind_counter==0) bind_counter=2; |
| 43 | + memset(&packet[3], 0x00, 12); |
| 44 | + if(bind_counter) |
| 45 | + {//Bind in progress |
| 46 | + bind_counter--; |
| 47 | + if(bind_counter) |
| 48 | + {//Bind |
| 49 | + packet[0] = 0x01; |
| 50 | + memcpy(&packet[1],rx_tx_addr,5); |
| 51 | + } |
| 52 | + else |
| 53 | + {//Switch to normal |
| 54 | + XN297_SetTXAddr(rx_tx_addr, 5); |
| 55 | + XN297_SetRXAddr(rx_tx_addr, PINECONE_PAYLOAD_SIZE); |
| 56 | + } |
| 57 | + } |
| 58 | + if(!bind_counter) |
| 59 | + {//Normal |
| 60 | + packet[0] = 0x08; |
| 61 | + packet[1] = convert_channel_16b_limit(AILERON,0,200); //ST |
| 62 | + packet[2] = convert_channel_16b_limit(THROTTLE,0,200); //TH |
| 63 | + packet[3] = convert_channel_16b_limit(ELEVATOR,0,200); //CH4 |
| 64 | + packet[4] = convert_channel_16b_limit(RUDDER,0,200); //CH3 |
| 65 | + } |
| 66 | + //packet[5/6..8] = 00 unknown |
| 67 | + packet[9] = convert_channel_16b_limit(CH5,0,200); //ESP |
| 68 | + packet[10] = convert_channel_16b_limit(CH6,0,200); //ST_TRIM |
| 69 | + packet[11] = convert_channel_16b_limit(CH7,0,200); //ST_DR |
| 70 | + packet[12] = GET_FLAG(CH8_SW, 0x40) //TH.REV |
| 71 | + |GET_FLAG(CH9_SW, 0x80); //ST.REV |
| 72 | + //packet[13] = 00 unknown |
| 73 | + for(uint8_t i=0;i<PINECONE_PAYLOAD_SIZE-1;i++) |
| 74 | + packet[14] += packet[i]; |
| 75 | + // Send |
| 76 | + XN297_SetPower(); |
| 77 | + XN297_SetTxRxMode(TX_EN); |
| 78 | + XN297_WriteEnhancedPayload(packet, PINECONE_PAYLOAD_SIZE,false); |
| 79 | + #ifdef DEBUG_SERIAL |
| 80 | + for(uint8_t i=0; i < PINECONE_PAYLOAD_SIZE; i++) |
| 81 | + debug("%02X ", packet[i]); |
| 82 | + debugln(); |
| 83 | + #endif |
| 84 | +} |
| 85 | + |
| 86 | +static void __attribute__((unused)) PINECONE_initialize_txid() |
| 87 | +{ |
| 88 | + #ifdef FORCE_PINECONE_ORIGINAL_ID |
| 89 | + rx_tx_addr[0] = 0xD0; |
| 90 | + rx_tx_addr[1] = 0x06; |
| 91 | + rx_tx_addr[2] = 0x00; |
| 92 | + rx_tx_addr[3] = 0x00; |
| 93 | + rx_tx_addr[4] = 0x81; |
| 94 | + hopping_frequency[0] = 45; |
| 95 | + hopping_frequency[1] = 59; |
| 96 | + hopping_frequency[2] = 52; |
| 97 | + hopping_frequency[3] = 67; |
| 98 | + #endif |
| 99 | +} |
| 100 | + |
| 101 | +static void __attribute__((unused)) PINECONE_RF_init() |
| 102 | +{ |
| 103 | + XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K); |
| 104 | + //Bind address |
| 105 | + XN297_SetTXAddr((uint8_t*)"\x01\x03\x05\x07\x09", 5); |
| 106 | + XN297_SetRXAddr((uint8_t*)"\x01\x03\x05\x07\x09", PINECONE_PAYLOAD_SIZE); |
| 107 | + XN297_HoppingCalib(PINECONE_RF_NUM_CHANNELS); |
| 108 | +} |
| 109 | + |
| 110 | +uint16_t PINECONE_callback() |
| 111 | +{ |
| 112 | + bool rx; |
| 113 | + switch(phase) |
| 114 | + { |
| 115 | + case PINECONE_DATA: |
| 116 | + rx = XN297_IsRX(); |
| 117 | + XN297_SetTxRxMode(TXRX_OFF); |
| 118 | + #ifdef MULTI_SYNC |
| 119 | + telemetry_set_input_sync(PINECONE_PACKET_PERIOD); |
| 120 | + #endif |
| 121 | + PINECONE_send_packet(); |
| 122 | + if(rx) |
| 123 | + { |
| 124 | + uint8_t val=XN297_ReadEnhancedPayload(packet_in, PINECONE_PAYLOAD_SIZE); |
| 125 | + debug("RX %d ",val); |
| 126 | + if(val==0) |
| 127 | + rf_ch_num = 1; |
| 128 | + else |
| 129 | + { |
| 130 | + #ifdef DEBUG_SERIAL |
| 131 | + for(uint8_t i=0; i < PINECONE_PAYLOAD_SIZE; i++) |
| 132 | + debug("%02X ", packet_in[i]); |
| 133 | + debugln(); |
| 134 | + #endif |
| 135 | + //could check the validity of the packet by looking at the sum... |
| 136 | + } |
| 137 | + //else |
| 138 | + // debug("NOK"); |
| 139 | + debugln(""); |
| 140 | + } |
| 141 | + phase++; |
| 142 | + return PINECONE_WRITE_TIME; |
| 143 | + default: //PINECONE_RX |
| 144 | + //Wait for the packet transmission to finish |
| 145 | + while(XN297_IsPacketSent()==false); |
| 146 | + //Switch to RX |
| 147 | + XN297_SetTxRxMode(TXRX_OFF); |
| 148 | + XN297_SetTxRxMode(RX_EN); |
| 149 | + phase = PINECONE_DATA; |
| 150 | + return PINECONE_PACKET_PERIOD - PINECONE_WRITE_TIME; |
| 151 | + } |
| 152 | + return 0; |
| 153 | +} |
| 154 | + |
| 155 | +void PINECONE_init() |
| 156 | +{ |
| 157 | + PINECONE_initialize_txid(); |
| 158 | + PINECONE_RF_init(); |
| 159 | + |
| 160 | + bind_counter = IS_BIND_IN_PROGRESS ? PINECONE_BIND_COUNT : 1; |
| 161 | + phase = PINECONE_DATA; |
| 162 | + hopping_frequency_no = 0; |
| 163 | + rf_ch_num=0; |
| 164 | + bind_counter = 2000; |
| 165 | +} |
| 166 | + |
| 167 | +#endif |
0 commit comments