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 <stdbool.h>
25
26 #include "mxc_device.h"
27 #include "mxc_assert.h"
28 #include "mxc_lock.h"
29 #include "mxc_sys.h"
30 #include "mxc_delay.h"
31 #include "spi_reva1.h"
32 #include "dma.h"
33
34 /* **** Definitions **** */
35
36 /* ************************************************************************** */
MXC_SPI_Init(mxc_spi_regs_t * spi,int masterMode,int quadModeUsed,int numSlaves,unsigned ssPolarity,unsigned int hz,mxc_spi_pins_t pins)37 int MXC_SPI_Init(mxc_spi_regs_t *spi, int masterMode, int quadModeUsed, int numSlaves,
38 unsigned ssPolarity, unsigned int hz, mxc_spi_pins_t pins)
39 {
40 int spi_num;
41
42 spi_num = MXC_SPI_GET_IDX(spi);
43 MXC_ASSERT(spi_num >= 0);
44
45 if (numSlaves > MXC_SPI_SS_INSTANCES) {
46 return E_BAD_PARAM;
47 }
48
49 // Check if frequency is too high
50 if ((spi_num < 3) && (hz > PeripheralClock)) {
51 return E_BAD_PARAM;
52 }
53
54 if ((spi_num > 2) && (hz > SystemCoreClock)) {
55 return E_BAD_PARAM;
56 }
57
58 #ifndef MSDK_NO_GPIO_CLK_INIT
59 // Configure GPIO for spi
60 if (spi == MXC_SPI0) {
61 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI0);
62 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
63 MXC_GPIO_Config(&gpio_cfg_spi0);
64
65 // Enable slave select pins
66 if (pins.ss0) {
67 MXC_GPIO_Config(&gpio_cfg_spi0_ss0);
68 }
69
70 if (pins.ss1) {
71 MXC_GPIO_Config(&gpio_cfg_spi0_ss1);
72 }
73
74 if (pins.ss2) {
75 return E_BAD_PARAM;
76 }
77 } else if (spi == MXC_SPI1) {
78 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
79 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
80 MXC_GPIO_Config(&gpio_cfg_spi1);
81
82 // Enable slave select pins
83 if (pins.ss0) {
84 MXC_GPIO_Config(&gpio_cfg_spi1_ss0);
85 }
86
87 if (pins.ss1) {
88 MXC_GPIO_Config(&gpio_cfg_spi1_ss1);
89 }
90
91 if (pins.ss2) {
92 MXC_GPIO_Config(&gpio_cfg_spi1_ss2);
93 }
94 } else if (spi == MXC_SPI2) {
95 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI2);
96 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI2);
97 MXC_GPIO_Config(&gpio_cfg_spi2);
98
99 // Enable slave select pins
100 if (pins.ss0) {
101 MXC_GPIO_Config(&gpio_cfg_spi2_ss0);
102 }
103
104 if (pins.ss1) {
105 MXC_GPIO_Config(&gpio_cfg_spi2_ss1);
106 }
107
108 if (pins.ss2) {
109 MXC_GPIO_Config(&gpio_cfg_spi2_ss2);
110 }
111 #ifndef __riscv
112 } else if (spi == MXC_SPI3) {
113 MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI3);
114 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI3);
115 MXC_GPIO_Config(&gpio_cfg_spi3);
116
117 // Enable slave select pins
118 if (pins.ss0) {
119 MXC_GPIO_Config(&gpio_cfg_spi3_ss0);
120 }
121
122 if (pins.ss1) {
123 MXC_GPIO_Config(&gpio_cfg_spi3_ss1);
124 }
125
126 if (pins.ss2) {
127 MXC_GPIO_Config(&gpio_cfg_spi3_ss2);
128 }
129 } else if (spi == MXC_SPI4) {
130 MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI4);
131 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI4);
132 MXC_GPIO_Config(&gpio_cfg_spi4);
133
134 // Enable slave select pins
135 if (pins.ss0) {
136 MXC_GPIO_Config(&gpio_cfg_spi4_ss0);
137 }
138
139 if (pins.ss1) {
140 MXC_GPIO_Config(&gpio_cfg_spi4_ss1);
141 }
142
143 if (pins.ss2) {
144 MXC_GPIO_Config(&gpio_cfg_spi4_ss2);
145 }
146 #endif // __riscv
147 } else {
148 return E_NO_DEVICE;
149 }
150 #else
151 (void)pins;
152 #endif // MSDK_NO_GPIO_CLK_INIT
153
154 return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves,
155 ssPolarity, hz);
156 }
157
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)158 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
159 {
160 int spi_num;
161 spi_num = MXC_SPI_GET_IDX(spi);
162 MXC_ASSERT(spi_num >= 0);
163 (void)spi_num;
164
165 MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi);
166
167 if (spi == MXC_SPI0) {
168 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
169 } else if (spi == MXC_SPI1) {
170 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
171 } else if (spi == MXC_SPI2) {
172 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI2);
173 #ifndef __riscv
174 } else if (spi == MXC_SPI3) {
175 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI3);
176 } else if (spi == MXC_SPI4) {
177 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI4);
178 #endif //__riscv
179 } else {
180 return E_NO_DEVICE;
181 }
182
183 return E_NO_ERROR;
184 }
185
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)186 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
187 {
188 return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
189 }
190
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)191 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
192 {
193 int clk_freq = 0;
194
195 if (MXC_SPI_GET_IDX(spi) > -1 && MXC_SPI_GET_IDX(spi) < 3) {
196 clk_freq = PeripheralClock;
197 } else if (MXC_SPI_GET_IDX(spi) > 2) {
198 uint32_t clk_src = (MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL) >>
199 MXC_F_GCR_CLKCTRL_SYSCLK_SEL_POS;
200 switch (clk_src) {
201 case MXC_SYS_CLOCK_IPO:
202 clk_freq = IPO_FREQ;
203 break;
204 case MXC_SYS_CLOCK_ERFO:
205 clk_freq = ERFO_FREQ;
206 break;
207 case MXC_SYS_CLOCK_IBRO:
208 clk_freq = IBRO_FREQ;
209 break;
210 case MXC_SYS_CLOCK_ISO:
211 clk_freq = ISO_FREQ;
212 break;
213 case MXC_SYS_CLOCK_INRO:
214 clk_freq = INRO_FREQ;
215 break;
216 case MXC_SYS_CLOCK_ERTCO:
217 clk_freq = ERTCO_FREQ;
218 break;
219 case MXC_SYS_CLOCK_EXTCLK:
220 clk_freq = EXTCLK_FREQ;
221 break;
222 default:
223 return E_BAD_PARAM;
224 }
225 } else {
226 return E_BAD_PARAM;
227 }
228 return (clk_freq / 2);
229 }
230
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)231 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
232 {
233 return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
234 }
235
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)236 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
237 {
238 return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi);
239 }
240
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)241 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
242 {
243 return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize);
244 }
245
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)246 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
247 {
248 return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi);
249 }
250
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)251 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
252 {
253 return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx);
254 }
255
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)256 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
257 {
258 return MXC_SPI_RevA1_GetSlave((mxc_spi_reva_regs_t *)spi);
259 }
260
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)261 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
262 {
263 return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, (mxc_spi_reva_width_t)spiWidth);
264 }
265
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)266 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
267 {
268 return (mxc_spi_width_t)MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi);
269 }
270
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)271 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
272 {
273 return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, (mxc_spi_reva_mode_t)spiMode);
274 }
275
MXC_SPI_GetMode(mxc_spi_regs_t * spi)276 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
277 {
278 return (mxc_spi_mode_t)MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi);
279 }
280
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)281 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
282 {
283 return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi);
284 }
285
MXC_SPI_GetActive(mxc_spi_regs_t * spi)286 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
287 {
288 return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi);
289 }
290
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)291 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
292 {
293 return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi);
294 }
295
MXC_SPI_ReadRXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)296 unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
297 {
298 return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
299 }
300
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)301 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
302 {
303 return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
304 }
305
MXC_SPI_WriteTXFIFO(mxc_spi_regs_t * spi,unsigned char * bytes,unsigned int len)306 unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len)
307 {
308 return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len);
309 }
310
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)311 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
312 {
313 return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
314 }
315
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)316 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
317 {
318 MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
319 }
320
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)321 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
322 {
323 MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
324 }
325
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)326 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
327 {
328 return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
329 }
330
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)331 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
332 {
333 return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
334 }
335
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)336 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
337 {
338 return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
339 }
340
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)341 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
342 {
343 return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
344 }
345
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)346 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
347 {
348 return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi);
349 }
350
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)351 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
352 {
353 MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi);
354 }
355
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int intEn)356 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn)
357 {
358 MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, intEn);
359 }
360
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int intDis)361 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis)
362 {
363 MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, intDis);
364 }
365
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)366 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
367 {
368 return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req);
369 }
370
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)371 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
372 {
373 return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req);
374 }
375
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)376 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
377 {
378 int reqselTx = -1;
379 int reqselRx = -1;
380
381 int spi_num;
382
383 spi_num = MXC_SPI_GET_IDX(req->spi);
384 MXC_ASSERT(spi_num >= 0);
385
386 if (req->txData != NULL) {
387 switch (spi_num) {
388 case 0:
389 reqselTx = MXC_DMA_REQUEST_SPI0TX;
390 break;
391 case 1:
392 reqselTx = MXC_DMA_REQUEST_SPI1TX;
393 break;
394 case 2:
395 reqselTx = MXC_DMA_REQUEST_SPI2TX;
396 break;
397 case 3:
398 reqselTx = MXC_DMA_REQUEST_SPI3TX;
399 break;
400 case 4:
401 reqselTx = MXC_DMA_REQUEST_SPI4TX;
402 break;
403 default:
404 return E_BAD_PARAM;
405 }
406 }
407
408 if (req->rxData != NULL) {
409 switch (spi_num) {
410 case 0:
411 reqselRx = MXC_DMA_REQUEST_SPI0RX;
412 break;
413 case 1:
414 reqselRx = MXC_DMA_REQUEST_SPI1RX;
415 break;
416 case 2:
417 reqselRx = MXC_DMA_REQUEST_SPI2RX;
418 break;
419 case 3:
420 reqselRx = MXC_DMA_REQUEST_SPI3RX;
421 break;
422 case 4:
423 reqselRx = MXC_DMA_REQUEST_SPI4RX;
424 break;
425 default:
426 return E_BAD_PARAM;
427 }
428 }
429
430 return MXC_SPI_RevA1_MasterTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
431 MXC_DMA);
432 }
433
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)434 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
435 {
436 return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req);
437 }
438
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)439 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
440 {
441 return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req);
442 }
443
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)444 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
445 {
446 int reqselTx = -1;
447 int reqselRx = -1;
448
449 int spi_num;
450
451 spi_num = MXC_SPI_GET_IDX(req->spi);
452 MXC_ASSERT(spi_num >= 0);
453
454 if (req->txData != NULL) {
455 switch (spi_num) {
456 case 0:
457 reqselRx = MXC_DMA_REQUEST_SPI0TX;
458 break;
459 case 1:
460 reqselRx = MXC_DMA_REQUEST_SPI1TX;
461 break;
462 case 2:
463 reqselTx = MXC_DMA_REQUEST_SPI2TX;
464 break;
465 case 3:
466 reqselTx = MXC_DMA_REQUEST_SPI3TX;
467 break;
468 case 4:
469 reqselTx = MXC_DMA_REQUEST_SPI4TX;
470 break;
471 default:
472 return E_BAD_PARAM;
473 break;
474 }
475 }
476
477 if (req->rxData != NULL) {
478 switch (spi_num) {
479 case 0:
480 reqselRx = MXC_DMA_REQUEST_SPI0RX;
481 break;
482 case 1:
483 reqselRx = MXC_DMA_REQUEST_SPI1RX;
484 break;
485 case 2:
486 reqselTx = MXC_DMA_REQUEST_SPI2RX;
487 break;
488 case 3:
489 reqselTx = MXC_DMA_REQUEST_SPI3RX;
490 break;
491 case 4:
492 reqselTx = MXC_DMA_REQUEST_SPI4RX;
493 break;
494 default:
495 return E_BAD_PARAM;
496 break;
497 }
498 }
499
500 return MXC_SPI_RevA1_SlaveTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx,
501 MXC_DMA);
502 }
503
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)504 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
505 {
506 return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData);
507 }
508
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)509 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
510 {
511 MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi);
512 }
513
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)514 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
515 {
516 MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi);
517 }
518
MXC_SPI_HWSSControl(mxc_spi_regs_t * spi,int state)519 void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state)
520 {
521 MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state);
522 }
523