1 /******************************************************************************
2 *
3 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4 * Analog Devices, Inc.),
5 * Copyright (C) 2023-2024 Analog Devices, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************************/
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "mxc_sys.h"
25 #include "mxc_device.h"
26 #include "mxc_errors.h"
27 #include "mxc_assert.h"
28 #include "mxc_lock.h"
29
30 #include "dma.h"
31 #include "crc_regs.h"
32 #include "crc_reva.h"
33
34 /***** Global Variables *****/
35 static mxc_crc_reva_req_t *CRCreq;
36
37 /* ************************************************************************* */
38 /* Global Control/Configuration functions */
39 /* ************************************************************************* */
40
MXC_CRC_RevA_Init(mxc_crc_reva_regs_t * crc)41 int MXC_CRC_RevA_Init(mxc_crc_reva_regs_t *crc)
42 {
43 crc->ctrl = 0x00;
44 crc->val = 0xFFFFFFFF;
45 return E_NO_ERROR;
46 }
47
MXC_CRC_RevA_Shutdown(mxc_crc_reva_regs_t * crc)48 int MXC_CRC_RevA_Shutdown(mxc_crc_reva_regs_t *crc)
49 {
50 crc->ctrl &= ~MXC_F_CRC_REVA_CTRL_EN;
51 return E_NO_ERROR;
52 }
53
MXC_CRC_RevA_Handler(int ch,int error)54 int MXC_CRC_RevA_Handler(int ch, int error)
55 {
56 if (error == E_NO_ERROR) {
57 CRCreq->resultCRC = MXC_CRC_GetResult();
58 }
59 return error;
60 }
61
62 /* ************************************************************************* */
63 /* Cyclic Redundancy Check(CRC) functions */
64 /* ************************************************************************* */
65
66 /*******************************/
67 /* Low Level Functions */
68 /*******************************/
69
MXC_CRC_RevA_SetDirection(mxc_crc_reva_regs_t * crc,mxc_crc_reva_bitorder_t bitOrder)70 void MXC_CRC_RevA_SetDirection(mxc_crc_reva_regs_t *crc, mxc_crc_reva_bitorder_t bitOrder)
71 {
72 MXC_SETFIELD(crc->ctrl, MXC_F_CRC_REVA_CTRL_MSB, bitOrder << MXC_F_CRC_REVA_CTRL_MSB_POS);
73 }
74
MXC_CRC_RevA_GetDirection(mxc_crc_reva_regs_t * crc)75 mxc_crc_bitorder_t MXC_CRC_RevA_GetDirection(mxc_crc_reva_regs_t *crc)
76 {
77 return !!(crc->ctrl & MXC_F_CRC_REVA_CTRL_MSB);
78 }
79
MXC_CRC_RevA_SwapDataIn(mxc_crc_reva_regs_t * crc,mxc_crc_reva_bitorder_t bitOrder)80 void MXC_CRC_RevA_SwapDataIn(mxc_crc_reva_regs_t *crc, mxc_crc_reva_bitorder_t bitOrder)
81 {
82 MXC_SETFIELD(crc->ctrl, MXC_F_CRC_REVA_CTRL_BYTE_SWAP_IN,
83 bitOrder << MXC_F_CRC_REVA_CTRL_BYTE_SWAP_IN_POS);
84 }
85
MXC_CRC_RevA_SwapDataOut(mxc_crc_reva_regs_t * crc,mxc_crc_reva_bitorder_t bitOrder)86 void MXC_CRC_RevA_SwapDataOut(mxc_crc_reva_regs_t *crc, mxc_crc_reva_bitorder_t bitOrder)
87 {
88 MXC_SETFIELD(crc->ctrl, MXC_F_CRC_REVA_CTRL_BYTE_SWAP_OUT,
89 bitOrder << MXC_F_CRC_REVA_CTRL_BYTE_SWAP_OUT_POS);
90 }
91
MXC_CRC_RevA_SetPoly(mxc_crc_reva_regs_t * crc,uint32_t poly)92 void MXC_CRC_RevA_SetPoly(mxc_crc_reva_regs_t *crc, uint32_t poly)
93 {
94 crc->poly = poly;
95 }
96
MXC_CRC_RevA_GetPoly(mxc_crc_reva_regs_t * crc)97 uint32_t MXC_CRC_RevA_GetPoly(mxc_crc_reva_regs_t *crc)
98 {
99 return crc->poly;
100 }
101
MXC_CRC_RevA_GetResult(mxc_crc_reva_regs_t * crc)102 uint32_t MXC_CRC_RevA_GetResult(mxc_crc_reva_regs_t *crc)
103 {
104 return crc->val;
105 }
106
107 /*******************************/
108 /* High Level Functions */
109 /*******************************/
110
MXC_CRC_RevA_Compute(mxc_crc_reva_regs_t * crc,mxc_crc_reva_req_t * req)111 int MXC_CRC_RevA_Compute(mxc_crc_reva_regs_t *crc, mxc_crc_reva_req_t *req)
112 {
113 int i = 0;
114 volatile int length;
115
116 if (req == NULL) {
117 return E_NULL_PTR;
118 }
119
120 if (req->dataBuffer == NULL) {
121 return E_NULL_PTR;
122 }
123
124 if (req->dataLen == 0) {
125 return E_INVALID;
126 }
127
128 crc->ctrl |= MXC_F_CRC_REVA_CTRL_EN;
129
130 length = req->dataLen;
131
132 while (length--) {
133 crc->datain32 = req->dataBuffer[i++];
134 while (crc->ctrl & MXC_F_CRC_REVA_CTRL_BUSY) {}
135 }
136
137 // Store the crc value
138 req->resultCRC = MXC_CRC_GetResult();
139
140 return E_NO_ERROR;
141 }
142
MXC_CRC_RevA_ComputeAsync(mxc_crc_reva_regs_t * crc,mxc_crc_reva_req_t * req)143 int MXC_CRC_RevA_ComputeAsync(mxc_crc_reva_regs_t *crc, mxc_crc_reva_req_t *req)
144 {
145 uint8_t channel;
146 mxc_dma_config_t config;
147 mxc_dma_srcdst_t srcdst;
148
149 if (req == NULL) {
150 return E_NULL_PTR;
151 }
152
153 if (req->dataBuffer == NULL) {
154 return E_NULL_PTR;
155 }
156
157 if (req->dataLen == 0) {
158 return E_INVALID;
159 }
160
161 CRCreq = req;
162
163 MXC_DMA_Init();
164
165 channel = MXC_DMA_AcquireChannel();
166
167 config.reqsel = MXC_DMA_REQUEST_CRCTX;
168
169 config.ch = channel;
170
171 config.srcwd = MXC_DMA_WIDTH_BYTE;
172 config.dstwd = MXC_DMA_WIDTH_BYTE;
173
174 config.srcinc_en = 1;
175 config.dstinc_en = 0;
176
177 srcdst.ch = channel;
178 srcdst.source = (uint8_t *)req->dataBuffer; //transfering bytes
179 srcdst.len = req->dataLen * 4; //number of bytes
180
181 MXC_CRC->ctrl |= MXC_F_CRC_CTRL_DMA_EN;
182 MXC_CRC->ctrl |= MXC_F_CRC_CTRL_EN;
183
184 MXC_DMA_ConfigChannel(config, srcdst);
185 MXC_DMA_SetCallback(channel, MXC_CRC_Handler);
186 MXC_DMA_EnableInt(channel);
187 MXC_DMA_Start(channel);
188 //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
189 MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
190
191 return E_NO_ERROR;
192 }
193