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