Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 1205 → Rev 1206

/branches/V0.72p Code Redesign killagreg/dsl.c
2,23 → 2,51
#include "rc.h"
 
/*
1. GND (at channel 4 side)
2. TxD
3. RxD
4. 5V
*/
Connection of DSL to SV1 of FC:
( DSL Pin1 is on side of channel 4 )
 
// dsl protocol parser state machine
#define DSLSTATE_SYNC1 0
#define DSLSTATE_SYNC2 1
#define DSLSTATE_HDR 2
#define DSLSTATE_DATA 3
#define DSLSTATE_CRC 4
1. GND <--> pin 7 (GND)
2. TXD <--> pin 3 (RXD1 Atmega644p)
3. RXD <--> pin 4 (TXD1 Atmega644p) optional
4. 5V <--> pin 2 (5V)
 
#define DSL_SYNC1_CHAR 0xFF
#define DSL_SYNC2_CHAR 0xFF
Do not connect the receiver via PPM-Sumsignal output the same time.
 
Data are send at 38400baud8n1
 
Data Frame: |0xFF|0xFF|0x1F|FREQALLOC|??|RSSI|VBAT|??|CRC|10|CH0D1|CH0D0|CH1D1|CH1D0|CRC| ...etc
 
FREQALLOC = 35, 40, 72
RSSI = 0.. 255 // Received signal strength indicator
VBAT = 0...255 // supply voltage (0.0V.. 8.2V)
 
Servo Pair: |0x1X|CHXD1|CHXD0|CHX+1D1|CHX+1D0|CRC|
X is channel index of 1 servo value
D1D0 is servo value as u16 in range of 7373 (1ms) to 14745 (2ms)
there are 8 channels submitted, i.e 4 servo pairs
 
 
Frame examples with signel received
 
FFFF 1F23F079A304AD 1036012B1E6F 122AFB2AECB2 142B4D2B4404 1636872B33CE
FFFF 1F23F079A304AD 1036002B1F6F 122AFE2AEBB0 142B4B2B4406 1636872B33CE
FFFF 1F23F079A304AD 1035FF2B226E 122AFC2AEAB3 142B4E2B4304 1636882B33CD
FFFF 1F23F079A304AD 1036022B1E6E 122AFB2AEEB0 142B4A2B4506 1636872B33CE
FFFF 1F23F079A304AD 1036022B1E6E 122AFE2AEBB0 142B4B2B4406 1636882B33CD
FFFF 1F23F079A304AD 1036012B1E6F 122AFD2AEAB2 142B4E2B4403 1636862B33CF
FFFF 1F23F079A304AD 1036032B1D6E 122AFD2AEBB1 142B4C2B4504 1636862B33CF
 
Frame examples with no signal received
 
FFFF 1F23F000A30426
FFFF 1F23F000A30426
FFFF 1F23F000A30426
FFFF 1F23F000A30426
FFFF 1F23F000A30426
FFFF 1F23F000A30426
FFFF 1F23F000A30426
*/
 
uint8_t dsl_RSSI = 0;
uint8_t dsl_Battery = 0;
uint8_t dsl_Allocation = 0;
28,9 → 56,9
{
int16_t Servo[2];
uint8_t byte[4];
} ServoPair_t;
} ChannelPair_t;
 
ServoPair_t ServoPair;
ChannelPair_t ChannelPair;
 
 
// This function is called, when a new servo signal is properly received.
42,8 → 70,7
uint8_t index = channel + 1; // mk channels start with 1
 
 
// Signal vom ACTDSL-Empfänger liegt zwischen
// 7373 (1ms) und 14745 (2ms).
// signal from DSL-receiver is between 7373 (1ms) und 14745 (2ms).
signal-= 11059; // shift to neutral
signal/= 24; // scale to mk rc resolution
 
56,7 → 83,11
else PPM_diff[index] = 0;
PPM_in[index] = tmp; // update channel value
 
if(index == 4) NewPpmData = 0;
if(index == 4)
{
NewPpmData = 0;
NewRCFrames++;
}
}
 
// This function is called within dsl_parser(), when a complete
65,96 → 96,82
{
uint8_t i;
 
if(PacketBuffer[0] == 0x1F) // separate status frame
{
dsl_Allocation = PacketBuffer[1]; // Get frequency allocation
// ?? = PacketBuffer[2];
dsl_RSSI = PacketBuffer[3]; // Get signal quality
RC_Quality = dsl_RSSI; // have to be scaled
dsl_Battery = PacketBuffer[4]; // Get voltage of battery supply
// ?? = PacketBuffer[5];
}
else // analyze servo pair frame
{
i = PacketBuffer[0] & 0x0F; // last 4 bits of the header indicates servo pair
if(i < 10)
// check for header condition
if((PacketBuffer[0] & 0xF0) == 0x10)
{
if(PacketBuffer[0] == 0x1F) // separate status frame
{
// big to little endian
ServoPair.byte[1] = PacketBuffer[1];
ServoPair.byte[0] = PacketBuffer[2];
ServoPair.byte[3] = PacketBuffer[3];
ServoPair.byte[2] = PacketBuffer[4];
dsl_new_signal(i, ServoPair.Servo[0]);
dsl_new_signal(i+1,ServoPair.Servo[0]);
dsl_Allocation = PacketBuffer[1]; // Get frequency allocation
// ?? = PacketBuffer[2];
dsl_RSSI = PacketBuffer[3]; // Get signal quality
RC_Quality = (212 * (uint16_t)dsl_RSSI) / 128; // have to be scaled approx. by a factor of 1.66 to get 200 at full level
if(RC_Quality > 255) RC_Quality = 255;
dsl_Battery = PacketBuffer[4]; // Get voltage of battery supply
// ?? = PacketBuffer[5];
if(dsl_RSSI == 0)
{
for (i = 0; i<5; i++)
{
PPM_diff[i] = 0;
PPM_in[i] = 0;
}
}
}
}
else // probably a channel pair
{
i = PacketBuffer[0] & 0x0F; // last 4 bits of the header indicates the channel pair
if(i < 10)// maximum 12 channels
{
// big to little endian
ChannelPair.byte[1] = PacketBuffer[1];
ChannelPair.byte[0] = PacketBuffer[2];
ChannelPair.byte[3] = PacketBuffer[3];
ChannelPair.byte[2] = PacketBuffer[4];
dsl_new_signal(i, ChannelPair.Servo[0]);
dsl_new_signal(i+1,ChannelPair.Servo[1]);
}
}
} // EOF header condition
}
 
 
// Status Frame: |0xFF|0xFF|0x1F|FREQALLOC|??|RSSI|VBAT|??|CRC|
// FREQ ALLOC = 35, 40, 72
// RSSI = 0.. 255 // Received signal strength indicator
// VBAT = 0...255 // supply voltage (0.0V.. 8.2V)
//
// Servo Pair: |0xFF|0xFF|0x1X|D0|D1|D2|D3|CRC|
// X is channel index of 1 servo value
// D0, D1 is servo channel X
// D2, D3 is servo channel X+1
 
// this function should be called within the UART RX ISR
void dsl_parser(uint8_t c)
{
static uint8_t last_c = 0;
static uint8_t crc = 0;
static uint8_t cnt = 0;
static uint8_t packet_len = 0;
 
static uint8_t dslstate = DSLSTATE_SYNC1;
// check for sync condition
if ((c==0xFF) && (last_c==0xFF))
{
cnt = 0; // reset byte counter
crc = 0; // reset checksum
return;
}
 
switch(dslstate)
if(cnt == 0) // begin of a packet
{
case DSLSTATE_SYNC1: // check 1st sync byte
if (c == DSL_SYNC1_CHAR) dslstate = DSLSTATE_SYNC2;
else dslstate = DSLSTATE_SYNC1; // out of synchronization
break;
 
case DSLSTATE_SYNC2: // check 2nd sync byte
if (c == DSL_SYNC2_CHAR) dslstate = DSLSTATE_HDR; // snchrinization complete trigger to cmd
else dslstate = DSLSTATE_SYNC1; // out of synchronization
break;
 
case DSLSTATE_HDR: // check header byte
if ((c & 0xF0) != 0x10)
{
dslstate = DSLSTATE_SYNC1;
}
else
{
cnt = 0;
PacketBuffer[cnt++] = c;
crc = c;
if(c == 0x1F) packet_len = 5;
else packet_len = 4;
dslstate = DSLSTATE_DATA;
}
break;
 
case DSLSTATE_DATA:
PacketBuffer[cnt++] = c;
crc += c;
if(cnt > packet_len) dslstate = DSLSTATE_CRC;
break;
 
case DSLSTATE_CRC:
// Calculate checksum
crc = ~crc;
if (crc == 0xFF) crc = 0xFE;
// if crc matches
if (c == crc) dsl_decode_packet();
dslstate = DSLSTATE_SYNC1;
break;
 
default: // unknown ubx state
dslstate = DSLSTATE_SYNC1;
break;
if(c == 0x1F) packet_len = 5; // a status packet has 5 bytes + crc
else packet_len = 4; // a channel pair packet has 4 bytes + crc
}
if(cnt > packet_len) // packet complete, crc byte received
{
// calculate checksum
crc = ~crc;
if (crc == 0xFF) crc = 0xFE;
// if crc matches decode the packet
if (c == crc) dsl_decode_packet();
// handle next packet
cnt = 0;
crc = 0;
}
else // collect channel data bytes
{
PacketBuffer[cnt++] = c;
crc += c;
}
// store last byte for sync check
last_c = c;
}
/branches/V0.72p Code Redesign killagreg/rc.c
169,7 → 169,7
{
// if a sync gap happens and there where at least 4 channels decoded before
// then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
if(index >= 4)
if(index == 4)
{
NewPpmData = 0; // Null means NewData for the first 4 channels
NewRCFrames++;
/branches/V0.72p Code Redesign killagreg/rc.h
21,6 → 21,6
extern volatile int16_t PPM_diff[15]; // the differentiated RC-Signal
extern volatile uint8_t NewPpmData; // 0 indicates a new recieved PPM Frame
extern volatile int16_t RC_Quality; // rc signal quality indicator (0 to 200)
extern volatile uint8_t NewRCFrames;
 
 
#endif //_RC_H