diff options
| author | hathach <[email protected]> | 2026-03-06 16:06:42 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2026-03-06 16:06:42 +0700 |
| commit | 988b18a40a4276eb731c80bc4cec3bf5750523f9 (patch) | |
| tree | dfe79c7d7504a18dcb7ee95d1b3792e5f5b24931 | |
| parent | 5838c7f09dda8921fe6f350871211f8bd5a97208 (diff) | |
add full read/write() API, use edpt stream for printer class
| -rw-r--r-- | examples/device/printer_to_hid/src/main.c | 137 | ||||
| -rw-r--r-- | src/class/printer/printer_device.c | 246 | ||||
| -rw-r--r-- | src/class/printer/printer_device.h | 55 |
3 files changed, 206 insertions, 232 deletions
diff --git a/examples/device/printer_to_hid/src/main.c b/examples/device/printer_to_hid/src/main.c index 02b54c7d0..0d14147b4 100644 --- a/examples/device/printer_to_hid/src/main.c +++ b/examples/device/printer_to_hid/src/main.c @@ -33,34 +33,15 @@ #include "usb_descriptors.h" // -------------------------------------------------------------------+ -// Variables controlled with USB endpoint callbacks +// Variables // -------------------------------------------------------------------+ -// usb interface pointer -uint8_t printer_itf = 0; -// pendings bytes in usb endpoint buffer ; must process these bytes -size_t pending_bytes_on_usb_ep = 0; - - -// -------------------------------------------------------------------+ -// Variables controlled locally -// -------------------------------------------------------------------+ - -// local data buffer (copy data from usb endpoint into this buffer) ; acts as fifo -uint8_t data_buffer[16] = {0}; -// write offset for usb/printer incoming data to data_buffer -size_t data_rx_offset = 0; -// read offset for usb/hid outgoing data from data_buffer -size_t data_tx_offset = 0; -// available space in data_buffer -size_t data_available = sizeof(data_buffer); - // next keycode to send on usb/hid -uint8_t next_keycode = 0; +static uint8_t next_keycode = 0; // next key modifiers to send on usb/hid -uint8_t next_modifiers = 0; +static uint8_t next_modifiers = 0; // whether the next usb/hid report must be NULL to release the last keystroke -uint8_t next_keycode_is_release = false; +static bool next_keycode_is_release = false; // -------------------------------------------------------------------+ @@ -99,83 +80,34 @@ static void hid_tx_task(void) { next_keycode = 0; } -// Whenever there are pendings bytes on the USB endpoint, we will pull them from the -// endpoint buffer and write then in the local data buffer. We must take care to not -// overwrite local data that is not processed yet, so we use data_buffer as a fifo. -// We do not have to take care of reading correctly from the endpoint buffer, as all -// is done well by tud_printer_n_read(). -static void printer_rx_task(void) { - - if (pending_bytes_on_usb_ep == 0) { - return; +// Read one byte from printer FIFO and translate to HID keycode. +// Only a-zA-Z0-9 are translated; everything else becomes space. +static void printer_to_hid_task(void) { + if (next_keycode != 0) { + return; // previous key not yet sent } - size_t len1 = data_available; - size_t len2 = 0; - if (data_rx_offset + len1 > sizeof(data_buffer)) { - len2 = len1 - (sizeof(data_buffer) - data_rx_offset); - len1 = sizeof(data_buffer) - data_rx_offset; - } - uint32_t count = tud_printer_n_read(printer_itf, data_buffer + data_rx_offset, len1); - if (len2 > 0) { - count += tud_printer_n_read(printer_itf, data_buffer, len2); + uint8_t ch; + if (tud_printer_read(&ch, 1) == 0) { + return; // no data available } - if (count == 0) { - return; + uint8_t m = 0; + if ('a' <= ch && ch <= 'z') { + ch = (uint8_t)(ch - 'a' + HID_KEY_A); + } else if ('A' <= ch && ch <= 'Z') { + ch = (uint8_t)(ch - 'A' + HID_KEY_A); + m = KEYBOARD_MODIFIER_LEFTSHIFT; + } else if ('1' <= ch && ch <= '9') { + ch = (uint8_t)(ch - '1' + HID_KEY_1); + } else if (ch == '0') { + ch = HID_KEY_0; + } else { + ch = HID_KEY_SPACE; } - data_available -= count; - pending_bytes_on_usb_ep -= count; - data_rx_offset = (data_rx_offset + count) % sizeof(data_buffer); -} - -// The HID keycodes are not binary mapped like UTF8 codes. If we want to send the -// data received as a usb/printer, we have to translate the binary data for the -// usb/hid interface. Note that the simple mapping below will be valid only for -// hosts expecting hid data from a QWERTY keyboard. Also note that only a-zA-Z0-9 -// characters are converted, for simplicity of the example. Other characters are -// converted to spaces. -static void translation_task(void) { - if (data_tx_offset != data_rx_offset || data_available == 0) { - // If data_tx_offset and data_rx_offset have different values, then we - // can proceed: translate, prepare for TX, and advance data_tx_offset. - // - // If the buffer is full (data_available == 0), then we must also - // translate data and prepare it for TX. But the data_tx_offset and - // data_rx_offset will have the same value, since RX caught up to TX. - // Hence the OR. - - // Translate UTF8 to HID keystroke - char c = data_buffer[data_tx_offset]; - uint8_t m = 0; - if ('a' <= c && c <= 'z') { - c -= 'a'; - c += HID_KEY_A; - } else if ('A' <= c && c <= 'Z') { - c -= 'A'; - c += HID_KEY_A; - m = KEYBOARD_MODIFIER_LEFTSHIFT; - } else if ('1' <= c && c <= '9') { - c -= '1'; - c += HID_KEY_1; - } else if (c == '0') { - c = HID_KEY_0; - } else { - c = HID_KEY_SPACE; - } - - // Proceed only if there are no characters pending for TX - if (next_keycode == 0) { - // Prepare next keystroke with translated data - next_keycode = c; - next_modifiers = m; - // Increment read offset - data_tx_offset += 1; - data_tx_offset %= sizeof(data_buffer); - data_available += 1; - } - } + next_keycode = ch; + next_modifiers = m; } int main(void) { @@ -186,15 +118,9 @@ int main(void) { board_init_after_tusb(); while (1) { - tud_task(); // tinyusb device task - printer_rx_task(); // read data sent by host on our printer interface - translation_task(); // translate printer's UTF8 to HID keycodes - hid_tx_task(); // send data to host with our HID interface - if (pending_bytes_on_usb_ep > 0) { - board_led_on(); - } else { - board_led_off(); - } + tud_task(); // tinyusb device task + printer_to_hid_task(); // read printer data and translate to HID keycodes + hid_tx_task(); // send keycodes to host via HID } } @@ -203,9 +129,8 @@ int main(void) { // Printer callbacks //--------------------------------------------------------------------+ -void tud_printer_rx_cb(uint8_t itf, size_t n) { - printer_itf = itf; // get interface from which to read endpoint buffer - pending_bytes_on_usb_ep += n; // count pending bytes, counter must decrement when reading from the endpoint buffer +void tud_printer_rx_cb(uint8_t itf) { + (void)itf; } // IEEE 1284 Device ID: first 2 bytes are big-endian total length (including the 2 length bytes). diff --git a/src/class/printer/printer_device.c b/src/class/printer/printer_device.c index d288014a1..05d3f28eb 100644 --- a/src/class/printer/printer_device.c +++ b/src/class/printer/printer_device.c @@ -28,9 +28,6 @@ #if (CFG_TUD_ENABLED && CFG_TUD_PRINTER) -//--------------------------------------------------------------------+ -// INCLUDE -//--------------------------------------------------------------------+ #include "device/usbd.h" #include "device/usbd_pvt.h" @@ -42,73 +39,52 @@ typedef struct { uint8_t itf_num; - uint8_t ep_out; // Bulk Out endpoint - uint8_t ep_in; // optional Bulk In endpoint /*------------- From this point, data is not cleared by bus reset -------------*/ - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; + tu_edpt_stream_t rx_stream; + tu_edpt_stream_t tx_stream; uint8_t rx_ff_buf[CFG_TUD_PRINTER_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_PRINTER_TX_BUFSIZE]; - - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); } printer_interface_t; +#define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, rx_stream) + +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_PRINTER_EP_BUFSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_PRINTER_EP_BUFSIZE); } printer_epbuf_t; -#define ITF_MEM_RESET_SIZE offsetof(printer_interface_t, rx_ff) - -static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; CFG_TUD_MEM_SECTION static printer_epbuf_t _printer_epbuf[CFG_TUD_PRINTER]; +#endif +static printer_interface_t _printer_itf[CFG_TUD_PRINTER]; //--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION +// INTERNAL HELPERS //--------------------------------------------------------------------+ -static bool _prep_out_transaction(uint8_t itf) { - const uint8_t rhport = 0; - printer_interface_t *p_printer = &_printer_itf[itf]; - printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY(tud_ready() && p_printer->ep_out); - uint16_t available = tu_fifo_remaining(&p_printer->rx_ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= CFG_TUD_PRINTER_EP_BUFSIZE); - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_printer->ep_out)); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&p_printer->rx_ff); - - if (available >= CFG_TUD_PRINTER_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_printer->ep_out, p_epbuf->epout, CFG_TUD_PRINTER_EP_BUFSIZE, false); - } else { - // Release endpoint since we don't make any transfer - usbd_edpt_release(rhport, p_printer->ep_out); - return false; +TU_ATTR_ALWAYS_INLINE static inline uint8_t _find_itf(uint8_t ep_addr) { + for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { + const printer_interface_t *p = &_printer_itf[i]; + if (ep_addr == p->rx_stream.ep_addr || ep_addr == p->tx_stream.ep_addr) { + return i; + } } + return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ -TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf, size_t n) { +TU_ATTR_WEAK void tud_printer_rx_cb(uint8_t itf) { + (void)itf; +} + +TU_ATTR_WEAK void tud_printer_tx_complete_cb(uint8_t itf) { (void)itf; - (void)n; } TU_ATTR_WEAK void tud_printer_request_complete_cb(uint8_t itf, tusb_control_request_t const *request) { @@ -131,29 +107,53 @@ TU_ATTR_WEAK void tud_printer_soft_reset_cb(uint8_t itf) { } //--------------------------------------------------------------------+ -// APPLICATION API +// READ API //--------------------------------------------------------------------+ -uint32_t tud_printer_n_available(uint8_t itf) { - return tu_fifo_count(&_printer_itf[itf].rx_ff); +uint32_t tud_printer_n_read_available(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_read_available(&_printer_itf[itf].rx_stream); } uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize) { - printer_interface_t *p_printer = &_printer_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_printer->rx_ff, buffer, (uint16_t)TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(itf); - return num_read; + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_read(&_printer_itf[itf].rx_stream, buffer, bufsize); } bool tud_printer_n_peek(uint8_t itf, uint8_t *chr) { - return tu_fifo_peek(&_printer_itf[itf].rx_ff, chr); + TU_VERIFY(itf < CFG_TUD_PRINTER); + return tu_edpt_stream_peek(&_printer_itf[itf].rx_stream, chr); } void tud_printer_n_read_flush(uint8_t itf) { - printer_interface_t *p_printer = &_printer_itf[itf]; - tu_fifo_clear(&p_printer->rx_ff); - _prep_out_transaction(itf); + TU_VERIFY(itf < CFG_TUD_PRINTER, ); + printer_interface_t *p = &_printer_itf[itf]; + tu_edpt_stream_clear(&p->rx_stream); + tu_edpt_stream_read_xfer(&p->rx_stream); } +//--------------------------------------------------------------------+ +// WRITE API +//--------------------------------------------------------------------+ +uint32_t tud_printer_n_write(uint8_t itf, const void *buffer, uint32_t bufsize) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_write(&_printer_itf[itf].tx_stream, buffer, bufsize); +} + +uint32_t tud_printer_n_write_flush(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_write_xfer(&_printer_itf[itf].tx_stream); +} + +uint32_t tud_printer_n_write_available(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER, 0); + return tu_edpt_stream_write_available(&_printer_itf[itf].tx_stream); +} + +bool tud_printer_n_write_clear(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_PRINTER); + tu_edpt_stream_clear(&_printer_itf[itf].tx_stream); + return true; +} //--------------------------------------------------------------------+ // USBD-CLASS API @@ -162,41 +162,32 @@ void printerd_init(void) { tu_memclr(_printer_itf, sizeof(_printer_itf)); for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; + printer_interface_t *p = &_printer_itf[i]; - tu_fifo_config(&p_printer->rx_ff, p_printer->rx_ff_buf, TU_ARRAY_SIZE(p_printer->rx_ff_buf), false); - tu_fifo_config(&p_printer->tx_ff, p_printer->tx_ff_buf, TU_ARRAY_SIZE(p_printer->tx_ff_buf), true); + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + uint8_t *epout_buf = NULL; + uint8_t *epin_buf = NULL; + #else + uint8_t *epout_buf = _printer_epbuf[i].epout; + uint8_t *epin_buf = _printer_epbuf[i].epin; + #endif - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_printer->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&p_printer->tx_ff_mutex); - TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); + tu_edpt_stream_init(&p->rx_stream, false, false, false, + p->rx_ff_buf, CFG_TUD_PRINTER_RX_BUFSIZE, + epout_buf, CFG_TUD_PRINTER_EP_BUFSIZE); - tu_fifo_config_mutex(&p_printer->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&p_printer->tx_ff, mutex_wr, NULL); - #endif + tu_edpt_stream_init(&p->tx_stream, false, true, true, + p->tx_ff_buf, CFG_TUD_PRINTER_TX_BUFSIZE, + epin_buf, CFG_TUD_PRINTER_EP_BUFSIZE); } } bool printerd_deinit(void) { - #if OSAL_MUTEX_REQUIRED for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - osal_mutex_t mutex_rd = p_printer->rx_ff.mutex_rd; - osal_mutex_t mutex_wr = p_printer->tx_ff.mutex_wr; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_printer->rx_ff, NULL, NULL); - } - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_printer->tx_ff, NULL, NULL); - } + printer_interface_t *p = &_printer_itf[i]; + tu_edpt_stream_deinit(&p->rx_stream); + tu_edpt_stream_deinit(&p->tx_stream); } - #endif - return true; } @@ -204,40 +195,48 @@ void printerd_reset(uint8_t rhport) { (void)rhport; for (uint8_t i = 0; i < CFG_TUD_PRINTER; i++) { - printer_interface_t *p_printer = &_printer_itf[i]; - - tu_memclr(p_printer, ITF_MEM_RESET_SIZE); - tu_fifo_clear(&p_printer->rx_ff); - tu_fifo_clear(&p_printer->tx_ff); + printer_interface_t *p = &_printer_itf[i]; + tu_memclr(p, ITF_MEM_RESET_SIZE); + tu_edpt_stream_close(&p->rx_stream); + tu_edpt_stream_close(&p->tx_stream); } } uint16_t printerd_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len) { - (void)max_len; TU_VERIFY(TUSB_CLASS_PRINTER == itf_desc->bInterfaceClass, 0); - // Identify available interface to open - printer_interface_t *p_printer; - uint8_t printer_id; - for (printer_id = 0; printer_id < CFG_TUD_PRINTER; printer_id++) { - p_printer = &_printer_itf[printer_id]; - if (p_printer->ep_out == 0) { - break; - } - } - TU_ASSERT(printer_id < CFG_TUD_PRINTER); + // Find available interface slot + uint8_t const printer_id = _find_itf(0); + TU_ASSERT(printer_id < CFG_TUD_PRINTER, 0); + printer_interface_t *p = &_printer_itf[printer_id]; - //------------- Interface -------------// - uint16_t drv_len = sizeof(tusb_desc_interface_t); + p->itf_num = itf_desc->bInterfaceNumber; //------------- Endpoints -------------// - TU_ASSERT(itf_desc->bNumEndpoints == 2); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); - p_printer->itf_num = itf_desc->bInterfaceNumber; - const uint8_t *p_desc = tu_desc_next(itf_desc); - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_printer->ep_out, &p_printer->ep_in), 0); + const uint8_t *p_desc = (const uint8_t *)itf_desc; + const uint8_t *desc_end = p_desc + max_len; + uint16_t drv_len = sizeof(tusb_desc_interface_t); - _prep_out_transaction(printer_id); + p_desc = tu_desc_next(itf_desc); + for (uint8_t e = 0; e < itf_desc->bNumEndpoints; e++) { + TU_VERIFY(tu_desc_in_bounds(p_desc, desc_end), 0); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); + + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); + + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p->tx_stream, rhport, desc_ep); + tu_edpt_stream_clear(&p->tx_stream); + } else { + tu_edpt_stream_open(&p->rx_stream, rhport, desc_ep); + tu_edpt_stream_clear(&p->rx_stream); + TU_ASSERT(tu_edpt_stream_read_xfer(&p->rx_stream) > 0, 0); + } + + drv_len += sizeof(tusb_desc_endpoint_t); + p_desc = tu_desc_next(p_desc); + } return drv_len; } @@ -247,7 +246,6 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ uint8_t const itf_num = (uint8_t)request->wIndex; if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { - //------------- STD Request -------------// if (stage != CONTROL_STAGE_SETUP) { return true; } @@ -256,7 +254,6 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ if (stage == CONTROL_STAGE_SETUP) { switch (request->bRequest) { case TUSB_PRINTER_REQUEST_GET_DEVICE_ID: { - // App provides buffer with IEEE 1284 format (first 2 bytes = big-endian length) const uint8_t *device_id = tud_printer_get_device_id_cb(itf_num); TU_VERIFY(device_id); const uint16_t total_len = (uint16_t)((device_id[0] << 8) | device_id[1]); @@ -290,28 +287,29 @@ bool printerd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_ bool printerd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)rhport; (void)result; - uint8_t itf; - printer_interface_t *p_printer; - // Identify which interface to use - for (itf = 0; itf < CFG_TUD_PRINTER; itf++) { - p_printer = &_printer_itf[itf]; - if (ep_addr == p_printer->ep_out) { - break; - } - } + uint8_t const itf = _find_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_PRINTER); - printer_epbuf_t *p_epbuf = &_printer_epbuf[itf]; + printer_interface_t *p = &_printer_itf[itf]; // Received new data - if (ep_addr == p_printer->ep_out) { - tu_fifo_write_n(&p_printer->rx_ff, p_epbuf->epout, (uint16_t)xferred_bytes); - // invoke receive callback (if there is still data) - if (!tu_fifo_empty(&p_printer->rx_ff)) { - tud_printer_rx_cb(itf, xferred_bytes); + if (ep_addr == p->rx_stream.ep_addr) { + tu_edpt_stream_read_xfer_complete(&p->rx_stream, xferred_bytes); + + if (!tu_edpt_stream_empty(&p->rx_stream)) { + tud_printer_rx_cb(itf); + } + + tu_edpt_stream_read_xfer(&p->rx_stream); + } + + // Data sent to host + if (ep_addr == p->tx_stream.ep_addr) { + tud_printer_tx_complete_cb(itf); + + if (0 == tu_edpt_stream_write_xfer(&p->tx_stream)) { + tu_edpt_stream_write_zlp_if_needed(&p->tx_stream, xferred_bytes); } - // prepare for OUT transaction - _prep_out_transaction(itf); } return true; diff --git a/src/class/printer/printer_device.h b/src/class/printer/printer_device.h index aeff1ffc5..a6b7052cb 100644 --- a/src/class/printer/printer_device.h +++ b/src/class/printer/printer_device.h @@ -38,23 +38,74 @@ extern "C" { //--------------------------------------------------------------------+ // Get the number of bytes available for reading -uint32_t tud_printer_n_available(uint8_t itf); +uint32_t tud_printer_n_read_available(uint8_t itf); // Read received bytes uint32_t tud_printer_n_read(uint8_t itf, void *buffer, uint32_t bufsize); +// Get the number of bytes available for writing +uint32_t tud_printer_n_write_available(uint8_t itf); + // Clear the received FIFO void tud_printer_n_read_flush(uint8_t itf); // Get a byte from FIFO without removing it bool tud_printer_n_peek(uint8_t itf, uint8_t *ui8); +// Write data to host +uint32_t tud_printer_n_write(uint8_t itf, const void *buffer, uint32_t bufsize); + +// Force sending data in the TX FIFO +uint32_t tud_printer_n_write_flush(uint8_t itf); + +// Clear the transmit FIFO +bool tud_printer_n_write_clear(uint8_t itf); + +//--------------------------------------------------------------------+ +// Application API (Single Port) +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_read_available(void) { + return tud_printer_n_read_available(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write_available(void) { + return tud_printer_n_write_available(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_read(void *buffer, uint32_t bufsize) { + return tud_printer_n_read(0, buffer, bufsize); +} + +TU_ATTR_ALWAYS_INLINE static inline void tud_printer_read_flush(void) { + tud_printer_n_read_flush(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_printer_peek(uint8_t *ui8) { + return tud_printer_n_peek(0, ui8); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write(const void *buffer, uint32_t bufsize) { + return tud_printer_n_write(0, buffer, bufsize); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_printer_write_flush(void) { + return tud_printer_n_write_flush(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_printer_write_clear(void) { + return tud_printer_n_write_clear(0); +} + //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when received new data -void tud_printer_rx_cb(uint8_t itf, size_t n); +void tud_printer_rx_cb(uint8_t itf); + +// Invoked when last write transfer is completed +void tud_printer_tx_complete_cb(uint8_t itf); // Invoked when host requests device ID string (IEEE 1284). // Application returns pointer to device ID buffer (must remain valid until transfer completes). |
