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