DSM2 (ppm mode) pulled from er9x

This commit is contained in:
bsongis
2012-01-20 18:23:17 +00:00
parent 80bfc11a83
commit 30f513d586
7 changed files with 104 additions and 28 deletions
+21 -6
View File
@@ -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);
+6
View File
@@ -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
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
+3
View File
@@ -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"
+3
View File
@@ -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"