Skip to content

Commit 9405cc8

Browse files
committed
uart version of config
1 parent 37d0098 commit 9405cc8

File tree

1 file changed

+389
-0
lines changed

1 file changed

+389
-0
lines changed
Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
/*
2+
*---------------------------------------------------------------------------------
3+
*
4+
* Copyright (c) 2025, SparkFun Electronics Inc.
5+
*
6+
* SPDX-License-Identifier: MIT
7+
*
8+
*---------------------------------------------------------------------------------
9+
*/
10+
11+
/*
12+
* Example using the SparkFun FPC2534 Fingerprint sensor library to demonstrate the configuration
13+
* capabilities of the sensor. The example retrieves the current system configuration from the sensor,
14+
* modifies one of the configuration values, and sends the updated configuration back to the sensor.
15+
*
16+
* NOTE: Currently, the set of the updated values fails.
17+
*
18+
* This version of this example uses the SPI interface to communicate with the sensor.
19+
*
20+
*---------------------------------------------------------------------------------
21+
*/
22+
23+
#include <Arduino.h>
24+
25+
#include "SparkFun_FPC2534.h"
26+
27+
//----------------------------------------------------------------------------
28+
// User Config -
29+
//----------------------------------------------------------------------------
30+
// Define the pins being used for operation
31+
//
32+
// The FPC2534 uses one pin for reset, No interrupt pin is needed for UART operation
33+
//
34+
// The following pin definitions were used for testing - but can be modified as needed.
35+
//
36+
// ESP32 thing plus
37+
// #define RST_PIN 21
38+
39+
// ESP32 thing plus C
40+
// #define RST_PIN 14
41+
42+
// RP2350 thing plus
43+
#define RST_PIN 12
44+
45+
// IoT RedBoard - RP2350
46+
// #define RST_PIN 29
47+
48+
//----------------------------------------------------------------------------------
49+
// NOTE:
50+
// This example makes use of the Serial1 hardware serial port for communication with the FPC2534. If the board
51+
// being used does not have a Serial1 port, you will need to modify the code to use SoftwareSerial or another
52+
// serial port available on your board.
53+
54+
// Declare our sensor object. Note the SPI version of the sensor class is used.
55+
SfeFPC2534UART mySensor;
56+
57+
// flag used to indicate if config has been set....
58+
#define CONFIG_BEGIN 0
59+
#define CONFIG_REQUESTED 1
60+
#define CONFIG_RECEIVED 2
61+
#define CONFIG_SET 3
62+
#define CONFIG_VERIFY 4
63+
#define CONFIG_RESET 5
64+
#define CONFIG_COMPLETE 6
65+
#define CONFIG_EXIT 255
66+
67+
uint8_t configState = CONFIG_BEGIN;
68+
69+
fpc_system_config_t the_config = {0};
70+
bool deviceIdle = false;
71+
//------------------------------------------------------------------------------------
72+
// Callback functions the library calls
73+
//------------------------------------------------------------------------------------
74+
75+
//----------------------------------------------------------------------------
76+
// on_error()
77+
//
78+
// Called if the sensor library detects/encounters an error
79+
//
80+
static void on_error(uint16_t error)
81+
{
82+
Serial.print("[ERROR]\tSensor Error Code: ");
83+
Serial.println(error);
84+
85+
// this could indicated the sensor communications is out of synch - a reset might be needed
86+
reset_sensor();
87+
}
88+
89+
//----------------------------------------------------------------------------
90+
// on_is_ready_change()
91+
//
92+
// Called when the device ready state changes
93+
//
94+
static void on_is_ready_change(bool isReady)
95+
{
96+
// On startup the device isn't immediately ready. A message is sent when it is.
97+
// The Library will call this function when that happens
98+
99+
if (isReady)
100+
{
101+
Serial.println("[STARTUP]\tFPC2534 Device is ready");
102+
103+
Serial.println("[INFO]\t\tRequesting system configuration...");
104+
// Request the configuration from the connected device.
105+
fpc_result_t rc = mySensor.requestGetSystemConfig(FPC_SYS_CFG_TYPE_DEFAULT);
106+
if (rc != FPC_RESULT_OK)
107+
{
108+
Serial.print("[ERROR]\tGet config request failed - error: ");
109+
Serial.println(rc);
110+
}
111+
else
112+
configState = CONFIG_REQUESTED;
113+
}
114+
}
115+
116+
//----------------------------------------------------------------------------
117+
// on_status()
118+
//
119+
// Called when the sensor sends a status message
120+
//
121+
static void on_status(uint16_t event, uint16_t state)
122+
{
123+
deviceIdle = (event == EVENT_IDLE);
124+
}
125+
126+
//----------------------------------------------------------------------------
127+
static void update_config(fpc_system_config_t &new_config)
128+
{
129+
// The current values haven't been received yet
130+
if (configState < CONFIG_RECEIVED)
131+
return;
132+
133+
fpc_result_t rc = mySensor.setSystemConfig(&new_config);
134+
if (rc != FPC_RESULT_OK)
135+
{
136+
Serial.print("[ERROR]\tSet config request failed - error: ");
137+
Serial.println(rc);
138+
}
139+
}
140+
//----------------------------------------------------------------------------
141+
static void update_config_max_fails(uint8_t max_fails)
142+
{
143+
// The current values haven't been received yet
144+
if (configState < CONFIG_RECEIVED)
145+
return;
146+
// copy over the current defaults
147+
fpc_system_config_t new_config = the_config;
148+
149+
// update the value of max consecutive fails
150+
new_config.idfy_max_consecutive_fails = max_fails;
151+
152+
Serial.println();
153+
delay(500);
154+
Serial.print("[INFO]\t\tSetting Max Fails To: ");
155+
156+
Serial.println(new_config.idfy_max_consecutive_fails);
157+
158+
update_config(new_config);
159+
}
160+
//----------------------------------------------------------------------------
161+
static void print_config(fpc_system_config_t &cfg)
162+
{
163+
164+
Serial.print(" Version:\t\t\t ");
165+
Serial.println(cfg.version);
166+
Serial.print(" Finger Scan Interval (ms):\t ");
167+
Serial.println(cfg.finger_scan_interval_ms);
168+
Serial.print(" System Flags:\t\t\t 0x");
169+
Serial.println(cfg.sys_flags, HEX);
170+
Serial.print(" Allows Factory Reset:\t\t ");
171+
Serial.println((cfg.sys_flags & CFG_SYS_FLAG_ALLOW_FACTORY_RESET) ? "Yes" : "No");
172+
Serial.print(" UART Delay Before IRQ (ms):\t ");
173+
Serial.println(cfg.uart_delay_before_irq_ms);
174+
Serial.print(" UART Baudrate:\t\t 0x");
175+
Serial.println(cfg.uart_baudrate, HEX);
176+
Serial.print(" Max Consecutive Identify Fails: ");
177+
Serial.println(cfg.idfy_max_consecutive_fails);
178+
Serial.print(" Identify Lockout Time (s):\t ");
179+
Serial.println(cfg.idfy_lockout_time_s);
180+
Serial.print(" Idle Time Before Sleep (ms):\t ");
181+
Serial.println(cfg.idle_time_before_sleep_ms);
182+
Serial.print(" Enroll Touches:\t\t ");
183+
Serial.println(cfg.enroll_touches);
184+
Serial.print(" Enroll Immobile Touches:\t ");
185+
Serial.println(cfg.enroll_immobile_touches);
186+
Serial.print(" I2C Address (7bit):\t\t 0x");
187+
Serial.println(cfg.i2c_address, HEX);
188+
}
189+
//----------------------------------------------------------------------------
190+
// on_system_config_get()
191+
void on_system_config_get(fpc_system_config_t *cfg)
192+
{
193+
if (cfg == NULL)
194+
{
195+
Serial.println("[ERROR]\tInvalid configuration data received");
196+
return;
197+
}
198+
// first print the config
199+
Serial.println("[CONFIG]\tSystem Configuration Received:");
200+
print_config(*cfg);
201+
202+
// result of our initial request to get the config
203+
if (configState == CONFIG_REQUESTED)
204+
{
205+
// stash our current config as the default
206+
the_config = *cfg;
207+
208+
configState = CONFIG_RECEIVED;
209+
}
210+
else if (configState == CONFIG_VERIFY)
211+
{
212+
// verify the config set worked
213+
if (cfg->idfy_max_consecutive_fails == the_config.idfy_max_consecutive_fails + 1)
214+
Serial.println("[INFO]\t\tConfiguration update verified successfully.");
215+
else
216+
{
217+
Serial.println();
218+
Serial.println("[ERROR]\tConfiguration update verification failed.");
219+
Serial.println();
220+
}
221+
222+
// back to entry state
223+
configState = CONFIG_RESET;
224+
}
225+
}
226+
//------------------------------------------------------------------------------------
227+
// Callbacks
228+
//
229+
// Define our command callbacks structure - callback methods are assigned in setup
230+
static sfDevFPC2534Callbacks_t cmd_cb = {0};
231+
232+
//------------------------------------------------------------------------------------
233+
// reset_sensor()
234+
//
235+
// Simple function to toggle the reset pin of the sensor
236+
//
237+
void reset_sensor(void)
238+
{
239+
// Reset the sensor by toggling the reset pin.
240+
//
241+
// clear out our data buffer
242+
mySensor.clearData();
243+
pinMode(RST_PIN, OUTPUT);
244+
digitalWrite(RST_PIN, LOW); // Set reset pin low
245+
delay(10); // Wait for 10 ms
246+
247+
digitalWrite(RST_PIN, HIGH); // Set reset pin high
248+
delay(250); // Wait for sensor to initialize
249+
}
250+
//------------------------------------------------------------------------------------
251+
// Process the simple sequece of steps for the demo.
252+
253+
void process_demo_steps(void)
254+
{
255+
256+
// if we have the config, and haven't updated it yet, do so now
257+
if (configState == CONFIG_RECEIVED)
258+
{
259+
// update the max fails value
260+
update_config_max_fails(the_config.idfy_max_consecutive_fails + 1);
261+
262+
configState = CONFIG_SET;
263+
}
264+
else if (configState == CONFIG_SET)
265+
{
266+
// Get the new value of the config to verify the set worked
267+
Serial.println("[INFO]\t\tRequesting system configuration...");
268+
// Request the configuration from the connected device.
269+
fpc_result_t rc = mySensor.requestGetSystemConfig(FPC_SYS_CFG_TYPE_DEFAULT);
270+
if (rc != FPC_RESULT_OK)
271+
{
272+
Serial.print("[ERROR]\tGet config request failed - error: ");
273+
Serial.println(rc);
274+
}
275+
else
276+
configState = CONFIG_VERIFY;
277+
}
278+
else if (configState == CONFIG_RESET)
279+
{
280+
// Reset to defaults
281+
fpc_result_t rc = mySensor.setSystemConfig(&the_config);
282+
if (rc != FPC_RESULT_OK)
283+
{
284+
Serial.print("[ERROR]\tSet config request failed - error: ");
285+
Serial.println(rc);
286+
}
287+
else
288+
Serial.println("[INFO]\t\tSet config to the original value");
289+
configState = CONFIG_COMPLETE;
290+
}
291+
else if (configState == CONFIG_COMPLETE)
292+
{
293+
// Get the new value of the config to verify the set worked
294+
Serial.println("[INFO]\t\tRequesting final configuration...");
295+
// Request the configuration from the connected device.
296+
fpc_result_t rc = mySensor.requestGetSystemConfig(FPC_SYS_CFG_TYPE_DEFAULT);
297+
if (rc != FPC_RESULT_OK)
298+
{
299+
Serial.print("[ERROR]\tGet config request failed - error: ");
300+
Serial.println(rc);
301+
}
302+
else
303+
configState = CONFIG_EXIT;
304+
}
305+
}
306+
//------------------------------------------------------------------------------------
307+
// setup()
308+
//
309+
void setup()
310+
{
311+
delay(2000);
312+
313+
// Set up serial communication for debugging
314+
Serial.begin(115200); // Set baud rate to 115200
315+
while (!Serial)
316+
{
317+
; // Wait for serial port to connect. Needed for native USB port only
318+
}
319+
Serial.println();
320+
Serial.println("----------------------------------------------------------------");
321+
Serial.println(" SparkFun FPC2534 Fingerprint Config Example - SPI");
322+
Serial.println();
323+
Serial.println(" **NOTE** Currently the `setSystemConfig` command fails to set the updated values.");
324+
Serial.println();
325+
Serial.println("----------------------------------------------------------------");
326+
Serial.println();
327+
328+
// The internal UART buffer can fill up quickly and overflow. As such, increase its size.
329+
// This example is supporting ESP32 and RP2040 based boards - adjust as needed for other platforms.
330+
#if defined(ARDUINO_ARCH_RP2040)
331+
Serial1.setFIFOSize(512);
332+
#elif defined(ESP32)
333+
Serial1.setRxBufferSize(512);
334+
#endif
335+
336+
Serial1.begin(921600, SERIAL_8N1);
337+
delay(100);
338+
for (uint32_t startMS = millis(); !Serial1 && (millis() - startMS < 5000);) // Wait for the serial port to be ready
339+
delay(200);
340+
Serial.println("[STARTUP]\tSerial1 started for FPC2534 communication.");
341+
342+
// Reset the sensor to ensure it's in a known state - by default this also triggers the
343+
// sensor to send a status message
344+
reset_sensor();
345+
346+
// Initialize the sensor library
347+
if (!mySensor.begin(Serial1))
348+
{
349+
Serial.println("[ERROR]\tFPC2534 not found. Check wiring. HALT.");
350+
while (1)
351+
delay(1000);
352+
}
353+
Serial.println("[STARTUP]\tFPC2534 initialized.");
354+
355+
// setup our callback functions structure
356+
cmd_cb.on_error = on_error;
357+
cmd_cb.on_status = on_status;
358+
cmd_cb.on_is_ready_change = on_is_ready_change;
359+
cmd_cb.on_system_config_get = on_system_config_get;
360+
361+
// set the callbacks for the sensor library to call
362+
mySensor.setCallbacks(cmd_cb);
363+
364+
// Reset the sensor to start fresh
365+
reset_sensor();
366+
367+
// Ready to go!
368+
Serial.println("[STARTUP]\tFingerprint system initialized.");
369+
}
370+
371+
//------------------------------------------------------------------------------------
372+
void loop()
373+
{
374+
375+
// Call the library to process the next response from the sensor. The library will call our above
376+
// callback functions as events occur.
377+
fpc_result_t rc = mySensor.processNextResponse();
378+
if (rc != FPC_RESULT_OK && rc != FPC_PENDING_OPERATION)
379+
{
380+
Serial.print("[ERROR] Processing Error: ");
381+
Serial.println(rc);
382+
// Hmm - reset the sensor and start again?
383+
reset_sensor();
384+
}
385+
else if (deviceIdle)
386+
process_demo_steps();
387+
388+
delay(200);
389+
}

0 commit comments

Comments
 (0)