1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-15 12:25:20 +03:00

Merge pull request #49 from hydra/softserial-baud-rates

Softserial support for baud rates from 600 to 19200
This commit is contained in:
dongie 2014-04-03 21:03:17 +09:00
commit bd809bca1b
4 changed files with 32 additions and 11 deletions

View file

@ -126,7 +126,7 @@ const clivalue_t valueTable[] = {
{ "flaps_speed", VAR_UINT8, &mcfg.flaps_speed, 0, 100 },
{ "fixedwing_althold_dir", VAR_INT8, &mcfg.fixedwing_althold_dir, -1, 1 },
{ "serial_baudrate", VAR_UINT32, &mcfg.serial_baudrate, 1200, 115200 },
{ "softserial_baudrate", VAR_UINT32, &mcfg.softserial_baudrate, 9600, 19200 },
{ "softserial_baudrate", VAR_UINT32, &mcfg.softserial_baudrate, 600, 19200 },
{ "softserial_inverted", VAR_UINT8, &mcfg.softserial_inverted, 0, 1 },
{ "gps_type", VAR_UINT8, &mcfg.gps_type, 0, 3 },
{ "gps_baudrate", VAR_INT8, &mcfg.gps_baudrate, -1, 4 },

View file

@ -1,8 +1,5 @@
#include "board.h"
// There needs to be a table of timerMhz per baud rate so the system can set the timer correctly.
// See http://www.wormfood.net/avrbaudcalc.php?postbitrate=19200&postclock=72
// Currently defaulting to 3Mhz to support 19200.
#define SOFT_SERIAL_TIMER_MHZ 3
#define SOFT_SERIAL_1_TIMER_RX_HARDWARE 4
#define SOFT_SERIAL_1_TIMER_TX_HARDWARE 5
@ -74,10 +71,29 @@ void serialInputPortConfig(const timerHardware_t *timerHardwarePtr)
#define TICKS_PER_BIT 3
bool isTimerPeriodTooLarge(uint32_t timerPeriod)
{
return timerPeriod > 0xFFFF;
}
void serialTimerConfig(const timerHardware_t *timerHardwarePtr, uint32_t baud, uint8_t reference, timerCCCallbackPtr callback)
{
uint16_t timerPeriod = (SOFT_SERIAL_TIMER_MHZ * 1000000) / (baud * TICKS_PER_BIT);
timerInConfig(timerHardwarePtr, timerPeriod, SOFT_SERIAL_TIMER_MHZ);
uint32_t clock = SystemCoreClock;
uint32_t timerPeriod;
do {
timerPeriod = clock / (baud * TICKS_PER_BIT);
if (isTimerPeriodTooLarge(timerPeriod)) {
if (clock > 1) {
clock = clock / 2;
} else {
// TODO unable to continue, unable to determine clock and timerPeriods for the given baud
}
}
} while (isTimerPeriodTooLarge(timerPeriod));
uint8_t mhz = SystemCoreClock / 1000000;
timerInConfig(timerHardwarePtr, timerPeriod, mhz);
configureTimerCaptureCompareInterrupt(timerHardwarePtr, reference, callback);
}

View file

@ -145,19 +145,24 @@ void timerNVICConfig(uint8_t irq)
NVIC_Init(&NVIC_InitStructure);
}
void configTimeBase(TIM_TypeDef *tim, uint32_t period, uint8_t mhz)
void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint8_t mhz)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = period - 1;
TIM_TimeBaseStructure.TIM_Period = period - 1; // AKA TIMx_ARR
// "The counter clock frequency (CK_CNT) is equal to f CK_PSC / (PSC[15:0] + 1)." - STM32F10x Reference Manual 14.4.11
// Thus for 1Mhz: 72000000 / 1000000 = 72, 72 - 1 = 71 = TIM_Prescaler
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / ((uint32_t)mhz * 1000000)) - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);
}
void timerInConfig(const timerHardware_t *timerHardwarePtr, uint32_t period, uint8_t mhz)
void timerInConfig(const timerHardware_t *timerHardwarePtr, uint16_t period, uint8_t mhz)
{
configTimeBase(timerHardwarePtr->tim, period, mhz);
TIM_Cmd(timerHardwarePtr->tim, ENABLE);

View file

@ -13,8 +13,8 @@ typedef struct {
extern const timerHardware_t timerHardware[];
void configTimeBase(TIM_TypeDef *tim, uint32_t period, uint8_t mhz);
void timerInConfig(const timerHardware_t *timerHardwarePtr, uint32_t period, uint8_t mhz);
void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint8_t mhz);
void timerInConfig(const timerHardware_t *timerHardwarePtr, uint16_t period, uint8_t mhz);
void timerNVICConfig(uint8_t irq);
void configureTimerInputCaptureCompareChannel(TIM_TypeDef *tim, const uint8_t channel);