summaryrefslogtreecommitdiff
path: root/include/uart.h
blob: e40b0e866f1450a3ff5793dc3df0e1865946dfbc (plain)
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
/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* uart.h - UART module for Chrome EC */

#ifndef __CROS_EC_UART_H
#define __CROS_EC_UART_H

#include <stdarg.h>  /* For va_list */
#include "common.h"
#include "gpio.h"

/**
 * Initialize the UART module.
 */
void uart_init(void);

/**
 * Return non-zero if UART init has completed.
 */
int uart_init_done(void);

/*
 * Output functions
 *
 * Output is buffered.  If the buffer overflows, subsequent output is
 * discarded.
 *
 * Modules should use the output functions in console.h in preference to these
 * routines, so that output can be filtered on a module-by-module basis.
 */

/**
 * Put a single character to the UART, like putchar().
 *
 * @param c		Character to put
 * @return EC_SUCCESS, or non-zero if output was truncated.
 */
int uart_putc(int c);

/**
 * Put a null-terminated string to the UART, like fputs().
 *
 * @return EC_SUCCESS, or non-zero if output was truncated.
 */
int uart_puts(const char *outstr);

/**
 * Print formatted output to the UART, like printf().
 *
 * See printf.h for valid formatting codes.
 *
 * @return EC_SUCCESS, or non-zero if output was truncated.
 */
int uart_printf(const char *format, ...);

/**
 * Print formatted output to the UART, like vprintf().
 *
 * See printf.h for valid formatting codes.
 *
 * @return EC_SUCCESS, or non-zero if output was truncated.
 */
int uart_vprintf(const char *format, va_list args);

/**
 * Flush output.  Blocks until UART has transmitted all output.
 */
void uart_flush_output(void);

/*
 * Input functions
 *
 * Input is buffered.  If the buffer overflows, the oldest input in
 * the buffer is discarded to make room for the new input.
 *
 * Input lines may be terminated by CR ('\r'), LF ('\n'), or CRLF; all
 * are translated to newline.
 */

/**
 * Read a single character of input, similar to fgetc().
 *
 * @return the character, or -1 if no input waiting.
 */
int uart_getc(void);

/*
 * Hardware UART driver functions
 */

/**
 * Flush the transmit FIFO.
 */
void uart_tx_flush(void);

/**
 * Return non-zero if there is room to transmit a character immediately.
 */
int uart_tx_ready(void);

/**
 * Return non-zero if a transmit is in progress.
 */
int uart_tx_in_progress(void);

/**
 * Return non-zero if UART is ready to start a DMA transfer.
 */
int uart_tx_dma_ready(void);

/**
 * Start a UART transmit DMA transfer
 *
 * @param src		Pointer to data to send
 * @param len		Length of transfer in bytes
 */
void uart_tx_dma_start(const char *src, int len);

/**
 * Return non-zero if the UART has a character available to read.
 */
int uart_rx_available(void);

/**
 * Start a UART receive DMA transfer.
 *
 * DMA will be configured in circular buffer mode, so received characters
 * will be stored into the buffer continuously.
 *
 * @param dest		Pointer to destination buffer
 * @param len		Length of buffer in bytes
 */
void uart_rx_dma_start(char *dest, int len);

/**
 * Return the head of the receive DMA transfer buffer
 *
 * This is the next offset in the buffer which will receive a character, and
 * will be from 0..(len-1) where len is the buffer length passed to
 * uart_rx_dma_start().
 */
int uart_rx_dma_head(void);

/**
 * Send a character to the UART data register.
 *
 * If the transmit FIFO is full, blocks until there is space.
 *
 * @param c		Character to send.
 */
void uart_write_char(char c);

/**
 * Read one char from the UART data register.
 *
 * @return		The character read.
 */
int uart_read_char(void);

/**
 * Re-enable the UART transmit interrupt.
 *
 * This also forces triggering a UART interrupt, if the transmit interrupt was
 * disabled.
 */
void uart_tx_start(void);

/**
 * Disable the UART transmit interrupt.
 */
void uart_tx_stop(void);

/**
 * Helper for processing UART input.
 *
 * Reads the input FIFO until empty.  Intended to be called from the driver
 * interrupt handler.
 */
void uart_process_input(void);

/**
 * Helper for processing UART output.
 *
 * Fills the output FIFO until the transmit buffer is empty or the FIFO full.
 * Intended to be called from the driver interrupt handler.
 */
void uart_process_output(void);

/**
 * Return boolean expressing whether UART buffer is empty or not.
 */
int uart_buffer_empty(void);

/**
 * Disable the EC console UART and convert the UART RX pin to a generic GPIO
 * with an edge detect interrupt.
 */
void uart_enter_dsleep(void);

/**
 * Enable the EC console UART after a uart_enter_dsleep().
 */
void uart_exit_dsleep(void);

#ifdef CONFIG_LOW_POWER_IDLE
/**
 * Interrupt handler for UART RX pin transition in deep sleep.
 *
 * @param signal	Signal which triggered the interrupt.
 */
void uart_deepsleep_interrupt(enum gpio_signal signal);
#else
static inline void uart_deepsleep_interrupt(enum gpio_signal signal) { }
#endif /* !CONFIG_LOW_POWER_IDLE */

#if defined(HAS_TASK_CONSOLE) && defined(CONFIG_FORCE_CONSOLE_RESUME)
/**
 * Enable/Disable the UART controller low-power mode wake-up capability.
 *
 * @param enable  1 to enable wake-up, 0 to disable it.
 */
void uart_enable_wakeup(int enable);
#elif !defined(CHIP_FAMILY_NPCX5)
static inline void uart_enable_wakeup(int enable) {}
#endif

#ifdef CONFIG_UART_INPUT_FILTER
/**
 * Application-specific input filter, which takes the next input character as
 * a parameter.
 *
 * Return 0 to allow the character to be handled by the console, non-zero if
 * the character was handled by the filter.
 */
int uart_input_filter(int c);
#endif

/*
 * COMx functions
 */

/**
 * Enable COMx interrupts
 */
void uart_comx_enable(void);

/**
 * Return non-zero if ok to put a character via uart_comx_putc().
 */
int uart_comx_putc_ok(void);

/**
 * Write a character to the COMx UART interface.
 */
void uart_comx_putc(int c);

/*
 * Functions for pad switching UART, only defined on some chips (npcx), and
 * if CONFIG_UART_PAD_SWITCH is enabled.
 */
enum uart_pad {
	UART_DEFAULT_PAD = 0,
	UART_ALTERNATE_PAD = 1,
};

/**
 * Reset UART pad to default pad, so that a panic information can be printed
 * on the EC console.
 */
void uart_reset_default_pad_panic(void);

/**
 * Specialized function to write then read data on UART alternate pad.
 * The transfer may be interrupted at any time if data is received on the main
 * pad.
 *
 * @param tx		Data to be sent
 * @param tx_len	Length of data to be sent
 * @param rx		Buffer to receive data
 * @param rx_len	Receive buffer length
 * @param timeout_us	Timeout in microseconds for the transaction to complete.
 *
 * @return The number of bytes read back (indicates a timeout if != rx_len).
 *         - -EC_ERROR_BUSY if the alternate pad cannot be used (e.g. default
 *           pad is currently being used), or if the transfer was interrupted.
 *         - -EC_ERROR_TIMEOUT in case tx_len bytes cannot be written in the
 *           time specified in timeout_us.
 */
int uart_alt_pad_write_read(uint8_t *tx, int tx_len, uint8_t *rx, int rx_len,
			int timeout_us);

/**
 * Interrupt handler for default UART RX pin transition when UART is switched
 * to alternate pad.
 *
 * @param signal	Signal which triggered the interrupt.
 */
void uart_default_pad_rx_interrupt(enum gpio_signal signal);

/**
 * Prepare for following `uart_console_read_buffer()` call.  It will create a
 * snapshot of current uart buffer.
 *
 * @return result status (EC_RES_*)
 */
int uart_console_read_buffer_init(void);

/**
 * Read from uart buffer.
 *
 * `uart_console_read_buffer_init()` must be called first.
 *
 * If `type` is CONSOLE_READ_NEXT, this will return data starting from the
 * beginning of the last snapshot created by `uart_console_read_buffer_init()`.
 *
 * If `type` is CONSOLE_READ_RECENT, this will start from the end of the
 * previous snapshot (so if current snapshot and previous snapshot has overlaps,
 * only new content will be returned).
 *
 * @param type		an ec_console_read_subcmd value.
 * @param dest		output buffer, it will be a null-terminated string.
 * @param dest_size	size of output buffer.
 * @param write_count	number of bytes written (including '\0').
 *
 * @return result status (EC_RES_*)
 */
int uart_console_read_buffer(uint8_t type,
			     char *dest,
			     uint16_t dest_size,
			     uint16_t *write_count);

#endif  /* __CROS_EC_UART_H */