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];
4040uint8_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
8287SoftwareSerial::~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+ }
0 commit comments