fsl_flexio_camera_edma.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2020 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_flexio_camera_edma.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.flexio_camera_edma"
  15. #endif
  16. /*<! Structure definition for camera_edma_private_handle_t. The structure is private. */
  17. typedef struct _flexio_camera_edma_private_handle
  18. {
  19. FLEXIO_CAMERA_Type *base;
  20. flexio_camera_edma_handle_t *handle;
  21. } flexio_camera_edma_private_handle_t;
  22. /* CAMERA EDMA transfer handle. */
  23. enum _flexio_camera_edma_tansfer_states
  24. {
  25. kFLEXIO_CAMERA_RxIdle, /* RX idle. */
  26. kFLEXIO_CAMERA_RxBusy /* RX busy. */
  27. };
  28. /*******************************************************************************
  29. * Variables
  30. ******************************************************************************/
  31. /*< @brief user configurable flexio camera handle count. */
  32. #define FLEXIO_CAMERA_HANDLE_COUNT 1
  33. /*<! Private handle only used for internally. */
  34. static flexio_camera_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_CAMERA_HANDLE_COUNT];
  35. /*******************************************************************************
  36. * Prototypes
  37. ******************************************************************************/
  38. /*!
  39. * @brief FLEXIO CAMERA EDMA receive finished callback function.
  40. *
  41. * This function is called when FLEXIO CAMERA EDMA receive finished. It disables the CAMERA
  42. * RX EDMA request and sends @ref kStatus_FLEXIO_CAMERA_RxIdle to CAMERA callback.
  43. *
  44. * @param handle The EDMA handle.
  45. * @param param Callback function parameter.
  46. */
  47. static void FLEXIO_CAMERA_TransferReceiveEDMACallback(edma_handle_t *handle,
  48. void *param,
  49. bool transferDone,
  50. uint32_t tcds);
  51. /*******************************************************************************
  52. * Code
  53. ******************************************************************************/
  54. static void FLEXIO_CAMERA_TransferReceiveEDMACallback(edma_handle_t *handle,
  55. void *param,
  56. bool transferDone,
  57. uint32_t tcds)
  58. {
  59. flexio_camera_edma_private_handle_t *cameraPrivateHandle = (flexio_camera_edma_private_handle_t *)param;
  60. /* Avoid the warning for unused variables. */
  61. handle = handle;
  62. tcds = tcds;
  63. if (transferDone)
  64. {
  65. FLEXIO_CAMERA_TransferAbortReceiveEDMA(cameraPrivateHandle->base, cameraPrivateHandle->handle);
  66. if (cameraPrivateHandle->handle->callback != NULL)
  67. {
  68. cameraPrivateHandle->handle->callback(cameraPrivateHandle->base, cameraPrivateHandle->handle,
  69. kStatus_FLEXIO_CAMERA_RxIdle, cameraPrivateHandle->handle->userData);
  70. }
  71. }
  72. }
  73. /*!
  74. * brief Initializes the Camera handle, which is used in transactional functions.
  75. *
  76. * param base Pointer to the FLEXIO_CAMERA_Type.
  77. * param handle Pointer to flexio_camera_edma_handle_t structure.
  78. * param callback The callback function.
  79. * param userData The parameter of the callback function.
  80. * param rxEdmaHandle User requested DMA handle for RX DMA transfer.
  81. * retval kStatus_Success Successfully create the handle.
  82. * retval kStatus_OutOfRange The FlexIO Camera eDMA type/handle table out of range.
  83. */
  84. status_t FLEXIO_CAMERA_TransferCreateHandleEDMA(FLEXIO_CAMERA_Type *base,
  85. flexio_camera_edma_handle_t *handle,
  86. flexio_camera_edma_transfer_callback_t callback,
  87. void *userData,
  88. edma_handle_t *rxEdmaHandle)
  89. {
  90. assert(handle != NULL);
  91. uint8_t index;
  92. /* Find the an empty handle pointer to store the handle. */
  93. for (index = 0U; index < (uint8_t)FLEXIO_CAMERA_HANDLE_COUNT; index++)
  94. {
  95. if (s_edmaPrivateHandle[index].base == NULL)
  96. {
  97. s_edmaPrivateHandle[index].base = base;
  98. s_edmaPrivateHandle[index].handle = handle;
  99. break;
  100. }
  101. }
  102. if (index == (uint8_t)FLEXIO_CAMERA_HANDLE_COUNT)
  103. {
  104. return kStatus_OutOfRange;
  105. }
  106. s_edmaPrivateHandle[index].base = base;
  107. s_edmaPrivateHandle[index].handle = handle;
  108. (void)memset(handle, 0, sizeof(*handle));
  109. handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxIdle;
  110. handle->rxEdmaHandle = rxEdmaHandle;
  111. handle->callback = callback;
  112. handle->userData = userData;
  113. /* Configure RX. */
  114. if (rxEdmaHandle != NULL)
  115. {
  116. EDMA_SetCallback(handle->rxEdmaHandle, FLEXIO_CAMERA_TransferReceiveEDMACallback, &s_edmaPrivateHandle);
  117. }
  118. return kStatus_Success;
  119. }
  120. /*!
  121. * brief Receives data using eDMA.
  122. *
  123. * This function receives data using eDMA. This is a non-blocking function, which returns
  124. * right away. When all data is received, the receive callback function is called.
  125. *
  126. * param base Pointer to the FLEXIO_CAMERA_Type.
  127. * param handle Pointer to the flexio_camera_edma_handle_t structure.
  128. * param xfer Camera eDMA transfer structure, see #flexio_camera_transfer_t.
  129. * retval kStatus_Success if succeeded, others failed.
  130. * retval kStatus_CAMERA_RxBusy Previous transfer on going.
  131. */
  132. status_t FLEXIO_CAMERA_TransferReceiveEDMA(FLEXIO_CAMERA_Type *base,
  133. flexio_camera_edma_handle_t *handle,
  134. flexio_camera_transfer_t *xfer)
  135. {
  136. assert(handle->rxEdmaHandle != NULL);
  137. edma_transfer_config_t xferConfig;
  138. status_t status;
  139. /* If previous RX not finished. */
  140. if ((uint8_t)kFLEXIO_CAMERA_RxBusy == handle->rxState)
  141. {
  142. status = kStatus_FLEXIO_CAMERA_RxBusy;
  143. }
  144. else
  145. {
  146. handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxBusy;
  147. /* Prepare transfer. */
  148. EDMA_PrepareTransfer(&xferConfig, (uint32_t *)FLEXIO_CAMERA_GetRxBufferAddress(base), 32,
  149. (uint32_t *)xfer->dataAddress, 32, 32, xfer->dataNum, kEDMA_PeripheralToMemory);
  150. /* Store the initially configured eDMA minor byte transfer count into the FLEXIO CAMERA handle */
  151. handle->nbytes = 32;
  152. /* Submit transfer. */
  153. (void)EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
  154. EDMA_StartTransfer(handle->rxEdmaHandle);
  155. /* Enable CAMERA RX EDMA. */
  156. FLEXIO_CAMERA_EnableRxDMA(base, true);
  157. status = kStatus_Success;
  158. }
  159. return status;
  160. }
  161. /*!
  162. * brief Aborts the receive data which used the eDMA.
  163. *
  164. * This function aborts the receive data which used the eDMA.
  165. *
  166. * param base Pointer to the FLEXIO_CAMERA_Type.
  167. * param handle Pointer to the flexio_camera_edma_handle_t structure.
  168. */
  169. void FLEXIO_CAMERA_TransferAbortReceiveEDMA(FLEXIO_CAMERA_Type *base, flexio_camera_edma_handle_t *handle)
  170. {
  171. assert(handle->rxEdmaHandle != NULL);
  172. /* Disable CAMERA RX EDMA. */
  173. FLEXIO_CAMERA_EnableRxDMA(base, false);
  174. /* Stop transfer. */
  175. EDMA_StopTransfer(handle->rxEdmaHandle);
  176. handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxIdle;
  177. }
  178. /*!
  179. * brief Gets the remaining bytes to be received.
  180. *
  181. * This function gets the number of bytes still not received.
  182. *
  183. * param base Pointer to the FLEXIO_CAMERA_Type.
  184. * param handle Pointer to the flexio_camera_edma_handle_t structure.
  185. * param count Number of bytes sent so far by the non-blocking transaction.
  186. * retval kStatus_Success Succeed get the transfer count.
  187. * retval kStatus_InvalidArgument The count parameter is invalid.
  188. */
  189. status_t FLEXIO_CAMERA_TransferGetReceiveCountEDMA(FLEXIO_CAMERA_Type *base,
  190. flexio_camera_edma_handle_t *handle,
  191. size_t *count)
  192. {
  193. assert(handle->rxEdmaHandle != NULL);
  194. if (NULL == count)
  195. {
  196. return kStatus_InvalidArgument;
  197. }
  198. if ((uint8_t)kFLEXIO_CAMERA_RxBusy == handle->rxState)
  199. {
  200. *count = (handle->rxSize -
  201. (uint32_t)handle->nbytes *
  202. EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel));
  203. }
  204. else
  205. {
  206. *count = handle->rxSize;
  207. }
  208. return kStatus_Success;
  209. }