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