Skip to content

Commit 625f6bf

Browse files
committed
moved the ISR for new data logic into the underlying interface comm object - in prep for enabling SPI - which needs the same logic as I2C; Also added logic for ESP32 and RP2* boards so the IRS callback takes a paramter -- which will enable the use of multiple devices - if needed
1 parent 27c62b7 commit 625f6bf

File tree

2 files changed

+109
-23
lines changed

2 files changed

+109
-23
lines changed

src/sfTk/sfDevFPC2534I2C.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,6 @@ static sfDevFPC2534I2C_IRead *__readHelper = nullptr;
2828

2929
#endif
3030

31-
// When in I2C comm mode, an interrupt pin from the FPC2534 is used to signal when
32-
// data is available to read. We manage this here.
33-
//
34-
// For the ISR interrupt handler
35-
// static volatile bool data_available = false;
36-
static volatile bool data_available = false;
37-
38-
static void the_isr_cb()
39-
{
40-
// This is the interrupt callback function
41-
// It will be called when the IRQ pin goes high
42-
// We can use this to signal that data is available
43-
44-
data_available = true;
45-
}
46-
4731
// --------------------------------------------------------------------------------------------
4832
// CTOR
4933
sfDevFPC2534I2C::sfDevFPC2534I2C() : _i2cAddress{0}, _i2cPort{nullptr}, _i2cBusNumber{0}
@@ -63,9 +47,8 @@ bool sfDevFPC2534I2C::initialize(uint8_t address, TwoWire &wirePort, uint8_t i2c
6347
_i2cPort = &wirePort;
6448
_i2cBusNumber = i2cBusNumber;
6549

66-
// Setup the interrupt handler
67-
pinMode(interruptPin, INPUT);
68-
attachInterrupt(interruptPin, the_isr_cb, RISING);
50+
// Call our super to init the ISR handler
51+
sfDevFPC2534IComm::initISRHandler(interruptPin);
6952

7053
// clear out our data buffer
7154
clearData();
@@ -82,7 +65,7 @@ bool sfDevFPC2534I2C::dataAvailable()
8265
return false;
8366

8467
// the data available flag is set, or we have data in the buffer
85-
return data_available || _dataCount > 0;
68+
return isISRDataAvailable() || _dataCount > 0;
8669
}
8770

8871
//--------------------------------------------------------------------------------------------
@@ -93,7 +76,8 @@ void sfDevFPC2534I2C::clearData()
9376
_dataCount = 0;
9477
_dataHead = 0;
9578
_dataTail = 0;
96-
data_available = false;
79+
// clear any data signaled by the ISR
80+
clearISRDataAvailable();
9781
}
9882

9983
//--------------------------------------------------------------------------------------------
@@ -173,10 +157,10 @@ uint16_t sfDevFPC2534I2C::read(uint8_t *data, size_t len)
173157
return FPC_RESULT_IO_RUNTIME_FAILURE;
174158

175159
// is new data available from the sensor - always grab new data if we have room
176-
if (data_available)
160+
if (isISRDataAvailable())
177161
{
178162
// clear flag
179-
data_available = false;
163+
clearISRDataAvailable();
180164

181165
// how much data is available?
182166
uint16_t dataAvailable = __readHelper->readTransferSize(_i2cAddress);

src/sfTk/sfDevFPC2534IComm.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
*---------------------------------------------------------------------------------
3+
*
4+
* Copyright (c) 2025, SparkFun Electronics Inc.
5+
*
6+
* SPDX-License-Identifier: MIT
7+
*
8+
*---------------------------------------------------------------------------------
9+
*/
10+
11+
#include <Arduino.h>
12+
// Implementation file for the I2C communication class of the library.
13+
#include "sfDevFPC2534IComm.h"
14+
15+
// When in I2C comm mode, an interrupt pin from the FPC2534 is used to signal when
16+
// data is available to read. We manage this here.
17+
//
18+
// For the ISR interrupt handler
19+
// static volatile bool data_available = false;
20+
static volatile bool data_available = false;
21+
22+
static bool isISRInitialized = false;
23+
24+
//--------------------------------------------------------------------------------------------
25+
// standard ISR handler - no param version
26+
static void the_isr_cb()
27+
{
28+
// This is the interrupt callback function
29+
// It will be called when the IRQ pin goes high
30+
// We can use this to signal that data is available
31+
32+
data_available = true;
33+
}
34+
35+
//--------------------------------------------------------------------------------------------
36+
// ISR handler with param version ()
37+
static void the_isr_cb_arg(void *arg)
38+
{
39+
// set the data available flag in the instance
40+
if (arg != nullptr)
41+
static_cast<sfDevFPC2534IComm *>(arg)->setISRDataAvailable();
42+
}
43+
44+
//--------------------------------------------------------------------------------------------
45+
// method used to set the IRS Handler by a sub-class
46+
void sfDevFPC2534IComm::initISRHandler(uint32_t interruptPin)
47+
{
48+
// Some platforms (ESP32 , RP2040) support passing an argument to the ISR handler.
49+
// If so, use that method to pass in "this" pointer to the handler. Which allows
50+
// us to set the data_available flag in the instance, rather than a static/global flag
51+
// and possibly support multiple sensors at the same time.
52+
53+
pinMode(interruptPin, INPUT);
54+
#if defined(ESP32)
55+
56+
attachInterruptArg(interruptPin, the_isr_cb_arg, (void *)this, RISING);
57+
_usingISRParam = true;
58+
59+
#elif defined(ARDUINO_ARCH_RP2040)
60+
61+
attachInterruptParam(interruptPin, the_isr_cb_arg, RISING, (void *)this);
62+
_usingISRParam = true;
63+
64+
#else
65+
66+
// Setup the interrupt handler for non-parameter version (older arduino impls)
67+
attachInterrupt(interruptPin, the_isr_cb, RISING);
68+
69+
isISRInitialized = true;
70+
_usingISRParam = false;
71+
#endif
72+
}
73+
//--------------------------------------------------------------------------------------------
74+
void sfDevFPC2534IComm::setISRDataAvailable(void)
75+
{
76+
_dataAvailable = true;
77+
}
78+
//--------------------------------------------------------------------------------------------
79+
// method used to clear the data available flag
80+
void sfDevFPC2534IComm::clearISRDataAvailable(void)
81+
{
82+
// Are we using the ISR param method?
83+
if (_usingISRParam)
84+
_dataAvailable = false;
85+
else if (isISRInitialized)
86+
data_available = false;
87+
}
88+
89+
//--------------------------------------------------------------------------------------------
90+
// Data available ?
91+
bool sfDevFPC2534IComm::isISRDataAvailable(void)
92+
{
93+
// Are we using the ISR param method?
94+
if (_usingISRParam)
95+
return _dataAvailable;
96+
97+
// Nope, using the static ISR and static flag in this file (this only supports one instance)
98+
if (!isISRInitialized)
99+
return false;
100+
101+
return data_available;
102+
}

0 commit comments

Comments
 (0)