#define AUTOCONF_INCLUDED #define CONFIG_TIMER_ONESHOT 1 #define CONFIG_USB_AT90USB1287 1 #define CONFIG_GPT_AT90USB1287 1 #define CONFIG_SPI_AT90USB1287 1 #define CONFIG_TEXT_ROM_BASE 0x0 #define CONFIG_PRODUCT_ID 5 #define CONFIG_USBD_XFR_MASS 1 #define CONFIG_LPS_WEIGHT 8 #define CONFIG_SPI_MASTER 1 #define CONFIG_MAX_TIMERS 1 #define CONFIG_MAX_STATES 2 #define CONFIG_ARCH "avr" #define CONFIG_INPUT_NONE 1 #define CONFIG_USB_AT90USB1287_MAX_ENDPS 5 #define CONFIG_PN53X_DEBUG 1 #define CONFIG_USB_DEV 1 #define CONFIG_DEBUG_PANIC 1 #define CONFIG_PANIC_DEBUG 1 #define CONFIG_ARCH_AT90USB1287 1 #define CONFIG_UART 1 #define CONFIG_USB_AT90USB1287_DEV 1 #define CONFIG_VENDOR_NAME "Soliton" #define CONFIG_DEBUG_PRINT 1 #define CONFIG_UART_AT90USB1287 1 #define CONFIG_USBD_MAX_INTFS 1 #define CONFIG_USBD_XFR_ASYNC 1 #define CONFIG_CPU_8v51 1 #define CONFIG_PN53X 1 #define CONFIG_AVR_MEGA 1 #define CONFIG_DEBUG 1 #define CONFIG_MAX_VECTORS 3 #define CONFIG_CC_OPT_SIZE 1 #define CONFIG_SPI_AT90USB1287_FREQ_4M 1 #define CONFIG_CPU_AT90USB1287_FREQ_8M 1 #define CONFIG_AVR_ENHANCED 1 #define CONFIG_CPU_8 1 #define CONFIG_TIMER 1 #define CONFIG_BIT_FFS16 1 #define CONFIG_BIT_FLS16 1 #define CONFIG_OUTPUT_UART 1 #define CONFIG_EXPERIMENTAL 1 #define CONFIG_CPU_ATMEGA128 1 #define CONFIG_SPI_MAX_DEVICES 2 #define CONFIG_SYS_POLL 1 #define CONFIG_UART_38400 1 #define CONFIG_PRODUCT_NAME "USB PN532" #define CONFIG_ARCH_HAS_USB 1 #define CONFIG_ARCH_HAS_TSC 1 #define CONFIG_ARCH_HAS_GPT 1 #define CONFIG_ARCH_HAS_SPI 1 #define CONFIG_USB_PN53X 1 #define CONFIG_USB_DEBUG 1 #define CONFIG_VENDOR_ID 990 #define CONFIG_SERIAL_NO 0 #define CONFIG_TSC_AT90USB1287_FREQ_125K 1 #define CONFIG_UNAME_RELEASE "1.7.9(0.237/5/3)" #define CONFIG_ARCH_IS_TICKLESS 1 #define CONFIG_KERNELVERSION "1.0.0.0" #define CONFIG_AVR 1 #define CONFIG_USB 1 #define CONFIG_ARCH_HAS_USB_OTG 1 #define CONFIG_SPI 1 #define CONFIG_ARCH_HAS_UART 1 #define CONFIG_PN53X_STUB 1 #define CONFIG_TEXT_RAM_BASE 0x0 #define CONFIG_AVR_2_BYTE_PC 1 #ifdef __CHECKER__ # define __safe __attribute__((safe)) # define __force __attribute__((force)) # define __nocast __attribute__((nocast)) # define __iomem __attribute__((noderef, address_space(2))) #else # define __safe # define __force # define __nocast # define __iomem #endif #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) # define __INTR_ATTRS used, externally_visible #else /* GCC < 4.1 */ # define __INTR_ATTRS used #endif #ifdef CONFIG_CC_ISR_VECTOR #define DEFINE_ISR(vector, ...) \ void vector(void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__;\ void vector(void) #define _VECTOR(N) __vector_ ## N #endif #define ISR_BLOCK #define ISR_NOBLOCK __attribute__((interrupt)) #define ISR_NAKED __attribute__((naked)) #define ISR_ALIASOF(v) __attribute__((alias(__STRINGIFY(v)))) #define ULL(x) x##ULL #define __packed __attribute__((packed)) #define __always_inline inline __attribute__((always_inline)) typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed long int32_t; typedef unsigned long uint32_t; #define __text__ __attribute__((__progmem__)) #define __near__ #define __far__ #define __TEXT_TYPE__(type, name) \ typedef type name /* this can not work with structures, and need special wrappers using * LPM/ELPM instructions accessing program space * #define __TEXT_TYPE__(type, name) \ * typedef type name __text__ */ typedef uint16_t caddr_t; #define ARCH_HAVE_CADDR_T 1 typedef uint16_t size_t; #define ARCH_HAVE_SIZE_T 1 typedef uint8_t boolean; typedef unsigned short wchar_t; #ifndef ARCH_HAVE_UINT64_T typedef unsigned long long uint64_t; #endif #ifndef ARCH_HAVE_CADDR_T typedef uint16_t caddr_t; #endif #ifndef ARCH_HAVE_SIZE_T typedef uint32_t size_t; #endif #ifndef NULL #define NULL ((void *)0L) #endif /* NULL */ #define false (unsigned char)0 #define true !false #define _BV(bit) (1 << (bit)) __TEXT_TYPE__(char, text_char_t); __TEXT_TYPE__(uint8_t, text_byte_t); __TEXT_TYPE__(uint16_t, text_word_t); __TEXT_TYPE__(uint32_t, text_quad_t); int text_strlen(const text_char_t *str); void memory_set(caddr_t s, uint8_t c, size_t count); void memory_copy(caddr_t dest, const caddr_t src, size_t count); typedef uint8_t bits_t; #define BITS_PER_UNIT 8 #define BITS_TO_UNITS(bits) \ (((uint8_t)((bits)+BITS_PER_UNIT-1))/((uint8_t)BITS_PER_UNIT)) #define DECLARE_BITMAP(name, bits) \ bits_t name[BITS_TO_UNITS(bits)] #define BITOP_MASK(nr) ((uint8_t)1 << ((nr) % BITS_PER_UNIT)) #define BITOP_WORD(nr) ((uint8_t)(nr) / (uint8_t)BITS_PER_UNIT) void set_bit(uint8_t nr, bits_t *addr); void clear_bit(uint8_t nr, bits_t *addr); boolean test_bit(uint8_t nr, const bits_t *addr); #define find_first_set_bit(addr, size) \ find_next_set_bit((addr), (size), 0) #define find_first_clear_bit(addr, size) \ find_next_clear_bit((addr), (size), 0) uint8_t find_next_set_bit(const bits_t *addr, uint8_t size, uint8_t offset); uint8_t find_next_clear_bit(const bits_t *addr, uint8_t size, uint8_t offset); #define ALIGN(x,a) __ALIGN_MASK(x,(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) uint8_t __ffs8(uint8_t word); uint8_t __ffs16(uint16_t word); uint8_t __fls8(uint8_t x); uint8_t __fls16(uint16_t word); uint8_t __fls32(uint32_t word); #define __ffz8(x) __ffs8((uint8_t)(~(x))) #define __ffz16(x) __ffz8((uint16_t)(~(x))) uint32_t __roundup32(uint32_t n); uint32_t __rounddown32(uint32_t n); uint16_t __roundup16(uint16_t n); #define __ilog2_u8(n) __fls8(n) #define __ilog2_u16(n) __fls16(n) #define __ilog2_u32(n) __fls32(n) extern uint8_t ____ilog2_NaN(void); #define ilog2_const(n) \ ( \ (n) < 1 ? ____ilog2_NaN() : \ (n) & (ULL(1) << 63) ? 63 : \ (n) & (ULL(1) << 62) ? 62 : \ (n) & (ULL(1) << 61) ? 61 : \ (n) & (ULL(1) << 60) ? 60 : \ (n) & (ULL(1) << 59) ? 59 : \ (n) & (ULL(1) << 58) ? 58 : \ (n) & (ULL(1) << 57) ? 57 : \ (n) & (ULL(1) << 56) ? 56 : \ (n) & (ULL(1) << 55) ? 55 : \ (n) & (ULL(1) << 54) ? 54 : \ (n) & (ULL(1) << 53) ? 53 : \ (n) & (ULL(1) << 52) ? 52 : \ (n) & (ULL(1) << 51) ? 51 : \ (n) & (ULL(1) << 50) ? 50 : \ (n) & (ULL(1) << 49) ? 49 : \ (n) & (ULL(1) << 48) ? 48 : \ (n) & (ULL(1) << 47) ? 47 : \ (n) & (ULL(1) << 46) ? 46 : \ (n) & (ULL(1) << 45) ? 45 : \ (n) & (ULL(1) << 44) ? 44 : \ (n) & (ULL(1) << 43) ? 43 : \ (n) & (ULL(1) << 42) ? 42 : \ (n) & (ULL(1) << 41) ? 41 : \ (n) & (ULL(1) << 40) ? 40 : \ (n) & (ULL(1) << 39) ? 39 : \ (n) & (ULL(1) << 38) ? 38 : \ (n) & (ULL(1) << 37) ? 37 : \ (n) & (ULL(1) << 36) ? 36 : \ (n) & (ULL(1) << 35) ? 35 : \ (n) & (ULL(1) << 34) ? 34 : \ (n) & (ULL(1) << 33) ? 33 : \ (n) & (ULL(1) << 32) ? 32 : \ (n) & (ULL(1) << 31) ? 31 : \ (n) & (ULL(1) << 30) ? 30 : \ (n) & (ULL(1) << 29) ? 29 : \ (n) & (ULL(1) << 28) ? 28 : \ (n) & (ULL(1) << 27) ? 27 : \ (n) & (ULL(1) << 26) ? 26 : \ (n) & (ULL(1) << 25) ? 25 : \ (n) & (ULL(1) << 24) ? 24 : \ (n) & (ULL(1) << 23) ? 23 : \ (n) & (ULL(1) << 22) ? 22 : \ (n) & (ULL(1) << 21) ? 21 : \ (n) & (ULL(1) << 20) ? 20 : \ (n) & (ULL(1) << 19) ? 19 : \ (n) & (ULL(1) << 18) ? 18 : \ (n) & (ULL(1) << 17) ? 17 : \ (n) & (ULL(1) << 16) ? 16 : \ (n) & (ULL(1) << 15) ? 15 : \ (n) & (ULL(1) << 14) ? 14 : \ (n) & (ULL(1) << 13) ? 13 : \ (n) & (ULL(1) << 12) ? 12 : \ (n) & (ULL(1) << 11) ? 11 : \ (n) & (ULL(1) << 10) ? 10 : \ (n) & (ULL(1) << 9) ? 9 : \ (n) & (ULL(1) << 8) ? 8 : \ (n) & (ULL(1) << 7) ? 7 : \ (n) & (ULL(1) << 6) ? 6 : \ (n) & (ULL(1) << 5) ? 5 : \ (n) & (ULL(1) << 4) ? 4 : \ (n) & (ULL(1) << 3) ? 3 : \ (n) & (ULL(1) << 2) ? 2 : \ (n) & (ULL(1) << 1) ? 1 : \ (n) & (ULL(1) << 0) ? 0 : \ ____ilog2_NaN() \ ) uint8_t bitrev8(uint8_t byte); uint8_t hweight8(uint8_t byte); uint8_t hweight16(uint16_t word); #define swap16(x) \ ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00)) #define swap32(x) \ ((((x) >> 24) & 0x000000FF) | \ (((x) >> 8) & 0x0000FF00) | \ (((x) << 24) & 0xFF000000) | \ (((x) << 8) & 0x00FF0000)) #define swapb(d, bit) \ ((d) ^ ((uint8_t)0x01 << (bit))) #define LOHALF(b) (b & 0x0F) #define HIHALF(b) (b >> 4) #ifndef LOBYTE #define LOBYTE(w) ((uint8_t)w) #endif #ifndef HIBYTE #define HIBYTE(w) ((uint8_t)((w)>>8)) #endif #ifndef LOWORD #define LOWORD(w) ((uint16_t)w) #endif #ifndef HIWORD #define HIWORD(w) ((uint16_t)((w)>>16)) #endif #define MAKEBYTE(a, b) ((uint8_t)(((a) & 0x0F) | (((b) & 0x0F) << 4))) #ifndef MAKEWORD #define MAKEWORD(a, b) ((uint16_t)(((uint16_t)(a)) | \ ((uint16_t)(b)) << 8)) #endif #ifndef MAKELONG #define MAKELONG(a, b) ((uint32_t)(((uint32_t)(a)) | \ ((uint32_t)(b)) << 16)) #endif #define MAKELLONG(a, b) ((uint64_t)(((uint64_t)(a)) | \ ((uint64_t)(b)) << 32)) #define raise_bits(i, bits) ((i) |= (bits)) #define unraise_bits(i, bits) ((i) &= ~(bits)) #define bits_raised(i, bits) (((i) & (bits)) == (bits)) #define bits_raised_any(i, bits) ((i) & (bits)) #ifdef CONFIG_DEBUG_PRINT #define dbg_dump(x) io_putchar(x) void dbg_print(uint8_t tag, uint8_t val); void dbg_dump_str(const text_char_t *str); #else #define dbg_dump(x) #define dbg_dump_str(x) #define dbg_print(tag, val) #endif #ifdef CONFIG_DEBUG_PANIC /* * XXX: BUG Macros * No expression? Use BUG. * Expression shouldn't be executed when PANIC is disabled? Use BUG_ON. */ void dbg_panic(const text_char_t *file, int line); #ifndef BUG #define BUG() \ dbg_panic(__FILE__, __LINE__) #endif #ifndef BUG_ON #define BUG_ON(expr) \ do { \ if (expr) \ dbg_panic(__FILE__, __LINE__); \ } while (0) #endif #else #ifndef BUG #define BUG() #endif #ifndef BUG_ON #define BUG_ON(expr) #endif #endif /* XXX: Current DBG_SRC Start * current DBG_SRC_XXX should not use 0x00, since dumped 0x00 data are * too much to be correctly handled as simple raw data */ #define DBG_SRC_MAIN 1 #define DBG_SRC_IDLE 2 #define DBG_SRC_IO 3 #define DBG_SRC_USB 4 #define DBG_SRC_SCD 5 #define DBG_SRC_HID 6 #define DBG_SRC_SCS 7 #define DBG_SRC_MSD 8 #define DBG_SRC_DFU 9 #define DBG_SRC_PN53X 10 #define NR_DBG_SRCS 11 /* XXX: Current DBG_SRCS Limitation * current NR_DBG_SRCS should not exceed 0x14, or 0x15 could not be used * as raw data in the UI */ #define IO_DEBUG_BASE (DBG_SRC_IO<<4) #define IO_DEBUG_KEY_DOWN IO_DEBUG_BASE+0 #define IO_DEBUG_KEY_UP IO_DEBUG_BASE+1 #define IO_DEBUG_WAIT_KEY IO_DEBUG_BASE+2 #define NR_IO_EVENTS (IO_DEBUG_WAIT_KEY - IO_DEBUG_BASE + 1) #define USB_DEBUG_BASE (DBG_SRC_USB<<4) #define USB_DEBUG_IRQ USB_DEBUG_BASE+0 #define USB_DEBUG_STATE USB_DEBUG_BASE+1 #define USB_DEBUG_STAGE USB_DEBUG_BASE+2 #define USB_DEBUG_SETUP USB_DEBUG_BASE+3 #define USB_DEBUG_DESC USB_DEBUG_BASE+4 #define USB_DEBUG_ENDP USB_DEBUG_BASE+5 #define USB_DEBUG_INTF USB_DEBUG_BASE+6 #define USB_DEBUG_CALL USB_DEBUG_BASE+7 #define NR_USB_EVENTS (USB_DEBUG_CALL - IO_DEBUG_BASE + 1) #define SCD_DEBUG_BASE (DBG_SRC_SCD<<4) #define SCD_DEBUG_CS_REQ SCD_DEBUG_BASE+0 #define SCD_DEBUG_PC2RDR SCD_DEBUG_BASE+1 #define SCD_DEBUG_RDR2PC SCD_DEBUG_BASE+2 #define SCD_DEBUG_SLOT SCD_DEBUG_BASE+3 #define SCD_DEBUG_INTR SCD_DEBUG_BASE+4 #define SCD_DEBUG_STATE SCD_DEBUG_BASE+5 #define SCD_DEBUG_DIGIT SCD_DEBUG_BASE+6 #define SCD_DEBUG_INS SCD_DEBUG_BASE+7 #define SCD_DEBUG_ABORT SCD_DEBUG_BASE+8 #define NR_SCD_EVENTS (SCD_DEBUG_ABORT - SCD_DEBUG_BASE + 1) #define HID_DEBUG_BASE (DBG_SRC_HID<<4) #define HID_DEBUG_CS_REQ HID_DEBUG_BASE+0 #define HID_DEBUG_DESC HID_DEBUG_BASE+1 #define HID_DEBUG_REPORT HID_DEBUG_BASE+2 #define HID_DEBUG_INTR HID_DEBUG_BASE+3 #define NR_HID_EVENTS (HID_DEBUG_INTR - HID_DEBUG_BASE + 1) #define SCS_DEBUG_BASE (DBG_SRC_SCS<<4) #define SCS_DEBUG_SLOT SCS_DEBUG_BASE+0 #define SCS_DEBUG_SLOT_EVENT SCS_DEBUG_BASE+1 #define SCS_DEBUG_SLOT_STATE SCS_DEBUG_BASE+2 #define SCS_DEBUG_XCHG_STATE SCS_DEBUG_BASE+3 #define SCS_DEBUG_XCHG_EVENT SCS_DEBUG_BASE+4 #define SCS_DEBUG_SEQ SCS_DEBUG_BASE+5 #define SCS_DEBUG_ERROR SCS_DEBUG_BASE+6 #define SCS_DEBUG_CLASS SCS_DEBUG_BASE+7 #define SCS_DEBUG_CONV SCS_DEBUG_BASE+8 #define SCS_DEBUG_CONF_ETU SCS_DEBUG_BASE+9 #define SCS_DEBUG_CONF_WT SCS_DEBUG_BASE+10 #define SCS_DEBUG_CONF_GT SCS_DEBUG_BASE+11 #define NR_SCS_EVENTS (SCS_DEBUG_CONF_GT - SCS_DEBUG_BASE + 1) #define MSD_DEBUG_BASE (DBG_SRC_MSD<<4) #define MSD_DEBUG_CS_REQ MSD_DEBUG_BASE+0 #define MSD_DEBUG_STATE MSD_DEBUG_BASE+1 #define MSD_DEBUG_HALT MSD_DEBUG_BASE+2 #define NR_MSD_EVENTS (MSD_DEBUG_HALT - MSD_DEBUG_BASE + 1) #define DFU_DEBUG_BASE (DBG_SRC_DFU<<4) #define DFU_DEBUG_CS_REQ DFU_DEBUG_BASE+0 #define DFU_DEBUG_STATE DFU_DEBUG_BASE+1 #define DFU_DEBUG_ERROR DFU_DEBUG_BASE+2 #define NR_DFU_EVENTS (DFU_DEBUG_ERROR - DFU_DEBUG_BASE + 1) #define PN53X_DEBUG_BASE (DBG_SRC_PN53X<<4) #define PN53X_DEBUG_USB_STATE PN53X_DEBUG_BASE+0 #define PN53X_DEBUG_USB_FLAGS PN53X_DEBUG_BASE+1 #define PN53X_DEBUG_CMD_CODE PN53X_DEBUG_BASE+2 #define PN53X_DEBUG_ERR_CODE PN53X_DEBUG_BASE+3 #define NR_PN53X_EVENTS (PN53X_DEBUG_ERR_CODE - PN53X_DEBUG_BASE + 1) #define IDLE_DEBUG_BASE (DBG_SRC_IDLE<<4) #define IDLE_DEBUG_SID IDLE_DEBUG_BASE #define IDLE_DEBUG_TID IDLE_DEBUG_BASE+1 #define NR_IDLE_EVENTS (IDLE_DEBUG_TID - IDLE_DEBUG_BASE + 1) #define MAIN_DEBUG_BASE (DBG_SRC_MAIN<<4) #define MAIN_DEBUG_INIT MAIN_DEBUG_BASE #define MAIN_DEBUG_PANIC MAIN_DEBUG_BASE+1 #define NR_MAIN_EVENTS (MAIN_DEBUG_PANIC - MAIN_DEBUG_BASE + 1) #ifdef CONFIG_IDLE_DEBUG #define idle_debug(tag, val) dbg_print((tag), (val)) #else #define idle_debug(tag, val) #endif #ifdef CONFIG_PANIC_DEBUG #define main_debug(tag, val) dbg_print((tag), (val)) #else #define main_debug(tag, val) #endif #ifdef CONFIG_SCS_DEBUG #define scs_debug(tag, val) dbg_print((tag), (val)) #define scs_debug_sl_state(state) \ do { \ if (ifd_slot_get_state() != state) \ scs_debug(SCS_DEBUG_SLOT_STATE, state); \ } while (0) #define scs_debug_sl_event(event) \ do { \ if (!bits_raised(ifd_slot_event, event)) \ scs_debug(SCS_DEBUG_SLOT_EVENT, __ffs16(event));\ } while (0) #define scs_debug_xg_state(state) \ do { \ if (state != ifd_xchg_get_state()) \ scs_debug(SCS_DEBUG_XCHG_STATE, state); \ } while (0) #define scs_debug_xg_event(event) \ do { \ if (!bits_raised(ifd_xchg_event, event)) \ scs_debug(SCS_DEBUG_XCHG_EVENT, event); \ } while (0) #else #define scs_debug(type, val) #define scs_debug_sl_state(state) #define scs_debug_sl_event(event) #define scs_debug_xg_state(state) #define scs_debug_xg_event(event) #endif /* XXX: Faster Interrupt Handler * Such dumpers are called from interrupt handler. Enabling this will * reduce throughput of the interrupt handler. */ #ifdef CONFIG_SCS_DEBUG_DUMP #define scs_debug_dump(b) debug_dump(b) #else #define scs_debug_dump(b) #endif #define SCS_ATR_MAX 33 #ifdef CONFIG_SCS_APDU_SIZE #define SCS_APDU_MAX CONFIG_SCS_APDU_SIZE #else #define SCS_APDU_MAX 256 #endif /* TODO: Remove overhead of APDU extra size. */ #if SCS_APDU_MAX <= 256 typedef uint16_t scs_size_t; typedef uint16_t scs_off_t; #else typedef uint32_t scs_size_t; typedef uint32_t scs_off_t; #endif typedef uint8_t scs_err_t; typedef void (*scs_cmpl_cb)(void); typedef scs_err_t (*scs_txfr_cb)(scs_size_t nc, scs_size_t ne); typedef void (*scs_tvoid_cb)(void); /* Error number defined refers ccid */ #define SCS_ERR_WT_EXTEN 0xFF #define SCS_ERR_SANITY 0x20 #define SCS_ERR_ABORTED 0x0B #define SCS_ERR_PROGRESS 0x0A #define SCS_ERR_UNSUPPORT 0x09 #define SCS_ERR_BAD_POWER 0x08 #define SCS_ERR_PARITY_ERR 0x07 #define SCS_ERR_OVERRUN 0x06 #define SCS_ERR_BUSY_SLOT 0x05 #define SCS_ERR_BUSY_AUTO 0x04 #define SCS_ERR_TIMEOUT 0x03 #define SCS_ERR_NOTPRESENT 0x02 #define SCS_ERR_HW_ERROR 0x01 #define SCS_ERR_SUCCESS 0x00 #define SCS_PROTO_T0 0x00 #define SCS_PROTO_T1 0x01 #define SCS_PROTO_MAX 0x0E #define SCD_PROTO_T15 0x0F /* NFC target information in D.E.P. (Data Exchange Protocol) see * ISO/IEC 18092 (NFCIP-1) */ struct nfc_dep_info { uint8_t abtNFCID3[10]; /* NFCID3 */ uint8_t btDID; /* DID */ uint8_t btBS; /* Supported send-bit rate */ uint8_t btBR; /* Supported receive-bit rate */ uint8_t btTO; /* Timeout value */ uint8_t btPP; /* PP Parameters */ uint8_t abtGB[48]; /* General Bytes */ size_t szGB; uint8_t ndm; /* DEP mode */ #define NDM_UNDEFINED 0x00 #define NDM_PASSIVE 0x01 #define NDM_ACTIVE 0x02 } __packed; struct nfc_iso14443a_info { uint8_t abtAtqa[2]; uint8_t btSak; size_t szUidLen; uint8_t abtUid[10]; size_t szAtsLen; /* Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS */ uint8_t abtAts[254]; } __packed; struct nfc_felica_info { size_t szLen; uint8_t btResCode; uint8_t abtId[8]; uint8_t abtPad[8]; uint8_t abtSysCode[2]; } __packed; struct nfc_iso14443b_info { /* abtPupi store PUPI contained in ATQB * (Answer To reQuest of type B) (see ISO14443-3) */ uint8_t abtPupi[4]; /* abtApplicationData store Application Data contained in ATQB * (see ISO14443-3) */ uint8_t abtApplicationData[4]; /* abtProtocolInfo store Protocol Info contained in ATQB * (see ISO14443-3) */ uint8_t abtProtocolInfo[3]; /* ui8CardIdentifier store CID (Card Identifier) attributted by * PCD to the PICC */ uint8_t ui8CardIdentifier; } __packed; struct nfc_iso14443bi_info { uint8_t abtDIV[4]; /* DIV: 4 LSBytes of tag serial number */ uint8_t btVerLog; /* Software version & type of REPGEN */ uint8_t btConfig; /* Config Byte, present if long REPGEN */ size_t szAtrLen; /* ATR, if any */ uint8_t abtAtr[33]; } __packed; struct nfc_iso14443b2sr_info { uint8_t abtUID[8]; } __packed; struct nfc_iso14443b2ct_info { uint8_t abtUID[4]; uint8_t btProdCode; uint8_t btFabCode; } __packed; struct nfc_jewel_info { uint8_t btSensRes[2]; uint8_t btId[4]; } __packed; /* Union between all kind of tags information structures. */ union nfc_target_info { struct nfc_iso14443a_info nai; struct nfc_felica_info nfi; struct nfc_iso14443b_info nbi; struct nfc_iso14443bi_info nii; struct nfc_iso14443b2sr_info nsi; struct nfc_iso14443b2ct_info nci; struct nfc_jewel_info nji; struct nfc_dep_info ndi; }; #define NFC_MODUL_TYPE(nm) HIBYTE(nm) #define NFC_MODUL_BAUD(nm) LOBYTE(nm) #define NFC_MODULATION(type, baud) MAKEWORD((baud), (type)) #define NFC_TYPE_ISO14443A 0x00 #define NFC_TYPE_JEWEL 0x01 #define NFC_TYPE_ISO14443B 0x02 /* pre-ISO14443B aka ISO/IEC 14443 B' or Type B' */ #define NFC_TYPE_ISO14443BI 0x03 #define NFC_TYPE_ISO14443B2SR 0x04 /* ISO14443-2B ST SRx */ #define NFC_TYPE_ISO14443B2CT 0x05 /* ISO14443-2B ASK CTx */ #define NFC_TYPE_FELICA 0x06 #define NFC_TYPE_DEP 0x07 #define NFC_BAUD_UNDEFINED 0x00 #define NFC_BAUD_106 0x01 #define NFC_BAUD_212 0x02 #define NFC_BAUD_424 0x03 #define NFC_BAUD_847 0x04 struct nfc_target { union nfc_target_info nti; uint16_t nm; } __packed; #ifdef CONFIG_PN53X_DEBUG #define pn53x_debug(tag, val) dbg_print((tag), (val)) #define PN53X_DUMP_USBD true #else #define pn53x_debug(tag, val) #define PN53X_DUMP_USBD false #endif #define NR_PN53X_TARGETS PN53X_HW_MAX_TARGETS #define PN53X_POLL_INFINITE 0xFF #define PN53X_BUF_SIZE 264 #define PN53X_HEAD_SIZE 6 #define PN53X_TAIL_SIZE 2 #define PN53X_DATA_SIZE (PN53X_BUF_SIZE-PN53X_HEAD_SIZE-PN53X_TAIL_SIZE) /* Normal frames */ #define PN53X_LEN 3 #define PN53X_LCS 4 #define PN53X_TFI 5 #define PN53X_CMD 6 #define PN53X_PD(n) (PN53X_CMD+(n)) #define PN53X_OUT 0xD4 #define PN53X_IN 0xD5 #define PN53X_ACK 0x00FF #define PN53X_NAK 0xFF00 #define pn53x_type(buf) MAKEWORD((buf)[PN53X_LCS], (buf)[PN53X_LEN]) #define PN53X_NORMAL(buf) \ ((pn53x_type(buf) != PN53X_ACK) && (pn53x_type(buf) != PN53X_NAK)) #define PN53X_ERROR(buf) \ ((buf)[PN53X_LEN] == 0x01 && (buf)[PN53X_TFI] != PN53X_RESP) #define PN53X_NORMAL_SIZE(buf) \ ((PN53X_HEAD_SIZE -1) + (buf)[PN53X_LEN] + PN53X_TAIL_SIZE) #define PN53X_Diagnose 0x00 #define PN53X_GetFirmwareVersion 0x02 #define PN53X_GetGeneralStatus 0x04 #define PN53X_ReadRegister 0x06 #define PN53X_WriteRegister 0x08 #define PN53X_ReadGPIO 0x0C #define PN53X_WriteGPIO 0x0E #define PN53X_SetSerialBaudRate 0x10 #define PN53X_SetParameters 0x12 #define PN53X_SAMConfiguration 0x14 #define PN53X_PowerDown 0x16 #define PN53X_AlparCommandForTDA 0x18 /* RC-S360 has another command 0x18 for reset &..? */ /* RF communication */ #define PN53X_RFConfiguration 0x32 #define PN53X_RFRegulationTest 0x58 /* Initiator */ #define PN53X_InJumpForDEP 0x56 #define PN53X_InJumpForPSL 0x46 #define PN53X_InListPassiveTarget 0x4A #define PN53X_InATR 0x50 #define PN53X_InPSL 0x4E #define PN53X_InDataExchange 0x40 #define PN53X_InCommunicateThru 0x42 #define PN53X_InQuartetByteExchange 0x38 #define PN53X_InDeselect 0x44 #define PN53X_InRelease 0x52 #define PN53X_InSelect 0x54 #define PN53X_InActivateDeactivatePaypass 0x48 #define PN53X_InAutoPoll 0x60 /* Target */ #define PN53X_TgInitAsTarget 0x8C #define PN53X_TgSetGeneralBytes 0x92 #define PN53X_TgGetData 0x86 #define PN53X_TgSetData 0x8E #define PN53X_TgSetDataSecure 0x96 #define PN53X_TgSetMetaData 0x94 #define PN53X_TgSetMetaDataSecure 0x98 #define PN53X_TgGetInitiatorCommand 0x88 #define PN53X_TgResponseToInitiator 0x90 #define PN53X_TgGetTargetStatus 0x8A /*========================================================================= * error codes *=======================================================================*/ #define PN53X_ERR_SUCCESS 0x00 #define PN53X_ERR_TIMEOUT 0x01 #define PN53X_ERR_CRC 0x02 #define PN53X_ERR_PARITY 0x03 #define PN53X_ERR_BITCOUNT 0x04 #define PN53X_ERR_FRAMING 0x05 #define PN53X_ERR_BITCOLL 0x06 #define PN53X_ERR_SMALLBUF 0x07 #define PN53X_ERR_BUFOVF 0x09 #define PN53X_ERR_RFTIMEOUT 0x0a #define PN53X_ERR_RFPROTO 0x0b #define PN53X_ERR_OVHEAT 0x0d #define PN53X_ERR_INBUFOVF 0x0e #define PN53X_ERR_INVPARAM 0x10 #define PN53X_ERR_DEPUNKCMD 0x12 #define PN53X_ERR_INVRXFRAM 0x13 #define PN53X_ERR_MFAUTH 0x14 #define PN53X_ERR_NSECNOTSUPP 0x18 /* PN533 only */ #define PN53X_ERR_BCC 0x23 #define PN53X_ERR_DEPINVSTATE 0x25 #define PN53X_ERR_OPNOTALL 0x26 #define PN53X_ERR_CMD 0x27 #define PN53X_ERR_TGREL 0x29 #define PN53X_ERR_CID 0x2a #define PN53X_ERR_CDISCARDED 0x2b #define PN53X_ERR_NFCID3 0x2c #define PN53X_ERR_OVCURRENT 0x2d #define PN53X_ERR_NAD 0x2e /*========================================================================= * command/response parameters *=======================================================================*/ /* Diagnose */ #define PN53X_DIAG_CMDLINE 0x00 #define PN53X_DIAG_ROMTEST 0x01 #define PN53X_DIAG_RAMTEST 0x02 #define PN53X_DIAG_STATUS_OK 0x00 #define PN53X_DIAG_STATUS_FAIL 0xFF #define PN53X_DIAG_POLL_TARGET 0x04 #define PN53X_DIAG_ECHO_BACK 0x05 #define PN53X_DIAG_DETECT_14443 0x06 #define PN53X_DIAG_ANTENNA_TEST 0x07 /* Read/WriteRegister */ #define PN53X_REG_Control_switch_rng 0x6106 /* Read/WriteGPIO */ #define PN53X_SFR_P3 0xFFB0 #define PN53X_SFR_P7 0xFFF7 #define PN53X_P3_MASK (~(_BV(7) | _BV(6))) #define PN53X_P7_MASK (_BV(2) | _BV(1)) /* Host controller configuration mode from I0I1 */ #define PN53X_HCI_HSU 0x00 #define PN53X_HCI_I2C 0x01 #define PN53X_HCI_SPI 0x02 /* SetParameters */ #define PN53X_PARAM_NONE 0x00 #define PN53X_PARAM_NAD_USED 0x01 #define PN53X_PARAM_DID_USED 0x02 #define PN53X_PARAM_AUTO_ATR_RES 0x04 #define PN53X_PARAM_AUTO_RATS 0x10 #define PN53X_PARAM_14443_4_PICC 0x20 #define PN53X_PARAM_NFC_SECURE 0x20 #define PN53X_PARAM_NO_AMBLE 0x40 /* RFConfiguration */ #define PN53X_RFCI_FIELD 0x01 #define PN53X_RFCI_TIMING 0x02 #define PN53X_RFCI_RETRY_DATA 0x04 #define PN53X_RFCI_RETRY_SELECT 0x05 #define PN53X_RFCI_ANALOG_TYPE_A_106 0x0A #define PN53X_RFCI_ANALOG_TYPE_A_212_424 0x0B #define PN53X_RFCI_ANALOG_TYPE_B 0x0C #define PN53X_RFCI_ANALOG_TYPE_14443_4 0x0D /*========================================================================= * target/modulation types *=======================================================================*/ /* Undefined target type */ #define PN53X_TARGET_UNDEFINED 0xFF /* Generic passive 106 kbps (ISO/IEC14443-4A, mifare, DEP) */ #define PN53X_TARGET_GENERIC_PASSIVE_106 0x00 /* Generic passive 212 kbps (FeliCa, DEP) */ #define PN53X_TARGET_GENERIC_PASSIVE_212 0x01 /* Generic passive 424 kbps (FeliCa, DEP) */ #define PN53X_TARGET_GENERIC_PASSIVE_424 0x02 /* Passive 106 kbps ISO/IEC14443-4B */ #define PN53X_TARGET_ISO14443_4B_106 0x03 /* Innovision Jewel tag */ #define PN53X_TARGET_JEWEL_106 0x04 /* Mifare card */ #define PN53X_TARGET_MIFARE 0x10 /* FeliCa 212 kbps card */ #define PN53X_TARGET_FELICA_212 0x11 /* FeliCa 424 kbps card */ #define PN53X_TARGET_FELICA_424 0x12 /* Passive 106 kbps ISO/IEC 14443-4A */ #define PN53X_TARGET_ISO14443_4A_106 0x20 /* Passive 106 kbps ISO/IEC 14443-4B with TCL flag */ #define PN53X_TARGET_ISO14443_4B_TCL_106 0x23 /* DEP passive 106 kbps */ #define PN53X_TARGET_DEP_PASSIVE_106 0x40 /* DEP passive 212 kbps */ #define PN53X_TARGET_DEP_PASSIVE_212 0x41 /* DEP passive 424 kbps */ #define PN53X_TARGET_DEP_PASSIVE_424 0x42 /* DEP active 106 kbps */ #define PN53X_TARGET_DEP_ACTIVE_106 0x80 /* DEP active 212 kbps */ #define PN53X_TARGET_DEP_ACTIVE_212 0x81 /* DEP active 424 kbps */ #define PN53X_TARGET_DEP_ACTIVE_424 0x82 /* Undefined modulation */ #define PN53X_MODULATION_UNDEFINED 0xFF /* ISO14443-A (NXP MIFARE) http://en.wikipedia.org/wiki/MIFARE */ #define PN53X_MODULATION_ISO14443A_106 0x00 /* JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */ #define PN53X_MODULATION_FELICA_212 0x01 /* JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */ #define PN53X_MODULATION_FELICA_424 0x02 /* ISO14443-B * http://en.wikipedia.org/wiki/ISO/IEC_14443 * (Not supported by PN531) */ #define PN53X_MODULATION_ISO14443B_106 0x03 /* Jewel Topaz (Innovision Research & Development) * (Not supported by PN531) */ #define PN53X_MODULATION_JEWEL_106 0x04 /* ISO14443-B * http://en.wikipedia.org/wiki/ISO/IEC_14443 * (Not supported by PN531 nor PN532) */ #define PN53X_MODULATION_ISO14443B_212 0x06 /* ISO14443-B * http://en.wikipedia.org/wiki/ISO/IEC_14443 * (Not supported by PN531 nor PN532) */ #define PN53X_MODULATION_ISO14443B_424 0x07 /* ISO14443-B * http://en.wikipedia.org/wiki/ISO/IEC_14443 * (Not supported by PN531 nor PN532) */ #define PN53X_MODULATION_ISO14443B_847 0x08 /*========================================================================= * CIU registers *=======================================================================*/ #define PN53X_REG_CIU_BASE 0x6300 #define PN53X_CIU(offset) (PN53X_REG_BASE+(offset)) #define PN53X_REG_CIU_Mode PN53X_CIU(0x01) #define PN53X_REG_CIU_TxMode PN53X_CIU(0x02) #define PN53X_REG_CIU_RxMode PN53X_CIU(0x03) #define PN53X_REG_CIU_TxControl PN53X_CIU(0x04) #define PN53X_REG_CIU_TxAuto PN53X_CIU(0x05) #define PN53X_REG_CIU_TxSel PN53X_CIU(0x06) #define PN53X_REG_CIU_RxSel PN53X_CIU(0x07) #define PN53X_REG_CIU_RxThreshold PN53X_CIU(0x08) #define PN53X_REG_CIU_Demod PN53X_CIU(0x09) #define PN53X_REG_CIU_FelNFC1 PN53X_CIU(0x0A) #define PN53X_REG_CIU_FelNFC2 PN53X_CIU(0x0B) #define PN53X_REG_CIU_MifNFC PN53X_CIU(0x0C) #define PN53X_REG_CIU_ManualRCV PN53X_CIU(0x0D) #define PN53X_REG_CIU_TypeB PN53X_CIU(0x0E) /* #define PN53X_REG_- 0x630F */ /* #define PN53X_REG_- 0x6310 */ #define PN53X_REG_CIU_CRCResultMSB PN53X_CIU(0x11) #define PN53X_REG_CIU_CRCResultLSB PN53X_CIU(0x12) #define PN53X_REG_CIU_GsNOFF PN53X_CIU(0x13) #define PN53X_REG_CIU_ModWidth PN53X_CIU(0x14) #define PN53X_REG_CIU_TxBitPhase PN53X_CIU(0x15) #define PN53X_REG_CIU_RFCfg PN53X_CIU(0x16) #define PN53X_REG_CIU_GsNOn PN53X_CIU(0x17) #define PN53X_REG_CIU_CWGsP PN53X_CIU(0x18) #define PN53X_REG_CIU_ModGsP PN53X_CIU(0x19) #define PN53X_REG_CIU_TMode PN53X_CIU(0x1A) #define PN53X_REG_CIU_TPrescaler PN53X_CIU(0x1B) #define PN53X_REG_CIU_TReloadVal_hi PN53X_CIU(0x1C) #define PN53X_REG_CIU_TReloadVal_lo PN53X_CIU(0x1D) #define PN53X_REG_CIU_TCounterVal_hi PN53X_CIU(0x1E) #define PN53X_REG_CIU_TCounterVal_lo PN53X_CIU(0x1F) /* #define PN53X_REG_- 0x6320 */ #define PN53X_REG_CIU_TestSel1 PN53X_CIU(0x21) #define PN53X_REG_CIU_TestSel2 PN53X_CIU(0x22) #define PN53X_REG_CIU_TestPinEn PN53X_CIU(0x23) #define PN53X_REG_CIU_TestPinValue PN53X_CIU(0x24) #define PN53X_REG_CIU_TestBus PN53X_CIU(0x25) #define PN53X_REG_CIU_AutoTest PN53X_CIU(0x26) #define PN53X_REG_CIU_Version PN53X_CIU(0x27) #define PN53X_REG_CIU_AnalogTest PN53X_CIU(0x28) #define PN53X_REG_CIU_TestDAC1 PN53X_CIU(0x29) #define PN53X_REG_CIU_TestDAC2 PN53X_CIU(0x2A) #define PN53X_REG_CIU_TestADC PN53X_CIU(0x2B) /* #define PN53X_REG_- 0x632C */ /* #define PN53X_REG_- 0x632D */ /* #define PN53X_REG_- 0x632E */ #define PN53X_REG_CIU_RFlevelDet PN53X_CIU(0x2F) #define PN53X_REG_CIU_SIC_CLK_en PN53X_CIU(0x30) #define PN53X_REG_CIU_Command PN53X_CIU(0x31) #define PN53X_REG_CIU_CommIEn PN53X_CIU(0x32) #define PN53X_REG_CIU_DivIEn PN53X_CIU(0x33) #define PN53X_REG_CIU_CommIrq PN53X_CIU(0x34) #define PN53X_REG_CIU_DivIrq PN53X_CIU(0x35) #define PN53X_REG_CIU_Error PN53X_CIU(0x36) #define PN53X_REG_CIU_Status1 PN53X_CIU(0x37) #define PN53X_REG_CIU_Status2 PN53X_CIU(0x38) #define PN53X_REG_CIU_FIFOData PN53X_CIU(0x39) #define PN53X_REG_CIU_FIFOLevel PN53X_CIU(0x3A) #define PN53X_REG_CIU_WaterLevel PN53X_CIU(0x3B) #define PN53X_REG_CIU_Control PN53X_CIU(0x3C) #define PN53X_REG_CIU_BitFraming PN53X_CIU(0x3D) #define PN53X_REG_CIU_Coll PN53X_CIU(0x3E) #define PN53X_REG_CIU_SIZE 0x40 #define PN53X_CIU_REG2INDEX(reg) ((reg) - PN53X_REG_CIU_BASE) /* chip drivers for PN53x * support nothing but PN532 */ /* #define NR_PN53X_SLOTS 0x02 */ #define PN53X_HW_MAX_TARGETS 2 boolean pn53x_hw_poll_ready(void); void pn53x_hw_write_cmpl(scs_size_t nc); void pn53x_hw_read_cmpl(scs_size_t ne); uint8_t pn53x_hw_xchg_read(scs_off_t index); void pn53x_hw_xchg_write(scs_off_t index, uint8_t val); void pn53x_hw_ctrl_init(void); /* APIs for NFC<->PN53x constants conversion */ uint8_t pn53x_nm_to_pm(const uint16_t nm); uint16_t pn53x_ptt_to_nm(const uint8_t ptt); uint8_t pn53x_nm_to_ptt(const uint16_t nm); /* API used for PN53x USB devices */ #define pn53x_poll_ready() pn53x_hw_poll_ready() #define pn53x_write_cmpl(nc) pn53x_hw_write_cmpl(nc) #define pn53x_read_cmpl(ne) pn53x_hw_read_cmpl(ne) #define pn53x_xchg_read(index) pn53x_hw_xchg_read(index) #define pn53x_xchg_write(index, val) pn53x_hw_xchg_write(index, val) #define pn53x_ctrl_init() pn53x_hw_ctrl_init() struct pn53x_stub_driver { uint16_t nm; scs_err_t (*get_info)(uint8_t tg, union nfc_target_info *info); scs_err_t (*read_ready)(uint8_t tg); scs_size_t (*read_count)(uint8_t tg); uint8_t (*read_byte)(uint8_t tg, scs_off_t index); void (*write_ready)(uint8_t tg, scs_size_t size); void (*write_byte)(uint8_t tg, scs_off_t index, uint8_t value); }; __TEXT_TYPE__(struct pn53x_stub_driver, pn53x_stub_driver_t); uint8_t pn53x_register_stub_driver(pn53x_stub_driver_t *driver); void pn53x_stub_driver_init(void); uint8_t pn53x_stub_cmd[PN53X_BUF_SIZE]; uint8_t pn53x_stub_resp[PN53X_BUF_SIZE]; scs_size_t pn53x_stub_nc; scs_size_t pn53x_stub_ne; boolean pn53x_stub_ready; boolean pn53x_stub_is_resp; boolean pn53x_stub_is_cmd; static uint8_t pn53x_flags; static uint8_t pn53x_serial_br; static uint8_t pn53x_sfr_p3; static uint8_t pn53x_sfr_p7; static uint8_t pn53x_hci_mode = PN53X_HCI_SPI; static struct nfc_target pn53x_targets[NR_PN53X_TARGETS]; static uint8_t pn53x_nr_targets; #define NR_PN53X_STUB_DRIVERS 1 static pn53x_stub_driver_t *pn53x_stub_drivers[NR_PN53X_STUB_DRIVERS]; static uint8_t pn53x_nr_drivers; static uint8_t pn53x_ciu_regs[PN53X_REG_CIU_SIZE] = { 0x00, 0x3B, 0x00, 0x00, 0x80, 0x00, 0x10, 0x84, /* 0x00 */ 0x84, 0x4F, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, /* 0x08 */ 0x00, 0xFF, 0xFF, 0x88, 0x26, 0x87, 0x48, 0x88, /* 0x10 */ 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28 */ 0x00, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x21, /* 0x30 */ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xA0, 0x00 /* 0x38 */ }; static uint8_t pn53x_ciu_writables[PN53X_REG_CIU_SIZE] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, /* 0x00 */ 0xF7, 0xEF, 0xFF, 0xFF, 0xFF, 0x7F, 0xDF, 0x00, /* 0x08 */ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x10 */ 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, /* 0x18 */ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x00, /* 0x20 */ 0xFF, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xFF, /* 0x28 */ 0x8F, 0x3F, 0x7F, 0x2F, 0xFF, 0x9F, 0x00, 0x00, /* 0x30 */ 0x98, 0xFF, 0x80, 0x3F, 0xF0, 0xF7, 0x80, 0x00 /* 0x38 */ }; static uint8_t pn53x_ciu_readables[PN53X_REG_CIU_SIZE] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFB, 0xFB, 0xFF, 0xFF, /* 0x00 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* 0x08 */ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x10 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* 0x18 */ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x20 */ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, /* 0x28 */ 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, /* 0x30 */ 0xFF, 0xFF, 0x7F, 0xFF, 0x3F, 0x7F, 0xFF, 0x00 /* 0x38 */ }; static uint8_t pn53x_ctrl_reg_switch_rng; void pn53x_build_frame(uint8_t len) { scs_size_t ne; uint8_t dcs = 0x00; uint8_t i; pn53x_stub_resp[PN53X_LEN] = len; pn53x_stub_resp[PN53X_LCS] = (uint8_t)(0x00-len); /* Calculate DCS. */ ne = PN53X_NORMAL_SIZE(pn53x_stub_resp); for (i = 0; i < pn53x_stub_resp[PN53X_LEN]; i++) dcs -= pn53x_stub_resp[PN53X_TFI+i]; pn53x_stub_resp[ne-PN53X_TAIL_SIZE] = dcs; pn53x_stub_resp[ne-1] = 0x00; pn53x_stub_ne = ne; pn53x_stub_is_resp = true; pn53x_stub_ready = true; } void pn53x_response_error(uint8_t ec) { pn53x_debug(PN53X_DEBUG_ERR_CODE, ec); pn53x_stub_resp[PN53X_TFI] = ec; pn53x_build_frame(1); } void pn53x_response_Diagnose(void) { uint8_t len; switch (pn53x_stub_cmd[PN53X_PD(1)]) { case PN53X_DIAG_CMDLINE: len = pn53x_stub_cmd[PN53X_LEN]; memory_copy((caddr_t)(pn53x_stub_resp)+PN53X_PD(1), (caddr_t)(pn53x_stub_cmd)+PN53X_PD(1), len-2); break; case PN53X_DIAG_ROMTEST: case PN53X_DIAG_RAMTEST: pn53x_stub_resp[PN53X_PD(1)] = PN53X_DIAG_STATUS_OK; len = 3; break; case PN53X_DIAG_POLL_TARGET: case PN53X_DIAG_ECHO_BACK: case PN53X_DIAG_DETECT_14443: case PN53X_DIAG_ANTENNA_TEST: pn53x_response_error(PN53X_ERR_CMD); return; default: pn53x_response_error(PN53X_ERR_CMD); return; } pn53x_build_frame(len); } void pn53x_response_GetFirmwareVersion(void) { pn53x_stub_resp[PN53X_PD(1)] = 0x32; pn53x_stub_resp[PN53X_PD(2)] = 0x01; pn53x_stub_resp[PN53X_PD(3)] = 0x06; pn53x_stub_resp[PN53X_PD(4)] = 0x07; pn53x_build_frame(6); } void pn53x_response_SetParameters(void) { pn53x_flags = pn53x_stub_cmd[PN53X_PD(1)]; /* if (bits_raised(pn53x_flags, PN53X_PARAM_AUTO_ATR_RES) && bits_raised(pn53x_flags, PN53X_PARAM_AUTO_RATS)) if (bits_raised(pn53x_flags, PN53X_PARAM_14443_4_PICC)) */ pn53x_build_frame(2); } static uint8_t pn53x_target_iso14443a_size(uint8_t tg) { uint8_t size = 4; uint8_t len; len = pn53x_targets[tg].nti.nai.szAtsLen; if (len) size += (1+len); size += pn53x_targets[tg].nti.nai.szUidLen; return size; } static uint8_t pn53x_target_info_size(uint8_t tg) { uint8_t size = 1; switch (NFC_MODUL_TYPE(pn53x_targets[tg].nm)) { case NFC_TYPE_ISO14443A: size += pn53x_target_iso14443a_size(tg); break; default: BUG(); break; } return size; } static void pn53x_target_iso14443a_data(uint8_t tg, scs_off_t offset) { uint8_t len; pn53x_stub_resp[offset++] = pn53x_targets[tg].nti.nai.abtAtqa[0]; pn53x_stub_resp[offset++] = pn53x_targets[tg].nti.nai.abtAtqa[1]; pn53x_stub_resp[offset++] = pn53x_targets[tg].nti.nai.btSak; len = pn53x_targets[tg].nti.nai.szUidLen; pn53x_stub_resp[offset++] = len; memory_copy((caddr_t)(pn53x_stub_resp)+offset, (caddr_t)(pn53x_targets[tg].nti.nai.abtUid), len); offset += len; len = pn53x_targets[tg].nti.nai.szAtsLen; if (len) { pn53x_stub_resp[offset++] = len; memory_copy((caddr_t)(pn53x_stub_resp)+offset, (caddr_t)(pn53x_targets[tg].nti.nai.abtAts), len); } } static void pn53x_target_info_data(uint8_t tg, scs_off_t offset) { pn53x_stub_resp[offset++] = tg; switch (NFC_MODUL_TYPE(pn53x_targets[tg].nm)) { case NFC_TYPE_ISO14443A: pn53x_target_iso14443a_data(tg, offset); break; default: BUG(); break; } } uint8_t pn53x_stub_get_driver(uint16_t nm) { uint8_t drv; for (drv = 0; drv < pn53x_nr_drivers; drv++) { if (nm == pn53x_stub_drivers[drv]->nm) break; } return drv; } static void pn53x_poll_targets(uint8_t period) { scs_err_t err; uint8_t tg, drv; pn53x_stub_driver_t *driver; pn53x_nr_targets = 0; for (drv = 0; drv < pn53x_nr_drivers; drv++) { driver = pn53x_stub_drivers[drv]; BUG_ON(!driver || !driver->get_info); for (tg = 0; tg < NR_PN53X_TARGETS; tg++) { pn53x_targets[tg].nm = driver->nm; err = driver->get_info(tg, &pn53x_targets[0].nti); if (err == SCS_ERR_SUCCESS) { pn53x_nr_targets++; break; } } } } void pn53x_response_InAutoPoll(void) { uint8_t nr_poll; uint8_t period; uint8_t i; scs_off_t offset; /* This command is requesting N times polling (N is indicated by PD1), * each polling should have a period indicated by PD2. */ nr_poll = pn53x_stub_cmd[PN53X_PD(1)]; period = pn53x_stub_cmd[PN53X_PD(2)]; do { if (pn53x_nr_targets == 0) pn53x_poll_targets(period); if (pn53x_nr_targets > 0) break; if (nr_poll != PN53X_POLL_INFINITE) nr_poll--; } while (nr_poll > 0); offset = PN53X_PD(1); pn53x_stub_resp[offset++] = pn53x_nr_targets; for (i = 0; i < pn53x_nr_targets; i++) { uint8_t size = pn53x_target_info_size(i); pn53x_stub_resp[offset++] = pn53x_nm_to_ptt(pn53x_targets[i].nm); pn53x_stub_resp[offset++] = size; pn53x_target_info_data(i, offset); offset += size; } pn53x_build_frame(offset-PN53X_TFI); } static boolean pn53x_is_ciu_register(uint16_t reg) { return (reg >= PN53X_REG_CIU_BASE) && (reg < (PN53X_REG_CIU_BASE + PN53X_REG_CIU_SIZE)); } void pn53x_ciu_write_register(uint16_t reg, uint8_t val) { uint8_t index = PN53X_CIU_REG2INDEX(reg); BUG_ON(!pn53x_is_ciu_register(reg)); pn53x_ciu_regs[index] = val; } uint8_t pn53x_ciu_read_register(uint16_t reg) { uint8_t index = PN53X_CIU_REG2INDEX(reg); BUG_ON(!pn53x_is_ciu_register(reg)); return pn53x_ciu_regs[index]; } void pn53x_response_ReadRegister(void) { uint8_t i, j; uint16_t reg; uint8_t val; for (i = 0, j = 0; i < (pn53x_stub_cmd[PN53X_LEN]-2); i += 2, j++) { reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i], pn53x_stub_cmd[PN53X_PD(1)+i]); if (!pn53x_is_ciu_register(reg)) { if (reg == PN53X_REG_Control_switch_rng) { val = pn53x_ctrl_reg_switch_rng; } else { pn53x_response_error(PN53X_ERR_CMD); return; } } else { uint8_t mask; uint8_t index = PN53X_CIU_REG2INDEX(reg); mask = pn53x_ciu_readables[index]; val = (pn53x_ciu_read_register(reg) & mask); } pn53x_stub_resp[PN53X_PD(1)+j] = val; } pn53x_build_frame(j+2); } void pn53x_response_WriteRegister(void) { uint8_t i; uint8_t val; uint16_t reg; for (i = 0; i < (pn53x_stub_cmd[PN53X_LEN]-2); i += 3) { reg = MAKEWORD(pn53x_stub_cmd[PN53X_PD(2)+i], pn53x_stub_cmd[PN53X_PD(1)+i]); val = pn53x_stub_cmd[PN53X_PD(3)+i]; if (!pn53x_is_ciu_register(reg)) { if (reg == PN53X_REG_Control_switch_rng) { pn53x_ctrl_reg_switch_rng = val; } else { pn53x_response_error(PN53X_ERR_CMD); return; } } else { uint8_t mask; uint8_t index; index = PN53X_CIU_REG2INDEX(reg); mask = pn53x_ciu_writables[index]; pn53x_ciu_write_register(reg, val & mask); } } pn53x_build_frame(2); } void pn53x_response_ReadGPIO(void) { pn53x_stub_resp[PN53X_PD(1)] = (pn53x_sfr_p3 & PN53X_P3_MASK); pn53x_stub_resp[PN53X_PD(2)] = (pn53x_sfr_p7 & PN53X_P7_MASK); pn53x_stub_resp[PN53X_PD(3)] = pn53x_hci_mode; pn53x_build_frame(5); } void pn53x_response_WriteGPIO(void) { pn53x_sfr_p3 = pn53x_stub_cmd[PN53X_PD(1)]; pn53x_sfr_p7 = pn53x_stub_cmd[PN53X_PD(2)]; pn53x_build_frame(2); } void pn53x_response_SetSerialBaudRate(void) { pn53x_serial_br = pn53x_stub_cmd[PN53X_PD(1)]; pn53x_build_frame(2); } void pn53x_response_SAMConfiguration(void) { uint8_t mode; uint8_t timeout; uint8_t irq; mode = pn53x_stub_cmd[PN53X_PD(1)]; timeout = pn53x_stub_cmd[PN53X_PD(2)]; if (pn53x_stub_cmd[PN53X_LEN] > 4) irq = pn53x_stub_cmd[PN53X_PD(3)]; pn53x_build_frame(2); } void pn53x_response_PowerDown(void) { uint8_t wakeupenable; uint8_t generateirq; wakeupenable = pn53x_stub_cmd[PN53X_PD(1)]; if (pn53x_stub_cmd[PN53X_LEN] > 3) generateirq = pn53x_stub_cmd[PN53X_PD(2)]; pn53x_response_error(PN53X_ERR_SUCCESS); } void pn53x_response_RFConfiguration(void) { uint8_t type = pn53x_stub_cmd[PN53X_PD(1)]; switch (type) { case PN53X_RFCI_FIELD: case PN53X_RFCI_RETRY_DATA: break; case PN53X_RFCI_TIMING: case PN53X_RFCI_RETRY_SELECT: case PN53X_RFCI_ANALOG_TYPE_B: break; case PN53X_RFCI_ANALOG_TYPE_A_212_424: break; case PN53X_RFCI_ANALOG_TYPE_14443_4: break; case PN53X_RFCI_ANALOG_TYPE_A_106: break; default: BUG(); break; } pn53x_build_frame(2); } void pn53x_response_InListPassiveTarget(void) { uint8_t i; uint8_t modulation; uint8_t max_targets, nr_targets; scs_off_t offset; /* Handle MaxTg field */ max_targets = pn53x_stub_cmd[PN53X_PD(1)]; if (max_targets > NR_PN53X_TARGETS) { /* MaxTg should not exceed NR_PN53X_TARGETS */ pn53x_response_error(PN53X_ERR_CID); return; } if (max_targets > pn53x_nr_targets) max_targets = pn53x_nr_targets; if (pn53x_nr_targets == 0) pn53x_poll_targets(0); /* Handle BrTy field */ modulation = pn53x_stub_cmd[PN53X_PD(2)]; nr_targets = 0; offset = PN53X_PD(2); for (i = 0; i < pn53x_nr_targets; i++) { if (pn53x_nm_to_pm(pn53x_targets[i].nm) == modulation) { nr_targets++; pn53x_target_info_data(i, offset); offset += pn53x_target_info_size(i); } } pn53x_stub_resp[PN53X_PD(1)] = nr_targets; pn53x_build_frame(offset-PN53X_TFI); } void pn53x_response_InDataExchange(void) { uint8_t tg, drv; scs_off_t offset, i; scs_size_t len; pn53x_stub_driver_t *driver; scs_err_t err; tg = pn53x_stub_cmd[PN53X_PD(1)]; if (tg >= pn53x_nr_targets) { pn53x_response_error(PN53X_ERR_CID); return; } drv = pn53x_stub_get_driver(pn53x_targets[tg].nm); driver = pn53x_stub_drivers[drv]; BUG_ON(!driver); BUG_ON(!driver->write_byte || !driver->write_ready); /* get the DATA_OUT fields after the TFI and CMD fields */ offset = PN53X_PD(2); len = pn53x_stub_cmd[PN53X_LEN]-2; for (i = 0; i < len; i++) { driver->write_byte(tg, i, pn53x_stub_cmd[offset++]); } driver->write_ready(tg, i); /* TODO: Asynchronous Access for RX Handlers * Following codes might be put into a timeout handler to allow * asynchronous RX handlers. */ BUG_ON(!driver->read_ready || !driver->read_count || !driver->read_byte); do { err = driver->read_ready(tg); if (err != SCS_ERR_PROGRESS) break; } while (1); /* return error status on failure */ if (err != SCS_ERR_SUCCESS) { pn53x_response_error(PN53X_ERR_CMD); return; } /* set the STATUS field */ pn53x_stub_resp[PN53X_PD(1)] = PN53X_ERR_SUCCESS; /* set the DATA_IN fields */ offset = PN53X_PD(2); len = driver->read_count(tg); for (i = 0; i < len; i++) { pn53x_stub_resp[offset++] = driver->read_byte(tg, i); } pn53x_build_frame(offset-PN53X_TFI); } boolean pn53x_valiate_cmd(void) { uint8_t i; uint8_t dcs; /* Validate LCS. */ if (0x00 != (uint8_t)(pn53x_stub_cmd[PN53X_LEN]+ pn53x_stub_cmd[PN53X_LCS])) return false; /* Validate TFI. */ if (pn53x_stub_cmd[PN53X_TFI] != PN53X_OUT) return false; /* Validate DCS. */ for (i = 0, dcs = 0; i <= pn53x_stub_cmd[PN53X_LEN]; i++) dcs += pn53x_stub_cmd[PN53X_TFI+i]; if (dcs != 0x00) return false; return true; } void pn53x_xchg_pseudo(void) { uint8_t cmd; pn53x_stub_resp[0] = 0x00; pn53x_stub_resp[1] = 0x00; pn53x_stub_resp[2] = 0xFF; pn53x_stub_resp[PN53X_TFI] = PN53X_IN; pn53x_stub_resp[PN53X_CMD] = pn53x_stub_cmd[PN53X_CMD] + 1; cmd = pn53x_stub_cmd[PN53X_CMD]; pn53x_debug(PN53X_DEBUG_CMD_CODE, cmd); switch (cmd) { case PN53X_Diagnose: pn53x_response_Diagnose(); break; case PN53X_GetFirmwareVersion: pn53x_response_GetFirmwareVersion(); break; case PN53X_ReadRegister: pn53x_response_ReadRegister(); break; case PN53X_WriteRegister: pn53x_response_WriteRegister(); break; case PN53X_ReadGPIO: pn53x_response_ReadGPIO(); break; case PN53X_WriteGPIO: pn53x_response_WriteGPIO(); break; case PN53X_SetSerialBaudRate: pn53x_response_SetSerialBaudRate(); break; case PN53X_SetParameters: pn53x_response_SetParameters(); break; case PN53X_SAMConfiguration: pn53x_response_SAMConfiguration(); break; case PN53X_PowerDown: pn53x_response_PowerDown(); break; case PN53X_RFConfiguration: pn53x_response_RFConfiguration(); break; case PN53X_InListPassiveTarget: pn53x_response_InListPassiveTarget(); break; case PN53X_InAutoPoll: pn53x_response_InAutoPoll(); break; case PN53X_InDataExchange: pn53x_response_InDataExchange(); break; case PN53X_InJumpForDEP: case PN53X_InJumpForPSL: case PN53X_InActivateDeactivatePaypass: case PN53X_InATR: case PN53X_InPSL: case PN53X_InCommunicateThru: case PN53X_InQuartetByteExchange: case PN53X_InDeselect: case PN53X_InRelease: case PN53X_InSelect: case PN53X_AlparCommandForTDA: default: pn53x_response_error(PN53X_ERR_CMD); break; } } uint8_t pn53x_register_stub_driver(pn53x_stub_driver_t *driver) { uint8_t drv = pn53x_nr_drivers; BUG_ON(drv >= NR_PN53X_STUB_DRIVERS); pn53x_stub_drivers[drv] = driver; pn53x_nr_drivers++; return drv; } boolean pn53x_hw_poll_ready(void) { return pn53x_stub_ready; } void pn53x_hw_read_cmpl(scs_size_t ne) { pn53x_stub_ready = false; if (!pn53x_stub_is_resp && pn53x_stub_is_cmd) { pn53x_xchg_pseudo(); } } void pn53x_hw_write_cmpl(scs_size_t nc) { pn53x_stub_nc = nc; pn53x_stub_ready = false; switch (pn53x_type(pn53x_stub_cmd)) { case PN53X_ACK: pn53x_stub_is_cmd = false; pn53x_stub_is_resp = false; pn53x_stub_ne = 0; break; case PN53X_NAK: if (pn53x_stub_is_resp) pn53x_stub_ready = true; break; default: /* validate LCS, DCS, TFI */ if (pn53x_valiate_cmd()) { pn53x_stub_is_cmd = true; pn53x_stub_is_resp = false; pn53x_stub_resp[0] = 0x00; pn53x_stub_resp[1] = 0x00; pn53x_stub_resp[2] = 0xFF; pn53x_stub_resp[3] = 0x00; pn53x_stub_resp[4] = 0xFF; pn53x_stub_resp[5] = 0x00; pn53x_stub_ne = 6; pn53x_stub_ready = true; } break; } } uint8_t pn53x_hw_xchg_read(scs_off_t index) { if (index < pn53x_stub_ne) return pn53x_stub_resp[index]; return 0; } void pn53x_hw_xchg_write(scs_off_t index, uint8_t val) { pn53x_stub_cmd[index] = val; } void pn53x_hw_ctrl_init(void) { pn53x_stub_nc = 0; pn53x_stub_ne = 0; pn53x_stub_ready = false; pn53x_stub_is_resp = false; pn53x_stub_is_cmd = false; pn53x_stub_driver_init(); }