summaryrefslogtreecommitdiff
path: root/bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/src/drivers/crc.c
blob: 6c15756eda01fa7b0614f750d1cecf36a37e14a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
 /*
 * Copyright (C) 2017-2024 Alibaba Group Holding Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/******************************************************************************
 * @file     crc.c
 * @brief    CSI Source File for CRC Driver
 * @version  V1.0
 * @date     19. Feb 2020
 ******************************************************************************/
#include <drv/irq.h>
#include <stdio.h>
#include <string.h>
#include <drv/crc.h>
#include <drv/common.h>
#include    <assert.h>

/**
\brief CRC State
*/
typedef struct {
    uint32_t busy             : 1;        ///< busy flag
    uint32_t timeout          : 1;        ///< timeout state
    uint32_t error            : 1;        ///< error
} csi_crc_state_t;

/*----- CRC Control Codes: Mode -----*/
typedef enum {
    CRC_MODE_CRC8                   = 0,   ///< Mode CRC8
    CRC_MODE_CRC16,                        ///< Mode CRC16
    CRC_MODE_CRC32                         ///< Mode CRC32
} csi_crc_mode_t;


/*----- CRC Control Codes: Mode Parameters: Key length -----*/
typedef enum {
    CRC_STANDARD_ROHC         = 0,    ///< Standard CRC RHOC
    CRC_STANDARD_MAXIM,               ///< Standard CRC MAXIAM
    CRC_STANDARD_X25,                 ///< Standard CRC X25
    CRC_STANDARD_CCITT,               ///< Standard CRC CCITT
    CRC_STANDARD_CCITT_FALSE,         ///< Standard CRC CCITT-FALSE
    CRC_STANDARD_USB,                 ///< Standard CRC USB
    CRC_STANDARD_IBM,                 ///< Standard CRC IBM
    CRC_STANDARD_MODBUS,              ///< Standard CRC MODBUS
    CRC_STANDARD_ITU,                 ///< Standard CRC ITU
    CRC_STANDARD_PMEQ_2,              ///< Standard CRC PMEQ_2
    CRC_STANDARD_XMODEM,              ///< Standard CRC XMODEM
    CRC_STANDARD_DNP,                 ///< Standard CRC DNP
    CRC_STANDARD_NONE,                ///< Standard CRC NONE
    CRC_STANDARD_CRC8_31,
    CRC_STANDARD_CRC8_7,
} csi_crc_standard_t;

/**
\brief CRC config param
 */
typedef struct {
   csi_crc_mode_t       mode;
   csi_crc_standard_t   standard;
} csi_crc_config_t;

/**
\brief CRC ctrl block
 */
typedef struct {
    csi_dev_t           dev;
    csi_crc_config_t    config;
    csi_crc_state_t     state;
} csi_crc_t;

/**
  \brief       Initialize CRC Interface. 1. Initializes the resources needed for the CRC interface 2.registers event callback function
  \param[in]   crc  crc handle to operate.
  \param[in]   idx  device id
  \return      \ref csi_error_t
*/
csi_error_t csi_crc_init(csi_crc_t *crc, uint32_t idx)
{
    CSI_PARAM_CHK(crc, CSI_ERROR);
    ///< 获取中断号、基地址等相关信息
    target_get(DEV_WJ_CRC_TAG, idx, &crc->dev);

    return CSI_OK;
}

/**
  \brief       De-initialize CRC Interface. stops operation and releases the software resources used by the interface
  \param[in]   crc  crc handle to operate.
  \return      none
*/
void csi_crc_uninit(csi_crc_t *crc)
{

}
/**
  \brief       config crc mode.
  \param[in]   crc       crc handle to operate.
  \param[in]   config    \ref csi_crc_config_t
  \return      \ref csi_error_t
*/
csi_error_t csi_crc_config(csi_crc_t *crc, csi_crc_config_t *config)
{
    csi_error_t ret = CSI_OK;
    CSI_PARAM_CHK(crc, CSI_ERROR);

    crc->config = *config;

    switch (config->standard) {
        case CRC_STANDARD_MODBUS:
            ///< TODO:设置模式
            ///< TODO:设置极性
            ///< TODO:设置初始值

            break;

        case CRC_STANDARD_IBM:

            ///< TODO:设置模式
            ///< TODO:设置极性
            ///< TODO:设置初始值
            break;

        case CRC_STANDARD_MAXIM:
            ///< TODO:设置模式
            ///< TODO:设置极性
            ///< TODO:设置初始值
            break;

        case CRC_STANDARD_USB:
            ///< TODO:设置模式
            ///< TODO:设置极性
            ///< TODO:设置初始值
            break;

        case CRC_STANDARD_CCITT:
            ///< TODO:设置模式
            ///< TODO:设置极性
            ///< TODO:设置初始值
            break;

        case CRC_STANDARD_CCITT_FALSE:
            ret = CSI_ERROR;
            break;

        case CRC_STANDARD_X25:
            ///< TODO:设置模式
            ///< TODO:设置极性
            ///< TODO:设置初始值
            break;

        case CRC_STANDARD_CRC8_31:
            ///< TODO:设置模式
            ///< TODO:设置极性
            break;

        case CRC_STANDARD_CRC8_7:
            ///< TODO:设置模式
            ///< TODO:设置极性
            break;


        case CRC_STANDARD_XMODEM:
            ret = CSI_ERROR;
            break;


        case CRC_STANDARD_DNP:
            ret = CSI_ERROR;
            break;

        default:
            ret = CSI_ERROR;
    }

    return ret;

}

/**
  \brief       accumulate crc. Computes the 32-bit CRC of 32-bit data buffer using combination of the previous CRC value and the new one.
  \param[in]   crc     crc handle to operate.
  \param[in]   data    Pointer to the input data
  \param[in]   size    intput data size.
  \return      \ref calculate value
*/
uint32_t csi_crc_accumulate(csi_crc_t *crc, const void *data, uint32_t size)
{
    uint32_t ret = 0U;
    CSI_PARAM_CHK(crc, CSI_ERROR);
    CSI_PARAM_CHK(data, CSI_ERROR);

    if (size <= 0U) {
        ret = 0U;
    } else {

        crc->state.busy = 1U;

        /* put the data int the register */
        uint32_t cur;
        uint8_t *p = (uint8_t *)data;

        for (cur = 0U; cur < (size - 3U); cur += 4U, p += 4U) {
             ///< TODO:设置待计算crc 数据: (uint32_t)(p[0]) | ((uint32_t)(p[1]) << 8U) | ((uint32_t)(p[2]) << 16U) | ((uint32_t)(p[3]) << 24U)
        }

        uint32_t data1 = 0U;
        uint8_t i;

        if (cur < size) {
            for (i = 0U; i < (size - cur); i++) {
                data1 |= ((uint32_t)(p[i]) << (i * 8U));
            }
            ///< TODO:设置待计算crc 数据 : data1
        }

        crc->state.busy = 0U;
        ///< TODO:获取计算结果到ret
    }

    return ret;

}

/**
  \brief       calculate crc. Computes the 32-bit CRC of 32-bit data buffer independently of the previous CRC value.
  \param[in]   crc     crc handle to operate.
  \param[in]   data    Pointer to the input data
  \param[in]   size    intput data size.
  \return      \ref calculate value
*/
uint32_t csi_crc_calculate(csi_crc_t *crc, const void *data, uint32_t size)
{
    uint32_t ret = 0U;

    CSI_PARAM_CHK(crc, CSI_ERROR);
    CSI_PARAM_CHK(data, CSI_ERROR);

    if (size <= 0U) {
        ret = 0U;
    } else {

        crc->state.busy = 1U;
        /* put the data int the register */
        uint32_t cur;
        uint8_t *p = (uint8_t *)data;

        for (cur = 0U; cur < (size - 3U); cur += 4U, p += 4U) {
        ///< TODO:设置待计算crc 数据: (uint32_t)(p[0]) | ((uint32_t)(p[1]) << 8U) | ((uint32_t)(p[2]) << 16U) | ((uint32_t)(p[3]) << 24U)
        }

        uint32_t data1 = 0U;
        uint8_t i;

        if (cur < size) {
            for (i = 0U; i < (size - cur); i++) {
                data1 |= ((uint32_t)(p[i]) << (i * 8U));
            }

            ///< TODO:设置待计算crc 数据 : data1
        }

        crc->state.busy = 0U;

        ///< TODO:获取计算结果到ret
    }

    return ret;
}

/**
  \brief       Get CRC state.
  \param[in]   crc  crc handle to operate.
  \return      CRC state \ref  csi_crc_state_t
*/
csi_crc_state_t csi_crc_get_state(csi_crc_t *crc)
{

    return  crc->state;
}

/**
 * \brief Compute the CRC-7 checksum of a buffer.
 *
 * See JESD84-A441.  Used by the MMC protocol.  Uses 0x09 as the
 * polynomial with no reflection.  The CRC is left
 * justified, so bit 7 of the result is bit 6 of the CRC.
 * init = 0; poly = 0x09 refin = 0 refout = 0 xorout = 0
 * \param[in] crc      crc init value or crc immediate result
 * \param[in] data     data buf to be calculate
 * \param[in] size     data size
 *
 * \return    The computed CRC7 value
 */
uint8_t csi_crc7_be(uint8_t crc, uint8_t *data, uint32_t size)
{
    return 0;
}

/**
 * \brief Compute the CRC-8 checksum of a buffer.
 *  init = 0 or 0xff; poly = 0x07 refin = 0 refout = 0 xorout = 0
 * \param[in] crc      crc init value or crc immediate result
 * \param[in] data     data buf to be calculate
 * \param[in] size     data size
 * \return    The computed CRC8 value
 */
uint8_t csi_crc8(uint8_t crc, uint8_t *data, size_t size)
{
    csi_crc_state_t status;
    csi_crc_config_t config;
    static csi_crc_t crc1;
    uint8_t out;

    status.busy = 1U;

    csi_crc_init(&crc1, 0U);

    config.mode = CRC_MODE_CRC8;
    config.standard = CRC_STANDARD_CRC8_7;

    csi_crc_config(&crc1, &config);
    ///< TODO:设置初始值:crc
    out = (uint16_t)(csi_crc_calculate(&crc1, data, size));

    while (status.busy == 1U) {
        status = csi_crc_get_state(&crc1);
    }

    csi_crc_uninit(&crc1);
    return out;
}

/**
 * \brief Compute the CRC-8 checksum of a buffer.
 *  init = 0; poly = 0x31 refin = 1 refout = 1 xorout = 0
 * \param[in] crc      crc init value or crc immediate result
 * \param[in] data     data buf to be calculate
 * \param[in] size     data size
 * \return    The computed CRC8 value
 */
uint8_t csi_crc8_maxim(uint8_t crc, uint8_t *data, size_t size)
{
    csi_crc_state_t status;
    csi_crc_config_t config;
    static csi_crc_t crc1;
    uint8_t out;

    status.busy = 1U;

    csi_crc_init(&crc1, 0U);

    config.mode = CRC_MODE_CRC8;
    config.standard = CRC_STANDARD_CRC8_31;
    csi_crc_config(&crc1, &config);
    ///< TODO:设置初始值:crc
    out = (uint16_t)(csi_crc_calculate(&crc1, data, size));

    while (status.busy == 1U) {
        status = csi_crc_get_state(&crc1);
    }

    csi_crc_uninit(&crc1);
    return out;

}

/**
 * \brief Compute the CRC-16 checksum of a buffer.
 *   init = 0 or 0xffff; poly = 0x8005 refin = 1 refout = 1 xorout = 0
 * \param[in] crc      crc init value or crc immediate result
 * \param[in] data     data buf to be calculate
 * \param[in] size     data size
 * \return    The computed CRC16 without xorout
 */
uint16_t csi_crc16(uint16_t crc, uint8_t *data, uint32_t size)
{
    csi_crc_state_t status;
    csi_crc_t crc1;
    csi_crc_config_t config;
    uint16_t out;
    status.busy = 1U;

    if ((crc == 0U) || (crc == 0xffffU)) {

        csi_crc_init(&crc1, 0U);

        config.mode = CRC_MODE_CRC16;

        if (crc == 0xffffU) {
            config.standard = CRC_STANDARD_MODBUS;
        } else {
            config.standard = CRC_STANDARD_IBM;
        }

        csi_crc_config(&crc1, &config);
        out = (uint16_t)(csi_crc_calculate(&crc1, data, size));

        while (status.busy == 1U) {
            status = csi_crc_get_state(&crc1);
        }

        csi_crc_uninit(&crc1);
    } else {
        out = 0U; /* code */

    }

    return out;
}

/**
 * \brief Compute the CRC-16 checksum of a buffer.
 *  init = 0; poly = 0x1021 refin = 1 refout = 1 xorout = 0
 * \param[in] crc      crc init value or crc immediate result
 * \param[in] data     data buf to be calculate
 * \param[in] size     data size
 * \return    The computed CRC16 without xorout
 */
uint16_t csi_crc16_ccitt(uint16_t crc, uint8_t *data, uint32_t size)
{
    csi_crc_state_t status;
    csi_crc_config_t config;
    static csi_crc_t crc1;
    uint16_t out;

    status.busy = 1U;

    csi_crc_init(&crc1, 0U);
    config.mode = CRC_MODE_CRC16;
    config.standard = CRC_STANDARD_CCITT;
    csi_crc_config(&crc1, &config);
    out = (uint16_t)(csi_crc_calculate(&crc1, data, size));

    while (status.busy == 1U) {
        status = csi_crc_get_state(&crc1);
    }

    csi_crc_uninit(&crc1);

    return out;
}