1 /*
2  * SPDX-FileCopyrightText: 2015, 2016 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #pragma once
8 #include <stdint.h>
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 typedef void cdc_acm_device;
15 extern cdc_acm_device *uart_acm_dev;
16 
17 #define ACM_BYTES_PER_TX  64
18 
19 //ACM statuses are negative to distinguish from USB_DC_* status codes
20 #define ACM_STATUS_LINESTATE_CHANGED -1
21 #define ACM_STATUS_LINECODING_CHANGED -2
22 #define ACM_STATUS_TX -3
23 #define ACM_STATUS_RX -4
24 
25 typedef void(*uart_irq_callback_t)(cdc_acm_device *dev, int status);
26 
27 /**
28  * @brief Get amount of received characters in buffer
29  *
30  * @returns character count
31  */
32 
33 int cdc_acm_rx_fifo_cnt(cdc_acm_device *dev);
34 
35 /*
36  * @brief Output a character in polled mode.
37  *
38  * The UART poll method for USB UART is simulated by waiting till
39  * we get the next BULK In upcall from the USB device controller or 100 ms.
40  *
41  * @return the same character which is sent
42  */
43 unsigned char cdc_acm_poll_out(cdc_acm_device *dev, unsigned char c);
44 
45 /**
46  * @brief Fill FIFO with data
47  *
48  * @param dev     CDC ACM device struct.
49  * @param tx_data Data to transmit.
50  * @param len     Number of bytes to send.
51  *
52  * @return Number of bytes sent.
53  */
54 int cdc_acm_fifo_fill(cdc_acm_device *dev, const uint8_t *tx_data, int len);
55 
56 /**
57  * @brief Read data from FIFO
58  *
59  * @param dev     CDC ACM device struct.
60  * @param rx_data Pointer to data container.
61  * @param size    Container size.
62  *
63  * @return Number of bytes read.
64  */
65 int cdc_acm_fifo_read(cdc_acm_device *dev, uint8_t *rx_data, const int size);
66 
67 /**
68  * @brief Enable TX interrupt
69  *
70  * @param dev CDC ACM device struct.
71  *
72  * @return N/A.
73  */
74 void cdc_acm_irq_tx_enable(cdc_acm_device *dev);
75 
76 /**
77  * @brief Disable TX interrupt
78  *
79  * @param dev CDC ACM device struct.
80  *
81  * @return N/A.
82  */
83 void cdc_acm_irq_tx_disable(cdc_acm_device *dev);
84 
85 /**
86  * @brief Check if Tx IRQ has been raised
87  *
88  * @param dev CDC ACM device struct.
89  *
90  * @return 1 if a Tx IRQ is pending, 0 otherwise.
91  */
92 int cdc_acm_irq_tx_ready(cdc_acm_device *dev);
93 
94 /**
95  * @brief Enable RX interrupt
96  *
97  * @param dev CDC ACM device struct.
98  *
99  * @return N/A
100  */
101 void cdc_acm_irq_rx_enable(cdc_acm_device *dev);
102 
103 /**
104  * @brief Disable RX interrupt
105  *
106  * @param dev CDC ACM device struct.
107  *
108  * @return N/A.
109  */
110 void cdc_acm_irq_rx_disable(cdc_acm_device *dev);
111 
112 /**
113  * @brief Enable line state interrupt
114  *
115  * @param dev CDC ACM device struct.
116  *
117  * @return N/A.
118  */
119 void cdc_acm_irq_state_enable(cdc_acm_device *dev);
120 
121 /**
122  * @brief Disable line state interrupt
123  *
124  * @param dev CDC ACM device struct.
125  *
126  * @return N/A.
127  */
128 void cdc_acm_irq_state_disable(cdc_acm_device *dev);
129 
130 
131 /**
132  * @brief Check if Rx IRQ has been raised
133  *
134  * @param dev CDC ACM device struct.
135  *
136  * @return 1 if an IRQ is ready, 0 otherwise.
137  */
138 int cdc_acm_irq_rx_ready(cdc_acm_device *dev);
139 
140 /**
141  * @brief Check if Tx or Rx IRQ is pending
142  *
143  * @param dev CDC ACM device struct.
144  *
145  * @return 1 if a Tx or Rx IRQ is pending, 0 otherwise.
146  */
147 int cdc_acm_irq_is_pending(cdc_acm_device *dev);
148 
149 /**
150  * @brief Set the callback function pointer for IRQ.
151  *
152  * @param dev CDC ACM device struct.
153  * @param cb  Callback function pointer.
154  *
155  * @return N/A
156  */
157 void cdc_acm_irq_callback_set(cdc_acm_device *dev, uart_irq_callback_t cb);
158 
159 /**
160  * @brief Manipulate line control for UART.
161  *
162  * @param dev CDC ACM device struct
163  * @param ctrl The line control to be manipulated
164  * @param val Value to set the line control
165  *
166  * @return 0 if successful, failed otherwise.
167  */
168 int cdc_acm_line_ctrl_set(cdc_acm_device *dev, uint32_t ctrl, uint32_t val);
169 
170 /**
171  * @brief Manipulate line control for UART.
172  *
173  * @param dev CDC ACM device struct
174  * @param ctrl The line control to be manipulated
175  * @param val Value to set the line control
176  *
177  * @return 0 if successful, failed otherwise.
178  */
179 int cdc_acm_line_ctrl_get(cdc_acm_device *dev, uint32_t ctrl, uint32_t *val);
180 
181 
182 /**
183  * @brief Initialize UART channel
184  *
185  * This routine is called to reset the chip in a quiescent state.
186  * It is assumed that this function is called only once per UART.
187  *
188  * @param mem_chunk Memory chunk to use for internal use
189  * @param mem_chunk_size Size of the memory chunk in bytes
190  *
191  * @return dev or NULL
192  */
193 cdc_acm_device *cdc_acm_init(void *mem_chunk, int mem_chunk_size);
194 
195 
196 /** Common line controls for UART.*/
197 #define LINE_CTRL_BAUD_RATE (1 << 0)
198 #define LINE_CTRL_RTS       (1 << 1)
199 #define LINE_CTRL_DTR       (1 << 2)
200 #define LINE_CTRL_DCD       (1 << 3)
201 #define LINE_CTRL_DSR       (1 << 4)
202 
203 /* Common communication errors for UART.*/
204 
205 /** @brief Overrun error */
206 #define UART_ERROR_OVERRUN  (1 << 0)
207 
208 /** @brief Parity error */
209 #define UART_ERROR_PARITY   (1 << 1)
210 
211 /** @brief Framing error */
212 #define UART_ERROR_FRAMING  (1 << 2)
213 
214 /**
215  * @brief Break interrupt error:
216  *
217  * A break interrupt was received. This happens when the serial input is
218  * held at a logic '0' state for longer than the sum of start time + data bits
219  * + parity + stop bits.
220  */
221 #define UART_ERROR_BREAK    (1 << 3)
222 
223 #ifdef __cplusplus
224 }
225 #endif
226