Merge pull request #942 from hathach/hid-set-report

Better Support Hid Get/Set report
This commit is contained in:
Ha Thach 2021-07-02 13:02:29 +07:00 committed by GitHub
commit 896388d796
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 140 additions and 19 deletions

View File

@ -255,12 +255,31 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
// TODO set LED based on CAPLOCK, NUMLOCK etc...
(void) itf;
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
if (report_type == HID_REPORT_TYPE_OUTPUT)
{
// Set keyboard LED e.g Capslock, Numlock etc...
if (report_id == REPORT_ID_KEYBOARD)
{
// bufsize should be (at least) 1
if ( bufsize < 1 ) return;
uint8_t const kbd_leds = buffer[0];
if (kbd_leds & KEYBOARD_LED_CAPSLOCK)
{
// Capslock On: disable blink, turn led on
blink_interval_ms = 0;
board_led_write(true);
}else
{
// Caplocks Off: back to normal blink
board_led_write(false);
blink_interval_ms = BLINK_MOUNTED;
}
}
}
}
//--------------------------------------------------------------------+
@ -271,6 +290,9 @@ void led_blinking_task(void)
static uint32_t start_ms = 0;
static bool led_state = false;
// blink is disabled
if (!blink_interval_ms) return;
// Blink every interval ms
if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
start_ms += blink_interval_ms;

View File

@ -315,12 +315,31 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
// TODO set LED based on CAPLOCK, NUMLOCK etc...
(void) itf;
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
if (report_type == HID_REPORT_TYPE_OUTPUT)
{
// Set keyboard LED e.g Capslock, Numlock etc...
if (report_id == REPORT_ID_KEYBOARD)
{
// bufsize should be (at least) 1
if ( bufsize < 1 ) return;
uint8_t const kbd_leds = buffer[0];
if (kbd_leds & KEYBOARD_LED_CAPSLOCK)
{
// Capslock On: disable blink, turn led on
xTimerStop(blinky_tm, portMAX_DELAY);
board_led_write(true);
}else
{
// Caplocks Off: back to normal blink
board_led_write(false);
xTimerStart(blinky_tm, portMAX_DELAY);
}
}
}
}
//--------------------------------------------------------------------+

View File

@ -25,6 +25,60 @@
#include "board.h"
#if 0
#define LED_PHASE_MAX 8
static struct
{
uint32_t phase[LED_PHASE_MAX];
uint8_t phase_count;
bool led_state;
uint8_t current_phase;
uint32_t current_ms;
}led_pattern;
void board_led_pattern(uint32_t const phase_ms[], uint8_t count)
{
memcpy(led_pattern.phase, phase_ms, 4*count);
led_pattern.phase_count = count;
// reset with 1st phase is on
led_pattern.current_ms = board_millis();
led_pattern.current_phase = 0;
led_pattern.led_state = true;
board_led_on();
}
void board_led_task(void)
{
if ( led_pattern.phase_count == 0 ) return;
uint32_t const duration = led_pattern.phase[led_pattern.current_phase];
// return if not enough time
if (board_millis() - led_pattern.current_ms < duration) return;
led_pattern.led_state = !led_pattern.led_state;
board_led_write(led_pattern.led_state);
led_pattern.current_ms += duration;
led_pattern.current_phase++;
if (led_pattern.current_phase == led_pattern.phase_count)
{
led_pattern.current_phase = 0;
led_pattern.led_state = true;
board_led_on();
}
}
#endif
//--------------------------------------------------------------------+
// newlib read()/write() retarget
//--------------------------------------------------------------------+
#if defined(__MSP430__)
#define sys_write write
#define sys_read read
@ -33,10 +87,6 @@
#define sys_read _read
#endif
//--------------------------------------------------------------------+
// newlib read()/write() retarget
//--------------------------------------------------------------------+
#if defined(LOGGER_RTT)
// Logging with RTT

View File

@ -54,6 +54,10 @@ void board_init(void);
// Turn LED on or off
void board_led_write(bool state);
// Control led pattern using phase duration in ms.
// For each phase, LED is toggle then repeated, board_led_task() is required to be called
//void board_led_pattern(uint32_t const phase_ms[], uint8_t count);
// Get the current state of button
// a '1' means active (pressed), a '0' means inactive.
uint32_t board_button_read(void);
@ -81,11 +85,12 @@ int board_uart_write(void const * buf, int len);
}
#elif CFG_TUSB_OS == OPT_OS_PICO
#include "pico/time.h"
static inline uint32_t board_millis(void)
#include "pico/time.h"
static inline uint32_t board_millis(void)
{
return to_ms_since_boot(get_absolute_time());
}
#elif CFG_TUSB_OS == OPT_OS_RTTHREAD
static inline uint32_t board_millis(void)
{

View File

@ -280,7 +280,21 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t const report_id = tu_u16_low(request->wValue);
uint16_t xferlen = tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength);
uint8_t* report_buf = p_hid->epin_buf;
uint16_t req_len = request->wLength;
uint16_t xferlen = 0;
// If host request a specific Report ID, add ID to as 1 byte of response
if ( (report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1) )
{
*report_buf++ = report_id;
req_len--;
xferlen++;
}
xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len);
TU_ASSERT( xferlen > 0 );
tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen);
@ -298,7 +312,17 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t const report_id = tu_u16_low(request->wValue);
tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epout_buf, request->wLength);
uint8_t const* report_buf = p_hid->epout_buf;
uint16_t report_len = request->wLength;
// If host request a specific Report ID, extract report ID in buffer before invoking callback
if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0]) )
{
report_buf++;
report_len--;
}
tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len);
}
break;

View File

@ -1243,7 +1243,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes);
TU_LOG2(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
// Attempt to transfer on a busy endpoint, sound like an race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);

View File

@ -186,6 +186,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
{
TU_VERIFY(_ctrl_xfer.buffer);
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
TU_LOG_MEM(2, _usbd_ctrl_buf, xferred_bytes, 2);
}
_ctrl_xfer.total_xferred += xferred_bytes;