sc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /**************************************************************************//**
  2. * @file sc.c
  3. * @version V3.00
  4. * @brief M480 Smartcard(SC) driver source file
  5. *
  6. * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
  7. *****************************************************************************/
  8. #include "NuMicro.h"
  9. /* Below are variables used locally by SC driver and does not want to parse by doxygen unless HIDDEN_SYMBOLS is defined */
  10. /** @cond HIDDEN_SYMBOLS */
  11. static uint32_t u32CardStateIgnore[SC_INTERFACE_NUM] = {0UL, 0UL, 0UL};
  12. /** @endcond HIDDEN_SYMBOLS */
  13. /** @addtogroup Standard_Driver Standard Driver
  14. @{
  15. */
  16. /** @addtogroup SC_Driver SC Driver
  17. @{
  18. */
  19. /** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
  20. @{
  21. */
  22. /**
  23. * @brief This function indicates specified smartcard slot status
  24. * @param[in] sc Base address of smartcard module
  25. * @return Card insert status
  26. * @retval TRUE Card insert
  27. * @retval FALSE Card remove
  28. */
  29. uint32_t SC_IsCardInserted(SC_T *sc)
  30. {
  31. uint32_t ret;
  32. /* put conditions into two variable to remove IAR compilation warning */
  33. uint32_t cond1 = ((sc->STATUS & SC_STATUS_CDPINSTS_Msk) >> SC_STATUS_CDPINSTS_Pos);
  34. uint32_t cond2 = ((sc->CTL & SC_CTL_CDLV_Msk) >> SC_CTL_CDLV_Pos);
  35. if((sc == SC0) && (u32CardStateIgnore[0] == 1UL))
  36. {
  37. ret = (uint32_t)TRUE;
  38. }
  39. else if((sc == SC1) && (u32CardStateIgnore[1] == 1UL))
  40. {
  41. ret = (uint32_t)TRUE;
  42. }
  43. else if((sc == SC2) && (u32CardStateIgnore[2] == 1UL))
  44. {
  45. ret = (uint32_t)TRUE;
  46. }
  47. else if(cond1 != cond2)
  48. {
  49. ret = (uint32_t)FALSE;
  50. }
  51. else
  52. {
  53. ret = (uint32_t)TRUE;
  54. }
  55. return ret;
  56. }
  57. /**
  58. * @brief This function reset both transmit and receive FIFO of specified smartcard module
  59. * @param[in] sc Base address of smartcard module
  60. * @return None
  61. */
  62. void SC_ClearFIFO(SC_T *sc)
  63. {
  64. while(sc->ALTCTL & SC_ALTCTL_SYNC_Msk)
  65. {
  66. ;
  67. }
  68. sc->ALTCTL |= (SC_ALTCTL_TXRST_Msk | SC_ALTCTL_RXRST_Msk);
  69. }
  70. /**
  71. * @brief This function disable specified smartcard module
  72. * @param[in] sc Base address of smartcard module
  73. * @return None
  74. */
  75. void SC_Close(SC_T *sc)
  76. {
  77. sc->INTEN = 0UL;
  78. while(sc->PINCTL & SC_PINCTL_SYNC_Msk)
  79. {
  80. ;
  81. }
  82. sc->PINCTL = 0UL;
  83. sc->ALTCTL = 0UL;
  84. while(sc->CTL & SC_CTL_SYNC_Msk)
  85. {
  86. ;
  87. }
  88. sc->CTL = 0UL;
  89. }
  90. /**
  91. * @brief This function initialized smartcard module
  92. * @param[in] sc Base address of smartcard module
  93. * @param[in] u32CardDet Card detect polarity, select the CD pin state which indicates card absent. Could be
  94. * -\ref SC_PIN_STATE_HIGH
  95. * -\ref SC_PIN_STATE_LOW
  96. * -\ref SC_PIN_STATE_IGNORE, no card detect pin, always assumes card present
  97. * @param[in] u32PWR Power on polarity, select the PWR pin state which could set smartcard VCC to high level. Could be
  98. * -\ref SC_PIN_STATE_HIGH
  99. * -\ref SC_PIN_STATE_LOW
  100. * @return None
  101. */
  102. void SC_Open(SC_T *sc, uint32_t u32CardDet, uint32_t u32PWR)
  103. {
  104. uint32_t u32Reg = 0UL, u32Intf;
  105. if(sc == SC0)
  106. {
  107. u32Intf = 0UL;
  108. }
  109. else if(sc == SC1)
  110. {
  111. u32Intf = 1UL;
  112. }
  113. else
  114. {
  115. u32Intf = 2UL;
  116. }
  117. if(u32CardDet != SC_PIN_STATE_IGNORE)
  118. {
  119. u32Reg = u32CardDet ? 0UL: SC_CTL_CDLV_Msk;
  120. u32CardStateIgnore[u32Intf] = 0UL;
  121. }
  122. else
  123. {
  124. u32CardStateIgnore[u32Intf] = 1UL;
  125. }
  126. sc->PINCTL = u32PWR ? 0UL : SC_PINCTL_PWRINV_Msk;
  127. while(sc->CTL & SC_CTL_SYNC_Msk)
  128. {
  129. ;
  130. }
  131. sc->CTL = SC_CTL_SCEN_Msk | SC_CTL_TMRSEL_Msk | u32Reg;
  132. }
  133. /**
  134. * @brief This function reset specified smartcard module to its default state for activate smartcard
  135. * @param[in] sc Base address of smartcard module
  136. * @return None
  137. */
  138. void SC_ResetReader(SC_T *sc)
  139. {
  140. uint32_t u32Intf;
  141. if(sc == SC0)
  142. {
  143. u32Intf = 0UL;
  144. }
  145. else if(sc == SC1)
  146. {
  147. u32Intf = 1UL;
  148. }
  149. else
  150. {
  151. u32Intf = 2UL;
  152. }
  153. /* Reset FIFO, enable auto de-activation while card removal */
  154. sc->ALTCTL |= (SC_ALTCTL_TXRST_Msk | SC_ALTCTL_RXRST_Msk | SC_ALTCTL_ADACEN_Msk);
  155. /* Set Rx trigger level to 1 character, longest card detect debounce period, disable error retry (EMV ATR does not use error retry) */
  156. while(sc->CTL & SC_CTL_SYNC_Msk)
  157. {
  158. ;
  159. }
  160. sc->CTL &= ~(SC_CTL_RXTRGLV_Msk |
  161. SC_CTL_CDDBSEL_Msk |
  162. SC_CTL_TXRTY_Msk |
  163. SC_CTL_TXRTYEN_Msk |
  164. SC_CTL_RXRTY_Msk |
  165. SC_CTL_RXRTYEN_Msk);
  166. while(sc->CTL & SC_CTL_SYNC_Msk)
  167. {
  168. ;
  169. }
  170. /* Enable auto convention, and all three smartcard internal timers */
  171. sc->CTL |= SC_CTL_AUTOCEN_Msk | SC_CTL_TMRSEL_Msk;
  172. /* Disable Rx timeout */
  173. sc->RXTOUT = 0UL;
  174. /* 372 clocks per ETU by default */
  175. sc->ETUCTL= 371UL;
  176. /* Enable necessary interrupt for smartcard operation */
  177. if(u32CardStateIgnore[u32Intf]) /* Do not enable card detect interrupt if card present state ignore */
  178. {
  179. sc->INTEN = (SC_INTEN_RDAIEN_Msk |
  180. SC_INTEN_TERRIEN_Msk |
  181. SC_INTEN_TMR0IEN_Msk |
  182. SC_INTEN_TMR1IEN_Msk |
  183. SC_INTEN_TMR2IEN_Msk |
  184. SC_INTEN_BGTIEN_Msk |
  185. SC_INTEN_ACERRIEN_Msk);
  186. }
  187. else
  188. {
  189. sc->INTEN = (SC_INTEN_RDAIEN_Msk |
  190. SC_INTEN_TERRIEN_Msk |
  191. SC_INTEN_TMR0IEN_Msk |
  192. SC_INTEN_TMR1IEN_Msk |
  193. SC_INTEN_TMR2IEN_Msk |
  194. SC_INTEN_BGTIEN_Msk |
  195. SC_INTEN_CDIEN_Msk |
  196. SC_INTEN_ACERRIEN_Msk);
  197. }
  198. return;
  199. }
  200. /**
  201. * @brief This function block guard time (BGT) of specified smartcard module
  202. * @param[in] sc Base address of smartcard module
  203. * @param[in] u32BGT Block guard time using ETU as unit, valid range are between 1 ~ 32
  204. * @return None
  205. */
  206. void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT)
  207. {
  208. sc->CTL = (sc->CTL & ~SC_CTL_BGT_Msk) | ((u32BGT - 1UL) << SC_CTL_BGT_Pos);
  209. }
  210. /**
  211. * @brief This function character guard time (CGT) of specified smartcard module
  212. * @param[in] sc Base address of smartcard module
  213. * @param[in] u32CGT Character guard time using ETU as unit, valid range are between 11 ~ 267
  214. * @return None
  215. */
  216. void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT)
  217. {
  218. u32CGT -= sc->CTL & SC_CTL_NSB_Msk ? 11UL: 12UL;
  219. sc->EGT = u32CGT;
  220. }
  221. /**
  222. * @brief This function stop all smartcard timer of specified smartcard module
  223. * @param[in] sc Base address of smartcard module
  224. * @return None
  225. * @note This function stop the timers within smartcard module, \b not timer module
  226. */
  227. void SC_StopAllTimer(SC_T *sc)
  228. {
  229. while(sc->ALTCTL & SC_ALTCTL_SYNC_Msk)
  230. {
  231. ;
  232. }
  233. sc->ALTCTL &= ~(SC_ALTCTL_CNTEN0_Msk | SC_ALTCTL_CNTEN1_Msk | SC_ALTCTL_CNTEN2_Msk);
  234. }
  235. /**
  236. * @brief This function configure and start a smartcard timer of specified smartcard module
  237. * @param[in] sc Base address of smartcard module
  238. * @param[in] u32TimerNum Timer to start. Valid values are 0, 1, 2.
  239. * @param[in] u32Mode Timer operating mode, valid values are:
  240. * - \ref SC_TMR_MODE_0
  241. * - \ref SC_TMR_MODE_1
  242. * - \ref SC_TMR_MODE_2
  243. * - \ref SC_TMR_MODE_3
  244. * - \ref SC_TMR_MODE_4
  245. * - \ref SC_TMR_MODE_5
  246. * - \ref SC_TMR_MODE_6
  247. * - \ref SC_TMR_MODE_7
  248. * - \ref SC_TMR_MODE_8
  249. * - \ref SC_TMR_MODE_F
  250. * @param[in] u32ETUCount Timer timeout duration, ETU based. For timer 0, valid range are between 1~0x1000000ETUs.
  251. * For timer 1 and timer 2, valid range are between 1 ~ 0x100 ETUs
  252. * @return None
  253. * @note This function start the timer within smartcard module, \b not timer module
  254. * @note Depend on the timer operating mode, timer may not start counting immediately
  255. */
  256. void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount)
  257. {
  258. uint32_t reg = u32Mode | (SC_TMRCTL0_CNT_Msk & (u32ETUCount - 1UL));
  259. while(sc->ALTCTL & SC_ALTCTL_SYNC_Msk)
  260. {
  261. ;
  262. }
  263. if(u32TimerNum == 0UL)
  264. {
  265. while(sc->TMRCTL0 & SC_TMRCTL0_SYNC_Msk)
  266. {
  267. ;
  268. }
  269. sc->TMRCTL0 = reg;
  270. sc->ALTCTL |= SC_ALTCTL_CNTEN0_Msk;
  271. }
  272. else if(u32TimerNum == 1UL)
  273. {
  274. while(sc->TMRCTL1 & SC_TMRCTL1_SYNC_Msk)
  275. {
  276. ;
  277. }
  278. sc->TMRCTL1 = reg;
  279. sc->ALTCTL |= SC_ALTCTL_CNTEN1_Msk;
  280. }
  281. else /* timer 2 */
  282. {
  283. while(sc->TMRCTL2 & SC_TMRCTL2_SYNC_Msk)
  284. {
  285. ;
  286. }
  287. sc->TMRCTL2 = reg;
  288. sc->ALTCTL |= SC_ALTCTL_CNTEN2_Msk;
  289. }
  290. }
  291. /**
  292. * @brief This function stop a smartcard timer of specified smartcard module
  293. * @param[in] sc Base address of smartcard module
  294. * @param[in] u32TimerNum Timer to stop. Valid values are 0, 1, 2.
  295. * @return None
  296. * @note This function stop the timer within smartcard module, \b not timer module
  297. */
  298. void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum)
  299. {
  300. while(sc->ALTCTL & SC_ALTCTL_SYNC_Msk)
  301. {
  302. ;
  303. }
  304. if(u32TimerNum == 0UL)
  305. {
  306. sc->ALTCTL &= ~SC_ALTCTL_CNTEN0_Msk;
  307. }
  308. else if(u32TimerNum == 1UL)
  309. {
  310. sc->ALTCTL &= ~SC_ALTCTL_CNTEN1_Msk;
  311. }
  312. else /* timer 2 */
  313. {
  314. sc->ALTCTL &= ~SC_ALTCTL_CNTEN2_Msk;
  315. }
  316. }
  317. /**
  318. * @brief This function gets smartcard clock frequency.
  319. * @param[in] sc Base address of smartcard module
  320. * @return Smartcard frequency in kHz
  321. */
  322. uint32_t SC_GetInterfaceClock(SC_T *sc)
  323. {
  324. uint32_t u32ClkSrc, u32Num, u32Clk;
  325. if(sc == SC0)
  326. {
  327. u32Num = 0UL;
  328. }
  329. else if(sc == SC1)
  330. {
  331. u32Num = 1UL;
  332. }
  333. else
  334. {
  335. u32Num = 2UL;
  336. }
  337. u32ClkSrc = (CLK->CLKSEL3 >> (2UL * u32Num)) & CLK_CLKSEL3_SC0SEL_Msk;
  338. /* Get smartcard module clock */
  339. if(u32ClkSrc == 0UL)
  340. {
  341. u32Clk = __HXT;
  342. }
  343. else if(u32ClkSrc == 1UL)
  344. {
  345. u32Clk = CLK_GetPLLClockFreq();
  346. }
  347. else if(u32ClkSrc == 2UL)
  348. {
  349. if(u32Num == 1UL)
  350. {
  351. u32Clk = CLK_GetPCLK1Freq();
  352. }
  353. else
  354. {
  355. u32Clk = CLK_GetPCLK0Freq();
  356. }
  357. }
  358. else
  359. {
  360. u32Clk = __HIRC;
  361. }
  362. u32Clk /= (((CLK->CLKDIV1 >> (8UL * u32Num)) & CLK_CLKDIV1_SC0DIV_Msk) + 1UL) * 1000UL;
  363. return u32Clk;
  364. }
  365. /*@}*/ /* end of group SC_EXPORTED_FUNCTIONS */
  366. /*@}*/ /* end of group SC_Driver */
  367. /*@}*/ /* end of group Standard_Driver */
  368. /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/