From 9b0b2d078c2ed03e84060ad5dbe066572e14a275 Mon Sep 17 00:00:00 2001 From: "bsongis@gmail.com" Date: Fri, 21 Jun 2013 18:28:59 +0000 Subject: [PATCH] [sky9x] PXX fixes [Taranis] DSM2 fixes --- src/protocols/dsm2_arm.cpp | 124 ++++++++++++++++------------ src/protocols/pulses_avr.cpp | 8 +- src/protocols/pxx_arm.cpp | 46 ++++++++++- src/targets/sky9x/pulses_driver.cpp | 13 ++- 4 files changed, 126 insertions(+), 65 deletions(-) diff --git a/src/protocols/dsm2_arm.cpp b/src/protocols/dsm2_arm.cpp index 794d7e82d..c91b84dd3 100644 --- a/src/protocols/dsm2_arm.cpp +++ b/src/protocols/dsm2_arm.cpp @@ -36,11 +36,15 @@ #include "../opentx.h" -uint8_t Bit_pulses[64] ; // Likely more than we need -uint8_t *Pulses2MHzptr ; -uint8_t Serial_byte ; -uint8_t Serial_bit_count; -uint8_t Serial_byte_count ; +#if defined(PCBTARANIS) +uint8_t dsm2Stream[400]; // Likely more than we need +#else +uint8_t dsm2Stream[64]; // Likely more than we need +uint8_t dsm2SerialByte ; +uint8_t dsm2SerialBitCount; +#endif + +uint8_t *dsm2StreamPtr; // DSM2 control bits #define DSM2_CHANS 6 @@ -52,43 +56,64 @@ uint8_t Serial_byte_count ; #define BITLEN_DSM2 (8*2) //125000 Baud => 8uS per bit -void put_serial_bit(uint8_t bit) +#if defined(PCBTARANIS) +void _send_1(uint8_t v) { - Serial_byte >>= 1 ; - if (bit & 1) - { - Serial_byte |= 0x80 ; - } - if (++Serial_bit_count >= 8) - { - *Pulses2MHzptr++ = Serial_byte ; - Serial_bit_count = 0 ; - Serial_byte_count += 1 ; - } + *dsm2StreamPtr++ = v; } void sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1 { - put_serial_bit(0) ; // Start bit - for(uint8_t i=0; i<8; i++) // 8 data Bits - { - put_serial_bit(b & 1) ; - b >>= 1 ; - } - - put_serial_bit(1) ; // Stop bit - put_serial_bit(1) ; // Stop bit + 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 } - -#if defined(PCBTARANIS) -// TODO should be in the driver void putDsm2Flush() { - *Pulses2MHzptr++ = 171 ; // Past the 44000 of the ARR - *Pulses2MHzptr++ = 234 ; // Past the 44000 of the ARR + *dsm2StreamPtr++ = 171; // Past the 44000 of the ARR + *dsm2StreamPtr++ = 234; // Past the 44000 of the ARR } #else -#define putDsm2Flush(...) +void putDsm2SerialBit(uint8_t bit) +{ + dsm2SerialByte >>= 1; + if (bit & 1) { + dsm2SerialByte |= 0x80; + } + if (++dsm2SerialBitCount >= 8) { + *dsm2StreamPtr++ = dsm2SerialByte; + dsm2SerialBitCount = 0; + } +} +void sendByteDsm2(uint8_t b) // max 10changes 0 10 10 10 10 1 +{ + putDsm2SerialBit(0); // Start bit + for (uint8_t i=0; i<8; i++) { // 8 data Bits + putDsm2SerialBit(b & 1); + b >>= 1; + } + + putDsm2SerialBit(1); // Stop bit + putDsm2SerialBit(1); // Stop bit +} +void putDsm2Flush() +{ + for (int i=0; i<16; i++) { + putDsm2SerialBit(1); // 16 extra stop bits + } +} #endif // This is the data stream to send, prepare after 19.5 mS @@ -97,16 +122,17 @@ void putDsm2Flush() //static uint8_t *Dsm2_pulsePtr = pulses2MHz.pbyte ; void setupPulsesDSM2(unsigned int port) { - static uint8_t dsmDat[2+6*2]={0xFF,0x00, 0x00,0xAA, 0x05,0xFF, 0x09,0xFF, 0x0D,0xFF, 0x13,0x54, 0x14,0xAA}; - uint8_t counter ; + static uint8_t dsmDat[2+6*2]={0xFF,0x00, 0x00,0xAA, 0x05,0xFF, 0x09,0xFF, 0x0D,0xFF, 0x13,0x54, 0x14,0xAA}; - Serial_byte = 0 ; - Serial_bit_count = 0 ; - Serial_byte_count = 0 ; - Pulses2MHzptr = Bit_pulses ; +#if defined(PCBSKY9X) + dsm2SerialByte = 0 ; + dsm2SerialBitCount = 0 ; +#endif + + dsm2StreamPtr = dsm2Stream; // If more channels needed make sure the pulses union/array is large enough - if (dsmDat[0]&BAD_DATA) //first time through, setup header + if (dsmDat[0] & BAD_DATA) //first time through, setup header { switch(s_current_protocol[port]) { @@ -122,25 +148,21 @@ void setupPulsesDSM2(unsigned int port) } } if ((dsmDat[0] & BIND_BIT) && (!switchState(SW_DSM2_BIND))) - dsmDat[0] &= ~BIND_BIT; // clear bind bit if trainer not pulled + dsmDat[0] &= ~BIND_BIT; // clear bind bit if trainer not pulled if ((!(dsmDat[0] & BIND_BIT)) && s_rangecheck_mode) - dsmDat[0] |= RANGECHECK_BIT; // range check function + dsmDat[0] |= RANGECHECK_BIT; // range check function else - dsmDat[0] &= ~RANGECHECK_BIT; + dsmDat[0] &= ~RANGECHECK_BIT; dsmDat[1] = g_model.header.modelId; //DSM2 Header second byte for model match - for(uint8_t i=0; i<6; i++) { - uint16_t pulse = limit(0, ((channelOutputs[g_model.moduleData[port].channelsStart+i]*13)>>5)+512,1023); + + for (int i=0; i>5)+512, 1023); dsmDat[2+2*i] = (i<<2) | ((pulse>>8)&0x03); dsmDat[3+2*i] = pulse & 0xff; } - for (counter = 0 ; counter < 14 ; counter += 1) - { - sendByteDsm2(dsmDat[counter]); - } - for (counter = 0 ; counter < 16 ; counter += 1) - { - put_serial_bit(1) ; // 16 extra stop bits + for (int i=0; i<14; i++) { + sendByteDsm2(dsmDat[i]); } putDsm2Flush(); diff --git a/src/protocols/pulses_avr.cpp b/src/protocols/pulses_avr.cpp index d6ba0a3a3..7113b99c0 100644 --- a/src/protocols/pulses_avr.cpp +++ b/src/protocols/pulses_avr.cpp @@ -537,15 +537,15 @@ void setupPulsesDSM2() s_bind_mode = false; dsmDat[1] = g_model.header.modelId; // DSM2 Header second byte for model match - for (uint8_t i=0; i>5)+512,1023); + for (uint8_t i=0; i>5)+512, 1023); dsmDat[2+2*i] = (i<<2) | ((pulse>>8)&0x03); // encoded channel + upper 2 bits pulse width dsmDat[3+2*i] = pulse & 0xff; // low byte } - for (counter=0; counter<14; counter++) + for (counter=0; counter<14; counter++) { sendByteDsm2(dsmDat[counter]); + } pulses2MHzWPtr -= 1; //remove last stopbits and diff --git a/src/protocols/pxx_arm.cpp b/src/protocols/pxx_arm.cpp index 362d73d50..0f84fd6d5 100644 --- a/src/protocols/pxx_arm.cpp +++ b/src/protocols/pxx_arm.cpp @@ -37,8 +37,15 @@ #include "../opentx.h" uint8_t pxxFlag[NUM_MODULES] = { MODULES_INIT(0) }; -uint16_t pxxStream[NUM_MODULES][400]; // Transitions + +#if defined(PCBTARANIS) +uint16_t pxxStream[NUM_MODULES][400]; uint16_t *pxxStreamPtr[NUM_MODULES]; +#else +uint8_t pxxStream[NUM_MODULES][64]; +uint8_t *pxxStreamPtr[NUM_MODULES]; +#endif + uint16_t PxxValue[NUM_MODULES]; uint16_t PcmCrc[NUM_MODULES]; uint8_t PcmOnesCount[NUM_MODULES]; @@ -84,6 +91,8 @@ void crc(uint8_t data, unsigned int port) PcmCrc[port]=(PcmCrc[port]<<8)^(CRCTable[((PcmCrc[port]>>8)^data) & 0xFF]); } +#if defined(PCBTARANIS) + void putPcmPart(uint8_t value, unsigned int port) { PxxValue[port] += 18 ; // Output 1 for this time @@ -95,13 +104,44 @@ void putPcmPart(uint8_t value, unsigned int port) *pxxStreamPtr[port]++ = PxxValue[port] ; // Output 0 for this time } -#if defined(PCBTARANIS) void putPcmFlush(unsigned int port) { *pxxStreamPtr[port]++ = 18010 ; // Past the 18000 of the ARR } + #else -#define putPcmFlush(...) + +uint8_t pcmSerialByte[NUM_MODULES]; +uint8_t pcmSerialBitCount[NUM_MODULES]; +void putPcmSerialBit(uint8_t bit, unsigned int port) +{ + pcmSerialByte[port] >>= 1; + if (bit & 1) { + pcmSerialByte[port] |= 0x80; + } + if (++pcmSerialBitCount[port] >= 8) { + *pxxStreamPtr[port]++ = pcmSerialByte[port]; + pcmSerialBitCount[port] = 0; + } +} + +// 8uS/bit 01 = 0, 001 = 1 +void putPcmPart(uint8_t value, unsigned int port) +{ + putPcmSerialBit(0, port); + if (value) { + putPcmSerialBit(0, port); + } + putPcmSerialBit(1, port); +} + +void putPcmFlush(unsigned int port) +{ + while (pcmSerialBitCount[port] != 0) { + putPcmSerialBit(1, port); + } +} + #endif void putPcmBit(uint8_t bit, unsigned int port) diff --git a/src/targets/sky9x/pulses_driver.cpp b/src/targets/sky9x/pulses_driver.cpp index 5d3f5354d..a5aef743e 100644 --- a/src/targets/sky9x/pulses_driver.cpp +++ b/src/targets/sky9x/pulses_driver.cpp @@ -38,11 +38,10 @@ extern uint16_t ppmStream[NUM_MODULES][20]; volatile uint32_t ppmStreamIndex[NUM_MODULES] = { MODULES_INIT(0) }; // Modified in interrupt routine -extern uint16_t pxxStream[NUM_MODULES][400]; // Transitions -extern uint16_t *pxxStreamPtr[NUM_MODULES]; -extern uint8_t Bit_pulses[64] ; // Likely more than we need -extern uint8_t Serial_byte_count ; - +extern uint8_t pxxStream[NUM_MODULES][64]; // TODO not here, duplicated +extern uint8_t *pxxStreamPtr[NUM_MODULES]; // TODO not here, duplicated +extern uint8_t dsm2Stream[64]; // Likely more than we need +extern uint8_t *dsm2StreamPtr; void init_main_ppm(uint32_t period, uint32_t out_enable) { @@ -192,8 +191,8 @@ extern "C" void PWM_IRQHandler(void) else { // Kick off serial output here sscptr = SSC; - sscptr->SSC_TPR = CONVERT_PTR(Bit_pulses); - sscptr->SSC_TCR = Serial_byte_count; + sscptr->SSC_TPR = CONVERT_PTR(dsm2Stream); + sscptr->SSC_TCR = (uint8_t *)dsm2StreamPtr - (uint8_t *)dsm2Stream; sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers } break;