1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-18 05:45:31 +03:00

Move port telemetry port configuration logic into common telemetry code.

Update software serial to support RX, TX or RX&TX modes.  Update serial
API to allow on-the-fly changing of serial port mode.  Update HoTT to
change serial port mode when transmitting.
This commit is contained in:
Dominic Clifton 2014-04-07 16:39:09 +01:00
parent 1051cbcf52
commit ac0f3e9186
12 changed files with 169 additions and 64 deletions

View file

@ -38,3 +38,8 @@ inline bool isSerialTransmitBufferEmpty(serialPort_t *instance)
return instance->vTable->isSerialTransmitBufferEmpty(instance);
}
inline void serialSetMode(serialPort_t *instance, portMode_t mode)
{
instance->vTable->setMode(instance, mode);
}

View file

@ -38,12 +38,15 @@ struct serialPortVTable {
void (*serialSetBaudRate)(serialPort_t *instance, uint32_t baudRate);
bool (*isSerialTransmitBufferEmpty)(serialPort_t *instance);
void (*setMode)(serialPort_t *instance, portMode_t mode);
};
inline void serialWrite(serialPort_t *instance, uint8_t ch);
inline uint8_t serialTotalBytesWaiting(serialPort_t *instance);
inline uint8_t serialRead(serialPort_t *instance);
inline void serialSetBaudRate(serialPort_t *instance, uint32_t baudRate);
void serialSetMode(serialPort_t *instance, portMode_t mode);
inline bool isSerialTransmitBufferEmpty(serialPort_t *instance);
void serialPrint(serialPort_t *instance, const char *str);
uint32_t serialGetBaudRate(serialPort_t *instance);

View file

@ -120,11 +120,8 @@ void serialOutputPortConfig(const timerHardware_t *timerHardwarePtr)
softSerialGPIOConfig(timerHardwarePtr->gpio, timerHardwarePtr->pin, Mode_Out_PP);
}
void initialiseSoftSerial(softSerial_t *softSerial, uint8_t portIndex, uint32_t baud, uint8_t inverted)
void resetBuffers(softSerial_t *softSerial)
{
softSerial->port.vTable = softSerialVTable;
softSerial->port.mode = MODE_RXTX;
softSerial->port.rxBufferSize = SOFT_SERIAL_BUFFER_SIZE;
softSerial->port.rxBuffer = softSerial->rxBuffer;
softSerial->port.rxBufferTail = 0;
@ -134,6 +131,14 @@ void initialiseSoftSerial(softSerial_t *softSerial, uint8_t portIndex, uint32_t
softSerial->port.txBufferSize = SOFT_SERIAL_BUFFER_SIZE,
softSerial->port.txBufferTail = 0;
softSerial->port.txBufferHead = 0;
}
void initialiseSoftSerial(softSerial_t *softSerial, uint8_t portIndex, uint32_t baud, uint8_t inverted)
{
softSerial->port.vTable = softSerialVTable;
softSerial->port.mode = MODE_RXTX;
resetBuffers(softSerial);
softSerial->isTransmittingData = false;
@ -198,17 +203,19 @@ void updateBufferIndex(softSerial_t *softSerial)
/*********************************************/
void processTxState(softSerial_t *softSerial)
void prepareToSendNextByte(softSerial_t *softSerial)
{
uint8_t mask;
if (!softSerial->isTransmittingData) {
char byteToSend;
if ((softSerial->port.mode & MODE_TX) == 0) {
return;
}
if (isSoftSerialTransmitBufferEmpty((serialPort_t *)softSerial)) {
return;
}
// data to send
// choose data to send and update pointer to next byte
byteToSend = softSerial->port.txBuffer[softSerial->port.txBufferTail++];
if (softSerial->port.txBufferTail >= softSerial->port.txBufferSize) {
softSerial->port.txBufferTail = 0;
@ -218,9 +225,13 @@ void processTxState(softSerial_t *softSerial)
softSerial->internalTxBuffer = (1 << (TX_TOTAL_BITS - 1)) | (byteToSend << 1);
softSerial->bitsLeftToTransmit = TX_TOTAL_BITS;
softSerial->isTransmittingData = true;
return;
}
void processTxState(softSerial_t *softSerial)
{
uint8_t mask;
if (softSerial->isTransmittingData) {
mask = softSerial->internalTxBuffer & 1;
softSerial->internalTxBuffer >>= 1;
@ -229,8 +240,13 @@ void processTxState(softSerial_t *softSerial)
if (--softSerial->bitsLeftToTransmit <= 0) {
softSerial->isTransmittingData = false;
}
return;
}
prepareToSendNextByte(softSerial);
}
enum {
TRAILING,
LEADING
@ -259,6 +275,10 @@ void prepareForNextRxByte(softSerial_t *softSerial)
void extractAndStoreRxByte(softSerial_t *softSerial)
{
if ((softSerial->port.mode & MODE_RX) == 0) {
return;
}
uint8_t rxByte = (softSerial->internalRxBuffer >> 1) & 0xFF;
softSerial->port.rxBuffer[softSerial->port.rxBufferTail] = rxByte;
updateBufferIndex(softSerial);
@ -295,6 +315,10 @@ void onSerialRxPinChange(uint8_t portIndex, uint16_t capture)
{
softSerial_t *softSerial = &(softSerialPorts[portIndex]);
if ((softSerial->port.mode & MODE_RX) == 0) {
return;
}
if (softSerial->isSearchingForStartBit) {
TIM_SetCounter(softSerial->rxTimerHardware->tim, 0); // synchronise bit counter
serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, softSerial->isInverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
@ -324,6 +348,10 @@ void onSerialRxPinChange(uint8_t portIndex, uint16_t capture)
uint8_t softSerialTotalBytesWaiting(serialPort_t *instance)
{
if ((instance->mode & MODE_RX) == 0) {
return 0;
}
int availableBytes;
softSerial_t *softSerial = (softSerial_t *)instance;
if (softSerial->port.rxBufferTail == softSerial->port.rxBufferHead) {
@ -350,6 +378,11 @@ static void moveHeadToNextByte(softSerial_t *softSerial)
uint8_t softSerialReadByte(serialPort_t *instance)
{
char b;
if ((instance->mode & MODE_RX) == 0) {
return 0;
}
if (softSerialTotalBytesWaiting(instance) == 0) {
return 0;
}
@ -362,6 +395,10 @@ uint8_t softSerialReadByte(serialPort_t *instance)
void softSerialWriteByte(serialPort_t *s, uint8_t ch)
{
if ((s->mode & MODE_TX) == 0) {
return;
}
s->txBuffer[s->txBufferHead] = ch;
s->txBufferHead = (s->txBufferHead + 1) % s->txBufferSize;
}
@ -371,6 +408,11 @@ void softSerialSetBaudRate(serialPort_t *s, uint32_t baudRate)
// not implemented.
}
void softSerialSetMode(serialPort_t *instance, portMode_t mode)
{
instance->mode = mode;
}
bool isSoftSerialTransmitBufferEmpty(serialPort_t *instance)
{
return instance->txBufferHead == instance->txBufferTail;
@ -382,6 +424,7 @@ const struct serialPortVTable softSerialVTable[] = {
softSerialTotalBytesWaiting,
softSerialReadByte,
softSerialSetBaudRate,
isSoftSerialTransmitBufferEmpty
isSoftSerialTransmitBufferEmpty,
softSerialSetMode,
}
};

View file

@ -202,6 +202,12 @@ void uartSetBaudRate(serialPort_t *instance, uint32_t baudRate)
s->port.baudRate = baudRate;
}
void uartSetMode(serialPort_t *s, portMode_t mode)
{
// not implemented.
}
static void uartStartTxDMA(uartPort_t *s)
{
s->txDMAChannel->CMAR = (uint32_t)&s->port.txBuffer[s->port.txBufferTail];
@ -273,7 +279,8 @@ const struct serialPortVTable uartVTable[] = {
uartTotalBytesWaiting,
uartRead,
uartSetBaudRate,
isUartTransmitBufferEmpty
isUartTransmitBufferEmpty,
uartSetMode,
}
};

View file

@ -189,7 +189,7 @@ int main(void)
if (loopbackPort2) {
while (serialTotalBytesWaiting(loopbackPort2)) {
uint8_t b = serialRead(loopbackPort2);
serialWrite(loopbackPort1, b);
serialWrite(loopbackPort2, b);
//serialWrite(core.mainport, 0x02);
//serialWrite(core.mainport, b);
};

View file

@ -182,7 +182,7 @@ void annexCode(void)
LED0_ON;
// This will switch to/from 9600 or 115200 baud depending on state. Of course, it should only do it on changes. With telemetry_softserial>0 telemetry is always enabled, also see updateTelemetryState()
if (feature(FEATURE_TELEMETRY))
updateTelemetryState();
checkTelemetryState();
}
#ifdef LEDRING

View file

@ -4,6 +4,16 @@
#include "telemetry_frsky.h"
#include "telemetry_hott.h"
bool isTelemetryProviderFrSky(void)
{
return mcfg.telemetry_provider == TELEMETRY_PROVIDER_FRSKY;
}
bool isTelemetryProviderHoTT(void)
{
return mcfg.telemetry_provider == TELEMETRY_PROVIDER_HOTT;
}
void initTelemetry(void)
{
// Sanity check for softserial vs. telemetry port
@ -18,9 +28,7 @@ void initTelemetry(void)
core.telemport = core.mainport;
}
void updateTelemetryState(void) {
updateFrSkyTelemetryState();
}
static bool telemetryEnabled = false;
bool isTelemetryEnabled(void)
{
@ -36,14 +44,45 @@ bool isTelemetryEnabled(void)
return telemetryCurrentlyEnabled;
}
bool isFrSkyTelemetryEnabled(void)
bool shouldChangeTelemetryStateNow(bool telemetryCurrentlyEnabled)
{
return mcfg.telemetry_provider == TELEMETRY_PROVIDER_FRSKY;
return telemetryCurrentlyEnabled != telemetryEnabled;
}
bool isHoTTTelemetryEnabled(void)
void configureTelemetryPort(void) {
if (isTelemetryProviderFrSky()) {
configureFrSkyTelemetryPort();
}
if (isTelemetryProviderHoTT()) {
configureHoTTTelemetryPort();
}
}
void freeTelemetryPort(void) {
if (isTelemetryProviderFrSky()) {
freeFrSkyTelemetryPort();
}
if (isTelemetryProviderHoTT()) {
freeHoTTTelemetryPort();
}
}
void checkTelemetryState(void)
{
return mcfg.telemetry_provider == TELEMETRY_PROVIDER_HOTT;
bool telemetryCurrentlyEnabled = isTelemetryEnabled();
if (!shouldChangeTelemetryStateNow(telemetryCurrentlyEnabled)) {
return;
}
if (telemetryCurrentlyEnabled)
configureTelemetryPort();
else
freeTelemetryPort();
telemetryEnabled = telemetryCurrentlyEnabled;
}
void handleTelemetry(void)
@ -51,11 +90,11 @@ void handleTelemetry(void)
if (!isTelemetryEnabled())
return;
if (isFrSkyTelemetryEnabled()) {
if (isTelemetryProviderFrSky()) {
handleFrSkyTelemetry();
}
if (isHoTTTelemetryEnabled()) {
if (isTelemetryProviderHoTT()) {
handleHoTTTelemetry();
}
}

View file

@ -10,7 +10,7 @@
// telemetry
void initTelemetry(void);
void updateTelemetryState(void);
void checkTelemetryState(void);
void handleTelemetry(void);
bool isTelemetryEnabled(void);

View file

@ -215,28 +215,18 @@ static void sendHeading(void)
serialize16(0);
}
static bool frSkyTelemetryEnabled = false;
bool shouldChangeTelemetryStateNow(bool frSkyTelemetryCurrentlyEnabled)
void freeFrSkyTelemetryPort(void)
{
return frSkyTelemetryCurrentlyEnabled != frSkyTelemetryEnabled;
}
void updateFrSkyTelemetryState(void)
{
bool frSkyTelemetryCurrentlyEnabled = isTelemetryEnabled();
if (!shouldChangeTelemetryStateNow(frSkyTelemetryCurrentlyEnabled)) {
return;
}
if (mcfg.telemetry_port == TELEMETRY_PORT_UART && mcfg.telemetry_provider == TELEMETRY_PROVIDER_FRSKY) {
if (frSkyTelemetryCurrentlyEnabled)
serialInit(9600);
else
if (mcfg.telemetry_port == TELEMETRY_PORT_UART) {
serialInit(mcfg.serial_baudrate);
}
frSkyTelemetryEnabled = frSkyTelemetryCurrentlyEnabled;
}
void configureFrSkyTelemetryPort(void)
{
if (mcfg.telemetry_port == TELEMETRY_PORT_UART) {
serialInit(9600);
}
}
static uint32_t lastCycleTime = 0;

View file

@ -9,6 +9,9 @@
#define TELEMETRY_FRSKY_H_
void handleFrSkyTelemetry(void);
void updateFrSkyTelemetryState(void);
void checkFrSkyTelemetryState(void);
void configureFrSkyTelemetryPort(void);
void freeFrSkyTelemetryPort(void);
#endif /* TELEMETRY_FRSKY_H_ */

View file

@ -216,9 +216,7 @@ void hottV4FormatAndSendEAMResponse(void) {
static void hottV4Respond(uint8_t *data, uint8_t size) {
if (serialTotalBytesWaiting(core.telemport) != 0 ) {
return; // cannot respond since another request came in.
}
serialSetMode(core.telemport, MODE_TX);
uint16_t crc = 0;
uint8_t i;
@ -235,16 +233,29 @@ static void hottV4Respond(uint8_t *data, uint8_t size) {
hottV4SerialWrite(crc & 0xFF);
delayMicroseconds(HOTTV4_TX_DELAY);
serialSetMode(core.telemport, MODE_RX);
}
static void hottV4SerialWrite(uint8_t c) {
serialWrite(core.telemport, c);
}
void configureHoTTTelemetryPort(void) {
// TODO set speed here to 19200
serialSetMode(core.telemport, MODE_RX);
}
void freeHoTTTelemetryPort(void) {
serialSetMode(core.telemport, MODE_RXTX);
}
void handleHoTTTelemetry(void)
{
while (serialTotalBytesWaiting(core.telemport)) {
uint8_t c = serialRead(core.telemport);
uint8_t c;
while (serialTotalBytesWaiting(core.telemport) > 0) {
c = serialRead(core.telemport);
// Protocol specific waiting time
// to avoid collisions

View file

@ -198,5 +198,9 @@ struct {
} HoTTV4ElectricAirModule;
void handleHoTTTelemetry(void);
void checkTelemetryState(void);
void configureHoTTTelemetryPort(void);
void freeHoTTTelemetryPort(void);
#endif /* TELEMETRY_HOTT_H_ */