/** * @file hal_scr.h * @author XRADIO IOT WLAN Team */ /* * Copyright (C) 2019 XRADIO TECHNOLOGY CO., LTD. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _DRIVER_CHIP_HAL_SCR_H_ #define _DRIVER_CHIP_HAL_SCR_H_ #include "driver/chip/hal_def.h" #ifdef __cplusplus extern "C" { #endif #define SCR_MDelay(ms) HAL_MSleep(ms) #define SCR_UDelay(us) HAL_UDelay(us) #define SCR_ATR_RESP_INVALID 0 #define SCR_ATR_RESP_FAIL 1 #define SCR_ATR_RESP_OK 2 #define SCR_BUFFER_SIZE_MASK 0x3f /* 64 */ /** * @brief SmartCard-Reader register block structure */ typedef struct { __IO uint32_t SCR_CSR; /* offset: 0x00, SmartCard-Reader control and status register */ __IO uint32_t SCR_INT_EN; /* offset: 0x04, SmartCard-Reader interrupt enable register */ __IO uint32_t SCR_INT_ST; /* offset: 0x08, SmartCard-Reader interrupt status register */ __IO uint32_t SCR_FIFO_CSR; /* offset: 0x0C, SmartCard-Reader FIFO control and status register */ __IO uint32_t SCR_FIFO_CNT; /* offset: 0x10, SmartCard-Reader FIFO counter register */ __IO uint32_t SCR_FIFO_REPEAT; /* offset: 0x14, SmartCard-Reader repeat control register */ __IO uint32_t SCR_CLKDIV; /* offset: 0x18, SmartCard-Reader clock divisor register */ __IO uint32_t SCR_LTIM; /* offset: 0x1C, SmartCard-Reader line time register */ __IO uint32_t SCR_CTIM; /* offset: 0x20, SmartCard-Reader character register */ uint32_t RESERVED1[3]; __IO uint32_t SCR_PAD; /* offset: 0x30, SmartCard-Reader line control register */ uint32_t RESERVED2[2]; __I uint32_t SCR_FSM; /* offset: 0x3C, SmartCard-Reader FSM register */ __IO uint32_t SCR_DT; /* offset: 0x40, SmartCard-Reader debounce time register */ uint32_t RESERVED3[47]; __IO uint32_t SCR_FIFO_DATA; /* offset: 0x100, SmartCard-Reader FIFO data register */ } SCREADER_T; #define SCREDAER ((SCREADER_T *)ISO7816_CTRL_BASE) #define SCR_FIFO_DEPTH 16 /* SCREDAER->SCR_CSR */ #define SCR_DETECT_BIT HAL_BIT(31) #define SCR_DETECT_POL_HIGH HAL_BIT(24) #define SCR_PROTOCOL_SELECT_SHIFT 22 #define SCR_PROTOCOL_SELECT_MASK (0x3UL << SCR_PROTOCOL_SELECT_SHIFT) typedef enum { SCR_PROTOCOL_T0 = 0UL, SCR_PROTOCOL_T1, } SCR_PROTOL_SEL; #define SCR_ATR_ST_FLUSH_FIFO_BIT HAL_BIT(21) #define SCR_TS_RX_EN HAL_BIT(20) #define SCR_CLK_STOP_PROTOL_BIT HAL_BIT(19) #define SCR_PARITY_ERR_RX_EN HAL_BIT(18) #define SCR_MSB_FIRST_EN HAL_BIT(17) #define SCR_DATA_POL_BIT HAL_BIT(16) #define SCR_DEACT_BIT HAL_BIT(11) #define SCR_ACT_BIT HAL_BIT(10) #define SCR_WARM_RESET_BIT HAL_BIT(9) #define SCR_CLK_STOP_BIT HAL_BIT(8) #define SCR_GINT_EN HAL_BIT(2) #define SCR_RX_EN HAL_BIT(1) #define SCR_TX_EN HAL_BIT(0) /* SCREDAER->SCR_INT_EN & SCREDAER->SCR_INT_ST */ #define SCR_INT_ALL_MASK 0xFF1E1FUL #define SCR_INT_DEACT HAL_BIT(23) #define SCR_INT_ACT HAL_BIT(22) #define SCR_INT_INSERT HAL_BIT(21) #define SCR_INT_REMOVE HAL_BIT(20) #define SCR_INT_ATR_DONE HAL_BIT(19) #define SCR_INT_ATR_FAIL HAL_BIT(18) #define SCR_INT_C2CFULL HAL_BIT(17) /* Character Timout */ #define SCR_INT_CLOCK_STOPRUN HAL_BIT(16) #define SCR_INT_RXPARITY_ERR HAL_BIT(12) #define SCR_INT_RX_DONE HAL_BIT(11) #define SCR_INT_RXFIFO_THR HAL_BIT(10) #define SCR_INT_RXFIFO_FULL HAL_BIT(9) #define SCR_INT_TXPARITY_ERR HAL_BIT(4) #define SCR_INT_TX_DONE HAL_BIT(3) #define SCR_INT_TXFIFO_THR HAL_BIT(2) #define SCR_INT_TXFIFO_EMPTY HAL_BIT(1) #define SCR_INT_TXFIFO_DONE HAL_BIT(0) /* SCREDAER->SCR_FIFO_CSR */ #define SCR_FLUSH_RXFIFO HAL_BIT(10) #define SCR_RXFIFO_FULL HAL_BIT(9) #define SCR_RXFIFO_EMPTY HAL_BIT(8) #define SCR_FLUSH_TXFIFO HAL_BIT(2) #define SCR_TXFIFO_FULL HAL_BIT(1) #define SCR_TXFIFO_EMPTY HAL_BIT(0) /* SCREDAER->SCR_FIFO_CNT */ #define SCR_FIFO_CNT_MASK 0xFFUL #define SCR_RXFIFO_THR_SHIFT 24 #define SCR_TXFIFO_THR_SHIFT 16 #define SCR_RXFIFO_CNT_SHIFT 8 #define SCR_TXFIFO_CNT_SHIFT 0 /* SCREDAER->SCR_FIFO_REPEAT */ #define SCR_REPEAT_MASK 0xFUL #define SCR_RX_REPEAT_NUM_SHIFT 4 #define SCR_TX_REPEAT_NUM_SHIFT 0 /* SCREDAER->SCR_CLKDIV */ #define SCR_CLKDIV_MASK 0xFFFFUL #define SCR_BAUD_DIV_SHIFT 16 #define SCR_MCLK_DIV_SHIFT 0 /* SCREDAER->SCR_LTIM */ #define SCR_LTIM_8BTI_MASK 0xFFUL #define SCR_LTIM_ATR_SHIFT 16 #define SCR_LTIM_RST_SHIFT 8 #define SCR_LTIM_ACT_SHIFT 0 /* SCREDAER->SCR_CTIM */ #define SCR_CTIM_CHARLIMT_MASK 0xFFFFUL #define SCR_CTIM_CHARLIMT_SHIFT 16 #define SCR_CTIM_GUARDTIME_MASK 0xFFUL #define SCR_CTIM_GUARDTIME_SHIFT 0 /* SCREDAER->SCR_PAD */ #define SCR_PAD_DSCVPP_PP HAL_BIT(7) #define SCR_PAD_DSCVPP_EN HAL_BIT(6) #define SCR_PAD_AUTO_ACT_VPP HAL_BIT(5) #define SCR_PAD_DSC_VCC HAL_BIT(4) #define SCR_PAD_DSC_RST HAL_BIT(3) #define SCR_PAD_DSC_CLK HAL_BIT(2) #define SCR_PAD_DSC_IO HAL_BIT(1) #define SCR_PAD_DIR_AC_PADS HAL_BIT(0) /* SCREDAER->SCR_FSM */ #define SCR_RSM_8BIT_MASK 0xFFUL #define SCR_FSM_ATR_STRUCT (SCR_RSM_8BIT_MASK << 24) #define SCR_FSM_ATR (SCR_RSM_8BIT_MASK << 16) #define SCR_FSM_ACT (SCR_RSM_8BIT_MASK << 8) #define SCR_FSM_SCR (SCR_RSM_8BIT_MASK << 0) /* SCREDAER->SCR_FIFO_DATA */ #define SCR_FIFO_DATA_MASK 0xFFUL /* SCR Card State FSM */ #define SCR_CARD_IDLE 0x0 #define SCR_CARD_ACT 0x1 #define SCR_CARD_ATR 0x2 #define SCR_CARD_DATA 0x3 #define SCR_CARD_DEACT 0x4 /* SCR Active/Deactive State FSM */ #define SCR_ACT_INACTIVE 0x0 #define SCR_ACT_A1 0x1 /* Vcc shall be powered */ #define SCR_ACT_A2 0x2 /* I/O shall be put in reception mode */ #define SCR_ACT_A3 0x3 /* Vpp shall be raised to idle state (if AutoVPP) */ #define SCR_ACT_ACTIVE 0x4 /* CLK shall be provided with a suitable and stable clock */ #define SCR_ACT_D1 0x5 /* State L on RST */ #define SCR_ACT_D2 0x6 /* State L on CLK */ #define SCR_ACT_D3 0x7 /* Vpp inactive (if AutoVPP) */ #define SCR_ACT_D4 0x8 /* State A on I/O */ #define SCR_ACT_D5 0x9 /* Vcc inactive */ /* SCR ATR State FSM */ #define SCR_ATR_IDLE 0x0 #define SCR_ATR_RST 0x1 #define SCR_ATR_WAIT 0x2 #define SCR_ATR_START 0x3 #define SCR_ATR_DONEx 0x4 #define SCR_ATR_FAILx 0x5 /* SCR ATR Structure State FSM */ #define SCR_STR_IDLE 0x0 #define SCR_STR_TS 0x1 #define SCR_STR_T0 0x2 #define SCR_STR_TX 0x3 #define SCR_STR_TK 0x4 #define SCR_STR_TCK 0x5 #define SCR_STR_DONE 0x6 #define SCR_STR_FAIL 0x7 #define SCR_FSM_MAX_RECORD 1024 typedef struct { uint32_t count; uint32_t old; uint32_t record[SCR_FSM_MAX_RECORD]; } scr_fsm_record, *pscr_fsm_record; typedef struct { uint8_t TS; uint8_t TK[15]; uint8_t TK_NUM; uint32_t T; /*Protocol */ uint32_t FMAX; /*in MHz */ uint32_t F; uint32_t D; uint32_t I; /* Max Cunrrent for Program, in mA */ uint32_t P; /* Program Voltage */ uint32_t N; /* Extra Guard Time, in ETUs */ } scatr_struct, *pscatr_struct; typedef struct { uint8_t ppss; uint8_t pps0; uint8_t pps1; uint8_t pps2; uint8_t pps3; uint8_t pck; } upps_struct, *ppps_struct; typedef enum { STS_WAIT_CONNECT = 0, STS_WAIT_ACT, STS_WAIT_ATR, STS_WARM_RESET, STS_WAIT_ATR_AGAIN, STS_START_PPS, STS_WAIT_PPS_RESP, STS_SEND_CMD, STS_START_DEACT, STS_WAIT_DEACT, STS_WAIT_DISCONNECT, STS_IDLE, STS_RW_TEST, } SCR_TEST_STAGE; /** @brief Type define of QDEC interrupt callback function */ typedef void (*SCR_IRQCallback)(void *arg); /** * @brief SCR initialization parameters */ typedef struct { uint32_t mclk; /* smart card clock frequency */ uint8_t fifo_thr; /* tx & rx fifo threshold */ uint8_t repeat_num; /* the re-transmission time when wrong parity */ uint8_t act_time; /* activation/deactivation time */ uint8_t rst_time; /* reset duration */ uint8_t atr_time; /* atr start limit */ uint8_t guard_time; /* character guard time */ uint32_t char_limit; /* character limit */ SCR_IRQCallback IRQCallback; void *arg; } SCR_InitParam; /* write cmd and read data immediately */ typedef struct { uint8_t *cmd_buf; uint32_t cmd_len; uint8_t *rtn_data; uint32_t rtn_len; uint8_t psw1; uint8_t psw2; } SCR_WRData; /** * @brief Initialize the SCR * @retval HAL_Status, HAL_OK on success */ HAL_Status HAL_SCR_Init(SCR_InitParam *initParam); /** * @brief DeInitialize the SCR * @retval HAL_Status, HAL_OK on success */ HAL_Status HAL_SCR_DeInit(void); SCR_TEST_STAGE HAL_SCR_Process(SCR_InitParam *initParam); /** * @brief SCR write the assigned length data, send in polling mode * @retval Number of bytes transmitted, -1 on error */ int32_t HAL_SCR_SendByPoll(uint8_t *buf, int32_t size); /** * @brief SCR write the assigned length data, suspend current thread until send finish * @retval Number of bytes transmitted, -1 on error */ int32_t HAL_SCR_SendByIT(uint8_t *buf, int32_t size); /** * @brief SCR read the assigned length data, suspend current thread until received finish * @retval Number of bytes received, -1 on error */ int32_t HAL_SCR_ReceiveByIT(uint8_t *buf, int32_t size); /** * @brief Send APDU command to card, and receive data from card * @param[in] apdu_t load apdu command parameters * @return 0 on success, -1 on error * @note APDU, smart card cammand format: * send format: * type1: CLS + INS + P1 + P2 + le -> only read, le=read size * type2: CLS + INS + P1 + P2 + lc + data only lc, write data, lc=data size * type3: CLS + INS + P1 + P2 + lc + data +le -> le + lc * respond format: * type1: INS(apdu_t->cmd_buf[1]) + valid_data(apdu_t->cmd_buf[4]) + SW1 + SW2 * type2: INS + SW1 + SW2 * type3: INS + valid_data + SW1 + SW2 */ HAL_Status HAL_SCR_APDUCmd(SCR_WRData *apdu_t); #ifdef __cplusplus } #endif #endif /* _DRIVER_CHIP_HAL_SCR_H_ */