Switch all protocols to use a resolution of 2048

- Change how PPM is handled with a resolution of 2048 and scaled to match serial input range. PPM is now fully scaled for all protocols which was not the case before. If you are using PPM, you might have to adjust the end points depending on the protocols.
 - Change all range conversions to use 2048 where possible
 - Updated all protocols with new range functions
 - Protocols which are taking advantage of 2048 are Assan, FrSky V/D/X, DSM, Devo, WK2x01
 - Renamed AUX xto CHx for code readbility
This commit is contained in:
Pascal Langer 2018-01-08 19:37:14 +01:00
parent 11287cb9c0
commit 984aa3f413
39 changed files with 462 additions and 506 deletions

View File

@ -195,7 +195,7 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
}
}
if(offset==1024) // Use channel 15 as an input
offset=map(Channel_data[14],CHANNEL_MIN_100,CHANNEL_MAX_100,-300,300);
offset=convert_channel_16b_nolimit(CH15,-300,300);
if(old_offset==offset) // offset is the same as before...
return;

View File

@ -171,8 +171,9 @@ static void AFHDS2A_build_packet(uint8_t type)
packet[0] = 0x58;
for(uint8_t ch=0; ch<14; ch++)
{
packet[9 + ch*2] = Servo_data[CH_AETR[ch]]&0xFF;
packet[10 + ch*2] = (Servo_data[CH_AETR[ch]]>>8)&0xFF;
uint16_t channelMicros = convert_channel_ppm(CH_AETR[ch]);
packet[9 + ch*2] = channelMicros&0xFF;
packet[10 + ch*2] = (channelMicros>>8)&0xFF;
}
break;
case AFHDS2A_PACKET_FAILSAFE:
@ -180,7 +181,8 @@ static void AFHDS2A_build_packet(uint8_t type)
for(uint8_t ch=0; ch<14; ch++)
{
#ifdef FAILSAFE_ENABLE
uint16_t failsafeMicros = (Failsafe_data[CH_AETR[ch]]*5)/8+860;
uint16_t failsafeMicros = Failsafe_data[CH_AETR[ch]];
failsafeMicros = (((failsafeMicros<<2)+failsafeMicros)>>3)+860;
if( failsafeMicros!=FAILSAFE_CHANNEL_HOLD+860)
{ // Failsafe values
packet[9 + ch*2] = failsafeMicros & 0xff;

View File

@ -50,16 +50,13 @@ void ASSAN_init()
void ASSAN_send_packet()
{
uint16_t temp;
for(uint8_t i=0;i<8;i++)
{
if(mode_select != MODE_SERIAL) // If in PPM mode extend the output to 1000...2000µs
temp=convert_channel_16b_nolim(i,1000,2000);
else
temp=Servo_data[i];
temp<<=3;
packet[2*i]=temp>>8;
packet[2*i+1]=temp;
uint16_t val=Channel_data[i];
val=((val<<2)+val)+(860<<3); // PPM value <<3
packet[2*i]=val>>8;
packet[2*i+1]=val;
}
for(uint8_t i=0;i<ASSAN_ADDRESS_LENGTH;i++)
packet[16+i]=packet[23-i];

View File

@ -12,13 +12,12 @@
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STM32_BOARD
/************************************/
/************************************/
/** Arduino replacement routines **/
/************************************/
// replacement map()
int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max)
int16_t map16b( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max)
{
// return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
long y ;
@ -29,6 +28,7 @@ int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t
return x + out_min ;
}
#ifndef STM32_BOARD
// replacement millis() and micros()
// These work polled, no interrupts
// micros() MUST be called at least once every 32 milliseconds
@ -38,6 +38,17 @@ uint32_t TotalMicros ;
uint32_t TotalMillis ;
uint8_t Correction ;
int16_t map( int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max)
{
// return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
long y ;
x -= in_min ;
y = out_max - out_min ;
y *= x ;
x = y / (in_max - in_min) ;
return x + out_min ;
}
uint32_t micros()
{
uint16_t elapsed ;

View File

@ -90,28 +90,28 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
//Flags packet[2]
packet[2] = 0x00;
if(Servo_AUX1)
if(CH5_SW)
packet[2] = BAYANG_FLAG_FLIP;
if(Servo_AUX2)
if(CH6_SW)
packet[2] |= BAYANG_FLAG_RTH;
if(Servo_AUX3)
if(CH7_SW)
packet[2] |= BAYANG_FLAG_PICTURE;
if(Servo_AUX4)
if(CH8_SW)
packet[2] |= BAYANG_FLAG_VIDEO;
if(Servo_AUX5)
if(CH9_SW)
{
packet[2] |= BAYANG_FLAG_HEADLESS;
dyntrim = 0;
}
//Flags packet[3]
packet[3] = 0x00;
if(Servo_AUX6)
if(CH10_SW)
packet[3] = BAYANG_FLAG_INVERTED;
if(Servo_AUX7)
if(CH11_SW)
dyntrim = 0;
if(Servo_AUX8)
if(CH12_SW)
packet[3] |= BAYANG_FLAG_TAKE_OFF;
if(Servo_AUX9)
if(CH13_SW)
packet[3] |= BAYANG_FLAG_EMG_STOP;
//Aileron
val = convert_channel_10b(AILERON);

View File

@ -208,7 +208,7 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
case 3 : adjusted_x = THROTTLE; break;
default : adjusted_x = x; break;
}
holdValue = map(limit_channel_100(adjusted_x),servo_min_100,servo_max_100,1000,2000); // valid channel values are 1000 to 2000
holdValue = convert_channel_16b_limit(adjusted_x,1000,2000); // valid channel values are 1000 to 2000
if (bindMode)
{
switch (adjusted_x)

View File

@ -54,13 +54,13 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
// throttle : 0x00 - 0xFF
throttle=convert_channel_8b(THROTTLE);
// rudder
rudder = convert_channel_8b_scale(RUDDER,0x44,0xBC); // yaw right : 0x80 (neutral) - 0xBC (right)
rudder = convert_channel_16b_limit(RUDDER,0x44,0xBC); // yaw right : 0x80 (neutral) - 0xBC (right)
if (rudder<=0x80)
rudder=0x80-rudder; // yaw left : 0x00 (neutral) - 0x3C (left)
// elevator : 0xBB - 0x7F - 0x43
elevator = convert_channel_8b_scale(ELEVATOR, 0x43, 0xBB);
elevator = convert_channel_16b_limit(ELEVATOR, 0x43, 0xBB);
// aileron : 0x43 - 0x7F - 0xBB
aileron = convert_channel_8b_scale(AILERON, 0x43, 0xBB);
aileron = convert_channel_16b_limit(AILERON, 0x43, 0xBB);
if (bind)
packet[0]= 0xaa;
@ -86,20 +86,20 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
{
// rate
packet[13] = CG023_FLAG_RATE_HIGH
| GET_FLAG(Servo_AUX1,CG023_FLAG_FLIP)
| GET_FLAG(Servo_AUX2,CG023_FLAG_LED_OFF)
| GET_FLAG(Servo_AUX3,CG023_FLAG_STILL)
| GET_FLAG(Servo_AUX4,CG023_FLAG_VIDEO)
| GET_FLAG(Servo_AUX5,CG023_FLAG_EASY);
| GET_FLAG(CH5_SW,CG023_FLAG_FLIP)
| GET_FLAG(CH6_SW,CG023_FLAG_LED_OFF)
| GET_FLAG(CH7_SW,CG023_FLAG_STILL)
| GET_FLAG(CH8_SW,CG023_FLAG_VIDEO)
| GET_FLAG(CH9_SW,CG023_FLAG_EASY);
}
else
{// YD829
// rate
packet[13] = YD829_FLAG_RATE_HIGH
| GET_FLAG(Servo_AUX1,YD829_FLAG_FLIP)
| GET_FLAG(Servo_AUX3,YD829_FLAG_STILL)
| GET_FLAG(Servo_AUX4,YD829_FLAG_VIDEO)
| GET_FLAG(Servo_AUX5,YD829_FLAG_HEADLESS);
| GET_FLAG(CH5_SW,YD829_FLAG_FLIP)
| GET_FLAG(CH7_SW,YD829_FLAG_STILL)
| GET_FLAG(CH8_SW,YD829_FLAG_VIDEO)
| GET_FLAG(CH9_SW,YD829_FLAG_HEADLESS);
}
packet[14] = 0;

View File

@ -57,18 +57,18 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
packet[3] = rx_tx_addr[2];
packet[4] = rx_tx_addr[3];
// packet[5] to [8] (aircraft id) is filled during bind for blue board
uint16_t aileron=map(limit_channel_100(AILERON),servo_min_100,servo_max_100,1000,2000);
uint16_t elevator=map(limit_channel_100(ELEVATOR),servo_min_100,servo_max_100,2000,1000);
uint16_t throttle=map(limit_channel_100(THROTTLE),servo_min_100,servo_max_100,1000,2000);
uint16_t rudder=map(limit_channel_100(RUDDER),servo_min_100,servo_max_100,2000,1000);
uint16_t aileron= convert_channel_16b_limit(AILERON ,1000,2000);
uint16_t elevator=convert_channel_16b_limit(ELEVATOR,2000,1000);
uint16_t throttle=convert_channel_16b_limit(THROTTLE,1000,2000);
uint16_t rudder= convert_channel_16b_limit(RUDDER ,2000,1000);
// Channel 5 - flip flag
packet[12+offset] = GET_FLAG(Servo_AUX1,CX10_FLAG_FLIP); // flip flag applied on rudder
packet[12+offset] = GET_FLAG(CH5_SW,CX10_FLAG_FLIP); // flip flag applied on rudder
// Channel 6 - rate mode is 2 lsb of packet 13
if(Servo_data[AUX2] > PPM_MAX_COMMAND) // rate 3 / headless on CX-10A
if(CH6_SW) // rate 3 / headless on CX-10A
flags = 0x02;
else
if(Servo_data[AUX2] < PPM_MIN_COMMAND)
if(Channel_data[CH6] < CHANNEL_MIN_COMMAND)
flags = 0x00; // rate 1
else
flags = 0x01; // rate 2
@ -78,66 +78,66 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
switch(sub_protocol)
{
case CX10_BLUE:
flags |= GET_FLAG(!Servo_AUX3, 0x10) // Channel 7 - picture
|GET_FLAG( Servo_AUX4, 0x08); // Channel 8 - video
flags |= GET_FLAG(!CH7_SW, 0x10) // Channel 7 - picture
|GET_FLAG( CH8_SW, 0x08); // Channel 8 - video
break;
case Q282:
case Q242:
case Q222:
memcpy(&packet[15], "\x10\x10\xaa\xaa\x00\x00", 6);
//FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
flags2 = GET_FLAG(Servo_AUX1, 0x80) // Channel 5 - FLIP
|GET_FLAG(!Servo_AUX2, 0x40) // Channel 6 - LED
|GET_FLAG(Servo_AUX5, 0x08) // Channel 9 - HEADLESS
|GET_FLAG(Servo_AUX7, 0x04) // Channel 11 - XCAL
|GET_FLAG(Servo_AUX8, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509
flags2 = GET_FLAG(CH5_SW, 0x80) // Channel 5 - FLIP
|GET_FLAG(!CH6_SW, 0x40) // Channel 6 - LED
|GET_FLAG(CH9_SW, 0x08) // Channel 9 - HEADLESS
|GET_FLAG(CH11_SW, 0x04) // Channel 11 - XCAL
|GET_FLAG(CH12_SW, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509
if(sub_protocol==Q242)
{
flags=2;
flags2|= GET_FLAG(Servo_AUX3,0x01) // Channel 7 - picture
|GET_FLAG(Servo_AUX4,0x10); // Channel 8 - video
flags2|= GET_FLAG(CH7_SW,0x01) // Channel 7 - picture
|GET_FLAG(CH8_SW,0x10); // Channel 8 - video
packet[17]=0x00;
packet[18]=0x00;
}
else
{ // Q282 & Q222
flags=3; // expert
if(Servo_AUX4) // Channel 8 - Q282 video / Q222 Module 1
if(CH8_SW) // Channel 8 - Q282 video / Q222 Module 1
{
if (!(video_state & 0x20)) video_state ^= 0x21;
}
else
if (video_state & 0x20) video_state &= 0x01;
flags2 |= video_state
|GET_FLAG(Servo_AUX3,0x10); // Channel 7 - Q282 picture / Q222 Module 2
|GET_FLAG(CH7_SW,0x10); // Channel 7 - Q282 picture / Q222 Module 2
}
if(Servo_AUX6) flags |=0x80; // Channel 10 - RTH
if(CH10_SW) flags |=0x80; // Channel 10 - RTH
break;
case DM007:
aileron = 3000 - aileron;
//FLIP|MODE|PICTURE|VIDEO|HEADLESS
flags2= GET_FLAG(Servo_AUX3,CX10_FLAG_SNAPSHOT) // Channel 7 - picture
|GET_FLAG(Servo_AUX4,CX10_FLAG_VIDEO); // Channel 8 - video
if(Servo_AUX5) flags |= CX10_FLAG_HEADLESS; // Channel 9 - headless
flags2= GET_FLAG(CH7_SW,CX10_FLAG_SNAPSHOT) // Channel 7 - picture
|GET_FLAG(CH8_SW,CX10_FLAG_VIDEO); // Channel 8 - video
if(CH9_SW) flags |= CX10_FLAG_HEADLESS; // Channel 9 - headless
break;
case JC3015_2:
aileron = 3000 - aileron;
elevator = 3000 - elevator;
//FLIP|MODE|LED|DFLIP
if(Servo_AUX4) packet[12] &= ~CX10_FLAG_FLIP;
if(CH8_SW) packet[12] &= ~CX10_FLAG_FLIP;
case JC3015_1:
//FLIP|MODE|PICTURE|VIDEO
flags2= GET_FLAG(Servo_AUX3,_BV(3)) // Channel 7
|GET_FLAG(Servo_AUX4,_BV(4)); // Channel 8
flags2= GET_FLAG(CH7_SW,_BV(3)) // Channel 7
|GET_FLAG(CH8_SW,_BV(4)); // Channel 8
break;
case MK33041:
elevator = 3000 - elevator;
//FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
flags|=GET_FLAG(Servo_AUX3,_BV(7)) // Channel 7 - picture
|GET_FLAG(Servo_AUX6,_BV(2)); // Channel 10 - rth
flags2=GET_FLAG(Servo_AUX4,_BV(0)) // Channel 8 - video
|GET_FLAG(Servo_AUX5,_BV(5)); // Channel 9 - headless
flags|=GET_FLAG(CH7_SW,_BV(7)) // Channel 7 - picture
|GET_FLAG(CH10_SW,_BV(2)); // Channel 10 - rth
flags2=GET_FLAG(CH8_SW,_BV(0)) // Channel 8 - video
|GET_FLAG(CH9_SW,_BV(5)); // Channel 9 - headless
break;
}
packet[5+offset] = lowByte(aileron);

View File

@ -35,30 +35,73 @@ void InitFailsafe()
#endif
}
#endif
#ifdef ENABLE_PPM
void InitPPM()
{
for(uint8_t i=0;i<NUM_CHN;i++)
PPM_data[i]=PPM_MAX_100+PPM_MIN_100;
PPM_data[THROTTLE]=PPM_MIN_100*2;
}
#endif
void InitChannel()
{
for(uint8_t i=0;i<NUM_CHN;i++)
Channel_data[i]=1024;
#ifdef FAILSAFE_ENABLE
#ifdef FAILSAFE_THROTTLE_LOW_VAL
Channel_data[THROTTLE]=(uint16_t)FAILSAFE_THROTTLE_LOW_VAL; //0=-125%, 204=-100%
#else
Channel_data[THROTTLE]=204;
#endif
}
/************************/
/** Convert routines **/
/************************/
// Channel value is converted to 8bit values full scale
// Revert a channel and store it
void reverse_channel(uint8_t num)
{
uint16_t val=2048-Channel_data[num];
if(val>=2048) val=2047;
Channel_data[num]=val;
}
// Channel value is converted to ppm 860<->2140 -125%<->+125% and 988<->2012 -100%<->+100%
uint16_t convert_channel_ppm(uint8_t num)
{
uint16_t val=Channel_data[num];
return (((val<<2)+val)>>3)+860; //value range 860<->2140 -125%<->+125%
}
// Channel value 100% is converted to 10bit values 0<->1023
uint16_t convert_channel_10b(uint8_t num)
{
uint16_t val=Channel_data[num];
val=((val<<2)+val)>>3;
if(val<=128) return 0;
if(val>=1152) return 1023;
return val-128;
}
// Channel value 100% is converted to 8bit values 0<->255
uint8_t convert_channel_8b(uint8_t num)
{
return (uint8_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,0,255));
uint16_t val=Channel_data[num];
val=((val<<2)+val)>>5;
if(val<=32) return 0;
if(val>=288) return 255;
return val-32;
}
// Channel value is converted to 8bit values to provided values scale
uint8_t convert_channel_8b_scale(uint8_t num,uint8_t min,uint8_t max)
// Channel value 100% is converted to value scaled
int16_t convert_channel_16b_limit(uint8_t num,int16_t min,int16_t max)
{
return (uint8_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,min,max));
int32_t val=limit_channel_100(num); // 204<->1844
val=(val-CHANNEL_MIN_100)*(max-min)/(CHANNEL_MAX_100-CHANNEL_MIN_100)+min;
return (uint16_t)val;
}
// Channel value -125%<->125% is scaled to 16bit value with no limit
int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max)
{
int32_t val=Channel_data[num]; // 0<->2047
val=(val-CHANNEL_MIN_100)*(max-min)/(CHANNEL_MAX_100-CHANNEL_MIN_100)+min;
return (uint16_t)val;
}
// Channel value is converted sign + magnitude 8bit values
@ -69,27 +112,25 @@ uint8_t convert_channel_s8b(uint8_t num)
return (ch < 128 ? 127-ch : ch);
}
// Channel value is converted to 10bit values
uint16_t convert_channel_10b(uint8_t num)
// Channel value is limited to 100%
uint16_t limit_channel_100(uint8_t num)
{
return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,1,1023));
}
// Channel value is multiplied by 1.5
uint16_t convert_channel_frsky(uint8_t num)
{
return Servo_data[num] + Servo_data[num]/2;
if(Channel_data[num]>=CHANNEL_MAX_100)
return CHANNEL_MAX_100;
if (Channel_data[num]<=CHANNEL_MIN_100)
return CHANNEL_MIN_100;
return Channel_data[num];
}
// Channel value is converted for HK310
void convert_channel_HK310(uint8_t num, uint8_t *low, uint8_t *high)
{
uint16_t temp=0xFFFF-(4*Servo_data[num])/3;
uint16_t temp=0xFFFF-(3440+((Channel_data[num]*5)>>1))/3;
*low=(uint8_t)(temp&0xFF);
*high=(uint8_t)(temp>>8);
}
// Failsafe value is converted for HK310
#ifdef FAILSAFE_ENABLE
// Failsafe value is converted for HK310
void convert_failsafe_HK310(uint8_t num, uint8_t *low, uint8_t *high)
{
uint16_t temp=0xFFFF-(3440+((Failsafe_data[num]*5)>>1))/3;
@ -98,27 +139,11 @@ void convert_failsafe_HK310(uint8_t num, uint8_t *low, uint8_t *high)
}
#endif
// Channel value is converted to 16bit values
uint16_t convert_channel_16b(uint8_t num, int16_t out_min, int16_t out_max)
// Channel value for FrSky (PPM is multiplied by 1.5)
uint16_t convert_channel_frsky(uint8_t num)
{
return (uint16_t) (map(limit_channel_100(num),servo_min_100,servo_max_100,out_min,out_max));
}
// Channel value is converted to 16bit values with no limit
uint16_t convert_channel_16b_nolim(uint8_t num, int16_t out_min, int16_t out_max)
{
return (uint16_t) (map(Servo_data[num],servo_min_100,servo_max_100,out_min,out_max));
}
// Channel value is limited to PPM_100
uint16_t limit_channel_100(uint8_t ch)
{
if(Servo_data[ch]>servo_max_100)
return servo_max_100;
else
if (Servo_data[ch]<servo_min_100)
return servo_min_100;
return Servo_data[ch];
uint16_t val=Channel_data[num];
return ((val*15)>>4)+1290;
}
/******************************/

View File

@ -120,8 +120,9 @@ static void __attribute__((unused)) CORONA_send_packet()
memset(packet+9, 0x00, 4);
for(uint8_t i=0; i<8; i++)
{ // Channel values are packed
packet[i+1] = Servo_data[i];
packet[9 + (i>>1)] |= (i&0x01)?(Servo_data[i]>>4)&0xF0:(Servo_data[i]>>8)&0x0F;
uint16_t val=convert_channel_ppm(i);
packet[i+1] = val;
packet[9 + (i>>1)] |= (i&0x01)?(val>>4)&0xF0:(val>>8)&0x0F;
}
//TX ID

View File

@ -52,19 +52,19 @@ static void __attribute__((unused)) DM002_send_packet(uint8_t bind)
{
packet[0]=0x55;
// Throttle : 0 .. 200
packet[1]=convert_channel_8b_scale(THROTTLE,0,200);
packet[1]=convert_channel_16b_limit(THROTTLE,0,200);
// Other channels min 0x57, mid 0x7F, max 0xA7
packet[2] = convert_channel_8b_scale(RUDDER,0x57,0xA7);
packet[3] = convert_channel_8b_scale(AILERON, 0x57,0xA7);
packet[4] = convert_channel_8b_scale(ELEVATOR, 0xA7, 0x57);
packet[2] = convert_channel_16b_limit(RUDDER,0x57,0xA7);
packet[3] = convert_channel_16b_limit(AILERON, 0x57,0xA7);
packet[4] = convert_channel_16b_limit(ELEVATOR, 0xA7, 0x57);
// Features
packet[9] = GET_FLAG(Servo_AUX1,DM002_FLAG_FLIP)
| GET_FLAG(!Servo_AUX2,DM002_FLAG_LED)
| GET_FLAG(Servo_AUX3,DM002_FLAG_CAMERA1)
| GET_FLAG(Servo_AUX4,DM002_FLAG_CAMERA2)
| GET_FLAG(Servo_AUX5,DM002_FLAG_HEADLESS)
| GET_FLAG(Servo_AUX6,DM002_FLAG_RTH)
| GET_FLAG(!Servo_AUX7,DM002_FLAG_HIGH);
packet[9] = GET_FLAG(CH5_SW,DM002_FLAG_FLIP)
| GET_FLAG(!CH6_SW,DM002_FLAG_LED)
| GET_FLAG(CH7_SW,DM002_FLAG_CAMERA1)
| GET_FLAG(CH8_SW,DM002_FLAG_CAMERA2)
| GET_FLAG(CH9_SW,DM002_FLAG_HEADLESS)
| GET_FLAG(CH10_SW,DM002_FLAG_RTH)
| GET_FLAG(!CH11_SW,DM002_FLAG_HIGH);
// Packet counter
if(packet_count&0x03)
{

View File

@ -245,7 +245,6 @@ static void __attribute__((unused)) DSM_update_channels()
static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
{
uint16_t max = 2047;
uint8_t bits = 11;
if(prev_option!=option)
@ -261,10 +260,7 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
packet[0] = (0xff ^ cyrfmfg_id[2]);
packet[1] = (0xff ^ cyrfmfg_id[3]);
if(sub_protocol==DSM2_22)
{
max=1023; // Only DSM_22 is using a resolution of 1024
bits=10;
}
bits=10; // Only DSM_22 is using a resolution of 1024
}
for (uint8_t i = 0; i < 7; i++)
@ -276,7 +272,8 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
/* Spektrum own remotes transmit normal values during bind and actually
* use this (e.g. Nano CP X) to select the transmitter mode (e.g. computer vs
* non-computer radio, so always end normal output */
value=map(Servo_data[CH_TAER[idx]],servo_min_125,servo_max_125,0,max);
value=Channel_data[CH_TAER[idx]];
if(bits==10) value>>=1;
value |= (upper && i==0 ? 0x8000 : 0) | (idx << bits);
}
packet[i*2+2] = (value >> 8) & 0xff;

View File

@ -148,7 +148,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
uint8_t sign = 0x0b;
for (uint8_t i = 0; i < 4; i++)
{
int16_t value=map(Servo_data[CH_EATR[ch_idx * 4 + i]],servo_min_100,servo_max_100,-1600,1600);//range -1600..+1600
int16_t value=convert_channel_16b_nolimit(CH_EATR[ch_idx * 4 + i],-1600,1600);//range -1600..+1600
if(value < 0)
{
value = -value;

View File

@ -84,19 +84,19 @@ static void __attribute__((unused)) ESKY150_bind_init()
static void __attribute__((unused)) ESKY150_send_packet()
{
// Build packet
uint16_t throttle=convert_channel_16b(THROTTLE,1000,2000);
uint16_t aileron=convert_channel_16b(AILERON,1000,2000);
uint16_t elevator=convert_channel_16b(ELEVATOR,1000,2000);
uint16_t rudder=convert_channel_16b(RUDDER,1000,2000);
uint16_t throttle=convert_channel_16b_limit(THROTTLE,1000,2000);
uint16_t aileron=convert_channel_16b_limit(AILERON,1000,2000);
uint16_t elevator=convert_channel_16b_limit(ELEVATOR,1000,2000);
uint16_t rudder=convert_channel_16b_limit(RUDDER,1000,2000);
//set unused channels to zero, for compatibility with older 4 channel models
uint8_t flight_mode=0;
uint16_t aux_ch6=0;
uint8_t aux_ch7=0;
if(option==1)
{
flight_mode=ESKY150_convert_2bit_channel(AUX1);
aux_ch6=convert_channel_16b(AUX2,1000,2000);
aux_ch7=ESKY150_convert_2bit_channel(AUX3);
flight_mode=ESKY150_convert_2bit_channel(CH5);
aux_ch6=convert_channel_16b_limit(CH6,1000,2000);
aux_ch7=ESKY150_convert_2bit_channel(CH7);
}
packet[0] = hopping_frequency[0];
packet[1] = hopping_frequency[1];
@ -137,13 +137,13 @@ static void __attribute__((unused)) ESKY150_send_packet()
uint8_t ESKY150_convert_2bit_channel(uint8_t num)
{
if(Servo_data[num] > PPM_MAX_COMMAND)
if(Channel_data[num] > CHANNEL_MAX_COMMAND)
return 0x03;
else
if(Servo_data[num] < PPM_MIN_COMMAND)
if(Channel_data[num] < CHANNEL_MIN_COMMAND)
return 0x00;
else
if(Servo_data[num] > PPM_SWITCH)
if(Channel_data[num] > CHANNEL_SWITCH)
return 0x02;
return 0x01;
}

View File

@ -119,8 +119,9 @@ static void __attribute__((unused)) ESKY_send_packet(uint8_t bind)
{
for (uint8_t i = 0; i < 6; i++)
{
packet[i*2] = Servo_data[CH_AETR[i]]>>8; //high byte of servo timing(1000-2000us)
packet[i*2+1] = Servo_data[CH_AETR[i]]&0xFF; //low byte of servo timing(1000-2000us)
uint16_t val=convert_channel_ppm(CH_AETR[i]);
packet[i*2] = val>>8; //high byte of servo timing(1000-2000us)
packet[i*2+1] = val&0xFF; //low byte of servo timing(1000-2000us)
}
}
rf_ch = hopping_frequency[hopping_frequency_no];

View File

@ -125,15 +125,15 @@ static void __attribute__((unused)) FQ777_send_packet(uint8_t bind)
else // roll
trim_val = 0x60;
packet_ori[0] = convert_channel_8b_scale(THROTTLE,0,0x64);
packet_ori[1] = convert_channel_8b_scale(RUDDER,0,0x64);
packet_ori[2] = convert_channel_8b_scale(ELEVATOR,0,0x64);
packet_ori[3] = convert_channel_8b_scale(AILERON,0,0x64);
packet_ori[0] = convert_channel_16b_limit(THROTTLE,0,0x64);
packet_ori[1] = convert_channel_16b_limit(RUDDER,0,0x64);
packet_ori[2] = convert_channel_16b_limit(ELEVATOR,0,0x64);
packet_ori[3] = convert_channel_16b_limit(AILERON,0,0x64);
packet_ori[4] = trim_val; // calculated above
packet_ori[5] = GET_FLAG(Servo_AUX1, FQ777_FLAG_FLIP)
| GET_FLAG(Servo_AUX3, FQ777_FLAG_HEADLESS)
| GET_FLAG(!Servo_AUX2, FQ777_FLAG_RETURN)
| GET_FLAG(Servo_AUX4,FQ777_FLAG_EXPERT);
packet_ori[5] = GET_FLAG(CH5_SW, FQ777_FLAG_FLIP)
| GET_FLAG(CH7_SW, FQ777_FLAG_HEADLESS)
| GET_FLAG(!CH6_SW, FQ777_FLAG_RETURN)
| GET_FLAG(CH8_SW,FQ777_FLAG_EXPERT);
packet_ori[6] = 0x00;
// calculate checksum
uint8_t checksum = 0;

View File

@ -43,15 +43,15 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
if(bind)
packet[1] = 0x55;
else
packet[1] = GET_FLAG(Servo_AUX3, 0x80) // Headless
| GET_FLAG(Servo_AUX2, 0x40) // RTH
| GET_FLAG(Servo_AUX1, 0x02) // Flip
| GET_FLAG(Servo_AUX5, 0x01) // Calibrate
| GET_FLAG(Servo_AUX4, 0x04); // Expert
packet[2] = convert_channel_8b_scale(AILERON, 0, 200); // aileron
packet[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator
packet[4] = convert_channel_8b_scale(RUDDER, 0, 200); // rudder
packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle
packet[1] = GET_FLAG(CH7_SW, 0x80) // Headless
| GET_FLAG(CH6_SW, 0x40) // RTH
| GET_FLAG(CH5_SW, 0x02) // Flip
| GET_FLAG(CH9_SW, 0x01) // Calibrate
| GET_FLAG(CH8_SW, 0x04); // Expert
packet[2] = convert_channel_16b_limit(AILERON, 0, 200); // aileron
packet[3] = convert_channel_16b_limit(ELEVATOR, 0, 200); // elevator
packet[4] = convert_channel_16b_limit(RUDDER, 0, 200); // rudder
packet[5] = convert_channel_16b_limit(THROTTLE, 0, 200); // throttle
if(sub_protocol==FY319)
{
packet[6] = convert_channel_8b(AILERON);

View File

@ -58,37 +58,37 @@ static void __attribute__((unused)) flysky_apply_extension_flags()
switch(sub_protocol)
{
case V9X9:
if(Servo_AUX1)
if(CH5_SW)
packet[12] |= FLAG_V9X9_FLIP;
if(Servo_AUX2)
if(CH6_SW)
packet[12] |= FLAG_V9X9_LED;
if(Servo_AUX3)
if(CH7_SW)
packet[10] |= FLAG_V9X9_CAMERA;
if(Servo_AUX4)
if(CH8_SW)
packet[10] |= FLAG_V9X9_VIDEO;
break;
case V6X6:
packet[13] = 0x03; // 3 = 100% rate (0=40%, 1=60%, 2=80%)
packet[14] = 0x00;
if(Servo_AUX1)
if(CH5_SW)
packet[14] |= FLAG_V6X6_FLIP;
if(Servo_AUX2)
if(CH6_SW)
packet[14] |= FLAG_V6X6_LED;
if(Servo_AUX3)
if(CH7_SW)
packet[14] |= FLAG_V6X6_CAMERA;
if(Servo_AUX4)
if(CH8_SW)
packet[14] |= FLAG_V6X6_VIDEO;
if(Servo_AUX5)
if(CH9_SW)
{
packet[13] |= FLAG_V6X6_HLESS1;
packet[14] |= FLAG_V6X6_HLESS2;
}
if(Servo_AUX6)
if(CH10_SW)
packet[14] |= FLAG_V6X6_RTH;
if(Servo_AUX7)
if(CH11_SW)
packet[14] |= FLAG_V6X6_XCAL;
if(Servo_AUX8)
if(CH12_SW)
packet[14] |= FLAG_V6X6_YCAL;
packet[15] = 0x10; // unknown
packet[16] = 0x10; // unknown
@ -105,9 +105,9 @@ static void __attribute__((unused)) flysky_apply_extension_flags()
packet[12] |= 0x20; // bit 6 is always set ?
packet[13] = 0x00; // unknown
packet[14] = 0x00;
if(Servo_AUX1)
if(CH5_SW)
packet[14] = FLAG_V912_BTMBTN;
if(Servo_AUX2)
if(CH6_SW)
packet[14] |= FLAG_V912_TOPBTN;
packet[15] = 0x27; // [15] and [16] apparently hold an analog channel with a value lower than 1000
packet[16] = 0x03; // maybe it's there for a pitch channel for a CP copter ?
@ -136,7 +136,7 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
//-100% =~ 0x03e8//=1000us(min)
//+100% =~ 0x07ca//=1994us(max)
//Center = 0x5d9//=1497us(center)
//channel order AIL;ELE;THR;RUD;AUX1;AUX2;AUX3;AUX4
//channel order AIL;ELE;THR;RUD;CH5;CH6;CH7;CH8
packet[0] = init ? 0xaa : 0x55;
packet[1] = rx_tx_addr[3];
packet[2] = rx_tx_addr[2];
@ -144,11 +144,9 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
packet[4] = rx_tx_addr[0];
for(i = 0; i < 8; i++)
{
uint16_t temp=Servo_data[CH_AETR[i]];
if(sub_protocol == CX20 && CH_AETR[i] == ELEVATOR)
temp=servo_mid-temp; //reverse channel
if(mode_select != MODE_SERIAL) //if in PPM mode extend the output to 1000...2000µs
temp=map(temp,servo_min_100,servo_max_100,1000,2000);
uint16_t temp=convert_channel_ppm(CH_AETR[i]);
if(sub_protocol == CX20 && CH_AETR[i]==ELEVATOR)
temp=3000-temp;
packet[5 + i*2]=temp&0xFF; //low byte of servo timing(1000-2000us)
packet[6 + i*2]=(temp>>8)&0xFF; //high byte of servo timing(1000-2000us)
}

View File

@ -105,7 +105,7 @@ static void __attribute__((unused)) frskyX_build_bind_packet()
//64=860,1024=1500,1984=2140//Taranis 125%
static uint16_t __attribute__((unused)) frskyX_scaleForPXX( uint8_t i )
{ //mapped 860,2140(125%) range to 64,1984(PXX values);
uint16_t chan_val=(((Servo_data[i]-servo_min_125)*3)>>1)+64;
uint16_t chan_val=convert_channel_frsky(i)-1226;
if(i>7) chan_val|=2048; // upper channels offset
return chan_val;
}

View File

@ -47,11 +47,11 @@ static void __attribute__((unused)) send_packet(uint8_t bind)
}
else
{
packet[1] = 0x01 | GET_FLAG(AUX1, 0x40); // flip
packet[2] = convert_channel_8b_scale(AILERON , 200, 0); // aileron
packet[3] = convert_channel_8b_scale(ELEVATOR, 0, 200); // elevator
packet[4] = convert_channel_8b_scale(RUDDER , 200, 0); // rudder
packet[5] = convert_channel_8b_scale(THROTTLE, 0, 200); // throttle
packet[1] = 0x01 | GET_FLAG(CH5, 0x40); // flip
packet[2] = convert_channel_16b_limit(AILERON , 200, 0); // aileron
packet[3] = convert_channel_16b_limit(ELEVATOR, 0, 200); // elevator
packet[4] = convert_channel_16b_limit(RUDDER , 200, 0); // rudder
packet[5] = convert_channel_16b_limit(THROTTLE, 0, 200); // throttle
packet[6] = 0xaa;
packet[7] = 0x02; // max rate
packet[8] = 0x00;

View File

@ -74,7 +74,7 @@ static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind)
packet[5] = hopping_frequency_no;
packet[7] = 0x03;
rudder = convert_channel_8b_scale(RUDDER,0x44,0xBC); // yaw right : 0x80 (neutral) - 0xBC (right)
rudder = convert_channel_16b_limit(RUDDER,0x44,0xBC); // yaw right : 0x80 (neutral) - 0xBC (right)
if(sub_protocol!=H20H)
{ // H8_3D, H20MINI, H30MINI
packet[6] = 0x08;
@ -89,7 +89,7 @@ static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind)
else
{ //H20H
packet[6] = hopping_frequency_no == 0 ? 8 - packet_count : 16 - packet_count;
packet[9] = convert_channel_8b_scale(THROTTLE, 0x43, 0xBB); // throttle : 0x43 - 0x7F - 0xBB
packet[9] = convert_channel_16b_limit(THROTTLE, 0x43, 0xBB); // throttle : 0x43 - 0x7F - 0xBB
packet[15]= 0x40; // trims
packet[16]= 0x40; // trims
rudder--; // rudder : 0x43 - 0x7F - 0xBB
@ -97,24 +97,24 @@ static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind)
rudder=0x7F; // Small deadband
}
packet[10] = rudder;
packet[11] = convert_channel_8b_scale(ELEVATOR, 0x43, 0xBB); // elevator : 0x43 - 0x7F - 0xBB
packet[12] = convert_channel_8b_scale(AILERON, 0x43, 0xBB); // aileron : 0x43 - 0x7F - 0xBB
packet[11] = convert_channel_16b_limit(ELEVATOR, 0x43, 0xBB); // elevator : 0x43 - 0x7F - 0xBB
packet[12] = convert_channel_16b_limit(AILERON, 0x43, 0xBB); // aileron : 0x43 - 0x7F - 0xBB
// neutral trims
packet[13] = 0x20;
packet[14] = 0x20;
// flags
packet[17] = H8_3D_FLAG_RATE_HIGH
| GET_FLAG(Servo_AUX1,H8_3D_FLAG_FLIP)
| GET_FLAG(Servo_AUX2,H8_3D_FLAG_LIGTH) //H22 light
| GET_FLAG(Servo_AUX5,H8_3D_FLAG_HEADLESS)
| GET_FLAG(Servo_AUX6,H8_3D_FLAG_RTH); // 180/360 flip mode on H8 3D
packet[18] = GET_FLAG(Servo_AUX3,H8_3D_FLAG_PICTURE)
| GET_FLAG(Servo_AUX4,H8_3D_FLAG_VIDEO)
| GET_FLAG(Servo_AUX7,H8_3D_FLAG_CALIBRATE1)
| GET_FLAG(Servo_AUX8,H8_3D_FLAG_CALIBRATE2);
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
| GET_FLAG(CH5_SW,H8_3D_FLAG_FLIP)
| GET_FLAG(CH6_SW,H8_3D_FLAG_LIGTH) //H22 light
| GET_FLAG(CH9_SW,H8_3D_FLAG_HEADLESS)
| GET_FLAG(CH10_SW,H8_3D_FLAG_RTH); // 180/360 flip mode on H8 3D
packet[18] = GET_FLAG(CH7_SW,H8_3D_FLAG_PICTURE)
| GET_FLAG(CH8_SW,H8_3D_FLAG_VIDEO)
| GET_FLAG(CH11_SW,H8_3D_FLAG_CALIBRATE1)
| GET_FLAG(CH12_SW,H8_3D_FLAG_CALIBRATE2);
if(Channel_data[CH13]<CHANNEL_MIN_COMMAND)
packet[18] |= H8_3D_FLAG_CAM_DN;
if(Servo_data[AUX9]>PPM_MAX_COMMAND)
if(CH13_SW)
packet[18] |= H8_3D_FLAG_CAM_UP;
}
uint8_t sum = packet[9];

View File

@ -122,10 +122,10 @@ static void __attribute__((unused)) build_ch_data()
uint8_t i,j;
for (i = 0; i< 8; i++) {
j=CH_AETR[i];
temp=map(limit_channel_100(j),servo_min_100,servo_max_100,0,1000);
temp=convert_channel_16b_limit(j,0,1000);
if (j == THROTTLE) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose
temp = 1000 -temp;
if (j == AUX3)
if (j == CH7)
temp = temp < 400 ? 0 : 3; // Gyro mode, 0 - 6 axis, 3 - 3 axis
packet[i] = (uint8_t)(temp&0xFF);
packet[i<4?8:9]>>=2;
@ -156,7 +156,7 @@ uint16_t hisky_cb()
{ // send failsafe every 100ms
convert_failsafe_HK310(RUDDER, &packet[0],&packet[1]);
convert_failsafe_HK310(THROTTLE,&packet[2],&packet[3]);
convert_failsafe_HK310(AUX1, &packet[4],&packet[5]);
convert_failsafe_HK310(CH5, &packet[4],&packet[5]);
packet[7]=0xAA;
packet[8]=0x5A;
}
@ -165,7 +165,7 @@ uint16_t hisky_cb()
{
convert_channel_HK310(RUDDER, &packet[0],&packet[1]);
convert_channel_HK310(THROTTLE,&packet[2],&packet[3]);
convert_channel_HK310(AUX1, &packet[4],&packet[5]);
convert_channel_HK310(CH5, &packet[4],&packet[5]);
packet[7]=0x55;
packet[8]=0x67;
}

View File

@ -69,60 +69,60 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
else
{
memset(packet,0,HONTAI_PACKET_SIZE);
packet[3] = convert_channel_8b_scale(THROTTLE, 0, 127) << 1; // Throttle
packet[4] = convert_channel_8b_scale(AILERON, 63, 0); // Aileron
packet[5] = convert_channel_8b_scale(ELEVATOR, 0, 63); // Elevator
packet[6] = convert_channel_8b_scale(RUDDER, 0, 63); // Rudder
packet[3] = convert_channel_16b_limit(THROTTLE, 0, 127) << 1; // Throttle
packet[4] = convert_channel_16b_limit(AILERON, 63, 0); // Aileron
packet[5] = convert_channel_16b_limit(ELEVATOR, 0, 63); // Elevator
packet[6] = convert_channel_16b_limit(RUDDER, 0, 63); // Rudder
if(sub_protocol == FORMAT_X5C1)
packet[7] = convert_channel_8b_scale(AILERON, 0, 63)-31; // Aileron trim
packet[7] = convert_channel_16b_limit(AILERON, 0, 63)-31; // Aileron trim
else
packet[7] = convert_channel_8b_scale(AILERON, 0, 32)-16; // Aileron trim
packet[8] = convert_channel_8b_scale(RUDDER, 0, 32)-16; // Rudder trim
packet[7] = convert_channel_16b_limit(AILERON, 0, 32)-16; // Aileron trim
packet[8] = convert_channel_16b_limit(RUDDER, 0, 32)-16; // Rudder trim
if (sub_protocol == FORMAT_X5C1)
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 63)-31; // Elevator trim
packet[9] = convert_channel_16b_limit(ELEVATOR, 0, 63)-31; // Elevator trim
else
packet[9] = convert_channel_8b_scale(ELEVATOR, 0, 32)-16; // Elevator trim
packet[9] = convert_channel_16b_limit(ELEVATOR, 0, 32)-16; // Elevator trim
switch(sub_protocol)
{
case FORMAT_HONTAI:
packet[0] = 0x0B;
packet[3] |= GET_FLAG(Servo_AUX3, 0x01); // Picture
packet[4] |= GET_FLAG(Servo_AUX6, 0x80) // RTH
| GET_FLAG(Servo_AUX5, 0x40); // Headless
packet[5] |= GET_FLAG(Servo_AUX7, 0x80) // Calibrate
| GET_FLAG(Servo_AUX1, 0x40); // Flip
packet[6] |= GET_FLAG(Servo_AUX4, 0x80); // Video
packet[3] |= GET_FLAG(CH7_SW, 0x01); // Picture
packet[4] |= GET_FLAG(CH10_SW, 0x80) // RTH
| GET_FLAG(CH9_SW, 0x40); // Headless
packet[5] |= GET_FLAG(CH11_SW, 0x80) // Calibrate
| GET_FLAG(CH5_SW, 0x40); // Flip
packet[6] |= GET_FLAG(CH8_SW, 0x80); // Video
break;
case FORMAT_JJRCX1:
packet[0] = GET_FLAG(Servo_AUX2, 0x02); // Arm
packet[3] |= GET_FLAG(Servo_AUX3, 0x01); // Picture
packet[0] = GET_FLAG(CH6_SW, 0x02); // Arm
packet[3] |= GET_FLAG(CH7_SW, 0x01); // Picture
packet[4] |= 0x80; // unknown
packet[5] |= GET_FLAG(Servo_AUX7, 0x80) // Calibrate
| GET_FLAG(Servo_AUX1, 0x40); // Flip
packet[6] |= GET_FLAG(Servo_AUX4, 0x80); // Video
packet[5] |= GET_FLAG(CH11_SW, 0x80) // Calibrate
| GET_FLAG(CH5_SW, 0x40); // Flip
packet[6] |= GET_FLAG(CH8_SW, 0x80); // Video
packet[8] = 0xC0 // high rate, no rudder trim
| GET_FLAG(Servo_AUX6, 0x02) // RTH
| GET_FLAG(Servo_AUX5, 0x01); // Headless
| GET_FLAG(CH10_SW, 0x02) // RTH
| GET_FLAG(CH9_SW, 0x01); // Headless
break;
case FORMAT_X5C1:
packet[0] = 0x0B;
packet[3] |= GET_FLAG(Servo_AUX3, 0x01); // Picture
packet[3] |= GET_FLAG(CH7_SW, 0x01); // Picture
packet[4] = 0x80 // unknown
| GET_FLAG(Servo_AUX2, 0x40); // Lights
packet[5] |= GET_FLAG(Servo_AUX7, 0x80) // Calibrate
| GET_FLAG(Servo_AUX1, 0x40); // Flip
packet[6] |= GET_FLAG(Servo_AUX4, 0x80); // Video
| GET_FLAG(CH6_SW, 0x40); // Lights
packet[5] |= GET_FLAG(CH11_SW, 0x80) // Calibrate
| GET_FLAG(CH5_SW, 0x40); // Flip
packet[6] |= GET_FLAG(CH8_SW, 0x80); // Video
packet[8] = 0xC0 // high rate, no rudder trim
| GET_FLAG(Servo_AUX6, 0x02) // RTH
| GET_FLAG(Servo_AUX5, 0x01); // Headless
| GET_FLAG(CH10_SW, 0x02) // RTH
| GET_FLAG(CH9_SW, 0x01); // Headless
break;
case FORMAT_FQ777_951:
packet[0] = GET_FLAG(Servo_AUX3, 0x01) // Picture
| GET_FLAG(Servo_AUX4, 0x02); // Video
packet[3] |= GET_FLAG(Servo_AUX1, 0x01); // Flip
packet[0] = GET_FLAG(CH7_SW, 0x01) // Picture
| GET_FLAG(CH8_SW, 0x02); // Video
packet[3] |= GET_FLAG(CH5_SW, 0x01); // Flip
packet[4] |= 0xC0; // High rate (mid=0xa0, low=0x60)
packet[5] |= GET_FLAG(Servo_AUX7, 0x80); // Calibrate
packet[6] |= GET_FLAG(Servo_AUX5, 0x40); // Headless
packet[5] |= GET_FLAG(CH11_SW, 0x80); // Calibrate
packet[6] |= GET_FLAG(CH9_SW, 0x40); // Headless
break;
}
}

View File

@ -162,11 +162,11 @@ static void __attribute__((unused)) hubsan_build_packet()
{
packet[9] = 0x02;
// Channel 5
if(Servo_AUX1) packet[9] |= HUBSAN_FLAG_FLIP;
if(CH5_SW) packet[9] |= HUBSAN_FLAG_FLIP;
// Channel 6
if(Servo_AUX2) packet[9] |= HUBSAN_FLAG_LED;
if(CH6_SW) packet[9] |= HUBSAN_FLAG_LED;
// Channel 8
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO; // H102D
if(CH8_SW) packet[9] |= HUBSAN_FLAG_VIDEO; // H102D
}
packet[10] = 0x64;
//const uint32_t txid = 0xdb042679;
@ -183,10 +183,10 @@ static void __attribute__((unused)) hubsan_build_packet()
}
else
{
packet[9] = GET_FLAG(Servo_AUX2, FLAG_H301_LED)
| GET_FLAG(Servo_AUX3, FLAG_H301_STAB)
| GET_FLAG(Servo_AUX4, FLAG_H301_VIDEO)
| GET_FLAG(Servo_AUX1, FLAG_H301_RTH);
packet[9] = GET_FLAG(CH6_SW, FLAG_H301_LED)
| GET_FLAG(CH7_SW, FLAG_H301_STAB)
| GET_FLAG(CH8_SW, FLAG_H301_VIDEO)
| GET_FLAG(CH5_SW, FLAG_H301_RTH);
}
packet[10] = 0x18; // ?
packet[12] = 0x5c; // ?
@ -201,27 +201,27 @@ static void __attribute__((unused)) hubsan_build_packet()
if(sub_protocol==H501)
{ // H501S
packet[9] = 0x02
| GET_FLAG(Servo_AUX2, FLAG_H501_LED)
| GET_FLAG(Servo_AUX4, FLAG_H501_VIDEO)
| GET_FLAG(Servo_AUX1, FLAG_H501_RTH)
| GET_FLAG(Servo_AUX7, FLAG_H501_GPS_HOLD)
| GET_FLAG(Servo_AUX5, FLAG_H501_HEADLESS1);
| GET_FLAG(CH6_SW, FLAG_H501_LED)
| GET_FLAG(CH8_SW, FLAG_H501_VIDEO)
| GET_FLAG(CH5_SW, FLAG_H501_RTH)
| GET_FLAG(CH11_SW, FLAG_H501_GPS_HOLD)
| GET_FLAG(CH9_SW, FLAG_H501_HEADLESS1);
//packet[10]= 0x1A;
packet[13] = GET_FLAG(Servo_AUX6, FLAG_H501_HEADLESS2)
| GET_FLAG(Servo_AUX8, FLAG_H501_ALT_HOLD)
| GET_FLAG(Servo_AUX3, FLAG_H501_SNAPSHOT);
packet[13] = GET_FLAG(CH10_SW, FLAG_H501_HEADLESS2)
| GET_FLAG(CH12_SW, FLAG_H501_ALT_HOLD)
| GET_FLAG(CH7_SW, FLAG_H501_SNAPSHOT);
}
else
{ // H107P/C+/D+
packet[9] = 0x06;
//FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
if(Servo_AUX4) packet[9] |= HUBSAN_FLAG_VIDEO;
if(Servo_AUX5) packet[9] |= HUBSAN_FLAG_HEADLESS;
if(CH8_SW) packet[9] |= HUBSAN_FLAG_VIDEO;
if(CH9_SW) packet[9] |= HUBSAN_FLAG_HEADLESS;
packet[10]= 0x19;
packet[12]= 0x5C; // ghost channel ?
packet[13] = 0;
if(Servo_AUX3) packet[13] = HUBSAN_FLAG_SNAPSHOT;
if(Servo_AUX1) packet[13] |= HUBSAN_FLAG_FLIP_PLUS;
if(CH7_SW) packet[13] = HUBSAN_FLAG_SNAPSHOT;
if(CH5_SW) packet[13] |= HUBSAN_FLAG_FLIP_PLUS;
packet[14]= 0x49; // ghost channel ?
}
if(packet_count < 100)

View File

@ -138,19 +138,19 @@ static void __attribute__((unused)) kn_update_packet_control_data()
packet[6] = (value >> 8) & 0xFF;
packet[7] = value & 0xFF;
// Trims, middle is 0x64 (100) range 0-200
packet[8] = convert_channel_8b_scale(AUX5,0,200); // 0x64; // T
packet[9] = convert_channel_8b_scale(AUX6,0,200); // 0x64; // A
packet[10] = convert_channel_8b_scale(AUX7,0,200); // 0x64; // E
packet[8] = convert_channel_16b_limit(CH9,0,200); // 0x64; // T
packet[9] = convert_channel_16b_limit(CH10,0,200); // 0x64; // A
packet[10] = convert_channel_16b_limit(CH11,0,200); // 0x64; // E
packet[11] = 0x64; // R
flags=0;
if (Servo_AUX1)
if (CH5_SW)
flags = KN_FLAG_DR;
if (Servo_AUX2)
if (CH6_SW)
flags |= KN_FLAG_TH;
if (Servo_AUX3)
if (CH7_SW)
flags |= KN_FLAG_IDLEUP;
if (Servo_AUX4)
if (CH8_SW)
flags |= KN_FLAG_GYRO3;
packet[12] = flags;

View File

@ -80,19 +80,19 @@ const uint8_t PROGMEM E010_map_rfchan[][2] = {
#define MJXQ_TILT_UP 0x10
static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
{
// Servo_AUX8 PAN // H26D
// Servo_AUX9 TILT
// CH12_SW PAN // H26D
// CH13_SW TILT
uint8_t pan = 0;
packet_count++;
if(packet_count & MJXQ_PAN_TILT_COUNT)
{
if(Servo_data[AUX8]>PPM_MAX_COMMAND)
if(CH12_SW)
pan=MJXQ_PAN_UP;
if(Servo_data[AUX8]<PPM_MIN_COMMAND)
if(Channel_data[CH12]<CHANNEL_MIN_COMMAND)
pan=MJXQ_PAN_DOWN;
if(Servo_data[AUX9]>PPM_MAX_COMMAND)
if(CH13_SW)
pan+=MJXQ_TILT_UP;
if(Servo_data[AUX9]<PPM_MIN_COMMAND)
if(Channel_data[CH13]<CHANNEL_MIN_COMMAND)
pan+=MJXQ_TILT_DOWN;
}
return pan;
@ -105,9 +105,9 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
packet[1] = convert_channel_s8b(RUDDER);
packet[4] = 0x40; // rudder does not work well with dyntrim
packet[2] = 0x80 ^ convert_channel_s8b(ELEVATOR);
packet[5] = (Servo_AUX5 || Servo_AUX10) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
packet[5] = (CH9_SW || CH14_SW) ? 0x40 : MJXQ_CHAN2TRIM(packet[2]); // trim elevator
packet[3] = convert_channel_s8b(AILERON);
packet[6] = (Servo_AUX5 || Servo_AUX10) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron
packet[6] = (CH9_SW || CH14_SW) ? 0x40 : MJXQ_CHAN2TRIM(packet[3]); // trim aileron
packet[7] = rx_tx_addr[0];
packet[8] = rx_tx_addr[1];
packet[9] = rx_tx_addr[2];
@ -119,16 +119,16 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
packet[14] = 0xC0; // bind value
// Servo_AUX1 FLIP
// Servo_AUX2 LED / ARM
// Servo_AUX3 PICTURE
// Servo_AUX4 VIDEO
// Servo_AUX5 HEADLESS
// Servo_AUX6 RTH
// Servo_AUX7 AUTOFLIP // X800, X600
// Servo_AUX8 PAN
// Servo_AUX9 TILT
// Servo_AUX10 XTRM // Dyntrim, don't use if high.
// CH5_SW FLIP
// CH6_SW LED / ARM
// CH7_SW PICTURE
// CH8_SW VIDEO
// CH9_SW HEADLESS
// CH10_SW RTH
// CH11_SW AUTOFLIP // X800, X600
// CH12_SW PAN
// CH13_SW TILT
// CH14_SW XTRM // Dyntrim, don't use if high.
switch(sub_protocol)
{
case H26WH:
@ -137,45 +137,45 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
// fall through on purpose - no break
case WLH08:
case E010:
packet[10] += GET_FLAG(Servo_AUX6, 0x02) //RTH
| GET_FLAG(Servo_AUX5, 0x01); //HEADLESS
packet[10] += GET_FLAG(CH10_SW, 0x02) //RTH
| GET_FLAG(CH9_SW, 0x01); //HEADLESS
if (!bind)
{
packet[14] = 0x04
| GET_FLAG(Servo_AUX1, 0x01) //FLIP
| GET_FLAG(Servo_AUX3, 0x08) //PICTURE
| GET_FLAG(Servo_AUX4, 0x10) //VIDEO
| GET_FLAG(!Servo_AUX2, 0x20); // LED or air/ground mode
| GET_FLAG(CH5_SW, 0x01) //FLIP
| GET_FLAG(CH7_SW, 0x08) //PICTURE
| GET_FLAG(CH8_SW, 0x10) //VIDEO
| GET_FLAG(!CH6_SW, 0x20); // LED or air/ground mode
if(sub_protocol==H26WH)
{
packet[10] |=0x40; //High rate
packet[14] &= ~0x24; // unset air/ground & arm flags
packet[14] |= GET_FLAG(Servo_AUX2, 0x02); // arm
packet[14] |= GET_FLAG(CH6_SW, 0x02); // arm
}
}
break;
case X600:
packet[10] = GET_FLAG(!Servo_AUX2, 0x02); //LED
packet[11] = GET_FLAG(Servo_AUX6, 0x01); //RTH
packet[10] = GET_FLAG(!CH6_SW, 0x02); //LED
packet[11] = GET_FLAG(CH10_SW, 0x01); //RTH
if (!bind)
{
packet[14] = 0x02 // always high rates by bit2 = 1
| GET_FLAG(Servo_AUX1, 0x04) //FLIP
| GET_FLAG(Servo_AUX7, 0x10) //AUTOFLIP
| GET_FLAG(Servo_AUX5, 0x20); //HEADLESS
| GET_FLAG(CH5_SW, 0x04) //FLIP
| GET_FLAG(CH11_SW, 0x10) //AUTOFLIP
| GET_FLAG(CH9_SW, 0x20); //HEADLESS
}
break;
case X800:
default:
packet[10] = 0x10
| GET_FLAG(!Servo_AUX2, 0x02) //LED
| GET_FLAG(Servo_AUX7, 0x01); //AUTOFLIP
| GET_FLAG(!CH6_SW, 0x02) //LED
| GET_FLAG(CH11_SW, 0x01); //AUTOFLIP
if (!bind)
{
packet[14] = 0x02 // always high rates by bit2 = 1
| GET_FLAG(Servo_AUX1, 0x04) //FLIP
| GET_FLAG(Servo_AUX3, 0x08) //PICTURE
| GET_FLAG(Servo_AUX4, 0x10); //VIDEO
| GET_FLAG(CH5_SW, 0x04) //FLIP
| GET_FLAG(CH7_SW, 0x08) //PICTURE
| GET_FLAG(CH8_SW, 0x10); //VIDEO
}
break;
}

View File

@ -79,13 +79,13 @@ static void __attribute__((unused)) MT99XX_send_packet()
if(sub_protocol != YZ)
{ // MT99XX & H7 & LS
packet[0] = convert_channel_8b_scale(THROTTLE,0xE1,0x00); // throttle
packet[1] = convert_channel_8b_scale(RUDDER ,0x00,0xE1); // rudder
packet[2] = convert_channel_8b_scale(AILERON ,0xE1,0x00); // aileron
packet[3] = convert_channel_8b_scale(ELEVATOR,0x00,0xE1); // elevator
packet[0] = convert_channel_16b_limit(THROTTLE,0xE1,0x00); // throttle
packet[1] = convert_channel_16b_limit(RUDDER ,0x00,0xE1); // rudder
packet[2] = convert_channel_16b_limit(AILERON ,0xE1,0x00); // aileron
packet[3] = convert_channel_16b_limit(ELEVATOR,0x00,0xE1); // elevator
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
packet[6] = GET_FLAG( Servo_AUX1, FLAG_MT_FLIP );
packet[6] = GET_FLAG( CH5_SW, FLAG_MT_FLIP );
packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ?
if(sub_protocol==H7)
@ -93,8 +93,8 @@ static void __attribute__((unused)) MT99XX_send_packet()
else
if(sub_protocol==MT99)
packet[6] |= 0x40 | FLAG_MT_RATE2
| GET_FLAG( Servo_AUX3, FLAG_MT_SNAPSHOT )
| GET_FLAG( Servo_AUX4, FLAG_MT_VIDEO ); // max rate on MT99xx
| GET_FLAG( CH7_SW, FLAG_MT_SNAPSHOT )
| GET_FLAG( CH8_SW, FLAG_MT_VIDEO ); // max rate on MT99xx
else
if(sub_protocol==FY805)
{
@ -102,17 +102,17 @@ static void __attribute__((unused)) MT99XX_send_packet()
//Rate 0x01?
//Flip ?
packet[7]=0x01
|GET_FLAG( Servo_AUX1, FLAG_MT_FLIP )
|GET_FLAG( Servo_AUX5, FLAG_FY805_HEADLESS ); //HEADLESS
|GET_FLAG( CH5_SW, FLAG_MT_FLIP )
|GET_FLAG( CH9_SW, FLAG_FY805_HEADLESS ); //HEADLESS
checksum_offset=0;
}
else //LS
{
packet[6] |= FLAG_LS_RATE // max rate
| GET_FLAG( Servo_AUX2, FLAG_LS_INVERT ) //INVERT
| GET_FLAG( Servo_AUX3, FLAG_LS_SNAPSHOT ) //SNAPSHOT
| GET_FLAG( Servo_AUX4, FLAG_LS_VIDEO ) //VIDEO
| GET_FLAG( Servo_AUX5, FLAG_LS_HEADLESS ); //HEADLESS
| GET_FLAG( CH6_SW, FLAG_LS_INVERT ) //INVERT
| GET_FLAG( CH7_SW, FLAG_LS_SNAPSHOT ) //SNAPSHOT
| GET_FLAG( CH8_SW, FLAG_LS_VIDEO ) //VIDEO
| GET_FLAG( CH9_SW, FLAG_LS_HEADLESS ); //HEADLESS
packet[7] = ls_mys_byte[ls_counter++];
if(ls_counter >= sizeof(ls_mys_byte))
ls_counter=0;
@ -125,10 +125,10 @@ static void __attribute__((unused)) MT99XX_send_packet()
}
else
{ // YZ
packet[0] = convert_channel_8b_scale(THROTTLE,0x00,0x64); // throttle
packet[1] = convert_channel_8b_scale(RUDDER ,0x64,0x00); // rudder
packet[2] = convert_channel_8b_scale(ELEVATOR,0x00,0x64); // elevator
packet[3] = convert_channel_8b_scale(AILERON ,0x64,0x00); // aileron
packet[0] = convert_channel_16b_limit(THROTTLE,0x00,0x64); // throttle
packet[1] = convert_channel_16b_limit(RUDDER ,0x64,0x00); // rudder
packet[2] = convert_channel_16b_limit(ELEVATOR,0x00,0x64); // elevator
packet[3] = convert_channel_16b_limit(AILERON ,0x64,0x00); // aileron
if(packet_count++ >= 23)
{
yz_seq_num ++;
@ -138,11 +138,11 @@ static void __attribute__((unused)) MT99XX_send_packet()
}
packet[4] = yz_p4_seq[yz_seq_num];
packet[5] = 0x02 // expert ? (0=unarmed, 1=normal)
| GET_FLAG(Servo_AUX4, 0x10) //VIDEO
| GET_FLAG(Servo_AUX1, 0x80) //FLIP
| GET_FLAG(Servo_AUX5, 0x04) //HEADLESS
| GET_FLAG(Servo_AUX3, 0x20); //SNAPSHOT
packet[6] = GET_FLAG(Servo_AUX2, 0x80); //LED
| GET_FLAG(CH8_SW, 0x10) //VIDEO
| GET_FLAG(CH5_SW, 0x80) //FLIP
| GET_FLAG(CH9_SW, 0x04) //HEADLESS
| GET_FLAG(CH7_SW, 0x20); //SNAPSHOT
packet[6] = GET_FLAG(CH6_SW, 0x80); //LED
packet[7] = packet[0];
for(uint8_t idx = 1; idx < MT99XX_PACKET_SIZE-2; idx++)
packet[7] += packet[idx];

View File

@ -6,54 +6,6 @@
#include <string.h>
#include <avr/interrupt.h>
/*static void protocol_init(void) ;
static void update_channels_aux(void) ;
static uint32_t random_id(uint16_t adress, uint8_t create_new) ;
static void update_serial_data(void) ;
static void Mprotocol_serial_init(void) ;
static void update_led_status(void) ;
static void set_rx_tx_addr(uint32_t id) ;
uint16_t limit_channel_100(uint8_t ch) ;
void initTXSerial( uint8_t speed);
void Serial_write(uint8_t data);
extern void NRF24L01_Reset(void ) ;
extern void A7105_Reset(void ) ;
extern void CC2500_Reset(void ) ;
extern uint8_t CYRF_Reset(void ) ;
extern void CYRF_SetTxRxMode(uint8_t mode) ;
extern void frskyUpdate(void) ;
extern uint16_t initDsm2(void) ;
extern uint16_t ReadDsm2(void) ;
extern uint16_t DevoInit(void) ;
extern uint16_t devo_callback(void) ;
extern uint16_t initJ6Pro(void) ;
extern uint16_t ReadJ6Pro(void) ;
extern uint16_t WK_setup(void) ;
extern uint16_t WK_cb(void) ;
extern void randomSeed(unsigned int seed) ;
extern long random(long howbig) ;
extern long map(long x, long in_min, long in_max, long out_min, long out_max) ;
extern uint32_t millis(void) ;
extern uint32_t micros(void) ;
extern void delayMicroseconds(uint16_t x) ;
extern void delayMilliseconds(unsigned long ms) ;
extern void init(void) ;
extern void modules_reset() ;
extern uint8_t Update_All() ;
extern void tx_pause() ;
extern void tx_resume() ;
extern void TelemetryUpdate() ;
extern uint16_t initDsm() ;
extern uint16_t ReadDsm() ;
extern void setup() ;
extern void loop() ;
*/
#define yield()
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )

View File

@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_REVISION 0
#define VERSION_PATCH_LEVEL 5
#define VERSION_PATCH_LEVEL 7
//******************
// Protocols
//******************
@ -364,16 +364,18 @@ enum MultiPacketTypes
//*** AUX flags ***
//*******************
#define GET_FLAG(ch, mask) ( ch ? mask : 0)
#define Servo_AUX1 (Servo_AUX & _BV(0))
#define Servo_AUX2 (Servo_AUX & _BV(1))
#define Servo_AUX3 (Servo_AUX & _BV(2))
#define Servo_AUX4 (Servo_AUX & _BV(3))
#define Servo_AUX5 (Servo_AUX & _BV(4))
#define Servo_AUX6 (Servo_AUX & _BV(5))
#define Servo_AUX7 (Servo_AUX & _BV(6))
#define Servo_AUX8 (Servo_AUX & _BV(7))
#define Servo_AUX9 (Servo_data[AUX9 ]>PPM_SWITCH)
#define Servo_AUX10 (Servo_data[AUX10]>PPM_SWITCH)
#define CH5_SW (Channel_AUX & _BV(0))
#define CH6_SW (Channel_AUX & _BV(1))
#define CH7_SW (Channel_AUX & _BV(2))
#define CH8_SW (Channel_AUX & _BV(3))
#define CH9_SW (Channel_AUX & _BV(4))
#define CH10_SW (Channel_AUX & _BV(5))
#define CH11_SW (Channel_AUX & _BV(6))
#define CH12_SW (Channel_AUX & _BV(7))
#define CH13_SW (Channel_data[CH13]>CHANNEL_SWITCH)
#define CH14_SW (Channel_data[CH14]>CHANNEL_SWITCH)
#define CH15_SW (Channel_data[CH15]>CHANNEL_SWITCH)
#define CH16_SW (Channel_data[CH16]>CHANNEL_SWITCH)
//************************
//*** Power settings ***

View File

@ -75,11 +75,8 @@ uint8_t packet[40];
#define NUM_CHN 16
// Servo data
uint16_t Servo_data[NUM_CHN];
uint16_t Channel_data[NUM_CHN];
uint8_t Servo_AUX;
uint16_t servo_max_100,servo_min_100,servo_max_125,servo_min_125;
uint16_t servo_mid;
uint8_t Channel_AUX;
#ifdef FAILSAFE_ENABLE
uint16_t Failsafe_data[NUM_CHN];
#endif
@ -128,10 +125,10 @@ uint8_t RX_num;
#endif
//Channel mapping for protocols
const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10};
const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8};
const uint8_t CH_RETA[]={RUDDER, ELEVATOR, THROTTLE, AILERON, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8};
const uint8_t CH_EATR[]={ELEVATOR, AILERON, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8};
const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, CH5, CH6, CH7, CH8, CH9, CH10, CH11, CH12, CH13, CH14, CH15, CH16};
const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, CH5, CH6, CH7, CH8, CH9, CH10, CH11, CH12, CH13, CH14, CH15, CH16};
const uint8_t CH_RETA[]={RUDDER, ELEVATOR, THROTTLE, AILERON, CH5, CH6, CH7, CH8, CH9, CH10, CH11, CH12, CH13, CH14, CH15, CH16};
const uint8_t CH_EATR[]={ELEVATOR, AILERON, THROTTLE, RUDDER, CH5, CH6, CH7, CH8, CH9, CH10, CH11, CH12, CH13, CH14, CH15, CH16};
// Mode_select variables
uint8_t mode_select;
@ -362,21 +359,14 @@ void setup()
((MODE_DIAL3_ipr & _BV(MODE_DIAL3_pin)) ? 0 : 4) +
((MODE_DIAL4_ipr & _BV(MODE_DIAL4_pin)) ? 0 : 8);
#endif
//mode_select=1;
debugln("Mode switch reads as %d", mode_select);
// Set default channels' value
for(uint8_t i=0;i<NUM_CHN;i++)
{
Servo_data[i]=1500;
#ifdef ENABLE_PPM
PPM_data[i]=PPM_MAX_100+PPM_MIN_100;
#endif
}
Servo_data[THROTTLE]=servo_min_100;
#ifdef ENABLE_PPM
PPM_data[THROTTLE]=PPM_MIN_100*2;
#endif
InitChannel();
#ifdef ENABLE_PPM
InitPPM();
#endif
// Update LED
LED_off;
@ -444,8 +434,6 @@ void setup()
BIND_IN_PROGRESS; // Force a bind at protocol startup
}
mode_select++;
servo_max_100=PPM_MAX_100; servo_min_100=PPM_MIN_100;
servo_max_125=PPM_MAX_125; servo_min_125=PPM_MIN_125;
protocol_init();
@ -475,8 +463,6 @@ void setup()
for(uint8_t i=0;i<3;i++)
cur_protocol[i]=0;
protocol=0;
servo_max_100=SERIAL_MAX_100; servo_min_100=SERIAL_MIN_100;
servo_max_125=SERIAL_MAX_125; servo_min_125=SERIAL_MIN_125;
#ifdef CHECK_FOR_BOOTLOADER
Mprotocol_serial_init(1); // Configure serial and enable RX interrupt
#else
@ -484,7 +470,6 @@ void setup()
#endif
#endif //ENABLE_SERIAL
}
servo_mid=servo_min_100+servo_max_100; //In fact 2* mid_value
debugln("Init complete");
}
@ -594,25 +579,18 @@ uint8_t Update_All()
{
for(uint8_t i=0;i<PPM_chan_max;i++)
{ // update servo data without interrupts to prevent bad read
uint16_t temp_ppm ;
uint16_t val;
cli(); // disable global int
temp_ppm = PPM_data[i];
val = PPM_data[i];
sei(); // enable global int
uint16_t temp_ppm2;
temp_ppm2=map(temp_ppm,PPM_MIN_100,PPM_MAX_100,CHANNEL_MIN_100,CHANNEL_MAX_100);
if(temp_ppm2&0x8000) temp_ppm2=CHANNEL_MIN_125;
else if(temp_ppm2>CHANNEL_MAX_125) temp_ppm2=CHANNEL_MAX_125;
Channel_data[i]=temp_ppm2;
temp_ppm>>=1;
if(temp_ppm<PPM_MIN_125) temp_ppm=PPM_MIN_125;
else if(temp_ppm>PPM_MAX_125) temp_ppm=PPM_MAX_125;
Servo_data[i]= temp_ppm ;
val=map16b(val,PPM_MIN_100*2,PPM_MAX_100*2,CHANNEL_MIN_100,CHANNEL_MAX_100);
if(val&0x8000) val=CHANNEL_MIN_125;
else if(val>CHANNEL_MAX_125) val=CHANNEL_MAX_125;
Channel_data[i]=val;
}
PPM_FLAG_off; // wait for next frame before update
update_channels_aux();
INPUT_SIGNAL_on; //valid signal received
INPUT_SIGNAL_on; // valid signal received
last_signal=millis();
}
#endif //ENABLE_PPM
@ -624,13 +602,13 @@ uint8_t Update_All()
TelemetryUpdate();
#endif
#ifdef ENABLE_BIND_CH
if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_off && Servo_data[BIND_CH-1]>PPM_MAX_COMMAND && Servo_data[THROTTLE]<(servo_min_100+25))
if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_off && Channel_data[BIND_CH-1]>CHANNEL_MAX_COMMAND && Channel_data[THROTTLE]<(CHANNEL_MIN_100+50))
{ // Autobind is on and BIND_CH went up and Throttle is low
CHANGE_PROTOCOL_FLAG_on; //reload protocol
BIND_IN_PROGRESS; //enable bind
BIND_CH_PREV_on;
}
if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_on && Servo_data[BIND_CH-1]<PPM_MIN_COMMAND)
if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_on && Channel_data[BIND_CH-1]<CHANNEL_MIN_COMMAND)
{ // Autobind is on and BIND_CH went down
BIND_CH_PREV_off;
//Request protocol to terminate bind
@ -651,27 +629,28 @@ uint8_t Update_All()
return 0;
}
// Update channels direction and Servo_AUX flags based on servo AUX positions
// Update channels direction and Channel_AUX flags based on servo AUX positions
static void update_channels_aux(void)
{
//Reverse channels direction
#ifdef REVERSE_AILERON
Servo_data[AILERON]=servo_mid-Servo_data[AILERON];
reverse_channel(AILREON);
#endif
#ifdef REVERSE_ELEVATOR
Servo_data[ELEVATOR]=servo_mid-Servo_data[ELEVATOR];
reverse_channel(ELEVATOR);
#endif
#ifdef REVERSE_THROTTLE
Servo_data[THROTTLE]=servo_mid-Servo_data[THROTTLE];
reverse_channel(THROTTLE);
#endif
#ifdef REVERSE_RUDDER
Servo_data[RUDDER]=servo_mid-Servo_data[RUDDER];
reverse_channel(RUDDER);
#endif
//Calc AUX flags
Servo_AUX=0;
Channel_AUX=0;
for(uint8_t i=0;i<8;i++)
if(Servo_data[AUX1+i]>PPM_SWITCH)
Servo_AUX|=1<<i;
if(Channel_data[CH5+i]>CHANNEL_SWITCH)
Channel_AUX|=1<<i;
}
// Update led status based on binding and serial
@ -883,7 +862,6 @@ static void protocol_init()
case MODE_DSM:
PE2_on; //antenna RF4
next_callback = initDsm();
//Servo_data[2]=1500;//before binding
remote_callback = ReadDsm;
break;
#endif
@ -1083,6 +1061,7 @@ static void protocol_init()
#endif
}
}
debugln("Protocol selected: %d, sub proto %d, rxnum %d, option %d", protocol, sub_protocol, RX_num, option);
#if defined(WAIT_FOR_BIND) && defined(ENABLE_BIND_CH)
if( IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_off && (cur_protocol[1]&0x80)==0 && mode_select == MODE_SERIAL)
@ -1176,7 +1155,6 @@ void update_serial_data()
protocol=(rx_ok_buff[0]==0x55?0:32) + (rx_ok_buff[1]&0x1F); //protocol no (0-63) bits 4-6 of buff[1] and bit 0 of buf[0]
sub_protocol=(rx_ok_buff[2]>>4)& 0x07; //subprotocol no (0-7) bits 4-6
RX_num=rx_ok_buff[2]& 0x0F; // rx_num bits 0---3
debugln("New protocol selected: %d, sub proto %d, rxnum %d, option %d", protocol, sub_protocol, RX_num, option);
}
else
if( ((rx_ok_buff[1]&0x80)!=0) && ((cur_protocol[1]&0x80)==0) ) // Bind flag has been set
@ -1218,10 +1196,7 @@ void update_serial_data()
Failsafe_data[i]=temp; //value range 0..2047, 0=no pulses, 2047=hold
else
#endif
{
Channel_data[i]=temp; //value range 0..2047, 0=-125%, 2047=+125%
Servo_data[i]=(temp*5)/8+860; //value range 860<->2140 -125%<->+125%
}
}
RX_DONOTUPDATE_off;
#ifdef ORANGE_TX
@ -1710,5 +1685,3 @@ static uint32_t random_id(uint16_t address, uint8_t create_new)
}
}
#endif

View File

@ -45,7 +45,7 @@ static uint8_t __attribute__((unused)) cx10wd_getButtons()
packet_count++;
}
// auto land
else if((Servo_data[AUX1] < PPM_MIN_COMMAND) && !(BTN_state & Q303_BTN_DESCEND))
else if((Channel_data[CH5]<CHANNEL_MIN_COMMAND) && !(BTN_state & Q303_BTN_DESCEND))
{
BTN_state |= Q303_BTN_DESCEND;
BTN_state &= ~Q303_BTN_TAKEOFF;
@ -60,7 +60,7 @@ static uint8_t __attribute__((unused)) cx10wd_getButtons()
}
}
// auto take off
else if(Servo_AUX1 && !(BTN_state & Q303_BTN_TAKEOFF))
else if(CH5_SW && !(BTN_state & Q303_BTN_TAKEOFF))
{
BTN_state |= Q303_BTN_TAKEOFF;
BTN_state &= ~Q303_BTN_DESCEND;
@ -100,21 +100,21 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
command |= 0x20; // 2nd keypress
}
// descend
else if(!(GET_FLAG(Servo_AUX1, 1)) && !(BTN_state & Q303_BTN_DESCEND))
else if(!(GET_FLAG(CH5_SW, 1)) && !(BTN_state & Q303_BTN_DESCEND))
{
BTN_state |= Q303_BTN_DESCEND;
BTN_state &= ~Q303_BTN_TAKEOFF;
command = CX35_CMD_DESCEND;
}
// take off
else if(GET_FLAG(Servo_AUX1,1) && !(BTN_state & Q303_BTN_TAKEOFF))
else if(GET_FLAG(CH5_SW,1) && !(BTN_state & Q303_BTN_TAKEOFF))
{
BTN_state |= Q303_BTN_TAKEOFF;
BTN_state &= ~Q303_BTN_DESCEND;
command = CX35_CMD_TAKEOFF;
}
// RTH
else if(GET_FLAG(Servo_AUX6,1) && !(BTN_state & Q303_BTN_RTH))
else if(GET_FLAG(CH10_SW,1) && !(BTN_state & Q303_BTN_RTH))
{
BTN_state |= Q303_BTN_RTH;
if(command == CX35_CMD_RTH)
@ -122,7 +122,7 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
else
command = CX35_CMD_RTH;
}
else if(!(GET_FLAG(Servo_AUX6,1)) && (BTN_state & Q303_BTN_RTH))
else if(!(GET_FLAG(CH10_SW,1)) && (BTN_state & Q303_BTN_RTH))
{
BTN_state &= ~Q303_BTN_RTH;
if(command == CX35_CMD_RTH)
@ -131,7 +131,7 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
command = CX35_CMD_RTH;
}
// video
else if(GET_FLAG(Servo_AUX4,1) && !(BTN_state & Q303_BTN_VIDEO))
else if(GET_FLAG(CH8_SW,1) && !(BTN_state & Q303_BTN_VIDEO))
{
BTN_state |= Q303_BTN_VIDEO;
if(command == CX35_CMD_VIDEO)
@ -139,7 +139,7 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
else
command = CX35_CMD_VIDEO;
}
else if(!(GET_FLAG(Servo_AUX4,1)) && (BTN_state & Q303_BTN_VIDEO))
else if(!(GET_FLAG(CH8_SW,1)) && (BTN_state & Q303_BTN_VIDEO))
{
BTN_state &= ~Q303_BTN_VIDEO;
if(command == CX35_CMD_VIDEO)
@ -148,7 +148,7 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
command = CX35_CMD_VIDEO;
}
// snapshot
else if(GET_FLAG(Servo_AUX3,1) && !(BTN_state & Q303_BTN_SNAPSHOT))
else if(GET_FLAG(CH7_SW,1) && !(BTN_state & Q303_BTN_SNAPSHOT))
{
BTN_state |= Q303_BTN_SNAPSHOT;
if(command == CX35_CMD_SNAPSHOT)
@ -157,7 +157,7 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
command = CX35_CMD_SNAPSHOT;
}
// vtx channel
else if(GET_FLAG(Servo_AUX2,1) && !(BTN_state & Q303_BTN_VTX))
else if(GET_FLAG(CH6_SW,1) && !(BTN_state & Q303_BTN_VTX))
{
BTN_state |= Q303_BTN_VTX;
if(command == CX35_CMD_VTX)
@ -166,9 +166,9 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
command = CX35_CMD_VTX;
}
if(!(GET_FLAG(Servo_AUX3,1)))
if(!(GET_FLAG(CH7_SW,1)))
BTN_state &= ~Q303_BTN_SNAPSHOT;
if(!(GET_FLAG(Servo_AUX2,1)))
if(!(GET_FLAG(CH6_SW,1)))
BTN_state &= ~Q303_BTN_VTX;
return command;
@ -191,10 +191,10 @@ static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
{
case Q303:
case CX35:
aileron = convert_channel_16b(AILERON, 0, 1000);
elevator = convert_channel_16b(ELEVATOR, 1000, 0);
throttle = convert_channel_16b(THROTTLE, 0, 1000);
rudder = convert_channel_16b(RUDDER, 1000, 0);
aileron = convert_channel_16b_limit(AILERON, 0, 1000);
elevator = convert_channel_16b_limit(ELEVATOR, 1000, 0);
throttle = convert_channel_16b_limit(THROTTLE, 0, 1000);
rudder = convert_channel_16b_limit(RUDDER, 1000, 0);
if(sub_protocol == CX35)
aileron = 1000 - aileron;
packet[1] = aileron >> 2; // 8 bits
@ -208,10 +208,10 @@ static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
break;
case CX10D:
case CX10WD:
aileron = convert_channel_16b(AILERON, 2000, 1000);
elevator = convert_channel_16b(ELEVATOR, 2000, 1000);
throttle = convert_channel_16b(THROTTLE, 1000, 2000);
rudder = convert_channel_16b(RUDDER, 1000, 2000);
aileron = convert_channel_16b_limit(AILERON, 2000, 1000);
elevator = convert_channel_16b_limit(ELEVATOR, 2000, 1000);
throttle = convert_channel_16b_limit(THROTTLE, 1000, 2000);
rudder = convert_channel_16b_limit(RUDDER, 1000, 2000);
packet[1] = aileron & 0xff;
packet[2] = aileron >> 8;
packet[3] = elevator & 0xff;
@ -230,21 +230,21 @@ static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
packet[6] = 0x10; // trim(s) ?
packet[7] = 0x10; // trim(s) ?
packet[8] = 0x03 // high rate (0-3)
| GET_FLAG(Servo_AUX1, 0x40)
| GET_FLAG(Servo_AUX6, 0x80);
| GET_FLAG(CH5_SW, 0x40)
| GET_FLAG(CH10_SW, 0x80);
packet[9] = 0x40 // always set
| GET_FLAG(Servo_AUX5,0x08)
| GET_FLAG(Servo_AUX2, 0x80)
| GET_FLAG(Servo_AUX3,0x10)
| GET_FLAG(Servo_AUX4, 0x01);
if(Servo_data[AUX7] < PPM_MIN_COMMAND)
| GET_FLAG(CH9_SW,0x08)
| GET_FLAG(CH6_SW, 0x80)
| GET_FLAG(CH7_SW,0x10)
| GET_FLAG(CH8_SW, 0x01);
if(Channel_data[CH11] < CHANNEL_MIN_COMMAND)
packet[9] |= 0x04; // gimbal down
else if(Servo_data[AUX7] > PPM_MAX_COMMAND)
else if(CH11_SW)
packet[9] |= 0x20; // gimbal up
break;
case CX35:
slider = convert_channel_16b(AUX7, 731, 342);
slider = convert_channel_16b_limit(CH11, 731, 342);
packet[6] = slider >> 2;
packet[7] = ((slider & 3) << 6)
| 0x3e; // ?? 6 bit left (always 111110 ?)
@ -253,13 +253,13 @@ static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
break;
case CX10D:
packet[8] |= GET_FLAG(Servo_AUX2, 0x10);
packet[8] |= GET_FLAG(CH6_SW, 0x10);
packet[9] = 0x02; // rate (0-2)
packet[10]= cx10wd_getButtons(); // auto land / take off management
break;
case CX10WD:
packet[8] |= GET_FLAG(Servo_AUX2, 0x10);
packet[8] |= GET_FLAG(CH6_SW, 0x10);
packet[9] = 0x02 // rate (0-2)
| cx10wd_getButtons(); // auto land / take off management
packet[10] = 0x00;

View File

@ -182,7 +182,7 @@ static void __attribute__((unused)) SFHSS_build_data_packet()
#endif
{ //Normal data
for(uint8_t i=0;i<4;i++)
ch[i] = convert_channel_16b_nolim(CH_AETR[ch_offset+i],2020,1020);
ch[i] = convert_channel_16b_nolimit(CH_AETR[ch_offset+i],2020,1020);
}

View File

@ -65,7 +65,7 @@ void SHENQI_send_packet()
{
LT8900_SetAddress(rx_tx_addr,4);
packet[1]=255-convert_channel_8b(RUDDER);
packet[2]=255-convert_channel_8b_scale(THROTTLE,0x60,0xA0);
packet[2]=255-convert_channel_16b_limit(THROTTLE,0x60,0xA0);
uint8_t freq=pgm_read_byte_near(&SHENQI_Freq[hopping_frequency_no])+(rx_tx_addr[2]&0x0F);
LT8900_SetChannel(freq);
hopping_frequency_no++;

View File

@ -119,8 +119,8 @@ static void __attribute__((unused)) SLT_build_packet()
// Extra bits for AETR
packet[4] = e;
// 8-bit channels
packet[5] = convert_channel_8b(AUX1);
packet[6] = convert_channel_8b(AUX2);
packet[5] = convert_channel_8b(CH5);
packet[6] = convert_channel_8b(CH6);
}
static void __attribute__((unused)) SLT_send_bind_packet()

View File

@ -66,19 +66,19 @@ static void __attribute__((unused)) SYMAX_read_controls()
flags=0;
// Channel 5
if (Servo_AUX1)
if (CH5_SW)
flags = SYMAX_FLAG_FLIP;
// Channel 6
if (Servo_AUX2)
if (CH6_SW)
flags |= SYMAX_XTRM_RATES;
// Channel 7
if (Servo_AUX3)
if (CH7_SW)
flags |= SYMAX_FLAG_PICTURE;
// Channel 8
if (Servo_AUX4)
if (CH8_SW)
flags |= SYMAX_FLAG_VIDEO;
// Channel 9
if (Servo_AUX5)
if (CH9_SW)
{
flags |= SYMAX_FLAG_HEADLESS;
flags &= ~SYMAX_XTRM_RATES; // Extended rates & headless incompatible

View File

@ -46,22 +46,15 @@
#define PPM_MIN_125 900 // 125%
#endif
//Serial MIN MAX values
#define SERIAL_MAX_100 2012 // 100%
#define SERIAL_MIN_100 988 // 100%
#define SERIAL_MAX_125 2140 // 125%
#define SERIAL_MIN_125 860 // 125%
//Channel MIN MAX values
#define CHANNEL_MAX_100 1844 // 100%
#define CHANNEL_MIN_100 204 // 100%
#define CHANNEL_MAX_125 2047 // 125%
#define CHANNEL_MIN_125 0 // 125%
//PPM values used to compare
#define PPM_MIN_COMMAND 1250
#define PPM_SWITCH 1550
#define PPM_MAX_COMMAND 1750
#define CHANNEL_MIN_COMMAND 784 // 1350us
#define CHANNEL_SWITCH 1104 // 1550us
#define CHANNEL_MAX_COMMAND 1424 // 1750us
//Channel definitions
#ifdef AETR
@ -212,15 +205,19 @@
#define RUDDER 0
#endif
#define AUX1 4
#define AUX2 5
#define AUX3 6
#define AUX4 7
#define AUX5 8
#define AUX6 9
#define AUX7 10
#define AUX8 11
#define AUX9 12
#define AUX10 13
#define AUX11 14
#define AUX12 15
#define CH1 0
#define CH2 1
#define CH3 2
#define CH4 3
#define CH5 4
#define CH6 5
#define CH7 6
#define CH8 7
#define CH9 8
#define CH10 9
#define CH11 10
#define CH12 11
#define CH13 12
#define CH14 13
#define CH15 14
#define CH16 15

View File

@ -173,31 +173,31 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind)
//Flags
flags=0;
// Channel 5
if (Servo_AUX1) flags = V2X2_FLAG_FLIP;
if (CH5_SW) flags = V2X2_FLAG_FLIP;
// Channel 6
if (Servo_AUX2) flags |= V2X2_FLAG_LIGHT;
if (CH6_SW) flags |= V2X2_FLAG_LIGHT;
// Channel 7
if (Servo_AUX3) flags |= V2X2_FLAG_CAMERA;
if (CH7_SW) flags |= V2X2_FLAG_CAMERA;
// Channel 8
if (Servo_AUX4) flags |= V2X2_FLAG_VIDEO;
if (CH8_SW) flags |= V2X2_FLAG_VIDEO;
//Flags2
// Channel 9
if (Servo_AUX5)
if (CH9_SW)
flags2 = V2X2_FLAG_HEADLESS;
if(sub_protocol==JXD506)
{
// Channel 11
if (Servo_AUX7)
if (CH11_SW)
flags2 |= V2X2_FLAG_EMERGENCY;
}
else
{
// Channel 10
if (Servo_AUX6)
if (CH10_SW)
flags2 |= V2X2_FLAG_MAG_CAL_X;
// Channel 11
if (Servo_AUX7)
if (CH11_SW)
flags2 |= V2X2_FLAG_MAG_CAL_Y;
}
}
@ -213,12 +213,12 @@ static void __attribute__((unused)) V2X2_send_packet(uint8_t bind)
if(sub_protocol==JXD506)
{
// Channel 10
if (Servo_AUX6)
if (CH10_SW)
packet[11] = V2X2_FLAG_START_STOP;
// Channel 12
if(Servo_data[AUX8] > PPM_MAX_COMMAND)
if(CH12_SW)
packet[11] |= V2X2_FLAG_CAMERA_UP;
else if(Servo_data[AUX8] < PPM_MIN_COMMAND)
else if(Channel_data[CH12] < CHANNEL_MIN_COMMAND)
packet[11] |= V2X2_FLAG_CAMERA_DN;
packet[12] = 0x40;
packet[13] = 0x40;

View File

@ -79,7 +79,7 @@ static void __attribute__((unused)) WK_build_bind_pkt(const uint8_t *init)
static int16_t __attribute__((unused)) WK_get_channel(uint8_t ch, int32_t scale, int16_t center, int16_t range)
{
int16_t value = map(Servo_data[CH_AETR[ch]],servo_min_100,servo_max_100,-scale,scale)+center;
int16_t value = convert_channel_16b_nolimit(CH_AETR[ch],-scale,scale)+center;
if (value < center - range) value = center - range;
if (value > center + range) value = center + range;
return value;

View File

@ -87,15 +87,15 @@ static void __attribute__((unused)) yd717_send_packet(uint8_t bind)
// Flags
flags=0;
// Channel 5
if (Servo_AUX1) flags = YD717_FLAG_FLIP;
if (CH5_SW) flags = YD717_FLAG_FLIP;
// Channel 6
if (Servo_AUX2) flags |= YD717_FLAG_LIGHT;
if (CH6_SW) flags |= YD717_FLAG_LIGHT;
// Channel 7
if (Servo_AUX3) flags |= YD717_FLAG_PICTURE;
if (CH7_SW) flags |= YD717_FLAG_PICTURE;
// Channel 8
if (Servo_AUX4) flags |= YD717_FLAG_VIDEO;
if (CH8_SW) flags |= YD717_FLAG_VIDEO;
// Channel 9
if (Servo_AUX5) flags |= YD717_FLAG_HEADLESS;
if (CH9_SW) flags |= YD717_FLAG_HEADLESS;
packet[7] = flags;
}