ck_crc.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /******************************************************************************
  17. * @file ck_crc.c
  18. * @brief CSI Source File for CRC Driver
  19. * @version V1.0
  20. * @date 02. June 2017
  21. ******************************************************************************/
  22. #include <stdio.h>
  23. #include "drv_crc.h"
  24. #include "ck_crc.h"
  25. #define ERR_CRC(errno) (CSI_DRV_ERRNO_CRC_BASE | errno)
  26. #define CRC_NULL_PARAM_CHK(para) \
  27. do { \
  28. if (para == NULL) { \
  29. return ERR_CRC(EDRV_PARAMETER); \
  30. } \
  31. } while (0)
  32. typedef struct {
  33. uint32_t base;
  34. crc_event_cb_t cb;
  35. crc_status_t status;
  36. } ck_crc_priv_t;
  37. static ck_crc_priv_t crc_handle[CONFIG_CRC_NUM];
  38. /* Driver Capabilities */
  39. static const crc_capabilities_t driver_capabilities = {
  40. .ROHC = 1, /* ROHC mode */
  41. .MAXIM = 1, /* MAXIM mode */
  42. .X25 = 1, /* X25 mode */
  43. .CCITT = 1, /* CCITT mode */
  44. .USB = 1, /* USB mode */
  45. .IBM = 1, /* IBM mode */
  46. .MODBUS = 1 /* MODBUS mode */
  47. };
  48. //
  49. // Functions
  50. //
  51. static ck_crc_reg_t *crc_reg = NULL;
  52. static int32_t crc_set_mode(crc_mode_e mode, crc_standard_crc_e standard)
  53. {
  54. if (mode == CRC_MODE_CRC16) {
  55. switch (standard) {
  56. case CRC_STANDARD_CRC_MODBUS:
  57. crc_reg->CRC_SEL = 0x0;
  58. crc_reg->CRC_INIT = 0xffff;
  59. break;
  60. case CRC_STANDARD_CRC_IBM:
  61. crc_reg->CRC_SEL = 0x0;
  62. crc_reg->CRC_INIT = 0x0;
  63. break;
  64. case CRC_STANDARD_CRC_MAXIM:
  65. crc_reg->CRC_SEL = 0x4;
  66. crc_reg->CRC_INIT = 0x0;
  67. break;
  68. case CRC_STANDARD_CRC_USB:
  69. crc_reg->CRC_SEL = 0x4;
  70. crc_reg->CRC_INIT = 0xffff;
  71. break;
  72. case CRC_STANDARD_CRC_CCITT:
  73. crc_reg->CRC_SEL = 0x1;
  74. crc_reg->CRC_INIT = 0x0;
  75. break;
  76. case CRC_STANDARD_CRC_X25:
  77. crc_reg->CRC_SEL = 0x5;
  78. crc_reg->CRC_INIT = 0xffff;
  79. break;
  80. default:
  81. return ERR_CRC(EDRV_PARAMETER);
  82. }
  83. } else if (mode == CRC_MODE_CRC8) {
  84. switch (standard) {
  85. case CRC_STANDARD_CRC_MAXIM:
  86. crc_reg->CRC_SEL = 0x2;
  87. crc_reg->CRC_INIT = 0x0;
  88. break;
  89. case CRC_STANDARD_CRC_ROHC:
  90. crc_reg->CRC_SEL = 0x3;
  91. crc_reg->CRC_INIT = 0xff;
  92. break;
  93. default:
  94. return ERR_CRC(EDRV_PARAMETER);
  95. }
  96. } else {
  97. return ERR_CRC(EDRV_PARAMETER);
  98. }
  99. return 0;
  100. }
  101. static int32_t crc_set_data(uint32_t data)
  102. {
  103. crc_reg->CRC_DATA = data;
  104. return 0;
  105. }
  106. static int32_t crc_get_data(uint32_t *data)
  107. {
  108. *data = crc_reg->CRC_DATA;
  109. return 0;
  110. }
  111. int32_t __attribute__((weak)) target_get_crc_count(void)
  112. {
  113. return 0;
  114. }
  115. int32_t __attribute__((weak)) target_get_crc(int32_t idx, uint32_t *base)
  116. {
  117. return NULL;
  118. }
  119. /**
  120. \brief get crc handle count.
  121. \return crc handle count
  122. */
  123. int32_t csi_crc_get_instance_count(void)
  124. {
  125. return target_get_crc_count();
  126. }
  127. /**
  128. \brief Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function
  129. \param[in] idx must not exceed return value of csi_crc_get_handle_count()
  130. \param[in] cb_event Pointer to \ref crc_event_cb_t
  131. \return return crc handle if success
  132. */
  133. crc_handle_t csi_crc_initialize(int32_t idx, crc_event_cb_t cb_event)
  134. {
  135. if (idx < 0 || idx >= CONFIG_CRC_NUM) {
  136. return NULL;
  137. }
  138. /* obtain the crc information */
  139. uint32_t base = 0u;
  140. int32_t real_idx = target_get_crc(idx, &base);
  141. if (real_idx != idx) {
  142. return NULL;
  143. }
  144. ck_crc_priv_t *crc_priv = &crc_handle[idx];
  145. crc_reg = (ck_crc_reg_t *)(crc_priv->base);
  146. crc_priv->base = base;
  147. crc_priv->cb = cb_event;
  148. crc_priv->status.busy = 0;
  149. return (crc_handle_t)crc_priv;
  150. }
  151. /**
  152. \brief De-initialize CRC Interface. stops operation and releases the software resources used by the interface
  153. \param[in] handle crc handle to operate.
  154. \return error code
  155. */
  156. int32_t csi_crc_uninitialize(crc_handle_t handle)
  157. {
  158. CRC_NULL_PARAM_CHK(handle);
  159. ck_crc_priv_t *crc_priv = handle;
  160. crc_priv->cb = NULL;
  161. return 0;
  162. }
  163. /**
  164. \brief Get driver capabilities.
  165. \param[in] handle crc handle to operate.
  166. \return \ref crc_capabilities_t
  167. */
  168. crc_capabilities_t csi_crc_get_capabilities(crc_handle_t handle)
  169. {
  170. return driver_capabilities;
  171. }
  172. /**
  173. \brief config crc mode.
  174. \param[in] handle crc handle to operate.
  175. \param[in] mode \ref crc_mode_e
  176. \param[in] standard \ref crc_standard_crc_e
  177. \return error code
  178. */
  179. int32_t csi_crc_config(crc_handle_t handle, crc_mode_e mode, crc_standard_crc_e standard)
  180. {
  181. CRC_NULL_PARAM_CHK(handle);
  182. /* set the crc mode */
  183. uint32_t ret = crc_set_mode(mode, standard);
  184. return ret;
  185. }
  186. /**
  187. \brief calculate crc.
  188. \param[in] handle crc handle to operate.
  189. \param[in] in Pointer to the input data
  190. \param[out] out Pointer to the result.
  191. \param[in] len intpu data len.
  192. \return error code
  193. */
  194. int32_t csi_crc_calculate(crc_handle_t handle, const void *in, void *out, uint32_t len)
  195. {
  196. CRC_NULL_PARAM_CHK(handle);
  197. CRC_NULL_PARAM_CHK(in);
  198. CRC_NULL_PARAM_CHK(out);
  199. if (len <= 0) {
  200. return ERR_CRC(EDRV_PARAMETER);
  201. }
  202. ck_crc_priv_t *crc_priv = handle;
  203. crc_reg = (ck_crc_reg_t *)(crc_priv->base);
  204. crc_priv->status.busy = 1;
  205. /* put the data int the register */
  206. uint8_t cur;
  207. uint8_t *p = (uint8_t *)in;
  208. for (cur=0; cur<len - 3; cur += 4, p+=4) {
  209. crc_set_data(p[0]
  210. | (p[1] << 8)
  211. | (p[2] << 16)
  212. | (p[3] << 24));
  213. }
  214. uint32_t data = 0;
  215. uint8_t i;
  216. if (cur < len) {
  217. for (i=0; i<len-cur; i++) {
  218. data |= (p[cur + i] << (i*8));
  219. }
  220. crc_set_data(data);
  221. }
  222. crc_get_data((uint32_t *)out);
  223. crc_priv->status.busy = 0;
  224. return 0;
  225. }
  226. /**
  227. \brief Get CRC status.
  228. \param[in] handle crc handle to operate.
  229. \return CRC status \ref crc_status_t
  230. */
  231. crc_status_t csi_crc_get_status(crc_handle_t handle)
  232. {
  233. ck_crc_priv_t *crc_priv = handle;
  234. return crc_priv->status;
  235. }