ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
tusb_cdc_acm.h File Reference
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "tusb.h"
#include "tinyusb.h"
Include dependency graph for tusb_cdc_acm.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  cdcacm_event_rx_wanted_char_data_t
 Data provided to the input of the callback_rx_wanted_char callback. More...
struct  cdcacm_event_line_state_changed_data_t
 Data provided to the input of the callback_line_state_changed callback. More...
struct  cdcacm_event_line_coding_changed_data_t
 Data provided to the input of the line_coding_changed callback. More...
struct  cdcacm_event_t
 Describes an event passing to the input of a callbacks. More...
struct  tinyusb_config_cdcacm_t
 Configuration structure for CDC-ACM. More...

Typedefs

typedef void(* tusb_cdcacm_callback_t) (int itf, cdcacm_event_t *event)
 CDC-ACM callback type.

Enumerations

enum  tinyusb_cdcacm_itf_t { TINYUSB_CDC_ACM_0 = 0x0 , TINYUSB_CDC_ACM_1 , TINYUSB_CDC_ACM_MAX }
 CDC ports available to setup. More...
enum  cdcacm_event_type_t { CDC_EVENT_RX , CDC_EVENT_RX_WANTED_CHAR , CDC_EVENT_LINE_STATE_CHANGED , CDC_EVENT_LINE_CODING_CHANGED }
 Types of CDC ACM events. More...

Functions

esp_err_t tusb_cdc_acm_init (const tinyusb_config_cdcacm_t *cfg)
 Initialize CDC ACM. Initialization will be finished with the tud_cdc_line_state_cb callback.
esp_err_t tinyusb_cdcacm_register_callback (tinyusb_cdcacm_itf_t itf, cdcacm_event_type_t event_type, tusb_cdcacm_callback_t callback)
 Register a callback invoking on CDC event. If the callback had been already registered, it will be overwritten.
esp_err_t tinyusb_cdcacm_unregister_callback (tinyusb_cdcacm_itf_t itf, cdcacm_event_type_t event_type)
 Unregister a callback invoking on CDC event.
size_t tinyusb_cdcacm_write_queue_char (tinyusb_cdcacm_itf_t itf, char ch)
 Sent one character to a write buffer.
size_t tinyusb_cdcacm_write_queue (tinyusb_cdcacm_itf_t itf, const uint8_t *in_buf, size_t in_size)
 Write data to write buffer from a byte array.
esp_err_t tinyusb_cdcacm_write_flush (tinyusb_cdcacm_itf_t itf, uint32_t timeout_ticks)
 Send all data from a write buffer. Use tinyusb_cdcacm_write_queue to add data to the buffer.
esp_err_t tinyusb_cdcacm_read (tinyusb_cdcacm_itf_t itf, uint8_t *out_buf, size_t out_buf_sz, size_t *rx_data_size)
 Read a content to the array, and defines it's size to the sz_store.
bool tusb_cdc_acm_initialized (tinyusb_cdcacm_itf_t itf)
 Check if the ACM initialized.

Typedef Documentation

◆ tusb_cdcacm_callback_t

typedef void(* tusb_cdcacm_callback_t) (int itf, cdcacm_event_t *event)

CDC-ACM callback type.

Definition at line 79 of file tusb_cdc_acm.h.

Enumeration Type Documentation

◆ cdcacm_event_type_t

Types of CDC ACM events.

Enumerator
CDC_EVENT_RX 
CDC_EVENT_RX_WANTED_CHAR 
CDC_EVENT_LINE_STATE_CHANGED 
CDC_EVENT_LINE_CODING_CHANGED 

Definition at line 57 of file tusb_cdc_acm.h.

57 {
cdcacm_event_type_t
Types of CDC ACM events.
@ CDC_EVENT_LINE_STATE_CHANGED
@ CDC_EVENT_RX_WANTED_CHAR
@ CDC_EVENT_LINE_CODING_CHANGED
@ CDC_EVENT_RX

◆ tinyusb_cdcacm_itf_t

CDC ports available to setup.

Enumerator
TINYUSB_CDC_ACM_0 
TINYUSB_CDC_ACM_1 
TINYUSB_CDC_ACM_MAX 

Definition at line 23 of file tusb_cdc_acm.h.

23 {
tinyusb_cdcacm_itf_t
CDC ports available to setup.
@ TINYUSB_CDC_ACM_1
@ TINYUSB_CDC_ACM_MAX
@ TINYUSB_CDC_ACM_0

Function Documentation

◆ tinyusb_cdcacm_read()

esp_err_t tinyusb_cdcacm_read ( tinyusb_cdcacm_itf_t itf,
uint8_t * out_buf,
size_t out_buf_sz,
size_t * rx_data_size )

Read a content to the array, and defines it's size to the sz_store.

Parameters
itf- number of a CDC object
out_buf- to this array will be stored the object from a CDC buffer
out_buf_sz- size of buffer for results
rx_data_size- to this address will be stored the object's size
Returns
esp_err_t ESP_OK, ESP_FAIL or ESP_ERR_INVALID_STATE

Definition at line 247 of file tusb_cdc_acm.c.

248{
249 esp_tusb_cdcacm_t *acm = get_acm(itf);
250 ESP_RETURN_ON_FALSE(acm, ESP_ERR_INVALID_STATE, TAG, "Interface is not initialized. Use `tinyusb_cdc_init` for initialization");
251 size_t read_sz;
252
253 /* Take a mutex to proceed two uninterrupted read operations */
254 ESP_RETURN_ON_ERROR(ringbuf_mux_take(acm), TAG, "ringbuf_mux_take failed");
255
256 esp_err_t res = read_from_rx_unread_to_buffer(acm, out_buf, out_buf_sz, &read_sz);
257 if (res != ESP_OK) {
258 ESP_RETURN_ON_ERROR(ringbuf_mux_give(acm), TAG, "ringbuf_mux_give failed");
259 return res;
260 }
261
262 *rx_data_size = read_sz;
263 /* Buffer's data can be wrapped, at that situations we should make another retrievement */
264 if (read_from_rx_unread_to_buffer(acm, out_buf + read_sz, out_buf_sz - read_sz, &read_sz) == ESP_OK) {
265 *rx_data_size += read_sz;
266 }
267
268 ESP_RETURN_ON_ERROR(ringbuf_mux_give(acm), TAG, "ringbuf_mux_give failed");
269 return ESP_OK;
270}
#define ESP_RETURN_ON_ERROR(x, log_tag, format,...)
int esp_err_t
Definition esp_err.h:21
#define ESP_OK
Definition esp_err.h:23
static const char * TAG
Definition main/main.c:31
static esp_err_t ringbuf_mux_give(esp_tusb_cdcacm_t *acm)
static esp_err_t ringbuf_mux_take(esp_tusb_cdcacm_t *acm)
static esp_err_t read_from_rx_unread_to_buffer(esp_tusb_cdcacm_t *acm, uint8_t *out_buf, size_t req_bytes, size_t *read_bytes)
static esp_tusb_cdcacm_t * get_acm(tinyusb_cdcacm_itf_t itf)

References ESP_OK, ESP_RETURN_ON_ERROR, get_acm(), read_from_rx_unread_to_buffer(), ringbuf_mux_give(), ringbuf_mux_take(), and TAG.

Here is the call graph for this function:

◆ tinyusb_cdcacm_register_callback()

esp_err_t tinyusb_cdcacm_register_callback ( tinyusb_cdcacm_itf_t itf,
cdcacm_event_type_t event_type,
tusb_cdcacm_callback_t callback )

Register a callback invoking on CDC event. If the callback had been already registered, it will be overwritten.

Parameters
itf- number of a CDC object
event_type- type of registered event for a callback
callback- callback function
Returns
esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG

Definition at line 159 of file tusb_cdc_acm.c.

162{
163 esp_tusb_cdcacm_t *acm = get_acm(itf);
164 if (acm) {
165 switch (event_type) {
166 case CDC_EVENT_RX:
167 acm->callback_rx = callback;
168 return ESP_OK;
170 acm->callback_rx_wanted_char = callback;
171 return ESP_OK;
173 acm->callback_line_state_changed = callback;
174 return ESP_OK;
176 acm->callback_line_coding_changed = callback;
177 return ESP_OK;
178 default:
179 ESP_LOGE(TAG, "Wrong event type");
180 return ESP_ERR_INVALID_ARG;
181 }
182 } else {
183 ESP_LOGE(TAG, "CDC-ACM is not initialized");
184 return ESP_ERR_INVALID_STATE;
185 }
186}
tusb_cdcacm_callback_t callback_line_coding_changed
tusb_cdcacm_callback_t callback_line_state_changed
tusb_cdcacm_callback_t callback_rx
tusb_cdcacm_callback_t callback_rx_wanted_char

References esp_tusb_cdcacm_t::callback_line_coding_changed, esp_tusb_cdcacm_t::callback_line_state_changed, esp_tusb_cdcacm_t::callback_rx, esp_tusb_cdcacm_t::callback_rx_wanted_char, CDC_EVENT_LINE_CODING_CHANGED, CDC_EVENT_LINE_STATE_CHANGED, CDC_EVENT_RX, CDC_EVENT_RX_WANTED_CHAR, ESP_OK, get_acm(), and TAG.

Referenced by tusb_cdc_acm_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tinyusb_cdcacm_unregister_callback()

esp_err_t tinyusb_cdcacm_unregister_callback ( tinyusb_cdcacm_itf_t itf,
cdcacm_event_type_t event_type )

Unregister a callback invoking on CDC event.

Parameters
itf- number of a CDC object
event_type- type of registered event for a callback
Returns
esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG

Definition at line 188 of file tusb_cdc_acm.c.

190{
191 esp_tusb_cdcacm_t *acm = get_acm(itf);
192 if (!acm) {
193 ESP_LOGE(TAG, "Interface is not initialized. Use `tinyusb_cdc_init` for initialization");
194 return ESP_ERR_INVALID_STATE;
195 }
196 switch (event_type) {
197 case CDC_EVENT_RX:
198 acm->callback_rx = NULL;
199 return ESP_OK;
201 acm->callback_rx_wanted_char = NULL;
202 return ESP_OK;
204 acm->callback_line_state_changed = NULL;
205 return ESP_OK;
208 return ESP_OK;
209 default:
210 ESP_LOGE(TAG, "Wrong event type");
211 return ESP_ERR_INVALID_ARG;
212 }
213}

References esp_tusb_cdcacm_t::callback_line_coding_changed, esp_tusb_cdcacm_t::callback_line_state_changed, esp_tusb_cdcacm_t::callback_rx, esp_tusb_cdcacm_t::callback_rx_wanted_char, CDC_EVENT_LINE_CODING_CHANGED, CDC_EVENT_LINE_STATE_CHANGED, CDC_EVENT_RX, CDC_EVENT_RX_WANTED_CHAR, ESP_OK, get_acm(), and TAG.

Here is the call graph for this function:

◆ tinyusb_cdcacm_write_flush()

esp_err_t tinyusb_cdcacm_write_flush ( tinyusb_cdcacm_itf_t itf,
uint32_t timeout_ticks )

Send all data from a write buffer. Use tinyusb_cdcacm_write_queue to add data to the buffer.

   WARNING! TinyUSB can block output Endpoint for several RX callbacks, after will do additional flush
   after the each trasfer. That can leads to the situation when you requested a flush, but it will fail until
   ont of the next callbacks ends.
   SO USING OF THE FLUSH WITH TIMEOUTS IN CALLBACKS IS NOT RECOMENDED - YOU CAN GET A LOCK FOR THE TIMEOUT
Parameters
itf- number of a CDC object
timeout_ticks- waiting until flush will be considered as failed
Returns
esp_err_t - ESP_OK if (timeout_ticks > 0) and and flush was successful, ESP_ERR_TIMEOUT if timeout occurred3 or flush was successful with (timeout_ticks == 0) ESP_FAIL if flush was unsuccessful

Definition at line 294 of file tusb_cdc_acm.c.

295{
296 if (!get_acm(itf)) { // non-initialized
297 return ESP_FAIL;
298 }
299
300 if (!timeout_ticks) { // if no timeout - nonblocking mode
301 int res = tud_cdc_n_write_flush(itf);
302 if (!res) {
303 ESP_LOGW(TAG, "flush failed (res: %d)", res);
304 return ESP_FAIL;
305 } else {
306 if (tud_cdc_n_write_occupied(itf)) {
307 ESP_LOGW(TAG, "remained data to flush!");
308 return ESP_FAIL;
309 } else {
310 return ESP_OK;
311 }
312 }
313 } else { // trying during the timeout
314 uint32_t ticks_start = xTaskGetTickCount();
315 uint32_t ticks_now = ticks_start;
316 while (1) { // loop until success or until the time runs out
317 ticks_now = xTaskGetTickCount();
318 if (!tud_cdc_n_write_occupied(itf)) { // if nothing to write - nothing to flush
319 break;
320 }
321 if (tud_cdc_n_write_flush(itf)) { // Success
322 break;
323 }
324 if ( (ticks_now - ticks_start) > timeout_ticks ) { // Time is up
325 ESP_LOGW(TAG, "Flush failed");
326 return ESP_ERR_TIMEOUT;
327 }
328 vTaskDelay(1);
329 }
330 return ESP_OK;
331 }
332}
static uint32_t tud_cdc_n_write_occupied(tinyusb_cdcacm_itf_t itf)

References ESP_OK, get_acm(), TAG, and tud_cdc_n_write_occupied().

Referenced by safe_cdcacm_write_flush().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tinyusb_cdcacm_write_queue()

size_t tinyusb_cdcacm_write_queue ( tinyusb_cdcacm_itf_t itf,
const uint8_t * in_buf,
size_t in_size )

Write data to write buffer from a byte array.

Parameters
itf- number of a CDC object
in_buf- a source array
in_size- size to write from arr_src
Returns
size_t - amount of queued bytes

Definition at line 280 of file tusb_cdc_acm.c.

281{
282 if (!get_acm(itf)) { // non-initialized
283 return 0;
284 }
285 const uint32_t size_available = tud_cdc_n_write_available(itf);
286 return tud_cdc_n_write(itf, in_buf, MIN(in_size, size_available));
287}
#define MIN(x, y)

References get_acm(), and MIN.

Referenced by cdc_tx_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tinyusb_cdcacm_write_queue_char()

size_t tinyusb_cdcacm_write_queue_char ( tinyusb_cdcacm_itf_t itf,
char ch )

Sent one character to a write buffer.

Parameters
itf- number of a CDC object
ch- character to send
Returns
size_t - amount of queued bytes

Definition at line 272 of file tusb_cdc_acm.c.

273{
274 if (!get_acm(itf)) { // non-initialized
275 return 0;
276 }
277 return tud_cdc_n_write_char(itf, ch);
278}

References get_acm().

Referenced by tusb_write().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tusb_cdc_acm_init()

esp_err_t tusb_cdc_acm_init ( const tinyusb_config_cdcacm_t * cfg)

Initialize CDC ACM. Initialization will be finished with the tud_cdc_line_state_cb callback.

Parameters
cfg- init configuration structure
Returns
esp_err_t

Definition at line 352 of file tusb_cdc_acm.c.

353{
354 esp_err_t ret = ESP_OK;
355 int itf = (int)cfg->cdc_port;
356 /* Creating a CDC object */
357 const tinyusb_config_cdc_t cdc_cfg = {
358 .usb_dev = cfg->usb_dev,
359 .cdc_class = TUSB_CLASS_CDC,
360 .cdc_subclass.comm_subclass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
361 };
362
363 ESP_RETURN_ON_ERROR(tinyusb_cdc_init(itf, &cdc_cfg), TAG, "tinyusb_cdc_init failed");
364 ESP_GOTO_ON_FALSE(!alloc_obj(itf), ESP_FAIL, out4, TAG, "alloc_obj failed");
365
366 /* Callbacks setting up*/
367 if (cfg->callback_rx) {
369 }
370 if (cfg->callback_rx_wanted_char) {
372 }
375 }
378 }
379
380 /* Buffers */
381 esp_tusb_cdcacm_t *acm = get_acm(itf);
382
383 acm->ringbuf_read_mux = xSemaphoreCreateMutex();
384 ESP_GOTO_ON_FALSE(acm->ringbuf_read_mux, ESP_ERR_NO_MEM, out3, TAG, "Creation of a ringbuf mutex failed");
385
386 acm->rx_tfbuf = malloc(CONFIG_TINYUSB_CDC_RX_BUFSIZE);
387 ESP_GOTO_ON_FALSE(acm->rx_tfbuf, ESP_ERR_NO_MEM, out2, TAG, "Creation buffer error");
388
390 acm->rx_unread_buf = xRingbufferCreate(acm->rx_unread_buf_sz, RINGBUF_TYPE_BYTEBUF);
391 ESP_GOTO_ON_FALSE(acm->rx_unread_buf, ESP_ERR_NO_MEM, out1, TAG, "Creation buffer error");
392
393 ESP_LOGD(TAG, "Comm Initialized buff:%d bytes", cfg->rx_unread_buf_sz);
394 return ESP_OK;
395
396out1:
397 free(acm->rx_tfbuf);
398out2:
399 vSemaphoreDelete(acm->ringbuf_read_mux);
400out3:
401 free_obj(itf);
402out4:
404 return ret;
405}
esp_err_t tinyusb_cdc_deinit(int itf)
De-initializing CDC. Clean its objects.
Definition cdc.c:96
esp_err_t tinyusb_cdc_init(int itf, const tinyusb_config_cdc_t *cfg)
Initializing CDC basic object.
Definition cdc.c:80
#define ESP_LOGD
Definition esp_log.h:22
SemaphoreHandle_t ringbuf_read_mux
RingbufHandle_t rx_unread_buf
tusb_cdcacm_callback_t callback_rx_wanted_char
tusb_cdcacm_callback_t callback_line_coding_changed
tinyusb_usbdev_t usb_dev
tusb_cdcacm_callback_t callback_rx
tusb_cdcacm_callback_t callback_line_state_changed
tinyusb_cdcacm_itf_t cdc_port
esp_err_t tinyusb_cdcacm_register_callback(tinyusb_cdcacm_itf_t itf, cdcacm_event_type_t event_type, tusb_cdcacm_callback_t callback)
Register a callback invoking on CDC event. If the callback had been already registered,...
static esp_err_t alloc_obj(tinyusb_cdcacm_itf_t itf)
static void free_obj(tinyusb_cdcacm_itf_t itf)
#define RX_UNREADBUF_SZ_DEFAULT

References alloc_obj(), tinyusb_config_cdcacm_t::callback_line_coding_changed, tinyusb_config_cdcacm_t::callback_line_state_changed, tinyusb_config_cdcacm_t::callback_rx, tinyusb_config_cdcacm_t::callback_rx_wanted_char, CDC_EVENT_LINE_CODING_CHANGED, CDC_EVENT_LINE_STATE_CHANGED, CDC_EVENT_RX, CDC_EVENT_RX_WANTED_CHAR, tinyusb_config_cdcacm_t::cdc_port, ESP_LOGD, ESP_OK, ESP_RETURN_ON_ERROR, free_obj(), get_acm(), esp_tusb_cdcacm_t::ringbuf_read_mux, esp_tusb_cdcacm_t::rx_tfbuf, esp_tusb_cdcacm_t::rx_unread_buf, esp_tusb_cdcacm_t::rx_unread_buf_sz, tinyusb_config_cdcacm_t::rx_unread_buf_sz, RX_UNREADBUF_SZ_DEFAULT, TAG, tinyusb_cdc_deinit(), tinyusb_cdc_init(), tinyusb_cdcacm_register_callback(), and tinyusb_config_cdcacm_t::usb_dev.

Referenced by app_main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tusb_cdc_acm_initialized()

bool tusb_cdc_acm_initialized ( tinyusb_cdcacm_itf_t itf)

Check if the ACM initialized.

Parameters
itf- number of a CDC object
Returns
true or false

Definition at line 407 of file tusb_cdc_acm.c.

408{
409 esp_tusb_cdcacm_t *acm = get_acm(itf);
410 if (acm) {
411 return true;
412 } else {
413 return false;
414 }
415}

References get_acm().

Referenced by cdc_tx_task(), and esp_vfs_tusb_cdc_register().

Here is the call graph for this function:
Here is the caller graph for this function: