Merge pull request #51 from DzikuVx/feature/crc-with-salt

Feature/crc with salt
This commit is contained in:
Paweł Spychalski
2018-04-27 22:11:46 +02:00
committed by GitHub
6 changed files with 55 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
{ {
"board": "bsfrance:avr:lora32u4", "board": "bsfrance:avr:lora32u4",
"sketch": "crossbow/crossbow.ino", "sketch": "crossbow/crossbow.ino",
"port": "COM7", "port": "COM5",
"output": "../build" "output": "../build"
} }

View File

@@ -4,16 +4,31 @@ _QuadMeUp Crossbow_ is a DIY project that gives 5km (at least) of RC link for UA
# Current state # Current state
Development, ready for testing Works:
* Getting data from OpenTX radio using SBUS protocol
* Transmitting 10 channels to RX modules
* Frequency hopping
* Getting basic telemetry from RX module
* Sending 10 channels using SBUS to flight controller
Needs implementation:
* Binding
* TX module configuration
* Allowing to use OLED on TX to get basic data
* RX configuration from TX module
* Sending telemetry from TX to OpenTX radio
# Protocol # Protocol
| Byte | Description | Notes | | Byte | Description | Notes |
| ---- | ---- | ---- | | ---- | ---- | ---- |
| 1 | Channel ID | channel used for comunication between TX and RX | | 1 | Frame type & used radio channel | bits 7-5 defines frame, bits 4-0 current radio channel |
| 2 | Frame type & Length | bits 7-5 defines frame, bits 4-0 current radio channel | | 2 - 33 | Payload | lenghth defined by frame type |
| 3 - 34 | Payload | lenghth defined by frame type | | payload length + 2 | CRC | using crc8_dvb_s2 method |
| payload length + 3 | CRC | using crc8_dvb_s2 method |
## CRC
CRC is computed using `crc8_dvb_s2` method. Initial CRC value for each frame CRC is equal to CRC of 4 bind bytes (unique for transmitter module).
## Frame types ## Frame types

View File

@@ -5,16 +5,18 @@
* Hardware type. Available types: * Hardware type. Available types:
* ARDUINO_AVR_FEATHER32U4 * ARDUINO_AVR_FEATHER32U4
* ARDUINO_SAMD_FEATHER_M0 * ARDUINO_SAMD_FEATHER_M0
*
* Leave commented for autodetect
*/ */
#define ARDUINO_AVR_FEATHER32U4 // #define ARDUINO_AVR_FEATHER32U4
/* /*
* TX or RX mode for hardware. Available types: * TX or RX mode for hardware. Available types:
* DEVICE_MODE_TX * DEVICE_MODE_TX
* DEVICE_MODE_RX * DEVICE_MODE_RX
*/ */
// #define DEVICE_MODE_TX #define DEVICE_MODE_TX
#define DEVICE_MODE_RX // #define DEVICE_MODE_RX
// #define FEATURE_TX_OLED // #define FEATURE_TX_OLED
// #define FORCE_TX_WITHOUT_INPUT // #define FORCE_TX_WITHOUT_INPUT

View File

@@ -274,6 +274,14 @@ void setup(void)
qsp.debugConfig |= DEBUG_FLAG_LED; qsp.debugConfig |= DEBUG_FLAG_LED;
#endif #endif
/*
* Setup salt bind key
*/
qsp.bindKey[0] = 0x12;
qsp.bindKey[1] = 0x0a;
qsp.bindKey[2] = 0x36;
qsp.bindKey[3] = 0xa7;
} }
uint8_t currentSequenceIndex = 0; uint8_t currentSequenceIndex = 0;

View File

@@ -151,6 +151,16 @@ void qspClearPayload(QspConfiguration_t *qsp)
qsp->payloadLength = 0; qsp->payloadLength = 0;
} }
/**
* Init CRC with salt based on 4 byte bind key
*/
void qspInitCrc(QspConfiguration_t *qsp) {
qsp->crc = 0;
for (uint8_t i = 0; i < 4; i++) {
qspComputeCrc(qsp, qsp->bindKey[i]);
}
}
void qspDecodeIncomingFrame( void qspDecodeIncomingFrame(
QspConfiguration_t *qsp, QspConfiguration_t *qsp,
uint8_t incomingByte, uint8_t incomingByte,
@@ -165,24 +175,11 @@ void qspDecodeIncomingFrame(
if (qsp->protocolState == QSP_STATE_IDLE) if (qsp->protocolState == QSP_STATE_IDLE)
{ {
// Check if incomming channel ID is the same as receiver qspInitCrc(qsp);
if (incomingByte == CHANNEL_ID)
{
qsp->frameDecodingStartedAt = millis();
qsp->protocolState = QSP_STATE_CHANNEL_RECEIVED;
qsp->crc = 0;
qspComputeCrc(qsp, incomingByte);
qspClearPayload(qsp); qspClearPayload(qsp);
receivedPayload = 0; receivedPayload = 0;
} qsp->frameDecodingStartedAt = millis();
else
{
qsp->protocolState = QSP_STATE_IDLE;
}
}
else if (qsp->protocolState == QSP_STATE_CHANNEL_RECEIVED)
{
//Frame ID and payload length //Frame ID and payload length
qspComputeCrc(qsp, incomingByte); qspComputeCrc(qsp, incomingByte);
@@ -228,11 +225,8 @@ void qspDecodeIncomingFrame(
* Encode frame is corrent format and write to hardware * Encode frame is corrent format and write to hardware
*/ */
void qspEncodeFrame(QspConfiguration_t *qsp, volatile RadioState_t *radioState, uint8_t buffer[], uint8_t *size) { void qspEncodeFrame(QspConfiguration_t *qsp, volatile RadioState_t *radioState, uint8_t buffer[], uint8_t *size) {
//Zero CRC //Salt CRC with bind key
qsp->crc = 0; qspInitCrc(qsp);
qspComputeCrc(qsp, CHANNEL_ID);
buffer[0] = CHANNEL_ID;
//Write frame type and length //Write frame type and length
// We are no longer sending payload length, so 4 bits are now free for other usages // We are no longer sending payload length, so 4 bits are now free for other usages
@@ -240,16 +234,16 @@ void qspEncodeFrame(QspConfiguration_t *qsp, volatile RadioState_t *radioState,
uint8_t data = radioState->channel; uint8_t data = radioState->channel;
data |= (qsp->frameToSend << 4) & 0xf0; data |= (qsp->frameToSend << 4) & 0xf0;
qspComputeCrc(qsp, data); qspComputeCrc(qsp, data);
buffer[1] = data; buffer[0] = data;
for (uint8_t i = 0; i < qsp->payloadLength; i++) for (uint8_t i = 0; i < qsp->payloadLength; i++)
{ {
qspComputeCrc(qsp, qsp->payload[i]); qspComputeCrc(qsp, qsp->payload[i]);
buffer[i + 2] = qsp->payload[i]; buffer[i + 1] = qsp->payload[i];
} }
buffer[qsp->payloadLength + 2] = qsp->crc; buffer[qsp->payloadLength + 1] = qsp->crc;
*size = qsp->payloadLength + 3; //Total length of QSP frame *size = qsp->payloadLength + 2; //Total length of QSP frame
} }
void encodePingPayload(QspConfiguration_t *qsp, uint32_t currentMicros) { void encodePingPayload(QspConfiguration_t *qsp, uint32_t currentMicros) {

View File

@@ -48,7 +48,6 @@ static const uint8_t qspFrameLengths[QSP_FRAME_COUNT] = {
enum dataStates { enum dataStates {
QSP_STATE_IDLE, QSP_STATE_IDLE,
QSP_STATE_CHANNEL_RECEIVED,
QSP_STATE_FRAME_TYPE_RECEIVED, QSP_STATE_FRAME_TYPE_RECEIVED,
QSP_STATE_PAYLOAD_RECEIVED, QSP_STATE_PAYLOAD_RECEIVED,
QSP_STATE_CRC_RECEIVED QSP_STATE_CRC_RECEIVED
@@ -130,6 +129,7 @@ struct RxDeviceState_t {
}; };
struct QspConfiguration_t { struct QspConfiguration_t {
uint8_t bindKey[4] = {0, 0, 0, 0};
uint8_t protocolState = QSP_STATE_IDLE; uint8_t protocolState = QSP_STATE_IDLE;
uint8_t crc = 0; uint8_t crc = 0;
uint8_t payload[QSP_PAYLOAD_LENGTH] = {0}; uint8_t payload[QSP_PAYLOAD_LENGTH] = {0};