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>&copy; 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