1 /*
2  * Copyright 2020, 2022-2023 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef __FSL_RPMSG_ADAPTER_H__
10 #define __FSL_RPMSG_ADAPTER_H__
11 
12 #if defined(SDK_OS_FREE_RTOS)
13 #include "FreeRTOS.h"
14 #endif
15 
16 /*!
17  * @addtogroup RPMSG_Adapter
18  * @{
19  */
20 
21 /*******************************************************************************
22  * Definitions
23  ******************************************************************************/
24 
25 /*! @brief RPMSG Msaster/Remote role definition (0 - Master, 1 - Remote) */
26 #ifndef HAL_RPMSG_SELECT_ROLE
27 #define HAL_RPMSG_SELECT_ROLE (1U)
28 #endif
29 
30 /*! @brief RPMSG handle size definition */
31 #define HAL_RPMSG_HANDLE_SIZE (52U)
32 
33 #ifndef REMOTE_CORE_BOOT_ADDRESS
34 #define REMOTE_CORE_BOOT_ADDRESS (0x01000000U)
35 #endif
36 
37 #ifndef MAX_EP_COUNT
38 #define MAX_EP_COUNT (5U)
39 #endif
40 
41 #define RPMSG_WAITFOREVER (0xFFFFFFFFU)
42 
43 /*!
44  * @brief Defines the rpmsg handle
45  *
46  * This macro is used to define a 4 byte aligned rpmsg handle.
47  * Then use "(hal_rpmsg_handle_t)name" to get the rpmsg handle.
48  *
49  * The macro should be global and could be optional. You could also define rpmsg handle by yourself.
50  *
51  * This is an example,
52  * @code
53  * RPMSG_HANDLE_DEFINE(rpmsgHandle);
54  * @endcode
55  *
56  * @param name The name string of the rpmsg handle.
57  */
58 #define RPMSG_HANDLE_DEFINE(name) uint32_t name[((HAL_RPMSG_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]
59 
60 /*! @brief The handle of RPMSG adapter */
61 typedef void *hal_rpmsg_handle_t;
62 
63 /*! @brief RPMSG status */
64 typedef enum _hal_rpmsg_status
65 {
66     kStatus_HAL_RpmsgSuccess = 0U,
67     kStatus_HAL_RpmsgError,
68     kStatus_HAL_RpmsgRxBusy,
69     kStatus_HAL_RpmsgTxBusy,
70     kStatus_HAL_RpmsgTxIdle,
71     kStatus_HAL_RpmsgRxIdle,
72     kStatus_HAL_RpmsgTimeout,
73 } hal_rpmsg_status_t;
74 
75 /*! @brief RPMSG return status */
76 typedef enum _hal_rpmsg_return_status
77 {
78     kStatus_HAL_RL_RELEASE = 0U,
79     kStatus_HAL_RL_HOLD,
80 } hal_rpmsg_return_status_t;
81 
82 /*! @brief The callback function of RPMSG adapter.
83  *
84  * @note If Rpmsg RX callback function return kStatus_HAL_RL_RELEASE mode, no need to call HAL_RpmsgFreeRxBuffer.
85  * @note If Rpmsg RX callback function return kStatus_HAL_RL_HOLD mode,then need to call HAL_RpmsgFreeRxBuffer.
86  *
87  */
88 typedef hal_rpmsg_return_status_t (*rpmsg_rx_callback_t)(void *param, uint8_t *data, uint32_t len);
89 
90 /*! @brief The configure structure of RPMSG adapter. */
91 typedef struct _hal_rpmsg_config
92 {
93     uint8_t local_addr;           /* Local address for rx */
94     uint8_t remote_addr;          /* Remote address for tx */
95     rpmsg_rx_callback_t callback; /* RPMGS Rx callback  */
96     void *param;                  /* RPMGS Rx callback parameter */
97     uint8_t imuLink;
98 } hal_rpmsg_config_t;
99 
100 /*******************************************************************************
101  * API
102  ******************************************************************************/
103 
104 #if defined(__cplusplus)
105 extern "C" {
106 #endif /* _cplusplus */
107 
108 /*!
109  * @brief Initializes the RPMSG adapter module for dual core communication.
110  *
111  * @note This API should be called at the beginning of the application using the RPMSG adapter driver.
112  *
113  * @retval kStatus_HAL_RpmsgSuccess RPMSG module initialize succeed.
114  */
115 hal_rpmsg_status_t HAL_RpmsgMcmgrInit(void);
116 
117 /*!
118  * @brief Initializes the RPMSG adapter for RPMSG channel configure.
119  *
120  * @note This API should be called to software RPMSG communication configure, and it be
121  * called whenever application need it.
122  *
123  * @param handle Pointer to point to a memory space of size #HAL_RPMSG_HANDLE_SIZE allocated by the caller.
124  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
125  * You can define the handle in the following two ways:
126  * #RPMSG_HANDLE_DEFINE(handle);
127  * or
128  * uint32_t handle[((HAL_RPMSG_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
129  * @param config           Used for config local/remote endpoint addr.
130  * @retval kStatus_HAL_RpmsgSuccess RPMSG module initialize succeed.
131  */
132 hal_rpmsg_status_t HAL_RpmsgInit(hal_rpmsg_handle_t handle, hal_rpmsg_config_t *config);
133 
134 /*!
135  * @brief DeInitilizate the RPMSG adapter module.
136  *
137  * @note This API should be called when not using the RPMSG adapter driver anymore.
138  *
139  * @param handle           RPMSG handle pointer.
140  * @retval kStatus_HAL_RpmsgSuccess RPMSG module deinitialize succeed.
141  */
142 hal_rpmsg_status_t HAL_RpmsgDeinit(hal_rpmsg_handle_t handle);
143 
144 /*!
145  * @brief Send data to another RPMSG module with timeout.
146  *
147  * This function will send a specified length of data to another core by RPMSG.
148  *
149  * @note This API should be called to send data.
150  *
151  * @param handle           RPMSG handle pointer.
152  * @param data             Pointer to where the send data from.
153  * @param length           The send data length.
154  * @param timeout          Timeout in ms, 0 if nonblocking, RPMSG_WAITFOREVER for wait for forever.
155  * @retval kStatus_HAL_RpmsgSuccess RPMSG send data succeed.
156  */
157 hal_rpmsg_status_t HAL_RpmsgSendTimeout(hal_rpmsg_handle_t handle, uint8_t *data, uint32_t length, uint32_t timeout);
158 
159 /*!
160  * @brief Send data to another RPMSG module.
161  *
162  * This function will send a specified length of data to another core by RPMSG.
163  *
164  * @note This API should be called to send data.
165  *
166  * @param handle           RPMSG handle pointer.
167  * @param data             Pointer to where the send data from.
168  * @param length           The send data length.
169  * @retval kStatus_HAL_RpmsgSuccess RPMSG send data succeed.
170  */
171 hal_rpmsg_status_t HAL_RpmsgSend(hal_rpmsg_handle_t handle, uint8_t *data, uint32_t length);
172 
173 /*!
174  * @brief Allocates the tx buffer for message payload with timeout.
175  *
176  * This API can only be called at process context to get the tx buffer in vring. By this way, the
177  * application can directly put its message into the vring tx buffer without copy from an application buffer.
178  * It is the application responsibility to correctly fill the allocated tx buffer by data and passing correct
179  * parameters to the rpmsg_lite_send_nocopy() function to perform data no-copy-send mechanism.
180  *
181  *
182  * @param handle           RPMSG handle pointer.
183  * @param size             The send data length.
184  * @param timeout          Timeout in ms, 0 if nonblocking, RPMSG_WAITFOREVER for wait for forever.
185  * @retval The tx buffer address on success and RL_NULL on failure.
186  */
187 void *HAL_RpmsgAllocTxBufferTimeout(hal_rpmsg_handle_t handle, uint32_t size, uint32_t timeout);
188 
189 /*!
190  * @brief Allocates the tx buffer for message payload.
191  *
192  * This API can only be called at process context to get the tx buffer in vring. By this way, the
193  * application can directly put its message into the vring tx buffer without copy from an application buffer.
194  * It is the application responsibility to correctly fill the allocated tx buffer by data and passing correct
195  * parameters to the rpmsg_lite_send_nocopy() function to perform data no-copy-send mechanism.
196  *
197  *
198  * @param handle           RPMSG handle pointer.
199  * @param size           The send data length.
200  * @retval The tx buffer address on success and RL_NULL on failure.
201  */
202 void *HAL_RpmsgAllocTxBuffer(hal_rpmsg_handle_t handle, uint32_t size);
203 
204 /*!
205  * @brief Send data with NoCopy to another RPMSG module.
206  *
207  * This function will send a specified length of data to another core by RPMSG.
208  * This function sends txbuf of length len to the remote dst address,
209  * and uses ept->addr as the source address.
210  * The application has to take the responsibility for:
211  *  1. tx buffer allocation (HAL_RpmsgAllocTxBuffer())
212  *  2. filling the data to be sent into the pre-allocated tx buffer
213  *  3. not exceeding the buffer size when filling the data
214  *  4. data cache coherency
215  *
216  * After the HAL_RpmsgNoCopySend() function is issued the tx buffer is no more owned
217  * by the sending task and must not be touched anymore unless the HAL_RpmsgNoCopySend()
218  * function fails and returns an error.
219  *
220  * @note This API should be called to send data.
221  *
222  * @param handle           RPMSG handle pointer.
223  * @param data             Pointer to where the send data from.
224  * @param length           The send data length.
225  * @retval kStatus_HAL_RpmsgSuccess RPMSG send data succeed.
226  */
227 hal_rpmsg_status_t HAL_RpmsgNoCopySend(hal_rpmsg_handle_t handle, uint8_t *data, uint32_t length);
228 
229 /*!
230  * @brief Releases the rx buffer for future reuse in vring.
231  * This API can be called at process context when the
232  * message in rx buffer is processed.
233  *
234  * @note The HAL_RpmsgFreeRxBuffer need be called only if Rpmsg RX callback function return kStatus_HAL_RL_HOLD mode.
235  *
236  * @param handle           RPMSG handle pointer.
237  * @param data             Pointer to where the received data from perr.
238 
239  *
240  * @return Status of function execution, RL_SUCCESS on success.
241  */
242 hal_rpmsg_status_t HAL_RpmsgFreeRxBuffer(hal_rpmsg_handle_t handle, uint8_t *data);
243 
244 /*!
245  * @brief Install RPMSG rx callback.
246  *
247  * @note The function must be called because rpmsg adapter just support asynchronous receive mode
248  *        should make sure the callback function is installed before the data received from peer soc,
249  *        and the rx callback function will be called when the rx process complete.
250  *
251  *
252  * @param handle    RPMSG handle pointer.
253  * @retval kStatus_HAL_RpmsgSuccess RPMSG install rx callback succeed.
254  */
255 hal_rpmsg_status_t HAL_RpmsgInstallRxCallback(hal_rpmsg_handle_t handle, rpmsg_rx_callback_t callback, void *param);
256 
257 /*!
258  * @brief Prepares to enter low power consumption.
259  *
260  * This function is used to prepare to enter low power consumption.
261  *
262  * @param handle           RPMSG handle pointer.
263  * @retval kStatus_HAL_RpmsgSuccess Successful operation.
264  * @retval kStatus_HAL_RpmsgError An error occurred.
265  */
266 hal_rpmsg_status_t HAL_RpmsgEnterLowpower(hal_rpmsg_handle_t handle);
267 
268 /*!
269  * @brief Prepares to exit low power consumption.
270  *
271  * This function is used to restore from low power consumption.
272  *
273  * @param handle           RPMSG handle pointer.
274  * @retval kStatus_HAL_RpmsgSuccess Successful operation.
275  * @retval kStatus_HAL_RpmsgError An error occurred.
276  */
277 hal_rpmsg_status_t HAL_RpmsgExitLowpower(hal_rpmsg_handle_t handle);
278 
279 /*! @}*/
280 
281 #if defined(__cplusplus)
282 }
283 #endif
284 /*! @}*/
285 #endif /* __FSL_RPMSG_ADAPTER_H__ */
286