Fixing software serial inversion. RX inversion was not implemented in

the new software serial receive implementation and TX was ignored
because the 'isInverted' flag was never set.
This commit is contained in:
Dominic Clifton 2014-04-06 17:10:48 +01:00
parent f336fc8d20
commit dbceb44fce
2 changed files with 31 additions and 35 deletions

View File

@ -16,18 +16,13 @@ softSerial_t softSerialPorts[MAX_SOFTSERIAL_PORTS];
void onSerialTimer(uint8_t portIndex, uint16_t capture); void onSerialTimer(uint8_t portIndex, uint16_t capture);
void onSerialRxPinChange(uint8_t portIndex, uint16_t capture); void onSerialRxPinChange(uint8_t portIndex, uint16_t capture);
uint8_t readRxSignal(softSerial_t *softSerial)
{
uint8_t invertedSignal = (digitalIn(softSerial->rxTimerHardware->gpio, softSerial->rxTimerHardware->pin) == 0);
if (softSerial->isInverted) {
return invertedSignal;
}
return !invertedSignal;
}
void setTxSignal(softSerial_t *softSerial, uint8_t state) void setTxSignal(softSerial_t *softSerial, uint8_t state)
{ {
if ((state == 1 && softSerial->isInverted == false) || (state == 0 && softSerial->isInverted == true)) { if (softSerial->isInverted) {
state = !state;
}
if (state) {
digitalHi(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin); digitalHi(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin);
} else { } else {
digitalLo(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin); digitalLo(softSerial->txTimerHardware->gpio, softSerial->txTimerHardware->pin);
@ -113,10 +108,10 @@ void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
TIM_ICInit(tim, &TIM_ICInitStructure); TIM_ICInit(tim, &TIM_ICInitStructure);
} }
void serialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference) void serialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference, uint8_t inverted)
{ {
// start bit is a FALLING signal // start bit is usually a FALLING signal
serialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Falling); serialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, inverted ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
configureTimerCaptureCompareInterrupt(timerHardwarePtr, reference, onSerialRxPinChange); configureTimerCaptureCompareInterrupt(timerHardwarePtr, reference, onSerialRxPinChange);
} }
@ -144,6 +139,7 @@ void initialiseSoftSerial(softSerial_t *softSerial, uint8_t portIndex, uint32_t
softSerial->isSearchingForStartBit = true; softSerial->isSearchingForStartBit = true;
softSerial->rxBitIndex = 0; softSerial->rxBitIndex = 0;
softSerial->isInverted = inverted;
serialOutputPortConfig(softSerial->txTimerHardware); serialOutputPortConfig(softSerial->txTimerHardware);
serialInputPortConfig(softSerial->rxTimerHardware); serialInputPortConfig(softSerial->rxTimerHardware);
@ -152,7 +148,7 @@ void initialiseSoftSerial(softSerial_t *softSerial, uint8_t portIndex, uint32_t
delay(50); delay(50);
serialTimerTxConfig(softSerial->txTimerHardware, portIndex, baud); serialTimerTxConfig(softSerial->txTimerHardware, portIndex, baud);
serialTimerRxConfig(softSerial->rxTimerHardware, portIndex); serialTimerRxConfig(softSerial->rxTimerHardware, portIndex, inverted);
} }
typedef struct softSerialConfiguration_s { typedef struct softSerialConfiguration_s {
@ -204,7 +200,7 @@ void updateBufferIndex(softSerial_t *softSerial)
void processTxState(softSerial_t *softSerial) void processTxState(softSerial_t *softSerial)
{ {
char mask; uint8_t mask;
if (!softSerial->isTransmittingData) { if (!softSerial->isTransmittingData) {
char byteToSend; char byteToSend;
@ -218,7 +214,7 @@ void processTxState(softSerial_t *softSerial)
softSerial->port.txBufferTail = 0; softSerial->port.txBufferTail = 0;
} }
// build internal buffer, start bit(1) + data bits + stop bit(0) // build internal buffer, MSB = Stop Bit (1) + data bits (MSB to LSB) + start bit(0) LSB
softSerial->internalTxBuffer = (1 << (TX_TOTAL_BITS - 1)) | (byteToSend << 1); softSerial->internalTxBuffer = (1 << (TX_TOTAL_BITS - 1)) | (byteToSend << 1);
softSerial->bitsLeftToTransmit = TX_TOTAL_BITS; softSerial->bitsLeftToTransmit = TX_TOTAL_BITS;
softSerial->isTransmittingData = true; softSerial->isTransmittingData = true;
@ -236,15 +232,15 @@ void processTxState(softSerial_t *softSerial)
} }
enum { enum {
FALLING, TRAILING,
RISING LEADING
}; };
void applyChangedBits(softSerial_t *softSerial) void applyChangedBits(softSerial_t *softSerial)
{ {
if (softSerial->rxPinMode == FALLING) { if (softSerial->rxEdge == TRAILING) {
uint8_t bitToSet; uint8_t bitToSet;
for (bitToSet = softSerial->rxLastRiseAtBitIndex; bitToSet < softSerial->rxBitIndex ; bitToSet++) { for (bitToSet = softSerial->rxLastLeadingEdgeAtBitIndex; bitToSet < softSerial->rxBitIndex ; bitToSet++) {
softSerial->internalRxBuffer |= 1 << bitToSet; softSerial->internalRxBuffer |= 1 << bitToSet;
} }
} }
@ -255,9 +251,9 @@ void prepareForNextRxByte(softSerial_t *softSerial)
// prepare for next byte // prepare for next byte
softSerial->rxBitIndex = 0; softSerial->rxBitIndex = 0;
softSerial->isSearchingForStartBit = true; softSerial->isSearchingForStartBit = true;
if (softSerial->rxPinMode == RISING) { if (softSerial->rxEdge == LEADING) {
softSerial->rxPinMode = FALLING; softSerial->rxEdge = TRAILING;
serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, TIM_ICPolarity_Falling); serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, softSerial->isInverted ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
} }
} }
@ -301,28 +297,28 @@ void onSerialRxPinChange(uint8_t portIndex, uint16_t capture)
if (softSerial->isSearchingForStartBit) { if (softSerial->isSearchingForStartBit) {
TIM_SetCounter(softSerial->rxTimerHardware->tim, 0); // synchronise bit counter TIM_SetCounter(softSerial->rxTimerHardware->tim, 0); // synchronise bit counter
serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, TIM_ICPolarity_Rising); serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, softSerial->isInverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
softSerial->rxPinMode = RISING; softSerial->rxEdge = LEADING;
softSerial->rxBitIndex = 0; softSerial->rxBitIndex = 0;
softSerial->rxLastRiseAtBitIndex = 0; softSerial->rxLastLeadingEdgeAtBitIndex = 0;
softSerial->internalRxBuffer = 0; softSerial->internalRxBuffer = 0;
softSerial->isSearchingForStartBit = false; softSerial->isSearchingForStartBit = false;
return; return;
} }
if (softSerial->rxPinMode == RISING) { if (softSerial->rxEdge == LEADING) {
softSerial->rxLastRiseAtBitIndex = softSerial->rxBitIndex; softSerial->rxLastLeadingEdgeAtBitIndex = softSerial->rxBitIndex;
} }
applyChangedBits(softSerial); applyChangedBits(softSerial);
if (softSerial->rxPinMode == FALLING) { if (softSerial->rxEdge == TRAILING) {
softSerial->rxPinMode = RISING; softSerial->rxEdge = LEADING;
serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, TIM_ICPolarity_Rising); serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, softSerial->isInverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
} else { } else {
softSerial->rxPinMode = FALLING; softSerial->rxEdge = TRAILING;
serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, TIM_ICPolarity_Falling); serialICConfig(softSerial->rxTimerHardware->tim, softSerial->rxTimerHardware->channel, softSerial->isInverted ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
} }
} }

View File

@ -20,8 +20,8 @@ typedef struct softSerial_s {
uint8_t isSearchingForStartBit; uint8_t isSearchingForStartBit;
uint8_t rxBitIndex; uint8_t rxBitIndex;
uint8_t rxLastRiseAtBitIndex; uint8_t rxLastLeadingEdgeAtBitIndex;
uint8_t rxPinMode; uint8_t rxEdge;
uint8_t isTransmittingData; uint8_t isTransmittingData;
uint8_t bitsLeftToTransmit; uint8_t bitsLeftToTransmit;