Skip to content

Commit c83d88a

Browse files
committed
Use 'attachInterruptArg()' for RX interrupts with 'this' argument
This allows us to dispose of the ugly global table of pointers to software serial objects. Instead those pointers are all handled in the GPIO core. We will need to make sure to detach the interrupt (and thereby remove reference to the software serial object) when the object is destroyed.
1 parent 15571ad commit c83d88a

File tree

2 files changed

+7
-60
lines changed

2 files changed

+7
-60
lines changed

libraries/SoftwareSerial/src/SoftwareSerial.cpp

Lines changed: 7 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@
3535
#include "SoftwareSerial.h"
3636
#include "Arduino.h"
3737

38-
// Global Table of SoftwareSerial Pointers
39-
SoftwareSerial *gpSoftwareSerialObjs[AP3_GPIO_MAX_PADS];
40-
uint8_t gSoftwareSerialNumObjs = 0;
41-
4238
SoftwareSerial *ap3_serial_handle = 0;
4339

4440
//Uncomment to enable debug pulses and Serial.prints
@@ -49,74 +45,29 @@ SoftwareSerial *ap3_serial_handle = 0;
4945
ap3_gpio_pad_t debugPad = ap3_gpio_pin2pad(SS_DEBUG_PIN);
5046
#endif
5147

52-
// Software Serial ISR (To attach to pin change interrupts)
53-
/*void _software_serial_isr(void)
54-
{
55-
uint64_t gpio_int_mask = 0x00;
56-
am_hal_gpio_interrupt_status_get(true, &gpio_int_mask);
57-
SoftwareSerial *obj = NULL;
58-
for (uint8_t indi = 0; indi < gSoftwareSerialNumObjs; indi++)
59-
{
60-
obj = gpSoftwareSerialObjs[indi];
61-
if (obj == NULL)
62-
{
63-
break; // there should not be any null pointers in the global object table
64-
}
65-
if (obj->_rxPadBitMask & gpio_int_mask)
66-
{
67-
obj->rxBit();
68-
}
69-
}
70-
}*/
71-
inline void _software_serial_isr(void)
48+
inline void _software_serial_isr(void* arg)
7249
{
73-
ap3_serial_handle->rxBit();
50+
SoftwareSerial* handle = (SoftwareSerial*)arg;
51+
handle->rxBit();
7452
}
7553

7654
//Constructor
7755
SoftwareSerial::SoftwareSerial(uint8_t rxPin, uint8_t txPin, bool invertLogic)
7856
{
79-
if (gSoftwareSerialNumObjs >= AP3_GPIO_MAX_PADS)
80-
{
81-
return; // Error -- no instances left to create
82-
}
83-
8457
_rxPin = rxPin;
8558
_txPin = txPin;
8659

8760
_txPad = ap3_gpio_pin2pad(_txPin);
8861
_rxPad = ap3_gpio_pin2pad(_rxPin);
8962

9063
_invertLogic = invertLogic;
91-
92-
_rxPadBitMask = (0x01 << _rxPad);
93-
94-
// Add to the global array
95-
_indexNumber = gSoftwareSerialNumObjs;
96-
gpSoftwareSerialObjs[_indexNumber] = this;
97-
gSoftwareSerialNumObjs++;
9864
}
9965

10066
// Destructor
10167
SoftwareSerial::~SoftwareSerial()
10268
{
103-
if (gSoftwareSerialNumObjs < 1)
104-
{
105-
return; // error -- no instances left to destroy
106-
}
107-
108-
// Remove from global pointer list by filtering others down:
109-
uint8_t index = _indexNumber;
110-
do
111-
{
112-
gpSoftwareSerialObjs[index] = NULL;
113-
if (index < (gSoftwareSerialNumObjs - 1))
114-
{
115-
gpSoftwareSerialObjs[index] = gpSoftwareSerialObjs[index + 1];
116-
}
117-
index++;
118-
} while (index < gSoftwareSerialNumObjs);
119-
gSoftwareSerialNumObjs--;
69+
// Todo: call an "end" function that will detach the interrupt before removing the object
70+
// (otherwise rx interrupts will try to access an invalid object)
12071
}
12172

12273
void SoftwareSerial::begin(uint32_t baudRate)
@@ -157,10 +108,8 @@ void SoftwareSerial::begin(uint32_t baudRate, HardwareSerial_Config_e SSconfig)
157108
//Clear compare interrupt
158109
am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREH);
159110

160-
// Register the class into the local list
161-
ap3_serial_handle = this;
162-
163-
attachInterrupt(digitalPinToInterrupt(_rxPin), _software_serial_isr, CHANGE);
111+
// Attach argument interrupt with 'this' as argument
112+
attachInterruptArg(digitalPinToInterrupt(_rxPin), _software_serial_isr, (void*)this, CHANGE);
164113
}
165114

166115
int SoftwareSerial::available()

libraries/SoftwareSerial/src/SoftwareSerial.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ class SoftwareSerial
5959
void rxBit(void);
6060
void endOfByte(void);
6161

62-
uint64_t _rxPadBitMask; // The AM HAL style pad bit mask associated with the RX pad
63-
6462
private:
6563
void startRXListening(void);
6664

0 commit comments

Comments
 (0)