1 /**
2   ******************************************************************************
3   * @file    lib_iso7816.c
4   * @author  Application Team
5   * @version V4.4.0
6   * @date    2018-09-27
7   * @brief   ISO7816 library.
8   ******************************************************************************
9   * @attention
10   *
11   ******************************************************************************
12   */
13 #include "lib_iso7816.h"
14 #include "lib_clk.h"
15 
16 //registers default reset values
17 #define ISO7816_BAUDDIVL_RSTValue   0
18 #define ISO7816_BAUDDIVH_RSTValue   0
19 #define ISO7816_CFG_RSTValue        0
20 #define ISO7816_CLK_RSTValue        0
21 
22 #define ISO7816_INFO_RC_MASK    (0xECUL) //R/C
23 #define ISO7816_INFO_RW_MASK    (0x13UL) //R/W
24 
25 /**
26   * @brief  ISO7816 initialization.
27   * @param  ISO7816x: ISO78160~ISO78161
28             Init_Struct:iso7816 configuration.
29                 FirstBit:
30                     ISO7816_FIRSTBIT_LSB
31                     ISO7816_FIRSTBIT_MSB
32                 ACKLen:
33                     ISO7816_ACKLEN_1
34                     ISO7816_ACKLEN_2
35                 Parity:
36                     ISO7816_PARITY_EVEN
37                     ISO7816_PARITY_ODD
38                 Baudrate: Baud rate value
39   * @retval None
40   */
ISO7816_Init(ISO7816_TypeDef * ISO7816x,ISO7816_InitType * Init_Struct)41 void ISO7816_Init(ISO7816_TypeDef *ISO7816x, ISO7816_InitType *Init_Struct)
42 {
43   uint32_t tmp;
44   uint16_t div;
45   uint32_t pclk;
46 
47   /* Check parameters */
48   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
49   assert_parameters(IS_ISO7816_FIRSTBIT(Init_Struct->FirstBit));
50   assert_parameters(IS_ISO7816_ACKLEN(Init_Struct->ACKLen));
51   assert_parameters(IS_ISO7816_PARITY(Init_Struct->Parity));
52   assert_parameters(IS_ISO7816_BAUDRATE(Init_Struct->Baudrate));
53 
54   tmp = ISO7816x->INFO;
55   tmp &= ~(ISO7816_INFO_LSB|ISO7816_INFO_RC_MASK);
56   tmp |= Init_Struct->FirstBit;
57   ISO7816x->INFO = tmp;
58 
59   tmp = ISO7816x->CFG;
60   tmp &= ~(ISO7816_CFG_ACKLEN\
61           |BIT3\
62           |BIT2\
63           |ISO7816_CFG_CHKP);
64   tmp |= (Init_Struct->ACKLen\
65          |Init_Struct->Parity);
66   ISO7816x->CFG = tmp;
67 
68   pclk = CLK_GetPCLKFreq();
69   div = 0x10000 - (pclk/Init_Struct->Baudrate);
70   ISO7816x->BAUDDIVH = (div>>8) & ISO7816_BAUDDIVH;
71   ISO7816x->BAUDDIVL = div & ISO7816_BAUDDIVL;
72 }
73 
74 /**
75   * @brief  Fills each InitStruct member with its default value.
76   * @param  InitStruct: pointer to an ISO7816_InitType structure which will be initialized.
77   * @retval None
78   */
ISO7816_StructInit(ISO7816_InitType * InitStruct)79 void ISO7816_StructInit(ISO7816_InitType *InitStruct)
80 {
81   /*--------------- Reset ISO7816 init structure parameters values ---------------*/
82   /* Initialize the ACKLen member */
83   InitStruct->ACKLen = ISO7816_ACKLEN_1;
84   /* Initialize the Baudrate member */
85   InitStruct->Baudrate = 9600;
86   /* Initialize the FirstBit member */
87   InitStruct->FirstBit = ISO7816_FIRSTBIT_MSB;
88   /* Initialize the Parity member */
89   InitStruct->Parity = ISO7816_PARITY_EVEN;
90 }
91 
92 /**
93   * @brief  Initializes the ISO7816 peripheral registers to their default reset
94             values.
95   * @param  ISO7816x: ISO78160~ISO78161
96   * @retval None
97   */
ISO7816_DeInit(ISO7816_TypeDef * ISO7816x)98 void ISO7816_DeInit(ISO7816_TypeDef *ISO7816x)
99 {
100   /* Check parameters */
101   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
102 
103   ISO7816x->CFG &= ~ISO7816_CFG_EN;
104 
105   /* clear interrupt flag */
106   ISO7816x->INFO = ISO7816_INFO_RC_MASK;
107   ISO7816x->BAUDDIVH = ISO7816_BAUDDIVH_RSTValue;
108   ISO7816x->BAUDDIVL = ISO7816_BAUDDIVL_RSTValue;
109   ISO7816x->CFG = ISO7816_CFG_RSTValue;
110   ISO7816x->CLK = ISO7816_CLK_RSTValue;
111 }
112 
113 /**
114   * @brief  ISO7816 enable control.
115   * @param  ISO7816x: ISO78160~ISO78161
116             NewState:
117                 ENABLE
118                 DISABLE
119   * @retval None.
120   */
ISO7816_Cmd(ISO7816_TypeDef * ISO7816x,uint32_t NewState)121 void ISO7816_Cmd(ISO7816_TypeDef *ISO7816x, uint32_t NewState)
122 {
123   /* Check parameters */
124   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
125   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
126 
127   if (NewState == ENABLE)
128   {
129     ISO7816x->CFG |= ISO7816_CFG_EN;
130   }
131   else
132   {
133     ISO7816x->CFG &= ~ISO7816_CFG_EN;
134   }
135 }
136 
137 /**
138   * @brief  ISO7816 Baudrate control.
139   * @param  ISO7816x: ISO78160~ISO78161
140             BaudRate:
141   * @retval None
142   */
ISO7816_BaudrateConfig(ISO7816_TypeDef * ISO7816x,uint32_t BaudRate)143 void ISO7816_BaudrateConfig(ISO7816_TypeDef *ISO7816x, uint32_t BaudRate)
144 {
145   uint32_t pclk;
146   uint16_t div;
147 
148   /* Check parameters */
149   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
150   assert_parameters(IS_ISO7816_BAUDRATE(BaudRate));
151 
152   pclk = CLK_GetPCLKFreq();
153   div = 0x10000 - (pclk/BaudRate);
154   ISO7816x->BAUDDIVH = (div>>8) & ISO7816_BAUDDIVH;
155   ISO7816x->BAUDDIVL = div & ISO7816_BAUDDIVL;
156 }
157 
158 /**
159   * @brief  ISO7816 clock divider configure.
160   * @param  ISO7816x: ISO78160~ISO78161
161             Prescaler:1~128
162   * @retval None
163   */
ISO7816_CLKDIVConfig(ISO7816_TypeDef * ISO7816x,uint32_t Prescaler)164 void ISO7816_CLKDIVConfig(ISO7816_TypeDef *ISO7816x, uint32_t Prescaler)
165 {
166   uint32_t tmp;
167 
168   /* Check parameters */
169   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
170   assert_parameters(IS_ISO7816_PRESCALER(Prescaler));
171 
172   tmp = ISO7816x->CLK;
173   tmp &= ~ISO7816_CLK_CLKDIV;
174   tmp |= ((Prescaler - 1) & ISO7816_CLK_CLKDIV);
175   ISO7816x->CLK = tmp;
176 }
177 
178 /**
179   * @brief  ISO7816 clock output enable control.
180   * @param  ISO7816x: ISO78160~ISO78161
181             NewState:
182                 ENABLE
183                 DISABLE
184   * @retval None
185   */
ISO7816_CLKOutputCmd(ISO7816_TypeDef * ISO7816x,uint32_t NewState)186 void ISO7816_CLKOutputCmd(ISO7816_TypeDef *ISO7816x, uint32_t NewState)
187 {
188   /* Check parameters */
189   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
190   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
191 
192   if (NewState != DISABLE)
193   {
194     ISO7816x->CLK |= ISO7816_CLK_CLKEN;
195   }
196   else
197   {
198     ISO7816x->CLK &= ~ISO7816_CLK_CLKEN;
199   }
200 }
201 
202 /**
203   * @brief  Read data.
204   * @param  ISO7816: ISO78160~ISO78161
205   * @retval The received data.
206   */
ISO7816_ReceiveData(ISO7816_TypeDef * ISO7816x)207 uint8_t ISO7816_ReceiveData(ISO7816_TypeDef *ISO7816x)
208 {
209   /* Check parameters */
210   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
211 
212   return ISO7816x->DATA;
213 }
214 
215 /**
216   * @brief  Write data.
217   * @param  ISO7816x: ISO78160~ISO78161
218   * @retval None
219   */
ISO7816_SendData(ISO7816_TypeDef * ISO7816x,uint8_t ch)220 void ISO7816_SendData(ISO7816_TypeDef *ISO7816x, uint8_t ch)
221 {
222   /* Check parameters */
223   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
224 
225   ISO7816x->DATA = ch;
226 }
227 
228 /**
229   * @brief  Interrupt configure.
230   * @param  ISO7816x: ISO78160~ISO78161
231             INTMask:
232                 This parameter can be any combination of the following values
233                 ISO7816_INT_RXOV
234                 ISO7816_INT_RX
235                 ISO7816_INT_TX
236             NewState:
237                 ENABLE
238                 DISABLE
239   * @retval None
240   */
ISO7816_INTConfig(ISO7816_TypeDef * ISO7816x,uint32_t INTMask,uint8_t NewState)241 void ISO7816_INTConfig(ISO7816_TypeDef *ISO7816x, uint32_t INTMask, uint8_t NewState)
242 {
243   /* Check parameters */
244   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
245   assert_parameters(IS_ISO7816_INT(INTMask));
246   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
247 
248   if (NewState == ENABLE)
249   {
250     ISO7816x->CFG |= INTMask;
251   }
252   else
253   {
254     ISO7816x->CFG &= ~INTMask;
255   }
256 }
257 
258 /**
259   * @brief  Get interrupt state
260   * @param  ISO7816x: ISO78160~ISO78161
261             INTMask:
262                 ISO7816_INTSTS_RXOV
263                 ISO7816_INTSTS_RX
264                 ISO7816_INTSTS_TX
265   * @retval 1: state set
266             0: state reset
267   */
ISO7816_GetINTStatus(ISO7816_TypeDef * ISO7816x,uint32_t INTMask)268 uint8_t ISO7816_GetINTStatus(ISO7816_TypeDef *ISO7816x, uint32_t INTMask)
269 {
270   /* Check parameters */
271   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
272   assert_parameters(IS_ISO7816_INTFLAGR(INTMask));
273 
274   if (ISO7816x->INFO & INTMask)
275   {
276     return 1;
277   }
278   else
279   {
280     return 0;
281   }
282 }
283 
284 /**
285   * @brief  Clear interrupt state.
286   * @param  ISO7816x: ISO78160~ISO78161
287             INTMask:
288                 This parameter can be any combination of the following values
289                 ISO7816_INTSTS_RXOV
290                 ISO7816_INTSTS_RX
291                 ISO7816_INTSTS_TX
292   * @retval None
293   */
ISO7816_ClearINTStatus(ISO7816_TypeDef * ISO7816x,uint32_t INTMask)294 void ISO7816_ClearINTStatus(ISO7816_TypeDef *ISO7816x, uint32_t INTMask)
295 {
296     uint32_t tmp;
297 
298   /* Check parameters */
299   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
300   assert_parameters(IS_ISO7816_INTFLAGC(INTMask));
301 
302   tmp = ISO7816x->INFO;
303   tmp &= ~ISO7816_INFO_RC_MASK;
304   tmp |= INTMask;
305   ISO7816x->INFO = tmp;
306 }
307 
308 /**
309   * @brief  Get peripheral flag.
310   * @param  ISO7816x: ISO78160~ISO78161
311             FlagMask:
312                 ISO7816_FLAG_SDERR
313                 ISO7816_FLAG_RCERR
314   * @retval 1: state set
315             0: state reset
316   */
ISO7816_GetFlag(ISO7816_TypeDef * ISO7816x,uint32_t FlagMask)317 uint8_t ISO7816_GetFlag(ISO7816_TypeDef *ISO7816x, uint32_t FlagMask)
318 {
319   /* Check parameters */
320   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
321   assert_parameters(IS_ISO7816_FLAGR(FlagMask));
322 
323   if (ISO7816x->INFO&FlagMask)
324   {
325     return 1;
326   }
327   else
328   {
329     return 0;
330   }
331 }
332 
333 /**
334   * @brief  Clear peripheral flag.
335   * @param  ISO7816x: ISO78160~ISO78161
336             FlagMask:
337                 This parameter can be any combination of the following values
338                 ISO7816_FLAG_SDERR
339                 ISO7816_FLAG_RCERR
340   * @retval None
341   */
ISO7816_ClearFlag(ISO7816_TypeDef * ISO7816x,uint32_t FlagMask)342 void ISO7816_ClearFlag(ISO7816_TypeDef *ISO7816x, uint32_t FlagMask)
343 {
344   uint32_t tmp;
345 
346   /* Check parameters */
347   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
348   assert_parameters(IS_ISO7816_FLAGC(FlagMask));
349 
350   tmp = ISO7816x->INFO;
351   tmp &= ~ISO7816_INFO_RC_MASK;
352   tmp |= FlagMask;
353   ISO7816x->INFO = tmp;
354 }
355 
356 /**
357   * @brief  Get last transmit ACK.
358   * @param  ISO7816: ISO78160~ISO78161
359   * @retval ACK value
360   */
ISO7816_GetLastTransmitACK(ISO7816_TypeDef * ISO7816x)361 uint8_t ISO7816_GetLastTransmitACK(ISO7816_TypeDef *ISO7816x)
362 {
363   /* Check parameters */
364   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
365 
366   if (ISO7816x->INFO&ISO7816_INFO_RCACK)
367   {
368     return 1;
369   }
370   else
371   {
372     return 0;
373   }
374 }
375 
376 /**
377   * @brief  Get last receive check sum bit.
378   * @param  ISO7816: ISO78160~ISO78161
379   * @retval CHKSUM bit value
380   */
ISO7816_GetLastReceiveCHKSUM(ISO7816_TypeDef * ISO7816x)381 uint8_t ISO7816_GetLastReceiveCHKSUM(ISO7816_TypeDef *ISO7816x)
382 {
383   /* Check parameters */
384   assert_parameters(IS_ISO7816_ALL_INSTANCE(ISO7816x));
385 
386   if (ISO7816x->INFO&ISO7816_INFO_CHKSUM)
387   {
388     return 1;
389   }
390   else
391   {
392     return 0;
393   }
394 }
395 
396 /*********************************** END OF FILE ******************************/
397