cmem7_efuse.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /**
  2. *****************************************************************************
  3. * @file cmem7_efuse.c
  4. *
  5. * @brief CMEM7 EFUSE source file
  6. *
  7. *
  8. * @version V1.0
  9. * @date 3. September 2013
  10. *
  11. * @note
  12. *
  13. *****************************************************************************
  14. * @attention
  15. *
  16. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  17. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  18. * TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  19. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  20. * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  21. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  22. *
  23. * <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
  24. *****************************************************************************
  25. */
  26. #include "cmem7_efuse.h"
  27. static void efuse_SetClock(uint8_t dividor) {
  28. if (dividor <= 2) {
  29. GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 0;
  30. } else if (dividor <= 4) {
  31. GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 1;
  32. } else if (dividor <= 8) {
  33. GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 2;
  34. } else {
  35. GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK = 3;
  36. }
  37. }
  38. static uint32_t efuse_GetClock() {
  39. return SYSTEM_CLOCK_FREQ / (1 << (GLOBAL_CTRL->CLK_SEL_1_b.EFUSE_CLK + 1));
  40. }
  41. // static uint8_t efuse_Crc8Bit(uint8_t data, uint8_t crc) {
  42. // uint8_t newCrc;
  43. // uint8_t d[8], c[8], i;
  44. //
  45. // for (i = 0; i < 8; i++) {
  46. // d[i] = (data >> i) & 0x01;
  47. // c[i] = (crc >> i) & 0x01;
  48. // }
  49. //
  50. // newCrc = d[7] ^ d[6] ^ d[0] ^ c[0] ^ c[6] ^ c[7];
  51. // newCrc |= (d[6] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[6]) << 1;
  52. // newCrc |= (d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[2] ^ c[6]) << 2;
  53. // newCrc |= (d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[3] ^ c[7]) << 3;
  54. // newCrc |= (d[4] ^ d[3] ^ d[2] ^ c[2] ^ c[3] ^ c[4]) << 4;
  55. // newCrc |= (d[5] ^ d[4] ^ d[3] ^ c[3] ^ c[4] ^ c[5]) << 5;
  56. // newCrc |= (d[6] ^ d[5] ^ d[4] ^ c[4] ^ c[5] ^ c[6]) << 6;
  57. // newCrc |= (d[7] ^ d[6] ^ d[5] ^ c[5] ^ c[6] ^ c[7]) << 1;
  58. //
  59. // return newCrc;
  60. // }
  61. // static uint8_t efuse_Crc(EFUSE_AesKey* key, uint8_t lock, BOOL isLowRegion) {
  62. // uint8_t crc = 0;
  63. //
  64. // if (isLowRegion) {
  65. // crc = efuse_Crc8Bit(key->key0, crc);
  66. // crc = efuse_Crc8Bit(key->key0 >> 8, crc);
  67. // crc = efuse_Crc8Bit(key->key0 >> 16, crc);
  68. // crc = efuse_Crc8Bit(key->key0 >> 24, crc);
  69. // crc = efuse_Crc8Bit(key->key1, crc);
  70. // crc = efuse_Crc8Bit(key->key1 >> 8, crc);
  71. // crc = efuse_Crc8Bit(key->key1 >> 16, crc);
  72. // crc = efuse_Crc8Bit(key->key1 >> 24, crc);
  73. // crc = efuse_Crc8Bit(key->key2, crc);
  74. // crc = efuse_Crc8Bit(key->key2 >> 8, crc);
  75. // crc = efuse_Crc8Bit(key->key2 >> 16, crc);
  76. // crc = efuse_Crc8Bit(key->key2 >> 24, crc);
  77. // crc = efuse_Crc8Bit(key->key3, crc);
  78. // crc = efuse_Crc8Bit(key->key3 >> 8, crc);
  79. // crc = efuse_Crc8Bit(key->key3 >> 16, crc);
  80. // crc = efuse_Crc8Bit(key->key3 >> 24, crc);
  81. // crc = efuse_Crc8Bit(lock, crc);
  82. // crc = efuse_Crc8Bit(0x0, crc);
  83. // crc = efuse_Crc8Bit(0x0, crc);
  84. // } else {
  85. // crc = efuse_Crc8Bit(key->key4, crc);
  86. // crc = efuse_Crc8Bit(key->key4 >> 8, crc);
  87. // crc = efuse_Crc8Bit(key->key4 >> 16, crc);
  88. // crc = efuse_Crc8Bit(key->key4 >> 24, crc);
  89. // crc = efuse_Crc8Bit(key->key5, crc);
  90. // crc = efuse_Crc8Bit(key->key5 >> 8, crc);
  91. // crc = efuse_Crc8Bit(key->key5 >> 16, crc);
  92. // crc = efuse_Crc8Bit(key->key5 >> 24, crc);
  93. // crc = efuse_Crc8Bit(key->key6, crc);
  94. // crc = efuse_Crc8Bit(key->key6 >> 8, crc);
  95. // crc = efuse_Crc8Bit(key->key6 >> 16, crc);
  96. // crc = efuse_Crc8Bit(key->key6 >> 24, crc);
  97. // crc = efuse_Crc8Bit(key->key7, crc);
  98. // crc = efuse_Crc8Bit(key->key7 >> 8, crc);
  99. // crc = efuse_Crc8Bit(key->key7 >> 16, crc);
  100. // crc = efuse_Crc8Bit(key->key7 >> 24, crc);
  101. // crc = efuse_Crc8Bit(lock, crc);
  102. // crc = efuse_Crc8Bit(0x0, crc);
  103. // crc = efuse_Crc8Bit(0x0, crc);
  104. // }
  105. //
  106. // return crc;
  107. // }
  108. void EFUSE_Init(EFUSE_InitTypeDef* init) {
  109. assert_param(init);
  110. assert_param(IS_EFUSE_TMRF(init->EFUSE_TMRF));
  111. efuse_SetClock(init->EFUSE_ClockDividor);
  112. EFUSE->USER_CTRL_LOW_b.TMRF = init->EFUSE_TMRF;
  113. EFUSE->USER_CTRL_HI_b.TMRF = init->EFUSE_TMRF;
  114. if (init->timing) {
  115. uint32_t value;
  116. value = (init->timing->EFUSE_Tpwph * (efuse_GetClock() / 1000000) / 1000);
  117. value = (value == 0) ? 1 : value;
  118. EFUSE->TIMING_0_b.TPWPH = value >> 2;
  119. EFUSE->TIMING_1_b.TPWPH = value & 0x00000003;
  120. value = (init->timing->EFUSE_Trac * (efuse_GetClock() / 1000000) / 1000);
  121. value = (value == 0) ? 1 : value;
  122. EFUSE->TIMING_0_b.TRAC = value;
  123. value = (init->timing->EFUSE_Trah * (efuse_GetClock() / 1000000) / 1000);
  124. value = (value == 0) ? 1 : value;
  125. EFUSE->TIMING_0_b.TRAH = value;
  126. value = (init->timing->EFUSE_Trpw * (efuse_GetClock() / 1000000) / 1000);
  127. value = (value == 0) ? 1 : value;
  128. EFUSE->TIMING_0_b.TRPW = value;
  129. value = (init->timing->EFUSE_Trc * (efuse_GetClock() / 1000000) / 1000);
  130. value = (value == 0) ? 1 : value;
  131. EFUSE->TIMING_0_b.TRC = value;
  132. value = (init->timing->EFUSE_Tesr * (efuse_GetClock() / 1000000) / 1000);
  133. value = (value == 0) ? 1 : value;
  134. EFUSE->TIMING_0_b.TESR = value;
  135. value = (init->timing->EFUSE_Tprs * (efuse_GetClock() / 1000000) / 1000);
  136. value = (value == 0) ? 1 : value;
  137. EFUSE->TIMING_0_b.TPRS = value;
  138. value = (init->timing->EFUSE_Tpi * (efuse_GetClock() / 1000000) / 1000);
  139. value = (value == 0) ? 1 : value;
  140. EFUSE->TIMING_1_b.TPIT = value;
  141. value = (init->timing->EFUSE_Tpp * (efuse_GetClock() / 1000000) / 1000);
  142. value = (value == 0) ? 1 : value;
  143. EFUSE->TIMING_1_b.TPP = value;
  144. value = (init->timing->EFUSE_Teps * (efuse_GetClock() / 1000000) / 1000);
  145. value = (value == 0) ? 1 : value;
  146. EFUSE->TIMING_1_b.TEPS = value;
  147. value = (init->timing->EFUSE_Teps * (efuse_GetClock() / 1000000) / 1000);
  148. value = (value == 0) ? 1 : value;
  149. EFUSE->TIMING_1_b.TPWPS = value;
  150. }
  151. }
  152. /* It only can be written once */
  153. // BOOL EFUSE_Write(EFUSE_AesKey* key) {
  154. // assert_param(key);
  155. //
  156. // if ((EFUSE->USER_CTRL_LOW_b.LOCK || EFUSE->USER_CTRL_LOW_b.BUSY) ||
  157. // (EFUSE->USER_CTRL_HI_b.LOCK || EFUSE->USER_CTRL_HI_b.BUSY)) {
  158. // return FALSE;
  159. // }
  160. //
  161. // // write low region
  162. // EFUSE->USER_DATA0_LOW = key->key0;
  163. // EFUSE->USER_DATA1_LOW = key->key1;
  164. // EFUSE->USER_DATA2_LOW = key->key2;
  165. // EFUSE->USER_DATA3_LOW = key->key3;
  166. // EFUSE->USER_DATA4_LOW_b.CRC = efuse_Crc(key, 0x1, TRUE);
  167. // EFUSE->USER_DATA4_LOW_b.LOCK = 1;
  168. // EFUSE->USER_CTRL_LOW_b.WR_EN = FALSE;
  169. // EFUSE->USER_CTRL_LOW_b.WR_EN = TRUE;
  170. //
  171. // udelay(1000);
  172. // while (EFUSE->USER_CTRL_LOW_b.BUSY) ;
  173. //
  174. // if (EFUSE->USER_CTRL_LOW_b.WR_CRC_ERR) {
  175. // return FALSE;
  176. // }
  177. //
  178. // // write high region
  179. // EFUSE->USER_DATA0_HI = key->key4;
  180. // EFUSE->USER_DATA1_HI = key->key5;
  181. // EFUSE->USER_DATA2_HI = key->key6;
  182. // EFUSE->USER_DATA3_HI = key->key7;
  183. // EFUSE->USER_DATA4_HI_b.CRC = efuse_Crc(key, 0x1, FALSE);
  184. // EFUSE->USER_DATA4_HI_b.LOCK = 1;
  185. // EFUSE->USER_CTRL_HI_b.WR_EN = FALSE;
  186. // EFUSE->USER_CTRL_HI_b.WR_EN = TRUE;
  187. //
  188. // udelay(1000);
  189. // while (EFUSE->USER_CTRL_HI_b.BUSY) ;
  190. //
  191. // if (EFUSE->USER_CTRL_HI_b.WR_CRC_ERR) {
  192. // return FALSE;
  193. // }
  194. // return TRUE;
  195. // }
  196. BOOL EFUSE_Compare(EFUSE_AesKey* key) {
  197. assert_param(key);
  198. if (EFUSE->USER_CTRL_LOW_b.BUSY || EFUSE->USER_CTRL_HI_b.BUSY) {
  199. return FALSE;
  200. }
  201. // compare low region
  202. EFUSE->USER_DATA0_LOW = key->key0;
  203. EFUSE->USER_DATA1_LOW = key->key1;
  204. EFUSE->USER_DATA2_LOW = key->key2;
  205. EFUSE->USER_DATA3_LOW = key->key3;
  206. EFUSE->USER_CTRL_LOW_b.RD_EN = FALSE;
  207. EFUSE->USER_CTRL_LOW_b.RD_EN = TRUE;
  208. udelay(2);
  209. while (EFUSE->USER_CTRL_LOW_b.BUSY) ;
  210. if (EFUSE->USER_CTRL_LOW_b.COMPARE_FAIL) {
  211. return FALSE;
  212. }
  213. // compare high region
  214. EFUSE->USER_DATA0_HI = key->key4;
  215. EFUSE->USER_DATA1_HI = key->key5;
  216. EFUSE->USER_DATA2_HI = key->key6;
  217. EFUSE->USER_DATA3_HI = key->key7;
  218. EFUSE->USER_CTRL_HI_b.RD_EN = FALSE;
  219. EFUSE->USER_CTRL_HI_b.RD_EN = TRUE;
  220. udelay(2);
  221. while (EFUSE->USER_CTRL_HI_b.BUSY) ;
  222. if (EFUSE->USER_CTRL_HI_b.COMPARE_FAIL) {
  223. return FALSE;
  224. }
  225. return TRUE;
  226. }