Merge remote-tracking branch 'origin/eeprom' into eeprom
# Conflicts: # UAV-ControlSystem/src/config/cli.c # UAV-ControlSystem/src/tasks_main.c
This commit is contained in:
commit
c8599dcf61
131
UAV-ControlSystem/inc/drivers/sbus.h
Normal file
131
UAV-ControlSystem/inc/drivers/sbus.h
Normal file
@ -0,0 +1,131 @@
|
||||
/**********************************************************************
|
||||
* NAME: sbus.h *
|
||||
* AUTHOR: Philip Johansson *
|
||||
* PURPOSE: Read SBUS messages from RX *
|
||||
* INFORMATION: *
|
||||
* The SBUS protocol writes most significant bit first. So 1 in binary *
|
||||
* which is 0000001 will be sent as 10000000. *
|
||||
* Parity: even *
|
||||
* Stops: 2 *
|
||||
* Start byte: 0x0F (follows 0x00) *
|
||||
* Stop byte: 0x00 *
|
||||
* Packet size: 25 bytes *
|
||||
* *
|
||||
* GLOBAL VARIABLES: *
|
||||
* Variable Type Description *
|
||||
* -------- ---- ----------- *
|
||||
* *
|
||||
**********************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef DRIVERS_SBUS_H_
|
||||
#define DRIVERS_SBUS_H_
|
||||
|
||||
#define SBUS_BAUDRATE 100000
|
||||
#define SBUS_FRAME_SIZE 25
|
||||
#define SBUS_HEADER 0x0F
|
||||
#define SBUS_FOOTER 0x00
|
||||
#define USART1_SBUS_DMA_SIZE SBUS_FRAME_SIZE + 1 // sbus package is 176 bits (22 bytes)
|
||||
|
||||
#define SBUS_MAX_CHANNEL 18 // Including two digital
|
||||
#define STICK_CHANNEL_COUNT 4
|
||||
#define MAX_AUX_CHANNEL_COUNT (SBUS_MAX_CHANNEL - STICK_CHANNEL_COUNT)
|
||||
|
||||
|
||||
|
||||
#define PWM_RANGE_MIN 1000
|
||||
#define PWM_RANGE_MAX 2000
|
||||
#define PWM_RANGE_MIDDLE (PWM_RANGE_MIN + ((PWM_RANGE_MAX - PWM_RANGE_MIN) / 2)) // Should be 1500 default
|
||||
|
||||
#define PWM_PULSE_MIN 750 // minimum PWM pulse considered valid input
|
||||
#define PWM_PULSE_MAX 2250 // maximum PWM pulse considered valid input
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Failsafe scenarios of the RX *
|
||||
* INFORMATION: TODO: Implement use of these *
|
||||
***********************************************************************/
|
||||
typedef enum {
|
||||
RX_FAILSAFE_MODE_AUTO = 0,
|
||||
RX_FAILSAFE_MODE_HOLD,
|
||||
RX_FAILSAFE_MODE_SET,
|
||||
RX_FAILSAFE_MODE_INVALID,
|
||||
} rxFailsafeChannelMode_e;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: RX packet structure *
|
||||
* INFORMATION: Contains a whole SBUS message besides the footer *
|
||||
***********************************************************************/
|
||||
typedef struct sbusFrame_s {
|
||||
/* Whole package is 25 bytes */
|
||||
|
||||
/* SBUS Header is 0x0F (Byte 0) */
|
||||
uint8_t syncByte;
|
||||
|
||||
/* 176 bits of data for channels (11 bits per channel * 16 channels) = 22 bytes (1-22) */
|
||||
|
||||
/* Channel 1..4 are "sticks" */
|
||||
unsigned int chan1 : 11; // Elevator
|
||||
unsigned int chan2 : 11; // Aileron
|
||||
unsigned int chan3 : 11; // Throttle
|
||||
unsigned int chan4 : 11; // Rudder
|
||||
|
||||
/* Channel 5.. are AUX channels */
|
||||
unsigned int chan5 : 11;
|
||||
unsigned int chan6 : 11;
|
||||
unsigned int chan7 : 11;
|
||||
unsigned int chan8 : 11; // ARM switch
|
||||
|
||||
/* Depending on define 4 or more channels are used */
|
||||
unsigned int chan9 : 11;
|
||||
unsigned int chan10 : 11;
|
||||
unsigned int chan11 : 11;
|
||||
unsigned int chan12 : 11;
|
||||
unsigned int chan13 : 11;
|
||||
unsigned int chan14 : 11;
|
||||
unsigned int chan15 : 11;
|
||||
unsigned int chan16 : 11;
|
||||
|
||||
/* Byte 23 contains all flags
|
||||
* Bit 7: digital channel 17 (0x80)
|
||||
* Bit 6: digital channel 18 (0x40)
|
||||
* Bit 5: frame lost (0x20)
|
||||
* Bit 4: failsafe activated (0x10)
|
||||
* Bit 0-3: n/a
|
||||
*/
|
||||
unsigned int flag_DChannel_17 : 1;
|
||||
unsigned int flag_DChannel_18 : 1;
|
||||
unsigned int flag_FrameLost : 1;
|
||||
unsigned int flag_Failsafe : 1;
|
||||
unsigned int flag_NA : 4;
|
||||
|
||||
/* Byte 24 - The EndByte is 0x00 for FrSky
|
||||
* Not included in this struct
|
||||
*/
|
||||
|
||||
} __attribute__ ((__packed__)) sbusFrame_s;
|
||||
|
||||
/* This instance is read by the whole system and should contain actual RX data */
|
||||
extern sbusFrame_s sbusChannelData;
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Initializes the UART for sbus *
|
||||
* INFORMATION: A DMA Buffer starts storing the bytes received from RX *
|
||||
* Sbus Inverter is activated *
|
||||
***********************************************************************/
|
||||
void sbus_init();
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Checks if new RX packet is available *
|
||||
* INFORMATION: Is called by the scheduler *
|
||||
***********************************************************************/
|
||||
bool sbus_frame_available();
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Updates "sbusChannelData" *
|
||||
* INFORMATION: Is called by the scheduler *
|
||||
***********************************************************************/
|
||||
void sbus_read();
|
||||
|
||||
#endif /* DRIVERS_SBUS_H_ */
|
@ -23,6 +23,12 @@
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
typedef struct dma_usart_return {
|
||||
uint8_t* buff;
|
||||
bool new_data;
|
||||
} dma_usart_return;
|
||||
|
||||
|
||||
// Enumeration for USART stop bits
|
||||
typedef enum stop_bits
|
||||
{
|
||||
@ -33,7 +39,7 @@ typedef enum stop_bits
|
||||
} stop_bits;
|
||||
|
||||
// Enuymeration for USART parity
|
||||
typedef enum partiy
|
||||
typedef enum parity
|
||||
{
|
||||
PARITY_NONE = 0x0,
|
||||
PARITY_EVEN = 0x2,
|
||||
@ -82,6 +88,7 @@ bool usart_init_dma(USART_TypeDef* usart_inst,
|
||||
* Initialize the specified USART in order to get polling and regular
|
||||
* transmit of messages to work. If the initialization fails this function
|
||||
* returns false and otherwise it returns true
|
||||
* * For USART1 Inverter is ON on RX by default
|
||||
***********************************************************************/
|
||||
bool usart_init(USART_TypeDef* usart_inst,
|
||||
usart_profile* profile_out,
|
||||
@ -128,7 +135,7 @@ uint32_t usart_poll(usart_profile *profile,
|
||||
* completed so that the DMA can continue writing to the second buffer
|
||||
* without interfering with the rest of the system
|
||||
***********************************************************************/
|
||||
uint8_t* usart_get_dma_buffer(usart_dma_profile *profile);
|
||||
dma_usart_return usart_get_dma_buffer(usart_dma_profile *profile);
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: NOT IMPLEMENTED YET
|
||||
|
@ -102,8 +102,8 @@
|
||||
|
||||
/* Led Warnings */
|
||||
#define USE_LEDS
|
||||
#define USE_LED_WARNINGS
|
||||
#define USE_LED_WARNINGS_MISSED_PERIOD
|
||||
//#define USE_LED_WARNINGS
|
||||
//#define USE_LED_WARNINGS_MISSED_PERIOD
|
||||
//#define USE_LED_WARNINGS_SYSTEM_LOAD
|
||||
|
||||
/* Scheduler */
|
||||
|
@ -81,4 +81,6 @@ uint32_t accumulate(uint32_t list[], int length);
|
||||
***********************************************************************/
|
||||
void Error_Handler(void);
|
||||
|
||||
uint8_t reverse(uint8_t byte);
|
||||
|
||||
#endif /* UTILITIES_H_ */
|
||||
|
169
UAV-ControlSystem/src/drivers/sbus.c
Normal file
169
UAV-ControlSystem/src/drivers/sbus.c
Normal file
@ -0,0 +1,169 @@
|
||||
/**********************************************************************
|
||||
* NAME: sbus.c *
|
||||
* AUTHOR: Philip Johansson *
|
||||
* PURPOSE: Read SBUS messages from RX *
|
||||
* INFORMATION: *
|
||||
* The SBUS protocol writes most significant bit first. So 1 in binary *
|
||||
* which is 0000001 will be sent as 10000000. *
|
||||
* Parity: even *
|
||||
* Stops: 2 *
|
||||
* Start byte: 0x0F (follows 0x00) *
|
||||
* Stop byte: 0x00 *
|
||||
* Packet size: 25 bytes *
|
||||
* *
|
||||
* GLOBAL VARIABLES: *
|
||||
* Variable Type Description *
|
||||
* -------- ---- ----------- *
|
||||
* *
|
||||
**********************************************************************/
|
||||
#include "drivers/sbus.h"
|
||||
#include "drivers/usart.h"
|
||||
#include "utilities.h"
|
||||
#include "string.h"
|
||||
#include "drivers/uart1_inverter.h"
|
||||
#include "stm32f4xx_revo.h"
|
||||
|
||||
// Linear fitting
|
||||
#define SBUS_UNIT_CONV(channel) ((channel * 0.626) + 880)
|
||||
|
||||
/* This instance is read by the whole system and should contain actual RX data */
|
||||
sbusFrame_s sbusChannelData = {0};
|
||||
dma_usart_return raw_dma_data_t = {0};
|
||||
|
||||
/* Create a DMA Handler */
|
||||
usart_dma_profile dmaHandler;
|
||||
|
||||
/* TODO: This can be used to keep count of amount of errors before we trigger a failsafe */
|
||||
typedef struct rxFailsafeChannelConfiguration_s {
|
||||
uint8_t mode;
|
||||
uint8_t step;
|
||||
} rxFailsafeChannelConfiguration_t;
|
||||
|
||||
/* TODO: Move to EEPROM or remove or redo differently
|
||||
* The thought is to use these values for things as failsafe, RC stick center etc */
|
||||
typedef struct rxConfig_s {
|
||||
uint8_t rcmap[SBUS_MAX_CHANNEL];
|
||||
uint8_t sbus_inversion;
|
||||
uint8_t midrc;
|
||||
uint8_t deadband;
|
||||
uint8_t mincheck;
|
||||
uint8_t maxcheck;
|
||||
uint8_t rcInterpolation;
|
||||
uint8_t rcInterpolationInterval;
|
||||
uint8_t max_aux_channel;
|
||||
uint16_t airModeActivateThreshold;
|
||||
|
||||
rxFailsafeChannelConfiguration_t failsafe_channel_configurations[SBUS_MAX_CHANNEL];
|
||||
//rxChannelRangeConfiguration_t channelRanges[NON_AUX_CHANNEL_COUNT];
|
||||
} rxConfig_t;
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Initializes the UART for sbus *
|
||||
* INFORMATION: A DMA Buffer starts storing the bytes received from RX *
|
||||
* Sbus Inverter is activated *
|
||||
***********************************************************************/
|
||||
void sbus_init()
|
||||
{
|
||||
usart_init_dma(USART1, &dmaHandler, SBUS_BAUDRATE, STOP_BITS_2, PARITY_EVEN, USART1_SBUS_DMA_SIZE, 0);
|
||||
uart1_rx_inverter_set(true);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Checks if new RX packet is available *
|
||||
* INFORMATION: Is called by the scheduler *
|
||||
***********************************************************************/
|
||||
bool sbus_frame_available()
|
||||
{
|
||||
/* We read data from DMA */
|
||||
raw_dma_data_t = usart_get_dma_buffer(&dmaHandler);
|
||||
|
||||
return raw_dma_data_t.new_data;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Truncates RX data between [1000;2000] *
|
||||
* INFORMATION: Range set by defines *
|
||||
***********************************************************************/
|
||||
uint16_t rx_truncate(uint16_t rx_channel)
|
||||
{
|
||||
if (rx_channel < PWM_RANGE_MIN)
|
||||
return PWM_RANGE_MIN;
|
||||
else if (rx_channel > PWM_RANGE_MAX)
|
||||
return PWM_RANGE_MAX;
|
||||
else
|
||||
return rx_channel;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Updates "sbusChannelData" *
|
||||
* INFORMATION: Is called by the scheduler *
|
||||
***********************************************************************/
|
||||
void sbus_read()
|
||||
{
|
||||
// Holds what we've read so far
|
||||
static uint8_t sbus_arr[SBUS_FRAME_SIZE];
|
||||
|
||||
static int sbus_arr_iterator = SBUS_FRAME_SIZE;
|
||||
static bool stop_bit_read = false;
|
||||
|
||||
// If continue only if we get new data from DMA
|
||||
if (raw_dma_data_t.new_data)
|
||||
{
|
||||
for (int i = 0; i < USART1_SBUS_DMA_SIZE; i++)
|
||||
{
|
||||
// Look for the beginning of a sbus frame
|
||||
if (raw_dma_data_t.buff[i] == (uint8_t)SBUS_HEADER && stop_bit_read)
|
||||
{
|
||||
sbus_arr_iterator = 0;
|
||||
stop_bit_read = false;
|
||||
}
|
||||
// Look for the end of sbus frame
|
||||
else if(raw_dma_data_t.buff[i] == (uint8_t)SBUS_FOOTER)
|
||||
{
|
||||
stop_bit_read = true;
|
||||
// If the expected byte is stop byte, then we overwrite to the return value.
|
||||
if (sbus_arr_iterator == SBUS_FRAME_SIZE - 1)
|
||||
{
|
||||
sbusChannelData = *(sbusFrame_s*)sbus_arr;
|
||||
|
||||
// Linear fitting
|
||||
|
||||
sbusChannelData.chan1 = SBUS_UNIT_CONV(sbusChannelData.chan1);
|
||||
sbusChannelData.chan2 = SBUS_UNIT_CONV(sbusChannelData.chan2);
|
||||
sbusChannelData.chan3 = SBUS_UNIT_CONV(sbusChannelData.chan3);
|
||||
sbusChannelData.chan4 = SBUS_UNIT_CONV(sbusChannelData.chan4);
|
||||
sbusChannelData.chan5 = SBUS_UNIT_CONV(sbusChannelData.chan5);
|
||||
sbusChannelData.chan6 = SBUS_UNIT_CONV(sbusChannelData.chan6);
|
||||
sbusChannelData.chan7 = SBUS_UNIT_CONV(sbusChannelData.chan7);
|
||||
sbusChannelData.chan8 = SBUS_UNIT_CONV(sbusChannelData.chan8);
|
||||
|
||||
// TODO: Depending on defines don't process more than necessary
|
||||
sbusChannelData.chan9 = SBUS_UNIT_CONV(sbusChannelData.chan9);
|
||||
sbusChannelData.chan10 = SBUS_UNIT_CONV(sbusChannelData.chan10);
|
||||
sbusChannelData.chan11 = SBUS_UNIT_CONV(sbusChannelData.chan11);
|
||||
sbusChannelData.chan12 = SBUS_UNIT_CONV(sbusChannelData.chan12);
|
||||
sbusChannelData.chan13 = SBUS_UNIT_CONV(sbusChannelData.chan13);
|
||||
sbusChannelData.chan14 = SBUS_UNIT_CONV(sbusChannelData.chan14);
|
||||
sbusChannelData.chan15 = SBUS_UNIT_CONV(sbusChannelData.chan15);
|
||||
sbusChannelData.chan16 = SBUS_UNIT_CONV(sbusChannelData.chan16);
|
||||
|
||||
// TODO: Failsafe using defines checking if channels are in range BEFORE we truncate
|
||||
|
||||
|
||||
sbusChannelData.chan1 = rx_truncate(sbusChannelData.chan1);
|
||||
sbusChannelData.chan2 = rx_truncate(sbusChannelData.chan2);
|
||||
sbusChannelData.chan3 = rx_truncate(sbusChannelData.chan3);
|
||||
sbusChannelData.chan4 = rx_truncate(sbusChannelData.chan4);
|
||||
sbusChannelData.chan5 = rx_truncate(sbusChannelData.chan5);
|
||||
sbusChannelData.chan6 = rx_truncate(sbusChannelData.chan6);
|
||||
sbusChannelData.chan7 = rx_truncate(sbusChannelData.chan7);
|
||||
sbusChannelData.chan8 = rx_truncate(sbusChannelData.chan8);
|
||||
}
|
||||
}
|
||||
// Copy next byte into the sbus_arr
|
||||
if (sbus_arr_iterator < SBUS_FRAME_SIZE)
|
||||
sbus_arr[sbus_arr_iterator] = raw_dma_data_t.buff[i];
|
||||
sbus_arr_iterator++;
|
||||
}
|
||||
}
|
||||
}
|
@ -43,6 +43,8 @@
|
||||
//BRR
|
||||
#define USART_BRR(_PCLK_, _BAUD_) ((_PCLK_ /(_BAUD_ * 16)) * 16) // Calculate BRR from the desired baud rate
|
||||
|
||||
/* Stores last DMA buffer address from "usart_get_dma_buffer". Is used to compare if data read is new or old */
|
||||
uint8_t * prevBuf = NULL;
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Initialize the USART with DMA reception of messages
|
||||
@ -51,6 +53,7 @@
|
||||
* messages can be received without utilizing any processor load. This
|
||||
* function returns false if any error occurred during the initialization
|
||||
* and true of everything went well
|
||||
* For USART1 Inverter is ON on RX by default
|
||||
***********************************************************************/
|
||||
bool usart_init_dma(USART_TypeDef* usart_inst, // The USART instance to be used, i.e. USART1, USART3 or USART6 for the REVO card
|
||||
usart_dma_profile* profile_out, // The USART profile that will be used when sending or receiving data
|
||||
@ -71,6 +74,7 @@ bool usart_init_dma(USART_TypeDef* usart_inst, // The USART instance to be
|
||||
dma_rx_instance = DMA2_Stream2;
|
||||
dma_tx_instance = DMA2_Stream5;
|
||||
channel = DMA_CHANNEL_4;
|
||||
uart1_rx_inverter_init(true);
|
||||
}
|
||||
else if(usart_inst == USART3)
|
||||
{
|
||||
@ -378,22 +382,31 @@ uint32_t usart_poll(usart_profile *profile, // The USART profile to receive data
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* BRIEF: Get the DMA buffer that was most recently completed
|
||||
* INFORMATION:
|
||||
* This function will return the buffer that the DMA most recently
|
||||
* completed so that the DMA can continue writing to the second buffer
|
||||
* without interfering with the rest of the system
|
||||
* A boolean "new_data" tells if the data is new or not as last data is
|
||||
* read if no new one is available
|
||||
***********************************************************************/
|
||||
uint8_t* usart_get_dma_buffer(usart_dma_profile *profile)
|
||||
dma_usart_return usart_get_dma_buffer(usart_dma_profile *profile)
|
||||
{
|
||||
dma_usart_return data = { .buff = NULL , .new_data = false }; // init here first!!!!! continue later
|
||||
// Check which buffer the DMA is writing to at the moment and return the other buffer
|
||||
if(profile->dma_usart_rx_instance->CR & DMA_SxCR_CT)
|
||||
{
|
||||
return profile->dma_rx_buffer1;
|
||||
data.buff = profile->dma_rx_buffer1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return profile->dma_rx_buffer2;
|
||||
data.buff = profile->dma_rx_buffer2;
|
||||
}
|
||||
data.new_data = (data.buff != prevBuf);
|
||||
prevBuf = data.buff;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -97,21 +97,6 @@ int main(void)
|
||||
initScheduler();
|
||||
|
||||
|
||||
// while (1)
|
||||
// {
|
||||
// cliInit(USART1);
|
||||
// if (cliHasMessage() == true)
|
||||
// {
|
||||
// if (cliShouldRun() == true)
|
||||
// cliRun();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
while (1)
|
||||
{
|
||||
//Run the scheduler, responsible for distributing all the work of the running system
|
||||
|
@ -35,9 +35,7 @@
|
||||
#include "drivers/system_clock.h"
|
||||
#include "config/eeprom.h"
|
||||
#include "config/cli.h"
|
||||
|
||||
|
||||
|
||||
#include "drivers/sbus.h"
|
||||
|
||||
|
||||
|
||||
@ -61,8 +59,8 @@ void systemTaskAttitude(void)
|
||||
void systemTaskRx(void)
|
||||
{
|
||||
//Interpret commands to the vehicle
|
||||
|
||||
|
||||
sbus_read();
|
||||
sbusFrame_s frame = sbusChannelData;
|
||||
}
|
||||
|
||||
bool systemTaskRxCheck(uint32_t currentDeltaTime)
|
||||
@ -70,8 +68,7 @@ bool systemTaskRxCheck(uint32_t currentDeltaTime)
|
||||
//This task is what is controlling the event activation of the systemTaskRx
|
||||
//check if there is anything that has be received.
|
||||
|
||||
|
||||
return false;
|
||||
return sbus_frame_available();
|
||||
}
|
||||
|
||||
void systemTaskRxCli(void)
|
||||
|
@ -1,5 +1,3 @@
|
||||
/*
|
||||
* utilities.c
|
||||
/**********************************************************************
|
||||
* NAME: utilities.c *
|
||||
* AUTHOR: Philip Johansson *
|
||||
@ -207,3 +205,16 @@ void Error_Handler(void)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t reverse(uint8_t byte)
|
||||
{
|
||||
// uint8_t ret = 0;
|
||||
// ret = (byte & 0x80) >> 7 | (byte & 0x01) << 7;
|
||||
// ret = (byte & 0x40) >> 6 | (byte & 0x02) << 6;
|
||||
// ret = (byte & 0x20) >> 5 | (byte & 0x04) << 5;
|
||||
// ret = (byte & 0x10) >> 4 | (byte & 0x08) << 4;
|
||||
|
||||
byte = ((byte * 0x0802LU & 0x22110LU) | (byte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
Reference in New Issue
Block a user