21#ifndef GROVE_RFID_READER_HH
22#define GROVE_RFID_READER_HH
27#include "../interrupts.h"
29#include "../streambuf.h"
30#include "../streams.h"
32#include "../uart_commons.h"
49#define REGISTER_GROVE_RFID_READER_INT_ISR(DATA0_INT, DATA1_INT, READER) \
50 ISR(CAT3(INT, DATA0_INT, _vect)) \
52 devices::rfid::isr_handler_grove::callback_fall_0<DATA0_INT, DATA1_INT, READER>(); \
54 ISR(CAT3(INT, DATA1_INT, _vect)) \
56 devices::rfid::isr_handler_grove::callback_fall_1<DATA0_INT, DATA1_INT, READER>(); \
71#define REGISTER_GROVE_RFID_READER_PCI_ISR(DATA01_PCI, READER) \
72 ISR(CAT3(PCINT, DATA01_PCI, _vect)) \
74 devices::rfid::isr_handler_grove::callback_fall_0_or_1<DATA01_PCI, READER>(); \
120 static constexpr uint16_t UART_SPEED = 9600;
123 static_assert(serial::UART_trait<UART_>::IS_UART,
"UART template argument must be a serial device");
124 static_assert(serial::UART_trait<UART_>::HAS_RX,
"UART template argument must be a serial device with RX mode");
209 while (in_.
get() != STX)
217 static constexpr char STX = 0x02;
218 static constexpr char ETX = 0x03;
251 template<board::ExternalInterruptPin DATA0_, board::ExternalInterruptPin DATA1_>
256 static_assert(DATA0 != DATA1,
"DATA0 and DATA1 must be two distinct pins");
360 protocols::Wiegand wiegand_;
362 friend struct isr_handler_grove;
393 template<board::InterruptPin DATA0_, board::InterruptPin DATA1_>
400 using DATA0_TRAIT = board_traits::DigitalPin_trait<DATA0_PIN>;
402 using DATA1_TRAIT = board_traits::DigitalPin_trait<DATA1_PIN>;
405 static_assert(DATA0 != DATA1,
"DATA0 and DATA1 must be two distinct pins");
406 static_assert(DATA0_TRAIT::PORT == DATA1_TRAIT::PORT,
"DATA0 and DATA1 must be on the same port");
430 enabler_.set_enable_pins(PCI_MASK);
499 else if (!data1_.value())
503 static constexpr uint8_t PCI_MASK =
bits::BV8(DATA0_TRAIT::BIT, DATA1_TRAIT::BIT);
507 DATA_SIGNAL enabler_;
508 protocols::Wiegand wiegand_;
510 friend struct isr_handler_grove;
515 template<
typename READER>
struct Grove125KHzRFIDReader_trait
517 static constexpr bool IS_GROVE_125_READER =
false;
518 static constexpr bool IS_UART_MODE =
false;
519 static constexpr bool IS_WIEGAND_MODE =
false;
520 static constexpr bool IS_PCI =
false;
521 static constexpr bool IS_EXT =
false;
522 static constexpr bool USES_DISTINCT_PINS =
false;
524 template<
typename UART>
struct Grove125KHzRFIDReader_trait<Grove125KHzRFIDReaderUART<UART>>
526 static constexpr bool IS_GROVE_125_READER =
true;
527 static constexpr bool IS_UART_MODE =
true;
528 static constexpr bool IS_WIEGAND_MODE =
false;
529 static constexpr bool IS_PCI =
false;
530 static constexpr bool IS_EXT =
false;
531 static constexpr bool USES_DISTINCT_PINS =
false;
533 template<board::ExternalInterruptPin DATA0, board::ExternalInterruptPin DATA1>
534 struct Grove125KHzRFIDReader_trait<Grove125KHzRFIDReaderWiegandEXT<DATA0, DATA1>>
536 static constexpr bool IS_GROVE_125_READER =
true;
537 static constexpr bool IS_UART_MODE =
false;
538 static constexpr bool IS_WIEGAND_MODE =
true;
539 static constexpr bool IS_PCI =
false;
540 static constexpr bool IS_EXT =
true;
541 static constexpr bool USES_DISTINCT_PINS = (DATA0 != DATA1);
543 template<board::InterruptPin DATA0, board::InterruptPin DATA1>
544 struct Grove125KHzRFIDReader_trait<Grove125KHzRFIDReaderWiegandPCI<DATA0, DATA1>>
546 static constexpr bool IS_GROVE_125_READER =
true;
547 static constexpr bool IS_UART_MODE =
false;
548 static constexpr bool IS_WIEGAND_MODE =
true;
549 static constexpr bool IS_PCI =
true;
550 static constexpr bool IS_EXT =
false;
551 static constexpr bool USES_DISTINCT_PINS = (DATA0 != DATA1);
556 struct isr_handler_grove
558 template<u
int8_t DATA0_NUM, u
int8_t DATA1_NUM,
typename READER>
559 static void callback_fall_0()
562 using GROVE_TRAIT = Grove125KHzRFIDReader_trait<READER>;
563 static_assert(GROVE_TRAIT::IS_GROVE_125_READER,
"READER must be a Grove125KHzRFIDReaderWiegandEXT type");
564 static_assert(GROVE_TRAIT::IS_WIEGAND_MODE,
"READER must be a Grove125KHzRFIDReaderWiegandEXT type");
565 static_assert(GROVE_TRAIT::IS_EXT,
"READER must be a Grove125KHzRFIDReaderWiegandEXT type");
567 interrupt::isr_handler_int::check_int_pin<DATA0_NUM, READER::DATA0>();
568 interrupt::isr_handler_int::check_int_pin<DATA1_NUM, READER::DATA1>();
569 static_assert(DATA0_NUM != DATA1_NUM,
"DATA0 and DATA1 must be two distinct pins");
571 interrupt::CallbackHandler<void (READER::*)(), &READER::fall_0>::call();
574 template<u
int8_t DATA0_NUM, u
int8_t DATA1_NUM,
typename READER>
575 static void callback_fall_1()
578 using GROVE_TRAIT = Grove125KHzRFIDReader_trait<READER>;
579 static_assert(GROVE_TRAIT::IS_GROVE_125_READER,
"READER must be a Grove125KHzRFIDReaderWiegandEXT type");
580 static_assert(GROVE_TRAIT::IS_WIEGAND_MODE,
"READER must be a Grove125KHzRFIDReaderWiegandEXT type");
581 static_assert(GROVE_TRAIT::IS_EXT,
"READER must be a Grove125KHzRFIDReaderWiegandEXT type");
583 interrupt::isr_handler_int::check_int_pin<DATA0_NUM, READER::DATA0>();
584 interrupt::isr_handler_int::check_int_pin<DATA1_NUM, READER::DATA1>();
585 static_assert(DATA0_NUM != DATA1_NUM,
"DATA0 and DATA1 must be two distinct pins");
587 interrupt::CallbackHandler<void (READER::*)(), &READER::fall_1>::call();
590 template<u
int8_t DATA01_NUM,
typename READER>
591 static void callback_fall_0_or_1()
594 using GROVE_TRAIT = Grove125KHzRFIDReader_trait<READER>;
595 static_assert(GROVE_TRAIT::IS_GROVE_125_READER,
"READER must be a Grove125KHzRFIDReaderWiegandPCI type");
596 static_assert(GROVE_TRAIT::IS_WIEGAND_MODE,
"READER must be a Grove125KHzRFIDReaderWiegandPCI type");
597 static_assert(GROVE_TRAIT::IS_PCI,
"READER must be a Grove125KHzRFIDReaderWiegandPCI type");
599 static_assert(GROVE_TRAIT::USES_DISTINCT_PINS,
"DATA0 and DATA1 must be two distinct pins");
600 interrupt::isr_handler_pci::check_pci_pins<DATA01_NUM, READER::DATA0, READER::DATA1>();
602 interrupt::CallbackHandler<void (READER::*)(), &READER::fall_0_or_1>::call();
bool available_() const
Check if data is available, i.e.
DATA_TYPE get_data_() const
Get data read from access control device.
static constexpr uint8_t DATA_BITS
The actual number of bits of data in DATA_TYPE.
bool valid_() const
Check if current data is valid, i.e.
void reset()
Reset current read state of this instance.
void on_falling_data0()
Your device shall call this method whenever DATA0 line level is falling to 0, which means a 0 bit mus...
void on_falling_data1()
Your device shall call this method whenever DATA1 line level is falling to 0, which means a 1 bit mus...
uint32_t DATA_TYPE
The data type used to return data read from the access control device.
Support for seeedstudio Grove 125KHz RFID Reader in UART mode.
UART_ UART
The UART type used to communicate with the Grove device.
void begin()
Start operations of the device.
Grove125KHzRFIDReaderUART(UART &uart)
Construct a new Grove 125KHz RFID Reader UART instance.
void end()
Stop operations of the device.
void get_data(char *data, uint8_t size)
Get complete data as ASCII C-string from the Grove device.
bool has_data()
Check if data from Grove device is ready to read.
Support for seeedstudio Grove 125KHz RFID Reader in Wiegand mode.
void end()
Stop operations of the device.
typename protocols::Wiegand::DATA_TYPE DATA_TYPE
The data type used to return data read from the Grove device.
bool has_data()
Check if data from Grove device is ready to read and valid (correct parity).
static constexpr uint8_t DATA_BITS
The actual number of bits of data in DATA_TYPE.
void begin()
Start operations of the device.
Grove125KHzRFIDReaderWiegandEXT()
Construct a new Grove 125KHz RFID Reader instance in Wiegand mode, where wires are connected to board...
void get_data(DATA_TYPE &data)
Get complete data as a DATA_TYPE value (integral type) from the Grove device.
Support for seeedstudio Grove 125KHz RFID Reader in Wiegand mode.
typename protocols::Wiegand::DATA_TYPE DATA_TYPE
The data type used to return data read from the Grove device.
void end()
Stop operations of the device.
void get_data(DATA_TYPE &data)
Get complete data as a DATA_TYPE value (integral type) from the Grove device.
Grove125KHzRFIDReaderWiegandPCI()
Construct a new Grove 125KHz RFID Reader instance in Wiegand mode, where wires are connected to board...
static constexpr uint8_t DATA_BITS
The actual number of bits of data in DATA_TYPE.
void begin()
Start operations of the device.
bool has_data()
Check if data from Grove device is ready to read and valid (correct parity).
Handler of an External Interrupt.
void disable()
Disable interrupts for this external interrupt pin.
void enable()
Enable interrupts for this external interrupt pin.
Input stream wrapper to provide formatted input API, a la C++.
int get()
Extract a single character from this input stream.
istream & getline(char *str, size_t n, char delim='\n')
Extract characters from this input stream and stores them as a C-string, until either (n - 1) charact...
Input API based on a ring buffer.
static const int EOF
Special value returned by sbumpc() when buffer is empty.
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
DigitalPin
Defines all available digital input/output pins of the target MCU.
InterruptPin
Defines all digital output pins of target MCU, usable as pin change interrupt (PCI) pins.
ExternalInterruptPin
Defines all digital output pins of target MCU, usable as direct external interrupt pins.
This namespace contains classes to support various RFID devices.
Defines all API for all external devices supported by FastArduino.
typename FastPinType< DPIN_ >::TYPE FAST_PIN
Useful alias type to the FastPin type matching a given board::DigitalPin.
typename FastPinType< board::EXT_PIN< EPIN_ >()>::TYPE FAST_EXT_PIN
Useful alias type to the FastPin type matching a given board::ExternalInterruptPin.
@ INPUT_PULLUP
Digital pin is configured as input with an internal pullup resistor.
@ FALLING_EDGE
Interrupt is triggered whenever pin level is falling from high to low.
typename PCIType< PIN >::TYPE PCI_SIGNAL
Useful alias type to the PCISignal type matching a given board::InterruptPin.
void register_handler(Handler &handler)
Register a class instance containing methods that shall be called back by an ISR.
@ CLEAR
Stop transmission immediately, clear buffer.
void yield()
Utility method used by many FastArduino API in order to "yield" some processor time; concretely it ju...
Common types used by 3D sensors (e.g.