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 /examples/device | |
| parent | 5838c7f09dda8921fe6f350871211f8bd5a97208 (diff) | |
add full read/write() API, use edpt stream for printer class
Diffstat (limited to 'examples/device')
| -rw-r--r-- | examples/device/printer_to_hid/src/main.c | 137 |
1 files changed, 31 insertions, 106 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). |
