Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 6536

General • Re: Using Raspberry Pi Pico as HID bridge for Pi 5 - Feasibility check

$
0
0
To avoid any misunderstanding, here is the complete code for a new keymouse.c that implements the absolute position report map I posted earlier. It uses the keymouse.txt file currently on the github site, and overrides its SIZE settings by specifying the new packet lengths in write_ctic(). As an illustration it moves the cursor around a rectangle at the top left of the screen once per second. It works fine with a Windows PC.

Code:

/******** KEYMOUSE.C *********COMPILE  gcc keymouse.c btlib.c -o keymouse RUN   sudo ./keymouse********************************/#include <stdio.h>#include <stdlib.h>#include "btlib.h"  int lecallback(int clientnode,int op,int cticn);int send_key(int key);int send_mouse(int x,int y);unsigned char reportmap[100] = {0x05,0x01,0x09,0x06,0xA1,0x01,0x85,0x01,0x05,0x07,0x19,0xE0,0x29,0xE7,0x15,0x00,                               0x25,0x01,0x75,0x01,0x95,0x08,0x81,0x02,0x95,0x01,0x75,0x08,0x81,0x01,0x95,0x06,                               0x75,0x08,0x15,0x00,0x25,0x65,0x05,0x07,0x19,0x00,0x29,0x65,0x81,0x00,0xC0,                               0x05,0x01,0x09,0x02,0xA1,0x01,0x85,0x02,0x09,0x01,0xA1,0x00,0x05,0x09,0x19,0x01,                               0x29,0x03,0x15,0x00,0x25,0x01,0x95,0x03,0x75,0x01,0x81,0x02,0x95,0x01,0x75,0x05,                               0x81,0x03,0x05,0x01,0x09,0x30,0x09,0x31,0x15,0x01,0x26,0xFF,0x75,0x75,0x10,0x95,0x02,                               0x81,0x02,0xC0,0xC0};unsigned char report[8] = {0,0,0,0,0,0,0,0};unsigned char *name = "HID"; unsigned char appear[2] = {0xC1,0x03};  // 03C1 = keyboard icon appears on connecting device unsigned char pnpinfo[7] = {0x02,0x6B,0x1D,0x46,0x02,0x37,0x05};unsigned char protocolmode[1] = {0x01};unsigned char hidinfo[4] = {0x01,0x11,0x00,0x02};int main()  {  unsigned char uuid[2],randadd[6];     if(init_blue("keymouse.txt") == 0)    return(0);      if(localnode() != 1)    {    printf("ERROR - Edit keymouse.txt to set ADDRESS = %s\n",device_address(localnode()));    return(0);    }  // Write data to local characteristics  uuid[0] = 0x2A;  uuid[1] = 0x00;  write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),name,3);   uuid[0] = 0x2A;  uuid[1] = 0x01;  write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),appear,0);  uuid[0] = 0x2A;  uuid[1] = 0x4E;  write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),protocolmode,0);  uuid[0] = 0x2A;  uuid[1] = 0x4A;  write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),hidinfo,0);  uuid[0] = 0x2A;  uuid[1] = 0x4B;  write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),reportmap,100);  uuid[0] = 0x2A;  uuid[1] = 0x4D;  write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),report,0);  uuid[0] = 0x2A;  uuid[1] = 0x50;  write_ctic(localnode(),find_ctic_index(localnode(),UUID_2,uuid),pnpinfo,0);                              randadd[0] = 0xD3;   randadd[1] = 0x56;  randadd[2] = 0xD6;  randadd[3] = 0x74;  randadd[4] = 0x33;  randadd[5] = 0x06;  set_le_random_address(randadd);  keys_to_callback(KEY_ON,0);    set_le_wait(20000);                                            le_pair(localnode(),JUST_WORKS,0);                                         set_flags(FAST_TIMER,FLAG_ON);  le_server(lecallback,20);   close_all();  return(1);  }int lecallback(int clientnode,int op,int cticn)  {  int n,nread;  unsigned char buf[3];  static int timcount = 0;  static int absx[4] = { 100,5000,5000,100 };  static int absy[4] = { 100,100,5000,5000 };  static int xyn = 0;    if(op == LE_CONNECT)    {    printf("Connected OK\n");    timcount = 0;    }  if(op == LE_TIMER)    {    ++timcount;    if(timcount == 50)      {      send_mouse(absx[xyn],absy[xyn]);      ++xyn;      if(xyn == 4)        xyn = 0;      timcount = 0;      }    }  if(op == LE_KEYPRESS)    {  // cticn = ASCII code of key OR btferret custom code    send_key(cticn);          }  if(op == LE_DISCONNECT)    return(SERVER_EXIT);  return(SERVER_CONTINUE);  }int send_key(int key)  {  int n,hidcode;  unsigned char buf[8];  static int reportindex = -1;  // convert btferret code (key) to HID code    hidcode = hid_key_code(key);  if(hidcode == 0)    return(0);  if(reportindex < 0)    {  // look up Report1 index    buf[0] = 0x2A;    buf[1] = 0x4D;    reportindex = find_ctic_index(localnode(),UUID_2,buf);    if(reportindex < 0)      {      printf("Failed to find Report characteristic\n");      return(0);      }    }        for(n = 0 ; n < 8 ; ++n)    buf[n] = 0;          // send key press to Report1  buf[0] = (hidcode >> 8) & 0xFF;  // modifier  buf[2] = hidcode & 0xFF;         // key code  write_ctic(localnode(),reportindex,buf,0);  // send no key pressed - all zero  buf[0] = 0;  buf[2] = 0;  write_ctic(localnode(),reportindex,buf,0);   return(1);  }int send_mouse(int x,int y)  {  unsigned char buf[5];  static int reportindex = -1;     if(reportindex < 0)    {  // look up Report 1 index    buf[0] = 0x2A;    buf[1] = 0x4D;    reportindex = find_ctic_index(localnode(),UUID_2,buf);    if(reportindex < 0)      {      printf("Failed to find Report characteristic\n");      return(0);      }    ++reportindex;  // Mouse is Report 2    }        buf[0] = 0;  buf[1] = x & 0xFF;  buf[2] = (x >> 8) & 0xFF;  buf[3] = y & 0xFF;  buf[4] = (y >> 8) & 0xFF;  // send to Report2  write_ctic(localnode(),reportindex,buf,5);  return(1);  }

The issue was with the HID report descriptor. Specifically, the coordinate scaling was off. Originally, I assumed Barrier scaled my display to 3840x1080 (since I was using dual screens), but checking directly on Windows and via Python, it turned out the resolution being used was just 1920x1080.

After modifying the report descriptor to correctly match the screen dimensions, the movement worked perfectly.

Corrected reportmap:

Code:

unsigned char reportmap[100] = {0x05, 0x01,       // Usage Page (Generic Desktop)    0x09, 0x06,       // Usage (Keyboard)    0xA1, 0x01,       // Collection (Application)    0x85, 0x01,       // Report ID (1)    0x05, 0x07,       // Usage Page (Keyboard)    0x19, 0xE0,       // Usage Minimum (Left Control)    0x29, 0xE7,       // Usage Maximum (Right GUI)    0x15, 0x00,       // Logical Minimum (0)  <-- SHOULD ALWAYS BE 0    0x25, 0x01,       // Logical Maximum (1)    0x75, 0x01,       // Report Size (1)    0x95, 0x08,       // Report Count (8)    0x81, 0x02,       // Input (Data, Variable, Absolute)    0x95, 0x01,       // Report Count (1)    0x75, 0x08,       // Report Size (8)    0x81, 0x01,       // Input (Constant)    0x95, 0x06,       // Report Count (6)    0x75, 0x08,       // Report Size (8)    0x15, 0x00,       // Logical Minimum (0)  <-- CHANGED FROM 1 TO 0    0x25, 0x65,       // Logical Maximum (101)    0x05, 0x07,       // Usage Page (Keyboard)    0x19, 0x00,       // Usage Minimum (Reserved)    0x29, 0x65,       // Usage Maximum (Keyboard Application)    0x81, 0x00,       // Input (Data, Array)    0xC0,             // End Collection       0x05, 0x01,       // Usage Page (Generic Desktop)    0x09, 0x02,       // Usage (Mouse)    0xA1, 0x01,       // Collection (Application)    0x85, 0x02,       // Report ID (2)  <-- ATTENTION SENDING THIS ID    0x09, 0x01,       // Usage (Pointer)    0xA1, 0x00,       // Collection (Physical)    0x05, 0x09,       // Usage Page (Button)    0x19, 0x01,       // Usage Minimum (Button 1)    0x29, 0x03,       // Usage Maximum (Button 3)    0x15, 0x00,       // Logical Minimum (0)    0x25, 0x01,       // Logical Maximum (1)    0x95, 0x03,       // Report Count (3)    0x75, 0x01,       // Report Size (1)    0x81, 0x02,       // Input (Data, Variable, Absolute)    0x95, 0x01,       // Report Count (1)    0x75, 0x05,       // Report Size (5)    0x81, 0x01,       // Input (Constant)    0x05, 0x01,       // Usage Page (Generic Desktop)    0x09, 0x30,       // Usage (X)    0x09, 0x31,       // Usage (Y)    0x15, 0x00,       // Logical Minimum (0)  <-- CHANGED FROM 1 TO 0    0x26, 0xFF, 0x7F, // Logical Maximum (32767)    0x75, 0x10,       // Report Size (16)    0x95, 0x02,       // Report Count (2)    0x81, 0x02,       // Input (Data, Variable, Absolute)    0xC0,             // End Collection    0xC0};

Statistics: Posted by biomekh — Tue Apr 01, 2025 4:31 am



Viewing all articles
Browse latest Browse all 6536

Trending Articles