Program Listing for File bits.hpp
↰ Return to documentation for file (libspookyaction/include/pn532/bits.hpp
)
//
// Created by Pietro Saccardi on 20/12/2020.
//
#ifndef PN532_BITS_HPP
#define PN532_BITS_HPP
#include <array>
#include <cstddef>
#include <mlab/bin_data.hpp>
#include <vector>
namespace pn532 {
enum struct command_code : std::uint8_t {
diagnose = 0x00,
get_firmware_version = 0x02,
get_general_status = 0x04,
read_register = 0x06,
write_register = 0x08,
read_gpio = 0x0c,
write_gpio = 0x0e,
set_serial_baudrate = 0x10,
set_parameters = 0x12,
sam_configuration = 0x14,
power_down = 0x16,
rf_configuration = 0x32,
rf_regulation_test = 0x58,
in_jump_for_dep = 0x56,
in_jump_for_psl = 0x46,
in_list_passive_target = 0x4a,
in_atr = 0x50,
in_psl = 0x4e,
in_data_exchange = 0x40,
in_communicate_thru = 0x42,
in_deselect = 0x44,
in_release = 0x52,
in_select = 0x54,
in_autopoll = 0x60,
tg_init_as_target = 0x8c,
tg_set_general_bytes = 0x92,
tg_get_data = 0x86,
tg_set_data = 0x8e,
tg_set_metadata = 0x94,
tg_get_initiator_command = 0x88,
tg_response_to_initiator = 0x90,
tg_get_target_status = 0x8a
};
enum struct low_current_thr : std::uint8_t {
mA_25 = 0b10 << 4,
mA_35 = 0b11 << 4
};
enum struct high_current_thr : std::uint8_t {
mA_45 = 0b000 << 1,
mA_60 = 0b001 << 1,
mA_75 = 0b010 << 1,
mA_90 = 0b011 << 1,
mA_105 = 0b100 << 1,
mA_120 = 0b101 << 1,
mA_130 = 0b110 << 1,
mA_150 = 0b111 << 1
};
enum struct serial_baudrate : std::uint8_t {
baud9_600 = 0x00,
baud19_200 = 0x01,
baud38_400 = 0x02,
baud57_600 = 0x03,
baud115_200 = 0x04,
baud230_400 = 0x05,
baud460_800 = 0x06,
baud921_600 = 0x07,
baud1_288_000 = 0x08
};
enum struct rf_test_mode : std::uint8_t {
mifare_106kbps = 0b0000000,
mifare_212kbps = 0b0010000,
mifare_424kbps = 0b0100000,
mifare_848kbps = 0b0110000,
felica_106kbps = 0b0000010,
felica_212kbps = 0b0010010,
felica_424kbps = 0b0100010,
felica_848kbps = 0b0110010
};
enum struct rf_timeout : std::uint8_t {
none = 0x00,
us_100 = 0x01,
us_200 = 0x02,
us_400 = 0x03,
us_800 = 0x04,
ms_1_6 = 0x05,
ms_3_2 = 0x06,
ms_6_4 = 0x07,
ms_12_8 = 0x08,
ms_25_6 = 0x09,
ms_51_2 = 0x0a,
ms_102_4 = 0x0b,
ms_204_8 = 0x0c,
ms_409_6 = 0x0d,
ms_819_2 = 0x0e,
s_1_64 = 0x0f,
s_3_28 = 0x10
};
namespace reg {
struct ciu_212_424kbps {
std::uint8_t rf_cfg = 0x69;
std::uint8_t gs_n_on = 0xff;
std::uint8_t cw_gs_p = 0x3f;
std::uint8_t mod_gs_p = 0x11;
std::uint8_t demod_own_rf_on = 0x41;
std::uint8_t rx_threshold = 0x85;
std::uint8_t demod_own_rf_off = 0x61;
std::uint8_t gs_n_off = 0x6f;
};
struct ciu_106kbps_typea {
std::uint8_t rf_cfg = 0x59;
std::uint8_t gs_n_on = 0xf4;
std::uint8_t cw_gs_p = 0x3f;
std::uint8_t mod_gs_p = 0x11;
std::uint8_t demod_own_rf_on = 0x4d;
std::uint8_t rx_threshold = 0x85;
std::uint8_t demod_own_rf_off = 0x61;
std::uint8_t gs_n_off = 0x6f;
std::uint8_t mod_width = 0x26;
std::uint8_t mif_nfc = 0x62;
std::uint8_t tx_bit_phase = 0x87;
};
struct ciu_typeb {
std::uint8_t gs_n_on = 0xff;
std::uint8_t mod_gs_p = 0x17;
std::uint8_t rx_threshold = 0x85;
};
struct ciu_iso_iec_14443_4_at_baudrate {
std::uint8_t rx_threshold;
std::uint8_t mod_width;
std::uint8_t mif_nfc;
};
struct ciu_iso_iec_14443_4 {
ciu_iso_iec_14443_4_at_baudrate kbps212{0x85, 0x15, 0x8a};
ciu_iso_iec_14443_4_at_baudrate kbps424{0x85, 0x08, 0xb2};
ciu_iso_iec_14443_4_at_baudrate kbps848{0x85, 0x01, 0xda};
};
enum struct sfr_register : std::uint8_t {
pcon = 0x87,
rwl = 0x9a,
twl = 0x9b,
fifofs = 0x9c,
fifoff = 0x9d,
sff = 0x9e,
fit = 0x9f,
fiten = 0xa1,
fdata = 0xa2,
fsize = 0xa3,
ie0 = 0xa8,
spicontrol = 0xa9,
spistatus = 0xaa,
hsu_sta = 0xab,
hsu_ctr = 0xac,
hsu_pre = 0xad,
hsu_cnt = 0xae,
p3 = 0xb0,
ip0 = 0xb8,
ciu_command = 0xd1,
ien1 = 0xe8,
p7cfga = 0xf4,
p7cfgb = 0xf5,
p7 = 0xf7,
ip1 = 0xf8,
p3cfga = 0xfc,
p3cfgb = 0xfd
};
struct addr : public std::array<std::uint8_t, 2> {
inline addr(sfr_register sfr_reg);
explicit inline addr(std::uint16_t xram_mmap_reg);
};
}// namespace reg
enum struct baudrate : std::uint8_t {
kbps106 = 0x0,
kbps212 = 0x1,
kbps424 = 0x2
};
enum struct modulation : std::uint8_t {
mifare_iso_iec_14443_3_type_ab_iso_iec_18092_passive_kbps106 = 0x00,
felica_iso_iec_18092_kbps212_424 = 0x10,
iso_iec_18092_active = 0x01,
innovision_jewel_tag = 0x02
};
enum struct sam_mode : std::uint8_t {
normal = 0x01,
virtual_card = 0x02,
wired_card = 0x03,
dual_card = 0x04
};
enum struct wakeup_source : std::uint8_t {
i2c = 1 << 7,
gpio = 1 << 6,
spi = 1 << 5,
hsu = 1 << 4,
rf = 1 << 3,
int1 = 1 << 1,
int0 = 1 << 0
};
enum struct nfcip1_picc_status : std::uint8_t {
nfcip1_idle = 0x00,
nfcip1_activated = 0x01,
nfcip1_deselected = 0x02,
picc_released = 0x80,
picc_activated = 0x81,
picc_deselected = 0x82
};
enum struct internal_error_code : std::uint8_t {
none = 0x00,
timeout = 0x01,
crc_error = 0x02,
parity_error = 0x3,
erroneous_bit_count = 0x04,
framing_error = 0x05,
bit_collision = 0x06,
buffer_size_insufficient = 0x07,
rf_buffer_overflow = 0x09,
counterpart_rf_off = 0x0a,
rf_protocol_error = 0x0b,
temperature_error = 0x0d,
buffer_overflow = 0x0e,
invalid_parameter = 0x10,
dep_unsupported_command = 0x12,
specification_mismatch = 0x13,
mifare_auth_error = 0x14,
wrong_uid_check_byte = 0x23,
dep_invalid_device_state = 0x25,
operation_not_allowed = 0x26,
command_not_acceptable = 0x27,
released_by_initiator = 0x29,
card_exchanged = 0x2a,
card_disappeared = 0x2b,
nfcid3_initiator_target_mismatch = 0x2c,
overcurrent = 0x2d,
nad_missing_in_dep_frame = 0x2e
};
enum struct polling_method : std::uint8_t {
timeslot = 0x00,
probabilistic = 0x01
};
enum struct baudrate_modulation : std::uint8_t {
kbps106_iso_iec_14443_typea = 0x00,
kbps212_felica = 0x01,
kbps424_felica = 0x02,
kbps106_iso_iec_14443_3_typeb = 0x03,
kbps106_innovision_jewel_tag = 0x04
};
enum struct poll_period : std::uint8_t {
ms_150 = 0x1,
ms_300 = 0x2,
ms_450 = 0x3,
ms_600 = 0x4,
ms_750 = 0x5,
ms_900 = 0x6,
ms_1050 = 0x7,
ms_1200 = 0x8,
ms_1350 = 0x9,
ms_1500 = 0xa,
ms_1650 = 0xb,
ms_1800 = 0xc,
ms_1950 = 0xd,
ms_2100 = 0xe,
ms_2250 = 0xf
};
enum struct target_type : std::uint8_t {
generic_passive_106kbps = 0x00,
generic_passive_212kbps = 0x01,
generic_passive_424kbps = 0x02,
passive_106kbps_iso_iec_14443_4_typeb = 0x03,
innovision_jewel_tag = 0x04,
mifare_classic_ultralight = 0x10,
felica_212kbps_card = 0x11,
felica_424kbps_card = 0x12,
passive_106kbps_iso_iec_14443_4_typea = 0x20,
passive_106kbps_iso_iec_14443_4_typeb_alt = 0x23,
dep_passive_106kbps = 0x40,
dep_passive_212kbps = 0x41,
dep_passive_424kbps = 0x42,
dep_active_106kbps = 0x80,
dep_active_212kbps = 0x81,
dep_active_424kbps = 0x82
};
[[nodiscard]] constexpr baudrate_modulation baudrate_modulation_of(target_type target);
[[nodiscard]] constexpr baudrate baudrate_of(target_type target);
[[nodiscard]] constexpr modulation modulation_of(target_type target);
template <std::size_t Length>
struct nfcid_cascade_tag {};
using nfcid_1t = mlab::tagged_array<nfcid_cascade_tag<4>, 4>;
using nfcid_2t = mlab::tagged_array<nfcid_cascade_tag<7>, 7>;
using nfcid_3t = mlab::tagged_array<nfcid_cascade_tag<10>, 10>;
struct atr_res_info {
nfcid_3t nfcid;
std::uint8_t did_t;
std::uint8_t b_st;
std::uint8_t b_rt;
std::uint8_t to;
std::uint8_t pp_t;
std::vector<std::uint8_t> g_t;
};
enum struct framing_as_target : std::uint8_t {
mifare = 0b00,
active_mode = 0b01,
felica = 0b10
};
template <baudrate_modulation>
struct target {
};
struct target_logical_index {
std::uint8_t logical_index;
};
template <>
struct target<baudrate_modulation::kbps106_iso_iec_14443_typea> : public target_logical_index {
using target_logical_index::logical_index;
std::array<std::uint8_t, 2> sens_res;
std::uint8_t sel_res;
std::vector<std::uint8_t> nfcid;
std::vector<std::uint8_t> ats;
};
template <>
struct target<baudrate_modulation::kbps212_felica> : public target_logical_index {
using target_logical_index::logical_index;
std::array<std::uint8_t, 8> nfcid_2t;
std::array<std::uint8_t, 8> pad;
std::array<std::uint8_t, 2> syst_code;
};
template <>
struct target<baudrate_modulation::kbps424_felica> : public target_logical_index {
using target_logical_index::logical_index;
std::array<std::uint8_t, 8> nfcid_2t;
std::array<std::uint8_t, 8> pad;
std::array<std::uint8_t, 2> syst_code;
};
template <>
struct target<baudrate_modulation::kbps106_iso_iec_14443_3_typeb> : public target_logical_index {
using target_logical_index::logical_index;
std::array<std::uint8_t, 12> atqb_response;
std::vector<std::uint8_t> attrib_res;
};
template <>
struct target<baudrate_modulation::kbps106_innovision_jewel_tag> : public target_logical_index {
using target_logical_index::logical_index;
std::array<std::uint8_t, 2> sens_res;
nfcid_1t jewel_id;
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace bits {
template <std::uint8_t MinIdx, std::uint8_t MaxIdx>
static constexpr std::uint8_t bitmask_window = (0xff >> (7 + MinIdx - MaxIdx)) << MinIdx;
static constexpr std::uint8_t preamble = 0x00;
static constexpr std::uint8_t postamble = 0x00;
enum struct transport : std::uint8_t {
host_to_pn532 = 0xd4,
pn532_to_host = 0xd5
};
static constexpr std::uint8_t specific_app_level_err_code = 0x7f;
static constexpr std::array<std::uint8_t, 2> start_of_packet_code = {0x00, 0xff};
static constexpr std::array<std::uint8_t, 2> ack_packet_code = {0x00, 0xff};
static constexpr std::array<std::uint8_t, 2> nack_packet_code = {0xff, 0x00};
static constexpr std::array<std::uint8_t, 2> fixed_extended_packet_length = {0xff, 0xff};
static constexpr std::size_t max_firmware_data_length = 263;
static constexpr std::uint8_t firmware_iso_iec_14443_typea_mask = 0b0001;
static constexpr std::uint8_t firmware_iso_iec_14443_typeb_mask = 0b0010;
static constexpr std::uint8_t firmware_iso_18092_mask = 0b0100;
static constexpr unsigned echo_back_reply_delay_steps_per_ms = 2;
enum struct test : std::uint8_t {
comm_line = 0x0,
rom = 0x1,
ram = 0x2,
poll_target = 0x4,
echo_back = 0x5,
attention_req_or_card_presence = 0x6,
self_antenna = 0x7
};
static constexpr std::uint8_t reg_andet_control_low_current_mask = bitmask_window<4, 5>;
static constexpr std::uint8_t reg_andet_control_high_current_mask = bitmask_window<1, 3>;
static constexpr std::uint8_t reg_andet_control_too_low_power_mask = 1 << 7;
static constexpr std::uint8_t reg_andet_control_too_high_power_mask = 1 << 6;
static constexpr std::uint8_t reg_andet_control_antenna_detect_mask = 1 << 0;
static constexpr std::uint8_t rf_configuration_field_auto_rfca_mask = 0b10;
static constexpr std::uint8_t rf_configuration_field_auto_rf_on_mask = 0b01;
enum struct rf_config_item : std::uint8_t {
rf_field = 0x01,
timings = 0x02,
max_rty_com = 0x04,
max_retries = 0x05,
analog_106kbps_typea = 0x0a,
analog_212_424kbps = 0x0b,
analog_typeb = 0x0c,
analog_iso_iec_14443_4 = 0x0d
};
static constexpr unsigned status_as_target_initiator_speed_shift = 4;
static constexpr unsigned status_as_target_target_speed_shift = 0;
static constexpr std::uint8_t baudrate_mask = 0b111;
static constexpr unsigned sam_timeout_unit_ms = 50;
static constexpr std::uint8_t status_nad_mask = 0x1 << 7;
static constexpr std::uint8_t status_more_info_mask = 0x1 << 6;
static constexpr std::uint8_t status_error_mask = 0b00111111;
static constexpr std::uint8_t sam_status_neg_pulse_on_clad_line_bit = 1 << 0;
static constexpr std::uint8_t sam_status_detected_rf_field_off_bit = 1 << 1;
static constexpr std::uint8_t sam_status_timeout_after_sig_act_irq_bit = 1 << 2;
static constexpr std::uint8_t sam_status_clad_line_high_bit = 1 << 7;
static constexpr std::uint8_t parameters_use_nad_data_bit = 1 << 0;
static constexpr std::uint8_t parameters_use_did_data_bit = 1 << 1;
static constexpr std::uint8_t parameters_auto_generate_atr_res_bit = 1 << 2;
static constexpr std::uint8_t parameters_auto_generate_rats_bit = 1 << 4;
static constexpr std::uint8_t parameters_enable_iso_14443_4_picc_emulation_bit = 1 << 5;
static constexpr std::uint8_t parameters_remove_pre_post_amble_bit = 1 << 6;
static constexpr std::uint8_t max_num_targets = 2;
static constexpr std::uint8_t uid_cascade_tag = 0x88;
static constexpr unsigned autopoll_max_types = 15;
static constexpr std::uint8_t target_type_baudrate_modulation_mask = 0b111;
static constexpr unsigned init_as_target_res_baudrate_shift = 4;
static constexpr std::uint8_t init_as_target_res_picc_bit = 1 << 3;
static constexpr std::uint8_t init_as_target_res_dep_bit = 1 << 2;
static constexpr std::uint8_t framing_mask = 0b11;
static constexpr std::uint8_t init_as_target_picc_only_bit = 1 << 2;
static constexpr std::uint8_t init_as_target_dep_only_bit = 1 << 1;
static constexpr std::uint8_t init_as_target_passive_only_bit = 1 << 0;
[[maybe_unused]] static constexpr std::uint8_t sel_res_dep_mask = 0x40;
[[maybe_unused]] static constexpr std::uint8_t sel_res_picc_mask = 0x60;
static constexpr std::size_t init_as_target_general_info_max_length = 47;
static constexpr std::size_t init_as_target_historical_bytes_max_length = 48;
static constexpr std::uint8_t in_atr_nfcid_3t_present_mask = 0b01;
static constexpr std::uint8_t in_atr_general_info_present_mask = 0b10;
static constexpr std::uint8_t in_jump_for_dep_passive_init_data_present_mask = 0b001;
static constexpr std::uint8_t in_jump_for_dep_nfcid_3t_present_mask = 0b010;
static constexpr std::uint8_t in_jump_for_dep_general_info_present_mask = 0b100;
static constexpr std::size_t general_info_max_length = 48;
static constexpr std::uint8_t gpio_p3_pin_mask = bitmask_window<0, 5>;
static constexpr std::uint8_t gpio_p7_pin_mask = bitmask_window<1, 2>;
static constexpr std::uint8_t gpio_i0i1_pin_mask = 0x00;// Cannot set i0i1
static constexpr std::uint8_t gpio_write_validate_max = 1 << 7;
static constexpr std::uint8_t sfr_registers_high = 0xff;
struct reg_antenna_detector {
bool detected_low_pwr;
bool detected_high_pwr;
pn532::low_current_thr low_current_threshold;
pn532::high_current_thr high_current_threshold;
bool enable_detection;
};
}// namespace bits
#endif
}// namespace pn532
namespace pn532 {
constexpr baudrate_modulation baudrate_modulation_of(target_type target) {
return static_cast<baudrate_modulation>(static_cast<std::uint8_t>(target) & bits::target_type_baudrate_modulation_mask);
}
constexpr baudrate baudrate_of(target_type target) {
switch (baudrate_modulation_of(target)) {
case baudrate_modulation::kbps212_felica:
return baudrate::kbps212;
case baudrate_modulation::kbps424_felica:
return baudrate::kbps424;
default:
return baudrate::kbps106;
}
}
constexpr modulation modulation_of(target_type target) {
switch (baudrate_modulation_of(target)) {
case baudrate_modulation::kbps106_iso_iec_14443_typea:
[[fallthrough]];
case baudrate_modulation::kbps106_iso_iec_14443_3_typeb:
return modulation::mifare_iso_iec_14443_3_type_ab_iso_iec_18092_passive_kbps106;
case baudrate_modulation::kbps212_felica:
[[fallthrough]];
case baudrate_modulation::kbps424_felica:
return modulation::felica_iso_iec_18092_kbps212_424;
case baudrate_modulation::kbps106_innovision_jewel_tag:
return modulation::innovision_jewel_tag;
}
return modulation::iso_iec_18092_active;
}
namespace reg {
addr::addr(reg::sfr_register sfr_reg)
: std::array<std::uint8_t, 2>{{bits::sfr_registers_high, static_cast<std::uint8_t>(sfr_reg)}} {}
addr::addr(std::uint16_t xram_mmap_reg)
: std::array<std::uint8_t, 2>{{std::uint8_t(xram_mmap_reg >> 8),
std::uint8_t(xram_mmap_reg & 0xff)}} {}
}// namespace reg
}// namespace pn532
#endif//PN532_BITS_HPP