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 <string.h>
25 #include "mxc_device.h"
26 #include "mxc_errors.h"
27 #include "mxc_assert.h"
28 #include "mxc_lock.h"
29 #include "mxc_sys.h"
30 #include "mxc_delay.h"
31 #include "nvic_table.h"
32 #include "spi.h"
33 #include "spi_reva2.h"
34 #include "dma_reva.h"
35 
36 /* **** Definitions **** */
37 
38 // clang-format off
39 typedef struct {
40     // Info from initialization.
41     bool                dma_initialized;
42     mxc_spi_type_t      controller_target;      // Controller or Target Mode.
43     uint8_t             frame_size;             //
44     mxc_spi_interface_t if_mode;
45 
46 
47     // Transaction Data.
48     uint8_t            *tx_buffer;
49     uint32_t            tx_length_bytes;        // Terms of bytes
50     uint32_t            tx_count_bytes;         // Terms of bytes
51     uint8_t            *rx_buffer;
52     uint32_t            rx_length_bytes;        // Terms of bytes
53     uint32_t            rx_count_bytes;
54     uint16_t            tx_dummy_value;
55 
56     mxc_spi_callback_t  callback;
57     void                *callback_data;
58 
59     // Chip Select Info.
60     bool                deassert;               // Target Select (TS) Deasserted at the end of a transmission.
61     mxc_spi_tscontrol_t ts_control;
62 
63     // DMA Settings.
64     mxc_dma_reva_regs_t *dma;
65     int                 tx_dma_ch;
66     int                 rx_dma_ch;
67 
68     // Status Fields.
69     bool                transaction_done;
70     bool                tx_done;
71     bool                rx_done;
72 } mxc_spi_reva2_handle_data_t;
73 // clang-format on
74 
75 static volatile mxc_spi_reva2_handle_data_t STATES[MXC_SPI_INSTANCES];
76 
77 /* **** Private Functions **** */
78 
79 // The unique title for Private functions will not be capitalized.
80 
81 /** Private Function: writeTXFIFO16
82  * Writes 2 bytes to the TX FIFO for 9-16 bit frame lengths.
83  * This function helps package the frame when the STATES[n] fields
84  * are all in terms of bytes.
85  *
86  * @param   spi             Pointer to SPI instance.
87  * @param   buffer          Pointer to buffer of messages to transmit.
88  * @param   length_bytes    Number of messages (in terms of bytes) in buffer to transmit.
89  *
90  * @return  count           The number of frames written to the TX FIFO.
91  */
MXC_SPI_RevA2_writeTXFIFO16(mxc_spi_reva_regs_t * spi,uint8_t * buffer,uint32_t length_bytes)92 static uint32_t MXC_SPI_RevA2_writeTXFIFO16(mxc_spi_reva_regs_t *spi, uint8_t *buffer,
93                                             uint32_t length_bytes)
94 {
95     uint32_t tx_avail;
96     uint32_t count = 0;
97 
98     if (buffer == NULL || length_bytes == 0) {
99         return 0;
100     }
101 
102     tx_avail = MXC_SPI_FIFO_DEPTH -
103                ((spi->dma & MXC_F_SPI_REVA_DMA_TX_LVL) >> MXC_F_SPI_REVA_DMA_TX_LVL_POS);
104 
105     // Do not write more than the available FIFO size
106     if (length_bytes > tx_avail) {
107         length_bytes = tx_avail;
108     }
109 
110     // Ensure even lengths for halfword frame lengths.
111     // Note: Len is in terms of bytes, so sending 9-16bit transactions means sending
112     //          2 bytes per frame.
113     length_bytes &= ~0x01;
114 
115     while (length_bytes) {
116         if (length_bytes > 3) {
117             memcpy((void *)(&spi->fifo32), (uint8_t *)(&buffer[count]), 4);
118 
119             length_bytes -= 4;
120             count += 4;
121 
122         } else if (length_bytes > 1) {
123             memcpy((void *)(&spi->fifo16[0]), (uint8_t *)(&buffer[count]), 2);
124 
125             length_bytes -= 2;
126             count += 2;
127         }
128     }
129 
130     return count;
131 }
132 
133 /** Private Function: readRXFIFO16
134  * Reads 2 bytes from the RX FIFO for 9-16 bit frame lengths.
135  * This function helps package the frame when the STATES[n] fields
136  * are all in terms of bytes.
137  *
138  * @param   spi             Pointer to SPI instance.
139  * @param   buffer          Pointer to buffer to store read messages.
140  * @param   length_bytes    Number of messages (in terms of bytes) to store in receive buffer.
141  *
142  * @return  count           The number of frames read from the RX FIFO.
143  */
MXC_SPI_RevA2_readRXFIFO16(mxc_spi_reva_regs_t * spi,uint8_t * buffer,uint32_t length_bytes)144 static uint32_t MXC_SPI_RevA2_readRXFIFO16(mxc_spi_reva_regs_t *spi, uint8_t *buffer,
145                                            uint32_t length_bytes)
146 {
147     uint32_t rx_avail;
148     uint32_t count = 0;
149 
150     if (buffer == NULL || length_bytes == 0) {
151         return 0;
152     }
153 
154     rx_avail = (spi->dma & MXC_F_SPI_REVA_DMA_RX_LVL) >> MXC_F_SPI_REVA_DMA_RX_LVL_POS;
155 
156     // Do not read more than available frames in RX FIFO.
157     if (length_bytes > rx_avail) {
158         length_bytes = rx_avail;
159     }
160 
161     // Ensure even lengths for halfword frame lengths.
162     // Note: Len is in terms of bytes, so reading 9-16bit wide messages means reading
163     //          2 bytes per frame.
164     length_bytes &= ~0x01;
165 
166     if (length_bytes >= 2) {
167         // Read from the FIFO
168         while (length_bytes) {
169             if (length_bytes > 3) {
170                 memcpy((uint8_t *)(&buffer[count]), (void *)(&spi->fifo32), 4);
171                 length_bytes -= 4;
172                 count += 4;
173 
174             } else if (length_bytes > 1) {
175                 memcpy((uint8_t *)(&buffer[count]), (void *)(&spi->fifo16[0]), 2);
176                 length_bytes -= 2;
177                 count += 2;
178             }
179 
180             // Ensures read of less than 2 bytes aren't read.
181             // Code should never get to this point.
182             if (length_bytes == 1) {
183                 break;
184             }
185         }
186     }
187 
188     return count;
189 }
190 
191 /** Private Function: process
192  * This function handles the reads and writes to the SPI RX/TX FIFO.
193  *
194  * @param   spi     Pointer to SPI instance.
195  */
MXC_SPI_RevA2_process(mxc_spi_reva_regs_t * spi)196 static void MXC_SPI_RevA2_process(mxc_spi_reva_regs_t *spi)
197 {
198     int8_t spi_num;
199     int remain;
200 
201     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
202 
203     // Write any pending bytes out.
204     //  Dependent on 1) Valid TX Buffer, 2) TX Length not 0, and 3) TX FIFO Not Empty.
205     if (STATES[spi_num].tx_buffer && STATES[spi_num].tx_length_bytes > 0) {
206         // Write to the FIFO for byte size transactions (message sizes for 8 bits or less)
207         if (STATES[spi_num].frame_size <= 8) {
208             while (((spi->dma & MXC_F_SPI_REVA_DMA_TX_LVL) >> MXC_F_SPI_REVA_DMA_TX_LVL_POS) <
209                    (MXC_SPI_FIFO_DEPTH)) {
210                 // Check for overflow.
211                 if (STATES[spi_num].tx_count_bytes == STATES[spi_num].tx_length_bytes) {
212                     break;
213                 }
214 
215                 spi->fifo8[0] = STATES[spi_num].tx_buffer[STATES[spi_num].tx_count_bytes];
216                 STATES[spi_num].tx_count_bytes += 1;
217             }
218 
219             // Write to the FIFO for halfword size transactions (message sizes for 9 bits or greater)
220         } else {
221             STATES[spi_num].tx_count_bytes += MXC_SPI_RevA2_writeTXFIFO16(
222                 spi, &(STATES[spi_num].tx_buffer[STATES[spi_num].tx_count_bytes]),
223                 STATES[spi_num].tx_length_bytes - STATES[spi_num].tx_count_bytes);
224 
225             remain = STATES[spi_num].tx_length_bytes - STATES[spi_num].tx_count_bytes;
226 
227             if (remain) {
228                 if (remain >= MXC_SPI_FIFO_DEPTH) {
229                     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
230                                  ((MXC_SPI_FIFO_DEPTH - 1) << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS));
231                 } else {
232                     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
233                                  (remain << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS));
234                 }
235             }
236         }
237     }
238 
239     if (STATES[spi_num].tx_count_bytes == STATES[spi_num].tx_length_bytes) {
240         STATES[spi_num].tx_done = true;
241     }
242 
243     // Unload any SPI data that has come in
244     //  Dependent on 1) Valid RX Buffer, 2) RX Length not 0, and 3) RX FIFO Not Empty.
245     if (STATES[spi_num].rx_buffer && STATES[spi_num].rx_length_bytes > 0) {
246         // Read the FIFO for byte size transactions (message sizes for 8 bits or less)
247         if (STATES[spi_num].frame_size <= 8) {
248             while ((spi->dma & MXC_F_SPI_REVA_DMA_RX_LVL)) {
249                 // Check for overflow.
250                 if (STATES[spi_num].rx_count_bytes == STATES[spi_num].rx_length_bytes) {
251                     break;
252                 }
253 
254                 STATES[spi_num].rx_buffer[STATES[spi_num].rx_count_bytes] = spi->fifo8[0];
255                 STATES[spi_num].rx_count_bytes += 1;
256             }
257 
258             // Read the FIFO for halfword size transactions (message sizes for 9 bits or greater)
259         } else {
260             STATES[spi_num].rx_count_bytes += MXC_SPI_RevA2_readRXFIFO16(
261                 spi, &(STATES[spi_num].rx_buffer[STATES[spi_num].rx_count_bytes]),
262                 STATES[spi_num].rx_length_bytes - STATES[spi_num].rx_count_bytes);
263 
264             remain = STATES[spi_num].rx_length_bytes - STATES[spi_num].rx_count_bytes;
265 
266             if (remain) {
267                 if (remain >= MXC_SPI_FIFO_DEPTH) {
268                     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_RX_THD_VAL,
269                                  (2 << MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS));
270                 } else {
271                     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_RX_THD_VAL,
272                                  ((remain - 1) << MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS));
273                 }
274             }
275         }
276     }
277 
278     if (STATES[spi_num].rx_count_bytes == STATES[spi_num].rx_length_bytes) {
279         STATES[spi_num].rx_done = true;
280     }
281 
282     // Handle Target Transaction Completion.
283     //  Unlike the Controller, there is no Target Done interrupt to handle the callback and set the
284     //  transaction_done flag.
285     if (STATES[spi_num].controller_target == MXC_SPI_TYPE_TARGET) {
286         // Check if the transaction is complete.
287         if (STATES[spi_num].tx_done == true && STATES[spi_num].rx_done == true) {
288             // Callback if valid.
289             // Note: If Target Select (TS) Control Scheme is set in SW_App mode, then the caller needs to ensure the
290             //   Target Select (TS) pin is asserted or deasserted in their application.
291             if (STATES[spi_num].callback) {
292                 STATES[spi_num].callback(STATES[spi_num].callback_data, E_NO_ERROR);
293             }
294 
295             // Target is done after callback (if valid) is handled.
296             STATES[spi_num].transaction_done = true;
297 
298             // Reset the SPI to complete the on-going transaction.
299             //  SPIn may remain busy (SPI_STAT) even after the target select input
300             //  is deasserted. This ensures the SPI block is not busy after a
301             //  target transaction is completed.
302             spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL0_EN);
303             spi->ctrl0 |= (MXC_F_SPI_REVA_CTRL0_EN);
304         }
305     }
306 }
307 
308 /** Private Function: resetStateStruct
309  * This functions resets the STATE of an SPI instance.
310  *
311  * @param   spi_num     Index number of SPI instance.
312  */
MXC_SPI_RevA2_resetStateStruct(int8_t spi_num)313 static void MXC_SPI_RevA2_resetStateStruct(int8_t spi_num)
314 {
315     // Init Data
316     STATES[spi_num].dma_initialized = false;
317     STATES[spi_num].controller_target = MXC_SPI_TYPE_CONTROLLER;
318     STATES[spi_num].frame_size = 8; // 1 byte frame sizes.
319     STATES[spi_num].if_mode = MXC_SPI_INTERFACE_STANDARD;
320 
321     // Transaction Members
322     STATES[spi_num].tx_buffer = NULL;
323     STATES[spi_num].tx_length_bytes = 0;
324     STATES[spi_num].tx_count_bytes = 0;
325     STATES[spi_num].rx_buffer = NULL;
326     STATES[spi_num].rx_length_bytes = 0;
327     STATES[spi_num].rx_count_bytes = 0;
328     STATES[spi_num].deassert =
329         true; // Default state is TS will be deasserted at the end of a transmission.
330     STATES[spi_num].ts_control = MXC_SPI_TSCONTROL_HW_AUTO; // Default (0) state.
331 
332     // DMA
333     STATES[spi_num].dma = NULL;
334     STATES[spi_num].tx_dma_ch = -1;
335     STATES[spi_num].rx_dma_ch = -1;
336 
337     // Status Members
338     STATES[spi_num].transaction_done = false;
339     STATES[spi_num].tx_done = false;
340     STATES[spi_num].rx_done = false;
341 }
342 
343 /* **** Public Functions **** */
344 
MXC_SPI_RevA2_Init(mxc_spi_reva_regs_t * spi,mxc_spi_type_t controller_target,mxc_spi_interface_t if_mode,uint32_t freq,uint8_t ts_active_pol_mask)345 int MXC_SPI_RevA2_Init(mxc_spi_reva_regs_t *spi, mxc_spi_type_t controller_target,
346                        mxc_spi_interface_t if_mode, uint32_t freq, uint8_t ts_active_pol_mask)
347 {
348     int error;
349     int8_t spi_num;
350 
351     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
352     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
353         return E_BAD_PARAM;
354     }
355 
356     // Reset STATE of current SPI instance.
357     MXC_SPI_RevA2_resetStateStruct(spi_num);
358 
359     // Save init data states.
360     STATES[spi_num].controller_target = controller_target;
361     STATES[spi_num].frame_size = 8;
362     STATES[spi_num].if_mode = if_mode;
363 
364     // Enable SPI port.
365     spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL0_EN);
366     spi->ctrl0 |= (MXC_F_SPI_REVA_CTRL0_EN);
367 
368     // Set Controller (L. Master) or Target (L. Slave) mode.
369     switch (controller_target) {
370     case MXC_SPI_TYPE_CONTROLLER:
371         spi->ctrl0 |= MXC_F_SPI_REVA_CTRL0_MST_MODE;
372         break;
373 
374     case MXC_SPI_TYPE_TARGET:
375         spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL0_MST_MODE);
376         break;
377 
378     default:
379         return E_BAD_PARAM;
380     }
381 
382     // Set default frame size to 8 bits wide.
383     MXC_SETFIELD(spi->ctrl2, MXC_F_SPI_REVA_CTRL2_NUMBITS, 8 << MXC_F_SPI_REVA_CTRL2_NUMBITS_POS);
384 
385     // Remove any delay between TS (L. SS) and SCLK edges.
386     spi->sstime = (1 << MXC_F_SPI_REVA_SSTIME_PRE_POS) | (1 << MXC_F_SPI_REVA_SSTIME_POST_POS) |
387                   (1 << MXC_F_SPI_REVA_SSTIME_INACT_POS);
388 
389     // Enable TX/RX FIFOs
390     spi->dma |= MXC_F_SPI_REVA_DMA_TX_FIFO_EN | MXC_F_SPI_REVA_DMA_RX_FIFO_EN;
391 
392     // Set TX and RX Threshold to (FIFO_DEPTH - 1) and (0), respectively.
393     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
394                  ((MXC_SPI_FIFO_DEPTH - 1) << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS));
395     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_RX_THD_VAL, (0 << MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS));
396 
397     // Set Default Clock Mode (CPOL: 0, and CPHA: 0).
398     error = MXC_SPI_SetClkMode((mxc_spi_regs_t *)spi, MXC_SPI_CLKMODE_0);
399     if (error != E_NO_ERROR) {
400         return error;
401     }
402 
403     // Interface mode: 3-wire, standard (4-wire), dual, quad.
404     error = MXC_SPI_SetInterface((mxc_spi_regs_t *)spi, if_mode);
405     if (error != E_NO_ERROR) {
406         return error;
407     }
408 
409     error = MXC_SPI_SetFrequency((mxc_spi_regs_t *)spi, freq);
410     if (error != E_NO_ERROR) {
411         return error;
412     }
413 
414     // Clear any interrupt flags that may already be set.
415     spi->intfl = spi->intfl;
416     spi->inten = 0;
417 
418     // Clear the HW TS settings (These are set in the transaction functions).
419     MXC_SETFIELD(spi->ctrl0, MXC_F_SPI_REVA_CTRL0_SS_ACTIVE, 0);
420 
421     // Set the TS Active Polarity settings.
422     MXC_SETFIELD(spi->ctrl2, MXC_F_SPI_REVA_CTRL2_SS_POL,
423                  ts_active_pol_mask << MXC_F_SPI_REVA_CTRL2_SS_POL_POS);
424 
425     return E_NO_ERROR;
426 }
427 
MXC_SPI_RevA2_Config(mxc_spi_cfg_t * cfg)428 int MXC_SPI_RevA2_Config(mxc_spi_cfg_t *cfg)
429 {
430     int error;
431     int8_t spi_num;
432 
433     if (cfg == NULL) {
434         return E_NULL_PTR;
435     }
436 
437     // Ensure valid SPI instance.
438     spi_num = MXC_SPI_GET_IDX(cfg->spi);
439     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
440         return E_BAD_PARAM;
441     }
442 
443     // Set Single Frame Size.
444     error = MXC_SPI_SetFrameSize((cfg->spi), (cfg->frame_size));
445     if (error != E_NO_ERROR) {
446         return error;
447     }
448 
449     // Set Clock Mode (CPOL and CPHA).
450     error = MXC_SPI_SetClkMode((cfg->spi), (cfg->clk_mode));
451     if (error != E_NO_ERROR) {
452         return error;
453     }
454 
455     // Setup DMA features if used.
456     if (cfg->use_dma_tx || cfg->use_dma_rx) {
457         error = MXC_SPI_RevA2_DMA_Init((mxc_spi_reva_regs_t *)(cfg->spi),
458                                        (mxc_dma_reva_regs_t *)(cfg->dma), (cfg->use_dma_tx),
459                                        (cfg->use_dma_rx));
460         if (error != E_NO_ERROR) {
461             return error;
462         }
463     }
464 
465     return E_NO_ERROR;
466 }
467 
MXC_SPI_RevA2_Shutdown(mxc_spi_reva_regs_t * spi)468 int MXC_SPI_RevA2_Shutdown(mxc_spi_reva_regs_t *spi)
469 {
470     int8_t spi_num;
471 
472     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
473     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
474         return E_BAD_PARAM;
475     }
476 
477     // Disable and clear interrupts.
478     spi->inten = 0;
479     spi->intfl = spi->intfl;
480 
481     // Disable SPI and FIFOS
482     spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL0_EN);
483     spi->dma &= ~(MXC_F_SPI_REVA_DMA_TX_FIFO_EN | MXC_F_SPI_REVA_DMA_RX_FIFO_EN);
484 
485     // Clear registers.
486     spi->ctrl0 = 0;
487     spi->ctrl1 = 0;
488     spi->ctrl2 = 0;
489     spi->sstime = 0;
490 
491     // Release any acquired DMA channels.
492     if (STATES[spi_num].tx_dma_ch >= 0) {
493         MXC_DMA_ReleaseChannel(STATES[spi_num].tx_dma_ch);
494         STATES[spi_num].tx_dma_ch = E_NO_DEVICE;
495     }
496     if (STATES[spi_num].rx_dma_ch >= 0) {
497         MXC_DMA_ReleaseChannel(STATES[spi_num].rx_dma_ch);
498         STATES[spi_num].rx_dma_ch = E_NO_DEVICE;
499     }
500 
501     if (STATES[spi_num].dma_initialized) {
502         MXC_DMA_DeInit();
503     }
504 
505     // Reset the SPI instance's STATE when shutting down.
506     MXC_SPI_RevA2_resetStateStruct(spi_num);
507 
508     return E_NO_ERROR;
509 }
510 
MXC_SPI_RevA2_GetFlags(mxc_spi_reva_regs_t * spi)511 uint32_t MXC_SPI_RevA2_GetFlags(mxc_spi_reva_regs_t *spi)
512 {
513     return spi->intfl;
514 }
515 
MXC_SPI_RevA2_ClearFlags(mxc_spi_reva_regs_t * spi)516 void MXC_SPI_RevA2_ClearFlags(mxc_spi_reva_regs_t *spi)
517 {
518     spi->intfl = spi->intfl;
519 }
520 
MXC_SPI_RevA2_EnableInt(mxc_spi_reva_regs_t * spi,uint32_t en)521 void MXC_SPI_RevA2_EnableInt(mxc_spi_reva_regs_t *spi, uint32_t en)
522 {
523     spi->inten |= en;
524 }
525 
MXC_SPI_RevA2_DisableInt(mxc_spi_reva_regs_t * spi,uint32_t dis)526 void MXC_SPI_RevA2_DisableInt(mxc_spi_reva_regs_t *spi, uint32_t dis)
527 {
528     spi->inten &= ~(dis);
529 }
530 
MXC_SPI_RevA2_SetTSControl(mxc_spi_reva_regs_t * spi,mxc_spi_tscontrol_t ts_control)531 int MXC_SPI_RevA2_SetTSControl(mxc_spi_reva_regs_t *spi, mxc_spi_tscontrol_t ts_control)
532 {
533     int8_t spi_num;
534 
535     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
536     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
537         return E_BAD_PARAM;
538     }
539 
540     switch (ts_control) {
541     case MXC_SPI_TSCONTROL_HW_AUTO:
542         break;
543 
544     case MXC_SPI_TSCONTROL_SW_APP:
545         spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL0_SS_ACTIVE);
546         spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL2_SS_POL);
547         break;
548 
549     default:
550         return E_BAD_PARAM;
551     }
552 
553     STATES[spi_num].ts_control = ts_control;
554 
555     return E_NO_ERROR;
556 }
557 
MXC_SPI_RevA2_GetTSControl(mxc_spi_reva_regs_t * spi)558 mxc_spi_tscontrol_t MXC_SPI_RevA2_GetTSControl(mxc_spi_reva_regs_t *spi)
559 {
560     int8_t spi_num;
561 
562     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
563     if (spi_num < 0 || spi_num >= MXC_SPI_INSTANCES) {
564         return E_BAD_PARAM;
565     }
566 
567     return (STATES[spi_num].ts_control);
568 }
569 
MXC_SPI_RevA2_SetFrequency(mxc_spi_reva_regs_t * spi,uint32_t freq)570 int MXC_SPI_RevA2_SetFrequency(mxc_spi_reva_regs_t *spi, uint32_t freq)
571 {
572     int hi_clk, lo_clk, scale;
573     uint32_t freq_div;
574 
575     // Check if frequency is too high
576     if (freq > PeripheralClock) {
577         return E_BAD_PARAM;
578     }
579 
580     // Set the clock high and low
581     freq_div = MXC_SPI_GetPeripheralClock((mxc_spi_regs_t *)spi);
582     freq_div = (freq_div / freq);
583 
584     hi_clk = freq_div / 2;
585     lo_clk = freq_div / 2;
586     scale = 0;
587 
588     if (freq_div % 2) {
589         hi_clk += 1;
590     }
591 
592     while (hi_clk >= 16 && scale < 8) {
593         hi_clk /= 2;
594         lo_clk /= 2;
595         scale++;
596     }
597 
598     if (scale == 8) {
599         lo_clk = 15;
600         hi_clk = 15;
601     }
602 
603     MXC_SETFIELD(spi->clkctrl, MXC_F_SPI_REVA_CLKCTRL_LO,
604                  (lo_clk << MXC_F_SPI_REVA_CLKCTRL_LO_POS));
605     MXC_SETFIELD(spi->clkctrl, MXC_F_SPI_REVA_CLKCTRL_HI,
606                  (hi_clk << MXC_F_SPI_REVA_CLKCTRL_HI_POS));
607     MXC_SETFIELD(spi->clkctrl, MXC_F_SPI_REVA_CLKCTRL_CLKDIV,
608                  (scale << MXC_F_SPI_REVA_CLKCTRL_CLKDIV_POS));
609 
610     return E_NO_ERROR;
611 }
612 
MXC_SPI_RevA2_GetFrequency(mxc_spi_reva_regs_t * spi)613 int MXC_SPI_RevA2_GetFrequency(mxc_spi_reva_regs_t *spi)
614 {
615     unsigned scale, lo_clk, hi_clk;
616 
617     scale = (spi->clkctrl & MXC_F_SPI_REVA_CLKCTRL_CLKDIV) >> MXC_F_SPI_REVA_CLKCTRL_CLKDIV_POS;
618     hi_clk = (spi->clkctrl & MXC_F_SPI_REVA_CLKCTRL_HI) >> MXC_F_SPI_REVA_CLKCTRL_HI_POS;
619     lo_clk = (spi->clkctrl & MXC_F_SPI_REVA_CLKCTRL_LO) >> MXC_F_SPI_REVA_CLKCTRL_LO_POS;
620 
621     return (PeripheralClock / (1 << scale)) / (lo_clk + hi_clk);
622 }
623 
MXC_SPI_RevA2_SetFrameSize(mxc_spi_reva_regs_t * spi,int frame_size)624 int MXC_SPI_RevA2_SetFrameSize(mxc_spi_reva_regs_t *spi, int frame_size)
625 {
626     int8_t spi_num;
627     int saved_enable_state;
628 
629     // HW has problem with these two character sizes
630     if (frame_size <= 1 || frame_size > 16) {
631         return E_BAD_PARAM;
632     }
633 
634     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
635 
636     if ((spi->stat & MXC_F_SPI_REVA_STAT_BUSY) &&
637         (STATES[spi_num].controller_target == MXC_SPI_TYPE_CONTROLLER)) {
638         return E_BAD_STATE;
639     }
640 
641     // Set up the character size.
642     saved_enable_state = spi->ctrl0 | MXC_F_SPI_REVA_CTRL0_EN;
643 
644     // If enabled, disable SPI before changing character size.
645     if (saved_enable_state) {
646         spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL0_EN);
647     }
648 
649     // Update data size from save Init function.
650     STATES[spi_num].frame_size = frame_size;
651 
652     if (frame_size < 16) {
653         MXC_SETFIELD(spi->ctrl2, MXC_F_SPI_REVA_CTRL2_NUMBITS,
654                      frame_size << MXC_F_SPI_REVA_CTRL2_NUMBITS_POS);
655     } else {
656         // Set to 16 bits per character as default.
657         MXC_SETFIELD(spi->ctrl2, MXC_F_SPI_REVA_CTRL2_NUMBITS,
658                      0 << MXC_F_SPI_REVA_CTRL2_NUMBITS_POS);
659     }
660 
661     // Return back to original SPI enable state.
662     MXC_SETFIELD(spi->ctrl0, MXC_F_SPI_REVA_CTRL0_EN, saved_enable_state);
663 
664     return E_NO_ERROR;
665 }
666 
MXC_SPI_RevA2_GetFrameSize(mxc_spi_reva_regs_t * spi)667 int MXC_SPI_RevA2_GetFrameSize(mxc_spi_reva_regs_t *spi)
668 {
669     // NUMBITS = 0 means 16-bits per character
670     if (!(spi->ctrl2 & MXC_F_SPI_REVA_CTRL2_NUMBITS)) {
671         return 16;
672     } else {
673         return ((spi->ctrl2 & MXC_F_SPI_REVA_CTRL2_NUMBITS) >> MXC_F_SPI_REVA_CTRL2_NUMBITS_POS);
674     }
675 }
676 
MXC_SPI_RevA2_SetInterface(mxc_spi_reva_regs_t * spi,mxc_spi_interface_t if_mode)677 int MXC_SPI_RevA2_SetInterface(mxc_spi_reva_regs_t *spi, mxc_spi_interface_t if_mode)
678 {
679     // Clear before setting
680     spi->ctrl2 &= ~(MXC_F_SPI_REVA_CTRL2_THREE_WIRE | MXC_F_SPI_REVA_CTRL2_DATA_WIDTH);
681 
682     switch (if_mode) {
683     case MXC_SPI_INTERFACE_3WIRE:
684         spi->ctrl2 |= MXC_F_SPI_REVA_CTRL2_THREE_WIRE;
685         break;
686 
687     case MXC_SPI_INTERFACE_STANDARD:
688         spi->ctrl2 |= MXC_S_SPI_REVA_CTRL2_DATA_WIDTH_MONO;
689         break;
690 
691     case MXC_SPI_INTERFACE_DUAL:
692         spi->ctrl2 |= MXC_S_SPI_REVA_CTRL2_DATA_WIDTH_DUAL;
693         break;
694 
695     case MXC_SPI_INTERFACE_QUAD:
696         spi->ctrl2 |= MXC_S_SPI_REVA_CTRL2_DATA_WIDTH_QUAD;
697         break;
698 
699     // Default set to to 3-Wire
700     default:
701         spi->ctrl2 |= MXC_F_SPI_REVA_CTRL2_THREE_WIRE;
702         break;
703     }
704 
705     // Save state of new mode
706     STATES[MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi)].if_mode = if_mode;
707 
708     return E_NO_ERROR;
709 }
710 
MXC_SPI_RevA2_GetInterface(mxc_spi_reva_regs_t * spi)711 mxc_spi_interface_t MXC_SPI_RevA2_GetInterface(mxc_spi_reva_regs_t *spi)
712 {
713     if (spi->ctrl2 & MXC_F_SPI_REVA_CTRL2_THREE_WIRE) {
714         return MXC_SPI_INTERFACE_3WIRE;
715     }
716 
717     if (spi->ctrl2 & MXC_S_SPI_REVA_CTRL2_DATA_WIDTH_DUAL) {
718         return MXC_SPI_INTERFACE_DUAL;
719     }
720 
721     if (spi->ctrl2 & MXC_S_SPI_REVA_CTRL2_DATA_WIDTH_QUAD) {
722         return MXC_SPI_INTERFACE_QUAD;
723     }
724 
725     return MXC_SPI_INTERFACE_STANDARD;
726 }
727 
MXC_SPI_RevA2_SetClkMode(mxc_spi_reva_regs_t * spi,mxc_spi_clkmode_t clk_mode)728 int MXC_SPI_RevA2_SetClkMode(mxc_spi_reva_regs_t *spi, mxc_spi_clkmode_t clk_mode)
729 {
730     switch (clk_mode) {
731     // CPOL: 0    CPHA: 0
732     case MXC_SPI_CLKMODE_0:
733         spi->ctrl2 &= ~MXC_F_SPI_REVA_CTRL2_CLKPHA;
734         spi->ctrl2 &= ~MXC_F_SPI_REVA_CTRL2_CLKPOL;
735         break;
736 
737     // CPOL: 0    CPHA: 1
738     case MXC_SPI_CLKMODE_1:
739         spi->ctrl2 &= ~MXC_F_SPI_REVA_CTRL2_CLKPHA;
740         spi->ctrl2 |= MXC_F_SPI_REVA_CTRL2_CLKPOL;
741         break;
742 
743     // CPOL: 1    CPHA: 0
744     case MXC_SPI_CLKMODE_2:
745         spi->ctrl2 |= MXC_F_SPI_REVA_CTRL2_CLKPHA;
746         spi->ctrl2 &= ~MXC_F_SPI_REVA_CTRL2_CLKPOL;
747         break;
748 
749     // CPOL: 1    CPHA: 1
750     case MXC_SPI_CLKMODE_3:
751         spi->ctrl2 |= MXC_F_SPI_REVA_CTRL2_CLKPHA;
752         spi->ctrl2 |= MXC_F_SPI_REVA_CTRL2_CLKPOL;
753         break;
754 
755     // Mode 0 by default.
756     default:
757         spi->ctrl2 &= ~MXC_F_SPI_REVA_CTRL2_CLKPHA;
758         spi->ctrl2 &= ~MXC_F_SPI_REVA_CTRL2_CLKPOL;
759         break;
760     }
761 
762     return E_NO_ERROR;
763 }
764 
MXC_SPI_RevA2_GetClkMode(mxc_spi_reva_regs_t * spi)765 mxc_spi_clkmode_t MXC_SPI_RevA2_GetClkMode(mxc_spi_reva_regs_t *spi)
766 {
767     if (spi->ctrl2 & MXC_F_SPI_REVA_CTRL2_CLKPHA) {
768         if (spi->ctrl2 & MXC_F_SPI_REVA_CTRL2_CLKPOL) {
769             return MXC_SPI_CLKMODE_3;
770         } else {
771             return MXC_SPI_CLKMODE_2;
772         }
773     } else {
774         if (spi->ctrl2 & MXC_F_SPI_REVA_CTRL2_CLKPOL) {
775             return MXC_SPI_CLKMODE_1;
776         }
777     }
778 
779     return MXC_SPI_CLKMODE_0;
780 }
781 
MXC_SPI_RevA2_SetCallback(mxc_spi_reva_regs_t * spi,mxc_spi_callback_t callback,void * data)782 int MXC_SPI_RevA2_SetCallback(mxc_spi_reva_regs_t *spi, mxc_spi_callback_t callback, void *data)
783 {
784     int8_t spi_num;
785 
786     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
787 
788     STATES[spi_num].callback = callback;
789     STATES[spi_num].callback_data = data;
790 
791     return E_NO_ERROR;
792 }
793 
MXC_SPI_RevA2_GetActive(mxc_spi_reva_regs_t * spi)794 int MXC_SPI_RevA2_GetActive(mxc_spi_reva_regs_t *spi)
795 {
796     if (spi->stat & MXC_F_SPI_REVA_STAT_BUSY) {
797         return E_BUSY;
798     }
799 
800     return E_NO_ERROR;
801 }
802 
MXC_SPI_RevA2_ReadyForSleep(mxc_spi_reva_regs_t * spi)803 int MXC_SPI_RevA2_ReadyForSleep(mxc_spi_reva_regs_t *spi)
804 {
805     if (spi->stat & MXC_F_SPI_REVA_STAT_BUSY || (spi->dma & MXC_F_SPI_REVA_DMA_TX_LVL) ||
806         (spi->dma & MXC_F_SPI_REVA_DMA_RX_LVL)) {
807         return E_BUSY;
808     } else {
809         return E_NO_ERROR;
810     }
811 }
812 
MXC_SPI_RevA2_SetDummyTX(mxc_spi_reva_regs_t * spi,uint16_t tx_value)813 int MXC_SPI_RevA2_SetDummyTX(mxc_spi_reva_regs_t *spi, uint16_t tx_value)
814 {
815     STATES[MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi)].tx_dummy_value = tx_value;
816 
817     return E_NO_ERROR;
818 }
819 
MXC_SPI_RevA2_StartTransmission(mxc_spi_reva_regs_t * spi)820 int MXC_SPI_RevA2_StartTransmission(mxc_spi_reva_regs_t *spi)
821 {
822     if (MXC_SPI_GetActive((mxc_spi_regs_t *)spi) == E_BUSY) {
823         return E_BUSY;
824     }
825 
826     spi->ctrl0 |= MXC_F_SPI_REVA_CTRL0_START;
827 
828     return E_NO_ERROR;
829 }
830 
MXC_SPI_RevA2_AbortTransmission(mxc_spi_reva_regs_t * spi)831 int MXC_SPI_RevA2_AbortTransmission(mxc_spi_reva_regs_t *spi)
832 {
833     int8_t spi_num;
834 
835     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
836 
837     // Disable interrupts, clear the flags.
838     spi->inten = 0;
839     spi->intfl = spi->intfl;
840 
841     // Cancel on-going transaction before enabling.
842     spi->ctrl0 &= ~(MXC_F_SPI_REVA_CTRL0_EN);
843     spi->ctrl0 |= (MXC_F_SPI_REVA_CTRL0_EN);
844 
845     // Callback if not NULL
846     if (STATES[spi_num].callback != NULL) {
847         STATES[spi_num].callback(STATES[spi_num].callback_data, E_ABORT);
848     }
849 
850     return E_NO_ERROR;
851 }
852 
MXC_SPI_RevA2_GetTXFIFOAvailable(mxc_spi_reva_regs_t * spi)853 uint8_t MXC_SPI_RevA2_GetTXFIFOAvailable(mxc_spi_reva_regs_t *spi)
854 {
855     return MXC_SPI_FIFO_DEPTH -
856            ((spi->dma & MXC_F_SPI_REVA_DMA_TX_LVL) >> MXC_F_SPI_REVA_DMA_TX_LVL_POS);
857 }
858 
MXC_SPI_RevA2_GetRXFIFOAvailable(mxc_spi_reva_regs_t * spi)859 uint8_t MXC_SPI_RevA2_GetRXFIFOAvailable(mxc_spi_reva_regs_t *spi)
860 {
861     return (spi->dma & MXC_F_SPI_REVA_DMA_RX_LVL) >> MXC_F_SPI_REVA_DMA_RX_LVL_POS;
862 }
863 
MXC_SPI_RevA2_ClearTXFIFO(mxc_spi_reva_regs_t * spi)864 int MXC_SPI_RevA2_ClearTXFIFO(mxc_spi_reva_regs_t *spi)
865 {
866     uint32_t save_state;
867 
868     save_state = (spi->dma & (MXC_F_SPI_REVA_DMA_TX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_TX_EN));
869 
870     // Disable FIFOs before clearing as recommended by UG.
871     spi->dma &= ~(MXC_F_SPI_REVA_DMA_TX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_TX_EN);
872     spi->dma |= (MXC_F_SPI_REVA_DMA_TX_FLUSH);
873 
874     // Revert to previous state.
875     MXC_SETFIELD(spi->dma, (MXC_F_SPI_REVA_DMA_TX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_TX_EN),
876                  save_state);
877 
878     return E_NO_ERROR;
879 }
880 
MXC_SPI_RevA2_ClearRXFIFO(mxc_spi_reva_regs_t * spi)881 int MXC_SPI_RevA2_ClearRXFIFO(mxc_spi_reva_regs_t *spi)
882 {
883     uint32_t save_state;
884 
885     save_state = (spi->dma & (MXC_F_SPI_REVA_DMA_RX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_RX_EN));
886 
887     // Disable FIFOs before clearing as recommended by UG.
888     spi->dma &= ~(MXC_F_SPI_REVA_DMA_RX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_RX_EN);
889     spi->dma |= (MXC_F_SPI_REVA_DMA_RX_FLUSH);
890 
891     // Revert to previous state.
892     MXC_SETFIELD(spi->dma, (MXC_F_SPI_REVA_DMA_RX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_RX_EN),
893                  save_state);
894 
895     return E_NO_ERROR;
896 }
897 
MXC_SPI_RevA2_SetTXThreshold(mxc_spi_reva_regs_t * spi,uint8_t thd_val)898 int MXC_SPI_RevA2_SetTXThreshold(mxc_spi_reva_regs_t *spi, uint8_t thd_val)
899 {
900     // Valid values for the threshold are 0x1 to 0x1F
901     if (thd_val > (MXC_SPI_FIFO_DEPTH - 1) || thd_val == 0) {
902         return E_BAD_PARAM;
903     }
904 
905     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
906                  thd_val << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS);
907 
908     return E_NO_ERROR;
909 }
910 
MXC_SPI_RevA2_SetRXThreshold(mxc_spi_reva_regs_t * spi,uint8_t thd_val)911 int MXC_SPI_RevA2_SetRXThreshold(mxc_spi_reva_regs_t *spi, uint8_t thd_val)
912 {
913     if (thd_val >= (MXC_SPI_FIFO_DEPTH - 1)) {
914         return E_BAD_PARAM;
915     }
916 
917     MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_RX_THD_VAL,
918                  thd_val << MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS);
919 
920     return E_NO_ERROR;
921 }
922 
MXC_SPI_RevA2_GetTXThreshold(mxc_spi_reva_regs_t * spi)923 uint8_t MXC_SPI_RevA2_GetTXThreshold(mxc_spi_reva_regs_t *spi)
924 {
925     return (spi->dma & MXC_F_SPI_REVA_DMA_TX_THD_VAL) >> MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS;
926 }
927 
MXC_SPI_RevA2_GetRXThreshold(mxc_spi_reva_regs_t * spi)928 uint8_t MXC_SPI_RevA2_GetRXThreshold(mxc_spi_reva_regs_t *spi)
929 {
930     return (spi->dma & MXC_F_SPI_REVA_DMA_RX_THD_VAL) >> MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS;
931 }
932 
933 /* ** DMA-Specific Functions ** */
934 
935 // Available for switching between DMA and non-DMA transactions
MXC_SPI_RevA2_DMA_Init(mxc_spi_reva_regs_t * spi,mxc_dma_reva_regs_t * dma,bool use_dma_tx,bool use_dma_rx)936 int MXC_SPI_RevA2_DMA_Init(mxc_spi_reva_regs_t *spi, mxc_dma_reva_regs_t *dma, bool use_dma_tx,
937                            bool use_dma_rx)
938 {
939     int error;
940     int tx_ch, rx_ch; // For readability.
941     int8_t spi_num;
942 
943     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
944 
945     if (dma == NULL) {
946         return E_NULL_PTR;
947     }
948 
949     if (STATES[spi_num].dma_initialized) {
950         // Exit function if DMA is already initialized.
951         return E_NO_ERROR;
952     }
953 
954     STATES[spi_num].dma = dma;
955 
956 #if (MXC_DMA_INSTANCES == 1)
957     error = MXC_DMA_Init();
958 #else
959     error = MXC_DMA_Init(dma);
960 #endif
961     if (error != E_NO_ERROR) {
962         return error;
963     }
964 
965     // Set up SPI DMA TX.
966     if (use_dma_tx) {
967         STATES[spi_num].tx_dma_ch = MXC_DMA_AcquireChannel();
968         tx_ch = STATES[spi_num].tx_dma_ch;
969 
970         if (STATES[spi_num].tx_dma_ch < 0) {
971             return E_NONE_AVAIL;
972         }
973 
974         // TX Channel
975         STATES[spi_num].dma->ch[tx_ch].ctrl |= (MXC_F_DMA_REVA_CTRL_CTZ_IE);
976         STATES[spi_num].dma->inten |= (1 << tx_ch);
977     }
978 
979     // Set up SPI DMA RX.
980     if (use_dma_rx) {
981         STATES[spi_num].rx_dma_ch = MXC_DMA_AcquireChannel();
982         rx_ch = STATES[spi_num].rx_dma_ch;
983 
984         if (STATES[spi_num].rx_dma_ch < 0) {
985             return E_NONE_AVAIL;
986         }
987 
988         // RX Channel
989         STATES[spi_num].dma->ch[rx_ch].ctrl |= (MXC_F_DMA_REVA_CTRL_CTZ_IE);
990         STATES[spi_num].dma->inten |= (1 << rx_ch);
991     }
992 
993     error = MXC_SPI_DMA_SetRequestSelect((mxc_spi_regs_t *)spi, use_dma_tx, use_dma_rx);
994     if (error != E_NO_ERROR) {
995         return error;
996     }
997 
998     STATES[spi_num].dma_initialized = true;
999 
1000     return E_NO_ERROR;
1001 }
1002 
1003 // Available to chech whether DMA is already initialized for SPI instance.
1004 //      Useful for switching from non-DMA to DMA transactions.
MXC_SPI_RevA2_DMA_GetInitialized(mxc_spi_reva_regs_t * spi)1005 bool MXC_SPI_RevA2_DMA_GetInitialized(mxc_spi_reva_regs_t *spi)
1006 {
1007     return (STATES[MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi)].dma_initialized);
1008 }
1009 
MXC_SPI_RevA2_DMA_GetTXChannel(mxc_spi_reva_regs_t * spi)1010 int MXC_SPI_RevA2_DMA_GetTXChannel(mxc_spi_reva_regs_t *spi)
1011 {
1012     return (STATES[MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi)].tx_dma_ch);
1013 }
1014 
MXC_SPI_RevA2_DMA_GetRXChannel(mxc_spi_reva_regs_t * spi)1015 int MXC_SPI_RevA2_DMA_GetRXChannel(mxc_spi_reva_regs_t *spi)
1016 {
1017     return (STATES[MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi)].rx_dma_ch);
1018 }
1019 
MXC_SPI_RevA2_DMA_SetRequestSelect(mxc_spi_reva_regs_t * spi,uint32_t tx_reqsel,uint32_t rx_reqsel)1020 int MXC_SPI_RevA2_DMA_SetRequestSelect(mxc_spi_reva_regs_t *spi, uint32_t tx_reqsel,
1021                                        uint32_t rx_reqsel)
1022 {
1023     int8_t spi_num;
1024     uint32_t tx_ch;
1025     uint32_t rx_ch;
1026 
1027     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1028 
1029     // Ensure DMA was configured before setting DMA Request Selects.
1030     if (STATES[spi_num].dma == NULL) {
1031         return E_BAD_STATE;
1032     }
1033 
1034     tx_ch = STATES[spi_num].tx_dma_ch;
1035     rx_ch = STATES[spi_num].rx_dma_ch;
1036 
1037     // This function will overwrite the current DMA TX/RX Request Selects.
1038     if (tx_reqsel != -1) {
1039         STATES[spi_num].dma->ch[tx_ch].ctrl |= tx_reqsel;
1040     }
1041 
1042     if (rx_reqsel != -1) {
1043         STATES[spi_num].dma->ch[rx_ch].ctrl |= rx_reqsel;
1044     }
1045 
1046     return E_NO_ERROR;
1047 }
1048 
1049 // Swaps the upper and lower byte of 2-byte wide frame transactions.
1050 // HW Bug: For 2-byte wide frame transactions, RX DMA swaps the
1051 //      LSB and MSB.
1052 // Example: TX: 0x1234 => RX: 0x3412
1053 // Note: Use __REV assembly instruction for quicker Swap implementation.
MXC_SPI_RevA2_DMA_SwapByte(uint8_t * buffer,uint32_t length_bytes)1054 void MXC_SPI_RevA2_DMA_SwapByte(uint8_t *buffer, uint32_t length_bytes)
1055 {
1056     int i;
1057 
1058     MXC_ASSERT(buffer != NULL);
1059 
1060     for (i = 0; i < length_bytes; i += 2) {
1061         uint8_t temp = buffer[i];
1062         buffer[i] = buffer[i + 1];
1063         buffer[i + 1] = temp;
1064     }
1065 }
1066 
1067 /* ** Transaction Helper Functions ** */
1068 
1069 // SPI DMA/non-DMA Transaction Setup Helper Function.
MXC_SPI_RevA2_transactionSetup(mxc_spi_reva_regs_t * spi,uint8_t * tx_buffer,uint32_t tx_length_frames,uint8_t * rx_buffer,uint32_t rx_length_frames,bool use_dma)1070 static void MXC_SPI_RevA2_transactionSetup(mxc_spi_reva_regs_t *spi, uint8_t *tx_buffer,
1071                                            uint32_t tx_length_frames, uint8_t *rx_buffer,
1072                                            uint32_t rx_length_frames, bool use_dma)
1073 {
1074     int tx_dummy_length_frames;
1075     int8_t spi_num;
1076     // For readability purposes.
1077     int rx_ch, tx_ch;
1078 
1079     // Ensure valid SPI Instance.
1080     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1081 
1082     // Initialize SPIn state to handle data.
1083     STATES[spi_num].transaction_done = false;
1084 
1085     STATES[spi_num].tx_buffer = tx_buffer;
1086     STATES[spi_num].tx_count_bytes = 0;
1087     STATES[spi_num].tx_done = false;
1088 
1089     STATES[spi_num].rx_buffer = rx_buffer;
1090     STATES[spi_num].rx_count_bytes = 0;
1091     STATES[spi_num].rx_done = false;
1092 
1093     // Max number of frames to transmit/receive.
1094     MXC_ASSERT(tx_length_frames <
1095                (MXC_F_SPI_REVA_CTRL1_TX_NUM_CHAR >> MXC_F_SPI_REVA_CTRL1_TX_NUM_CHAR_POS));
1096     MXC_ASSERT(rx_length_frames <
1097                (MXC_F_SPI_REVA_CTRL1_RX_NUM_CHAR >> MXC_F_SPI_REVA_CTRL1_RX_NUM_CHAR_POS));
1098 
1099     // STATES[n] TX/RX Length Fields are in terms of number of bytes to send/receive.
1100     if (STATES[spi_num].frame_size <= 8) {
1101         STATES[spi_num].tx_length_bytes = tx_length_frames;
1102         STATES[spi_num].rx_length_bytes = rx_length_frames;
1103     } else {
1104         STATES[spi_num].tx_length_bytes = tx_length_frames * 2;
1105         STATES[spi_num].rx_length_bytes = rx_length_frames * 2;
1106     }
1107 
1108     // Set the number of messages to transmit/receive for the SPI transaction.
1109     if (STATES[spi_num].if_mode == MXC_SPI_INTERFACE_STANDARD) {
1110         if (rx_length_frames > tx_length_frames) {
1111             // In standard 4-wire mode, the RX_NUM_CHAR field of ctrl1 is ignored.
1112             // The number of bytes to transmit AND receive is set by TX_NUM_CHAR,
1113             // because the hardware always assume full duplex. Therefore extra
1114             // dummy bytes must be transmitted to support half duplex.
1115             tx_dummy_length_frames = rx_length_frames - tx_length_frames;
1116 
1117             // Check whether new frame length exceeds the possible number of frames to transmit.
1118             MXC_ASSERT((tx_length_frames + tx_dummy_length_frames) <
1119                        (MXC_F_SPI_REVA_CTRL1_TX_NUM_CHAR >> MXC_F_SPI_REVA_CTRL1_TX_NUM_CHAR_POS));
1120 
1121             spi->ctrl1 = ((tx_length_frames + tx_dummy_length_frames)
1122                           << MXC_F_SPI_REVA_CTRL1_TX_NUM_CHAR_POS);
1123         } else {
1124             spi->ctrl1 = (tx_length_frames << MXC_F_SPI_REVA_CTRL1_TX_NUM_CHAR_POS);
1125         }
1126     } else { // mode != MXC_SPI_INTERFACE_STANDARD
1127         spi->ctrl1 = (tx_length_frames << MXC_F_SPI_REVA_CTRL1_TX_NUM_CHAR_POS) |
1128                      (rx_length_frames << MXC_F_SPI_REVA_CTRL1_RX_NUM_CHAR_POS);
1129     }
1130 
1131     // Disable FIFOs before clearing as recommended by UG.
1132     spi->dma &= ~(MXC_F_SPI_REVA_DMA_TX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_TX_EN |
1133                   MXC_F_SPI_REVA_DMA_RX_FIFO_EN | MXC_F_SPI_REVA_DMA_DMA_RX_EN);
1134     spi->dma |= (MXC_F_SPI_REVA_DMA_TX_FLUSH | MXC_F_SPI_REVA_DMA_RX_FLUSH);
1135 
1136     //>>> Start of SPI DMA transaction setup.
1137     if (use_dma) {
1138         // Enable TX FIFO before configuring.
1139         spi->dma |= (MXC_F_SPI_REVA_DMA_TX_FIFO_EN);
1140 
1141         // Set TX and RX Thresholds before loading FIFO.
1142         MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
1143                      ((MXC_SPI_FIFO_DEPTH - 1) << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS));
1144         MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_RX_THD_VAL,
1145                      (0 << MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS));
1146 
1147         // Set up DMA TX Transactions.
1148         // Note: Number of transmitting frames greatly depends on the SPI DMA register settings for
1149         //      the DMA burst size and TX Threshold values.
1150         // 1) For TX transmissions.
1151         if (tx_length_frames > 1) {
1152             // For readability purposes.
1153             tx_ch = STATES[spi_num].tx_dma_ch;
1154 
1155             // Configure DMA TX depending on frame width.
1156             // 2-8 bit wide frames.
1157             if (STATES[spi_num].frame_size <= 8) {
1158                 // Hardware requires writing the first byte into the FIFO manually.
1159                 spi->fifo8[0] = tx_buffer[0];
1160 
1161                 // Threshold set to 2 frames (2 bytes) after pre-loading first byte for DMA.
1162                 //  This is the minimum threshold to handle any number of transmitting frames.
1163                 //  Note: This case is handling TX transactions of greater than 1 frame.
1164                 //        Threshold of 1 frame does not work.
1165                 MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
1166                              (2 << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS));
1167 
1168                 STATES[spi_num].dma->ch[tx_ch].src = (uint32_t)(tx_buffer + 1); // 1 Byte offset
1169                 STATES[spi_num].dma->ch[tx_ch].cnt = (tx_length_frames - 1);
1170 
1171                 // Set to 3 bytes (3 frames) burst size.
1172                 //  Due to design: burst_size = threshold + 1
1173                 //  Note: Assigning value of 2 to register-field equals 3 bytes transferred in/out of DMA.
1174                 //        Add 1 to the register-field setting to get the number of bytes for burst.
1175                 MXC_SETFIELD(STATES[spi_num].dma->ch[tx_ch].ctrl, MXC_F_DMA_REVA_CTRL_BURST_SIZE,
1176                              (2 << MXC_F_DMA_REVA_CTRL_BURST_SIZE_POS));
1177 
1178                 // Set source and destination width to one byte.
1179                 MXC_SETFIELD(STATES[spi_num].dma->ch[tx_ch].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD,
1180                              MXC_S_DMA_REVA_CTRL_SRCWD_BYTE);
1181                 MXC_SETFIELD(STATES[spi_num].dma->ch[tx_ch].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD,
1182                              MXC_S_DMA_REVA_CTRL_DSTWD_BYTE);
1183 
1184                 // 9-16 bit wide frames.
1185             } else {
1186                 // Hardware requires writing the first bytes into the FIFO manually.
1187                 STATES[spi_num].tx_count_bytes +=
1188                     MXC_SPI_RevA2_writeTXFIFO16(spi, (uint8_t *)(STATES[spi_num].tx_buffer), 2);
1189 
1190                 // Threshold set to 3 frames (6 bytes) after pre-loading FIFO for DMA.
1191                 //  This is the minimum threshold to handle any number of transmitting frames.
1192                 //  Note: This case is handling TX transactions of greater than 1 frame.
1193                 //        Threshold of 1 or 2 frames does not work.
1194                 MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
1195                              (3 << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS));
1196 
1197                 STATES[spi_num].dma->ch[tx_ch].src =
1198                     (uint32_t)(tx_buffer + STATES[spi_num].tx_count_bytes);
1199                 STATES[spi_num].dma->ch[tx_ch].cnt =
1200                     (STATES[spi_num].tx_length_bytes - STATES[spi_num].tx_count_bytes);
1201 
1202                 // Set to 4 bytes (2 frames) burst size.
1203                 //  Due to design: burst_size = threshold + 1
1204                 //  Note: Assigning value of 3 to register-field equals 4 bytes.
1205                 //        Add 1 to the register-field setting to get the number of bytes for burst.
1206                 MXC_SETFIELD(STATES[spi_num].dma->ch[tx_ch].ctrl, MXC_F_DMA_REVA_CTRL_BURST_SIZE,
1207                              (3 << MXC_F_DMA_REVA_CTRL_BURST_SIZE_POS));
1208 
1209                 // Set source and destination width to two bytes.
1210                 MXC_SETFIELD(STATES[spi_num].dma->ch[tx_ch].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD,
1211                              MXC_S_DMA_REVA_CTRL_SRCWD_HALFWORD);
1212                 MXC_SETFIELD(STATES[spi_num].dma->ch[tx_ch].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD,
1213                              MXC_S_DMA_REVA_CTRL_DSTWD_HALFWORD);
1214             }
1215 
1216             STATES[spi_num].dma->ch[tx_ch].ctrl |= MXC_F_DMA_REVA_CTRL_SRCINC;
1217             STATES[spi_num].dma->ch[tx_ch].ctrl |= MXC_F_DMA_REVA_CTRL_EN; // Start the DMA
1218 
1219             // 2) For single character transmissions.
1220             //    NOTE: Single-length transmissions does not trigger CTZ.
1221         } else if (tx_length_frames == 1) {
1222             // Write first frame into FIFO.
1223             if (STATES[spi_num].frame_size <= 8) {
1224                 spi->fifo8[0] = tx_buffer[0];
1225             } else {
1226                 MXC_SPI_RevA2_writeTXFIFO16(spi, (uint8_t *)(STATES[spi_num].tx_buffer), 2);
1227             }
1228 
1229             // If there is no RX DMA and only one frame is transmitted, then
1230             //  the transaction is done. Single-length transmissions
1231             //  does not trigger a CTZ interrupt.
1232             if (rx_length_frames > 0 && rx_buffer != NULL) {
1233                 STATES[spi_num].transaction_done = true;
1234             }
1235 
1236             STATES[spi_num].tx_done = true;
1237 
1238             // 3) Set up DMA TX for RX only transactions.
1239             //    Note: Even if you are not transmitting anything in standard 4-wire mode,
1240             //      the hardware always assume full duplex. Therefore dummy bytes
1241             //      must be transmitted to support half duplex. The number of bytes to transmit
1242             //      AND receive is set by TX_NUM_CHAR, and the RX_NUM_CHAR field of ctrl1 is ignored.
1243         } else if (tx_length_frames == 0 && STATES[spi_num].if_mode == MXC_SPI_INTERFACE_STANDARD) {
1244             // For readability purposes.
1245             tx_ch = STATES[spi_num].tx_dma_ch;
1246 
1247             // Configure TX DMA channel to retransmit the dummy byte.
1248             STATES[spi_num].dma->ch[tx_ch].src = (uint32_t)(&(STATES[spi_num].tx_dummy_value));
1249             STATES[spi_num].dma->ch[tx_ch].cnt = STATES[spi_num].rx_length_bytes; // Only receiving
1250             STATES[spi_num].dma->ch[tx_ch].ctrl &= ~MXC_F_DMA_REVA_CTRL_SRCINC;
1251             STATES[spi_num].dma->ch[tx_ch].ctrl |= MXC_F_DMA_REVA_CTRL_EN; // Start the DMA
1252         }
1253 
1254         // Enable SPI TX DMA after configuring.
1255         spi->dma |= (MXC_F_SPI_REVA_DMA_DMA_TX_EN);
1256 
1257         // Set up DMA RX Transactions.
1258         if (rx_length_frames > 0 && rx_buffer != NULL) {
1259             // For readability purposes.
1260             rx_ch = STATES[spi_num].rx_dma_ch;
1261 
1262             // Enable RX DMA channel before configuring.
1263             spi->dma |= (MXC_F_SPI_REVA_DMA_RX_FIFO_EN);
1264 
1265             // Set RX threshold to minimum value to handle any number of received frames.
1266             MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_RX_THD_VAL,
1267                          (0 << MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS));
1268 
1269             STATES[spi_num].dma->ch[rx_ch].dst = (uint32_t)rx_buffer;
1270             STATES[spi_num].dma->ch[rx_ch].cnt = STATES[spi_num].rx_length_bytes;
1271 
1272             // Set to one byte burst size - minimum value to handle any number of recevied frames.
1273             MXC_SETFIELD(STATES[spi_num].dma->ch[rx_ch].ctrl, MXC_F_DMA_REVA_CTRL_BURST_SIZE,
1274                          (0 << MXC_F_DMA_REVA_CTRL_BURST_SIZE_POS));
1275 
1276             // Match frame size (in terms of bytes) in DMA ctrl settings.
1277             if (STATES[spi_num].frame_size <= 8) {
1278                 // Set source and destination width to one byte
1279                 MXC_SETFIELD(STATES[spi_num].dma->ch[rx_ch].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD,
1280                              MXC_S_DMA_REVA_CTRL_SRCWD_BYTE);
1281                 MXC_SETFIELD(STATES[spi_num].dma->ch[rx_ch].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD,
1282                              MXC_S_DMA_REVA_CTRL_DSTWD_BYTE);
1283             } else {
1284                 // Set source destination width to 2 bytes
1285                 MXC_SETFIELD(STATES[spi_num].dma->ch[rx_ch].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD,
1286                              MXC_S_DMA_REVA_CTRL_SRCWD_HALFWORD);
1287                 MXC_SETFIELD(STATES[spi_num].dma->ch[rx_ch].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD,
1288                              MXC_S_DMA_REVA_CTRL_DSTWD_HALFWORD);
1289             }
1290 
1291             STATES[spi_num].dma->ch[rx_ch].ctrl |= MXC_F_DMA_REVA_CTRL_DSTINC;
1292             STATES[spi_num].dma->ch[rx_ch].ctrl |= MXC_F_DMA_REVA_CTRL_EN; // Start the DMA
1293 
1294             // Enable SPI RX DMA after configuring.
1295             spi->dma |= (MXC_F_SPI_REVA_DMA_DMA_RX_EN);
1296         }
1297         //<<< End of SPI DMA transaction setup.
1298         //>>> Start of SPI non-DMA transaction setup.
1299     } else {
1300         // Finish setting up SPI for TX and RX.
1301         if (tx_length_frames > 0) {
1302             // Enable TX FIFO & TX Threshold crossed interrupt.
1303             spi->dma |= (MXC_F_SPI_REVA_DMA_TX_FIFO_EN);
1304             spi->inten |= MXC_F_SPI_REVA_INTEN_TX_THD;
1305 
1306             // Set TX Threshold to minimum value after re-enabling TX FIFO.
1307             MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_TX_THD_VAL,
1308                          (1 << MXC_F_SPI_REVA_DMA_TX_THD_VAL_POS));
1309         }
1310 
1311         if (rx_length_frames > 0) {
1312             // Enable RX FIFO & RX Threshold crossed interrupt.
1313             spi->dma |= (MXC_F_SPI_REVA_DMA_RX_FIFO_EN);
1314             spi->inten |= MXC_F_SPI_REVA_INTEN_RX_THD;
1315 
1316             // Set RX Threshold to minimum value after re-enabling RX FIFO.
1317             MXC_SETFIELD(spi->dma, MXC_F_SPI_REVA_DMA_RX_THD_VAL,
1318                          (0 << MXC_F_SPI_REVA_DMA_RX_THD_VAL_POS));
1319         }
1320 
1321         // This private function, MXC_SPI_RevA2_process, call fills the TX FIFO as much as possible
1322         //   before launching the transaction. Subsequent FIFO management will be handled after
1323         //   transaction has started.
1324         MXC_SPI_RevA2_process(spi);
1325     } //<<< End of SPI non-DMA transaction setup.
1326 }
1327 
1328 // Helper function that handles the Target Select assertion/deassertion at start of transaction.
1329 // hw_ts_active_pol is either 1 or 0.
MXC_SPI_RevA2_handleTSControl(mxc_spi_reva_regs_t * spi,uint8_t deassert,uint8_t hw_ts_index)1330 static void MXC_SPI_RevA2_handleTSControl(mxc_spi_reva_regs_t *spi, uint8_t deassert,
1331                                           uint8_t hw_ts_index)
1332 {
1333     int8_t spi_num;
1334 
1335     // Ensure valid SPI Instance.
1336     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1337 
1338     // Handle target-select (L. SS) deassertion if HW is selected as Target Select (TS) Control Scheme. This must be done
1339     //   AFTER launching the transaction to avoid a glitch on the TS line if:
1340     //     - The TS line is asserted
1341     //     - We want to deassert the line as part of this transaction
1342     //
1343     // As soon as the SPI hardware receives CTRL0->START it seems to reinitialize the Target Select (TS) pin based
1344     //   on the value of CTRL->SS_CTRL, which causes the glitch.
1345     if (STATES[spi_num].ts_control == MXC_SPI_TSCONTROL_HW_AUTO) {
1346         // In HW Auto Scheme, only use the target index member.
1347         // Limitation: This implemention only support transactions with one target at a time.
1348         MXC_SETFIELD(spi->ctrl0, MXC_F_SPI_REVA_CTRL0_SS_ACTIVE,
1349                      ((1 << hw_ts_index) << MXC_F_SPI_REVA_CTRL0_SS_ACTIVE_POS));
1350 
1351         if (deassert) {
1352             spi->ctrl0 &= ~MXC_F_SPI_REVA_CTRL0_SS_CTRL;
1353         } else {
1354             spi->ctrl0 |= MXC_F_SPI_REVA_CTRL0_SS_CTRL;
1355         }
1356     }
1357 
1358     // Add support for SW_DRV TS Control here in the future.
1359 }
1360 
1361 /* ** Transaction Functions ** */
1362 
MXC_SPI_RevA2_ControllerTransaction(mxc_spi_reva_regs_t * spi,uint8_t * tx_buffer,uint32_t tx_length_frames,uint8_t * rx_buffer,uint32_t rx_length_frames,uint8_t deassert,uint8_t hw_ts_index)1363 int MXC_SPI_RevA2_ControllerTransaction(mxc_spi_reva_regs_t *spi, uint8_t *tx_buffer,
1364                                         uint32_t tx_length_frames, uint8_t *rx_buffer,
1365                                         uint32_t rx_length_frames, uint8_t deassert,
1366                                         uint8_t hw_ts_index)
1367 {
1368     int8_t spi_num;
1369 
1370     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1371 
1372     // Make sure DMA is not initialized.
1373     if (STATES[spi_num].dma_initialized == true) {
1374         return E_BAD_STATE;
1375     }
1376 
1377     // Make sure SPI Instance is in Controller mode (L. Master).
1378     if (STATES[spi_num].controller_target != MXC_SPI_TYPE_CONTROLLER) {
1379         return E_BAD_STATE;
1380     }
1381 
1382     // Save target settings.
1383     STATES[spi_num].deassert = deassert;
1384 
1385     // Setup SPI registers for non-DMA transaction.
1386     MXC_SPI_RevA2_transactionSetup(spi, tx_buffer, tx_length_frames, rx_buffer, rx_length_frames,
1387                                    false);
1388 
1389     // Start the SPI transaction.
1390     spi->ctrl0 |= MXC_F_SPI_REVA_CTRL0_START;
1391 
1392     // Handle Target Select Pin (Only applicable in HW_AUTO TS control scheme).
1393     MXC_SPI_RevA2_handleTSControl(spi, deassert, hw_ts_index);
1394 
1395     // Complete transaction once it started.
1396     while (STATES[spi_num].transaction_done == false) {
1397         if (STATES[spi_num].tx_done == true && STATES[spi_num].rx_done == true) {
1398             if (!(spi->stat & MXC_F_SPI_REVA_STAT_BUSY)) {
1399                 STATES[spi_num].transaction_done = true;
1400             }
1401         }
1402 
1403         MXC_SPI_RevA2_process(spi);
1404     }
1405 
1406     return E_SUCCESS;
1407 }
1408 
MXC_SPI_RevA2_ControllerTransactionAsync(mxc_spi_reva_regs_t * spi,uint8_t * tx_buffer,uint32_t tx_length_frames,uint8_t * rx_buffer,uint32_t rx_length_frames,uint8_t deassert,uint8_t hw_ts_index)1409 int MXC_SPI_RevA2_ControllerTransactionAsync(mxc_spi_reva_regs_t *spi, uint8_t *tx_buffer,
1410                                              uint32_t tx_length_frames, uint8_t *rx_buffer,
1411                                              uint32_t rx_length_frames, uint8_t deassert,
1412                                              uint8_t hw_ts_index)
1413 {
1414     int8_t spi_num;
1415 
1416     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1417 
1418     // Make sure DMA is not initialized.
1419     if (STATES[spi_num].dma_initialized == true) {
1420         return E_BAD_STATE;
1421     }
1422 
1423     // Make sure SPI Instance is in Controller mode (L. Master).
1424     if (STATES[spi_num].controller_target != MXC_SPI_TYPE_CONTROLLER) {
1425         return E_BAD_STATE;
1426     }
1427 
1428     // Save target settings.
1429     STATES[spi_num].deassert = deassert;
1430 
1431     // Setup SPI registers for non-DMA transaction.
1432     MXC_SPI_RevA2_transactionSetup(spi, tx_buffer, tx_length_frames, rx_buffer, rx_length_frames,
1433                                    false);
1434 
1435     // Enable Controller Done Interrupt.
1436     spi->inten |= MXC_F_SPI_REVA_INTEN_MST_DONE;
1437 
1438     // Start the SPI transaction.
1439     spi->ctrl0 |= MXC_F_SPI_REVA_CTRL0_START;
1440 
1441     // Handle Target Select Pin (Only applicable in HW_AUTO TS control scheme).
1442     MXC_SPI_RevA2_handleTSControl(spi, deassert, hw_ts_index);
1443 
1444     return E_SUCCESS;
1445 }
1446 
MXC_SPI_RevA2_ControllerTransactionDMA(mxc_spi_reva_regs_t * spi,uint8_t * tx_buffer,uint32_t tx_length_frames,uint8_t * rx_buffer,uint32_t rx_length_frames,uint8_t deassert,uint8_t hw_ts_index,mxc_dma_reva_regs_t * dma)1447 int MXC_SPI_RevA2_ControllerTransactionDMA(mxc_spi_reva_regs_t *spi, uint8_t *tx_buffer,
1448                                            uint32_t tx_length_frames, uint8_t *rx_buffer,
1449                                            uint32_t rx_length_frames, uint8_t deassert,
1450                                            uint8_t hw_ts_index, mxc_dma_reva_regs_t *dma)
1451 {
1452     int8_t spi_num;
1453     int error;
1454 
1455     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1456 
1457     // More overhead, but this function will initialize DMA if it wasn't done earlier.
1458     if (STATES[spi_num].dma_initialized == false) {
1459         error = MXC_SPI_RevA2_DMA_Init(spi, dma, true, true);
1460         if (error != E_NO_ERROR) {
1461             return error;
1462         }
1463     }
1464 
1465     // Make sure SPI Instance is in Controller mode (L. Master).
1466     if (STATES[spi_num].controller_target != MXC_SPI_TYPE_CONTROLLER) {
1467         return E_BAD_STATE;
1468     }
1469 
1470     // Save target settings.
1471     STATES[spi_num].deassert = deassert;
1472 
1473     // Setup SPI registers for non-DMA transaction.
1474     MXC_SPI_RevA2_transactionSetup(spi, tx_buffer, tx_length_frames, rx_buffer, rx_length_frames,
1475                                    true);
1476 
1477     // Start the SPI transaction.
1478     spi->ctrl0 |= MXC_F_SPI_REVA_CTRL0_START;
1479 
1480     // Handle Target Select Pin (Only applicable in HW_AUTO TS control scheme).
1481     MXC_SPI_RevA2_handleTSControl(spi, deassert, hw_ts_index);
1482 
1483     return E_SUCCESS;
1484 }
1485 
MXC_SPI_RevA2_TargetTransaction(mxc_spi_reva_regs_t * spi,uint8_t * tx_buffer,uint32_t tx_length_frames,uint8_t * rx_buffer,uint32_t rx_length_frames)1486 int MXC_SPI_RevA2_TargetTransaction(mxc_spi_reva_regs_t *spi, uint8_t *tx_buffer,
1487                                     uint32_t tx_length_frames, uint8_t *rx_buffer,
1488                                     uint32_t rx_length_frames)
1489 {
1490     int8_t spi_num;
1491 
1492     // Ensure valid SPI Instance.
1493     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1494 
1495     // Make sure DMA is not initialized.
1496     if (STATES[spi_num].dma_initialized == true) {
1497         return E_BAD_STATE;
1498     }
1499 
1500     // Make sure SPI Instance is in Target mode (L. Slave).
1501     if (STATES[spi_num].controller_target != MXC_SPI_TYPE_TARGET) {
1502         return E_BAD_STATE;
1503     }
1504 
1505     // Setup SPI registers for non-DMA transaction.
1506     MXC_SPI_RevA2_transactionSetup(spi, tx_buffer, tx_length_frames, rx_buffer, rx_length_frames,
1507                                    false);
1508 
1509     // Wait for Target Select pin to be asserted before starting transaction.
1510     while ((spi->stat & MXC_F_SPI_REVA_STAT_BUSY) == 0) {}
1511 
1512     // Complete transaction once started.
1513     while (STATES[spi_num].transaction_done == false) {
1514         if (STATES[spi_num].tx_count_bytes == STATES[spi_num].tx_length_bytes &&
1515             STATES[spi_num].rx_count_bytes == STATES[spi_num].rx_length_bytes) {
1516             STATES[spi_num].transaction_done = true;
1517         }
1518 
1519         MXC_SPI_RevA2_process(spi);
1520     }
1521 
1522     // Wait until transaction is complete.
1523     while (spi->stat & MXC_F_SPI_REVA_STAT_BUSY) {}
1524 
1525     return E_SUCCESS;
1526 }
1527 
MXC_SPI_RevA2_TargetTransactionAsync(mxc_spi_reva_regs_t * spi,uint8_t * tx_buffer,uint32_t tx_length_frames,uint8_t * rx_buffer,uint32_t rx_length_frames)1528 int MXC_SPI_RevA2_TargetTransactionAsync(mxc_spi_reva_regs_t *spi, uint8_t *tx_buffer,
1529                                          uint32_t tx_length_frames, uint8_t *rx_buffer,
1530                                          uint32_t rx_length_frames)
1531 {
1532     int8_t spi_num;
1533 
1534     // Ensure valid SPI Instance.
1535     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1536 
1537     // Make sure DMA is not initialized.
1538     if (STATES[spi_num].dma_initialized == true) {
1539         return E_BAD_STATE;
1540     }
1541 
1542     // Make sure SPI Instance is in Target mode (L. Slave).
1543     if (STATES[spi_num].controller_target != MXC_SPI_TYPE_TARGET) {
1544         return E_BAD_STATE;
1545     }
1546 
1547     // Setup SPI registers for non-DMA transaction.
1548     MXC_SPI_RevA2_transactionSetup(spi, tx_buffer, tx_length_frames, rx_buffer, rx_length_frames,
1549                                    false);
1550 
1551     return E_SUCCESS;
1552 }
1553 
MXC_SPI_RevA2_TargetTransactionDMA(mxc_spi_reva_regs_t * spi,uint8_t * tx_buffer,uint32_t tx_length_frames,uint8_t * rx_buffer,uint32_t rx_length_frames,mxc_dma_reva_regs_t * dma)1554 int MXC_SPI_RevA2_TargetTransactionDMA(mxc_spi_reva_regs_t *spi, uint8_t *tx_buffer,
1555                                        uint32_t tx_length_frames, uint8_t *rx_buffer,
1556                                        uint32_t rx_length_frames, mxc_dma_reva_regs_t *dma)
1557 {
1558     int8_t spi_num;
1559     int error;
1560 
1561     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1562 
1563     // More overhead, but this function will initialize DMA if it wasn't done earlier.
1564     if (STATES[spi_num].dma_initialized == false) {
1565         error = MXC_SPI_RevA2_DMA_Init(spi, dma, true, true);
1566         if (error != E_NO_ERROR) {
1567             return error;
1568         }
1569     }
1570 
1571     // Make sure SPI Instance is in Target mode (L. Slave).
1572     if (STATES[spi_num].controller_target != MXC_SPI_TYPE_TARGET) {
1573         return E_BAD_STATE;
1574     }
1575 
1576     // Setup SPI registers for DMA transaction.
1577     MXC_SPI_RevA2_transactionSetup(spi, tx_buffer, tx_length_frames, rx_buffer, rx_length_frames,
1578                                    true);
1579 
1580     // Target transaction is ready.
1581     return E_SUCCESS;
1582 }
1583 
1584 /* ** Handler Functions ** */
1585 
MXC_SPI_RevA2_Handler(mxc_spi_reva_regs_t * spi)1586 void MXC_SPI_RevA2_Handler(mxc_spi_reva_regs_t *spi)
1587 {
1588     int8_t spi_num;
1589     uint32_t status = spi->intfl;
1590 
1591     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1592 
1593     // Master done (TX complete)
1594     if (status & MXC_F_SPI_REVA_INTFL_MST_DONE) {
1595         spi->intfl |= MXC_F_SPI_REVA_INTFL_MST_DONE; // Clear flag
1596 
1597         // Callback if valid.
1598         // Note: If Target Select (TS) Control Scheme is set in SW_App mode, then the caller needs to ensure the
1599         //   Target Select (TS) pin is asserted or deasserted in their application.
1600         if (STATES[spi_num].callback) {
1601             STATES[spi_num].callback(STATES[spi_num].callback_data, E_NO_ERROR);
1602         }
1603 
1604         // Controller is done after callback (if valid) is handled.
1605         STATES[spi_num].transaction_done = true;
1606     }
1607 
1608     // Handle RX Threshold
1609     if (status & MXC_F_SPI_REVA_INTFL_RX_THD) {
1610         spi->intfl |= MXC_F_SPI_REVA_INTFL_RX_THD;
1611 
1612         // RX threshold has been crossed, there's data to unload from the FIFO
1613         MXC_SPI_RevA2_process(spi);
1614     }
1615 
1616     // Handle TX Threshold
1617     if (status & MXC_F_SPI_REVA_INTFL_TX_THD) {
1618         spi->intfl |= MXC_F_SPI_REVA_INTFL_TX_THD;
1619 
1620         // TX threshold has been crossed, we need to refill the FIFO
1621         MXC_SPI_RevA2_process(spi);
1622     }
1623 }
1624 
MXC_SPI_RevA2_DMA_TX_Handler(mxc_spi_reva_regs_t * spi)1625 void MXC_SPI_RevA2_DMA_TX_Handler(mxc_spi_reva_regs_t *spi)
1626 {
1627     int8_t spi_num;
1628     uint32_t tx_ch;
1629     uint32_t status;
1630 
1631     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1632 
1633     tx_ch = STATES[spi_num].tx_dma_ch;
1634     status = STATES[spi_num].dma->ch[tx_ch].status;
1635 
1636     // Count-to-Zero (DMA TX complete)
1637     if (status & MXC_F_DMA_REVA_STATUS_CTZ_IF) {
1638         STATES[spi_num].tx_done = true;
1639         STATES[spi_num].dma->ch[tx_ch].status |= MXC_F_DMA_REVA_STATUS_CTZ_IF;
1640 
1641         // For completeness-sake.
1642         STATES[spi_num].tx_count_bytes = STATES[spi_num].tx_length_bytes;
1643 
1644         // Callback if valid and if you're only transmitting.
1645         // Note: If Target Select (TS) Control Scheme is set in SW_App mode, then the caller needs to ensure the
1646         //   Target Select (TS) pin is asserted or deasserted in their application.
1647         if (STATES[spi_num].rx_buffer == NULL) {
1648             if (STATES[spi_num].callback) {
1649                 STATES[spi_num].callback(STATES[spi_num].callback_data, E_NO_ERROR);
1650             }
1651         }
1652 
1653         // TX Transaction is done if there's no RX transaction.
1654         if (STATES[spi_num].rx_length_bytes == 0 || STATES[spi_num].tx_buffer == NULL) {
1655             STATES[spi_num].transaction_done = true;
1656         }
1657     }
1658 
1659     // Bus Error
1660     if (status & MXC_F_DMA_REVA_STATUS_BUS_ERR) {
1661         STATES[spi_num].dma->ch[tx_ch].status |= MXC_F_DMA_REVA_STATUS_BUS_ERR;
1662     }
1663 }
1664 
MXC_SPI_RevA2_DMA_RX_Handler(mxc_spi_reva_regs_t * spi)1665 void MXC_SPI_RevA2_DMA_RX_Handler(mxc_spi_reva_regs_t *spi)
1666 {
1667     int8_t spi_num;
1668     uint32_t rx_ch;
1669     uint32_t status;
1670 
1671     spi_num = MXC_SPI_GET_IDX((mxc_spi_regs_t *)spi);
1672 
1673     rx_ch = STATES[spi_num].rx_dma_ch;
1674     status = STATES[spi_num].dma->ch[rx_ch].status;
1675 
1676     // Count-to-Zero (DMA RX complete).
1677     if (status & MXC_F_DMA_REVA_STATUS_CTZ_IF) {
1678         // HW Bug: For 2-byte wide frame transactions, RX DMA swaps the
1679         //      LSB and MSB.
1680         // Example: TX: 0x1234 => RX: 0x3412
1681         if (STATES[spi_num].frame_size > 8) {
1682             MXC_SPI_RevA2_DMA_SwapByte(STATES[spi_num].rx_buffer, STATES[spi_num].rx_length_bytes);
1683         }
1684 
1685         STATES[spi_num].rx_done = 1;
1686         STATES[spi_num].dma->ch[rx_ch].status |= MXC_F_DMA_STATUS_CTZ_IF;
1687 
1688         // For completeness-sake.
1689         STATES[spi_num].rx_count_bytes = STATES[spi_num].rx_length_bytes;
1690 
1691         // Callback if valid.
1692         // Note: If Target Select (TS) Control Scheme is set in SW_App mode, then the caller needs to ensure the
1693         //   Target Select (TS) pin is asserted or deasserted in their application.
1694         if (STATES[spi_num].callback) {
1695             STATES[spi_num].callback(STATES[spi_num].callback_data, E_NO_ERROR);
1696         }
1697 
1698         // RX transaction determines the controller is done if TX transaction is also present.
1699         if (STATES[spi_num].tx_length_bytes > 0 && STATES[spi_num].tx_buffer != NULL) {
1700             STATES[spi_num].transaction_done = true;
1701         }
1702     }
1703 
1704     // Bus Error
1705     if (status & MXC_F_DMA_REVA_STATUS_BUS_ERR) {
1706         STATES[spi_num].dma->ch[rx_ch].status |= MXC_F_DMA_STATUS_BUS_ERR;
1707     }
1708 }
1709