• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /****************************************************************************
17  * @file     wm_i2s.c
18  * @author
19  * @version
20  * @date
21  * @brief
22  *
23  * Copyright (c) 2014 Winner Microelectronics Co., Ltd. All rights reserved.
24  *****************************************************************************/
25 
26 #include <stdbool.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include "wm_regs.h"
30 #include "wm_gpio.h"
31 #include "wm_uart.h"
32 #include "wm_cpu.h"
33 #include "wm_7816.h"
34 
35 #include "wm_osal.h"
36 
37 #define DEBUG_7816        1
38 
39 #if DEBUG_7816
40 #define PRINT_DEBUG(fmt, args...)   do {(printf("[DEBUG] "), printf(fmt, ##args));}while (0)
41 #else
42 #define PRINT_DEBUG(fmt, args...)
43 #endif
44 
45 #define SYS_CLK        (40000000)
46 #define WM_SC_RST_PIN        WM_IO_PB_23 // (23)
47 #define WM_SC_PWR_PIN        WM_IO_PB_24 // (29)
48 
49 sc_io_map sc_io;
50 
51 /**
52  * @brief
53  *    This function is used to config the pin in gpio or 7816 mode for the 7816 power on timing
54  * @param[in] mode : 1--gpio mode ; 0--7816 mode
55  * @retval
56  */
wm_sc_io_clk_config(uint8_t mode)57 void wm_sc_io_clk_config(uint8_t mode)
58 {
59     if (sc_io.initialed == 0) {
60         printf("error : 7816 io map must init....\r\n");
61         return ;
62     }
63     if (mode) { // gpio mode
64         tls_io_cfg_set(sc_io.clk_pin_num, WM_IO_OPTION5);
65         tls_io_cfg_set(sc_io.io_pin_num, WM_IO_OPTION5);
66         tls_gpio_cfg(sc_io.clk_pin_num, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
67         tls_gpio_cfg(sc_io.io_pin_num, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
68     } else  { // 7816 mode
69         tls_io_cfg_set(sc_io.clk_pin_num, sc_io.clk_opt);
70         tls_io_cfg_set(sc_io.io_pin_num, sc_io.io_opt);
71     }
72 }
73 
74 /**
75  * @brief
76  *    This function is used to config the block guard time param in 7816 mode
77  * @param[in] bgt : the value of blcok guard time will be set
78  * @retval
79  */
wm_sc_set_bgt(uint8_t bgt)80 void wm_sc_set_bgt(uint8_t bgt)
81 {
82     uint32_t reg;
83     bgt = (bgt > 0x1f) ? 0x1F : bgt;
84     reg = tls_reg_read32(HR_UART2_LINE_CTRL);
85     reg &= ~(0x1f << 11);
86     reg |= (bgt << 11);
87     tls_reg_write32(HR_UART2_LINE_CTRL, reg);
88 }
89 
90 /**
91  * @brief
92  *    This function is used to config the tx retry count when detect err signal
93  * @param[in] count : the value of retry time will be set 7 for max
94  * @retval
95  */
wm_sc_tx_retry_times(uint8_t count)96 void wm_sc_tx_retry_times(uint8_t count)
97 {
98     uint32_t reg;
99     reg = tls_reg_read32(HR_UART2_LINE_CTRL);
100     reg &= ~(0x7 << 16);
101     tls_reg_write32(HR_UART2_LINE_CTRL, reg|(count<<16));
102     tls_bitband_write(HR_UART2_LINE_CTRL, 23, 1);
103 }
104 
105 /**
106  * @brief
107  *    This function is used to config the rx retry count when detect parity error
108  * @param[in] count : the value of retry time will be set 7 for max
109  * @retval
110  */
wm_sc_rx_retry_times(uint8_t count)111 void wm_sc_rx_retry_times(uint8_t count)
112 {
113     uint32_t reg;
114     reg = tls_reg_read32(HR_UART2_LINE_CTRL);
115     reg &= ~(0x7 << 20);
116     tls_reg_write32(HR_UART2_LINE_CTRL, reg|(count<<20));
117     tls_bitband_write(HR_UART2_LINE_CTRL, 19, 1);
118 }
119 
120 /**
121  * @brief
122  *    This function is used to config the etu param
123  * @param[in] etu : the value of etu will be set
124  * @retval
125  */
wm_sc_set_etu(uint16_t etu)126 void wm_sc_set_etu(uint16_t etu)
127 {
128     uint32_t reg;
129 
130     reg = tls_reg_read32(HR_UART2_BAUD_RATE_CTRL);
131     reg &= ~ 0xFFFF;
132     reg |= etu;
133     tls_reg_write32(HR_UART2_BAUD_RATE_CTRL, reg);
134 }
135 
136 /**
137  * @brief
138  *    This function config the module clock freq
139  * @param[in] freq : the value of clock freq
140  * @retval
141  */
wm_sc_set_frequency(uint32_t freq)142 void wm_sc_set_frequency(uint32_t freq)
143 {
144     uint32_t reg;
145     uint8_t div;
146     tls_sys_clk clk;
147 
148     tls_sys_clk_get(&clk);
149 
150     div = (clk.apbclk * 1000000 + freq)/(2 * freq) - 1;
151 
152     reg = tls_reg_read32(HR_UART2_BAUD_RATE_CTRL);
153     reg &= ~ 0x3F0000;
154     reg |= (div<<16);
155     tls_reg_write32(HR_UART2_BAUD_RATE_CTRL, reg);
156 }
157 
158 /**
159  * @brief
160  *    close af to use PB23 and PB24(uart2_rx as default if af is on) as gpio
161  * @retval
162  */
wm_sc_powerInit(void)163 void wm_sc_powerInit(void)
164 {
165 #ifdef WM_SC_PWR_PIN
166     tls_gpio_cfg(WM_SC_RST_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
167     tls_gpio_cfg(WM_SC_PWR_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
168 #endif
169 }
170 
171 /**
172  * @brief
173  *    power on the 7816 device if power is controled by GPIO
174  * @retval
175  */
wm_sc_poweron(void)176 void wm_sc_poweron(void)
177 {
178 #ifdef WM_SC_PWR_PIN
179     tls_gpio_cfg(WM_SC_PWR_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
180     tls_gpio_write(WM_SC_PWR_PIN, 1);
181 #endif
182 }
183 
184 /**
185  * @brief
186  *    power off the 7816 device if power is controled by GPIO
187  * @retval
188  */
wm_sc_poweroff(void)189 void wm_sc_poweroff(void)
190 {
191 #ifdef WM_SC_PWR_PIN
192     tls_gpio_cfg(WM_SC_PWR_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
193     tls_gpio_write(WM_SC_PWR_PIN, 0);
194 #endif
195 }
196 
197 /**
198  * @brief
199  *    driver the reset gpio in low level
200  * @retval
201  */
wm_sc_rst_low(void)202 void wm_sc_rst_low(void)
203 {
204 #ifdef WM_SC_RST_PIN
205     tls_gpio_cfg(WM_SC_RST_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
206     tls_gpio_write(WM_SC_RST_PIN, 0);
207 #endif
208 }
209 
210 /**
211  * @brief
212  *    driver the reset gpio in high level
213  * @retval
214  */
wm_sc_rst_high(void)215 void wm_sc_rst_high(void)
216 {
217 #ifdef WM_SC_RST_PIN
218     tls_gpio_cfg(WM_SC_RST_PIN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
219     tls_gpio_write(WM_SC_RST_PIN, 1);
220 #endif
221 }
222 
223 /**
224  * @brief
225  *    hotrest the 7816 device obey the 7816-3 timing
226  * @retval
227  */
wm_sc_hotreset(void)228 void wm_sc_hotreset(void)
229 {
230     uint32_t delay = 0xffff;
231 
232     /* set the rst pin to low */
233     wm_sc_rst_low();
234     /* delay */
235     while (delay--);
236     /* set f/d to default 372 */
237     wm_sc_set_etu(WM_SC_DEFAULT_FD);
238     /* set the rst pin to high */
239     wm_sc_rst_high();
240 }
241 
242 /**
243  * @brief
244  *    colreset the 7816 device obey the 7816-3 timing
245  * @retval
246  */
wm_sc_colreset(void)247 void wm_sc_colreset(void)
248 {
249     /* power down */
250     wm_sc_poweroff();
251     /* select the clk io in gpio mode */
252     wm_sc_io_clk_config(1);
253     /* reset the clk pin */
254     tls_gpio_write(sc_io.clk_pin_num, 0);
255     /* reset the io pin */
256     tls_gpio_write(sc_io.io_pin_num, 0);
257     /* set the ret pin to low */
258     wm_sc_rst_low();
259     /* power on the card */
260     wm_sc_poweron();
261     /* config the model in 7816 mode */
262     wm_sc_7816_mode(1);
263     /* select the clk io pin in 7816 mode */
264     wm_sc_io_clk_config(0);
265     /* config the output clock freq */
266     wm_sc_set_frequency(5000000);
267     /* set the F/D to default (372) */
268     wm_sc_set_etu(WM_SC_DEFAULT_FD);
269     /* set the rst pin to high */
270     wm_sc_rst_high();
271 }
272 
273 /**
274  * @brief
275  *    deactive the 7816 device obey the 7816-3 timing
276  * @retval
277  */
wm_sc_deactive(void)278 void wm_sc_deactive(void)
279 {
280     /* set the rst pin in low level */
281     wm_sc_rst_low();
282     /* select the clk and io pin to 7816 mode */
283     wm_sc_io_clk_config(0);
284     /* disable the output clock */
285     wm_sc_clk_enable(0);
286     /* select the clk and io pin to gpio mode */
287     wm_sc_io_clk_config(1);
288     /* set the clk pin to low */
289     tls_gpio_write(sc_io.clk_pin_num, 0);
290     /* set the io pin to low */
291     tls_gpio_write(sc_io.io_pin_num, 0);
292     /* set the power pin to low */
293     wm_sc_poweroff();
294 }