Skip to content

Commit b9cb3b1

Browse files
author
Nathan Seidle
committed
Adding compare ISR
1 parent f3b8bc4 commit b9cb3b1

File tree

2 files changed

+118
-22
lines changed

2 files changed

+118
-22
lines changed

libraries/SoftwareSerial/src/SoftwareSerial.cpp

Lines changed: 109 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,34 @@
3636
#include "Arduino.h"
3737

3838
// Global Table of SoftwareSerial Pointers
39-
SoftwareSerial* gpSoftwareSerialObjs[AP3_GPIO_MAX_PADS];
39+
SoftwareSerial *gpSoftwareSerialObjs[AP3_GPIO_MAX_PADS];
4040
uint8_t gSoftwareSerialNumObjs = 0;
4141

42-
4342
// Software Serial ISR (To attach to pin change interrupts)
44-
void _software_serial_isr( void ){
43+
void _software_serial_isr(void)
44+
{
4545
uint64_t gpio_int_mask = 0x00;
4646
am_hal_gpio_interrupt_status_get(true, &gpio_int_mask);
47-
SoftwareSerial* obj = NULL;
48-
for(uint8_t indi = 0; indi < gSoftwareSerialNumObjs; indi++){
47+
SoftwareSerial *obj = NULL;
48+
for (uint8_t indi = 0; indi < gSoftwareSerialNumObjs; indi++)
49+
{
4950
obj = gpSoftwareSerialObjs[indi];
50-
if(obj == NULL){
51+
if (obj == NULL)
52+
{
5153
break; // there should not be any null pointers in the global object table
5254
}
53-
if(obj->_rxPadBitMask & gpio_int_mask){
55+
if (obj->_rxPadBitMask & gpio_int_mask)
56+
{
5457
obj->rxBit();
5558
}
5659
}
5760
}
5861

59-
6062
//Constructor
61-
SoftwareSerial::SoftwareSerial(uint8_t rxPin, uint8_t txPin)
63+
SoftwareSerial::SoftwareSerial(uint8_t rxPin, uint8_t txPin, bool invertLogic)
6264
{
63-
if( gSoftwareSerialNumObjs >= AP3_GPIO_MAX_PADS ){
65+
if (gSoftwareSerialNumObjs >= AP3_GPIO_MAX_PADS)
66+
{
6467
return; // Error -- no instances left to create
6568
}
6669

@@ -70,7 +73,9 @@ SoftwareSerial::SoftwareSerial(uint8_t rxPin, uint8_t txPin)
7073
_txPad = ap3_gpio_pin2pad(_txPin);
7174
_rxPad = ap3_gpio_pin2pad(_rxPin);
7275

73-
_rxPadBitMask = ( 0x01 << _rxPad );
76+
_invertLogic = invertLogic;
77+
78+
_rxPadBitMask = (0x01 << _rxPad);
7479

7580
// Add to the global array
7681
_indexNumber = gSoftwareSerialNumObjs;
@@ -81,19 +86,22 @@ SoftwareSerial::SoftwareSerial(uint8_t rxPin, uint8_t txPin)
8186
// Destructor
8287
SoftwareSerial::~SoftwareSerial()
8388
{
84-
if( gSoftwareSerialNumObjs < 1 ){
89+
if (gSoftwareSerialNumObjs < 1)
90+
{
8591
return; // error -- no instances left to destroy
8692
}
8793

8894
// Remove from global pointer list by filtering others down:
8995
uint8_t index = _indexNumber;
90-
do{
96+
do
97+
{
9198
gpSoftwareSerialObjs[index] = NULL;
92-
if( index < (gSoftwareSerialNumObjs-1) ){
93-
gpSoftwareSerialObjs[index] = gpSoftwareSerialObjs[index+1];
99+
if (index < (gSoftwareSerialNumObjs - 1))
100+
{
101+
gpSoftwareSerialObjs[index] = gpSoftwareSerialObjs[index + 1];
94102
}
95103
index++;
96-
}while( index < gSoftwareSerialNumObjs );
104+
} while (index < gSoftwareSerialNumObjs);
97105
gSoftwareSerialNumObjs--;
98106
}
99107

@@ -348,3 +356,88 @@ void SoftwareSerial::rxBit(void)
348356
am_hal_gpio_output_clear(triggerPad);
349357
#endif
350358
}
359+
360+
void SoftwareSerial::endOfByte()
361+
{
362+
//Finish out bytes that are less than 8 bits
363+
#ifdef DEBUG
364+
Serial.printf("bitCounter: %d\n", bitCounter);
365+
Serial.printf("incoming: 0x%02X\n", incomingByte);
366+
#endif
367+
bitCounter--; //Remove start bit from count
368+
369+
//Edge case where we need to do an additional byte shift because we had data bits followed by a parity bit of same value
370+
if (_parity)
371+
{
372+
bitCounter = bitCounter - _parityBits; //Remove parity bit from count
373+
if (bitType == true)
374+
bitCounter++;
375+
}
376+
377+
#ifdef DEBUG
378+
Serial.printf("bitCounter: %d\n", bitCounter);
379+
#endif
380+
381+
while (bitCounter < 8)
382+
{
383+
incomingByte >>= 1;
384+
if (bitType == true)
385+
if (bitCounter < _dataBits)
386+
{
387+
#ifdef DEBUG
388+
Serial.println("Add bit");
389+
#endif
390+
incomingByte |= 0x80;
391+
}
392+
bitCounter++;
393+
}
394+
395+
//TODO - Check parity bit if parity is enabled
396+
397+
if (_invertLogic)
398+
incomingByte = ~incomingByte;
399+
400+
//See if we are going to overflow buffer
401+
uint8_t nextSpot = (rxBufferHead + 1) % AP3_SS_BUFFER_SIZE;
402+
if (nextSpot != rxBufferTail)
403+
{
404+
//Add this byte to the buffer
405+
rxBuffer[nextSpot] = incomingByte;
406+
rxBufferHead = nextSpot;
407+
}
408+
else
409+
{
410+
#ifdef DEBUG
411+
am_hal_gpio_output_set(triggerPad);
412+
am_hal_gpio_output_clear(triggerPad);
413+
#endif
414+
_rxBufferOverflow = true;
415+
}
416+
417+
lastBitTime = 0; //Reset for next byte
418+
419+
rxInUse = false;
420+
421+
// Disable the timer interrupt in the NVIC.
422+
NVIC_DisableIRQ(STIMER_CMPR7_IRQn);
423+
}
424+
425+
//Called at the completion of bytes
426+
extern "C" void am_stimer_cmpr7_isr(void)
427+
{
428+
#ifdef DEBUG
429+
am_hal_gpio_output_set(triggerPad);
430+
#endif
431+
432+
uint32_t ui32Status = am_hal_stimer_int_status_get(false);
433+
if (ui32Status & AM_HAL_STIMER_INT_COMPAREH)
434+
{
435+
am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREH);
436+
437+
//this->endOfByte();
438+
}
439+
440+
#ifdef DEBUG
441+
am_hal_gpio_output_clear(triggerPad);
442+
#endif
443+
}

libraries/SoftwareSerial/src/SoftwareSerial.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
class SoftwareSerial
4444
{
4545
public:
46-
SoftwareSerial(uint8_t rxPin, uint8_t txPin);
46+
SoftwareSerial(uint8_t rxPin, uint8_t txPin, bool invertLogic = false);
4747
~SoftwareSerial();
4848

4949
void begin(uint32_t baudRate);
@@ -52,8 +52,9 @@ class SoftwareSerial
5252
ap3_err_t softwareserialSetConfig(HardwareSerial_Config_e SSconfig);
5353

5454
void rxBit(void);
55+
void endOfByte(void);
5556

56-
uint64_t _rxPadBitMask; // The AM HAL style pad bit mask associated with the RX pad
57+
uint64_t _rxPadBitMask; // The AM HAL style pad bit mask associated with the RX pad
5758

5859
private:
5960
void startRXListening(void);
@@ -67,30 +68,32 @@ class SoftwareSerial
6768
volatile uint8_t rxBuffer[AP3_SS_BUFFER_SIZE];
6869
volatile uint8_t rxBufferHead = 0;
6970
uint8_t rxBufferTail = 0;
70-
volatile bool rxInUse = false;
7171
volatile uint8_t incomingByte = 0;
7272

7373
uint8_t _rxPin;
7474
uint8_t _txPin;
7575

76-
uint8_t _indexNumber; // The index number at which the pointer to this instance is stored in the global object table.
76+
uint8_t _indexNumber; // The index number at which the pointer to this instance is stored in the global object table.
7777

7878
ap3_gpio_pad_t _txPad;
7979
ap3_gpio_pad_t _rxPad;
8080

8181
uint8_t _dataBits = 0; //5, 6, 7, or 8
8282
uint8_t _parity = 0; //Type of parity (0, 1, 2)
8383
uint8_t _stopBits = 0;
84+
uint8_t _parityBits = 0; //Number of parity bits (0 or 1)
85+
bool _invertLogic;
8486

8587
//For RX
86-
uint8_t _parityBits = 0; //Number of parity bits (0 or 1)
8788
uint16_t sysTicksPerBit = 0;
8889
uint32_t sysTicksPerByte = 0;
8990
uint16_t sysTicksPartialBit = 0;
9091
volatile uint8_t numberOfBits[10];
91-
volatile uint8_t bitCounter;
9292
volatile uint32_t lastBitTime = 0;
93+
volatile uint8_t bitCounter;
9394
volatile bool bitType = false;
95+
volatile bool rxInUse = false;
96+
bool _rxBufferOverflow = false;
9497

9598
//For TX
9699
uint8_t _parityForByte = 0; //Calculated per byte

0 commit comments

Comments
 (0)