1 // Copyright 2020 Espressif Systems (Shanghai) Co. Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <stdint.h> 22 #include "freertos/FreeRTOS.h" 23 #include "freertos/ringbuf.h" 24 #include "freertos/semphr.h" 25 #include "freertos/timers.h" 26 #include "tusb.h" 27 #include "tinyusb.h" 28 29 /** 30 * @brief CDC ports available to setup 31 */ 32 typedef enum{ 33 TINYUSB_CDC_ACM_0 = 0x0 34 }tinyusb_cdcacm_itf_t; 35 36 /* Callbacks and events 37 ********************************************************************* */ 38 39 /** 40 * @brief Data provided to the input of the `callback_rx_wanted_char` callback 41 */ 42 typedef struct { 43 char wanted_char; /*!< Wanted character */ 44 } cdcacm_event_rx_wanted_char_data_t; 45 46 /** 47 * @brief Data provided to the input of the `callback_line_state_changed` callback 48 */ 49 typedef struct { 50 bool dtr; /*!< Data Terminal Ready (DTR) line state */ 51 bool rts; /*!< Request To Send (RTS) line state */ 52 } cdcacm_event_line_state_changed_data_t; 53 54 /** 55 * @brief Data provided to the input of the `line_coding_changed` callback 56 */ 57 typedef struct { 58 cdc_line_coding_t const *p_line_coding; /*!< New line coding value */ 59 } cdcacm_event_line_coding_changed_data_t; 60 61 /** 62 * @brief Types of CDC ACM events 63 */ 64 typedef enum { 65 CDC_EVENT_RX, 66 CDC_EVENT_RX_WANTED_CHAR, 67 CDC_EVENT_LINE_STATE_CHANGED, 68 CDC_EVENT_LINE_CODING_CHANGED 69 } cdcacm_event_type_t; 70 71 /** 72 * @brief Describes an event passing to the input of a callbacks 73 */ 74 typedef struct { 75 cdcacm_event_type_t type; /*!< Event type */ 76 union { 77 cdcacm_event_rx_wanted_char_data_t rx_wanted_char_data; /*!< Data input of the `callback_rx_wanted_char` callback */ 78 cdcacm_event_line_state_changed_data_t line_state_changed_data; /*!< Data input of the `callback_line_state_changed` callback */ 79 cdcacm_event_line_coding_changed_data_t line_coding_changed_data; /*!< Data input of the `line_coding_changed` callback */ 80 }; 81 } cdcacm_event_t; 82 83 /** 84 * @brief CDC-ACM callback type 85 */ 86 typedef void(*tusb_cdcacm_callback_t)(int itf, cdcacm_event_t *event); 87 88 /*********************************************************************** Callbacks and events*/ 89 /* Other structs 90 ********************************************************************* */ 91 92 /** 93 * @brief Configuration structure for CDC-ACM 94 */ 95 typedef struct { 96 tinyusb_usbdev_t usb_dev; /*!< Usb device to set up */ 97 tinyusb_cdcacm_itf_t cdc_port; /*!< CDC port */ 98 size_t rx_unread_buf_sz; /*!< Amount of data that can be passed to the AMC at once */ 99 tusb_cdcacm_callback_t callback_rx; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */ 100 tusb_cdcacm_callback_t callback_rx_wanted_char; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */ 101 tusb_cdcacm_callback_t callback_line_state_changed; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */ 102 tusb_cdcacm_callback_t callback_line_coding_changed; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */ 103 } tinyusb_config_cdcacm_t; 104 105 /*********************************************************************** Other structs*/ 106 /* Public functions 107 ********************************************************************* */ 108 /** 109 * @brief Initialize CDC ACM. Initialization will be finished with 110 * the `tud_cdc_line_state_cb` callback 111 * 112 * @param cfg - init configuration structure 113 * @return esp_err_t 114 */ 115 esp_err_t tusb_cdc_acm_init(const tinyusb_config_cdcacm_t *cfg); 116 117 118 /** 119 * @brief Register a callback invoking on CDC event. If the callback had been 120 * already registered, it will be overwritten 121 * 122 * @param itf - number of a CDC object 123 * @param event_type - type of registered event for a callback 124 * @param callback - callback function 125 * @return esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG 126 */ 127 esp_err_t tinyusb_cdcacm_register_callback(tinyusb_cdcacm_itf_t itf, 128 cdcacm_event_type_t event_type, 129 tusb_cdcacm_callback_t callback); 130 131 132 /** 133 * @brief Unregister a callback invoking on CDC event. 134 * 135 * @param itf - number of a CDC object 136 * @param event_type - type of registered event for a callback 137 * @return esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG 138 */ 139 esp_err_t tinyusb_cdcacm_unregister_callback(tinyusb_cdcacm_itf_t itf, cdcacm_event_type_t event_type); 140 141 142 /** 143 * @brief Sent one character to a write buffer 144 * 145 * @param itf - number of a CDC object 146 * @param ch - character to send 147 * @return size_t - amount of queued bytes 148 */ 149 size_t tinyusb_cdcacm_write_queue_char(tinyusb_cdcacm_itf_t itf, char ch); 150 151 152 /** 153 * @brief Write data to write buffer from a byte array 154 * 155 * @param itf - number of a CDC object 156 * @param in_buf - a source array 157 * @param in_size - size to write from arr_src 158 * @return size_t - amount of queued bytes 159 */ 160 size_t tinyusb_cdcacm_write_queue(tinyusb_cdcacm_itf_t itf, const uint8_t *in_buf, size_t in_size); 161 162 /** 163 * @brief Send all data from a write buffer. Use `tinyusb_cdcacm_write_queue` to add data to the buffer. 164 * 165 * WARNING! TinyUSB can block output Endpoint for several RX callbacks, after will do additional flush 166 * after the each trasfer. That can leads to the situation when you requested a flush, but it will fail until 167 * ont of the next callbacks ends. 168 * SO USING OF THE FLUSH WITH TIMEOUTS IN CALLBACKS IS NOT RECOMENDED - YOU CAN GET A LOCK FOR THE TIMEOUT 169 * 170 * @param itf - number of a CDC object 171 * @param timeout_ticks - waiting until flush will be considered as failed 172 * @return esp_err_t - ESP_OK if (timeout_ticks > 0) and and flush was successful, 173 * ESP_ERR_TIMEOUT if timeout occurred3 or flush was successful with (timeout_ticks == 0) 174 * ESP_FAIL if flush was unsuccessful 175 */ 176 esp_err_t tinyusb_cdcacm_write_flush(tinyusb_cdcacm_itf_t itf, uint32_t timeout_ticks); 177 178 /** 179 * @brief Read a content to the array, and defines it's size to the sz_store 180 * 181 * @param itf - number of a CDC object 182 * @param out_buf - to this array will be stored the object from a CDC buffer 183 * @param out_buf_sz - size of buffer for results 184 * @param rx_data_size - to this address will be stored the object's size 185 * @return esp_err_t ESP_OK, ESP_FAIL or ESP_ERR_INVALID_STATE 186 */ 187 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); 188 189 190 /** 191 * @brief Check if the ACM initialized 192 * 193 * @param itf - number of a CDC object 194 * @return true or false 195 */ 196 bool tusb_cdc_acm_initialized(tinyusb_cdcacm_itf_t itf); 197 198 /*********************************************************************** Public functions*/ 199 200 #ifdef __cplusplus 201 } 202 #endif 203