Merge pull request #51 from DzikuVx/feature/crc-with-salt
Feature/crc with salt
This commit is contained in:
2
.vscode/arduino.json
vendored
2
.vscode/arduino.json
vendored
@@ -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"
|
||||||
}
|
}
|
||||||
25
README.md
25
README.md
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
Reference in New Issue
Block a user