Skip to content

Commit

Permalink
Fixed baud rate and inversion. Added more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
martinbudden committed Nov 17, 2016
1 parent 6b53b20 commit 818a91b
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 55 deletions.
26 changes: 8 additions & 18 deletions src/main/rx/crsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "fc/fc_debug.h"
#endif

#include "build/build_config.h"
#include "build/debug.h"

#include "common/utils.h"
Expand All @@ -54,14 +55,13 @@

#define CRSF_TIME_NEEDED_PER_FRAME_US 1500 //!! this needs checking

#define CRSF_MAX_CHANNEL 16

#define CRSF_DIGITAL_CHANNEL_MIN 172
#define CRSF_DIGITAL_CHANNEL_MAX 1811

static bool crsfFrameDone = false;
STATIC_UNIT_TESTED bool crsfFrameDone = false;
STATIC_UNIT_TESTED crsfFrame_t crsfFrame;

static uint32_t crsfChannelData[CRSF_MAX_CHANNEL];
STATIC_UNIT_TESTED uint32_t crsfChannelData[CRSF_MAX_CHANNEL];

/*
Structure
Expand Down Expand Up @@ -101,19 +101,6 @@ struct crsfPayloadRcChannelsPacked_s {

typedef struct crsfPayloadRcChannelsPacked_s crsfPayloadRcChannelsPacked_t;

typedef union crsfFrameDef_s {
uint8_t deviceAddress;
uint8_t frameLength;
uint8_t type;
uint8_t payload[CRSF_PAYLOAD_SIZE_MAX + 1]; // +1 for CRC at end of payload
} crsfFrameDef_t;

typedef union crsfFrame_u {
uint8_t bytes[CRSF_FRAME_SIZE_MAX];
crsfFrameDef_t frame;
} crsfFrame_t;

static crsfFrame_t crsfFrame;

// Receive ISR callback, called back from serial port
static void crsfDataReceive(uint16_t c)
Expand All @@ -123,7 +110,9 @@ static void crsfDataReceive(uint16_t c)
const uint32_t now = micros();

const int32_t crsfFrameTime = now - crsfFrameStartAt;
DEBUG_SET(DEBUG_CRSF, 2, crsfFrameTime);
#ifdef DEBUG_CRSF_PACKETS
debug[2] = crsfFrameTime;
#endif

if (crsfFrameTime > (long)(CRSF_TIME_NEEDED_PER_FRAME_US + 500)) {
crsfFramePosition = 0;
Expand All @@ -146,6 +135,7 @@ uint8_t crsfFrameStatus(void)
if (crsfFrameDone) {
crsfFrameDone = false;
if (crsfFrame.frame.type == CRSF_FRAMETYPE_RC_CHANNELS_PACKED) {
crsfFrame.frame.frameLength = CRSF_FRAME_RC_CHANNELS_PAYLOAD_SIZE + CRSF_FRAME_LENGTH_TYPE_CRC;
// unpack the RC channels
const crsfPayloadRcChannelsPacked_t* rcChannels = (crsfPayloadRcChannelsPacked_t*)&crsfFrame.frame.payload;
crsfChannelData[0] = rcChannels->chan0;
Expand Down
18 changes: 16 additions & 2 deletions src/main/rx/crsf.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@

#pragma once

#define CRSF_BAUDRATE 400000
#define CRSF_PORT_OPTIONS (SERIAL_INVERTED | SERIAL_STOPBITS_1 | SERIAL_PARITY_NO)
#define CRSF_BAUDRATE 420000
#define CRSF_PORT_OPTIONS (SERIAL_STOPBITS_1 | SERIAL_PARITY_NO)

#define CRSF_MAX_CHANNEL 16

typedef enum {
CRSF_FRAMETYPE_GPS = 0x02,
Expand All @@ -45,6 +47,18 @@ enum {
#define CRSF_PAYLOAD_SIZE_MAX 32 // !!TODO needs checking
#define CRSF_FRAME_SIZE_MAX (CRSF_PAYLOAD_SIZE_MAX + 4)

typedef struct crsfFrameDef_s {
uint8_t deviceAddress;
uint8_t frameLength;
uint8_t type;
uint8_t payload[CRSF_PAYLOAD_SIZE_MAX + 1]; // +1 for CRC at end of payload
} crsfFrameDef_t;

typedef union crsfFrame_u {
uint8_t bytes[CRSF_FRAME_SIZE_MAX];
crsfFrameDef_t frame;
} crsfFrame_t;

uint8_t crsfFrameStatus(void);
struct rxConfig_s;
struct rxRuntimeConfig_s;
Expand Down
54 changes: 23 additions & 31 deletions src/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -490,66 +490,58 @@ $(OBJECT_DIR)/rx_rx_unittest : \

$(CXX) $(CXX_FLAGS) $^ -o $(OBJECT_DIR)/$@

$(OBJECT_DIR)/telemetry/crsf.o : \
$(USER_DIR)/telemetry/crsf.c \
$(USER_DIR)/telemetry/crsf.h \
$(OBJECT_DIR)/rx/crsf.o : \
$(USER_DIR)/rx/crsf.c \
$(USER_DIR)/rx/crsf.h \
$(GTEST_HEADERS)

@mkdir -p $(dir $@)
$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/telemetry/crsf.c -o $@
$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/rx/crsf.c -o $@

$(OBJECT_DIR)/telemetry_crsf_unittest.o : \
$(TEST_DIR)/telemetry_crsf_unittest.cc \
$(USER_DIR)/telemetry/crsf.h \
$(USER_DIR)/telemetry/crsf.c \
$(USER_DIR)/rx/crsf.c \
$(OBJECT_DIR)/rx_crsf_unittest.o : \
$(TEST_DIR)/rx_crsf_unittest.cc \
$(USER_DIR)/rx/crsf.h \
$(USER_DIR)/rx/crsf.c \
$(GTEST_HEADERS)

@mkdir -p $(dir $@)
$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/telemetry_crsf_unittest.cc -o $@
$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/rx_crsf_unittest.cc -o $@

$(OBJECT_DIR)/telemetry_crsf_unittest : \
$(OBJECT_DIR)/telemetry/crsf.o \
$(OBJECT_DIR)/telemetry_crsf_unittest.o \
$(OBJECT_DIR)/rx_crsf_unittest : \
$(OBJECT_DIR)/rx/crsf.o \
$(OBJECT_DIR)/rx_crsf_unittest.o \
$(OBJECT_DIR)/common/maths.o \
$(OBJECT_DIR)/common/streambuf.o \
$(OBJECT_DIR)/flight/gps_conversion.o \
$(OBJECT_DIR)/fc/runtime_config.o \
$(OBJECT_DIR)/gtest_main.a

$(CXX) $(CXX_FLAGS) $^ -o $(OBJECT_DIR)/$@

$(OBJECT_DIR)/rx/crsf.o : \
$(USER_DIR)/rx/crsf.c \
$(USER_DIR)/rx/crsf.h \
$(GTEST_HEADERS)

@mkdir -p $(dir $@)
$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/rx/crsf.c -o $@

$(OBJECT_DIR)/telemetry/crsf.o : \
$(USER_DIR)/telemetry/crsf.c \
$(USER_DIR)/telemetry/crsf.h \
$(USER_DIR)/rx/crsf.h \
$(GTEST_HEADERS)

@mkdir -p $(dir $@)
$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/telemetry/crsf.c -o $@

$(OBJECT_DIR)/rx_crsf_unittest.o : \
$(TEST_DIR)/rx_crsf_unittest.cc \
$(USER_DIR)/rx/crsf.h \
$(OBJECT_DIR)/telemetry_crsf_unittest.o : \
$(TEST_DIR)/telemetry_crsf_unittest.cc \
$(USER_DIR)/telemetry/crsf.h \
$(USER_DIR)/telemetry/crsf.c \
$(USER_DIR)/rx/crsf.c \
$(USER_DIR)/rx/crsf.h \
$(GTEST_HEADERS)

@mkdir -p $(dir $@)
$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/rx_crsf_unittest.cc -o $@
$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/telemetry_crsf_unittest.cc -o $@

$(OBJECT_DIR)/rx_crsf_unittest : \
$(OBJECT_DIR)/rx/crsf.o \
$(OBJECT_DIR)/telemetry_crsf_unittest : \
$(OBJECT_DIR)/telemetry/crsf.o \
$(OBJECT_DIR)/telemetry_crsf_unittest.o \
$(OBJECT_DIR)/common/maths.o \
$(OBJECT_DIR)/rx_crsf_unittest.o \
$(OBJECT_DIR)/common/streambuf.o \
$(OBJECT_DIR)/flight/gps_conversion.o \
$(OBJECT_DIR)/fc/runtime_config.o \
$(OBJECT_DIR)/gtest_main.a

$(CXX) $(CXX_FLAGS) $^ -o $(OBJECT_DIR)/$@
Expand Down
5 changes: 5 additions & 0 deletions src/test/unit/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ uint8_t DMA_GetFlagStatus(void *);
void DMA_Cmd(DMA_Channel_TypeDef*, FunctionalState );
void DMA_ClearFlag(uint32_t);

typedef struct
{
void* test;
} USART_TypeDef;

#define WS2811_DMA_TC_FLAG (void *)1
#define WS2811_DMA_HANDLER_IDENTIFER 0

Expand Down
100 changes: 96 additions & 4 deletions src/test/unit/rx_crsf_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,19 @@
extern "C" {
#include <platform.h>

#include "config/parameter_group.h"
#include "config/parameter_group_ids.h"
#include "build/debug.h"

#include "rx/rx.h"
#include "fc/rc_controls.h"
#include "common/maths.h"
#include "common/utils.h"

#include "io/serial.h"

#include "rx/rx.h"
#include "rx/crsf.h"

extern bool crsfFrameDone;
extern crsfFrame_t crsfFrame;
extern uint32_t crsfChannelData[CRSF_MAX_CHANNEL];
}

#include "unittest_macros.h"
Expand Down Expand Up @@ -95,5 +100,92 @@ TEST(CrossFireTest, CRC)
EXPECT_EQ(crc1, crc2);
}

TEST(CrossFireTest, TestCrsfFrameStatus)
{
crsfFrameDone = true;
crsfFrame.frame.deviceAddress = CRSF_RECEIVER_ADDRESS;
crsfFrame.frame.frameLength = 0;
crsfFrame.frame.type = CRSF_FRAMETYPE_RC_CHANNELS_PACKED;
memset(crsfFrame.frame.payload, 0, CRSF_FRAME_RC_CHANNELS_PAYLOAD_SIZE);

const uint8_t status = crsfFrameStatus();
EXPECT_EQ(RX_FRAME_COMPLETE, status);
EXPECT_EQ(false, crsfFrameDone);

EXPECT_EQ(CRSF_RECEIVER_ADDRESS, crsfFrame.frame.deviceAddress);
EXPECT_EQ(CRSF_FRAME_RC_CHANNELS_PAYLOAD_SIZE + CRSF_FRAME_LENGTH_TYPE_CRC, crsfFrame.frame.frameLength);
EXPECT_EQ(CRSF_FRAMETYPE_RC_CHANNELS_PACKED, crsfFrame.frame.type);
for (int ii = 0; ii < CRSF_MAX_CHANNEL; ++ii) {
EXPECT_EQ(0, crsfChannelData[ii]);
}
}

TEST(CrossFireTest, TestCrsfFrameStatusUnpacking)
{
crsfFrameDone = true;
crsfFrame.frame.deviceAddress = CRSF_RECEIVER_ADDRESS;
crsfFrame.frame.frameLength = 0;
crsfFrame.frame.type = CRSF_FRAMETYPE_RC_CHANNELS_PACKED;
// 16 11-bit channels packed into 22 bytes of data
crsfFrame.frame.payload[0] = 0xFF;
crsfFrame.frame.payload[1] = 0xFF;
// !!TODO add more test data
crsfFrame.frame.payload[2] = 0;
crsfFrame.frame.payload[3] = 0;
crsfFrame.frame.payload[4] = 0;
crsfFrame.frame.payload[5] = 0;
crsfFrame.frame.payload[6] = 0;
crsfFrame.frame.payload[7] = 0;
crsfFrame.frame.payload[8] = 0;
crsfFrame.frame.payload[9] = 0;
crsfFrame.frame.payload[10] = 0;
crsfFrame.frame.payload[11] = 0;
crsfFrame.frame.payload[12] = 0;
crsfFrame.frame.payload[13] = 0;
crsfFrame.frame.payload[14] = 0;
crsfFrame.frame.payload[15] = 0;
crsfFrame.frame.payload[16] = 0;
crsfFrame.frame.payload[17] = 0;
crsfFrame.frame.payload[18] = 0;
crsfFrame.frame.payload[19] = 0;
crsfFrame.frame.payload[20] = 0;
crsfFrame.frame.payload[21] = 0;

const uint8_t status = crsfFrameStatus();
EXPECT_EQ(RX_FRAME_COMPLETE, status);
EXPECT_EQ(false, crsfFrameDone);

EXPECT_EQ(CRSF_RECEIVER_ADDRESS, crsfFrame.frame.deviceAddress);
EXPECT_EQ(CRSF_FRAME_RC_CHANNELS_PAYLOAD_SIZE + CRSF_FRAME_LENGTH_TYPE_CRC, crsfFrame.frame.frameLength);
EXPECT_EQ(CRSF_FRAMETYPE_RC_CHANNELS_PACKED, crsfFrame.frame.type);
EXPECT_EQ(0x7ff, crsfChannelData[0]);
EXPECT_EQ(0x1f, crsfChannelData[1]);
EXPECT_EQ(0, crsfChannelData[2]);
EXPECT_EQ(0, crsfChannelData[3]);
EXPECT_EQ(0, crsfChannelData[4]);
EXPECT_EQ(0, crsfChannelData[5]);
EXPECT_EQ(0, crsfChannelData[6]);
EXPECT_EQ(0, crsfChannelData[7]);
EXPECT_EQ(0, crsfChannelData[8]);
EXPECT_EQ(0, crsfChannelData[9]);
EXPECT_EQ(0, crsfChannelData[10]);
EXPECT_EQ(0, crsfChannelData[11]);
EXPECT_EQ(0, crsfChannelData[12]);
EXPECT_EQ(0, crsfChannelData[13]);
EXPECT_EQ(0, crsfChannelData[14]);
EXPECT_EQ(0, crsfChannelData[15]);
}
// STUBS

extern "C" {

int16_t debug[DEBUG16_VALUE_COUNT];
uint32_t micros(void) {return 0;}
serialPort_t *openSerialPort(serialPortIdentifier_e, serialPortFunction_e, serialReceiveCallbackPtr, uint32_t, portMode_t, portOptions_t)
{
return NULL;
}
serialPortConfig_t *findSerialPortConfig(serialPortFunction_e ) {return NULL;}
bool telemetryCheckRxPortShared(const serialPortConfig_t *) {return false;}
serialPort_t *telemetrySharedPort = NULL;
}
1 change: 1 addition & 0 deletions src/test/unit/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define BARO
#define GPS
#define DISPLAY
#define SERIAL_RX
#define TELEMETRY
#define LED_STRIP
#define USE_SERVOS
Expand Down

0 comments on commit 818a91b

Please sign in to comment.