├── README.md ├── ino.ini ├── lib └── a7105 │ ├── a7105.h │ ├── a7105.ino │ └── hubsan.ino └── src ├── config.h ├── main.ino └── protocol.ino /README.md: -------------------------------------------------------------------------------- 1 | arduino-a7105 2 | ============= 3 | 4 | Fixed code from http://www.instructables.com/id/Easy-Android-controllable-PC-Interfaceable-Relati/step6/Arduino-Software/ 5 | 6 | Witten for the Arduino Duemilanove. 7 | 8 | 9 | How to use 10 | ---------- 11 | 12 | * Clone the repo 13 | * Work around [this ino bug](https://github.com/amperka/ino/issues/134): remove `/usr/share/arduino/libraries/Robot_Control/` (renaming will not work) 14 | * Install [`ino`](https://github.com/amperka/ino/) 15 | * run `ino build` 16 | * run `ino upload` to upload it to your Arduino 17 | -------------------------------------------------------------------------------- /ino.ini: -------------------------------------------------------------------------------- 1 | [build] 2 | board-model = atmega328 3 | 4 | [upload] 5 | board-model = atmega328 6 | 7 | [serial] 8 | baud-rate = 115200 9 | -------------------------------------------------------------------------------- /lib/a7105/a7105.h: -------------------------------------------------------------------------------- 1 | #ifndef _IFACE_A7105_H_ 2 | #define _IFACE_A7105_H_ 3 | 4 | #include "config.h" 5 | 6 | enum A7105_State { 7 | A7105_SLEEP = 0x80, 8 | A7105_IDLE = 0x90, 9 | A7105_STANDBY = 0xA0, 10 | A7105_PLL = 0xB0, 11 | A7105_RX = 0xC0, 12 | A7105_TX = 0xD0, 13 | A7105_RST_WRPTR = 0xE0, 14 | A7105_RST_RDPTR = 0xF0, 15 | }; 16 | 17 | enum { 18 | A7105_00_MODE = 0x00, 19 | A7105_01_MODE_CONTROL = 0x01, 20 | A7105_02_CALC = 0x02, 21 | A7105_03_FIFOI = 0x03, 22 | A7105_04_FIFOII = 0x04, 23 | A7105_05_FIFO_DATA = 0x05, 24 | A7105_06_ID_DATA = 0x06, 25 | A7105_07_RC_OSC_I = 0x07, 26 | A7105_08_RC_OSC_II = 0x08, 27 | A7105_09_RC_OSC_III = 0x09, 28 | A7105_0A_CK0_PIN = 0x0A, 29 | A7105_0B_GPIO1_PIN1 = 0x0B, 30 | A7105_0C_GPIO2_PIN_II = 0x0C, 31 | A7105_0D_CLOCK = 0x0D, 32 | A7105_0E_DATA_RATE = 0x0E, 33 | A7105_0F_PLL_I = 0x0F, 34 | A7105_10_PLL_II = 0x10, 35 | A7105_11_PLL_III = 0x11, 36 | A7105_12_PLL_IV = 0x12, 37 | A7105_13_PLL_V = 0x13, 38 | A7105_14_TX_I = 0x14, 39 | A7105_15_TX_II = 0x15, 40 | A7105_16_DELAY_I = 0x16, 41 | A7105_17_DELAY_II = 0x17, 42 | A7105_18_RX = 0x18, 43 | A7105_19_RX_GAIN_I = 0x19, 44 | A7105_1A_RX_GAIN_II = 0x1A, 45 | A7105_1B_RX_GAIN_III = 0x1B, 46 | A7105_1C_RX_GAIN_IV = 0x1C, 47 | A7105_1D_RSSI_THOLD = 0x1D, 48 | A7105_1E_ADC = 0x1E, 49 | A7105_1F_CODE_I = 0x1F, 50 | A7105_20_CODE_II = 0x20, 51 | A7105_21_CODE_III = 0x21, 52 | A7105_22_IF_CALIB_I = 0x22, 53 | A7105_23_IF_CALIB_II = 0x23, 54 | A7105_24_VCO_CURCAL = 0x24, 55 | A7105_25_VCO_SBCAL_I = 0x25, 56 | A7105_26_VCO_SBCAL_II = 0x26, 57 | A7105_27_BATTERY_DET = 0x27, 58 | A7105_28_TX_TEST = 0x28, 59 | A7105_29_RX_DEM_TEST_I = 0x29, 60 | A7105_2A_RX_DEM_TEST_II = 0x2A, 61 | A7105_2B_CPC = 0x2B, 62 | A7105_2C_XTAL_TEST = 0x2C, 63 | A7105_2D_PLL_TEST = 0x2D, 64 | A7105_2E_VCO_TEST_I = 0x2E, 65 | A7105_2F_VCO_TEST_II = 0x2F, 66 | A7105_30_IFAT = 0x30, 67 | A7105_31_RSCALE = 0x31, 68 | A7105_32_FILTER_TEST = 0x32, 69 | }; 70 | #define A7105_0F_CHANNEL A7105_0F_PLL_I 71 | 72 | enum A7105_MASK { 73 | A7105_MASK_FBCF = 1 << 4, 74 | A7105_MASK_VBCF = 1 << 3, 75 | }; 76 | 77 | void A7105_Initialize(); 78 | void A7105_WriteReg(u8 addr, u8 value); 79 | void A7105_WriteData(u8 *dpbuffer, u8 len, u8 channel); 80 | void A7105_ReadData(u8 *dpbuffer, u8 len); 81 | u8 A7105_ReadReg(u8 addr); 82 | void A7105_Reset(); 83 | void A7105_WriteID(u32 id); 84 | void A7105_Strobe(enum A7105_State); 85 | void A7105_SetPower(int power); 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /lib/a7105/a7105.ino: -------------------------------------------------------------------------------- 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 | Deviation 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 Deviation. If not, see . 14 | */ 15 | 16 | #include 17 | #include 18 | #include "config.h" 19 | #include "a7105.h" 20 | 21 | #define CS_PIN 10 22 | 23 | #define CS_HI() digitalWrite(CS_PIN, HIGH); 24 | #define CS_LO() digitalWrite(CS_PIN, LOW); 25 | 26 | void A7105_WriteReg(u8 address, u8 data) 27 | { 28 | CS_LO(); 29 | SPI.transfer(address); // spi_xfer(SPI2, address); 30 | SPI.transfer(data); // spi_xfer(SPI2, data); 31 | CS_HI(); 32 | } 33 | 34 | 35 | void A7105_Setup() { 36 | pinMode(CS_PIN, OUTPUT); 37 | SPI.begin(); 38 | SPI.setDataMode(SPI_MODE0); 39 | // SPI.setClockDivider(10); 40 | SPI.setBitOrder(MSBFIRST); 41 | // set gpio1 to SDO (MISO) by writing to reg GIO1S 42 | // A7105_WriteReg(0x0b,0x06); // 0b0110 43 | } 44 | 45 | u8 A7105_ReadReg(u8 address) 46 | { 47 | u8 data; 48 | int i; 49 | CS_LO(); 50 | // Bits A7-A0 make up the first u8. 51 | // Bit A7 = 1 == Strobe. A7 = 0 == access register. 52 | // Bit a6 = 1 == read. a6 = 0 == write. 53 | // bits 0-5 = address. Assuming address < 64 the below says we want to read an address. 54 | SPI.transfer(0x40 | address); //spi_xfer(SPI2, 0x40 | address); 55 | data = SPI.transfer(0); 56 | CS_HI(); 57 | // Serial.print(address); Serial.print(" "); Serial.println(data); 58 | return data; 59 | // Not necessary because we expect SPI class to handle this? 60 | // /* Wait for tx completion before spi shutdown */ 61 | // while(!(SPI_SR(SPI2) & SPI_SR_TXE)) 62 | // ; 63 | // while((SPI_SR(SPI2) & SPI_SR_BSY)) 64 | // ; 65 | 66 | // spi_disable(SPI2); 67 | // spi_set_bidirectional_receive_only_mode(SPI2); 68 | // */ 69 | // /* Force read from SPI_DR to ensure RXNE is clear (probably not needed) */ 70 | // volatile u8 x = SPI_DR(SPI2); 71 | // (void)x; 72 | // spi_enable(SPI2); //This starts the data read 73 | // for(i = 0; i < 20; i++) //Wait > 1 SPI clock (but less than 8). clock is 4.5MHz 74 | // asm volatile ("nop"); 75 | // ; 76 | // spi_disable(SPI2); //This ends the read window 77 | // data = spi_read(SPI2); 78 | // CS_HI(); 79 | // spi_set_unidirectional_mode(SPI2); 80 | // spi_enable(SPI2); 81 | // return data; 82 | } 83 | 84 | void A7105_WriteData(u8 *dpbuffer, u8 len, u8 channel) 85 | { 86 | int i; 87 | CS_LO(); 88 | SPI.transfer(A7105_RST_WRPTR); //reset write FIFO PTR 89 | SPI.transfer(0x05); // FIFO DATA register - about to send data to put into FIFO 90 | for (i = 0; i < len; i++) 91 | SPI.transfer(dpbuffer[i]); // send some data 92 | CS_HI(); 93 | 94 | // set the channel 95 | A7105_WriteReg(0x0F, channel); 96 | 97 | CS_LO(); 98 | SPI.transfer(A7105_TX); // strobe command to actually transmit the daat 99 | CS_HI(); 100 | } 101 | 102 | void A7105_ReadData(u8 *dpbuffer, u8 len) 103 | { 104 | A7105_Strobe(A7105_RST_RDPTR); //A7105_RST_RDPTR 105 | for(int i = 0; i < len; i++) { 106 | dpbuffer[i] = A7105_ReadReg(0x05); 107 | } 108 | 109 | return; 110 | } 111 | 112 | void A7105_Reset() 113 | { 114 | A7105_WriteReg(0x00, 0x00); 115 | delayMicroseconds(1000); 116 | // Serial.println(A7105_ReadReg(0x2)); 117 | } 118 | 119 | void A7105_WriteID(unsigned long id) 120 | { 121 | CS_LO(); 122 | SPI.transfer(0x06); 123 | SPI.transfer((id >> 24) & 0xFF); 124 | SPI.transfer((id >> 16) & 0xFF); 125 | SPI.transfer((id >> 8) & 0xFF); 126 | SPI.transfer((id >> 0) & 0xFF); 127 | CS_HI(); 128 | } 129 | 130 | void A7105_SetPower(int power) 131 | { 132 | /* 133 | Power amp is ~+16dBm so: 134 | TXPOWER_100uW = -23dBm == PAC=0 TBG=0 135 | TXPOWER_300uW = -20dBm == PAC=0 TBG=1 136 | TXPOWER_1mW = -16dBm == PAC=0 TBG=2 137 | TXPOWER_3mW = -11dBm == PAC=0 TBG=4 138 | TXPOWER_10mW = -6dBm == PAC=1 TBG=5 139 | TXPOWER_30mW = 0dBm == PAC=2 TBG=7 140 | TXPOWER_100mW = 1dBm == PAC=3 TBG=7 141 | TXPOWER_150mW = 1dBm == PAC=3 TBG=7 142 | */ 143 | u8 pac, tbg; 144 | switch(power) { 145 | case 0: pac = 0; tbg = 0; break; 146 | case 1: pac = 0; tbg = 1; break; 147 | case 2: pac = 0; tbg = 2; break; 148 | case 3: pac = 0; tbg = 4; break; 149 | case 4: pac = 1; tbg = 5; break; 150 | case 5: pac = 2; tbg = 7; break; 151 | case 6: pac = 3; tbg = 7; break; 152 | case 7: pac = 3; tbg = 7; break; 153 | default: pac = 0; tbg = 0; break; 154 | }; 155 | A7105_WriteReg(0x28, (pac << 3) | tbg); 156 | } 157 | 158 | void A7105_Strobe(enum A7105_State state) 159 | { 160 | CS_LO(); 161 | SPI.transfer(state); 162 | CS_HI(); 163 | } 164 | 165 | -------------------------------------------------------------------------------- /lib/a7105/hubsan.ino: -------------------------------------------------------------------------------- 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 | Deviation 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 Deviation. If not, see . 14 | */ 15 | 16 | //#include "interface.h" 17 | //#include "mixer.h" 18 | //#include "config/model.h" 19 | //#include 20 | //#include 21 | #include 22 | //#include "config.h" 23 | #include "a7105.h" 24 | 25 | volatile s16 Channels[NUM_OUT_CHANNELS]; 26 | 27 | u8 packet[16]; 28 | u8 channel; 29 | const u8 allowed_ch[] = {0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50, 0x5a, 0x64, 0x6e, 0x78, 0x82}; 30 | unsigned long sessionid; 31 | const unsigned long txid = 0xdb042679; 32 | u8 state; 33 | 34 | enum { 35 | BIND_1, 36 | BIND_2, 37 | BIND_3, 38 | BIND_4, 39 | BIND_5, 40 | BIND_6, 41 | BIND_7, 42 | BIND_8, 43 | DATA_1, 44 | DATA_2, 45 | DATA_3, 46 | DATA_4, 47 | DATA_5, 48 | }; 49 | #define WAIT_WRITE 0x80 50 | 51 | int hubsan_init() 52 | { 53 | u8 if_calibration1; 54 | u8 vco_calibration0; 55 | u8 vco_calibration1; 56 | //u8 vco_current; 57 | 58 | A7105_WriteID(0x55201041); 59 | A7105_WriteReg(A7105_01_MODE_CONTROL, 0x63); 60 | A7105_WriteReg(A7105_03_FIFOI, 0x0f); 61 | A7105_WriteReg(A7105_0D_CLOCK, 0x05); 62 | A7105_WriteReg(A7105_0E_DATA_RATE, 0x04); 63 | A7105_WriteReg(A7105_15_TX_II, 0x2b); 64 | A7105_WriteReg(A7105_18_RX, 0x62); 65 | A7105_WriteReg(A7105_19_RX_GAIN_I, 0x80); 66 | A7105_WriteReg(A7105_1C_RX_GAIN_IV, 0x0A); 67 | A7105_WriteReg(A7105_1F_CODE_I, 0x07); 68 | A7105_WriteReg(A7105_20_CODE_II, 0x17); 69 | A7105_WriteReg(A7105_29_RX_DEM_TEST_I, 0x47); 70 | 71 | A7105_Strobe(A7105_STANDBY); 72 | 73 | //IF Filter Bank Calibration 74 | A7105_WriteReg(0x02, 1); 75 | //vco_current = 76 | A7105_ReadReg(0x02); 77 | unsigned long ms = millis(); 78 | 79 | while(millis() - ms < 500) { 80 | if(! A7105_ReadReg(0x02)) 81 | break; 82 | } 83 | if (millis() - ms >= 500) 84 | return 0; 85 | if_calibration1 = A7105_ReadReg(A7105_22_IF_CALIB_I); 86 | A7105_ReadReg(A7105_24_VCO_CURCAL); 87 | if(if_calibration1 & A7105_MASK_FBCF) { 88 | //Calibration failed...what do we do? 89 | return 0; 90 | } 91 | 92 | //VCO Current Calibration 93 | //A7105_WriteReg(0x24, 0x13); //Recomended calibration from A7105 Datasheet 94 | 95 | //VCO Bank Calibration 96 | //A7105_WriteReg(0x26, 0x3b); //Recomended limits from A7105 Datasheet 97 | 98 | //VCO Bank Calibrate channel 0? 99 | //Set Channel 100 | A7105_WriteReg(A7105_0F_CHANNEL, 0); 101 | //VCO Calibration 102 | A7105_WriteReg(0x02, 2); 103 | ms = millis(); 104 | while(millis() - ms < 500) { 105 | if(! A7105_ReadReg(0x02)) 106 | break; 107 | } 108 | if (millis() - ms >= 500) 109 | return 0; 110 | vco_calibration0 = A7105_ReadReg(A7105_25_VCO_SBCAL_I); 111 | if (vco_calibration0 & A7105_MASK_VBCF) { 112 | //Calibration failed...what do we do? 113 | return 0; 114 | } 115 | 116 | //Calibrate channel 0xa0? 117 | //Set Channel 118 | A7105_WriteReg(A7105_0F_CHANNEL, 0xa0); 119 | //VCO Calibration 120 | A7105_WriteReg(A7105_02_CALC, 2); 121 | ms = millis(); 122 | while(millis() - ms < 500) { 123 | if(! A7105_ReadReg(A7105_02_CALC)) 124 | break; 125 | } 126 | if (millis() - ms >= 500) 127 | return 0; 128 | vco_calibration1 = A7105_ReadReg(A7105_25_VCO_SBCAL_I); 129 | if (vco_calibration1 & A7105_MASK_VBCF) { 130 | //Calibration failed...what do we do? 131 | } 132 | 133 | //Reset VCO Band calibration 134 | //A7105_WriteReg(0x25, 0x08); 135 | 136 | A7105_SetPower(TXPOWER_150mW); 137 | 138 | A7105_Strobe(A7105_STANDBY); 139 | return 1; 140 | } 141 | 142 | static void update_crc() 143 | { 144 | int sum = 0; 145 | for(int i = 0; i < 15; i++) 146 | sum += packet[i]; 147 | packet[15] = (256 - (sum % 256)) & 0xff; 148 | } 149 | static void hubsan_build_bind_packet(u8 state) 150 | { 151 | packet[0] = state; 152 | packet[1] = channel; 153 | packet[2] = (sessionid >> 24) & 0xff; 154 | packet[3] = (sessionid >> 16) & 0xff; 155 | packet[4] = (sessionid >> 8) & 0xff; 156 | packet[5] = (sessionid >> 0) & 0xff; 157 | packet[6] = 0x08; 158 | packet[7] = 0xe4; //??? 159 | packet[8] = 0xea; 160 | packet[9] = 0x9e; 161 | packet[10] = 0x50; 162 | packet[11] = (txid >> 24) & 0xff; 163 | packet[12] = (txid >> 16) & 0xff; 164 | packet[13] = (txid >> 8) & 0xff; 165 | packet[14] = (txid >> 0) & 0xff; 166 | update_crc(); 167 | } 168 | 169 | s16 get_channel(u8 ch, s32 scale, s32 center, s32 range) 170 | { 171 | static int a=0; 172 | if (a++<2550) return 0; 173 | 174 | // return 254; 175 | return 128; 176 | s32 value = (s32)Channels[ch] * scale / CHAN_MAX_VALUE + center; 177 | if (value < center - range) 178 | value = center - range; 179 | if (value >= center + range) 180 | value = center + range -1; 181 | return value; 182 | } 183 | 184 | 185 | volatile uint8_t throttle=0, rudder=0, aileron = 0, elevator = 0; 186 | 187 | static void hubsan_build_packet() 188 | { 189 | memset(packet, 0, 16); 190 | //20 00 00 00 80 00 7d 00 84 02 64 db 04 26 79 7b 191 | packet[0] = 0x20; 192 | packet[2] = throttle;//get_channel(2, 0x80, 0x80, 0x80); 193 | packet[4] = 0xff - rudder; // get_channel(3, 0x80, 0x80, 0x80); //Rudder is reversed 194 | packet[6] = 0xff - elevator; // get_channel(1, 0x80, 0x80, 0x80); //Elevator is reversed 195 | packet[8] = aileron; // get_channel(0, 0x80, 0x80, 0x80); 196 | packet[9] = 0x02; 197 | packet[10] = 0x64; 198 | packet[11] = (txid >> 24) & 0xff; 199 | packet[12] = (txid >> 16) & 0xff; 200 | packet[13] = (txid >> 8) & 0xff; 201 | packet[14] = (txid >> 0) & 0xff; 202 | update_crc(); 203 | } 204 | 205 | static u16 hubsan_cb() 206 | { 207 | int i; 208 | switch(state) { 209 | case BIND_1: 210 | case BIND_3: 211 | case BIND_5: 212 | case BIND_7: 213 | hubsan_build_bind_packet(state == BIND_7 ? 9 : (state == BIND_5 ? 1 : state + 1 - BIND_1)); 214 | A7105_Strobe(A7105_STANDBY); 215 | A7105_WriteData(packet, 16, channel); 216 | state |= WAIT_WRITE; 217 | return 3000; 218 | case BIND_1 | WAIT_WRITE: 219 | case BIND_3 | WAIT_WRITE: 220 | case BIND_5 | WAIT_WRITE: 221 | case BIND_7 | WAIT_WRITE: 222 | //wait for completion 223 | for(i = 0; i< 20; i++) { 224 | if(! (A7105_ReadReg(A7105_00_MODE) & 0x01)) 225 | break; 226 | } 227 | if (i == 20) 228 | Serial.println("Failed to complete write\n"); 229 | // else 230 | // Serial.println("Completed write\n"); 231 | A7105_Strobe(A7105_RX); 232 | state &= ~WAIT_WRITE; 233 | state++; 234 | return 4500; //7.5msec elapsed since last write 235 | case BIND_2: 236 | case BIND_4: 237 | case BIND_6: 238 | if(A7105_ReadReg(A7105_00_MODE) & 0x01) { 239 | state = BIND_1; //Serial.println("Restart"); 240 | return 4500; //No signal, restart binding procedure. 12msec elapsed since last write 241 | } 242 | 243 | A7105_ReadData(packet, 16); 244 | state++; 245 | if (state == BIND_5) 246 | A7105_WriteID((packet[2] << 24) | (packet[3] << 16) | (packet[4] << 8) | packet[5]); 247 | 248 | return 500; //8msec elapsed time since last write; 249 | case BIND_8: 250 | if(A7105_ReadReg(A7105_00_MODE) & 0x01) { 251 | state = BIND_7; 252 | return 15000; //22.5msec elapsed since last write 253 | } 254 | A7105_ReadData(packet, 16); 255 | if(packet[1] == 9) { 256 | state = DATA_1; 257 | A7105_WriteReg(A7105_1F_CODE_I, 0x0F); 258 | PROTOCOL_SetBindState(0); 259 | return 28000; //35.5msec elapsed since last write 260 | } else { 261 | state = BIND_7; 262 | return 15000; //22.5 msec elapsed since last write 263 | } 264 | case DATA_1: 265 | //Keep transmit power in sync 266 | A7105_SetPower(TXPOWER_150mW); 267 | case DATA_2: 268 | case DATA_3: 269 | case DATA_4: 270 | case DATA_5: 271 | hubsan_build_packet(); 272 | A7105_WriteData(packet, 16, state == DATA_5 ? channel + 0x23 : channel); 273 | if (state == DATA_5) 274 | state = DATA_1; 275 | else 276 | state++; 277 | return 10000; 278 | } 279 | return 0; 280 | } 281 | 282 | static void initialize() { 283 | while(1) { 284 | A7105_Reset(); 285 | if (hubsan_init()) 286 | break; 287 | } 288 | sessionid = rand(); 289 | channel = allowed_ch[rand() % sizeof(allowed_ch)]; 290 | state = BIND_1; 291 | } 292 | 293 | 294 | void setup() { } 295 | 296 | 297 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _IFACE_CONFIG_H_ 2 | #define _IFACE_CONFIG_H_ 3 | 4 | #include 5 | 6 | #define NUM_OUT_CHANNELS 12 7 | #define CHAN_MULTIPLIER 100 8 | #define CHAN_MAX_VALUE (100 * CHAN_MULTIPLIER) 9 | 10 | #define s16 int16_t 11 | #define u16 uint16_t 12 | #define s32 int32_t 13 | #define u32 uint32_t 14 | #define u8 uint8_t 15 | 16 | extern volatile s16 Channels[NUM_OUT_CHANNELS]; 17 | 18 | enum TxPower { 19 | TXPOWER_100uW, 20 | TXPOWER_300uW, 21 | TXPOWER_1mW, 22 | TXPOWER_3mW, 23 | TXPOWER_10mW, 24 | TXPOWER_30mW, 25 | TXPOWER_100mW, 26 | TXPOWER_150mW, 27 | TXPOWER_LAST, 28 | }; 29 | 30 | enum ProtoCmds { 31 | PROTOCMD_INIT, 32 | PROTOCMD_DEINIT, 33 | PROTOCMD_BIND, 34 | PROTOCMD_CHECK_AUTOBIND, 35 | PROTOCMD_NUMCHAN, 36 | PROTOCMD_DEFAULT_NUMCHAN, 37 | PROTOCMD_CURRENT_ID, 38 | PROTOCMD_SET_TXPOWER, 39 | PROTOCMD_GETOPTIONS, 40 | PROTOCMD_SETOPTIONS, 41 | PROTOCMD_TELEMETRYSTATE, 42 | }; 43 | 44 | 45 | void PROTOCOL_SetBindState(u32 msec); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/main.ino: -------------------------------------------------------------------------------- 1 | #include "a7105.ino" 2 | #include "hubsan.ino" 3 | 4 | void loop() { 5 | Serial.begin(115200); 6 | A7105_Setup(); //A7105_Reset(); 7 | int startTime, waitTime, hubsanWait,finishTime; 8 | //Serial.println("Preinit"); 9 | initialize(); 10 | 11 | startTime = micros(); 12 | while (1) { 13 | if (Serial.available()>4) { 14 | if (Serial.read()!=23) { 15 | throttle = rudder =aileron = elevator = 0; 16 | } else { 17 | throttle=Serial.read(); 18 | rudder=Serial.read(); 19 | aileron=Serial.read(); 20 | elevator=Serial.read(); 21 | } 22 | } 23 | 24 | //if (state!=0 && state!=1 & state!=128) 25 | //Serial.print("State: "); 26 | //Serial.println(state); 27 | hubsanWait = hubsan_cb(); 28 | // finishTime=micros(); 29 | // waitTime = hubsanWait - (micros() - startTime); 30 | // Serial.print("hubsanWait: " ); Serial.println(hubsanWait); 31 | // Serial.print("waitTime: " ); Serial.println(waitTime); 32 | //Serial.println(hubsanWait); 33 | delayMicroseconds(hubsanWait); 34 | startTime = micros(); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/protocol.ino: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | //#include 3 | 4 | static u8 proto_state; 5 | static u32 bind_time; 6 | 7 | #define PROTO_READY 0x01 8 | #define PROTO_BINDING 0x02 9 | #define PROTO_BINDDLG 0x04 10 | 11 | void PROTOCOL_SetBindState(u32 msec) 12 | { 13 | if (msec) { 14 | if (msec == 0xFFFFFFFF) 15 | bind_time = msec; 16 | else 17 | bind_time = millis() + msec; 18 | proto_state |= PROTO_BINDING; 19 | } else { 20 | proto_state &= ~PROTO_BINDING; 21 | } 22 | } 23 | --------------------------------------------------------------------------------