Skip to content

Commit a11dfbf

Browse files
committed
Add proof of concept sketches
Modified from library example sketches to fit the ILABS Challenger RP2040 NFC
1 parent 9627729 commit a11dfbf

File tree

3 files changed

+428
-0
lines changed

3 files changed

+428
-0
lines changed

build_all.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
arduino-cli compile --output-dir artifacts/ -b rp2040:rp2040:challenger_2040_nfc poc/TagDetect
4+
5+
arduino-cli compile --output-dir artifacts/ -b rp2040:rp2040:challenger_2040_nfc poc/WebClientRepeating

poc/TagDetect/TagDetect.ino

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
/*
2+
* TagDetect.ino
3+
*
4+
* Copyright (c) Thomas Buhot. All right reserved.
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
/******************************************************************************
22+
* Purpose of this sketch
23+
*
24+
* The purpose of this sketch is to provide an example of NFC tag detection
25+
* by using a simple but efficient NFC stack.
26+
*
27+
* The NFC stack implements a tag API which drives an NFC controller
28+
* through the NCI (NFC Controller Interface) as defined by the NFC Forum.
29+
* The NFC stack
30+
* consists in:
31+
* - NfcTagsi : high level tag API for detection, deactivation
32+
* - NfcNci : NCI implementation, hardware independent
33+
* - NfcHw : NFC hardaware interface
34+
*
35+
* The NFC stack configures the NFC Controller to detect tag of types 1,
36+
* 2 or 3 as per the NFC Forum specifications.
37+
*
38+
* This sketch:
39+
* 1. initializes the NFC controller
40+
* 2. configures the RF discovery parameters
41+
* 3. prints NFCID of the detected tag
42+
* 4. restart the tag detection back to step 2
43+
*
44+
* The HW configuration used to test that sketch is: Intel Arduino 101
45+
* with NXP PN7120 SBC kit.
46+
*****************************************************************************/
47+
48+
#include <Nfc.h>
49+
50+
/**********************************************
51+
* NFC controller hardware configuration
52+
*
53+
* - NXP PN7120 NFC chipset
54+
* - Connected with I2C + IRQ + RESET
55+
*********************************************/
56+
57+
#define PN7120_IRQ 9 // pin 2 configured as input for IRQ
58+
#define PN7120_RESET 12 // pin 4 configured as input for VEN (reset)
59+
#define PN7120_I2C_ADDRESS 0x28 // 0x28
60+
61+
/**********************************************
62+
* Sketch application class
63+
*
64+
* Implements the state machine and event
65+
* handler of the sketch. Besides, interfaces
66+
* with the NfcTags class which offers the
67+
* NFC API for tags detection and handling.
68+
* Each callback is called upon NFC controller
69+
* response or event received from Tags class.
70+
* The callbacks are used to:
71+
* - check the reponse / event status and data,
72+
* - change the current state accordingly.
73+
**********************************************/
74+
75+
// state definition
76+
enum
77+
{
78+
STATE_RESET = 0,
79+
STATE_RESET_RESPONSE,
80+
STATE_DISCOVER,
81+
STATE_DISCOVER_RESPONSE,
82+
STATE_DISCOVERING,
83+
STATE_DEACTIVATE,
84+
STATE_DEACTIVATE_RESPONSE,
85+
STATE_ERROR,
86+
STATE_END
87+
};
88+
89+
const char *tagDetectStateToStr[] = {
90+
"STATE_RESET",
91+
"STATE_RESET_RESPONSE",
92+
"STATE_DISCOVER",
93+
"STATE_DISCOVER_RESPONSE",
94+
"STATE_DISCOVERING",
95+
"STATE_DEACTIVATE",
96+
"STATE_DEACTIVATE_RESPONSE",
97+
"STATE_ERROR",
98+
"STATE_END"
99+
};
100+
101+
// Sketch application object to interface with NfcTags API
102+
class NfcApps : public NfcTagsCb
103+
{
104+
public:
105+
NfcApps(NfcLog& log, NfcTags& tags) : _state(STATE_RESET), _log(log), _tags(tags) {;}
106+
void init(void) {;}
107+
void handleEvent(void);
108+
void cbReset(uint8_t status, uint16_t id, void *data);
109+
void cbDiscover(uint8_t status, uint16_t id, void *data);
110+
void cbDiscoverNtf(uint8_t status, uint16_t id, void *data);
111+
void cbDeactivate(uint8_t status, uint16_t id, void *data);
112+
void cbDump(uint8_t status, uint16_t id, void *data);
113+
114+
private:
115+
uint8_t _state;
116+
NfcLog& _log;
117+
NfcTags& _tags;
118+
};
119+
120+
// State machine event handler
121+
void NfcApps::handleEvent(void)
122+
{
123+
uint8_t status = TAGS_STATUS_FAILED;
124+
125+
_log.d("TagDetect: %s state = %s\n", __func__, tagDetectStateToStr[_state]);
126+
127+
switch(_state) {
128+
case STATE_RESET:
129+
// reset NFC stack and hw
130+
status = _tags.cmdReset();
131+
_state = STATE_RESET_RESPONSE;
132+
break;
133+
case STATE_RESET_RESPONSE:
134+
// wait for reset
135+
status = TAGS_STATUS_OK;
136+
break;
137+
case STATE_DISCOVER:
138+
// find tags
139+
status = _tags.cmdDiscover();
140+
_state = STATE_DISCOVER_RESPONSE;
141+
break;
142+
case STATE_DISCOVER_RESPONSE:
143+
// wait for find tags response
144+
status = TAGS_STATUS_OK;
145+
break;
146+
case STATE_DISCOVERING:
147+
// waiting for a tag to be detected
148+
status = TAGS_STATUS_OK;
149+
break;
150+
case STATE_DEACTIVATE:
151+
// disconnect from tag and restart discovery loop
152+
status = _tags.cmdDeactivate();
153+
_state = STATE_DEACTIVATE_RESPONSE;
154+
break;
155+
case STATE_DEACTIVATE_RESPONSE:
156+
// wait for tag deactivation
157+
status = TAGS_STATUS_OK;
158+
break;
159+
case STATE_ERROR:
160+
case STATE_END:
161+
default:
162+
break;
163+
}
164+
165+
// handle error
166+
if (status != TAGS_STATUS_OK) {
167+
_log.e("TagDetect error: %s status = %d state = %d\n", __func__, status, _state);
168+
_state = STATE_ERROR;
169+
}
170+
}
171+
172+
// Hardware reset callback
173+
void NfcApps::cbReset(uint8_t status, uint16_t id, void *data)
174+
{
175+
_log.d("TagDetect: %s status = %d id = %d\n", __func__, status, id);
176+
177+
if (status != TAGS_STATUS_OK || id != TAGS_ID_RESET) {
178+
_state = STATE_ERROR;
179+
}
180+
else {
181+
_log.i("TagDetect: NFC stack and HW reseted\n");
182+
_state = STATE_DISCOVER;
183+
}
184+
}
185+
186+
// Discover target callback
187+
void NfcApps::cbDiscover(uint8_t status, uint16_t id, void *data)
188+
{
189+
_log.d("TagDetect: %s status = %d id = %d\n", __func__, status, id);
190+
191+
if (status != TAGS_STATUS_OK || id != TAGS_ID_DISCOVER) {
192+
_state = STATE_ERROR;
193+
}
194+
else {
195+
_log.i("TagDetect: NFC stack discovering tags...\n");
196+
_state = STATE_DISCOVERING;
197+
}
198+
}
199+
200+
// Discover notification on tag detected callback
201+
void NfcApps::cbDiscoverNtf(uint8_t status, uint16_t id, void *data)
202+
{
203+
NfcTagsIntf *pTag;
204+
uint8_t len, type;
205+
uint8_t *buf;
206+
207+
_log.d("TagDetect: %s status = %d id = %d\n", __func__, status, id);
208+
209+
if (status != TAGS_STATUS_OK || id != TAGS_ID_DISCOVER_ACTIVATED) {
210+
_state = STATE_ERROR;
211+
}
212+
else {
213+
pTag = _tags.getInterface();
214+
if (pTag != NULL) {
215+
type = pTag->getType();
216+
_log.i("TagDetect: tag type %d detected\n", type);
217+
len = pTag->getNfcidLen();
218+
buf = pTag->getNfcidBuf();
219+
_log.bi("TagDetect: tag NFCID = ", buf, len);
220+
}
221+
else {
222+
_log.i("TagDetect: unknown tag type detected\n");
223+
}
224+
}
225+
_state = STATE_DEACTIVATE;
226+
}
227+
228+
// Tag dump callback, unused in that sketch which ony detects tags
229+
void NfcApps::cbDump(uint8_t status, uint16_t id, void *data)
230+
{
231+
}
232+
233+
// Tag deactivation callback
234+
void NfcApps::cbDeactivate(uint8_t status, uint16_t id, void *data)
235+
{
236+
_log.d("TagDetect: %s status = %d id = %d\n", __func__, status, id);
237+
238+
if (status != TAGS_STATUS_OK || id != TAGS_ID_DEACTIVATE) {
239+
_state = STATE_ERROR;
240+
}
241+
else {
242+
_state = STATE_DISCOVERING;
243+
}
244+
}
245+
246+
/**********************************************
247+
* Sketch runtime
248+
*
249+
* _log: logger (serial)
250+
* _pn7120: NXP PN7120 NFC chipset
251+
* _nci: NFC Connection Interface (NFC Forum)
252+
* _tags: tag API wrapper to drive NCI chipset
253+
* _app: sketch implementation
254+
**********************************************/
255+
256+
NfcLog _log(NFC_LOG_LEVEL_INFO);
257+
NfcHw_pn7120 _pn7120(_log, PN7120_IRQ, PN7120_RESET, PN7120_I2C_ADDRESS);
258+
NfcNci _nci(_log, _pn7120);
259+
NfcTags _tags(_log, _nci);
260+
NfcApps _app(_log, _tags);
261+
262+
// the setup function runs once when you press reset or power the board
263+
void setup(void)
264+
{
265+
// add a delay for the serial bus to be mounted
266+
//delay(2000);
267+
Serial.begin(115200);
268+
while (!Serial) {delay(1);}
269+
270+
Serial.println("Serial connected.");
271+
272+
// init all layers from bottom to top
273+
// logger, hw, nci, tags, and state machine
274+
_log.init(230400);
275+
_pn7120.init();
276+
_nci.init(&_tags);
277+
_tags.init(&_app);
278+
_app.init();
279+
}
280+
281+
// the loop function runs over and over again forever
282+
void loop(void)
283+
{
284+
// handle sketch events (state machine based)
285+
_app.handleEvent();
286+
287+
// handle tags class events (state machine based)
288+
_tags.handleEvent();
289+
290+
// handle NCI events (state machine based),
291+
// it may block waiting for NFC controller
292+
// response or event
293+
_nci.handleEvent();
294+
}
295+

0 commit comments

Comments
 (0)