1 /*
2  * Copyright 2019-2020,2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_dbi.h"
9 #include "fsl_dbi_flexio_edma.h"
10 
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 
15 /*******************************************************************************
16  * Prototypes
17  ******************************************************************************/
18 /*!
19  * @brief FLEXIO DBI bus transfer complete callback function.
20  */
21 static void DBI_FLEXIO_EDMA_TransferCompletedCallback(FLEXIO_MCULCD_Type *base,
22                                                       flexio_mculcd_edma_handle_t *handle,
23                                                       status_t status,
24                                                       void *userData);
25 
26 /*******************************************************************************
27  * Variables
28  ******************************************************************************/
29 const dbi_xfer_ops_t g_dbiFlexioEdmaXferOps = {
30     .writeCommand          = DBI_FLEXIO_EDMA_WriteCommand,
31     .writeData             = DBI_FLEXIO_EDMA_WriteData,
32     .writeMemory           = DBI_FLEXIO_EDMA_WriteMemory,
33     .readMemory            = DBI_FLEXIO_EDMA_ReadMemory,
34     .setMemoryDoneCallback = DBI_FLEXIO_EDMA_SetMemoryDoneCallback,
35 };
36 
37 /*******************************************************************************
38  * Code
39  ******************************************************************************/
DBI_FLEXIO_EDMA_TransferCompletedCallback(FLEXIO_MCULCD_Type * base,flexio_mculcd_edma_handle_t * handle,status_t status,void * userData)40 static void DBI_FLEXIO_EDMA_TransferCompletedCallback(FLEXIO_MCULCD_Type *base,
41                                                       flexio_mculcd_edma_handle_t *handle,
42                                                       status_t status,
43                                                       void *userData)
44 {
45     dbi_flexio_edma_xfer_handle_t *xferHandle = (dbi_flexio_edma_xfer_handle_t *)userData;
46 
47     if (kStatus_FLEXIO_MCULCD_Idle == status)
48     {
49         status = kStatus_Success;
50     }
51 
52     xferHandle->memDoneCallback(status, xferHandle->userData);
53 }
54 
DBI_FLEXIO_EDMA_SetMemoryDoneCallback(void * dbiXferHandle,dbi_mem_done_callback_t callback,void * userData)55 void DBI_FLEXIO_EDMA_SetMemoryDoneCallback(void *dbiXferHandle, dbi_mem_done_callback_t callback, void *userData)
56 {
57     dbi_flexio_edma_xfer_handle_t *xferHandle = (dbi_flexio_edma_xfer_handle_t *)dbiXferHandle;
58 
59     xferHandle->memDoneCallback = callback;
60     xferHandle->userData        = userData;
61 }
62 
DBI_FLEXIO_EDMA_CreateXferHandle(dbi_flexio_edma_xfer_handle_t * dbiXferHandle,FLEXIO_MCULCD_Type * flexioLCD,edma_handle_t * txDmaHandle,edma_handle_t * rxDmaHandle)63 status_t DBI_FLEXIO_EDMA_CreateXferHandle(dbi_flexio_edma_xfer_handle_t *dbiXferHandle,
64                                           FLEXIO_MCULCD_Type *flexioLCD,
65                                           edma_handle_t *txDmaHandle,
66                                           edma_handle_t *rxDmaHandle)
67 {
68     (void)memset(dbiXferHandle, 0, sizeof(dbi_flexio_edma_xfer_handle_t));
69 
70     return FLEXIO_MCULCD_TransferCreateHandleEDMA(flexioLCD, &dbiXferHandle->flexioHandle,
71                                                   DBI_FLEXIO_EDMA_TransferCompletedCallback, dbiXferHandle, txDmaHandle,
72                                                   rxDmaHandle);
73 }
74 
DBI_FLEXIO_EDMA_WriteCommand(void * dbiXferHandle,uint32_t command)75 status_t DBI_FLEXIO_EDMA_WriteCommand(void *dbiXferHandle, uint32_t command)
76 {
77     dbi_flexio_edma_xfer_handle_t *xferHandle = (dbi_flexio_edma_xfer_handle_t *)dbiXferHandle;
78 
79     FLEXIO_MCULCD_Type *flexioLCD = xferHandle->flexioHandle.base;
80 
81     FLEXIO_MCULCD_StartTransfer(flexioLCD);
82     FLEXIO_MCULCD_WriteCommandBlocking(flexioLCD, command);
83     FLEXIO_MCULCD_StopTransfer(flexioLCD);
84 
85     return kStatus_Success;
86 }
87 
DBI_FLEXIO_EDMA_WriteData(void * dbiXferHandle,void * data,uint32_t len_byte)88 status_t DBI_FLEXIO_EDMA_WriteData(void *dbiXferHandle, void *data, uint32_t len_byte)
89 {
90     dbi_flexio_edma_xfer_handle_t *xferHandle = (dbi_flexio_edma_xfer_handle_t *)dbiXferHandle;
91 
92     FLEXIO_MCULCD_Type *flexioLCD = xferHandle->flexioHandle.base;
93 
94     FLEXIO_MCULCD_StartTransfer(flexioLCD);
95     FLEXIO_MCULCD_WriteDataArrayBlocking(flexioLCD, data, len_byte);
96     FLEXIO_MCULCD_StopTransfer(flexioLCD);
97 
98     return kStatus_Success;
99 }
100 
DBI_FLEXIO_EDMA_WriteMemory(void * dbiXferHandle,uint32_t command,const void * data,uint32_t len_byte)101 status_t DBI_FLEXIO_EDMA_WriteMemory(void *dbiXferHandle, uint32_t command, const void *data, uint32_t len_byte)
102 {
103     status_t status;
104 
105     flexio_mculcd_transfer_t xfer;
106 
107     dbi_flexio_edma_xfer_handle_t *xferHandle = (dbi_flexio_edma_xfer_handle_t *)dbiXferHandle;
108 
109     /* Callback is necessary to notify user. */
110     assert(NULL != xferHandle->memDoneCallback);
111 
112     FLEXIO_MCULCD_Type *flexioLCD = xferHandle->flexioHandle.base;
113 
114     if (NULL != xferHandle->flexioHandle.txDmaHandle)
115     {
116         xfer.command             = command;
117         xfer.mode                = kFLEXIO_MCULCD_WriteArray;
118         xfer.dataAddrOrSameValue = (uint32_t)(const uint8_t *)data;
119         xfer.dataSize            = len_byte;
120         xfer.dataOnly            = false;
121 
122         status = FLEXIO_MCULCD_TransferEDMA(flexioLCD, &xferHandle->flexioHandle, &xfer);
123     }
124     else
125     {
126         /* If DMA not enabled, use the blocking method. */
127         FLEXIO_MCULCD_StartTransfer(flexioLCD);
128         FLEXIO_MCULCD_WriteCommandBlocking(flexioLCD, command);
129         FLEXIO_MCULCD_WriteDataArrayBlocking(flexioLCD, (const void *)data, (size_t)len_byte);
130         FLEXIO_MCULCD_StopTransfer(flexioLCD);
131 
132         xferHandle->memDoneCallback(kStatus_Success, xferHandle->userData);
133 
134         status = kStatus_Success;
135     }
136 
137     return status;
138 }
139 
DBI_FLEXIO_EDMA_ReadMemory(void * dbiXferHandle,uint32_t command,void * data,uint32_t len_byte)140 status_t DBI_FLEXIO_EDMA_ReadMemory(void *dbiXferHandle, uint32_t command, void *data, uint32_t len_byte)
141 {
142     status_t status;
143 
144     flexio_mculcd_transfer_t xfer;
145 
146     dbi_flexio_edma_xfer_handle_t *xferHandle = (dbi_flexio_edma_xfer_handle_t *)dbiXferHandle;
147 
148     /* Callback is necessary to notify user. */
149     assert(NULL != xferHandle->memDoneCallback);
150 
151     FLEXIO_MCULCD_Type *flexioLCD = xferHandle->flexioHandle.base;
152 
153     if (NULL != xferHandle->flexioHandle.rxDmaHandle)
154     {
155         xfer.command             = command;
156         xfer.mode                = kFLEXIO_MCULCD_ReadArray;
157         xfer.dataAddrOrSameValue = (uint32_t)(uint8_t *)data;
158         xfer.dataSize            = len_byte;
159         xfer.dataOnly            = false;
160 
161         status = FLEXIO_MCULCD_TransferEDMA(flexioLCD, &xferHandle->flexioHandle, &xfer);
162     }
163     else
164     {
165         /* If DMA not enabled, use the blocking method. */
166         FLEXIO_MCULCD_StartTransfer(flexioLCD);
167         FLEXIO_MCULCD_WriteCommandBlocking(flexioLCD, command);
168         FLEXIO_MCULCD_ReadDataArrayBlocking(flexioLCD, data, (size_t)len_byte);
169         FLEXIO_MCULCD_StopTransfer(flexioLCD);
170 
171         xferHandle->memDoneCallback(kStatus_Success, xferHandle->userData);
172 
173         status = kStatus_Success;
174     }
175 
176     return status;
177 }
178