mirror of
https://gitlab.com/zephray/glider.git
synced 2024-11-10 11:17:54 +00:00
Initial bring up USB HID interface
This commit is contained in:
parent
3a16b26ec2
commit
3bf4096d43
10 changed files with 249 additions and 27 deletions
|
@ -28,10 +28,12 @@ add_executable(fw
|
|||
bitstream.c
|
||||
button.c
|
||||
caster.c
|
||||
crc16.c
|
||||
edid.c
|
||||
fpga.c
|
||||
fusb302.c
|
||||
fw.c
|
||||
iap.c
|
||||
power.c
|
||||
ptn3460.c
|
||||
tcpm_driver.c
|
||||
|
|
|
@ -95,4 +95,3 @@ uint8_t caster_load_waveform(uint8_t *waveform, uint8_t frames);
|
|||
uint8_t caster_redraw(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||||
uint8_t caster_setmode(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
||||
UPDATE_MODE mode);
|
||||
uint8_t caster_setinput(uint8_t input_src);
|
||||
|
|
60
fw/crc16.c
Normal file
60
fw/crc16.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "crc16.h"
|
||||
|
||||
/*
|
||||
* The crc32 is licensed under the Apache License, Version 2.0
|
||||
* CRC16 implementation according to CCITT standards.
|
||||
*
|
||||
* The XMODEM CRC 16 algorithm, using the following parameters:
|
||||
*
|
||||
* Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN"
|
||||
* Width : 16 bit
|
||||
* Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1)
|
||||
* Initialization : 0000
|
||||
* Reflect Input byte : False
|
||||
* Reflect Output CRC : False
|
||||
* Xor constant to output CRC : 0000
|
||||
* Output for "123456789" : 31C3
|
||||
*/
|
||||
|
||||
static const uint16_t crc16tab[256]= {
|
||||
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
|
||||
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
|
||||
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
|
||||
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
|
||||
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
|
||||
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
|
||||
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
|
||||
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
|
||||
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
|
||||
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
|
||||
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
|
||||
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
|
||||
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
|
||||
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
|
||||
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
|
||||
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
|
||||
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
|
||||
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
|
||||
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
|
||||
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
|
||||
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
|
||||
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
|
||||
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
|
||||
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
|
||||
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
|
||||
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
|
||||
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
|
||||
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
|
||||
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
|
||||
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
|
||||
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
|
||||
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
|
||||
};
|
||||
|
||||
uint16_t crc16(const char *buf, int len) {
|
||||
int counter;
|
||||
uint16_t crc = 0;
|
||||
for (counter = 0; counter < len; counter++)
|
||||
crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF];
|
||||
return crc;
|
||||
}
|
14
fw/crc16.h
Normal file
14
fw/crc16.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef _CRC_CRC16_H
|
||||
#define _CRC_CRC16_H
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
uint16_t crc16(const char *buf, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
2
fw/fw.c
2
fw/fw.c
|
@ -112,7 +112,7 @@ int main()
|
|||
}
|
||||
|
||||
void osd_task(void) {
|
||||
#ifdef BOARD_HAS_BUTTON
|
||||
#ifdef HAS_BUTTON
|
||||
static int mode_max = 6;
|
||||
static int mode = 1;
|
||||
const UPDATE_MODE modes[6] = {
|
||||
|
|
56
fw/iap.c
Normal file
56
fw/iap.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// Copyright 2024 Wenting Zhang <zephray@outlook.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/flash.h"
|
||||
#include "pico/bootrom.h"
|
||||
#include "iap.h"
|
||||
|
||||
void __no_inline_not_in_flash_func(nuke)() {
|
||||
uint flash_size_bytes;
|
||||
#ifndef PICO_FLASH_SIZE_BYTES
|
||||
#warning PICO_FLASH_SIZE_BYTES not set, assuming 16M
|
||||
flash_size_bytes = 16 * 1024 * 1024;
|
||||
#else
|
||||
flash_size_bytes = PICO_FLASH_SIZE_BYTES;
|
||||
#endif
|
||||
flash_range_erase(0, flash_size_bytes);
|
||||
|
||||
// Pop back up as an MSD drive
|
||||
reset_usb_boot(0, 0);
|
||||
}
|
||||
|
||||
void iap_usbboot(void) {
|
||||
reset_usb_boot(0, 0);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void iap_reset(void) {
|
||||
(*((volatile uint32_t*)(PPB_BASE + 0x0ED0C))) = 0x5FA0004; // Reset via NVIC
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void iap_nuke(void) {
|
||||
nuke();
|
||||
__builtin_unreachable();
|
||||
}
|
5
fw/iap.h
Normal file
5
fw/iap.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
void iap_nuke(void);
|
||||
void iap_usbboot(void);
|
||||
void iap_reset(void);
|
38
fw/usbapp.c
38
fw/usbapp.c
|
@ -25,6 +25,9 @@
|
|||
#include "caster.h"
|
||||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "usbapp.h"
|
||||
#include "crc16.h"
|
||||
#include "iap.h"
|
||||
|
||||
void usbapp_init(void) {
|
||||
tusb_init();
|
||||
|
@ -80,11 +83,19 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_
|
|||
uint16_t y1 = (buffer[11] << 8) | buffer[10];
|
||||
uint16_t id = (buffer[13] << 8) | buffer[12];
|
||||
uint16_t chksum = (buffer[15] << 8) | buffer[14];
|
||||
uint8_t retval = 1;
|
||||
switch (buffer[0]) {
|
||||
|
||||
uint8_t retval;
|
||||
uint16_t exp_chksum = crc16(buffer, 14);
|
||||
if (chksum != exp_chksum) {
|
||||
retval = USBRET_CHKSUMFAIL;
|
||||
goto returnval;
|
||||
}
|
||||
retval = 1;
|
||||
|
||||
switch (cmd) {
|
||||
case USBCMD_RESET:
|
||||
// reset system
|
||||
(*((volatile uint32_t*)(PPB_BASE + 0x0ED0C))) = 0x5FA0004; // Reset via NVIC
|
||||
//iap_reset();
|
||||
break;
|
||||
case USBCMD_POWERDOWN:
|
||||
// TODO
|
||||
|
@ -93,7 +104,7 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_
|
|||
// TODO
|
||||
break;
|
||||
case USBCMD_SETINPUT:
|
||||
retval = caster_setinput((uint8_t)param);
|
||||
// TODO
|
||||
break;
|
||||
case USBCMD_REDRAW:
|
||||
retval = caster_redraw(x0, y0, x1, y1);
|
||||
|
@ -101,12 +112,27 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_
|
|||
case USBCMD_SETMODE:
|
||||
retval = caster_setmode(x0, y0, x1, y1, (UPDATE_MODE)param);
|
||||
break;
|
||||
case USBCMD_USBBOOT:
|
||||
//iap_usbboot();
|
||||
break;
|
||||
case USBCMD_NUKE:
|
||||
//iap_nuke();
|
||||
break;
|
||||
}
|
||||
if (retval == 0)
|
||||
retval = USBRET_SUCCESS;
|
||||
else
|
||||
retval = USBRET_GENERALFAIL;
|
||||
|
||||
uint8_t txbuf[1];
|
||||
returnval:
|
||||
uint8_t txbuf[16] = {0};
|
||||
txbuf[0] = retval;
|
||||
txbuf[2] = buffer[14];
|
||||
txbuf[3] = buffer[15];
|
||||
txbuf[4] = exp_chksum & 0xff;
|
||||
txbuf[5] = (exp_chksum >> 8) & 0xff;
|
||||
|
||||
tud_hid_report(0, txbuf, 1);
|
||||
tud_hid_report(0, txbuf, 16);
|
||||
}
|
||||
|
||||
void usbapp_task(void) {
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
#define USBCMD_SETINPUT 0x03
|
||||
#define USBCMD_REDRAW 0x04
|
||||
#define USBCMD_SETMODE 0x05
|
||||
#define USBCMD_NUKE 0x06
|
||||
#define USBCMD_USBBOOT 0x07
|
||||
|
||||
#define USBRET_GENERALFAIL 0x00
|
||||
#define USBRET_CHKSUMFAIL 0x01
|
||||
#define USBRET_SUCCESS 0x55
|
||||
|
||||
void usbapp_init(void);
|
||||
void usbapp_task(void);
|
||||
|
|
|
@ -1,26 +1,80 @@
|
|||
# Install python3 HID package https://pypi.org/project/hid/
|
||||
# Install python3 hidapi package https://pypi.org/project/hidapi/
|
||||
import hid
|
||||
import struct
|
||||
|
||||
vid = 0xcafe
|
||||
pid = 0x4004
|
||||
USBCMD_RESET = 0x00
|
||||
USBCMD_POWERDOWN = 0x01
|
||||
USBCMD_POWERUP = 0x02
|
||||
USBCMD_SETINPUT = 0x03
|
||||
USBCMD_REDRAW = 0x04
|
||||
USBCMD_SETMODE = 0x05
|
||||
USBCMD_NUKE = 0x06
|
||||
USBCMD_USBBOOT = 0x07
|
||||
|
||||
dev = hid.Device(vid, pid)
|
||||
USBRET_GENERALFAIL = 0x00
|
||||
USBRET_CHKSUMFAIL = 0x01
|
||||
USBRET_SUCCESS = 0x55
|
||||
|
||||
if not dev:
|
||||
print("Unable to open device")
|
||||
exit()
|
||||
def crc16(data: bytes):
|
||||
'''
|
||||
CRC-16 (CCITT) implemented with a precomputed lookup table
|
||||
'''
|
||||
table = [
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
]
|
||||
|
||||
crc = 0x0
|
||||
for byte in data:
|
||||
crc = (crc << 8) ^ table[(crc >> 8) ^ byte]
|
||||
crc &= 0xFFFF # important, crc must stay 16bits all the way through
|
||||
return crc
|
||||
|
||||
cmd = 0x00
|
||||
param = 0x00
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 1600 - 1
|
||||
y1 = 1200 - 1
|
||||
pid = 0
|
||||
chksum = 0
|
||||
def send_cmd():
|
||||
vid = 0xcafe
|
||||
pid = 0x4004
|
||||
|
||||
str_out = struct.pack('>h>h>h>h>h>h>h>h', cmd, param, x0, y0, x1, y1, pid, chksum)
|
||||
dev.write(str_out)
|
||||
str_in = dev.read(1)
|
||||
print("Received from HID Device:", str_in, '\n')
|
||||
h = hid.device()
|
||||
h.open(vid, pid)
|
||||
|
||||
print("Manufacturer: %s" % h.get_manufacturer_string())
|
||||
print("Product: %s" % h.get_product_string())
|
||||
print("Serial No: %s" % h.get_serial_number_string())
|
||||
|
||||
#cmd = USBCMD_REDRAW
|
||||
cmd = USBCMD_SETMODE
|
||||
param = 0x02
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 1200 - 1
|
||||
y1 = 1200 - 1
|
||||
pid = 0
|
||||
|
||||
byteseq = struct.pack('<hhhhhhh', cmd, param, x0, y0, x1, y1, pid)
|
||||
chksum = struct.pack('<H', crc16(byteseq))
|
||||
byteout = byteseq + chksum
|
||||
print(byteout)
|
||||
|
||||
h.write(byteout)
|
||||
str_in = h.read(16)
|
||||
print("Received from HID Device:", str_in, '\n')
|
||||
|
||||
def main():
|
||||
send_cmd()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in a new issue