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
19 /********************************************************************************************************
20 * @file s7816.c
21 *
22 * @brief This is the source file for B91
23 *
24 * @author Driver Group
25 *
26 *******************************************************************************************************/
27 #include "s7816.h"
28 #include "dma.h"
29 #include "plic.h"
30
31 volatile unsigned int s7816_rst_pin;
32 volatile unsigned int s7816_vcc_pin;
33 volatile unsigned int s7816_rtx_pin;
34 volatile unsigned char s7816_clock;
35 volatile int s7816_rst_time;//us
36 /**
37 * @brief This function is used to set the s7816 clock.
38 * @param[in] div - set the divider of clock of 7816 module.
39 * @return none.
40 * @note the clk-source of s7816 is 24M-pad,the clk of clk-pin can be divided as follow.
41 * div: 0x60-4Mhz 0x40-6Mhz 0x20-12Mhz
42 * baudrate: 0x60-10752 0x40-16194 0x20-32388
43 */
s7816_set_clk(unsigned char div)44 void s7816_set_clk(unsigned char div)
45 {
46 reg_7816_clk_div&=0x0f;
47 reg_7816_clk_div|=(unsigned char)div;
48 }
49
50 /**
51 * @brief This function is used to set the rst-wait time of the s7816 module.
52 * @param[in] rst_time_us - set the s7816_rst_time.
53 * @return none.
54 */
s7816_set_time(int rst_time_us)55 void s7816_set_time(int rst_time_us)
56 {
57 s7816_rst_time=rst_time_us;
58 }
59 /**
60 * @brief This function is used to set the RST pin of s7816.
61 * @param[in] pin_7816_rst - the RST pin of s7816.
62 * @return none.
63 */
s7816_set_rst_pin(gpio_pin_e pin_7816_rst)64 void s7816_set_rst_pin(gpio_pin_e pin_7816_rst)
65 {
66 s7816_rst_pin=pin_7816_rst;
67 gpio_function_en(pin_7816_rst);
68 gpio_output_en(pin_7816_rst);
69 gpio_input_dis(pin_7816_rst);
70 gpio_set_low_level(pin_7816_rst);
71 }
72
73 /**
74 * @brief This function is used to set the VCC pin of s7816.
75 * @param[in] pin_7816_vcc - the VCC pin of s7816.
76 * @return none.
77 */
s7816_set_vcc_pin(gpio_pin_e pin_7816_vcc)78 void s7816_set_vcc_pin(gpio_pin_e pin_7816_vcc)
79 {
80 s7816_vcc_pin=pin_7816_vcc;
81 gpio_function_en(pin_7816_vcc);
82 gpio_output_en(pin_7816_vcc);
83 gpio_input_dis(pin_7816_vcc);
84 gpio_set_low_level(pin_7816_vcc);
85 }
86
87 /**
88 * @brief This function is used to initialize the s7816 module.
89 * @param[in] uart_num - UART0 or UART1.
90 * @param[in] clock - the clock of s7816.
91 * @param[in] f - the clock frequency regulator of s7816,372 by default.
92 * @param[in] d - the bitrate regulator of s7816,1 by default.
93 * @return none.
94 */
s7816_init(uart_num_e uart_num,s7816_clock_e clock,int f,int d)95 void s7816_init(uart_num_e uart_num,s7816_clock_e clock,int f,int d)
96 {
97 unsigned short div;
98 unsigned char bwpc;
99 s7816_clock=clock;
100 s7816_rst_time=40000/clock;//us
101
102 int baud=clock*1000000*d/f;
103 if(clock==S7816_4MHZ)
104 {
105 s7816_set_clk(0x60);
106 }
107 else if(clock==S7816_6MHZ)
108 {
109 s7816_set_clk(0x40);
110 }
111 else if(clock==S7816_12MHZ)
112 {
113 s7816_set_clk(0x20);
114 }
115 uart_reset(uart_num);
116 uart_cal_div_and_bwpc(baud, 24*1000*1000, &div, &bwpc);
117 uart_init(uart_num, div, bwpc, UART_PARITY_EVEN, UART_STOP_BIT_ONE);//7816 protocol stipulate the parity bit should be even.
118 }
119
120 /**
121 * @brief This function is used to set all the pin of s7816 module.
122 * @param[in] rst_pin - the rst pin of s7816.
123 * @param[in] vcc_pin - the vcc pin of s7816.
124 * @param[in] clk_pin - the clk pin of s7816.
125 * @param[in] trx_pin - the trx pin of s7816.
126 * @return none.
127 */
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)128 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)
129 {
130 s7816_set_rst_pin(rst_pin);
131 s7816_rst_pin=rst_pin;
132
133 s7816_set_vcc_pin(vcc_pin);
134 s7816_vcc_pin=vcc_pin;
135
136 reg_gpio_func_mux(clk_pin)=(reg_gpio_func_mux(clk_pin)&(~BIT_RNG(0,1)))|BIT(0);
137 gpio_function_dis(clk_pin);
138
139 s7816_rtx_pin=rtx_pin;//if the trx function set to early,it may trigger interrupt by accident.so we set the function in coldreset.
140 }
141
142 /**
143 * @brief This function is used to active the IC card,set the trx pin and coldreset.
144 * @param[in] none.
145 * @return none.
146 * @note extra time is needed for initial-atr after the function.
147 */
s7816_coldreset()148 void s7816_coldreset()
149 {
150 gpio_set_high_level(s7816_vcc_pin);
151 delay_us(20);//wait for the vcc stable.
152 reg_7816_clk_div|=BIT(7); //enable the 7816 clk,the pin is A0.
153 delay_us(s7816_rst_time);
154 s7816_set_rtx_pin(s7816_rtx_pin);// uart tx/rx pin set,if the trx pin set before this place,it may
155 gpio_set_high_level(s7816_rst_pin);//the IC card will return the initial ATR.
156 }
157
158 /**
159 * @brief This function is used to release the trigger.
160 * @param[in] none.
161 * @return none.
162 */
s7816_release_trig()163 void s7816_release_trig()
164 {
165 gpio_set_low_level(s7816_rst_pin);
166 reg_7816_clk_div&=(BIT(7)-1);
167 gpio_set_low_level(s7816_vcc_pin);
168 }
169
170 /**
171 * @brief This function is used to warmreset.
172 * @param[in] none.
173 * @return none.
174 * @note the warmreset is required after the IC-CARD active,extra time is needed for initial-atr after the function.
175 */
s7816_warmreset()176 void s7816_warmreset()
177 {
178 gpio_set_low_level(s7816_rst_pin);
179 delay_us(s7816_rst_time);
180 gpio_set_high_level(s7816_rst_pin);//The IC card will return the initial ATR.
181 }
182
183 /**
184 * @brief This function is used to warmreset.
185 * @param[in] uart_num - UART0 or UART1.
186 * @param[in] tx_data - the data need to send.
187 * return none.
188 */
s7816_send_byte(uart_num_e uart_num,unsigned char tx_data)189 void s7816_send_byte(uart_num_e uart_num, unsigned char tx_data)
190 {
191 uart_send_byte(uart_num,tx_data);
192 uart_rtx_pin_tx_trig(uart_num);
193 }
194