No known key found for this signature in database
				  
				  	
						GPG Key ID: 77E9DF7A0452BF64
				  	
				  
				
			
		
		
		
	
				 22 changed files with 802 additions and 691 deletions
			
			
		- 
					1remote/include/FrSkyD_cc2500.h
- 
					4remote/include/Multiprotocol.h
- 
					10remote/include/Validate.h
- 
					79remote/include/config.h
- 
					10remote/include/crc.h
- 
					4remote/include/eeprom.h
- 
					7remote/include/input.h
- 
					1remote/include/state.h
- 
					361remote/include/telemetry.h
- 
					36remote/include/tx_def.h
- 
					55remote/src/FrSkyD_cc2500.cpp
- 
					222remote/src/Multiprotocol.cpp
- 
					4remote/src/cc2500_spi.cpp
- 
					28remote/src/crc.cpp
- 
					25remote/src/eeprom.cpp
- 
					14remote/src/input.cpp
- 
					296remote/src/state.cpp
- 
					77remote/src/state_bind.cpp
- 
					29remote/src/state_fly.cpp
- 
					31remote/src/state_init.cpp
- 
					115remote/src/state_joy_calib.cpp
- 
					84remote/src/state_menu.cpp
| @ -1,7 +1,5 @@ | |||
| #ifndef __CRC_H_H__ | |||
| #define __CRC_H_H__ | |||
| #include <stdint.h> | |||
| 
 | |||
| uint32_t crc_update (uint32_t crc, uint8_t data); | |||
| 
 | |||
| #ifndef __CRC32_H_ | |||
| #define __CRC32_H_ | |||
| #include <Arduino.h> | |||
| uint32_t tiny_crc32(const void *data, unsigned int length); | |||
| #endif | |||
| @ -0,0 +1,361 @@ | |||
| /* | |||
|  This project is free software: you can redistribute it and/or modify | |||
|  it under the terms of the GNU General Public License as published by | |||
|  the Free Software Foundation, either version 3 of the License, or | |||
|  (at your option) any later version. | |||
| 
 | |||
|  Multiprotocol is distributed in the hope that it will be useful, | |||
|  but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | |||
|  GNU General Public License for more details. | |||
| 
 | |||
|  You should have received a copy of the GNU General Public License | |||
|  along with Multiprotocol.  If not, see <http://www.gnu.org/licenses/>. | |||
|  */ | |||
| //************************** | |||
| // Telemetry serial code   * | |||
| //************************** | |||
| #if defined TELEMETRY | |||
| 
 | |||
| uint8_t RetrySequence ; | |||
| 
 | |||
| #if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) | |||
|     #define MULTI_TIME              500 //in ms | |||
|     #define INPUT_SYNC_TIME         100 //in ms | |||
|     #define INPUT_ADDITIONAL_DELAY  100 // in 10µs, 100 => 1000 µs | |||
|     uint32_t lastMulti = 0; | |||
| #endif // MULTI_TELEMETRY/MULTI_STATUS | |||
| 
 | |||
| #if defined SPORT_TELEMETRY | |||
|     #define SPORT_TIME 12000    //12ms | |||
|     #define FRSKY_SPORT_PACKET_SIZE   8 | |||
|     #define FX_BUFFERS  4 | |||
|     uint32_t last = 0; | |||
|     uint8_t sport_counter=0; | |||
|     uint8_t RxBt = 0; | |||
|     uint8_t sport = 0; | |||
|     uint8_t pktx1[FRSKY_SPORT_PACKET_SIZE*FX_BUFFERS]; | |||
| 
 | |||
|     // Store for out of sequence packet | |||
|     uint8_t FrskyxRxTelemetryValidSequence ; | |||
|     struct t_fx_rx_frame | |||
|     { | |||
|         uint8_t valid ; | |||
|         uint8_t count ; | |||
|         uint8_t payload[6] ; | |||
|     } ; | |||
| 
 | |||
|     // Store for FrskyX telemetry | |||
|     struct t_fx_rx_frame FrskyxRxFrames[4] ; | |||
|     uint8_t NextFxFrameToForward ; | |||
|     #ifdef SPORT_POLLING | |||
|         uint8_t sport_rx_index[28] ; | |||
|         uint8_t ukindex ; | |||
|         uint8_t kindex ; | |||
|         uint8_t TxData[2]; | |||
|         uint8_t SportIndexPolling; | |||
|         uint8_t RxData[16] ; | |||
|         volatile uint8_t RxIndex=0 ; | |||
|         uint8_t sport_bytes=0; | |||
|         uint8_t skipped_id; | |||
|         uint8_t rx_counter=0; | |||
|     #endif | |||
| #endif // SPORT_TELEMETRY | |||
| 
 | |||
| #if defined HUB_TELEMETRY | |||
|     #define USER_MAX_BYTES 6 | |||
|     uint8_t prev_index; | |||
| #endif // HUB_TELEMETRY | |||
| 
 | |||
| #define START_STOP  0x7e | |||
| #define BYTESTUFF   0x7d | |||
| #define STUFF_MASK  0x20 | |||
| #define MAX_PKTX    10 | |||
| uint8_t pktx[MAX_PKTX]; | |||
| uint8_t indx; | |||
| uint8_t frame[18]; | |||
| 
 | |||
| #if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) | |||
| static void multi_send_header(uint8_t type, uint8_t len) | |||
| { | |||
|     Serial_write('M'); | |||
|     #ifdef MULTI_TELEMETRY | |||
|         Serial_write('P'); | |||
|         Serial_write(type); | |||
|     #else | |||
|         (void)type; | |||
|     #endif | |||
|     Serial_write(len); | |||
| } | |||
| 
 | |||
| #endif | |||
| 
 | |||
| #ifdef MULTI_TELEMETRY | |||
| static void multi_send_frskyhub() | |||
| { | |||
|     multi_send_header(MULTI_TELEMETRY_HUB, 9); | |||
|     for (uint8_t i = 0; i < 9; i++) | |||
|         Serial_write(frame[i]); | |||
| } | |||
| #endif | |||
| 
 | |||
| void frskySendStuffed() | |||
| { | |||
|     Serial_write(START_STOP); | |||
|     for (uint8_t i = 0; i < 9; i++) { | |||
|         if ((frame[i] == START_STOP) || (frame[i] == BYTESTUFF)) { | |||
|             Serial_write(BYTESTUFF); | |||
|             frame[i] ^= STUFF_MASK; | |||
|         } | |||
|         Serial_write(frame[i]); | |||
|     } | |||
|     Serial_write(START_STOP); | |||
| } | |||
| 
 | |||
| void frsky_check_telemetry(uint8_t *pkt,uint8_t len) | |||
| { | |||
|     uint8_t clen = pkt[0] + 3 ; | |||
|     if (len != clen)  // wrong length | |||
|         return; | |||
|     if(pkt[1] == rx_tx_addr[3] && | |||
|             pkt[2] == rx_tx_addr[2] ) { | |||
|         telemetry_link|=1;                              // Telemetry data is available | |||
|         TX_RSSI = pkt[len-2]; | |||
| 
 | |||
|         if(TX_RSSI >=128) | |||
|             TX_RSSI -= 128; | |||
|         else | |||
|             TX_RSSI += 128; | |||
| 
 | |||
|         TX_LQI = pkt[len-1]&0x7F; | |||
|         for (uint8_t i=3;i<len-2;i++) | |||
|             pktt[i]=pkt[i];                             // Buffer telemetry values to be sent | |||
| 
 | |||
|         if(pktt[6]>0 && pktt[6]<=10) { | |||
|             if (protocol==PROTO_FRSKYD) { | |||
|                 if ( ( pktt[7] & 0x1F ) == (telemetry_counter & 0x1F) ) { | |||
|                     uint8_t topBit = 0 ; | |||
|                     if ( telemetry_counter & 0x80 ) | |||
|                         if ( ( telemetry_counter & 0x1F ) != RetrySequence ) | |||
|                             topBit = 0x80 ; | |||
|                     telemetry_counter = ( (telemetry_counter+1)%32 ) | topBit ; // Request next telemetry frame | |||
|                 } else { | |||
|                     // incorrect sequence | |||
|                     RetrySequence = pktt[7] & 0x1F ; | |||
|                     telemetry_counter |= 0x80 ; | |||
|                     pktt[6]=0 ;                         // Discard current packet and wait for retransmit | |||
|                 } | |||
|             } | |||
|         } else | |||
|             pktt[6]=0;                                  // Discard packet | |||
|         // | |||
| #if defined SPORT_TELEMETRY && defined FRSKYX_CC2500_INO | |||
|         telemetry_lost=0; | |||
|         if (protocol==PROTO_FRSKYX) { | |||
|             uint16_t lcrc = frskyX_crc_x(&pkt[3], len-7 ) ; | |||
| 
 | |||
|             if ( ( (lcrc >> 8) == pkt[len-4]) && ( (lcrc & 0x00FF ) == pkt[len-3]) ) { | |||
|                 // Check if in sequence | |||
|                 if ( (pkt[5] & 0x0F) == 0x08 ) { | |||
|                     FrX_receive_seq = 0x08 ; | |||
|                     NextFxFrameToForward = 0 ; | |||
|                     FrskyxRxFrames[0].valid = 0 ; | |||
|                     FrskyxRxFrames[1].valid = 0 ; | |||
|                     FrskyxRxFrames[2].valid = 0 ; | |||
|                     FrskyxRxFrames[3].valid = 0 ; | |||
|                 } else if ( (pkt[5] & 0x03) == (FrX_receive_seq & 0x03 ) ) { | |||
|                     // OK to process | |||
|                     struct t_fx_rx_frame *p ; | |||
|                     uint8_t count ; | |||
|                     p = &FrskyxRxFrames[FrX_receive_seq & 3] ; | |||
|                     count = pkt[6] ; | |||
|                     if ( count <= 6 ) { | |||
|                         p->count = count ; | |||
|                         for ( uint8_t i = 0 ; i < count ; i += 1 ) | |||
|                             p->payload[i] = pkt[i+7] ; | |||
|                     } | |||
|                     else | |||
|                         p->count = 0 ; | |||
|                     p->valid = 1 ; | |||
| 
 | |||
|                     FrX_receive_seq = ( FrX_receive_seq + 1 ) & 0x03 ; | |||
| 
 | |||
|                     if ( FrskyxRxTelemetryValidSequence & 0x80 ) { | |||
|                         FrX_receive_seq = ( FrskyxRxTelemetryValidSequence + 1 ) & 3 ; | |||
|                         FrskyxRxTelemetryValidSequence &= 0x7F ; | |||
|                     } | |||
|                 } else { | |||
|                     // Save and request correct packet | |||
|                     struct t_fx_rx_frame *q ; | |||
|                     uint8_t count ; | |||
|                     // pkt[4] RSSI | |||
|                     // pkt[5] sequence control | |||
|                     // pkt[6] payload count | |||
|                     // pkt[7-12] payload | |||
|                     pktt[6] = 0 ; // Don't process | |||
|                     if ( (pkt[5] & 0x03) == ( ( FrX_receive_seq +1 ) & 3 ) ) { | |||
|                         q = &FrskyxRxFrames[(pkt[5] & 0x03)] ; | |||
|                         count = pkt[6] ; | |||
|                         if ( count <= 6 ) { | |||
|                             q->count = count ; | |||
|                             for ( uint8_t i = 0 ; i < count ; i += 1 ) { | |||
|                                 q->payload[i] = pkt[i+7] ; | |||
|                             } | |||
|                         } else | |||
|                             q->count = 0 ; | |||
|                         q->valid = 1 ; | |||
| 
 | |||
|                         FrskyxRxTelemetryValidSequence = 0x80 | ( pkt[5] & 0x03 ) ; | |||
|                     } | |||
| 
 | |||
|                      FrX_receive_seq = ( FrX_receive_seq & 0x03 ) | 0x04 ;  // Request re-transmission | |||
|                 } | |||
| 
 | |||
|                 if (((pktt[5] >> 4) & 0x0f) == 0x08) | |||
|                     FrX_send_seq = 0 ; | |||
|             } | |||
|         } | |||
| #endif | |||
|     } | |||
| } | |||
| 
 | |||
| void init_frskyd_link_telemetry() | |||
| { | |||
|     telemetry_link=0; | |||
|     telemetry_counter=0; | |||
|     v_lipo1=0; | |||
|     v_lipo2=0; | |||
|     RX_RSSI=0; | |||
|     TX_RSSI=0; | |||
|     RX_LQI=0; | |||
|     TX_LQI=0; | |||
| } | |||
| 
 | |||
| #if defined SPORT_TELEMETRY | |||
| /* SPORT details serial | |||
|             100K 8E2 normal-multiprotocol | |||
|             -every 12ms-or multiple of 12; %36 | |||
|             1  2  3  4  5  6  7  8  9  CRC DESCR | |||
|             7E 98 10 05 F1 20 23 0F 00 A6 SWR_ID | |||
|             7E 98 10 01 F1 33 00 00 00 C9 RSSI_ID | |||
|             7E 98 10 04 F1 58 00 00 00 A1 BATT_ID | |||
|             7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID | |||
|             7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID | |||
|             7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID | |||
|             7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID | |||
|             7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID | |||
|             7E BA 10 03 F1 E2 00 00 00 18 ADC2_ID | |||
| 
 | |||
| 
 | |||
|             Telemetry frames(RF) SPORT info | |||
|             15 bytes payload | |||
|             SPORT frame valid 6+3 bytes | |||
|             [00] PKLEN  0E 0E 0E 0E | |||
|             [01] TXID1  DD DD DD DD | |||
|             [02] TXID2  6D 6D 6D 6D | |||
|             [03] CONST  02 02 02 02 | |||
|             [04] RS/RB  2C D0 2C CE //D0;CE=2*RSSI;....2C = RX battery voltage(5V from Bec) | |||
|             [05] HD-SK  03 10 21 32 //TX/RX telemetry hand-shake bytes | |||
|             [06] NO.BT  00 00 06 03 //No.of valid SPORT frame bytes in the frame | |||
|             [07] STRM1  00 00 7E 00 | |||
|             [08] STRM2  00 00 1A 00 | |||
|             [09] STRM3  00 00 10 00 | |||
|             [10] STRM4  03 03 03 03 | |||
|             [11] STRM5  F1 F1 F1 F1 | |||
|             [12] STRM6  D1 D1 D0 D0 | |||
|             [13] CHKSUM1 --|2 CRC bytes sent by RX (calculated on RX side crc16/table) | |||
|             [14] CHKSUM2 --| | |||
|             +2  appended bytes automatically  RSSI and LQI/CRC bytes(len=0x0E+3); | |||
| 
 | |||
| 0x06    0x06    0x06    0x06    0x06 | |||
| 
 | |||
| 0x7E    0x00    0x03    0x7E    0x00 | |||
| 0x1A    0x00    0xF1    0x1A    0x00 | |||
| 0x10    0x00    0xD7    0x10    0x00 | |||
| 0x03    0x7E    0x00    0x03    0x7E | |||
| 0xF1    0x1A    0x00    0xF1    0x1A | |||
| 0xD7    0x10    0x00    0xD7    0x10 | |||
| 
 | |||
| 0xE1    0x1C    0xD0    0xEE    0x33 | |||
| 0x34    0x0A    0xC3    0x56    0xF3 | |||
| 
 | |||
|         */ | |||
| #if defined SPORT_POLLING || defined MULTI_TELEMETRY | |||
| const uint8_t PROGMEM Indices[] = { 0x00, 0xA1, 0x22, 0x83, 0xE4, 0x45, | |||
|                                     0xC6, 0x67, 0x48, 0xE9, 0x6A, 0xCB, | |||
|                                     0xAC, 0x0D, 0x8E, 0x2F, 0xD0, 0x71, | |||
|                                     0xF2, 0x53, 0x34, 0x95, 0x16, 0xB7, | |||
|                                     0x98, 0x39, 0xBA, 0x1B } ; | |||
| #endif | |||
| 
 | |||
| 
 | |||
| 
 | |||
| #endif | |||
| 
 | |||
| /**************************/ | |||
| /**************************/ | |||
| /**  Serial TX routines  **/ | |||
| /**************************/ | |||
| /**************************/ | |||
| 
 | |||
| // Routines for bit-bashed serial output | |||
| 
 | |||
| void Serial_write( uint8_t byte ) | |||
| { | |||
|     uint8_t temp ; | |||
|     uint8_t temp1 ; | |||
|     uint8_t byteLo ; | |||
| 
 | |||
|     #ifdef INVERT_SERIAL | |||
|         byte = ~byte ; | |||
|     #endif | |||
| 
 | |||
|     byteLo = byte ; | |||
|     byteLo >>= 7 ;      // Top bit | |||
|     if ( SerialControl.speed == SPEED_100K ) | |||
|     { | |||
|         #ifdef INVERT_SERIAL | |||
|                 byteLo |= 0x02 ;    // Parity bit | |||
|         #else | |||
|                 byteLo |= 0xFC ;    // Stop bits | |||
|         #endif | |||
|         // calc parity | |||
|         temp = byte ; | |||
|         temp >>= 4 ; | |||
|         temp = byte ^ temp ; | |||
|         temp1 = temp ; | |||
|         temp1 >>= 2 ; | |||
|         temp = temp ^ temp1 ; | |||
|         temp1 = temp ; | |||
|         temp1 <<= 1 ; | |||
|         temp ^= temp1 ; | |||
|         temp &= 0x02 ; | |||
|         #ifdef INVERT_SERIAL | |||
|                 byteLo ^= temp ; | |||
|         #else | |||
|                 byteLo |= temp ; | |||
|         #endif | |||
|     } | |||
|     else | |||
|     { | |||
|         byteLo |= 0xFE ;    // Stop bit | |||
|     } | |||
|     byte <<= 1 ; | |||
|     #ifdef INVERT_SERIAL | |||
|         byte |= 1 ;     // Start bit | |||
|     #endif | |||
|     uint8_t next = SerialControl.head + 2; | |||
|     if(next>=TXBUFFER_SIZE) | |||
|         next=0; | |||
|     if ( next != SerialControl.tail ) | |||
|     { | |||
|         SerialControl.data[SerialControl.head] = byte ; | |||
|         SerialControl.data[SerialControl.head+1] = byteLo ; | |||
|         SerialControl.head = next ; | |||
|     } | |||
|     if(!IS_TX_PAUSE_on) | |||
|         tx_resume(); | |||
| } | |||
| 
 | |||
| #endif // TELEMETRY | |||
| 
 | |||
| @ -1,22 +1,28 @@ | |||
| #include "Arduino.h"
 | |||
| #include "crc.h"
 | |||
| 
 | |||
| static uint32_t crc_table[16] = { | |||
| static const unsigned int tiny_crc32tab[16] = { | |||
|     0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, | |||
|     0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, | |||
|     0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, | |||
|     0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c | |||
| }; | |||
| 
 | |||
| uint32_t crc_update (uint32_t crc, uint8_t data) | |||
| { | |||
|     uint8_t tbl_idx; | |||
|     uint8_t mask = 0x0f; | |||
| 
 | |||
|     tbl_idx = crc ^ (data >> (0 * 4)); | |||
|     crc = (crc_table + (tbl_idx & mask)) ^ (crc >> 4); | |||
| uint32_t __tiny_crc32(const void *data, unsigned int length, uint32_t crc) | |||
| { | |||
|    const unsigned char *buf = (const unsigned char *)data; | |||
|    unsigned int i; | |||
| 
 | |||
|     tbl_idx = crc ^ (data >> (1 * 4)); | |||
|     crc = (crc_table + (tbl_idx & mask)) ^ (crc >> 4); | |||
|    for (i = 0; i < length; ++i) { | |||
|       crc ^= buf[i]; | |||
|       crc = tiny_crc32tab[crc & 0x0f] ^ (crc >> 4); | |||
|       crc = tiny_crc32tab[crc & 0x0f] ^ (crc >> 4); | |||
|    } | |||
| 
 | |||
|     return crc; | |||
|    return crc; | |||
| } | |||
| uint32_t tiny_crc32(const void *data, unsigned int length) | |||
| { | |||
|     // return value suitable for passing in next time, for final value invert it
 | |||
|     return __tiny_crc32(data, length, 42) ^ 0xffffff; | |||
| } | |||
| @ -0,0 +1,77 @@ | |||
| #include <LiquidCrystal_I2C.h>
 | |||
| #include <stdio.h>
 | |||
| #include "Arduino.h"
 | |||
| #include "FrSkyD_cc2500.h"
 | |||
| #include "state.h"
 | |||
| #include "input.h"
 | |||
| #include "eeprom.h"
 | |||
| #include "debug.h"
 | |||
| #include "tx_def.h"
 | |||
| #include "config.h"
 | |||
| 
 | |||
| 
 | |||
| LCD_state_bind::LCD_state_bind(void) { | |||
|     this->bind_time = DEFAULT_BIND_TIME; | |||
| } | |||
| void LCD_state_bind::enter(void) { | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("bind mode       "); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print("                "); | |||
|     this->time_enter = millis(); | |||
| } | |||
| 
 | |||
| void LCD_state_bind::update(void) | |||
| { | |||
|   debugln("blubber\n"); | |||
|   char line[17]; | |||
|   unsigned long time_in_ms = millis() - this->time_enter; | |||
|   unsigned long time_in_s = time_in_ms/1000; // to sec
 | |||
|   unsigned long remain_s = this->bind_time - time_in_s; | |||
| 
 | |||
|   snprintf(line,sizeof(line),"remaining sec %02lu",remain_s); | |||
|   lcd.setCursor(0,1); | |||
|   lcd.print(line); | |||
| 
 | |||
|     uint32_t end__ = micros(); | |||
|     uint32_t start = micros(); | |||
|     uint32_t next_callback_time; | |||
|     next_callback_time = initFrSky_2way(); | |||
|     while(1) { | |||
|         start = end__; | |||
|         next_callback_time = ReadFrSky_2way_bind(); | |||
| 
 | |||
| 
 | |||
|         // update time
 | |||
|         time_in_ms = millis() - this->time_enter; | |||
|         time_in_s = time_in_ms/1000; // to sec
 | |||
|         remain_s = this->bind_time - time_in_s; | |||
| 
 | |||
|         // print on lcd
 | |||
|         snprintf(line,sizeof(line),"%02lu",remain_s); | |||
|         lcd.setCursor(14,1); | |||
|         lcd.print(line); | |||
| 
 | |||
|         uint32_t wait_until = start + next_callback_time; | |||
|         end__ = micros(); | |||
| 
 | |||
|         if (end__ - start < next_callback_time) { | |||
|             uint32_t wait = next_callback_time; | |||
|             wait -= ((end__-start)); | |||
|             delayMicroseconds(wait); | |||
|             end__ += wait; | |||
|         } | |||
|         end__ = micros(); | |||
| 
 | |||
|         if (remain_s == 0) | |||
|             break; | |||
|     } | |||
| 
 | |||
|     // cange to menu when done
 | |||
|     new_state = s_menu; | |||
| } | |||
| 
 | |||
| void LCD_state_bind::leave(void) | |||
| { | |||
|     lcd.clear(); | |||
| } | |||
| @ -0,0 +1,29 @@ | |||
| #include <LiquidCrystal_I2C.h>
 | |||
| #include <stdio.h>
 | |||
| #include "Arduino.h"
 | |||
| #include "FrSkyD_cc2500.h"
 | |||
| #include "state.h"
 | |||
| #include "input.h"
 | |||
| #include "eeprom.h"
 | |||
| #include "debug.h"
 | |||
| #include "tx_def.h"
 | |||
| 
 | |||
| LCD_state_fly::LCD_state_fly(void) { | |||
| } | |||
| 
 | |||
| void LCD_state_fly::enter(void) { | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("fly mode        "); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print("                "); | |||
|     this->time_enter = millis(); | |||
| } | |||
| 
 | |||
| void LCD_state_fly::update(void) | |||
| { | |||
| 
 | |||
| } | |||
| void LCD_state_fly::leave(void) | |||
| { | |||
|     lcd.clear(); | |||
| } | |||
| @ -0,0 +1,31 @@ | |||
| #include <LiquidCrystal_I2C.h>
 | |||
| #include <stdio.h>
 | |||
| #include "Arduino.h"
 | |||
| #include "FrSkyD_cc2500.h"
 | |||
| #include "state.h"
 | |||
| #include "input.h"
 | |||
| #include "eeprom.h"
 | |||
| #include "debug.h"
 | |||
| #include "tx_def.h"
 | |||
| 
 | |||
| LCD_state_init::LCD_state_init(void) { | |||
| } | |||
| void LCD_state_init::enter(void) { | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("    wellcome    "); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print("    phschoen    "); | |||
|     this->time_enter = millis(); | |||
| } | |||
| void LCD_state_init::update(void) | |||
| { | |||
|     uint32_t diff; | |||
|     diff = millis() - this->time_enter; | |||
|     if (diff > 5 * 1000) { | |||
|         new_state = s_joy; | |||
|     } | |||
| } | |||
| void LCD_state_init::leave(void) | |||
| { | |||
|     lcd.clear(); | |||
| } | |||
| @ -0,0 +1,115 @@ | |||
| #include <LiquidCrystal_I2C.h>
 | |||
| #include <stdio.h>
 | |||
| #include "Arduino.h"
 | |||
| #include "FrSkyD_cc2500.h"
 | |||
| #include "state.h"
 | |||
| #include "input.h"
 | |||
| #include "eeprom.h"
 | |||
| #include "debug.h"
 | |||
| #include "tx_def.h"
 | |||
| 
 | |||
| LCD_state_joy_calibration::LCD_state_joy_calibration(void) { | |||
| 
 | |||
| } | |||
| void LCD_state_joy_calibration::enter(void) { | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("calib. start    "); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print("move all sticks "); | |||
|     delay(500); | |||
| } | |||
| void show_dots(int row, int number) { | |||
|     lcd.setCursor(0,row); | |||
|     for(int c = 0; c < 16;++c) { | |||
|         if (c < number) | |||
|             lcd.print("."); | |||
|         else | |||
|             lcd.print(" "); | |||
|     } | |||
| } | |||
| void LCD_state_joy_calibration::update(void) { | |||
|     int8_t turns = 50; | |||
|     int8_t i; | |||
| 
 | |||
|     // init min/max
 | |||
|     input.calibration_reset(); | |||
| 
 | |||
|     // min max calibration
 | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("min max Calib.  "); | |||
|     show_dots(1,16); | |||
|     i = turns; | |||
|     while(i > 0) { | |||
|         input.update(); | |||
|         if (true == input.calibration_update()) { | |||
|             i = turns; | |||
|         }else { | |||
|             i -= 1; | |||
|             show_dots(1,(i *16)/turns); | |||
|         } | |||
|         delay(100); | |||
|     } | |||
| 
 | |||
|     // center
 | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("center sticks   "); | |||
|     i = turns; | |||
|     while(i > 0) { | |||
|         input.update(); | |||
|         if (false == input.is_centered()) { | |||
|             i = turns; | |||
|         }else { | |||
|             i -= 1; | |||
|             show_dots(1,(i *16)/turns); | |||
|         } | |||
|         delay(100); | |||
|     } | |||
| 
 | |||
|     for (uint8_t _ch = 0; _ch < 4 ; ++_ch) { | |||
|         enum Input::input_channels ch = (enum Input::input_channels) _ch; | |||
|         lcd.setCursor(0,0); | |||
|         lcd.print("move to max:    "); | |||
|         lcd.setCursor(0,1); | |||
|         lcd.print("                "); | |||
|         lcd.setCursor(0,1); | |||
|         lcd.print(ch_name[ch]); | |||
| 
 | |||
|         i = turns; | |||
|         while(i>0) { | |||
|             delay(50); | |||
|             input.update(); | |||
| 
 | |||
|             input.print_ch(ch); | |||
|             if (input.is_high(ch)) { | |||
|                 i--; | |||
|                 continue; | |||
|             } | |||
| 
 | |||
|             if (input.is_low(ch)) { | |||
|                 input.invert_ch(ch); | |||
|                 debug("invert"); | |||
|                 i = turns; | |||
|                 continue; | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
|     struct Input::ch_config ch_config[Input::CH_COUNT]; | |||
|     input.get_calibration(ch_config); | |||
| 
 | |||
| 
 | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("center again    "); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print("all sticks      "); | |||
|     while (false == input.is_centered()) { | |||
|         input.update(); | |||
|     } | |||
|     new_state = s_menu; | |||
| } | |||
| void LCD_state_joy_calibration::leave(void) { | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("finished "); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print("calibration"); | |||
| } | |||
| @ -0,0 +1,84 @@ | |||
| #include <LiquidCrystal_I2C.h>
 | |||
| #include <stdio.h>
 | |||
| #include "Arduino.h"
 | |||
| #include "FrSkyD_cc2500.h"
 | |||
| #include "state.h"
 | |||
| #include "input.h"
 | |||
| #include "eeprom.h"
 | |||
| #include "debug.h"
 | |||
| #include "tx_def.h"
 | |||
| 
 | |||
| LCD_state_menu::LCD_state_menu(void) { | |||
| } | |||
| void LCD_state_menu::enter(void) { | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print("menu mode       "); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print("                "); | |||
|     this->curr_selected = 0; | |||
| } | |||
| 
 | |||
| void LCD_state_menu::update(void) | |||
| { | |||
|     struct { | |||
|         char name[15]; | |||
|         State * state; | |||
|     } menus[] = { | |||
|         { "Flight        ", s_fly }, | |||
|         { "Bind          ", s_bind }, | |||
|         { "Joy calib     ", s_joy }, | |||
|         { "HF calib      ", NULL }, | |||
|         { "              ", NULL }, | |||
|     }; | |||
| 
 | |||
|     bool wait = false; | |||
|     char curr[2][16]; | |||
|     snprintf(curr[0], sizeof(curr[0]), "> %s", menus[this->curr_selected].name); | |||
|     snprintf(curr[1], sizeof(curr[1]), "  %s", menus[this->curr_selected+1].name); | |||
| 
 | |||
|     lcd.setCursor(0,0); | |||
|     lcd.print(curr[0]); | |||
|     lcd.setCursor(0,1); | |||
|     lcd.print(curr[1]); | |||
| 
 | |||
|     if (false == input.is_centered(Input::MENU_UP_DOWN)) { | |||
|         if (input.is_low(Input::MENU_UP_DOWN)){ | |||
|             this->curr_selected +=1; | |||
|             if ( this->curr_selected > 3) | |||
|                 this->curr_selected = 3; | |||
|             else | |||
|                 wait = true; | |||
|         } | |||
|         if (input.is_high(Input::MENU_UP_DOWN)){ | |||
|             this->curr_selected -=1; | |||
|             if ( this->curr_selected < 0) | |||
|                 this->curr_selected = 0; | |||
|             else | |||
|                 wait = true; | |||
|         } | |||
|     } | |||
| 
 | |||
|     if (input.is_high(Input::MENU_LEFT_RIGHT)) { | |||
|         lcd.setCursor(0,0); | |||
|         lcd.print("entering         "); | |||
|         lcd.setCursor(0,1); | |||
|         lcd.print(menus[this->curr_selected].name); | |||
|         // do wait until its centered
 | |||
|         while(false == input.is_centered(Input::MENU_LEFT_RIGHT)) { | |||
|             input.update(); | |||
|         } | |||
| 
 | |||
|         if (menus[this->curr_selected].state != NULL) { | |||
|             new_state = menus[this->curr_selected].state; | |||
|         } | |||
|         wait = true; | |||
|     } | |||
| 
 | |||
|     if(wait) | |||
|         delay(500); | |||
| } | |||
| 
 | |||
| void LCD_state_menu::leave(void) | |||
| { | |||
|     lcd.clear(); | |||
| } | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue