Skip to content

Commit 84a483f

Browse files
committed
add more host cdc API
tuh_cdc_write_available(), tuh_cdc_read_flush(), tuh_cdc_rx_cb() callback
1 parent edc559c commit 84a483f

File tree

3 files changed

+72
-55
lines changed

3 files changed

+72
-55
lines changed

examples/host/cdc_msc_hid/src/cdc_app.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,34 +54,37 @@ void cdc_app_task(void)
5454
uint8_t buf[64+1]; // +1 for extra null character
5555
uint32_t const bufsize = sizeof(buf)-1;
5656

57-
uint32_t console_count = get_console_inputs(buf, bufsize);
58-
buf[console_count] = 0;
57+
uint32_t count = get_console_inputs(buf, bufsize);
58+
buf[count] = 0;
5959

6060
// loop over all mounted interfaces
6161
for(uint8_t idx=0; idx<CFG_TUH_CDC; idx++)
6262
{
6363
if ( tuh_cdc_mounted(idx) )
6464
{
6565
// console --> cdc interfaces
66-
if (console_count)
66+
if (count)
6767
{
68-
tuh_cdc_write(idx, buf, console_count);
68+
tuh_cdc_write(idx, buf, count);
6969
tuh_cdc_write_flush(idx);
7070
}
71-
72-
// cdc interfaces -> console
73-
if ( tuh_cdc_read_available(idx) )
74-
{
75-
uint8_t buf_cdc[64+1];
76-
uint32_t cdc_count = tuh_cdc_read(idx, buf_cdc, sizeof(buf_cdc)-1);
77-
buf_cdc[cdc_count] = 0;
78-
79-
printf((char*) buf_cdc);
80-
}
8171
}
8272
}
8373
}
8474

75+
// Invoked when received new data
76+
void tuh_cdc_rx_cb(uint8_t idx)
77+
{
78+
uint8_t buf[64+1]; // +1 for extra null character
79+
uint32_t const bufsize = sizeof(buf)-1;
80+
81+
// forward cdc interfaces -> console
82+
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
83+
buf[count] = 0;
84+
85+
printf((char*) buf);
86+
}
87+
8588
void tuh_cdc_mount_cb(uint8_t idx)
8689
{
8790
tuh_cdc_itf_info_t itf_info;

src/class/cdc/cdc_host.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s)
185185
return (uint32_t) tu_fifo_count(&s->ff);
186186
}
187187

188+
uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s)
189+
{
190+
return (uint32_t) tu_fifo_remaining(&s->ff);
191+
}
192+
193+
void tu_edpt_stream_read_clear(uint8_t daddr, tu_edpt_stream_t* s)
194+
{
195+
tu_fifo_clear(&s->ff);
196+
tu_edpt_stream_read_xfer(daddr, s);
197+
}
198+
188199
typedef struct {
189200
uint8_t daddr;
190201
uint8_t bInterfaceNumber;
@@ -227,6 +238,12 @@ static inline cdch_interface_t* get_itf(uint8_t idx)
227238
return (p_cdc->daddr != 0) ? p_cdc : NULL;
228239
}
229240

241+
TU_ATTR_ALWAYS_INLINE
242+
static inline uint8_t itf2idx(cdch_interface_t* p_cdc)
243+
{
244+
return (uint8_t) (p_cdc - cdch_data);
245+
}
246+
230247
static inline cdch_interface_t* get_itf_by_ep_addr(uint8_t daddr, uint8_t ep_addr)
231248
{
232249
for(uint8_t i=0; i<CFG_TUH_CDC; i++)
@@ -320,6 +337,14 @@ uint32_t tuh_cdc_write_flush(uint8_t idx)
320337
return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx);
321338
}
322339

340+
uint32_t tuh_cdc_write_available(uint8_t idx)
341+
{
342+
cdch_interface_t* p_cdc = get_itf(idx);
343+
TU_VERIFY(p_cdc);
344+
345+
return tu_edpt_stream_write_available(&p_cdc->stream.tx);
346+
}
347+
323348
uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize)
324349
{
325350
cdch_interface_t* p_cdc = get_itf(idx);
@@ -336,6 +361,14 @@ uint32_t tuh_cdc_read_available(uint8_t idx)
336361
return tu_edpt_stream_read_available(&p_cdc->stream.rx);
337362
}
338363

364+
void tuh_cdc_read_flush (uint8_t idx)
365+
{
366+
cdch_interface_t* p_cdc = get_itf(idx);
367+
TU_VERIFY(p_cdc, );
368+
369+
tu_edpt_stream_read_clear(p_cdc->daddr, &p_cdc->stream.rx);
370+
}
371+
339372
//--------------------------------------------------------------------+
340373
// Control Endpoint API
341374
//--------------------------------------------------------------------+
@@ -463,6 +496,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t
463496
if (xferred_bytes) tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes);
464497

465498
// invoke receive callback
499+
if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(itf2idx(p_cdc));
466500

467501
// prepare for next transfer if needed
468502
tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx);

src/class/cdc/cdc_host.h

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,32 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx)
9797
return tuh_cdc_get_dtr(idx);
9898
}
9999

100+
//--------------------------------------------------------------------+
101+
// Write API
102+
//--------------------------------------------------------------------+
103+
104+
// Get the number of bytes available for writing
105+
uint32_t tuh_cdc_write_available(uint8_t idx);
106+
100107
// Write to cdc interface
101108
uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize);
102109

103110
// Force sending data if possible, return number of forced bytes
104111
uint32_t tuh_cdc_write_flush(uint8_t idx);
105112

106-
// Read from cdc interface
107-
uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize);
113+
//--------------------------------------------------------------------+
114+
// Read API
115+
//--------------------------------------------------------------------+
108116

109117
// Get the number of bytes available for reading
110118
uint32_t tuh_cdc_read_available(uint8_t idx);
111119

120+
// Read from cdc interface
121+
uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize);
122+
123+
// Clear the received FIFO
124+
void tuh_cdc_read_flush (uint8_t idx);
125+
112126
//--------------------------------------------------------------------+
113127
// Control Endpoint (Request) API
114128
//--------------------------------------------------------------------+
@@ -132,47 +146,13 @@ static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, ui
132146

133147
// Invoked when a device with CDC interface is mounted
134148
// idx is index of cdc interface in the internal pool.
135-
TU_ATTR_WEAK void tuh_cdc_mount_cb(uint8_t idx);
149+
TU_ATTR_WEAK extern void tuh_cdc_mount_cb(uint8_t idx);
136150

137151
// Invoked when a device with CDC interface is unmounted
138-
TU_ATTR_WEAK void tuh_cdc_umount_cb(uint8_t idx);
139-
140-
/** \brief Check if the interface is currently busy or not
141-
* \param[in] dev_addr device address
142-
* \param[in] pipeid value from \ref cdc_pipeid_t to indicate target pipe.
143-
* \retval true if the interface is busy, meaning the stack is still transferring/waiting data from/to device
144-
* \retval false if the interface is not busy, meaning the stack successfully transferred data from/to device
145-
* \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
146-
* can be scheduled. User needs to make sure the corresponding interface is mounted
147-
* (by \ref tuh_cdc_serial_is_mounted) before calling this function.
148-
*/
149-
// bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid);
150-
151-
/** \brief Perform USB OUT transfer to device
152-
* \param[in] dev_addr device address
153-
* \param[in] p_data Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
154-
* \param[in] length Number of bytes to be transferred via USB bus
155-
* \retval TUSB_ERROR_NONE on success
156-
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
157-
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
158-
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
159-
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
160-
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
161-
*/
162-
// bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify);
163-
164-
/** \brief Perform USB IN transfer to get data from device
165-
* \param[in] dev_addr device address
166-
* \param[in] p_buffer Buffer containing received data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
167-
* \param[in] length Number of bytes to be transferred via USB bus
168-
* \retval TUSB_ERROR_NONE on success
169-
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
170-
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
171-
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
172-
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
173-
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
174-
*/
175-
// bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify);
152+
TU_ATTR_WEAK extern void tuh_cdc_umount_cb(uint8_t idx);
153+
154+
// Invoked when received new data
155+
TU_ATTR_WEAK extern void tuh_cdc_rx_cb(uint8_t idx);
176156

177157
//--------------------------------------------------------------------+
178158
// CDC APPLICATION CALLBACKS

0 commit comments

Comments
 (0)