This repository has been archived by the owner on Nov 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 99
/
u_port_uart.h
470 lines (431 loc) · 19.5 KB
/
u_port_uart.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
/*
* Copyright 2019-2024 u-blox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _U_PORT_UART_H_
#define _U_PORT_UART_H_
/* Only header files representing a direct and unavoidable
* dependency between the API of this module and the API
* of another module should be included here; otherwise
* please keep #includes to your .c files. */
/** \addtogroup __port
* @{
*/
/** @file
* @brief Porting layer for UART access functions. These functions
* are thread-safe unless otherwise stated.
*/
/* NOTE TO MAINTAINERS: there is a virtualised version of this
* in the form of u_device_serial.h over in the uDevice API:
* if you add or amend the API here you may need to make the
* same change there.
*/
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------------------------------------------
* COMPILE-TIME MACROS
* -------------------------------------------------------------- */
#ifndef U_PORT_UART_EVENT_QUEUE_SIZE
/** The UART event queue size.
*/
# define U_PORT_UART_EVENT_QUEUE_SIZE 20
#endif
#ifndef U_PORT_UART_WRITE_TIMEOUT_MS
/** uPortUartWrite() should always succeed in sending all characters;
* however, when flow control is enabled, it is possible that the
* receiving UART at the far end blocks transmission, potentially
* indefinitely, causing uPortUartWrite() to hang. It is not
* desirable to cause the whole application to fail because of an
* IO function; this [deliberately very large] defensive time-out
* may be employed by an implementation of uPortUartWrite()
* as a guard against that.
*/
# define U_PORT_UART_WRITE_TIMEOUT_MS 30000
#endif
/** The event which means that received data is available; this
* will be sent if the receive buffer goes from empty to containing
* one or more bytes of received data. It is used as a bit-mask.
* It is the only U_PORT_UART_EVENT_BITMASK_xxx currently supported.
*/
#define U_PORT_UART_EVENT_BITMASK_DATA_RECEIVED 0x01
#ifndef U_PORT_UART_PREFIX
/** The UART prefix to use, on platforms where such a prefix
* is employed (for example Linux).
*/
# define U_PORT_UART_PREFIX "/dev/ttyUSB"
#endif
#ifndef U_PORT_UART_MAX_PREFIX_LENGTH
/** The maximum length of the string passed to uPortUartPrefix(),
* not including the null terminator (what strlen() would return).
*/
# define U_PORT_UART_MAX_PREFIX_LENGTH 32
#endif
/* ----------------------------------------------------------------
* TYPES
* -------------------------------------------------------------- */
/* ----------------------------------------------------------------
* FUNCTIONS
* -------------------------------------------------------------- */
/** Initialise UART handling. THERE IS NO NEED FOR THE USER
* TO CALL THIS: it is called by uPortInit().
*
* @return zero on success else negative error code.
*/
int32_t uPortUartInit();
/** Shutdown UART handling. THERE IS NO NEED FOR THE USER
* TO CALL THIS: it is called by uPortDeinit().
*/
void uPortUartDeinit();
/** Set the uart name prefix to be used in the next call to
* uPortUartOpen(). This is NOT thread-safe.
*
* On some platforms this name will prefix the uart parameter
* passed to uPortUartOpen(); for example a prefix of "/dev/tty"
* with a uart value of 3 will result in device "/dev/tty3"
* being opened as a UART. If the uart parameter passed to
* uPortUartOpen() is < 0 then only the prefix will be used
* (e.g. "/dev/tty").
*
* This is currently only applicable for the Linux port.
* The default prefix if this function is not called will be
* #U_PORT_UART_PREFIX.
*
* @param[in] pPrefix a pointer to a string containing the name
* prefix, up to #U_PORT_UART_MAX_PREFIX_LENGTH
* characters long.
* @return zero on success else negative error code.
*/
int32_t uPortUartPrefix(const char *pPrefix);
/** Open a UART instance. If a UART instance has already
* been opened on the given UART HW block this function returns
* an error. Note that the pin numbers are those of the MCU:
* if you are using an MCU inside a u-blox module the IO pin
* numbering for the module is likely different to that from
* the MCU: check the data sheet for the module to determine
* the mapping.
*
* IMPORTANT: some platforms, specifically Zephyr, used on NRF53,
* do not permit UART pin choices to be made at run-time, only at
* compile time. For such platforms the pins passed in here MUST
* be -1 (otherwise an error will be returned) and you MUST check
* the README.md for that platform to find out how the pins
* are chosen.
*
* SPECIAL CASE FOR STM32U5: you may employ the single LPUART
* on STM32U5 platform by specifying uart 0 (the "normal" UARTs on
* STM32U5 platform start at HW block 1).
*
* @param uart the UART HW block to use.
* @param baudRate the baud rate to use.
* @param[in] pReceiveBuffer a receive buffer to use,
* should be NULL and a buffer
* will be allocated by the driver.
* If non-NULL then the given buffer
* will be used, however some
* platforms (e.g. ESP32) currently
* do not support passing in a buffer
* (an error will be returned) so to be
* platform independent NULL must
* be used.
* @param receiveBufferSizeBytes the amount of memory to allocate
* for the receive buffer. If
* pReceiveBuffer is not NULL
* then this is the amount of
* memory at pReceiveBuffer.
* @param pinTx the transmit (output) pin,
* a positive integer or -1 if the
* pin choice has already been
* determined at compile time,
* or is irrelevant (for example on
* Zephyr, Windows or Linux).
* @param pinRx the receive (input) pin,
* a positive integer or -1 if the
* pin choice has already been
* determined at compile time (for
* example on Zephyr, Windows or
* Linux).
* @param pinCts the CTS (input) flow control pin,
* asserted by the modem when it is
* ready to receive data; use -1
* for none or if the pin choice has
* already been determined at compile
* time (for example on Zephr). On some
* platforms where no pin selection
* can be made at run-time (e.g. Windows
* and Linux) this is simply treated
* as a flag where a negative value
* means no CTS flow control and a
* non-negative value means CTS flow
* control.
* @param pinRts the RTS (output) flow control pin,
* asserted when we are ready to
* receive data from the modem;
* use -1 for none or if the pin
* choice has already been determined
* at compile time (for example on
* Zephyr). On some platforms where
* no pin selection can be made at
* run-time (e.g. Windows and Linux)
* this is simply treated as a flag
* where a negative value means
* no RTS flow control and a
* non-negative value means RTS flow
* control.
* @return a UART handle else negative
* error code.
*/
int32_t uPortUartOpen(int32_t uart, int32_t baudRate,
void *pReceiveBuffer,
size_t receiveBufferSizeBytes,
int32_t pinTx, int32_t pinRx,
int32_t pinCts, int32_t pinRts);
/** Close a UART. Note that this should NOT be called if
* a UART read or write could be in progress.
*
* Note: when a UART is closed not all memory associated with it
* is immediately reclaimed; if you wish to reclaim memory before
* uPortDeinit() you may do so by calling uPortEventQueueCleanUp().
*
* @param handle the handle of the UART instance to close.
*/
void uPortUartClose(int32_t handle);
/** Get the number of bytes waiting in the receive buffer
* of a UART instance.
*
* @param handle the handle of the UART instance.
* @return the number of bytes in the receive buffer
* or negative error code.
*/
int32_t uPortUartGetReceiveSize(int32_t handle);
/** Read from the given UART instance, non-blocking:
* up to sizeBytes of data already in the UART buffer will
* be returned.
*
* @param handle the handle of the UART instance.
* @param[out] pBuffer a pointer to a buffer in which to store
* received bytes.
* @param sizeBytes the size of buffer pointed to by pBuffer.
* @return the number of bytes received else negative
* error code.
*/
int32_t uPortUartRead(int32_t handle, void *pBuffer,
size_t sizeBytes);
/** Write to the given UART interface. Will block until
* all of the data has been written or an error has occurred.
*
* @param handle the handle of the UART instance.
* @param[in] pBuffer a pointer to a buffer of data to send.
* @param sizeBytes the number of bytes in pBuffer.
* @return the number of bytes sent or negative
* error code.
*/
int32_t uPortUartWrite(int32_t handle, const void *pBuffer,
size_t sizeBytes);
/** Set a callback to be called when a UART event occurs.
* pFunction will be called asynchronously in its own task,
* for which the stack size and priority can be specified.
* Only one callback may be set per UART instance; the
* callback receives the UART handle as its first parameter
* and the event bit-map as its second parameter. If a
* callback has already been set for a UART instance this
* function will return an error.
*
* @param handle the handle of the UART instance.
* @param filter a bit-mask to filter the events
* on which pFunction will be called.
* 1 in a bit position means include
* that event, 0 means don't; at least
* one bit must be set. Select bits
* from one or more of
* U_PORT_UART_EVENT_BITMASK_xxx or
* set all bits to enable everything.
* @param[in] pFunction the function to call, cannot be
* NULL.
* @param[in] pParam a parameter which will be passed
* to pFunction as its last parameter
* when it is called.
* @param stackSizeBytes the number of bytes of stack for
* the task in which pFunction is
* called, must be at least
* #U_PORT_EVENT_QUEUE_MIN_TASK_STACK_SIZE_BYTES.
* @param priority the priority of the task in which
* pFunction is called; see
* u_cfg_os_platform_specific.h for
* your platform for more information.
* The default application, for instance,
* runs at U_CFG_OS_APP_TASK_PRIORITY,
* so if you want pFunction to be
* scheduled before it you might set a
* priority of
* U_CFG_OS_APP_TASK_PRIORITY + 1.
* @return zero on success else negative error
* code.
*/
int32_t uPortUartEventCallbackSet(int32_t handle,
uint32_t filter,
void (*pFunction)(int32_t, uint32_t,
void *),
void *pParam,
size_t stackSizeBytes,
int32_t priority);
/** Remove a UART event callback.
*
* NOTE: under the hood, this function likely calls
* uPortEventQueueClose() - PLEASE READ THE NOTE against
* that function concerning the potential for mutex lock-ups
* in the design of your re-entrancy protection. You might
* use the pParam context pointer that is passed to the event
* callback (see uPortUartEventCallbackSet()) to inform your
* callback when it is being shut-down, and hence avoid such
* mutex lock-up issues.
*
* @param handle the handle of the UART instance for
* which the callback is to be removed.
*/
void uPortUartEventCallbackRemove(int32_t handle);
/** Get the filter for which a callback is currently set.
* This can be used to determine whether a callback is
* set: if a callback is not set the return value will be
* zero.
*
* @param handle the handle of the UART instance.
* @return the filter bit-mask for the currently set
* callback.
*/
uint32_t uPortUartEventCallbackFilterGet(int32_t handle);
/** Change the callback filter bit-mask. If no event
* callback is set an error will be returned.
*
* @param handle the handle of the UART instance.
* @param filter the new filter bit-mask, must be non-zero.
* @return zero on success else negative error code.
*/
int32_t uPortUartEventCallbackFilterSet(int32_t handle,
uint32_t filter);
/** Send an event to the callback. This allows the user to
* re-trigger events: for instance, if a data event has only
* been partially handled it can be re-triggered by calling
* this function with #U_PORT_UART_EVENT_BITMASK_DATA_RECEIVED
* set. This call will block until there is room in the queue
* to send the event; if you want the function to return
* if there is no room in the queue to send the event then use
* uPortUartEventTrySend() instead
*
* @param handle the handle of the UART instance.
* @param eventBitMap the events bit-map with at least one of
* U_PORT_UART_EVENT_BITMASK_xxx set.
* @return zero on success else negative error code.
*/
int32_t uPortUartEventSend(int32_t handle, uint32_t eventBitMap);
/** Send an event to the callback, returning if there is no
* room in the queue to send the event within the given time.
* This allows the user to re-trigger events: for instance,
* if a data event has only been partially handled it can be
* re-triggered by calling this function with
* #U_PORT_UART_EVENT_BITMASK_DATA_RECEIVED set. Note that NOT
* ALL PLATFORMS support this API: where it is not implemented
* #U_ERROR_COMMON_NOT_IMPLEMENTED or #U_ERROR_COMMON_NOT_SUPPORTED
* should be returned.
*
* @param handle the handle of the UART instance.
* @param eventBitMap the events bit-map with at least one of
* U_PORT_UART_EVENT_BITMASK_xxx set.
* @param delayMs the maximum time to wait in milliseconds.
* @return zero on success else negative error code.
*/
int32_t uPortUartEventTrySend(int32_t handle,
uint32_t eventBitMap,
int32_t delayMs);
/** Detect whether the task currently executing is the
* event callback for this UART. Useful if you have code which
* is called a few levels down from the callback both by
* event code and other code and needs to know which context it
* is in.
*
* @param handle the handle of the UART instance.
* @return true if the current task is the event
* callback for this UART, else false.
*/
bool uPortUartEventIsCallback(int32_t handle);
/** Get the stack high watermark, the minimum amount of
* free stack, in bytes, for the task at the end of the event
* queue.
*
* @param handle the handle of the UART instance.
* @return the minimum amount of free stack for the
* lifetime of the task at the end of the event
* queue in bytes, else negative error code.
*/
int32_t uPortUartEventStackMinFree(int32_t handle);
/** Determine if RTS flow control, that is a signal from
* the module to this software that the module is ready to
* receive data, is enabled.
*
* @param handle the handle of the UART instance.
* @return true if RTS flow control is enabled
* on this UART, else false.
*/
bool uPortUartIsRtsFlowControlEnabled(int32_t handle);
/** Determine if CTS flow control, that is a signal from
* this software to the module that this sofware is ready
* to accept data, is enabled. Note that this returns
* true even if CTS flow control is currently suspended
* by a call to uPortUartCtsSuspend().
*
* @param handle the handle of the UART instance.
* @return true if CTS flow control is enabled
* on this UART, else false.
*/
bool uPortUartIsCtsFlowControlEnabled(int32_t handle);
/** Suspend CTS flow control. This is useful if the device
* on the other end of the UART can enter a sleep state during
* which the CTS line may float such as to prevent the UART
* from communicating with the device. When that happens, this
* function may be called while the device is revived from
* sleep state (e.g. by sending it "wake-up" characters), then
* CTS flow control should be resumed afterwards with a call to
* uPortUartCtsResume(). This function may NOT be supported on all
* platforms; where it is not supported the function will return
* #U_ERROR_COMMON_NOT_SUPPORTED.
* If suspension of CTS is supported but CTS flow control is
* not being used this function will return successfully.
*
* @param handle the handle of the UART instance.
* @return zero on success else negative error code.
*/
int32_t uPortUartCtsSuspend(int32_t handle);
/** Resume CTS flow control; should be called after
* uPortUartCtsSuspend() to resume normal flow control operation.
* This function must be supported if uPortUartCtsSuspend() is
* supported. Where uPortUartCtsSuspend() is not supported
* this function may still be called but will have no effect.
*
* @param handle the handle of the UART instance.
*/
void uPortUartCtsResume(int32_t handle);
/** Get the number of UART interfaces currently open; this may be
* used as a basic check for heap monitoring.
*
* You do not need to implement this function: where it is not
* implemented a #U_WEAK implementation provided in u_port_resource.c
* will return zero.
*/
int32_t uPortUartResourceAllocCount();
#ifdef __cplusplus
}
#endif
/** @}*/
#endif // _U_PORT_UART_H_
// End of file