• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 #include "s7816.h"
19 #include "dma.h"
20 #include "plic.h"
21 
22 volatile unsigned int s7816_rst_pin;
23 volatile unsigned int s7816_vcc_pin;
24 volatile unsigned int s7816_rtx_pin;
25 volatile unsigned char s7816_clock;
26 volatile int s7816_rst_time;  // us
27 volatile int s7816_atr_time;  // us
28 /**
29  * @brief      	This function is used to set the s7816 clock.
30  * @param[in]  	div	- set the divider of clock of 7816 module.
31  * @return     	none.
32  * @note        system clk is 24MHZ
33  * 				7816clk:    0x60-4Mhz     0x40-6Mhz   0x20-12Mhz
34  * 				baudrate:   0x60-10752    0x40-16194  0x20-32388
35  * 				the clk-pin is PA0 by default.
36  */
s7816_set_clk(unsigned char div)37 void s7816_set_clk(unsigned char div)
38 {
39     reg_7816_clk_div &= 0x0f;
40     reg_7816_clk_div |= (unsigned char)div;
41 }
42 
43 /**
44  * @brief      	This function is used to set the rst-wait time of the s7816 module.
45  * @param[in]  	rst_time_us - set the s7816_rst_time.
46  * @param[in]  	atr_time_us - set the s7816_atr_time.
47  * @return     	none.
48  */
s7816_set_time(int rst_time_us,int atr_time_us)49 void s7816_set_time(int rst_time_us, int atr_time_us)
50 {
51     s7816_rst_time = rst_time_us;
52     s7816_atr_time = atr_time_us;
53 }
54 /**
55  * @brief      	This function is used to set the RST pin of s7816.
56  * @param[in]  	pin_7816_rst - the RST pin of s7816.
57  * @return     	none.
58  */
s7816_set_rst_pin(gpio_pin_e pin_7816_rst)59 void s7816_set_rst_pin(gpio_pin_e pin_7816_rst)
60 {
61     s7816_rst_pin = pin_7816_rst;
62     gpio_function_en(pin_7816_rst);
63     gpio_output_en(pin_7816_rst);
64     gpio_input_dis(pin_7816_rst);
65     gpio_set_low_level(pin_7816_rst);
66 }
67 
68 /**
69  * @brief      	This function is used to set the VCC pin of s7816.
70  * @param[in]   pin_7816_vcc - the VCC pin of s7816.
71  * @return     	none.
72  */
s7816_set_vcc_pin(gpio_pin_e pin_7816_vcc)73 void s7816_set_vcc_pin(gpio_pin_e pin_7816_vcc)
74 {
75     s7816_vcc_pin = pin_7816_vcc;
76     gpio_function_en(pin_7816_vcc);
77     gpio_output_en(pin_7816_vcc);
78     gpio_input_dis(pin_7816_vcc);
79     gpio_set_low_level(pin_7816_vcc);
80 }
81 
82 /**
83  * @brief      	This function is used to initialize the s7816 module.
84  * @param[in]  	uart_num     - UART0 or UART1.
85  * @param[in]  	clock        - the clock of s7816.
86  * @param[in]  	f            - the clock frequency regulator of s7816,372 by default.
87  * @param[in]  	d            - the bitrate regulator of s7816,1 by default.
88  * @return     	none.
89  */
s7816_init(uart_num_e uart_num,s7816_clock_e clock,int f,int d)90 void s7816_init(uart_num_e uart_num, s7816_clock_e clock, int f, int d)
91 {
92     unsigned short div;
93     unsigned char bwpc;
94     s7816_clock = clock;
95     s7816_rst_time = 40000 / clock;  // us
96     s7816_atr_time = 40000 / clock;  // us
97 
98     int baud = clock * 1000000 * d / f;
99     if (clock == S7816_4MHZ) {
100         s7816_set_clk(0x60);
101     } else if (clock == S7816_6MHZ) {
102         s7816_set_clk(0x40);
103     } else if (clock == S7816_12MHZ) {
104         s7816_set_clk(0x20);
105     }
106     uart_reset(uart_num);
107     uart_cal_div_and_bwpc(baud, 24 * 1000 * 1000, &div, &bwpc);
108     uart_init(uart_num, div, bwpc, UART_PARITY_EVEN,
109               UART_STOP_BIT_ONE);  // 7816 protocol stipulate the parity bit should be even.
110 }
111 
112 /**
113  * @brief      	This function is used to set all the pin of s7816 module.
114  * @param[in]  	rst_pin     - the rst pin of s7816.
115  * @param[in]  	vcc_pin     - the vcc pin of s7816.
116  * @param[in]  	clk_pin     - the clk pin of s7816.
117  * @param[in]  	trx_pin     - the trx pin of s7816.
118  * @return     	none.
119  */
s7816_set_pin(gpio_pin_e rst_pin,gpio_pin_e vcc_pin,s7816_clk_pin_e clk_pin,s7816_rtx_pin_e rtx_pin)120 void s7816_set_pin(gpio_pin_e rst_pin, gpio_pin_e vcc_pin, s7816_clk_pin_e clk_pin, s7816_rtx_pin_e rtx_pin)
121 {
122     s7816_set_rst_pin(rst_pin);
123     s7816_rst_pin = rst_pin;
124 
125     s7816_set_vcc_pin(vcc_pin);
126     s7816_vcc_pin = vcc_pin;
127 
128     reg_gpio_func_mux(clk_pin) = (reg_gpio_func_mux(clk_pin) & (~BIT_RNG(0, 1))) | BIT(0);
129     gpio_function_dis(clk_pin);
130 
131     s7816_rtx_pin = rtx_pin;  // if the trx function set to early,it may trigger interrupt by accident.
132                               // so we set the function in coldreset.
133 }
134 
135 /**
136  * @brief      	This function is used to active the IC card,set the trx pin and coldreset.
137  * @param[in]  	none.
138  * @return     	none.
139  */
s7816_coldreset(void)140 void s7816_coldreset(void)
141 {
142     gpio_set_high_level(s7816_vcc_pin);
143     delay_us(20);                //  wait for the vcc  stable.
144     reg_7816_clk_div |= BIT(7);  //  enable the 7816 clk,the pin is A0.
145     delay_us(s7816_rst_time);
146     s7816_set_rtx_pin(s7816_rtx_pin);    // uart tx/rx pin set,if the trx pin set before this place,it may
147     gpio_set_high_level(s7816_rst_pin);  // the IC card will return the initial ATR.
148     delay_us(s7816_atr_time);
149 }
150 
151 /**
152  * @brief      	This function is used to release the trigger.
153  * @param[in]  	none.
154  * @return     	none.
155  */
s7816_release_trig(void)156 void s7816_release_trig(void)
157 {
158     gpio_set_low_level(s7816_rst_pin);
159     reg_7816_clk_div &= (BIT(7) - 1);
160     gpio_set_low_level(s7816_vcc_pin);
161 }
162 
163 /**
164  * @brief      	This function is used to warmreset.
165  * @param[in]  	none.
166  * @return     	none.
167  * @note        the warmreset is required after the IC-CARD active.
168  */
s7816_warmreset(void)169 void s7816_warmreset(void)
170 {
171     gpio_set_low_level(s7816_rst_pin);
172     delay_us(s7816_rst_time);
173     gpio_set_high_level(s7816_rst_pin);  // The IC card will return the initial ATR.
174     delay_us(s7816_atr_time);
175 }
176 
177 /**
178  * @brief      	This function is used to warmreset.
179  * @param[in]  	uart_num - UART0 or UART1.
180  * @param[in]   tx_data  - the data need to send.
181  * return       none.
182  */
s7816_send_byte(uart_num_e uart_num,unsigned char tx_data)183 void s7816_send_byte(uart_num_e uart_num, unsigned char tx_data)
184 {
185     uart_send_byte(uart_num, tx_data);
186     uart_rtx_pin_tx_trig(uart_num);
187 }
188