Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

353 lignes
11 KiB

  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_uart_freertos.h"
  9. #include <FreeRTOS.h>
  10. #include <event_groups.h>
  11. #include <semphr.h>
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.uart_freertos"
  15. #endif
  16. static void UART_RTOS_Callback(UART_Type *base, uart_handle_t *state, status_t status, void *param)
  17. {
  18. uart_rtos_handle_t *handle = (uart_rtos_handle_t *)param;
  19. BaseType_t xHigherPriorityTaskWoken, xResult;
  20. xHigherPriorityTaskWoken = pdFALSE;
  21. xResult = pdFAIL;
  22. if (status == kStatus_UART_RxIdle)
  23. {
  24. xResult = xEventGroupSetBitsFromISR(handle->rxEvent, RTOS_UART_COMPLETE, &xHigherPriorityTaskWoken);
  25. }
  26. else if (status == kStatus_UART_TxIdle)
  27. {
  28. xResult = xEventGroupSetBitsFromISR(handle->txEvent, RTOS_UART_COMPLETE, &xHigherPriorityTaskWoken);
  29. }
  30. else if (status == kStatus_UART_RxRingBufferOverrun)
  31. {
  32. xResult = xEventGroupSetBitsFromISR(handle->rxEvent, RTOS_UART_RING_BUFFER_OVERRUN, &xHigherPriorityTaskWoken);
  33. }
  34. else if (status == kStatus_UART_RxHardwareOverrun)
  35. {
  36. /* Clear Overrun flag (OR) in UART S1 register */
  37. UART_ClearStatusFlags(base, kUART_RxOverrunFlag);
  38. xResult =
  39. xEventGroupSetBitsFromISR(handle->rxEvent, RTOS_UART_HARDWARE_BUFFER_OVERRUN, &xHigherPriorityTaskWoken);
  40. }
  41. if (xResult != pdFAIL)
  42. {
  43. portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
  44. }
  45. }
  46. /*FUNCTION**********************************************************************
  47. *
  48. * Function Name : UART_RTOS_Init
  49. * Description : Initializes the UART instance for application
  50. *
  51. *END**************************************************************************/
  52. /*!
  53. * brief Initializes a UART instance for operation in RTOS.
  54. *
  55. * param handle The RTOS UART handle, the pointer to an allocated space for RTOS context.
  56. * param t_handle The pointer to the allocated space to store the transactional layer internal state.
  57. * param cfg The pointer to the parameters required to configure the UART after initialization.
  58. * return kStatus_Success, otherwise fail.
  59. */
  60. int UART_RTOS_Init(uart_rtos_handle_t *handle, uart_handle_t *t_handle, const uart_rtos_config_t *cfg)
  61. {
  62. uart_config_t defcfg;
  63. if (NULL == handle)
  64. {
  65. return kStatus_InvalidArgument;
  66. }
  67. if (NULL == t_handle)
  68. {
  69. return kStatus_InvalidArgument;
  70. }
  71. if (NULL == cfg)
  72. {
  73. return kStatus_InvalidArgument;
  74. }
  75. if (NULL == cfg->base)
  76. {
  77. return kStatus_InvalidArgument;
  78. }
  79. if (0 == cfg->srcclk)
  80. {
  81. return kStatus_InvalidArgument;
  82. }
  83. if (0 == cfg->baudrate)
  84. {
  85. return kStatus_InvalidArgument;
  86. }
  87. handle->base = cfg->base;
  88. handle->t_state = t_handle;
  89. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  90. handle->txSemaphore = xSemaphoreCreateMutexStatic(&handle->txSemaphoreBuffer);
  91. #else
  92. handle->txSemaphore = xSemaphoreCreateMutex();
  93. #endif
  94. if (NULL == handle->txSemaphore)
  95. {
  96. return kStatus_Fail;
  97. }
  98. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  99. handle->rxSemaphore = xSemaphoreCreateMutexStatic(&handle->rxSemaphoreBuffer);
  100. #else
  101. handle->rxSemaphore = xSemaphoreCreateMutex();
  102. #endif
  103. if (NULL == handle->rxSemaphore)
  104. {
  105. vSemaphoreDelete(handle->txSemaphore);
  106. return kStatus_Fail;
  107. }
  108. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  109. handle->txEvent = xEventGroupCreateStatic(&handle->txEventBuffer);
  110. #else
  111. handle->txEvent = xEventGroupCreate();
  112. #endif
  113. if (NULL == handle->txEvent)
  114. {
  115. vSemaphoreDelete(handle->rxSemaphore);
  116. vSemaphoreDelete(handle->txSemaphore);
  117. return kStatus_Fail;
  118. }
  119. #if (configSUPPORT_STATIC_ALLOCATION == 1)
  120. handle->rxEvent = xEventGroupCreateStatic(&handle->rxEventBuffer);
  121. #else
  122. handle->rxEvent = xEventGroupCreate();
  123. #endif
  124. if (NULL == handle->rxEvent)
  125. {
  126. vEventGroupDelete(handle->txEvent);
  127. vSemaphoreDelete(handle->rxSemaphore);
  128. vSemaphoreDelete(handle->txSemaphore);
  129. return kStatus_Fail;
  130. }
  131. UART_GetDefaultConfig(&defcfg);
  132. defcfg.baudRate_Bps = cfg->baudrate;
  133. defcfg.parityMode = cfg->parity;
  134. #if defined(FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT
  135. defcfg.stopBitCount = cfg->stopbits;
  136. #endif
  137. UART_Init(handle->base, &defcfg, cfg->srcclk);
  138. UART_TransferCreateHandle(handle->base, handle->t_state, UART_RTOS_Callback, handle);
  139. UART_TransferStartRingBuffer(handle->base, handle->t_state, cfg->buffer, cfg->buffer_size);
  140. UART_EnableTx(handle->base, true);
  141. UART_EnableRx(handle->base, true);
  142. return kStatus_Success;
  143. }
  144. /*FUNCTION**********************************************************************
  145. *
  146. * Function Name : UART_RTOS_Deinit
  147. * Description : Deinitializes the UART instance and frees resources
  148. *
  149. *END**************************************************************************/
  150. /*!
  151. * brief Deinitializes a UART instance for operation.
  152. *
  153. * This function deinitializes the UART module, sets all register values to reset value,
  154. * and frees the resources.
  155. *
  156. * param handle The RTOS UART handle.
  157. */
  158. int UART_RTOS_Deinit(uart_rtos_handle_t *handle)
  159. {
  160. UART_Deinit(handle->base);
  161. vEventGroupDelete(handle->txEvent);
  162. vEventGroupDelete(handle->rxEvent);
  163. /* Give the semaphore. This is for functional safety */
  164. xSemaphoreGive(handle->txSemaphore);
  165. xSemaphoreGive(handle->rxSemaphore);
  166. vSemaphoreDelete(handle->txSemaphore);
  167. vSemaphoreDelete(handle->rxSemaphore);
  168. /* Invalidate the handle */
  169. handle->base = NULL;
  170. handle->t_state = NULL;
  171. return kStatus_Success;
  172. }
  173. /*FUNCTION**********************************************************************
  174. *
  175. * Function Name : UART_RTOS_Send
  176. * Description : Initializes the UART instance for application
  177. *
  178. *END**************************************************************************/
  179. /*!
  180. * brief Sends data in the background.
  181. *
  182. * This function sends data. It is a synchronous API.
  183. * If the hardware buffer is full, the task is in the blocked state.
  184. *
  185. * param handle The RTOS UART handle.
  186. * param buffer The pointer to the buffer to send.
  187. * param length The number of bytes to send.
  188. */
  189. int UART_RTOS_Send(uart_rtos_handle_t *handle, const uint8_t *buffer, uint32_t length)
  190. {
  191. EventBits_t ev;
  192. int retval = kStatus_Success;
  193. if (NULL == handle->base)
  194. {
  195. /* Invalid handle. */
  196. return kStatus_Fail;
  197. }
  198. if (0 == length)
  199. {
  200. return kStatus_Success;
  201. }
  202. if (NULL == buffer)
  203. {
  204. return kStatus_InvalidArgument;
  205. }
  206. if (pdFALSE == xSemaphoreTake(handle->txSemaphore, 0))
  207. {
  208. /* We could not take the semaphore, exit with 0 data received */
  209. return kStatus_Fail;
  210. }
  211. handle->txTransfer.data = (uint8_t *)buffer;
  212. handle->txTransfer.dataSize = (uint32_t)length;
  213. /* Non-blocking call */
  214. UART_TransferSendNonBlocking(handle->base, handle->t_state, &handle->txTransfer);
  215. ev = xEventGroupWaitBits(handle->txEvent, RTOS_UART_COMPLETE, pdTRUE, pdFALSE, portMAX_DELAY);
  216. if (!(ev & RTOS_UART_COMPLETE))
  217. {
  218. retval = kStatus_Fail;
  219. }
  220. if (pdFALSE == xSemaphoreGive(handle->txSemaphore))
  221. {
  222. /* We could not post the semaphore, exit with error */
  223. retval = kStatus_Fail;
  224. }
  225. return retval;
  226. }
  227. /*FUNCTION**********************************************************************
  228. *
  229. * Function Name : UART_RTOS_Recv
  230. * Description : Receives chars for the application
  231. *
  232. *END**************************************************************************/
  233. /*!
  234. * brief Receives data.
  235. *
  236. * This function receives data from UART. It is a synchronous API. If data is immediately available,
  237. * it is returned immediately and the number of bytes received.
  238. *
  239. * param handle The RTOS UART handle.
  240. * param buffer The pointer to the buffer to write received data.
  241. * param length The number of bytes to receive.
  242. * param received The pointer to a variable of size_t where the number of received data is filled.
  243. */
  244. int UART_RTOS_Receive(uart_rtos_handle_t *handle, uint8_t *buffer, uint32_t length, size_t *received)
  245. {
  246. EventBits_t ev;
  247. size_t n = 0;
  248. int retval = kStatus_Fail;
  249. size_t local_received = 0;
  250. if (NULL == handle->base)
  251. {
  252. /* Invalid handle. */
  253. return kStatus_Fail;
  254. }
  255. if (0 == length)
  256. {
  257. if (received != NULL)
  258. {
  259. *received = n;
  260. }
  261. return kStatus_Success;
  262. }
  263. if (NULL == buffer)
  264. {
  265. return kStatus_InvalidArgument;
  266. }
  267. /* New transfer can be performed only after current one is finished */
  268. if (pdFALSE == xSemaphoreTake(handle->rxSemaphore, portMAX_DELAY))
  269. {
  270. /* We could not take the semaphore, exit with 0 data received */
  271. return kStatus_Fail;
  272. }
  273. handle->rxTransfer.data = buffer;
  274. handle->rxTransfer.dataSize = (uint32_t)length;
  275. /* Non-blocking call */
  276. UART_TransferReceiveNonBlocking(handle->base, handle->t_state, &handle->rxTransfer, &n);
  277. ev = xEventGroupWaitBits(handle->rxEvent,
  278. RTOS_UART_COMPLETE | RTOS_UART_RING_BUFFER_OVERRUN | RTOS_UART_HARDWARE_BUFFER_OVERRUN,
  279. pdTRUE, pdFALSE, portMAX_DELAY);
  280. if (ev & RTOS_UART_HARDWARE_BUFFER_OVERRUN)
  281. {
  282. /* Stop data transfer to application buffer, ring buffer is still active */
  283. UART_TransferAbortReceive(handle->base, handle->t_state);
  284. /* Prevent false indication of successful transfer in next call of UART_RTOS_Receive.
  285. RTOS_UART_COMPLETE flag could be set meanwhile overrun is handled */
  286. xEventGroupClearBits(handle->rxEvent, RTOS_UART_COMPLETE);
  287. retval = kStatus_UART_RxHardwareOverrun;
  288. local_received = 0;
  289. }
  290. else if (ev & RTOS_UART_RING_BUFFER_OVERRUN)
  291. {
  292. /* Stop data transfer to application buffer, ring buffer is still active */
  293. UART_TransferAbortReceive(handle->base, handle->t_state);
  294. /* Prevent false indication of successful transfer in next call of UART_RTOS_Receive.
  295. RTOS_UART_COMPLETE flag could be set meanwhile overrun is handled */
  296. xEventGroupClearBits(handle->rxEvent, RTOS_UART_COMPLETE);
  297. retval = kStatus_UART_RxRingBufferOverrun;
  298. local_received = 0;
  299. }
  300. else if (ev & RTOS_UART_COMPLETE)
  301. {
  302. retval = kStatus_Success;
  303. local_received = length;
  304. }
  305. /* Prevent repetitive NULL check */
  306. if (received != NULL)
  307. {
  308. *received = local_received;
  309. }
  310. /* Enable next transfer. Current one is finished */
  311. if (pdFALSE == xSemaphoreGive(handle->rxSemaphore))
  312. {
  313. /* We could not post the semaphore, exit with error */
  314. retval = kStatus_Fail;
  315. }
  316. return retval;
  317. }