1 /******************************************************************************
2  * Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
18  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Except as contained in this notice, the name of Maxim Integrated
23  * Products, Inc. shall not be used except as stated in the Maxim Integrated
24  * Products, Inc. Branding Policy.
25  *
26  * The mere transfer of this software does not imply any licenses
27  * of trade secrets, proprietary technology, copyrights, patents,
28  * trademarks, maskwork rights, or any other form of intellectual
29  * property whatsoever. Maxim Integrated Products, Inc. retains all
30  * ownership rights.
31  *
32  ******************************************************************************/
33 
34 #include <stdio.h>
35 #include <stddef.h>
36 #include <stdint.h>
37 #include <stdbool.h>
38 
39 #include "mxc_device.h"
40 #include "mxc_assert.h"
41 #include "mxc_errors.h"
42 #include "mxc_lock.h"
43 #include "mxc_sys.h"
44 #include "mxc_delay.h"
45 #include "spi_reva2.h"
46 #include "spi.h"
47 #include "dma.h"
48 #include "gpio.h"
49 
50 /* **** Definitions **** */
51 
52 /* ************************************************************************** */
53 
54 // Max 4 Possible Target Select Options per SPI instance
55 #define MXC_SPI_TS0_MASK_POS (0)
56 #define MXC_SPI_TS1_MASK_POS (1)
57 #define MXC_SPI_TS2_MASK_POS (2)
58 #define MXC_SPI_TS3_MASK_POS (3)
59 
MXC_SPI_Init(mxc_spi_regs_t * spi,mxc_spi_type_t controller_target,mxc_spi_interface_t if_mode,int numTargets,uint8_t ts_active_pol_mask,uint32_t freq,mxc_spi_pins_t pins)60 int MXC_SPI_Init(mxc_spi_regs_t *spi, mxc_spi_type_t controller_target, mxc_spi_interface_t if_mode,
61                  int numTargets, uint8_t ts_active_pol_mask, uint32_t freq, mxc_spi_pins_t pins)
62 {
63     int error;
64     int8_t spi_num;
65     mxc_spi_tscontrol_t ts_control;
66     mxc_gpio_cfg_t temp_cfg; // main SPI pins.
67     mxc_gpio_cfg_t temp_ts_cfg; // TS pins.
68     mxc_gpio_vssel_t vssel;
69 
70     spi_num = MXC_SPI_GET_IDX(spi);
71     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
72         return E_BAD_PARAM;
73     }
74 
75     // Check if frequency is too high
76     if ((spi_num == 0) && (freq > MXC_SPI_GetPeripheralClock(spi))) {
77         return E_BAD_PARAM;
78     }
79 
80     if ((spi_num == 1) && (freq > SystemCoreClock)) {
81         return E_BAD_PARAM;
82     }
83 
84     if (pins.vddioh) {
85         vssel = MXC_GPIO_VSSEL_VDDIOH;
86     } else {
87         vssel = MXC_GPIO_VSSEL_VDDIO;
88     }
89 
90     // SPI Target mode only supports HW_AUTO.
91     if (pins.ss0 || pins.ss1 || pins.ss2 || (controller_target == MXC_SPI_TYPE_TARGET)) {
92         ts_control = MXC_SPI_TSCONTROL_HW_AUTO;
93     } else {
94         ts_control = MXC_SPI_TSCONTROL_SW_APP;
95     }
96 
97     error = MXC_SPI_RevA2_SetTSControl((mxc_spi_reva_regs_t *)spi, ts_control);
98     if (error != E_NO_ERROR) {
99         return error;
100     }
101 
102     // Configure SPI peripheral and pins.
103     if (spi == MXC_SPI0) {
104         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI0);
105         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
106 
107         switch (if_mode) {
108         case MXC_SPI_INTERFACE_STANDARD:
109             temp_cfg = gpio_cfg_spi0_standard;
110             break;
111 
112         case MXC_SPI_INTERFACE_QUAD:
113             return E_NOT_SUPPORTED;
114 
115         case MXC_SPI_INTERFACE_3WIRE:
116             temp_cfg = gpio_cfg_spi0_3wire;
117             break;
118 
119         case MXC_SPI_INTERFACE_DUAL:
120             temp_cfg = gpio_cfg_spi0_dual;
121             break;
122 
123         default:
124             return E_BAD_PARAM;
125         }
126 
127         // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
128         // Voltage and drive strength settings will match the SPI pins.
129         if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
130             // Target Select 0 - TS0 (L. SS0 pin)
131             if (pins.ss0 == true) {
132                 temp_ts_cfg = gpio_cfg_spi0_ts0;
133                 temp_ts_cfg.vssel = vssel;
134                 temp_ts_cfg.drvstr = pins.drvstr;
135 
136                 error = MXC_GPIO_Config(&temp_ts_cfg);
137                 if (error != E_NO_ERROR) {
138                     return error;
139                 }
140             }
141         }
142     } else if (spi == MXC_SPI1) {
143         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
144         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
145 
146         switch (if_mode) {
147         case MXC_SPI_INTERFACE_STANDARD:
148             temp_cfg = gpio_cfg_spi1_standard;
149             break;
150 
151         case MXC_SPI_INTERFACE_QUAD:
152             return E_NOT_SUPPORTED;
153 
154         case MXC_SPI_INTERFACE_3WIRE:
155             temp_cfg = gpio_cfg_spi1_3wire;
156             break;
157 
158         case MXC_SPI_INTERFACE_DUAL:
159             temp_cfg = gpio_cfg_spi1_dual;
160             break;
161 
162         default:
163             return E_BAD_PARAM;
164         }
165 
166         // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
167         // Voltage and drive strength settings will match the SPI pins.
168         if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
169             // Target Select 0 - TS0 (L. SS0 pin)
170             if (pins.ss0 == true) {
171                 temp_ts_cfg = gpio_cfg_spi1_ts0;
172                 temp_ts_cfg.vssel = vssel;
173                 temp_ts_cfg.drvstr = pins.drvstr;
174 
175                 error = MXC_GPIO_Config(&temp_ts_cfg);
176                 if (error != E_NO_ERROR) {
177                     return error;
178                 }
179             }
180 
181             // Target Select 1 - TS1 (L. SS1 pin)
182             if (pins.ss1 == true) {
183                 temp_ts_cfg = gpio_cfg_spi1_ts1;
184                 temp_ts_cfg.vssel = vssel;
185                 temp_ts_cfg.drvstr = pins.drvstr;
186 
187                 error = MXC_GPIO_Config(&temp_ts_cfg);
188                 if (error != E_NO_ERROR) {
189                     return error;
190                 }
191             }
192 
193             // Target Select 2 - TS2 (L. SS2 pin)
194             if (pins.ss2 == true) {
195                 temp_ts_cfg = gpio_cfg_spi1_ts2;
196                 temp_ts_cfg.vssel = vssel;
197                 temp_ts_cfg.drvstr = pins.drvstr;
198 
199                 error = MXC_GPIO_Config(&temp_ts_cfg);
200                 if (error != E_NO_ERROR) {
201                     return error;
202                 }
203             }
204 
205             // Target Select 3 - TS2 (L. SS3 pin)
206             if (pins.ss3 == true) {
207                 temp_ts_cfg = gpio_cfg_spi1_ts3;
208                 temp_ts_cfg.vssel = vssel;
209                 temp_ts_cfg.drvstr = pins.drvstr;
210 
211                 error = MXC_GPIO_Config(&temp_ts_cfg);
212                 if (error != E_NO_ERROR) {
213                     return error;
214                 }
215             }
216         }
217         // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
218     } else if (spi == MXC_SPI3) {
219         MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI3);
220         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI3);
221 
222         switch (if_mode) {
223         case MXC_SPI_INTERFACE_STANDARD:
224             temp_cfg = gpio_cfg_spi3_standard;
225             break;
226 
227         case MXC_SPI_INTERFACE_QUAD:
228             temp_cfg = gpio_cfg_spi3_quad;
229             break;
230 
231         case MXC_SPI_INTERFACE_3WIRE:
232             temp_cfg = gpio_cfg_spi3_3wire;
233             break;
234 
235         case MXC_SPI_INTERFACE_DUAL:
236             temp_cfg = gpio_cfg_spi3_dual;
237             break;
238 
239         default:
240             return E_BAD_PARAM;
241         }
242 
243         // Set up HW TS pins (if HW_AUTO TS control scheme was selected).
244         // Voltage and drive strength settings will match the SPI pins.
245         if (ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
246             // Target Select 0 - TS0 (L. SS0 pin)
247             if (pins.ss0 == true) {
248                 temp_ts_cfg = gpio_cfg_spi3_ts0;
249                 temp_ts_cfg.vssel = vssel;
250                 temp_ts_cfg.drvstr = pins.drvstr;
251 
252                 error = MXC_GPIO_Config(&temp_ts_cfg);
253                 if (error != E_NO_ERROR) {
254                     return error;
255                 }
256             }
257 
258             // Target Select 1 - TS1 (L. SS1 pin)
259             if (pins.ss1 == true) {
260                 temp_ts_cfg = gpio_cfg_spi3_ts1;
261                 temp_ts_cfg.vssel = vssel;
262                 temp_ts_cfg.drvstr = pins.drvstr;
263 
264                 error = MXC_GPIO_Config(&temp_ts_cfg);
265                 if (error != E_NO_ERROR) {
266                     return error;
267                 }
268             }
269 
270             // Target Select 2 - TS2 (L. SS2 pin)
271             if (pins.ss2 == true) {
272                 temp_ts_cfg = gpio_cfg_spi3_ts2;
273                 temp_ts_cfg.vssel = vssel;
274                 temp_ts_cfg.drvstr = pins.drvstr;
275 
276                 error = MXC_GPIO_Config(&temp_ts_cfg);
277                 if (error != E_NO_ERROR) {
278                     return error;
279                 }
280             }
281 
282             // Target Select 3 - TS2 (L. SS3 pin)
283             if (pins.ss3 == true) {
284                 temp_ts_cfg = gpio_cfg_spi3_ts3;
285                 temp_ts_cfg.vssel = vssel;
286                 temp_ts_cfg.drvstr = pins.drvstr;
287 
288                 error = MXC_GPIO_Config(&temp_ts_cfg);
289                 if (error != E_NO_ERROR) {
290                     return error;
291                 }
292             }
293         }
294 
295     } else {
296         return E_NO_DEVICE;
297     }
298 
299     temp_cfg.vssel = vssel;
300     temp_cfg.drvstr = pins.drvstr;
301 
302     // Configure main SPI pins.
303     error = MXC_GPIO_Config(&temp_cfg);
304     if (error != E_NO_ERROR) {
305         return error;
306     }
307 
308     return MXC_SPI_RevA2_Init((mxc_spi_reva_regs_t *)spi, controller_target, if_mode, freq,
309                               ts_active_pol_mask);
310 }
311 
MXC_SPI_Config(mxc_spi_cfg_t * cfg)312 int MXC_SPI_Config(mxc_spi_cfg_t *cfg)
313 {
314     return MXC_SPI_RevA2_Config(cfg);
315 }
316 
MXC_SPI_ConfigStruct(mxc_spi_cfg_t * cfg,bool use_dma_tx,bool use_dma_rx)317 int MXC_SPI_ConfigStruct(mxc_spi_cfg_t *cfg, bool use_dma_tx, bool use_dma_rx)
318 {
319     if (cfg == NULL) {
320         return E_BAD_PARAM;
321     }
322 
323     cfg->spi = MXC_SPI1; // SPI1 is available on both the ARM and RISCV core.
324     cfg->clk_mode = MXC_SPI_CLKMODE_0; // 0 - CPOL :: 0 - CPHA
325 
326     if (use_dma_tx || use_dma_rx) {
327         cfg->use_dma_tx = use_dma_tx;
328         cfg->use_dma_rx = use_dma_rx;
329         cfg->dma = MXC_DMA;
330     } else {
331         cfg->use_dma_tx = false;
332         cfg->use_dma_rx = false;
333         cfg->dma = NULL;
334     }
335 
336     return E_SUCCESS;
337 }
338 
MXC_SPI_Shutdown(mxc_spi_regs_t * spi)339 int MXC_SPI_Shutdown(mxc_spi_regs_t *spi)
340 {
341     int8_t spi_num;
342 
343     spi_num = MXC_SPI_GET_IDX(spi);
344     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
345         return E_BAD_PARAM;
346     }
347 
348     MXC_SPI_RevA2_Shutdown((mxc_spi_reva_regs_t *)spi);
349 
350     if (spi == MXC_SPI0) {
351         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0);
352     } else if (spi == MXC_SPI1) {
353         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1);
354         // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
355     } else if (spi == MXC_SPI3) {
356         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI3);
357     } else {
358         return E_NO_DEVICE;
359     }
360 
361     return E_NO_ERROR;
362 }
363 
MXC_SPI_GetFlags(mxc_spi_regs_t * spi)364 unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi)
365 {
366     return (unsigned int)MXC_SPI_RevA2_GetFlags((mxc_spi_reva_regs_t *)spi);
367 }
368 
MXC_SPI_ClearFlags(mxc_spi_regs_t * spi)369 void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi)
370 {
371     MXC_SPI_RevA2_ClearFlags((mxc_spi_reva_regs_t *)spi);
372 }
373 
MXC_SPI_EnableInt(mxc_spi_regs_t * spi,unsigned int intEn)374 void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn)
375 {
376     MXC_SPI_RevA2_EnableInt((mxc_spi_reva_regs_t *)spi, (uint32_t)intEn);
377 }
378 
MXC_SPI_DisableInt(mxc_spi_regs_t * spi,unsigned int intDis)379 void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis)
380 {
381     MXC_SPI_RevA2_DisableInt((mxc_spi_reva_regs_t *)spi, (uint32_t)intDis);
382 }
383 
MXC_SPI_GetPeripheralClock(mxc_spi_regs_t * spi)384 int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi)
385 {
386     int retval;
387 
388     retval = PeripheralClock;
389     retval /= 2;
390 
391     return retval;
392 }
393 
MXC_SPI_SetTSControl(mxc_spi_regs_t * spi,mxc_spi_tscontrol_t ts_control)394 int MXC_SPI_SetTSControl(mxc_spi_regs_t *spi, mxc_spi_tscontrol_t ts_control)
395 {
396     return MXC_SPI_RevA2_SetTSControl((mxc_spi_reva_regs_t *)spi, ts_control);
397 }
398 
MXC_SPI_GetTSControl(mxc_spi_regs_t * spi)399 mxc_spi_tscontrol_t MXC_SPI_GetTSControl(mxc_spi_regs_t *spi)
400 {
401     return MXC_SPI_RevA2_GetTSControl((mxc_spi_reva_regs_t *)spi);
402 }
403 
MXC_SPI_SetFrequency(mxc_spi_regs_t * spi,unsigned int hz)404 int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz)
405 {
406     return MXC_SPI_RevA2_SetFrequency((mxc_spi_reva_regs_t *)spi, hz);
407 }
408 
MXC_SPI_GetFrequency(mxc_spi_regs_t * spi)409 unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi)
410 {
411     return MXC_SPI_RevA2_GetFrequency((mxc_spi_reva_regs_t *)spi);
412 }
413 
MXC_SPI_SetFrameSize(mxc_spi_regs_t * spi,int frame_size)414 int MXC_SPI_SetFrameSize(mxc_spi_regs_t *spi, int frame_size)
415 {
416     return MXC_SPI_RevA2_SetFrameSize((mxc_spi_reva_regs_t *)spi, frame_size);
417 }
418 
MXC_SPI_GetFrameSize(mxc_spi_regs_t * spi)419 int MXC_SPI_GetFrameSize(mxc_spi_regs_t *spi)
420 {
421     return MXC_SPI_RevA2_GetFrameSize((mxc_spi_reva_regs_t *)spi);
422 }
423 
MXC_SPI_SetInterface(mxc_spi_regs_t * spi,mxc_spi_interface_t mode)424 int MXC_SPI_SetInterface(mxc_spi_regs_t *spi, mxc_spi_interface_t mode)
425 {
426     return MXC_SPI_RevA2_SetInterface((mxc_spi_reva_regs_t *)spi, mode);
427 }
428 
MXC_SPI_GetInterface(mxc_spi_regs_t * spi)429 mxc_spi_interface_t MXC_SPI_GetInterface(mxc_spi_regs_t *spi)
430 {
431     return MXC_SPI_RevA2_GetInterface((mxc_spi_reva_regs_t *)spi);
432 }
433 
MXC_SPI_SetClkMode(mxc_spi_regs_t * spi,mxc_spi_clkmode_t clk_mode)434 int MXC_SPI_SetClkMode(mxc_spi_regs_t *spi, mxc_spi_clkmode_t clk_mode)
435 {
436     return MXC_SPI_RevA2_SetClkMode((mxc_spi_reva_regs_t *)spi, clk_mode);
437 }
438 
MXC_SPI_GetClkMode(mxc_spi_regs_t * spi)439 mxc_spi_clkmode_t MXC_SPI_GetClkMode(mxc_spi_regs_t *spi)
440 {
441     return MXC_SPI_RevA2_GetClkMode((mxc_spi_reva_regs_t *)spi);
442 }
443 
MXC_SPI_SetCallback(mxc_spi_regs_t * spi,mxc_spi_callback_t completeCB,void * data)444 int MXC_SPI_SetCallback(mxc_spi_regs_t *spi, mxc_spi_callback_t completeCB, void *data)
445 {
446     return MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)spi, completeCB, data);
447 }
448 
MXC_SPI_GetActive(mxc_spi_regs_t * spi)449 int MXC_SPI_GetActive(mxc_spi_regs_t *spi)
450 {
451     return MXC_SPI_RevA2_GetActive((mxc_spi_reva_regs_t *)spi);
452 }
453 
MXC_SPI_ReadyForSleep(mxc_spi_regs_t * spi)454 int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi)
455 {
456     return MXC_SPI_RevA2_ReadyForSleep((mxc_spi_reva_regs_t *)spi);
457 }
458 
MXC_SPI_SetDummyTX(mxc_spi_regs_t * spi,uint16_t tx_value)459 int MXC_SPI_SetDummyTX(mxc_spi_regs_t *spi, uint16_t tx_value)
460 {
461     return MXC_SPI_RevA2_SetDummyTX((mxc_spi_reva_regs_t *)spi, tx_value);
462 }
463 
MXC_SPI_StartTransmission(mxc_spi_regs_t * spi)464 int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi)
465 {
466     return MXC_SPI_RevA2_StartTransmission((mxc_spi_reva_regs_t *)spi);
467 }
468 
MXC_SPI_AbortTransmission(mxc_spi_regs_t * spi)469 int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi)
470 {
471     return MXC_SPI_RevA2_AbortTransmission((mxc_spi_reva_regs_t *)spi);
472 }
473 
MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t * spi)474 unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi)
475 {
476     return MXC_SPI_RevA2_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
477 }
478 
MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t * spi)479 unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi)
480 {
481     return MXC_SPI_RevA2_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi);
482 }
483 
MXC_SPI_ClearTXFIFO(mxc_spi_regs_t * spi)484 void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi)
485 {
486     MXC_SPI_RevA2_ClearTXFIFO((mxc_spi_reva_regs_t *)spi);
487 }
488 
MXC_SPI_ClearRXFIFO(mxc_spi_regs_t * spi)489 void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi)
490 {
491     MXC_SPI_RevA2_ClearRXFIFO((mxc_spi_reva_regs_t *)spi);
492 }
493 
MXC_SPI_SetTXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)494 int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
495 {
496     return (int)MXC_SPI_RevA2_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
497 }
498 
MXC_SPI_SetRXThreshold(mxc_spi_regs_t * spi,unsigned int numBytes)499 int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes)
500 {
501     return (int)MXC_SPI_RevA2_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes);
502 }
503 
MXC_SPI_GetTXThreshold(mxc_spi_regs_t * spi)504 unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi)
505 {
506     return (unsigned int)MXC_SPI_RevA2_GetTXThreshold((mxc_spi_reva_regs_t *)spi);
507 }
508 
MXC_SPI_GetRXThreshold(mxc_spi_regs_t * spi)509 unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi)
510 {
511     return (unsigned int)MXC_SPI_RevA2_GetRXThreshold((mxc_spi_reva_regs_t *)spi);
512 }
513 
514 /* ** DMA-Specific Functions ** */
515 
MXC_SPI_DMA_Init(mxc_spi_regs_t * spi,mxc_dma_regs_t * dma,bool use_dma_tx,bool use_dma_rx)516 int MXC_SPI_DMA_Init(mxc_spi_regs_t *spi, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx)
517 {
518     return MXC_SPI_RevA2_DMA_Init((mxc_spi_reva_regs_t *)spi, (mxc_dma_reva_regs_t *)dma,
519                                   use_dma_tx, use_dma_rx);
520 }
521 
MXC_SPI_DMA_GetInitialized(mxc_spi_regs_t * spi)522 bool MXC_SPI_DMA_GetInitialized(mxc_spi_regs_t *spi)
523 {
524     return MXC_SPI_RevA2_DMA_GetInitialized((mxc_spi_reva_regs_t *)spi);
525 }
526 
MXC_SPI_DMA_GetTXChannel(mxc_spi_regs_t * spi)527 int MXC_SPI_DMA_GetTXChannel(mxc_spi_regs_t *spi)
528 {
529     return MXC_SPI_RevA2_DMA_GetTXChannel((mxc_spi_reva_regs_t *)spi);
530 }
531 
MXC_SPI_DMA_GetRXChannel(mxc_spi_regs_t * spi)532 int MXC_SPI_DMA_GetRXChannel(mxc_spi_regs_t *spi)
533 {
534     return MXC_SPI_RevA2_DMA_GetRXChannel((mxc_spi_reva_regs_t *)spi);
535 }
536 
MXC_SPI_DMA_SetRequestSelect(mxc_spi_regs_t * spi,bool use_dma_tx,bool use_dma_rx)537 int MXC_SPI_DMA_SetRequestSelect(mxc_spi_regs_t *spi, bool use_dma_tx, bool use_dma_rx)
538 {
539     int8_t spi_num;
540     int tx_reqsel = -1;
541     int rx_reqsel = -1;
542 
543     spi_num = MXC_SPI_GET_IDX(spi);
544     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
545         return E_INVALID;
546     }
547 
548     if (use_dma_tx) {
549         switch (spi_num) {
550         case 0:
551             tx_reqsel = MXC_DMA_REQUEST_SPI0TX;
552             break;
553 
554         case 1:
555             tx_reqsel = MXC_DMA_REQUEST_SPI1TX;
556             break;
557 
558             // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
559 
560         case 3:
561             tx_reqsel = MXC_DMA_REQUEST_SPI3TX;
562             break;
563 
564         default:
565             return E_BAD_PARAM;
566         }
567     }
568 
569     if (use_dma_rx) {
570         switch (spi_num) {
571         case 0:
572             rx_reqsel = MXC_DMA_REQUEST_SPI0RX;
573             break;
574 
575         case 1:
576             rx_reqsel = MXC_DMA_REQUEST_SPI1RX;
577             break;
578 
579             // SPI2 does not exist in the MAX32572 (to match instance addressing with MAX32570B)
580 
581         case 3:
582             rx_reqsel = MXC_DMA_REQUEST_SPI3RX;
583             break;
584 
585         default:
586             return E_BAD_PARAM;
587         }
588     }
589 
590     return MXC_SPI_RevA2_DMA_SetRequestSelect((mxc_spi_reva_regs_t *)spi, tx_reqsel, rx_reqsel);
591 }
592 
593 /* ** Transaction Functions ** */
594 
MXC_SPI_MasterTransaction(mxc_spi_req_t * req)595 int MXC_SPI_MasterTransaction(mxc_spi_req_t *req)
596 {
597     return MXC_SPI_RevA2_ControllerTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
598                                                req->txLen, req->rxData, req->rxLen, req->ssDeassert,
599                                                req->ssIdx);
600 }
601 
MXC_SPI_MasterTransactionAsync(mxc_spi_req_t * req)602 int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req)
603 {
604     int error;
605 
606     // Users can set their own callback and pass in their own data if they choose to.
607     if (req->completeCB != NULL) {
608         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
609         if (error != E_NO_ERROR) {
610             return error;
611         }
612     }
613 
614     return MXC_SPI_RevA2_ControllerTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
615                                                     req->txLen, req->rxData, req->rxLen,
616                                                     req->ssDeassert, req->ssIdx);
617 }
618 
MXC_SPI_MasterTransactionDMA(mxc_spi_req_t * req)619 int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req)
620 {
621     int error;
622 
623     // Users can set their own callback and pass in their own data if they choose to.
624     if (req->completeCB != NULL) {
625         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
626         if (error != E_NO_ERROR) {
627             return error;
628         }
629     }
630 
631     return MXC_SPI_RevA2_ControllerTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
632                                                   req->txLen, req->rxData, req->rxLen,
633                                                   req->ssDeassert, req->ssIdx,
634                                                   (mxc_dma_reva_regs_t *)MXC_DMA);
635 }
636 
MXC_SPI_ControllerTransaction(mxc_spi_req_t * req)637 int MXC_SPI_ControllerTransaction(mxc_spi_req_t *req)
638 {
639     return MXC_SPI_RevA2_ControllerTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
640                                                req->txLen, req->rxData, req->rxLen, req->ssDeassert,
641                                                req->ssIdx);
642 }
643 
MXC_SPI_ControllerTransactionAsync(mxc_spi_req_t * req)644 int MXC_SPI_ControllerTransactionAsync(mxc_spi_req_t *req)
645 {
646     int error;
647 
648     // Users can set their own callback and pass in their own data if they choose to.
649     if (req->completeCB != NULL) {
650         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
651         if (error != E_NO_ERROR) {
652             return error;
653         }
654     }
655 
656     return MXC_SPI_RevA2_ControllerTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
657                                                     req->txLen, req->rxData, req->rxLen,
658                                                     req->ssDeassert, req->ssIdx);
659 }
660 
MXC_SPI_ControllerTransactionDMA(mxc_spi_req_t * req)661 int MXC_SPI_ControllerTransactionDMA(mxc_spi_req_t *req)
662 {
663     int error;
664 
665     // Users can set their own callback and pass in their own data if they choose to.
666     if (req->completeCB != NULL) {
667         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
668         if (error != E_NO_ERROR) {
669             return error;
670         }
671     }
672 
673     return MXC_SPI_RevA2_ControllerTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
674                                                   req->txLen, req->rxData, req->rxLen,
675                                                   req->ssDeassert, req->ssIdx,
676                                                   (mxc_dma_reva_regs_t *)MXC_DMA);
677 }
678 
MXC_SPI_SlaveTransaction(mxc_spi_req_t * req)679 int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req)
680 {
681     return MXC_SPI_RevA2_TargetTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
682                                            req->txLen, req->rxData, req->rxLen);
683 }
684 
MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t * req)685 int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req)
686 {
687     int error;
688 
689     // Users can set their own callback and pass in their own data if they choose to.
690     if (req->completeCB != NULL) {
691         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
692         if (error != E_NO_ERROR) {
693             return error;
694         }
695     }
696 
697     return MXC_SPI_RevA2_TargetTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
698                                                 req->txLen, req->rxData, req->rxLen);
699 }
700 
MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t * req)701 int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req)
702 {
703     int error;
704 
705     // Users can set their own callback and pass in their own data if they choose to.
706     if (req->completeCB != NULL) {
707         error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
708         if (error != E_NO_ERROR) {
709             return error;
710         }
711     }
712 
713     return MXC_SPI_RevA2_TargetTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
714                                               req->txLen, req->rxData, req->rxLen,
715                                               (mxc_dma_reva_regs_t *)MXC_DMA);
716 }
717 
MXC_SPI_TargetTransaction(mxc_spi_req_t * req)718 int MXC_SPI_TargetTransaction(mxc_spi_req_t *req)
719 {
720     return MXC_SPI_RevA2_TargetTransaction((mxc_spi_reva_regs_t *)(req->spi), req->txData,
721                                            req->txLen, req->rxData, req->rxLen);
722 }
723 
MXC_SPI_TargetTransactionAsync(mxc_spi_req_t * req)724 int MXC_SPI_TargetTransactionAsync(mxc_spi_req_t *req)
725 {
726     int error;
727 
728     error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
729     if (error != E_NO_ERROR) {
730         return error;
731     }
732 
733     return MXC_SPI_RevA2_TargetTransactionAsync((mxc_spi_reva_regs_t *)(req->spi), req->txData,
734                                                 req->txLen, req->rxData, req->rxLen);
735 }
736 
MXC_SPI_TargetTransactionDMA(mxc_spi_req_t * req)737 int MXC_SPI_TargetTransactionDMA(mxc_spi_req_t *req)
738 {
739     int error;
740 
741     error = MXC_SPI_RevA2_SetCallback((mxc_spi_reva_regs_t *)(req->spi), req->completeCB, req);
742     if (error != E_NO_ERROR) {
743         return error;
744     }
745 
746     return MXC_SPI_RevA2_TargetTransactionDMA((mxc_spi_reva_regs_t *)(req->spi), req->txData,
747                                               req->txLen, req->rxData, req->rxLen,
748                                               (mxc_dma_reva_regs_t *)MXC_DMA);
749 }
750 
751 /* ** Handler Functions ** */
752 
MXC_SPI_AsyncHandler(mxc_spi_regs_t * spi)753 void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi)
754 {
755     MXC_SPI_RevA2_Handler((mxc_spi_reva_regs_t *)spi);
756 }
757 
MXC_SPI_Handler(mxc_spi_regs_t * spi)758 void MXC_SPI_Handler(mxc_spi_regs_t *spi)
759 {
760     MXC_SPI_RevA2_Handler((mxc_spi_reva_regs_t *)spi);
761 }
762 
MXC_SPI_DMA_TX_Handler(mxc_spi_regs_t * spi)763 void MXC_SPI_DMA_TX_Handler(mxc_spi_regs_t *spi)
764 {
765     MXC_SPI_RevA2_DMA_TX_Handler((mxc_spi_reva_regs_t *)spi);
766 }
767 
MXC_SPI_DMA_RX_Handler(mxc_spi_regs_t * spi)768 void MXC_SPI_DMA_RX_Handler(mxc_spi_regs_t *spi)
769 {
770     MXC_SPI_RevA2_DMA_RX_Handler((mxc_spi_reva_regs_t *)spi);
771 }
772 
773 /* ** Unsupported-Legacy Functions from Previous Implementation ** */
774 
MXC_SPI_SetDataSize(mxc_spi_regs_t * spi,int dataSize)775 int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize)
776 {
777     return MXC_SPI_RevA2_SetFrameSize((mxc_spi_reva_regs_t *)spi, dataSize);
778 }
779 
MXC_SPI_GetDataSize(mxc_spi_regs_t * spi)780 int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi)
781 {
782     return MXC_SPI_RevA2_GetFrameSize((mxc_spi_reva_regs_t *)spi);
783 }
784 
MXC_SPI_SetWidth(mxc_spi_regs_t * spi,mxc_spi_width_t spiWidth)785 int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth)
786 {
787     switch (spiWidth) {
788     case SPI_WIDTH_3WIRE:
789         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_3WIRE);
790 
791     case SPI_WIDTH_STANDARD:
792         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_STANDARD);
793 
794     case SPI_WIDTH_DUAL:
795         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_DUAL);
796         break;
797 
798     case SPI_WIDTH_QUAD:
799         return MXC_SPI_SetInterface(spi, MXC_SPI_INTERFACE_QUAD);
800 
801     default:
802         return E_BAD_PARAM;
803     }
804 }
805 
MXC_SPI_GetWidth(mxc_spi_regs_t * spi)806 mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi)
807 {
808     mxc_spi_interface_t if_mode;
809 
810     if_mode = MXC_SPI_GetInterface(spi);
811 
812     switch (if_mode) {
813     case MXC_SPI_INTERFACE_STANDARD:
814         return SPI_WIDTH_STANDARD;
815 
816     case MXC_SPI_INTERFACE_QUAD:
817         return SPI_WIDTH_QUAD;
818 
819     case MXC_SPI_INTERFACE_DUAL:
820         return SPI_WIDTH_DUAL;
821 
822     case MXC_SPI_INTERFACE_3WIRE:
823         return SPI_WIDTH_3WIRE;
824 
825     default:
826         return SPI_WIDTH_STANDARD;
827     }
828 }
829 
MXC_SPI_AbortAsync(mxc_spi_regs_t * spi)830 void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi)
831 {
832     MXC_SPI_AbortTransmission(spi);
833 }
834 
MXC_SPI_SetSlave(mxc_spi_regs_t * spi,int ssIdx)835 int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx)
836 {
837     return E_NOT_SUPPORTED;
838 }
839 
MXC_SPI_GetSlave(mxc_spi_regs_t * spi)840 int MXC_SPI_GetSlave(mxc_spi_regs_t *spi)
841 {
842     return E_NOT_SUPPORTED;
843 }
844 
MXC_SPI_SetMode(mxc_spi_regs_t * spi,mxc_spi_mode_t spiMode)845 int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode)
846 {
847     switch (spiMode) {
848     case SPI_MODE_0:
849         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_0);
850 
851     case SPI_MODE_1:
852         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_1);
853 
854     case SPI_MODE_2:
855         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_2);
856 
857     case SPI_MODE_3:
858         return MXC_SPI_SetClkMode(spi, MXC_SPI_CLKMODE_3);
859 
860     default:
861         return E_BAD_PARAM;
862     }
863 }
864 
MXC_SPI_GetMode(mxc_spi_regs_t * spi)865 mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi)
866 {
867     mxc_spi_clkmode_t clk_mode;
868 
869     clk_mode = MXC_SPI_GetClkMode(spi);
870 
871     switch (clk_mode) {
872     case MXC_SPI_CLKMODE_0:
873         return SPI_MODE_0;
874 
875     case MXC_SPI_CLKMODE_1:
876         return SPI_MODE_1;
877 
878     case MXC_SPI_CLKMODE_2:
879         return SPI_MODE_2;
880 
881     case MXC_SPI_CLKMODE_3:
882         return SPI_MODE_3;
883 
884     default:
885         return SPI_MODE_0;
886     }
887 }
888 
MXC_SPI_SetDefaultTXData(mxc_spi_regs_t * spi,unsigned int defaultTXData)889 int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData)
890 {
891     return MXC_SPI_RevA2_SetDummyTX((mxc_spi_reva_regs_t *)spi, defaultTXData);
892 }
893