summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera_edma.c
blob: 12bb77b020b01509254ddbac4c76f7d7f553b1f0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * Copyright 2016-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_flexio_camera_edma.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.flexio_camera_edma"
#endif

/*<! Structure definition for camera_edma_private_handle_t. The structure is private. */
typedef struct _flexio_camera_edma_private_handle
{
    FLEXIO_CAMERA_Type *base;
    flexio_camera_edma_handle_t *handle;
} flexio_camera_edma_private_handle_t;

/* CAMERA EDMA transfer handle. */
enum _flexio_camera_edma_tansfer_states
{
    kFLEXIO_CAMERA_RxIdle, /* RX idle. */
    kFLEXIO_CAMERA_RxBusy  /* RX busy. */
};

/*******************************************************************************
 * Variables
 ******************************************************************************/

/*< @brief user configurable flexio camera handle count. */
#define FLEXIO_CAMERA_HANDLE_COUNT 1

/*<! Private handle only used for internally. */
static flexio_camera_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_CAMERA_HANDLE_COUNT];

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*!
 * @brief FLEXIO CAMERA EDMA receive finished callback function.
 *
 * This function is called when FLEXIO CAMERA EDMA receive finished. It disables the CAMERA
 * RX EDMA request and sends @ref kStatus_FLEXIO_CAMERA_RxIdle to CAMERA callback.
 *
 * @param handle The EDMA handle.
 * @param param Callback function parameter.
 */
static void FLEXIO_CAMERA_TransferReceiveEDMACallback(edma_handle_t *handle,
                                                      void *param,
                                                      bool transferDone,
                                                      uint32_t tcds);

/*******************************************************************************
 * Code
 ******************************************************************************/

static void FLEXIO_CAMERA_TransferReceiveEDMACallback(edma_handle_t *handle,
                                                      void *param,
                                                      bool transferDone,
                                                      uint32_t tcds)
{
    flexio_camera_edma_private_handle_t *cameraPrivateHandle = (flexio_camera_edma_private_handle_t *)param;

    /* Avoid the warning for unused variables. */
    handle = handle;
    tcds   = tcds;

    if (transferDone)
    {
        FLEXIO_CAMERA_TransferAbortReceiveEDMA(cameraPrivateHandle->base, cameraPrivateHandle->handle);

        if (cameraPrivateHandle->handle->callback != NULL)
        {
            cameraPrivateHandle->handle->callback(cameraPrivateHandle->base, cameraPrivateHandle->handle,
                                                  kStatus_FLEXIO_CAMERA_RxIdle, cameraPrivateHandle->handle->userData);
        }
    }
}
/*!
 * brief Initializes the Camera handle, which is used in transactional functions.
 *
 * param base Pointer to the FLEXIO_CAMERA_Type.
 * param handle Pointer to flexio_camera_edma_handle_t structure.
 * param callback The callback function.
 * param userData The parameter of the callback function.
 * param rxEdmaHandle User requested DMA handle for RX DMA transfer.
 * retval kStatus_Success Successfully create the handle.
 * retval kStatus_OutOfRange The FlexIO Camera eDMA type/handle table out of range.
 */
status_t FLEXIO_CAMERA_TransferCreateHandleEDMA(FLEXIO_CAMERA_Type *base,
                                                flexio_camera_edma_handle_t *handle,
                                                flexio_camera_edma_transfer_callback_t callback,
                                                void *userData,
                                                edma_handle_t *rxEdmaHandle)
{
    assert(handle != NULL);

    uint8_t index;

    /* Find the an empty handle pointer to store the handle. */
    for (index = 0U; index < (uint8_t)FLEXIO_CAMERA_HANDLE_COUNT; index++)
    {
        if (s_edmaPrivateHandle[index].base == NULL)
        {
            s_edmaPrivateHandle[index].base   = base;
            s_edmaPrivateHandle[index].handle = handle;
            break;
        }
    }

    if (index == (uint8_t)FLEXIO_CAMERA_HANDLE_COUNT)
    {
        return kStatus_OutOfRange;
    }

    s_edmaPrivateHandle[index].base   = base;
    s_edmaPrivateHandle[index].handle = handle;

    (void)memset(handle, 0, sizeof(*handle));

    handle->rxState      = (uint8_t)kFLEXIO_CAMERA_RxIdle;
    handle->rxEdmaHandle = rxEdmaHandle;

    handle->callback = callback;
    handle->userData = userData;

    /* Configure RX. */
    if (rxEdmaHandle != NULL)
    {
        EDMA_SetCallback(handle->rxEdmaHandle, FLEXIO_CAMERA_TransferReceiveEDMACallback, &s_edmaPrivateHandle);
    }

    return kStatus_Success;
}

/*!
 * brief Receives data using eDMA.
 *
 * This function receives data using eDMA. This is a non-blocking function, which returns
 * right away. When all data is received, the receive callback function is called.
 *
 * param base Pointer to the FLEXIO_CAMERA_Type.
 * param handle Pointer to the flexio_camera_edma_handle_t structure.
 * param xfer Camera eDMA transfer structure, see #flexio_camera_transfer_t.
 * retval kStatus_Success if succeeded, others failed.
 * retval kStatus_CAMERA_RxBusy Previous transfer on going.
 */
status_t FLEXIO_CAMERA_TransferReceiveEDMA(FLEXIO_CAMERA_Type *base,
                                           flexio_camera_edma_handle_t *handle,
                                           flexio_camera_transfer_t *xfer)
{
    assert(handle->rxEdmaHandle != NULL);

    edma_transfer_config_t xferConfig;
    status_t status;

    /* If previous RX not finished. */
    if ((uint8_t)kFLEXIO_CAMERA_RxBusy == handle->rxState)
    {
        status = kStatus_FLEXIO_CAMERA_RxBusy;
    }
    else
    {
        handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxBusy;

        /* Prepare transfer. */
        EDMA_PrepareTransfer(&xferConfig, (uint32_t *)FLEXIO_CAMERA_GetRxBufferAddress(base), 32,
                             (uint32_t *)xfer->dataAddress, 32, 32, xfer->dataNum, kEDMA_PeripheralToMemory);

        /* Store the initially configured eDMA minor byte transfer count into the FLEXIO CAMERA handle */
        handle->nbytes = 32;

        /* Submit transfer. */
        (void)EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
        EDMA_StartTransfer(handle->rxEdmaHandle);
        /* Enable CAMERA RX EDMA. */
        FLEXIO_CAMERA_EnableRxDMA(base, true);
        status = kStatus_Success;
    }

    return status;
}

/*!
 * brief Aborts the receive data which used the eDMA.
 *
 * This function aborts the receive data which used the eDMA.
 *
 * param base Pointer to the FLEXIO_CAMERA_Type.
 * param handle Pointer to the flexio_camera_edma_handle_t structure.
 */
void FLEXIO_CAMERA_TransferAbortReceiveEDMA(FLEXIO_CAMERA_Type *base, flexio_camera_edma_handle_t *handle)
{
    assert(handle->rxEdmaHandle != NULL);

    /* Disable CAMERA RX EDMA. */
    FLEXIO_CAMERA_EnableRxDMA(base, false);

    /* Stop transfer. */
    EDMA_StopTransfer(handle->rxEdmaHandle);

    handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxIdle;
}

/*!
 * brief Gets the remaining bytes to be received.
 *
 * This function gets the number of bytes still not received.
 *
 * param base Pointer to the FLEXIO_CAMERA_Type.
 * param handle Pointer to the flexio_camera_edma_handle_t structure.
 * param count Number of bytes sent so far by the non-blocking transaction.
 * retval kStatus_Success Succeed get the transfer count.
 * retval kStatus_InvalidArgument The count parameter is invalid.
 */
status_t FLEXIO_CAMERA_TransferGetReceiveCountEDMA(FLEXIO_CAMERA_Type *base,
                                                   flexio_camera_edma_handle_t *handle,
                                                   size_t *count)
{
    assert(handle->rxEdmaHandle != NULL);

    if (NULL == count)
    {
        return kStatus_InvalidArgument;
    }

    if ((uint8_t)kFLEXIO_CAMERA_RxBusy == handle->rxState)
    {
        *count = (handle->rxSize -
                  (uint32_t)handle->nbytes *
                      EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel));
    }
    else
    {
        *count = handle->rxSize;
    }

    return kStatus_Success;
}