summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-03-06 16:06:42 +0700
committerhathach <[email protected]>2026-03-06 16:06:42 +0700
commit988b18a40a4276eb731c80bc4cec3bf5750523f9 (patch)
treedfe79c7d7504a18dcb7ee95d1b3792e5f5b24931 /examples
parent5838c7f09dda8921fe6f350871211f8bd5a97208 (diff)
add full read/write() API, use edpt stream for printer class
Diffstat (limited to 'examples')
-rw-r--r--examples/device/printer_to_hid/src/main.c137
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).