Merge pull request #56 from hydra/software-serial-fix-inversion

Fixing software serial inversion.
This commit is contained in:
dongie 2014-04-07 02:13:10 +09:00
commit c2c1613dac
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;