DSM2 (ppm mode) pulled from er9x
This commit is contained in:
+21
-6
@@ -387,7 +387,7 @@ void EditName(uint8_t x, uint8_t y, char *name, uint8_t size, uint8_t event, boo
|
||||
void menuProcModel(uint8_t event)
|
||||
{
|
||||
lcd_outdezNAtt(7*FW,0,g_eeGeneral.currModel+1,INVERS+LEADING0,2);
|
||||
MENU(STR_MENUSETUP, menuTabModel, e_Model, (g_model.protocol ? 10 : 11), {0,sizeof(g_model.name)-1,2,2,0,0,0,0,6,2,1});
|
||||
MENU(STR_MENUSETUP, menuTabModel, e_Model, (g_model.protocol==PROTO_PPM ? 12 : 11), {0,sizeof(g_model.name)-1,2,2,0,0,0,0,0,6,2,1});
|
||||
|
||||
uint8_t sub = m_posVert;
|
||||
uint8_t y = 1*FH;
|
||||
@@ -491,24 +491,39 @@ void menuProcModel(uint8_t event)
|
||||
lcd_puts_P(0, y, STR_PROTO);
|
||||
lcd_putsnAtt(PARAM_OFS, y, STR_VPROTOS+LEN_VPROTOS*g_model.protocol, LEN_VPROTOS,
|
||||
(sub==subN && m_posHorz==0 ? (s_editMode>0 ? BLINK : INVERS):0));
|
||||
if(!g_model.protocol) {
|
||||
if (!g_model.protocol) {
|
||||
lcd_putsnAtt(PARAM_OFS+4*FW, y, STR_NCHANNELS+LEN_NCHANNELS*(g_model.ppmNCH+2), LEN_NCHANNELS, ((sub==subN && m_posHorz==1) ? ((s_editMode>0) ? BLINK : INVERS) : 0));
|
||||
lcd_puts_P(PARAM_OFS+11*FW, y, PSTR("u"));
|
||||
lcd_outdezAtt(PARAM_OFS+11*FW, y, (g_model.ppmDelay*50)+300, ((sub==subN && m_posHorz==2) ? ((s_editMode>0) ? BLINK : INVERS) : 0));
|
||||
}
|
||||
#ifdef DSM2
|
||||
// TODO optimize that?
|
||||
else if (g_model.protocol == PROTO_DSM2) {
|
||||
if (m_posHorz > 1) m_posHorz = 1;
|
||||
int8_t x;
|
||||
x = g_model.ppmNCH;
|
||||
if ( x < 0 ) x = 0;
|
||||
if ( x > 2 ) x = 2;
|
||||
g_model.ppmNCH = x;
|
||||
lcd_putsnAtt(PARAM_OFS+5*FW, y, STR_DSM2MODE+LEN_DSM2MODE*x, LEN_DSM2MODE, (sub==subN && m_posHorz==1 ? ((s_editMode>0) ? BLINK : INVERS) : 0));
|
||||
}
|
||||
#endif
|
||||
else if (sub==subN) {
|
||||
m_posHorz = 0;
|
||||
}
|
||||
if (sub==subN && (s_editMode>0 || p1valdiff || g_model.protocol) ) {
|
||||
if (sub==subN && (s_editMode>0 || p1valdiff || (g_model.protocol!=0 && g_model.protocol!=PROTO_DSM2))) { // TODO avoid DSM2 when not defined
|
||||
switch (m_posHorz) {
|
||||
case 0:
|
||||
CHECK_INCDEC_MODELVAR(event,g_model.protocol,0,PROT_MAX);
|
||||
break;
|
||||
case 1:
|
||||
CHECK_INCDEC_MODELVAR(event,g_model.ppmNCH,-2,4);
|
||||
if (g_model.protocol == PROTO_DSM2) // TODO avoid DSM2 when not defined
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.ppmNCH, 0, 2);
|
||||
else
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.ppmNCH, -2, 4);
|
||||
break;
|
||||
case 2:
|
||||
CHECK_INCDEC_MODELVAR(event,g_model.ppmDelay,-4,10);
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.ppmDelay, -4, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -516,7 +531,7 @@ void menuProcModel(uint8_t event)
|
||||
}subN++;
|
||||
|
||||
if(s_pgOfs<subN) {
|
||||
if (!g_model.protocol) {
|
||||
if (g_model.protocol == PROTO_PPM) {
|
||||
lcd_puts_P(0, y, STR_PPMFRAME);
|
||||
lcd_puts_P(PARAM_OFS+3*FW, y, STR_MS);
|
||||
lcd_outdezAtt(PARAM_OFS, y, (int16_t)g_model.ppmFrameLength*5 + 225, ((sub==subN && m_posHorz==0) ? (s_editMode>0 ? BLINK : INVERS) : 0) | PREC1|LEFT);
|
||||
|
||||
@@ -255,6 +255,12 @@ PACK(typedef struct t_TimerData {
|
||||
uint16_t val;
|
||||
}) TimerData;
|
||||
|
||||
#ifdef DSM2
|
||||
#define LPXDSM2 0
|
||||
#define DSM2only 1
|
||||
#define DSM2_DSMX 2
|
||||
#endif
|
||||
|
||||
PACK(typedef struct t_ModelData {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
TimerData timer1; // TODO timers array
|
||||
|
||||
@@ -38,6 +38,9 @@ const prog_char APM STR_OPEN9X[] =
|
||||
TR_VSWITCHES
|
||||
TR_VSRCRAW
|
||||
TR_VTMRMODES
|
||||
#if defined(DSM2)
|
||||
TR_DSM2MODE
|
||||
#endif
|
||||
#if defined(PCBV3)
|
||||
TR_RE1RE2
|
||||
TR_DATETIME
|
||||
|
||||
+15
-1
@@ -60,8 +60,14 @@ extern const PROGMEM char STR_OPEN9X[];
|
||||
#define OFS_VSWITCHES (OFS_VKEYS + PSIZE(TR_VKEYS))
|
||||
#define OFS_VSRCRAW (OFS_VSWITCHES + PSIZE(TR_VSWITCHES))
|
||||
#define OFS_VTMRMODES (OFS_VSRCRAW + PSIZE(TR_VSRCRAW))
|
||||
#if defined(DSM2)
|
||||
#define OFS_DSM2MODE (OFS_VTMRMODES + PSIZE(TR_VTMRMODES))
|
||||
#define OFS_ENDDSM2 (OFS_DSM2MODE + PSIZE(TR_DSM2MODE))
|
||||
#else
|
||||
#define OFS_ENDDSM2 (OFS_VTMRMODES + PSIZE(TR_VTMRMODES))
|
||||
#endif
|
||||
#if defined(PCBV3)
|
||||
#define OFS_RE1RE2 (OFS_VTMRMODES + PSIZE(TR_VTMRMODES))
|
||||
#define OFS_RE1RE2 (OFS_ENDDSM2)
|
||||
#define OFS_DATETIME (OFS_RE1RE2 + PSIZE(TR_RE1RE2))
|
||||
#endif
|
||||
|
||||
@@ -87,6 +93,7 @@ extern const PROGMEM char STR_OPEN9X[];
|
||||
#define STR_VMLTPX2 (STR_OPEN9X + OFS_VMLTPX2)
|
||||
#define STR_VCSWFUNC (STR_OPEN9X + OFS_VCSWFUNC)
|
||||
#define STR_VFSWFUNC (STR_OPEN9X + OFS_VFSWFUNC)
|
||||
|
||||
#ifdef FRSKY
|
||||
#define STR_VTELEMUNIT (STR_OPEN9X + OFS_VTELEMUNIT)
|
||||
#define STR_VALARM (STR_OPEN9X + OFS_VALARM)
|
||||
@@ -94,17 +101,24 @@ extern const PROGMEM char STR_OPEN9X[];
|
||||
#define STR_VTELPROTO (STR_OPEN9X + OFS_VTELPROTO)
|
||||
#define STR_TELEMCHNS (STR_OPEN9X + OFS_TELEMCHNS)
|
||||
#endif
|
||||
|
||||
#ifdef TEMPLATES
|
||||
#define STR_VTEMPLATES (STR_OPEN9X + OFS_VTEMPLATES)
|
||||
#endif
|
||||
|
||||
#ifdef HELI
|
||||
#define STR_VSWASHTYPE (STR_OPEN9X + OFS_VSWASHTYPE)
|
||||
#endif
|
||||
|
||||
#define STR_VKEYS (STR_OPEN9X + OFS_VKEYS)
|
||||
#define STR_VSWITCHES (STR_OPEN9X + OFS_VSWITCHES)
|
||||
#define STR_VSRCRAW (STR_OPEN9X + OFS_VSRCRAW)
|
||||
#define STR_VTMRMODES (STR_OPEN9X + OFS_VTMRMODES)
|
||||
|
||||
#if defined(DSM2)
|
||||
#define STR_DSM2MODE (STR_OPEN9X + OFS_DSM2MODE)
|
||||
#endif
|
||||
|
||||
#if defined(PCBV3)
|
||||
#define STR_RE1RE2 (STR_OPEN9X + OFS_RE1RE2)
|
||||
#define STR_DATETIME (STR_OPEN9X + OFS_DATETIME)
|
||||
|
||||
+53
-21
@@ -21,6 +21,15 @@
|
||||
|
||||
#include "open9x.h"
|
||||
|
||||
#ifdef DSM2
|
||||
#define DSM2_CHANS 6
|
||||
#define BIND_BIT 0x80
|
||||
#define RANGECHECK_BIT 0x20
|
||||
#define FRANCE_BIT 0x10
|
||||
#define DSMX_BIT 0x08
|
||||
#define BAD_DATA 0x47
|
||||
#endif
|
||||
|
||||
#if defined(DSM2_PPM) || defined(PXX)
|
||||
uint8_t s_current_protocol = 255;
|
||||
#endif
|
||||
@@ -248,11 +257,9 @@ normal:
|
||||
|
||||
*/
|
||||
|
||||
#define DSM2_CHANS 6
|
||||
|
||||
FORCEINLINE void setupPulsesDsm2()
|
||||
{
|
||||
*pulses2MHzWPtr++ = (isFunctionActive(FUNC_MODELMATCH) ? 0x80 : 0x00);
|
||||
*pulses2MHzWPtr++ = (isFunctionActive(FUNC_MODELMATCH) ? BIND_BIT : 0x00);
|
||||
*pulses2MHzWPtr++ = g_eeGeneral.currModel;
|
||||
for (uint8_t i=0; i<DSM2_CHANS; i++) {
|
||||
uint16_t pulse = limit(0, (g_chans512[i]>>1)+512, 1023);
|
||||
@@ -300,34 +307,59 @@ void DSM2_Init(void)
|
||||
#endif
|
||||
|
||||
#if defined(DSM2_PPM)
|
||||
static uint8_t *Dsm2_pulsePtr = (uint8_t *)pulses2MHz;
|
||||
void setupPulsesDsm2(uint8_t chns)
|
||||
static uint8_t *pulses2MHzDSM2WPtr = (uint8_t *)pulses2MHz;
|
||||
static uint8_t *pulses2MHzDSM2RPtr = (uint8_t *)pulses2MHz;
|
||||
inline void _send_1(uint8_t v)
|
||||
{
|
||||
static uint8_t dsmDat[2+6*2]= {0xFF,0x00, 0x00,0xAA, 0x05,0xFF, 0x09,0xFF, 0x0D,0xFF, 0x13,0x54, 0x14,0xAA};
|
||||
*pulses2MHzDSM2WPtr++ = v;
|
||||
}
|
||||
|
||||
#define BITLEN_DSM2 (8*2) //125000 Baud
|
||||
void sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1
|
||||
{
|
||||
bool lev = 0;
|
||||
uint8_t len = BITLEN_DSM2; //max val: 9*16 < 256
|
||||
for( uint8_t i=0; i<=8; i++){ //8Bits + Stop=1
|
||||
bool nlev = b & 1; //lsb first
|
||||
if(lev == nlev){
|
||||
len += BITLEN_DSM2;
|
||||
}else{
|
||||
_send_1(len -1);
|
||||
len = BITLEN_DSM2;
|
||||
lev = nlev;
|
||||
}
|
||||
b = (b>>1) | 0x80; //shift in stop bit
|
||||
}
|
||||
_send_1(len+BITLEN_DSM2-1); // 2 stop bits
|
||||
}
|
||||
|
||||
void setupPulsesDsm2()
|
||||
{
|
||||
static uint8_t dsmDat[2+6*2] = {0xFF,0x00, 0x00,0xAA, 0x05,0xFF, 0x09,0xFF, 0x0D,0xFF, 0x13,0x54, 0x14,0xAA};
|
||||
uint8_t counter;
|
||||
|
||||
// If more channels needed make sure the pulses union/array is large enough
|
||||
if (dsmDat[0] & BadData) //first time through, setup header
|
||||
if (dsmDat[0] & BAD_DATA) // first time through, setup header
|
||||
{
|
||||
switch(g_model.ppmNCH)
|
||||
{
|
||||
case LPXDSM2:
|
||||
dsmDat[0]= 0x80;
|
||||
dsmDat[0] = BIND_BIT;
|
||||
break;
|
||||
case DSM2only:
|
||||
dsmDat[0]=0x90;
|
||||
dsmDat[0] = 0x90;
|
||||
break;
|
||||
default:
|
||||
dsmDat[0]=0x98; //dsmx, bind mode
|
||||
dsmDat[0] = 0x98; // DSMX bind mode
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((dsmDat[0]&BindBit)&&(!keyState(SW_Trainer))) dsmDat[0]&=~BindBit; //clear bind bit if trainer not pulled
|
||||
if ((!(dsmDat[0]&BindBit))&&getSwitch(MAX_DRSWITCH-1,0,0)) dsmDat[0]|=RangeCheckBit; //range check function
|
||||
if ((dsmDat[0] & BIND_BIT) && (!isFunctionActive(FUNC_MODELMATCH))) dsmDat[0] &= ~BIND_BIT; //clear bind bit if trainer not pulled
|
||||
// TODO add a function key for that: if ((!(dsmDat[0] & BIND_BIT)) && isFunctionActive(FUNC_RANGECHECK)) dsmDat[0] |= RANGECHECK_BIT; //range check function
|
||||
|
||||
else dsmDat[0]&=~RangeCheckBit;
|
||||
dsmDat[1]=g_eeGeneral.currModel+1; //DSM2 Header second byte for model match
|
||||
for(uint8_t i=0; i<chns; i++)
|
||||
else dsmDat[0] &= ~RANGECHECK_BIT;
|
||||
dsmDat[1] = g_eeGeneral.currModel+1; //DSM2 Header second byte for model match
|
||||
for (uint8_t i=0; i<DSM2_CHANS; i++)
|
||||
{
|
||||
uint16_t pulse = limit(0, (g_chans512[i]>>1)+512,1023);
|
||||
dsmDat[2+2*i] = (i<<2) | ((pulse>>8)&0x03);
|
||||
@@ -338,12 +370,11 @@ void setupPulsesDsm2(uint8_t chns)
|
||||
{
|
||||
sendByteDsm2(dsmDat[counter]);
|
||||
}
|
||||
pulses2MHzptr-=1; //remove last stopbits and
|
||||
pulses2MHzDSM2WPtr -= 1; //remove last stopbits and
|
||||
_send_1( 255 ); //prolong them
|
||||
_send_1(0); //end of pulse stream
|
||||
Dsm2_pulsePtr = pulses2MHz.pbyte;
|
||||
pulses2MHzDSM2RPtr = (uint8_t *)pulses2MHz;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SILVER) || defined(CTP1009)
|
||||
@@ -545,6 +576,7 @@ void setupPulses()
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO these 2 lines could be avoided when protocol is DSM2 (PPM output)
|
||||
pulses2MHzWPtr = pulses2MHz;
|
||||
pulses2MHzRPtr = pulses2MHz;
|
||||
|
||||
@@ -567,7 +599,7 @@ void setupPulses()
|
||||
setupPulsesPXX();
|
||||
break;
|
||||
#endif
|
||||
#ifdef DSM2_SERIAL
|
||||
#ifdef DSM2
|
||||
case PROTO_DSM2:
|
||||
sei();
|
||||
setupPulsesDsm2();
|
||||
@@ -585,10 +617,10 @@ ISR(TIMER1_CAPT_vect) // 2MHz pulse generation
|
||||
{
|
||||
uint8_t x ;
|
||||
PORTB ^= (1<<OUT_B_PPM);
|
||||
x = *Dsm2_pulsePtr++; // Byte size
|
||||
x = *pulses2MHzDSM2RPtr++; // Byte size
|
||||
ICR1 = x ;
|
||||
if (x > 200) PORTB |= (1<<OUT_B_PPM); // Make sure pulses are the correct way up
|
||||
heartbeat |= HEART_TIMER2Mhz;
|
||||
heartbeat |= HEART_TIMER2Mhz; // TODO why not in TIMER1_COMPB_vect (in setupPulses)?
|
||||
}
|
||||
|
||||
ISR(TIMER1_COMPB_vect) // DSM2 end of frame
|
||||
|
||||
@@ -115,6 +115,9 @@
|
||||
#define TR_TELEMCHNS "AD1AD2"
|
||||
#endif
|
||||
|
||||
#define LEN_DSM2MODE 7
|
||||
#define TR_DSM2MODE "LP4/LP5DSMonlyDSMX "
|
||||
|
||||
// ZERO TERMINATED STRINGS
|
||||
#define TR_POPUPS "[MENU] [EXIT]"
|
||||
#define TR_MENUWHENDONE " [MENU] WHEN DONE"
|
||||
|
||||
@@ -115,6 +115,9 @@
|
||||
#define TR_TELEMCHNS "AD1AD2"
|
||||
#endif
|
||||
|
||||
#define LEN_DSM2MODE 7
|
||||
#define TR_DSM2MODE "LP4/LP5DSMonlyDSMX "
|
||||
|
||||
// ZERO TERMINATED STRINGS
|
||||
#define TR_POPUPS "[MENU] [EXIT]"
|
||||
#define TR_MENUWHENDONE " [MENU] WHEN DONE"
|
||||
|
||||
Reference in New Issue
Block a user