1 /**
2 ******************************************************************************
3 * @file virt_uart.c
4 * @author MCD Application Team
5 * @brief UART HAL module driver.
6 * This file provides firmware functions to manage an rpmsg endpoint
7 * from user application
8 *
9 *
10 @verbatim
11 ===============================================================================
12 ##### How to use this driver #####
13 ===============================================================================
14 [..]
15 The VIRTUAL UART driver can be used as follows:
16 (#) Initialize the Virtual UART by calling the VIRT_UART_Init() API.
17 (++) create an endpoint. listener on the OpenAMP-rpmsg channel is now enabled.
18 Receive data is now possible if user registers a callback to this VIRTUAL UART instance
19 by calling in providing a callback function when a message is received from
20 remote processor (VIRT_UART_read_cb)
21 OpenAMP MW deals with memory allocation/free and signal events
22 (#) Transmit data on the created rpmsg channel by calling the VIRT_UART_Transmit()
23 (#) Receive data in calling VIRT_UART_RegisterCallback to register user callback
24
25
26 @endverbatim
27 ******************************************************************************
28 * @attention
29 *
30 * <h2><center>© Copyright (c) 2019 STMicroelectronics.
31 * All rights reserved.</center></h2>
32 *
33 * This software component is licensed by ST under BSD 3-Clause license,
34 * the "License"; You may not use this file except in compliance with the
35 * License. You may obtain a copy of the License at:
36 * opensource.org/licenses/BSD-3-Clause
37 *
38 ******************************************************************************
39 */
40
41 /* Includes ------------------------------------------------------------------*/
42 #include "virt_uart.h"
43 #include "metal/utilities.h"
44
45
46 /* Private typedef -----------------------------------------------------------*/
47 /* Private define ------------------------------------------------------------*/
48 /* this string will be sent to remote processor */
49 #define RPMSG_SERVICE_NAME "rpmsg-tty-channel"
50
51 /* Private macro -------------------------------------------------------------*/
52 /* Private variables ---------------------------------------------------------*/
53
VIRT_UART_read_cb(struct rpmsg_endpoint * ept,void * data,size_t len,uint32_t src,void * priv)54 static int VIRT_UART_read_cb(struct rpmsg_endpoint *ept, void *data,
55 size_t len, uint32_t src, void *priv)
56 {
57 VIRT_UART_HandleTypeDef *huart = metal_container_of(ept, VIRT_UART_HandleTypeDef, ept);
58 (void)src;
59
60 huart->pRxBuffPtr = data;
61 huart->RxXferSize = len;
62 if (huart->RxCpltCallback != NULL) {
63 huart->RxCpltCallback(huart);
64 }
65
66 return 0;
67 }
68
VIRT_UART_Init(VIRT_UART_HandleTypeDef * huart)69 VIRT_UART_StatusTypeDef VIRT_UART_Init(VIRT_UART_HandleTypeDef *huart)
70 {
71
72 int status;
73
74 /* Create a endpoint for rmpsg communication */
75
76 status = OPENAMP_create_endpoint(&huart->ept, RPMSG_SERVICE_NAME, RPMSG_ADDR_ANY,
77 VIRT_UART_read_cb, NULL);
78
79 if(status < 0) {
80 return VIRT_UART_ERROR;
81 }
82
83 return VIRT_UART_OK;
84 }
85
VIRT_UART_DeInit(VIRT_UART_HandleTypeDef * huart)86 VIRT_UART_StatusTypeDef VIRT_UART_DeInit (VIRT_UART_HandleTypeDef *huart)
87 {
88 OPENAMP_destroy_ept(&huart->ept);
89
90 return VIRT_UART_OK;
91 }
92
VIRT_UART_RegisterCallback(VIRT_UART_HandleTypeDef * huart,VIRT_UART_CallbackIDTypeDef CallbackID,void (* pCallback)(VIRT_UART_HandleTypeDef * _huart))93 VIRT_UART_StatusTypeDef VIRT_UART_RegisterCallback(VIRT_UART_HandleTypeDef *huart,
94 VIRT_UART_CallbackIDTypeDef CallbackID,
95 void (* pCallback)(VIRT_UART_HandleTypeDef *_huart))
96 {
97 VIRT_UART_StatusTypeDef status = VIRT_UART_OK;
98
99 switch (CallbackID)
100 {
101 case VIRT_UART_RXCPLT_CB_ID :
102 huart->RxCpltCallback = pCallback;
103 break;
104
105 default :
106 /* Return error status */
107 status = VIRT_UART_ERROR;
108 break;
109 }
110 return status;
111 }
112
VIRT_UART_Transmit(VIRT_UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)113 VIRT_UART_StatusTypeDef VIRT_UART_Transmit(VIRT_UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
114 {
115 int res;
116
117 if (Size > (RPMSG_BUFFER_SIZE-16))
118 return VIRT_UART_ERROR;
119
120 res = OPENAMP_send(&huart->ept, pData, Size);
121 if (res <0) {
122 return VIRT_UART_ERROR;
123 }
124
125 return VIRT_UART_OK;
126 }
127