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 #include <stdio.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include "mxc_device.h"
24 #include "mxc_assert.h"
25 #include "mxc_lock.h"
26 #include "mxc_sys.h"
27 #include "mxc_delay.h"
28 #include "spi_reva1.h"
29 #include "dma.h"
30 
31 /* **** Functions **** */
32 
MXC_SPI_Init(mxc_spi_regs_t * spi,int masterMode,int quadModeUsed,int numSlaves,unsigned ssPolarity,unsigned int hz)33 int MXC_SPI_Init(mxc_spi_regs_t *spi, int masterMode, int quadModeUsed, int numSlaves,
34                  unsigned ssPolarity, unsigned int hz)
35 {
36     int spi_num;
37 
38     spi_num = MXC_SPI_GET_IDX(spi);
39     MXC_ASSERT(spi_num >= 0);
40 
41     if (numSlaves > MXC_SPI_SS_INSTANCES) {
42         return E_BAD_PARAM;
43     }
44 
45     // Check if frequency is too high
46     if (hz > PeripheralClock) {
47         return E_BAD_PARAM;
48     }
49 
50 #ifndef MSDK_NO_GPIO_CLK_INIT
51     // Configure GPIO for spi
52     if (spi == MXC_SPI0) {
53         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
54         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI0);
55         MXC_GPIO_Config(&gpio_cfg_spi0);
56 
57         //ME21 SPI0 supports ss0-ss3 ship select
58         if (numSlaves == 1) {
59             MXC_GPIO_Config(&gpio_cfg_spi0_ss0);
60         }
61         if (numSlaves == 2) {
62             MXC_GPIO_Config(&gpio_cfg_spi0_ss0);
63             MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
64         }
65         if (numSlaves == 3) {
66             MXC_GPIO_Config(&gpio_cfg_spi0_ss0);
67             MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
68             MXC_GPIO_Config(&gpio_cfg_spi0_ss2);
69         }
70         if (numSlaves == 4) {
71             MXC_GPIO_Config(&gpio_cfg_spi0_ss0);
72             MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
73             MXC_GPIO_Config(&gpio_cfg_spi0_ss2);
74             MXC_GPIO_Config(&gpio_cfg_spi0_ss3);
75         }
76     } else if (spi == MXC_SPI1) {
77         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
78         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
79         MXC_GPIO_Config(&gpio_cfg_spi1);
80     } else if (spi == MXC_SPI2) {
81         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI2);
82         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI2);
83         MXC_GPIO_Config(&gpio_cfg_spi2);
84     } else {
85         return E_NO_DEVICE;
86     }
87 #endif // MSDK_NO_GPIO_CLK_INIT
88 
89     return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves,
90                               ssPolarity, hz);
91 }
92 
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)93 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
94 {
95     int spi_num;
96     spi_num = MXC_SPI_GET_IDX(spi);
97     MXC_ASSERT(spi_num >= 0);
98 
99     MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi);
100 
101     if (spi == MXC_SPI0) {
102         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
103     } else if (spi == MXC_SPI1) {
104         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
105     } else if (spi == MXC_SPI2) {
106         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI2);
107     } else {
108         return E_INVALID;
109     }
110 
111     return E_NO_ERROR;
112 }
113 
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)114 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
115 {
116     return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
117 }
118 
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)119 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
120 {
121     if (MXC_SPI_GET_IDX(spi) != -1) {
122         return PeripheralClock;
123     } else {
124         return E_BAD_PARAM;
125     }
126     return E_NO_ERROR;
127 }
128 
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)129 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
130 {
131     return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
132 }
133 
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)134 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
135 {
136     return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi);
137 }
138 
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)139 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
140 {
141     return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize);
142 }
143 
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)144 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
145 {
146     return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi);
147 }
148 
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)149 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
150 {
151     return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx);
152 }
153 
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)154 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
155 {
156     return MXC_SPI_RevA1_GetSlave((mxc_spi_reva_regs_t *)spi);
157 }
158 
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)159 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
160 {
161     return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, spiWidth);
162 }
163 
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)164 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
165 {
166     return MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi);
167 }
168 
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)169 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
170 {
171     return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, spiMode);
172 }
173 
MXC_SPI_GetMode(mxc_spi_regs_t * spi)174 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
175 {
176     return MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi);
177 }
178 
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)179 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
180 {
181     return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi);
182 }
183 
MXC_SPI_GetActive(mxc_spi_regs_t * spi)184 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
185 {
186     return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi);
187 }
188 
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)189 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
190 {
191     return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi);
192 }
193 
MXC_SPI_ReadRXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)194 unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
195 {
196     return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
197 }
198 
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)199 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
200 {
201     return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
202 }
203 
MXC_SPI_WriteTXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)204 unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
205 {
206     return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
207 }
208 
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)209 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
210 {
211     return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
212 }
213 
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)214 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
215 {
216     MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
217 }
218 
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)219 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
220 {
221     MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
222 }
223 
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)224 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
225 {
226     return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
227 }
228 
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)229 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
230 {
231     return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
232 }
233 
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)234 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
235 {
236     return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
237 }
238 
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)239 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
240 {
241     return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
242 }
243 
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)244 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
245 {
246     return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi);
247 }
248 
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)249 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
250 {
251     MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi);
252 }
253 
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int mask)254 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int mask)
255 {
256     MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, mask);
257 }
258 
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int mask)259 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int mask)
260 {
261     MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, mask);
262 }
263 
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)264 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
265 {
266     return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req);
267 }
268 
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)269 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
270 {
271     return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req);
272 }
273 
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)274 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
275 {
276     int reqselTx = -1;
277     int reqselRx = -1;
278 
279     int spi_num;
280 
281     spi_num = MXC_SPI_GET_IDX(req->spi);
282     MXC_ASSERT(spi_num >= 0);
283 
284     if (req->txData != NULL) {
285         switch (spi_num) {
286         case 0:
287             reqselTx = MXC_DMA_REQUEST_SPI0TX;
288             break;
289 
290         case 1:
291             reqselTx = MXC_DMA_REQUEST_SPI1TX;
292             break;
293 
294         case 2:
295             reqselTx = MXC_DMA_REQUEST_SPI2TX;
296             break;
297 
298         default:
299             return E_BAD_PARAM;
300         }
301     }
302 
303     if (req->rxData != NULL) {
304         switch (spi_num) {
305         case 0:
306             reqselRx = MXC_DMA_REQUEST_SPI0RX;
307             break;
308 
309         case 1:
310             reqselRx = MXC_DMA_REQUEST_SPI1RX;
311             break;
312 
313         case 2:
314             reqselRx = MXC_DMA_REQUEST_SPI2RX;
315             break;
316 
317         default:
318             return E_BAD_PARAM;
319         }
320     }
321 
322     return MXC_SPI_RevA1_MasterTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
323                                               MXC_DMA);
324 }
325 
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)326 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
327 {
328     return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req);
329 }
330 
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)331 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
332 {
333     return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req);
334 }
335 
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)336 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
337 {
338     int reqselTx = -1;
339     int reqselRx = -1;
340 
341     int spi_num;
342 
343     spi_num = MXC_SPI_GET_IDX(req->spi);
344     MXC_ASSERT(spi_num >= 0);
345 
346     if (req->txData != NULL) {
347         switch (spi_num) {
348         case 0:
349             reqselTx = MXC_DMA_REQUEST_SPI0TX;
350             break;
351 
352         case 1:
353             reqselTx = MXC_DMA_REQUEST_SPI1TX;
354             break;
355 
356         case 2:
357             reqselTx = MXC_DMA_REQUEST_SPI2TX;
358             break;
359 
360         default:
361             return E_BAD_PARAM;
362         }
363     }
364 
365     if (req->rxData != NULL) {
366         switch (spi_num) {
367         case 0:
368             reqselRx = MXC_DMA_REQUEST_SPI0RX;
369             break;
370 
371         case 1:
372             reqselRx = MXC_DMA_REQUEST_SPI1RX;
373             break;
374 
375         case 2:
376             reqselRx = MXC_DMA_REQUEST_SPI2RX;
377             break;
378 
379         default:
380             return E_BAD_PARAM;
381         }
382     }
383     return MXC_SPI_RevA1_SlaveTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
384                                              MXC_DMA);
385 }
386 
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)387 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
388 {
389     return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData);
390 }
391 
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)392 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
393 {
394     MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi);
395 }
396 
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)397 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
398 {
399     MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi);
400 }
401 
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)402 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
403 {
404     MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state);
405 }
406