├── 3dprint ├── USB_Knob_knob.stl ├── USB_Knob_case.fcstd ├── USB_Knob_case_ring.stl ├── USB_Knob_case_top.stl └── USB_Knob_case_bottom.stl ├── hardware ├── USB_Knob_BOM.tsv ├── USB_Knob_gerber.zip └── USB_Knob_schematic.pdf ├── documentation ├── USB_Knob_pic1.jpg ├── USB_Knob_pic2.jpg ├── USB_Knob_pic3.jpg ├── USB_Knob_pic4.jpg └── USB_Knob_wiring.png ├── software ├── custom_knob │ ├── custom_knob.bin │ ├── src │ │ ├── usb_hid.h │ │ ├── config.h │ │ ├── neo.h │ │ ├── usb_handler.h │ │ ├── delay.c │ │ ├── usb_descr.h │ │ ├── usb_hid.c │ │ ├── delay.h │ │ ├── usb_composite.h │ │ ├── neo.c │ │ ├── usb_composite.c │ │ ├── system.h │ │ ├── usb_descr.c │ │ └── usb.h │ ├── custom_knob.ino │ ├── makefile │ └── custom_knob.c ├── volume_knob │ ├── volume_knob.bin │ ├── src │ │ ├── usb_hid.h │ │ ├── usb_consumer.c │ │ ├── config.h │ │ ├── neo.h │ │ ├── usb_consumer.h │ │ ├── usb_handler.h │ │ ├── usb_hid.c │ │ ├── delay.c │ │ ├── usb_descr.h │ │ ├── delay.h │ │ ├── neo.c │ │ ├── usb_descr.c │ │ ├── system.h │ │ └── usb.h │ ├── volume_knob.ino │ ├── makefile │ └── volume_knob.c └── mousewheel_knob │ ├── mousewheel_knob.bin │ ├── src │ ├── usb_hid.h │ ├── usb_mouse.h │ ├── config.h │ ├── neo.h │ ├── usb_handler.h │ ├── usb_mouse.c │ ├── usb_hid.c │ ├── delay.c │ ├── usb_descr.h │ ├── delay.h │ ├── neo.c │ ├── usb_descr.c │ ├── system.h │ └── usb.h │ ├── mousewheel_knob.ino │ ├── makefile │ └── mousewheel_knob.c ├── LICENSE └── README.md /3dprint/USB_Knob_knob.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/3dprint/USB_Knob_knob.stl -------------------------------------------------------------------------------- /hardware/USB_Knob_BOM.tsv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/hardware/USB_Knob_BOM.tsv -------------------------------------------------------------------------------- /3dprint/USB_Knob_case.fcstd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/3dprint/USB_Knob_case.fcstd -------------------------------------------------------------------------------- /hardware/USB_Knob_gerber.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/hardware/USB_Knob_gerber.zip -------------------------------------------------------------------------------- /3dprint/USB_Knob_case_ring.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/3dprint/USB_Knob_case_ring.stl -------------------------------------------------------------------------------- /3dprint/USB_Knob_case_top.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/3dprint/USB_Knob_case_top.stl -------------------------------------------------------------------------------- /3dprint/USB_Knob_case_bottom.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/3dprint/USB_Knob_case_bottom.stl -------------------------------------------------------------------------------- /documentation/USB_Knob_pic1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/documentation/USB_Knob_pic1.jpg -------------------------------------------------------------------------------- /documentation/USB_Knob_pic2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/documentation/USB_Knob_pic2.jpg -------------------------------------------------------------------------------- /documentation/USB_Knob_pic3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/documentation/USB_Knob_pic3.jpg -------------------------------------------------------------------------------- /documentation/USB_Knob_pic4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/documentation/USB_Knob_pic4.jpg -------------------------------------------------------------------------------- /documentation/USB_Knob_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/documentation/USB_Knob_wiring.png -------------------------------------------------------------------------------- /hardware/USB_Knob_schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/hardware/USB_Knob_schematic.pdf -------------------------------------------------------------------------------- /software/custom_knob/custom_knob.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/software/custom_knob/custom_knob.bin -------------------------------------------------------------------------------- /software/volume_knob/volume_knob.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/software/volume_knob/volume_knob.bin -------------------------------------------------------------------------------- /software/mousewheel_knob/mousewheel_knob.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/HEAD/software/mousewheel_knob/mousewheel_knob.bin -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. 2 | To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send 3 | a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. 4 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb_hid.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | 8 | void HID_init(void); // setup USB-HID 9 | void HID_sendReport(__xdata uint8_t* buf, uint8_t len); // send HID report 10 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/usb_hid.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | 8 | void HID_init(void); // setup USB-HID 9 | void HID_sendReport(__xdata uint8_t* buf, uint8_t len); // send HID report 10 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb_hid.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | #include "usb_handler.h" 8 | 9 | void HID_init(void); // setup USB-HID 10 | void HID_sendReport(__xdata uint8_t* buf, uint8_t len); // send HID report 11 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/usb_mouse.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Standard Mouse Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | #include "usb_hid.h" 8 | 9 | // Functions 10 | #define MOUSE_init() HID_init() // init mouse 11 | void MOUSE_press(uint8_t buttons); // press button(s) 12 | void MOUSE_release(uint8_t buttons); // release button(s) 13 | void MOUSE_move(int8_t xrel, int8_t yrel); // move mouse pointer (relative) 14 | void MOUSE_wheel(int8_t rel); // move mouse wheel (relative) 15 | 16 | // Mouse buttons 17 | #define MOUSE_BUTTON_LEFT 0x01 // left mouse button 18 | #define MOUSE_BUTTON_RIGHT 0x02 // right mouse button 19 | #define MOUSE_BUTTON_MIDDLE 0x04 // middle mouse button 20 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb_consumer.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Consumer Keyboard Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #include "usb_consumer.h" 6 | #include "usb_hid.h" 7 | #include "usb_handler.h" 8 | 9 | #define CON_sendReport() HID_sendReport(CON_report, sizeof(CON_report)) 10 | 11 | // Consumer Keyboard HID report 12 | __xdata uint8_t CON_report[3] = {1,0,0}; 13 | 14 | // Press a consumer key on keyboard 15 | void CON_press(uint8_t key) { 16 | CON_report[1] = key; 17 | CON_sendReport(); 18 | } 19 | 20 | // Release a consumer key on keyboard 21 | void CON_release(void) { 22 | CON_report[1] = 0; 23 | CON_sendReport(); 24 | } 25 | 26 | // Press and release a consumer key on keyboard 27 | void CON_type(uint8_t key) { 28 | CON_press(key); 29 | CON_release(); 30 | } 31 | -------------------------------------------------------------------------------- /software/custom_knob/custom_knob.ino: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Arduino IDE Wrapper for ch55xduino 3 | // =================================================================================== 4 | // 5 | // Compilation Instructions for the Arduino IDE: 6 | // --------------------------------------------- 7 | // - Make sure you have installed ch55xduino: https://github.com/DeqingSun/ch55xduino 8 | // - Copy the .ino and .c files as well as the /src folder together into one folder 9 | // and name it like the .ino file. Open the .ino file in the Arduino IDE. Go to 10 | // "Tools -> Board -> CH55x Boards -> CH552 Board". Under "Tools" select the 11 | // following board options: 12 | // - Clock Source: 16 MHz (internal) 13 | // - Upload Method: USB 14 | // - USB Settings: USER CODE /w 266B USB RAM 15 | // - Press BOOT button on the board and keep it pressed while connecting it via USB 16 | // with your PC. 17 | // - Click on "Upload" immediatly afterwards. 18 | // - To compile the firmware using the makefile, follow the instructions in the 19 | // .c file. 20 | 21 | #ifndef USER_USB_RAM 22 | #error "This firmware needs to be compiled with a USER USB setting" 23 | #endif 24 | 25 | unsigned char _sdcc_external_startup (void) __nonbanked { 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /software/volume_knob/volume_knob.ino: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Arduino IDE Wrapper for ch55xduino 3 | // =================================================================================== 4 | // 5 | // Compilation Instructions for the Arduino IDE: 6 | // --------------------------------------------- 7 | // - Make sure you have installed ch55xduino: https://github.com/DeqingSun/ch55xduino 8 | // - Copy the .ino and .c files as well as the /src folder together into one folder 9 | // and name it like the .ino file. Open the .ino file in the Arduino IDE. Go to 10 | // "Tools -> Board -> CH55x Boards -> CH552 Board". Under "Tools" select the 11 | // following board options: 12 | // - Clock Source: 16 MHz (internal) 13 | // - Upload Method: USB 14 | // - USB Settings: USER CODE /w 266B USB RAM 15 | // - Press BOOT button on the board and keep it pressed while connecting it via USB 16 | // with your PC. 17 | // - Click on "Upload" immediatly afterwards. 18 | // - To compile the firmware using the makefile, follow the instructions in the 19 | // .c file. 20 | 21 | #ifndef USER_USB_RAM 22 | #error "This firmware needs to be compiled with a USER USB setting" 23 | #endif 24 | 25 | unsigned char _sdcc_external_startup (void) __nonbanked { 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /software/mousewheel_knob/mousewheel_knob.ino: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Arduino IDE Wrapper for ch55xduino 3 | // =================================================================================== 4 | // 5 | // Compilation Instructions for the Arduino IDE: 6 | // --------------------------------------------- 7 | // - Make sure you have installed ch55xduino: https://github.com/DeqingSun/ch55xduino 8 | // - Copy the .ino and .c files as well as the /src folder together into one folder 9 | // and name it like the .ino file. Open the .ino file in the Arduino IDE. Go to 10 | // "Tools -> Board -> CH55x Boards -> CH552 Board". Under "Tools" select the 11 | // following board options: 12 | // - Clock Source: 16 MHz (internal) 13 | // - Upload Method: USB 14 | // - USB Settings: USER CODE /w 266B USB RAM 15 | // - Press BOOT button on the board and keep it pressed while connecting it via USB 16 | // with your PC. 17 | // - Click on "Upload" immediatly afterwards. 18 | // - To compile the firmware using the makefile, follow the instructions in the 19 | // .c file. 20 | 21 | #ifndef USER_USB_RAM 22 | #error "This firmware needs to be compiled with a USER USB setting" 23 | #endif 24 | 25 | unsigned char _sdcc_external_startup (void) __nonbanked { 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/config.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // User Configurations for CH552E USB Rotary Encoder 3 | // =================================================================================== 4 | 5 | #pragma once 6 | 7 | // Pin definitions 8 | #define PIN_NEO P14 // pin connected to NeoPixel 9 | #define PIN_ENC_A P15 // pin connected to rotary encoder A 10 | #define PIN_ENC_B P16 // pin connected to rotary encoder B 11 | #define PIN_ENC_SW P17 // pin connected to rotary encoder switch 12 | 13 | // NeoPixel configuration 14 | #define NEO_GRB // type of pixel: NEO_GRB or NEO_RGB 15 | 16 | // USB device descriptor 17 | #define USB_VENDOR_ID 0x1189 // VID 18 | #define USB_PRODUCT_ID 0x8890 // PID 19 | #define USB_DEVICE_VERSION 0x0100 // v1.0 (BCD-format) 20 | 21 | // USB configuration descriptor 22 | #define USB_MAX_POWER_mA 50 // max power in mA 23 | 24 | // USB descriptor strings 25 | #define MANUFACTURER_STR 'w','a','g','i','m','i','n','a','t','o','r' 26 | #define PRODUCT_STR 'T','i','n','y','K','n','o','b' 27 | #define SERIAL_STR 'C','H','5','5','2','x','H','I','D' 28 | #define INTERFACE_STR 'H','I','D','-','M','o','u','s','e' 29 | -------------------------------------------------------------------------------- /software/custom_knob/src/config.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // User Configurations for CH552E USB Rotary Encoder 3 | // =================================================================================== 4 | 5 | #pragma once 6 | 7 | // Pin definitions 8 | #define PIN_NEO P14 // pin connected to NeoPixel 9 | #define PIN_ENC_A P15 // pin connected to rotary encoder A 10 | #define PIN_ENC_B P16 // pin connected to rotary encoder B 11 | #define PIN_ENC_SW P17 // pin connected to rotary encoder switch 12 | 13 | // NeoPixel configuration 14 | #define NEO_GRB // type of pixel: NEO_GRB or NEO_RGB 15 | 16 | // USB device descriptor 17 | #define USB_VENDOR_ID 0x1189 // VID 18 | #define USB_PRODUCT_ID 0x8890 // PID 19 | #define USB_DEVICE_VERSION 0x0100 // v1.0 (BCD-format) 20 | 21 | // USB configuration descriptor 22 | #define USB_MAX_POWER_mA 50 // max power in mA 23 | 24 | // USB descriptor strings 25 | #define MANUFACTURER_STR 'w','a','g','i','m','i','n','a','t','o','r' 26 | #define PRODUCT_STR 'T','i','n','y','K','n','o','b' 27 | #define SERIAL_STR 'C','H','5','5','2','x','H','I','D' 28 | #define INTERFACE_STR 'H','I','D','-','K','e','y','b','o','a','r','d' 29 | -------------------------------------------------------------------------------- /software/volume_knob/src/config.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // User Configurations for CH552E USB Rotary Encoder 3 | // =================================================================================== 4 | 5 | #pragma once 6 | 7 | // Pin definitions 8 | #define PIN_NEO P14 // pin connected to NeoPixel 9 | #define PIN_ENC_A P15 // pin connected to rotary encoder A 10 | #define PIN_ENC_B P16 // pin connected to rotary encoder B 11 | #define PIN_ENC_SW P17 // pin connected to rotary encoder switch 12 | 13 | // NeoPixel configuration 14 | #define NEO_GRB // type of pixel: NEO_GRB or NEO_RGB 15 | 16 | // USB device descriptor 17 | #define USB_VENDOR_ID 0x1189 // VID 18 | #define USB_PRODUCT_ID 0x8890 // PID 19 | #define USB_DEVICE_VERSION 0x0100 // v1.0 (BCD-format) 20 | 21 | // USB configuration descriptor 22 | #define USB_MAX_POWER_mA 50 // max power in mA 23 | 24 | // USB descriptor strings 25 | #define MANUFACTURER_STR 'w','a','g','i','m','i','n','a','t','o','r' 26 | #define PRODUCT_STR 'T','i','n','y','K','n','o','b' 27 | #define SERIAL_STR 'C','H','5','5','2','x','H','I','D' 28 | #define INTERFACE_STR 'H','I','D','-','K','e','y','b','o','a','r','d' 29 | -------------------------------------------------------------------------------- /software/custom_knob/src/neo.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // NeoPixel (Addressable LED) Functions for CH551, CH552 and CH554 * v1.1 * 3 | // =================================================================================== 4 | // 5 | // Basic control functions for 800kHz addressable LEDs (NeoPixel). A simplified 6 | // protocol is used which should work with most LEDs. 7 | // 8 | // The following must be defined in config.h: 9 | // PIN_NEO - pin connected to DATA-IN of the pixel strip (via a ~330 ohms resistor). 10 | // NEO_GRB - type of pixel: NEO_GRB or NEO_RGB 11 | // System clock frequency must be at least 6 MHz. 12 | // 13 | // Further information: https://github.com/wagiminator/ATtiny13-NeoController 14 | // 2023 by Stefan Wagner: https://github.com/wagiminator 15 | 16 | #pragma once 17 | #include 18 | #include "gpio.h" 19 | #include "delay.h" 20 | #include "config.h" 21 | 22 | #define NEO_init() PIN_low(PIN_NEO);PIN_output(PIN_NEO) // init NeoPixels 23 | #define NEO_latch() DLY_us(281) // latch colors 24 | 25 | void NEO_sendByte(uint8_t data); // send a single byte to the pixels 26 | void NEO_writeColor(uint8_t r, uint8_t g, uint8_t b); // write color to a single pixel 27 | void NEO_writeHue(uint8_t hue, uint8_t bright); // hue (0..191), brightness (0..2) 28 | -------------------------------------------------------------------------------- /software/volume_knob/src/neo.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // NeoPixel (Addressable LED) Functions for CH551, CH552 and CH554 * v1.1 * 3 | // =================================================================================== 4 | // 5 | // Basic control functions for 800kHz addressable LEDs (NeoPixel). A simplified 6 | // protocol is used which should work with most LEDs. 7 | // 8 | // The following must be defined in config.h: 9 | // PIN_NEO - pin connected to DATA-IN of the pixel strip (via a ~330 ohms resistor). 10 | // NEO_GRB - type of pixel: NEO_GRB or NEO_RGB 11 | // System clock frequency must be at least 6 MHz. 12 | // 13 | // Further information: https://github.com/wagiminator/ATtiny13-NeoController 14 | // 2023 by Stefan Wagner: https://github.com/wagiminator 15 | 16 | #pragma once 17 | #include 18 | #include "gpio.h" 19 | #include "delay.h" 20 | #include "config.h" 21 | 22 | #define NEO_init() PIN_low(PIN_NEO);PIN_output(PIN_NEO) // init NeoPixels 23 | #define NEO_latch() DLY_us(281) // latch colors 24 | 25 | void NEO_sendByte(uint8_t data); // send a single byte to the pixels 26 | void NEO_writeColor(uint8_t r, uint8_t g, uint8_t b); // write color to a single pixel 27 | void NEO_writeHue(uint8_t hue, uint8_t bright); // hue (0..191), brightness (0..2) 28 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/neo.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // NeoPixel (Addressable LED) Functions for CH551, CH552 and CH554 * v1.1 * 3 | // =================================================================================== 4 | // 5 | // Basic control functions for 800kHz addressable LEDs (NeoPixel). A simplified 6 | // protocol is used which should work with most LEDs. 7 | // 8 | // The following must be defined in config.h: 9 | // PIN_NEO - pin connected to DATA-IN of the pixel strip (via a ~330 ohms resistor). 10 | // NEO_GRB - type of pixel: NEO_GRB or NEO_RGB 11 | // System clock frequency must be at least 6 MHz. 12 | // 13 | // Further information: https://github.com/wagiminator/ATtiny13-NeoController 14 | // 2023 by Stefan Wagner: https://github.com/wagiminator 15 | 16 | #pragma once 17 | #include 18 | #include "gpio.h" 19 | #include "delay.h" 20 | #include "config.h" 21 | 22 | #define NEO_init() PIN_low(PIN_NEO);PIN_output(PIN_NEO) // init NeoPixels 23 | #define NEO_latch() DLY_us(281) // latch colors 24 | 25 | void NEO_sendByte(uint8_t data); // send a single byte to the pixels 26 | void NEO_writeColor(uint8_t r, uint8_t g, uint8_t b); // write color to a single pixel 27 | void NEO_writeHue(uint8_t hue, uint8_t bright); // hue (0..191), brightness (0..2) 28 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb_consumer.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Consumer Keyboard Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | #include "usb_hid.h" 8 | 9 | // Functions 10 | void CON_press(uint8_t key); // press a consumer key on keyboard 11 | void CON_release(void); // release a consumer key on keyboard 12 | void CON_type(uint8_t key); // press and release a consumer key 13 | 14 | // Consumer Keyboard Keycodes 15 | #define CON_SYS_POWER 0x30 16 | #define CON_SYS_RESET 0x31 17 | #define CON_SYS_SLEEP 0x32 18 | 19 | #define CON_VOL_MUTE 0xE2 20 | #define CON_VOL_UP 0xE9 21 | #define CON_VOL_DOWN 0xEA 22 | 23 | #define CON_MEDIA_PLAY 0xB0 24 | #define CON_MEDIA_PAUSE 0xB1 25 | #define CON_MEDIA_RECORD 0xB2 26 | #define CON_MEDIA_FORWARD 0xB3 27 | #define CON_MEDIA_REWIND 0xB4 28 | #define CON_MEDIA_NEXT 0xB5 29 | #define CON_MEDIA_PREV 0xB6 30 | #define CON_MEDIA_STOP 0xB7 31 | #define CON_MEDIA_EJECT 0xB8 32 | #define CON_MEDIA_RANDOM 0xB9 33 | 34 | #define CON_MENU 0x40 35 | #define CON_MENU_PICK 0x41 36 | #define CON_MENU_UP 0x42 37 | #define CON_MENU_DOWN 0x43 38 | #define CON_MENU_LEFT 0x44 39 | #define CON_MENU_RIGHT 0x45 40 | #define CON_MENU_ESCAPE 0x46 41 | #define CON_MENU_INCR 0x47 42 | #define CON_MENU_DECR 0x48 43 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb_handler.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Handler for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | #include "usb_descr.h" 8 | 9 | // =================================================================================== 10 | // Endpoint Buffer 11 | // =================================================================================== 12 | __xdata __at (EP0_ADDR) uint8_t EP0_buffer[EP0_BUF_SIZE]; 13 | __xdata __at (EP1_ADDR) uint8_t EP1_buffer[EP1_BUF_SIZE]; 14 | 15 | #define USB_setupBuf ((PUSB_SETUP_REQ)EP0_buffer) 16 | extern uint8_t SetupReq; 17 | 18 | // =================================================================================== 19 | // Custom External USB Handler Functions 20 | // =================================================================================== 21 | void HID_setup(void); 22 | void HID_reset(void); 23 | void HID_EP1_IN(void); 24 | 25 | // =================================================================================== 26 | // USB Handler Defines 27 | // =================================================================================== 28 | // Custom USB handler functions 29 | #define USB_INIT_handler HID_setup // init custom endpoints 30 | #define USB_RESET_handler HID_reset // custom USB reset handler 31 | 32 | // Endpoint callback functions 33 | #define EP0_SETUP_callback USB_EP0_SETUP 34 | #define EP0_IN_callback USB_EP0_IN 35 | #define EP0_OUT_callback USB_EP0_OUT 36 | #define EP1_IN_callback HID_EP1_IN 37 | 38 | // =================================================================================== 39 | // Functions 40 | // =================================================================================== 41 | void USB_interrupt(void); 42 | void USB_init(void); 43 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/usb_handler.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Handler for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | #include "usb_descr.h" 8 | 9 | // =================================================================================== 10 | // Endpoint Buffer 11 | // =================================================================================== 12 | __xdata __at (EP0_ADDR) uint8_t EP0_buffer[EP0_BUF_SIZE]; 13 | __xdata __at (EP1_ADDR) uint8_t EP1_buffer[EP1_BUF_SIZE]; 14 | 15 | #define USB_setupBuf ((PUSB_SETUP_REQ)EP0_buffer) 16 | extern uint8_t SetupReq; 17 | 18 | // =================================================================================== 19 | // Custom External USB Handler Functions 20 | // =================================================================================== 21 | void HID_setup(void); 22 | void HID_reset(void); 23 | void HID_EP1_IN(void); 24 | 25 | // =================================================================================== 26 | // USB Handler Defines 27 | // =================================================================================== 28 | // Custom USB handler functions 29 | #define USB_INIT_handler HID_setup // init custom endpoints 30 | #define USB_RESET_handler HID_reset // custom USB reset handler 31 | 32 | // Endpoint callback functions 33 | #define EP0_SETUP_callback USB_EP0_SETUP 34 | #define EP0_IN_callback USB_EP0_IN 35 | #define EP0_OUT_callback USB_EP0_OUT 36 | #define EP1_IN_callback HID_EP1_IN 37 | 38 | // =================================================================================== 39 | // Functions 40 | // =================================================================================== 41 | void USB_interrupt(void); 42 | void USB_init(void); 43 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb_handler.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Handler for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | #include "usb_descr.h" 8 | 9 | // =================================================================================== 10 | // Endpoint Buffer 11 | // =================================================================================== 12 | __xdata __at (EP0_ADDR) uint8_t EP0_buffer[EP0_BUF_SIZE]; 13 | __xdata __at (EP1_ADDR) uint8_t EP1_buffer[EP1_BUF_SIZE]; 14 | __xdata __at (EP2_ADDR) uint8_t EP2_buffer[EP2_BUF_SIZE]; 15 | 16 | #define USB_setupBuf ((PUSB_SETUP_REQ)EP0_buffer) 17 | extern uint8_t SetupReq; 18 | 19 | // =================================================================================== 20 | // Custom External USB Handler Functions 21 | // =================================================================================== 22 | void HID_setup(void); 23 | void HID_reset(void); 24 | void HID_EP1_IN(void); 25 | void HID_EP2_OUT(void); 26 | 27 | // =================================================================================== 28 | // USB Handler Defines 29 | // =================================================================================== 30 | // Custom USB handler functions 31 | #define USB_INIT_handler HID_setup // init custom endpoints 32 | #define USB_RESET_handler HID_reset // custom USB reset handler 33 | 34 | // Endpoint callback functions 35 | #define EP0_SETUP_callback USB_EP0_SETUP 36 | #define EP0_IN_callback USB_EP0_IN 37 | #define EP0_OUT_callback USB_EP0_OUT 38 | #define EP1_IN_callback HID_EP1_IN 39 | #define EP2_OUT_callback HID_EP2_OUT 40 | 41 | // =================================================================================== 42 | // Functions 43 | // =================================================================================== 44 | void USB_interrupt(void); 45 | void USB_init(void); 46 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/usb_mouse.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Standard Mouse Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #include "usb_mouse.h" 6 | #include "usb_hid.h" 7 | #include "usb_handler.h" 8 | 9 | // =================================================================================== 10 | // Mouse HID report 11 | // =================================================================================== 12 | 13 | #define MOUSE_report ((PHID_MOUSE_REPORT_TYPE)HID_report) 14 | #define MOUSE_sendReport() HID_sendReport((uint8_t*)&HID_report, sizeof(HID_report)) 15 | 16 | // HID report typedef 17 | typedef struct _HID_MOUSE_REPORT_TYPE { 18 | uint8_t buttons; // button states 19 | int8_t xmove; // relative movement on the x-axis 20 | int8_t ymove; // relative movement on the y-axis 21 | int8_t wmove; // relative movement of the wheel 22 | } HID_MOUSE_REPORT_TYPE, *PHID_MOUSE_REPORT_TYPE; 23 | 24 | // Initialize HID report 25 | __xdata HID_MOUSE_REPORT_TYPE HID_report = { 26 | .buttons = 0, 27 | .xmove = 0, 28 | .ymove = 0, 29 | .wmove = 0 30 | }; 31 | 32 | // =================================================================================== 33 | // Mouse functions 34 | // =================================================================================== 35 | 36 | // Press mouse button(s) 37 | void MOUSE_press(uint8_t buttons) { 38 | MOUSE_report->buttons |= buttons; // press button(s) 39 | MOUSE_sendReport(); // send HID report 40 | } 41 | 42 | // Release mouse button(s) 43 | void MOUSE_release(uint8_t buttons) { 44 | MOUSE_report->buttons &= ~buttons; // release button(s) 45 | MOUSE_sendReport(); // send HID report 46 | } 47 | 48 | // Move mouse pointer 49 | void MOUSE_move(int8_t xrel, int8_t yrel) { 50 | MOUSE_report->xmove = xrel; // set relative x-movement 51 | MOUSE_report->ymove = yrel; // set relative y-movement 52 | MOUSE_sendReport(); // send HID report 53 | MOUSE_report->xmove = 0; // reset movements 54 | MOUSE_report->ymove = 0; 55 | } 56 | 57 | // Move mouse wheel 58 | void MOUSE_wheel(int8_t rel) { 59 | MOUSE_report->wmove = rel; // set relative wheel movement 60 | MOUSE_sendReport(); // send HID report 61 | MOUSE_report->wmove = 0; // reset movements 62 | } 63 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb_hid.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #include "ch554.h" 6 | #include "usb.h" 7 | #include "usb_hid.h" 8 | #include "usb_descr.h" 9 | #include "usb_handler.h" 10 | 11 | // =================================================================================== 12 | // Variables and Defines 13 | // =================================================================================== 14 | 15 | volatile __bit HID_EP1_writeBusyFlag = 0; // upload pointer busy flag 16 | 17 | // =================================================================================== 18 | // Front End Functions 19 | // =================================================================================== 20 | 21 | // Setup USB HID 22 | void HID_init(void) { 23 | USB_init(); 24 | UEP1_T_LEN = 0; 25 | } 26 | 27 | // Send HID report 28 | void HID_sendReport(__xdata uint8_t* buf, uint8_t len) { 29 | uint8_t i; 30 | while(HID_EP1_writeBusyFlag); // wait for ready to write 31 | for(i=0; i>= 2; 15 | #endif 16 | #if F_CPU <= 3000000 17 | n >>= 2; 18 | #endif 19 | #if F_CPU <= 750000 20 | n >>= 4; 21 | #endif 22 | #endif 23 | 24 | while(n) { // total = 12~13 Fsys cycles, 1uS @Fsys=12MHz 25 | SAFE_MOD++; // 2 Fsys cycles, for higher Fsys, add operation here 26 | #ifdef F_CPU 27 | #if F_CPU >= 14000000 28 | SAFE_MOD++; 29 | #endif 30 | #if F_CPU >= 16000000 31 | SAFE_MOD++; 32 | #endif 33 | #if F_CPU >= 18000000 34 | SAFE_MOD++; 35 | #endif 36 | #if F_CPU >= 20000000 37 | SAFE_MOD++; 38 | #endif 39 | #if F_CPU >= 22000000 40 | SAFE_MOD++; 41 | #endif 42 | #if F_CPU >= 24000000 43 | SAFE_MOD++; 44 | #endif 45 | #if F_CPU >= 26000000 46 | SAFE_MOD++; 47 | #endif 48 | #if F_CPU >= 28000000 49 | SAFE_MOD++; 50 | #endif 51 | #if F_CPU >= 30000000 52 | SAFE_MOD++; 53 | #endif 54 | #if F_CPU >= 32000000 55 | SAFE_MOD++; 56 | #endif 57 | #endif 58 | n--; 59 | } 60 | } 61 | 62 | // =================================================================================== 63 | // Delay in Units of ms 64 | // =================================================================================== 65 | void DLY_ms(uint16_t n) { // delay in ms 66 | while(n) { 67 | DLY_us(1000); 68 | n--; 69 | } 70 | } 71 | 72 | // =================================================================================== 73 | // Delay 20+4*(n-1) Clock Cycles 74 | // =================================================================================== 75 | #pragma callee_saves _delay_more_cycles 76 | void _delay_more_cycles (uint8_t n) __naked { 77 | n; // stop unreferenced arg warning 78 | __asm 79 | .even ; make predictable cycles for jumps 80 | push ar7 ; 2 cycles 81 | mov r7, dpl ; 2 cycles 82 | djnz r7, .+0 ; 2/4 cycles 83 | pop ar7 ; 2 cycles 84 | ret ; 4|5 cycles 85 | __endasm; 86 | } 87 | -------------------------------------------------------------------------------- /software/volume_knob/src/delay.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Delay Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #include "delay.h" 6 | #include "ch554.h" 7 | 8 | // =================================================================================== 9 | // Delay in Units of us 10 | // =================================================================================== 11 | void DLY_us(uint16_t n) { // delay in us 12 | #ifdef F_CPU 13 | #if F_CPU <= 6000000 14 | n >>= 2; 15 | #endif 16 | #if F_CPU <= 3000000 17 | n >>= 2; 18 | #endif 19 | #if F_CPU <= 750000 20 | n >>= 4; 21 | #endif 22 | #endif 23 | 24 | while(n) { // total = 12~13 Fsys cycles, 1uS @Fsys=12MHz 25 | SAFE_MOD++; // 2 Fsys cycles, for higher Fsys, add operation here 26 | #ifdef F_CPU 27 | #if F_CPU >= 14000000 28 | SAFE_MOD++; 29 | #endif 30 | #if F_CPU >= 16000000 31 | SAFE_MOD++; 32 | #endif 33 | #if F_CPU >= 18000000 34 | SAFE_MOD++; 35 | #endif 36 | #if F_CPU >= 20000000 37 | SAFE_MOD++; 38 | #endif 39 | #if F_CPU >= 22000000 40 | SAFE_MOD++; 41 | #endif 42 | #if F_CPU >= 24000000 43 | SAFE_MOD++; 44 | #endif 45 | #if F_CPU >= 26000000 46 | SAFE_MOD++; 47 | #endif 48 | #if F_CPU >= 28000000 49 | SAFE_MOD++; 50 | #endif 51 | #if F_CPU >= 30000000 52 | SAFE_MOD++; 53 | #endif 54 | #if F_CPU >= 32000000 55 | SAFE_MOD++; 56 | #endif 57 | #endif 58 | n--; 59 | } 60 | } 61 | 62 | // =================================================================================== 63 | // Delay in Units of ms 64 | // =================================================================================== 65 | void DLY_ms(uint16_t n) { // delay in ms 66 | while(n) { 67 | DLY_us(1000); 68 | n--; 69 | } 70 | } 71 | 72 | // =================================================================================== 73 | // Delay 20+4*(n-1) Clock Cycles 74 | // =================================================================================== 75 | #pragma callee_saves _delay_more_cycles 76 | void _delay_more_cycles (uint8_t n) __naked { 77 | n; // stop unreferenced arg warning 78 | __asm 79 | .even ; make predictable cycles for jumps 80 | push ar7 ; 2 cycles 81 | mov r7, dpl ; 2 cycles 82 | djnz r7, .+0 ; 2/4 cycles 83 | pop ar7 ; 2 cycles 84 | ret ; 4|5 cycles 85 | __endasm; 86 | } 87 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/delay.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Delay Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #include "delay.h" 6 | #include "ch554.h" 7 | 8 | // =================================================================================== 9 | // Delay in Units of us 10 | // =================================================================================== 11 | void DLY_us(uint16_t n) { // delay in us 12 | #ifdef F_CPU 13 | #if F_CPU <= 6000000 14 | n >>= 2; 15 | #endif 16 | #if F_CPU <= 3000000 17 | n >>= 2; 18 | #endif 19 | #if F_CPU <= 750000 20 | n >>= 4; 21 | #endif 22 | #endif 23 | 24 | while(n) { // total = 12~13 Fsys cycles, 1uS @Fsys=12MHz 25 | SAFE_MOD++; // 2 Fsys cycles, for higher Fsys, add operation here 26 | #ifdef F_CPU 27 | #if F_CPU >= 14000000 28 | SAFE_MOD++; 29 | #endif 30 | #if F_CPU >= 16000000 31 | SAFE_MOD++; 32 | #endif 33 | #if F_CPU >= 18000000 34 | SAFE_MOD++; 35 | #endif 36 | #if F_CPU >= 20000000 37 | SAFE_MOD++; 38 | #endif 39 | #if F_CPU >= 22000000 40 | SAFE_MOD++; 41 | #endif 42 | #if F_CPU >= 24000000 43 | SAFE_MOD++; 44 | #endif 45 | #if F_CPU >= 26000000 46 | SAFE_MOD++; 47 | #endif 48 | #if F_CPU >= 28000000 49 | SAFE_MOD++; 50 | #endif 51 | #if F_CPU >= 30000000 52 | SAFE_MOD++; 53 | #endif 54 | #if F_CPU >= 32000000 55 | SAFE_MOD++; 56 | #endif 57 | #endif 58 | n--; 59 | } 60 | } 61 | 62 | // =================================================================================== 63 | // Delay in Units of ms 64 | // =================================================================================== 65 | void DLY_ms(uint16_t n) { // delay in ms 66 | while(n) { 67 | DLY_us(1000); 68 | n--; 69 | } 70 | } 71 | 72 | // =================================================================================== 73 | // Delay 20+4*(n-1) Clock Cycles 74 | // =================================================================================== 75 | #pragma callee_saves _delay_more_cycles 76 | void _delay_more_cycles (uint8_t n) __naked { 77 | n; // stop unreferenced arg warning 78 | __asm 79 | .even ; make predictable cycles for jumps 80 | push ar7 ; 2 cycles 81 | mov r7, dpl ; 2 cycles 82 | djnz r7, .+0 ; 2/4 cycles 83 | pop ar7 ; 2 cycles 84 | ret ; 4|5 cycles 85 | __endasm; 86 | } 87 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb_descr.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Descriptors and Definitions 3 | // =================================================================================== 4 | // 5 | // Definition of USB descriptors and endpoint sizes and addresses. 6 | // 7 | // The following must be defined in config.h: 8 | // USB_VENDOR_ID - Vendor ID (16-bit word) 9 | // USB_PRODUCT_ID - Product ID (16-bit word) 10 | // USB_DEVICE_VERSION - Device version (16-bit BCD) 11 | // USB_MAX_POWER_mA - Device max power in mA 12 | // All string descriptors. 13 | 14 | #pragma once 15 | #include 16 | #include "usb.h" 17 | 18 | // =================================================================================== 19 | // USB Endpoint Addresses and Sizes 20 | // =================================================================================== 21 | #define EP0_SIZE 8 22 | #define EP1_SIZE 8 23 | 24 | #define EP0_ADDR 0 25 | #define EP1_ADDR (EP0_ADDR + EP0_BUF_SIZE) 26 | 27 | #define EP0_BUF_SIZE EP_BUF_SIZE(EP0_SIZE) 28 | #define EP1_BUF_SIZE EP_BUF_SIZE(EP1_SIZE) 29 | 30 | #define EP_BUF_SIZE(x) (x+2<64 ? x+2 : 64) 31 | 32 | // =================================================================================== 33 | // Device and Configuration Descriptors 34 | // =================================================================================== 35 | typedef struct _USB_CFG_DESCR_HID { 36 | USB_CFG_DESCR config; 37 | USB_ITF_DESCR interface0; 38 | USB_HID_DESCR hid0; 39 | USB_ENDP_DESCR ep1IN; 40 | } USB_CFG_DESCR_HID, *PUSB_CFG_DESCR_HID; 41 | typedef USB_CFG_DESCR_HID __xdata *PXUSB_CFG_DESCR_HID; 42 | 43 | extern __code USB_DEV_DESCR DevDescr; 44 | extern __code USB_CFG_DESCR_HID CfgDescr; 45 | 46 | // =================================================================================== 47 | // HID Report Descriptors 48 | // =================================================================================== 49 | extern __code uint8_t ReportDescr[]; 50 | extern __code uint8_t ReportDescrLen; 51 | 52 | #define USB_REPORT_DESCR ReportDescr 53 | #define USB_REPORT_DESCR_LEN ReportDescrLen 54 | 55 | // =================================================================================== 56 | // String Descriptors 57 | // =================================================================================== 58 | extern __code uint16_t LangDescr[]; 59 | extern __code uint16_t ManufDescr[]; 60 | extern __code uint16_t ProdDescr[]; 61 | extern __code uint16_t SerDescr[]; 62 | extern __code uint16_t InterfDescr[]; 63 | 64 | #define USB_STR_DESCR_i0 (uint8_t*)LangDescr 65 | #define USB_STR_DESCR_i1 (uint8_t*)ManufDescr 66 | #define USB_STR_DESCR_i2 (uint8_t*)ProdDescr 67 | #define USB_STR_DESCR_i3 (uint8_t*)SerDescr 68 | #define USB_STR_DESCR_i4 (uint8_t*)InterfDescr 69 | #define USB_STR_DESCR_ix (uint8_t*)SerDescr 70 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/usb_descr.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Descriptors and Definitions 3 | // =================================================================================== 4 | // 5 | // Definition of USB descriptors and endpoint sizes and addresses. 6 | // 7 | // The following must be defined in config.h: 8 | // USB_VENDOR_ID - Vendor ID (16-bit word) 9 | // USB_PRODUCT_ID - Product ID (16-bit word) 10 | // USB_DEVICE_VERSION - Device version (16-bit BCD) 11 | // USB_MAX_POWER_mA - Device max power in mA 12 | // All string descriptors. 13 | 14 | #pragma once 15 | #include 16 | #include "usb.h" 17 | 18 | // =================================================================================== 19 | // USB Endpoint Addresses and Sizes 20 | // =================================================================================== 21 | #define EP0_SIZE 8 22 | #define EP1_SIZE 8 23 | 24 | #define EP0_ADDR 0 25 | #define EP1_ADDR (EP0_ADDR + EP0_BUF_SIZE) 26 | 27 | #define EP0_BUF_SIZE EP_BUF_SIZE(EP0_SIZE) 28 | #define EP1_BUF_SIZE EP_BUF_SIZE(EP1_SIZE) 29 | 30 | #define EP_BUF_SIZE(x) (x+2<64 ? x+2 : 64) 31 | 32 | // =================================================================================== 33 | // Device and Configuration Descriptors 34 | // =================================================================================== 35 | typedef struct _USB_CFG_DESCR_HID { 36 | USB_CFG_DESCR config; 37 | USB_ITF_DESCR interface0; 38 | USB_HID_DESCR hid0; 39 | USB_ENDP_DESCR ep1IN; 40 | } USB_CFG_DESCR_HID, *PUSB_CFG_DESCR_HID; 41 | typedef USB_CFG_DESCR_HID __xdata *PXUSB_CFG_DESCR_HID; 42 | 43 | extern __code USB_DEV_DESCR DevDescr; 44 | extern __code USB_CFG_DESCR_HID CfgDescr; 45 | 46 | // =================================================================================== 47 | // HID Report Descriptors 48 | // =================================================================================== 49 | extern __code uint8_t ReportDescr[]; 50 | extern __code uint8_t ReportDescrLen; 51 | 52 | #define USB_REPORT_DESCR ReportDescr 53 | #define USB_REPORT_DESCR_LEN ReportDescrLen 54 | 55 | // =================================================================================== 56 | // String Descriptors 57 | // =================================================================================== 58 | extern __code uint16_t LangDescr[]; 59 | extern __code uint16_t ManufDescr[]; 60 | extern __code uint16_t ProdDescr[]; 61 | extern __code uint16_t SerDescr[]; 62 | extern __code uint16_t InterfDescr[]; 63 | 64 | #define USB_STR_DESCR_i0 (uint8_t*)LangDescr 65 | #define USB_STR_DESCR_i1 (uint8_t*)ManufDescr 66 | #define USB_STR_DESCR_i2 (uint8_t*)ProdDescr 67 | #define USB_STR_DESCR_i3 (uint8_t*)SerDescr 68 | #define USB_STR_DESCR_i4 (uint8_t*)InterfDescr 69 | #define USB_STR_DESCR_ix (uint8_t*)SerDescr 70 | -------------------------------------------------------------------------------- /software/custom_knob/makefile: -------------------------------------------------------------------------------- 1 | # =================================================================================== 2 | # Project: USB Rotary Encoder for CH551, CH552, CH554 3 | # Author: Stefan Wagner 4 | # Year: 2023 5 | # URL: https://github.com/wagiminator 6 | # =================================================================================== 7 | # Type "make help" in the command line. 8 | # =================================================================================== 9 | 10 | # Input and Output File Names 11 | SKETCH = custom_knob.c 12 | TARGET = custom_knob 13 | INCLUDE = src 14 | 15 | # Microcontroller Settings 16 | FREQ_SYS = 16000000 17 | XRAM_LOC = 0x0100 18 | XRAM_SIZE = 0x0300 19 | CODE_SIZE = 0x3800 20 | 21 | # Toolchain 22 | CC = sdcc 23 | OBJCOPY = objcopy 24 | PACK_HEX = packihx 25 | WCHISP ?= python3 tools/chprog.py 26 | 27 | # Compiler Flags 28 | CFLAGS = -mmcs51 --model-small --no-xinit-opt 29 | CFLAGS += --xram-size $(XRAM_SIZE) --xram-loc $(XRAM_LOC) --code-size $(CODE_SIZE) 30 | CFLAGS += -I$(INCLUDE) -DF_CPU=$(FREQ_SYS) 31 | CFILES = $(SKETCH) $(wildcard $(INCLUDE)/*.c) 32 | RFILES = $(CFILES:.c=.rel) 33 | CLEAN = rm -f *.ihx *.lk *.map *.mem *.lst *.rel *.rst *.sym *.asm *.adb 34 | 35 | # Symbolic Targets 36 | help: 37 | @echo "Use the following commands:" 38 | @echo "make all compile, build and keep all files" 39 | @echo "make hex compile and build $(TARGET).hex" 40 | @echo "make bin compile and build $(TARGET).bin" 41 | @echo "make flash compile, build and upload $(TARGET).bin to device" 42 | @echo "make clean remove all build files" 43 | 44 | %.rel : %.c 45 | @echo "Compiling $< ..." 46 | @$(CC) -c $(CFLAGS) $< 47 | 48 | $(TARGET).ihx: $(RFILES) 49 | @echo "Building $(TARGET).ihx ..." 50 | @$(CC) $(notdir $(RFILES)) $(CFLAGS) -o $(TARGET).ihx 51 | 52 | $(TARGET).hex: $(TARGET).ihx 53 | @echo "Building $(TARGET).hex ..." 54 | @$(PACK_HEX) $(TARGET).ihx > $(TARGET).hex 55 | 56 | $(TARGET).bin: $(TARGET).ihx 57 | @echo "Building $(TARGET).bin ..." 58 | @$(OBJCOPY) -I ihex -O binary $(TARGET).ihx $(TARGET).bin 59 | 60 | flash: $(TARGET).bin size removetemp 61 | @echo "Uploading to CH55x ..." 62 | @$(WCHISP) $(TARGET).bin 63 | 64 | all: $(TARGET).bin $(TARGET).hex size 65 | 66 | hex: $(TARGET).hex size removetemp 67 | 68 | bin: $(TARGET).bin size removetemp 69 | 70 | bin-hex: $(TARGET).bin $(TARGET).hex size removetemp 71 | 72 | install: flash 73 | 74 | size: 75 | @echo "------------------" 76 | @echo "FLASH: $(shell awk '$$1 == "ROM/EPROM/FLASH" {print $$4}' $(TARGET).mem) bytes" 77 | @echo "IRAM: $(shell awk '$$1 == "Stack" {print 248-$$10}' $(TARGET).mem) bytes" 78 | @echo "XRAM: $(shell awk '$$1 == "EXTERNAL" {print $(XRAM_LOC)+$$5}' $(TARGET).mem) bytes" 79 | @echo "------------------" 80 | 81 | removetemp: 82 | @echo "Removing temporary files ..." 83 | @$(CLEAN) 84 | 85 | clean: 86 | @echo "Cleaning all up ..." 87 | @$(CLEAN) 88 | @rm -f $(TARGET).hex $(TARGET).bin 89 | -------------------------------------------------------------------------------- /software/volume_knob/makefile: -------------------------------------------------------------------------------- 1 | # =================================================================================== 2 | # Project: USB Rotary Encoder for CH551, CH552, CH554 3 | # Author: Stefan Wagner 4 | # Year: 2023 5 | # URL: https://github.com/wagiminator 6 | # =================================================================================== 7 | # Type "make help" in the command line. 8 | # =================================================================================== 9 | 10 | # Input and Output File Names 11 | SKETCH = volume_knob.c 12 | TARGET = volume_knob 13 | INCLUDE = src 14 | 15 | # Microcontroller Settings 16 | FREQ_SYS = 16000000 17 | XRAM_LOC = 0x0100 18 | XRAM_SIZE = 0x0300 19 | CODE_SIZE = 0x3800 20 | 21 | # Toolchain 22 | CC = sdcc 23 | OBJCOPY = objcopy 24 | PACK_HEX = packihx 25 | WCHISP ?= python3 tools/chprog.py 26 | 27 | # Compiler Flags 28 | CFLAGS = -mmcs51 --model-small --no-xinit-opt 29 | CFLAGS += --xram-size $(XRAM_SIZE) --xram-loc $(XRAM_LOC) --code-size $(CODE_SIZE) 30 | CFLAGS += -I$(INCLUDE) -DF_CPU=$(FREQ_SYS) 31 | CFILES = $(SKETCH) $(wildcard $(INCLUDE)/*.c) 32 | RFILES = $(CFILES:.c=.rel) 33 | CLEAN = rm -f *.ihx *.lk *.map *.mem *.lst *.rel *.rst *.sym *.asm *.adb 34 | 35 | # Symbolic Targets 36 | help: 37 | @echo "Use the following commands:" 38 | @echo "make all compile, build and keep all files" 39 | @echo "make hex compile and build $(TARGET).hex" 40 | @echo "make bin compile and build $(TARGET).bin" 41 | @echo "make flash compile, build and upload $(TARGET).bin to device" 42 | @echo "make clean remove all build files" 43 | 44 | %.rel : %.c 45 | @echo "Compiling $< ..." 46 | @$(CC) -c $(CFLAGS) $< 47 | 48 | $(TARGET).ihx: $(RFILES) 49 | @echo "Building $(TARGET).ihx ..." 50 | @$(CC) $(notdir $(RFILES)) $(CFLAGS) -o $(TARGET).ihx 51 | 52 | $(TARGET).hex: $(TARGET).ihx 53 | @echo "Building $(TARGET).hex ..." 54 | @$(PACK_HEX) $(TARGET).ihx > $(TARGET).hex 55 | 56 | $(TARGET).bin: $(TARGET).ihx 57 | @echo "Building $(TARGET).bin ..." 58 | @$(OBJCOPY) -I ihex -O binary $(TARGET).ihx $(TARGET).bin 59 | 60 | flash: $(TARGET).bin size removetemp 61 | @echo "Uploading to CH55x ..." 62 | @$(WCHISP) $(TARGET).bin 63 | 64 | all: $(TARGET).bin $(TARGET).hex size 65 | 66 | hex: $(TARGET).hex size removetemp 67 | 68 | bin: $(TARGET).bin size removetemp 69 | 70 | bin-hex: $(TARGET).bin $(TARGET).hex size removetemp 71 | 72 | install: flash 73 | 74 | size: 75 | @echo "------------------" 76 | @echo "FLASH: $(shell awk '$$1 == "ROM/EPROM/FLASH" {print $$4}' $(TARGET).mem) bytes" 77 | @echo "IRAM: $(shell awk '$$1 == "Stack" {print 248-$$10}' $(TARGET).mem) bytes" 78 | @echo "XRAM: $(shell awk '$$1 == "EXTERNAL" {print $(XRAM_LOC)+$$5}' $(TARGET).mem) bytes" 79 | @echo "------------------" 80 | 81 | removetemp: 82 | @echo "Removing temporary files ..." 83 | @$(CLEAN) 84 | 85 | clean: 86 | @echo "Cleaning all up ..." 87 | @$(CLEAN) 88 | @rm -f $(TARGET).hex $(TARGET).bin 89 | -------------------------------------------------------------------------------- /software/mousewheel_knob/makefile: -------------------------------------------------------------------------------- 1 | # =================================================================================== 2 | # Project: USB Rotary Encoder for CH551, CH552, CH554 3 | # Author: Stefan Wagner 4 | # Year: 2023 5 | # URL: https://github.com/wagiminator 6 | # =================================================================================== 7 | # Type "make help" in the command line. 8 | # =================================================================================== 9 | 10 | # Input and Output File Names 11 | SKETCH = mousewheel_knob.c 12 | TARGET = mousewheel_knob 13 | INCLUDE = src 14 | 15 | # Microcontroller Settings 16 | FREQ_SYS = 16000000 17 | XRAM_LOC = 0x0100 18 | XRAM_SIZE = 0x0300 19 | CODE_SIZE = 0x3800 20 | 21 | # Toolchain 22 | CC = sdcc 23 | OBJCOPY = objcopy 24 | PACK_HEX = packihx 25 | WCHISP ?= python3 tools/chprog.py 26 | 27 | # Compiler Flags 28 | CFLAGS = -mmcs51 --model-small --no-xinit-opt 29 | CFLAGS += --xram-size $(XRAM_SIZE) --xram-loc $(XRAM_LOC) --code-size $(CODE_SIZE) 30 | CFLAGS += -I$(INCLUDE) -DF_CPU=$(FREQ_SYS) 31 | CFILES = $(SKETCH) $(wildcard $(INCLUDE)/*.c) 32 | RFILES = $(CFILES:.c=.rel) 33 | CLEAN = rm -f *.ihx *.lk *.map *.mem *.lst *.rel *.rst *.sym *.asm *.adb 34 | 35 | # Symbolic Targets 36 | help: 37 | @echo "Use the following commands:" 38 | @echo "make all compile, build and keep all files" 39 | @echo "make hex compile and build $(TARGET).hex" 40 | @echo "make bin compile and build $(TARGET).bin" 41 | @echo "make flash compile, build and upload $(TARGET).bin to device" 42 | @echo "make clean remove all build files" 43 | 44 | %.rel : %.c 45 | @echo "Compiling $< ..." 46 | @$(CC) -c $(CFLAGS) $< 47 | 48 | $(TARGET).ihx: $(RFILES) 49 | @echo "Building $(TARGET).ihx ..." 50 | @$(CC) $(notdir $(RFILES)) $(CFLAGS) -o $(TARGET).ihx 51 | 52 | $(TARGET).hex: $(TARGET).ihx 53 | @echo "Building $(TARGET).hex ..." 54 | @$(PACK_HEX) $(TARGET).ihx > $(TARGET).hex 55 | 56 | $(TARGET).bin: $(TARGET).ihx 57 | @echo "Building $(TARGET).bin ..." 58 | @$(OBJCOPY) -I ihex -O binary $(TARGET).ihx $(TARGET).bin 59 | 60 | flash: $(TARGET).bin size removetemp 61 | @echo "Uploading to CH55x ..." 62 | @$(WCHISP) $(TARGET).bin 63 | 64 | all: $(TARGET).bin $(TARGET).hex size 65 | 66 | hex: $(TARGET).hex size removetemp 67 | 68 | bin: $(TARGET).bin size removetemp 69 | 70 | bin-hex: $(TARGET).bin $(TARGET).hex size removetemp 71 | 72 | install: flash 73 | 74 | size: 75 | @echo "------------------" 76 | @echo "FLASH: $(shell awk '$$1 == "ROM/EPROM/FLASH" {print $$4}' $(TARGET).mem) bytes" 77 | @echo "IRAM: $(shell awk '$$1 == "Stack" {print 248-$$10}' $(TARGET).mem) bytes" 78 | @echo "XRAM: $(shell awk '$$1 == "EXTERNAL" {print $(XRAM_LOC)+$$5}' $(TARGET).mem) bytes" 79 | @echo "------------------" 80 | 81 | removetemp: 82 | @echo "Removing temporary files ..." 83 | @$(CLEAN) 84 | 85 | clean: 86 | @echo "Cleaning all up ..." 87 | @$(CLEAN) 88 | @rm -f $(TARGET).hex $(TARGET).bin 89 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb_descr.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Descriptors and Definitions 3 | // =================================================================================== 4 | // 5 | // Definition of USB descriptors and endpoint sizes and addresses. 6 | // 7 | // The following must be defined in config.h: 8 | // USB_VENDOR_ID - Vendor ID (16-bit word) 9 | // USB_PRODUCT_ID - Product ID (16-bit word) 10 | // USB_DEVICE_VERSION - Device version (16-bit BCD) 11 | // USB_MAX_POWER_mA - Device max power in mA 12 | // All string descriptors. 13 | 14 | #pragma once 15 | #include 16 | #include "usb.h" 17 | #include "config.h" 18 | 19 | // =================================================================================== 20 | // USB Endpoint Addresses and Sizes 21 | // =================================================================================== 22 | #define EP0_SIZE 8 23 | #define EP1_SIZE 8 24 | #define EP2_SIZE 8 25 | 26 | #define EP0_ADDR 0 27 | #define EP1_ADDR (EP0_ADDR + EP0_BUF_SIZE) 28 | #define EP2_ADDR (EP1_ADDR + EP1_BUF_SIZE) 29 | 30 | #define EP0_BUF_SIZE EP_BUF_SIZE(EP0_SIZE) 31 | #define EP1_BUF_SIZE EP_BUF_SIZE(EP1_SIZE) 32 | #define EP2_BUF_SIZE EP_BUF_SIZE(EP2_SIZE) 33 | 34 | #define EP_BUF_SIZE(x) (x+2<64 ? x+2 : 64) 35 | 36 | // =================================================================================== 37 | // Device and Configuration Descriptors 38 | // =================================================================================== 39 | typedef struct _USB_CFG_DESCR_HID { 40 | USB_CFG_DESCR config; 41 | USB_ITF_DESCR interface0; 42 | USB_HID_DESCR hid0; 43 | USB_ENDP_DESCR ep1IN; 44 | USB_ENDP_DESCR ep2OUT; 45 | } USB_CFG_DESCR_HID, *PUSB_CFG_DESCR_HID; 46 | typedef USB_CFG_DESCR_HID __xdata *PXUSB_CFG_DESCR_HID; 47 | 48 | extern __code USB_DEV_DESCR DevDescr; 49 | extern __code USB_CFG_DESCR_HID CfgDescr; 50 | 51 | // =================================================================================== 52 | // HID Report Descriptors 53 | // =================================================================================== 54 | extern __code uint8_t ReportDescr[]; 55 | extern __code uint8_t ReportDescrLen; 56 | 57 | #define USB_REPORT_DESCR ReportDescr 58 | #define USB_REPORT_DESCR_LEN ReportDescrLen 59 | 60 | // =================================================================================== 61 | // String Descriptors 62 | // =================================================================================== 63 | extern __code uint16_t LangDescr[]; 64 | extern __code uint16_t ManufDescr[]; 65 | extern __code uint16_t ProdDescr[]; 66 | extern __code uint16_t SerDescr[]; 67 | extern __code uint16_t InterfDescr[]; 68 | 69 | #define USB_STR_DESCR_i0 (uint8_t*)LangDescr 70 | #define USB_STR_DESCR_i1 (uint8_t*)ManufDescr 71 | #define USB_STR_DESCR_i2 (uint8_t*)ProdDescr 72 | #define USB_STR_DESCR_i3 (uint8_t*)SerDescr 73 | #define USB_STR_DESCR_i4 (uint8_t*)InterfDescr 74 | #define USB_STR_DESCR_ix (uint8_t*)SerDescr 75 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb_hid.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #include "ch554.h" 6 | #include "usb.h" 7 | #include "usb_hid.h" 8 | #include "usb_descr.h" 9 | 10 | // =================================================================================== 11 | // Variables and Defines 12 | // =================================================================================== 13 | 14 | volatile __bit HID_EP1_writeBusyFlag = 0; // upload pointer busy flag 15 | 16 | // =================================================================================== 17 | // Front End Functions 18 | // =================================================================================== 19 | 20 | // Setup USB HID 21 | void HID_init(void) { 22 | USB_init(); 23 | UEP1_T_LEN = 0; 24 | } 25 | 26 | // Send HID report 27 | void HID_sendReport(__xdata uint8_t* buf, uint8_t len) { 28 | uint8_t i; 29 | while(HID_EP1_writeBusyFlag); // wait for ready to write 30 | for(i=0; i 7 | 8 | void DLY_us(uint16_t n); // delay in units of us 9 | void DLY_ms(uint16_t n); // delay in units of ms 10 | 11 | // Delay clock cycles (max. 1039) 12 | // (need to find a smarter way...) 13 | #define DLY_cycles(n) \ 14 | (n == 1 ? (_delay_cycles_1()) : \ 15 | (n == 2 ? (_delay_cycles_2()) : \ 16 | (n == 3 ? (_delay_cycles_3()) : \ 17 | (n == 4 ? (_delay_cycles_4()) : \ 18 | (n == 5 ? (_delay_cycles_5()) : \ 19 | (n == 6 ? (_delay_cycles_6()) : \ 20 | (n == 7 ? (_delay_cycles_7()) : \ 21 | (n == 8 ? (_delay_cycles_8()) : \ 22 | (n == 9 ? (_delay_cycles_9()) : \ 23 | (n == 10 ? (_delay_cycles_10()) : \ 24 | (n == 11 ? (_delay_cycles_11()) : \ 25 | (n == 12 ? (_delay_cycles_12()) : \ 26 | (n == 13 ? (_delay_cycles_13()) : \ 27 | (n == 14 ? (_delay_cycles_14()) : \ 28 | (n == 15 ? (_delay_cycles_15()) : \ 29 | (n == 16 ? (_delay_cycles_16()) : \ 30 | (n == 17 ? (_delay_cycles_17()) : \ 31 | (n == 18 ? (_delay_cycles_18()) : \ 32 | (n == 19 ? (_delay_cycles_19()) : \ 33 | ((n-20)%4 == 0 ? _delay_more_cycles(((n-20)/4)+1) : \ 34 | ((n-20)%4 == 1 ? _delay_more_cycles_1(((n-20)/4)+1) : \ 35 | ((n-20)%4 == 2 ? _delay_more_cycles_2(((n-20)/4)+1) : \ 36 | ((n-20)%4 == 3 ? _delay_more_cycles_3(((n-20)/4)+1) : \ 37 | (0)))))))))))))))))))))))) 38 | 39 | #define _delay_less_cycles(n) _delay_cycles_##n() 40 | 41 | void _delay_more_cycles(uint8_t n); 42 | 43 | inline void _delay_cycles_1(void) { 44 | __asm__("nop"); 45 | } 46 | 47 | inline void _delay_cycles_2(void) { 48 | _delay_cycles_1(); 49 | _delay_cycles_1(); 50 | } 51 | 52 | inline void _delay_cycles_3(void) { 53 | _delay_cycles_2(); 54 | _delay_cycles_1(); 55 | } 56 | 57 | inline void _delay_cycles_4(void) { 58 | _delay_cycles_3(); 59 | _delay_cycles_1(); 60 | } 61 | 62 | inline void _delay_cycles_5(void) { 63 | _delay_cycles_4(); 64 | _delay_cycles_1(); 65 | } 66 | 67 | inline void _delay_cycles_6(void) { 68 | _delay_cycles_5(); 69 | _delay_cycles_1(); 70 | } 71 | 72 | inline void _delay_cycles_7(void) { 73 | _delay_cycles_6(); 74 | _delay_cycles_1(); 75 | } 76 | 77 | inline void _delay_cycles_8(void) { 78 | _delay_cycles_7(); 79 | _delay_cycles_1(); 80 | } 81 | 82 | inline void _delay_cycles_9(void) { 83 | _delay_cycles_8(); 84 | _delay_cycles_1(); 85 | } 86 | 87 | inline void _delay_cycles_10(void) { 88 | _delay_cycles_9(); 89 | _delay_cycles_1(); 90 | } 91 | 92 | inline void _delay_cycles_11(void) { 93 | _delay_cycles_10(); 94 | _delay_cycles_1(); 95 | } 96 | 97 | inline void _delay_cycles_12(void) { 98 | __asm 99 | push a 100 | push b 101 | div ab 102 | pop b 103 | pop a 104 | __endasm; 105 | } 106 | 107 | inline void _delay_cycles_13(void) { 108 | _delay_cycles_12(); 109 | _delay_cycles_1(); 110 | } 111 | 112 | inline void _delay_cycles_14(void) { 113 | _delay_cycles_12(); 114 | _delay_cycles_2(); 115 | } 116 | 117 | inline void _delay_cycles_15(void) { 118 | _delay_cycles_12(); 119 | _delay_cycles_3(); 120 | } 121 | 122 | inline void _delay_cycles_16(void) { 123 | __asm 124 | push a 125 | push b 126 | div ab 127 | div ab 128 | pop b 129 | pop a 130 | __endasm; 131 | } 132 | 133 | inline void _delay_cycles_17(void) { 134 | _delay_cycles_16(); 135 | _delay_cycles_1(); 136 | } 137 | 138 | inline void _delay_cycles_18(void) { 139 | _delay_cycles_16(); 140 | _delay_cycles_2(); 141 | } 142 | 143 | inline void _delay_cycles_19(void) { 144 | _delay_cycles_16(); 145 | _delay_cycles_3(); 146 | } 147 | 148 | inline void _delay_more_cycles_1(uint8_t n) { 149 | _delay_more_cycles(n); 150 | _delay_cycles_1(); 151 | } 152 | 153 | inline void _delay_more_cycles_2(uint8_t n) { 154 | _delay_more_cycles(n); 155 | _delay_cycles_2(); 156 | } 157 | 158 | inline void _delay_more_cycles_3(uint8_t n) { 159 | _delay_more_cycles(n); 160 | _delay_cycles_3(); 161 | } 162 | -------------------------------------------------------------------------------- /software/volume_knob/src/delay.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Delay Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | 8 | void DLY_us(uint16_t n); // delay in units of us 9 | void DLY_ms(uint16_t n); // delay in units of ms 10 | 11 | // Delay clock cycles (max. 1039) 12 | // (need to find a smarter way...) 13 | #define DLY_cycles(n) \ 14 | (n == 1 ? (_delay_cycles_1()) : \ 15 | (n == 2 ? (_delay_cycles_2()) : \ 16 | (n == 3 ? (_delay_cycles_3()) : \ 17 | (n == 4 ? (_delay_cycles_4()) : \ 18 | (n == 5 ? (_delay_cycles_5()) : \ 19 | (n == 6 ? (_delay_cycles_6()) : \ 20 | (n == 7 ? (_delay_cycles_7()) : \ 21 | (n == 8 ? (_delay_cycles_8()) : \ 22 | (n == 9 ? (_delay_cycles_9()) : \ 23 | (n == 10 ? (_delay_cycles_10()) : \ 24 | (n == 11 ? (_delay_cycles_11()) : \ 25 | (n == 12 ? (_delay_cycles_12()) : \ 26 | (n == 13 ? (_delay_cycles_13()) : \ 27 | (n == 14 ? (_delay_cycles_14()) : \ 28 | (n == 15 ? (_delay_cycles_15()) : \ 29 | (n == 16 ? (_delay_cycles_16()) : \ 30 | (n == 17 ? (_delay_cycles_17()) : \ 31 | (n == 18 ? (_delay_cycles_18()) : \ 32 | (n == 19 ? (_delay_cycles_19()) : \ 33 | ((n-20)%4 == 0 ? _delay_more_cycles(((n-20)/4)+1) : \ 34 | ((n-20)%4 == 1 ? _delay_more_cycles_1(((n-20)/4)+1) : \ 35 | ((n-20)%4 == 2 ? _delay_more_cycles_2(((n-20)/4)+1) : \ 36 | ((n-20)%4 == 3 ? _delay_more_cycles_3(((n-20)/4)+1) : \ 37 | (0)))))))))))))))))))))))) 38 | 39 | #define _delay_less_cycles(n) _delay_cycles_##n() 40 | 41 | void _delay_more_cycles(uint8_t n); 42 | 43 | inline void _delay_cycles_1(void) { 44 | __asm__("nop"); 45 | } 46 | 47 | inline void _delay_cycles_2(void) { 48 | _delay_cycles_1(); 49 | _delay_cycles_1(); 50 | } 51 | 52 | inline void _delay_cycles_3(void) { 53 | _delay_cycles_2(); 54 | _delay_cycles_1(); 55 | } 56 | 57 | inline void _delay_cycles_4(void) { 58 | _delay_cycles_3(); 59 | _delay_cycles_1(); 60 | } 61 | 62 | inline void _delay_cycles_5(void) { 63 | _delay_cycles_4(); 64 | _delay_cycles_1(); 65 | } 66 | 67 | inline void _delay_cycles_6(void) { 68 | _delay_cycles_5(); 69 | _delay_cycles_1(); 70 | } 71 | 72 | inline void _delay_cycles_7(void) { 73 | _delay_cycles_6(); 74 | _delay_cycles_1(); 75 | } 76 | 77 | inline void _delay_cycles_8(void) { 78 | _delay_cycles_7(); 79 | _delay_cycles_1(); 80 | } 81 | 82 | inline void _delay_cycles_9(void) { 83 | _delay_cycles_8(); 84 | _delay_cycles_1(); 85 | } 86 | 87 | inline void _delay_cycles_10(void) { 88 | _delay_cycles_9(); 89 | _delay_cycles_1(); 90 | } 91 | 92 | inline void _delay_cycles_11(void) { 93 | _delay_cycles_10(); 94 | _delay_cycles_1(); 95 | } 96 | 97 | inline void _delay_cycles_12(void) { 98 | __asm 99 | push a 100 | push b 101 | div ab 102 | pop b 103 | pop a 104 | __endasm; 105 | } 106 | 107 | inline void _delay_cycles_13(void) { 108 | _delay_cycles_12(); 109 | _delay_cycles_1(); 110 | } 111 | 112 | inline void _delay_cycles_14(void) { 113 | _delay_cycles_12(); 114 | _delay_cycles_2(); 115 | } 116 | 117 | inline void _delay_cycles_15(void) { 118 | _delay_cycles_12(); 119 | _delay_cycles_3(); 120 | } 121 | 122 | inline void _delay_cycles_16(void) { 123 | __asm 124 | push a 125 | push b 126 | div ab 127 | div ab 128 | pop b 129 | pop a 130 | __endasm; 131 | } 132 | 133 | inline void _delay_cycles_17(void) { 134 | _delay_cycles_16(); 135 | _delay_cycles_1(); 136 | } 137 | 138 | inline void _delay_cycles_18(void) { 139 | _delay_cycles_16(); 140 | _delay_cycles_2(); 141 | } 142 | 143 | inline void _delay_cycles_19(void) { 144 | _delay_cycles_16(); 145 | _delay_cycles_3(); 146 | } 147 | 148 | inline void _delay_more_cycles_1(uint8_t n) { 149 | _delay_more_cycles(n); 150 | _delay_cycles_1(); 151 | } 152 | 153 | inline void _delay_more_cycles_2(uint8_t n) { 154 | _delay_more_cycles(n); 155 | _delay_cycles_2(); 156 | } 157 | 158 | inline void _delay_more_cycles_3(uint8_t n) { 159 | _delay_more_cycles(n); 160 | _delay_cycles_3(); 161 | } 162 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/delay.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Delay Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | 8 | void DLY_us(uint16_t n); // delay in units of us 9 | void DLY_ms(uint16_t n); // delay in units of ms 10 | 11 | // Delay clock cycles (max. 1039) 12 | // (need to find a smarter way...) 13 | #define DLY_cycles(n) \ 14 | (n == 1 ? (_delay_cycles_1()) : \ 15 | (n == 2 ? (_delay_cycles_2()) : \ 16 | (n == 3 ? (_delay_cycles_3()) : \ 17 | (n == 4 ? (_delay_cycles_4()) : \ 18 | (n == 5 ? (_delay_cycles_5()) : \ 19 | (n == 6 ? (_delay_cycles_6()) : \ 20 | (n == 7 ? (_delay_cycles_7()) : \ 21 | (n == 8 ? (_delay_cycles_8()) : \ 22 | (n == 9 ? (_delay_cycles_9()) : \ 23 | (n == 10 ? (_delay_cycles_10()) : \ 24 | (n == 11 ? (_delay_cycles_11()) : \ 25 | (n == 12 ? (_delay_cycles_12()) : \ 26 | (n == 13 ? (_delay_cycles_13()) : \ 27 | (n == 14 ? (_delay_cycles_14()) : \ 28 | (n == 15 ? (_delay_cycles_15()) : \ 29 | (n == 16 ? (_delay_cycles_16()) : \ 30 | (n == 17 ? (_delay_cycles_17()) : \ 31 | (n == 18 ? (_delay_cycles_18()) : \ 32 | (n == 19 ? (_delay_cycles_19()) : \ 33 | ((n-20)%4 == 0 ? _delay_more_cycles(((n-20)/4)+1) : \ 34 | ((n-20)%4 == 1 ? _delay_more_cycles_1(((n-20)/4)+1) : \ 35 | ((n-20)%4 == 2 ? _delay_more_cycles_2(((n-20)/4)+1) : \ 36 | ((n-20)%4 == 3 ? _delay_more_cycles_3(((n-20)/4)+1) : \ 37 | (0)))))))))))))))))))))))) 38 | 39 | #define _delay_less_cycles(n) _delay_cycles_##n() 40 | 41 | void _delay_more_cycles(uint8_t n); 42 | 43 | inline void _delay_cycles_1(void) { 44 | __asm__("nop"); 45 | } 46 | 47 | inline void _delay_cycles_2(void) { 48 | _delay_cycles_1(); 49 | _delay_cycles_1(); 50 | } 51 | 52 | inline void _delay_cycles_3(void) { 53 | _delay_cycles_2(); 54 | _delay_cycles_1(); 55 | } 56 | 57 | inline void _delay_cycles_4(void) { 58 | _delay_cycles_3(); 59 | _delay_cycles_1(); 60 | } 61 | 62 | inline void _delay_cycles_5(void) { 63 | _delay_cycles_4(); 64 | _delay_cycles_1(); 65 | } 66 | 67 | inline void _delay_cycles_6(void) { 68 | _delay_cycles_5(); 69 | _delay_cycles_1(); 70 | } 71 | 72 | inline void _delay_cycles_7(void) { 73 | _delay_cycles_6(); 74 | _delay_cycles_1(); 75 | } 76 | 77 | inline void _delay_cycles_8(void) { 78 | _delay_cycles_7(); 79 | _delay_cycles_1(); 80 | } 81 | 82 | inline void _delay_cycles_9(void) { 83 | _delay_cycles_8(); 84 | _delay_cycles_1(); 85 | } 86 | 87 | inline void _delay_cycles_10(void) { 88 | _delay_cycles_9(); 89 | _delay_cycles_1(); 90 | } 91 | 92 | inline void _delay_cycles_11(void) { 93 | _delay_cycles_10(); 94 | _delay_cycles_1(); 95 | } 96 | 97 | inline void _delay_cycles_12(void) { 98 | __asm 99 | push a 100 | push b 101 | div ab 102 | pop b 103 | pop a 104 | __endasm; 105 | } 106 | 107 | inline void _delay_cycles_13(void) { 108 | _delay_cycles_12(); 109 | _delay_cycles_1(); 110 | } 111 | 112 | inline void _delay_cycles_14(void) { 113 | _delay_cycles_12(); 114 | _delay_cycles_2(); 115 | } 116 | 117 | inline void _delay_cycles_15(void) { 118 | _delay_cycles_12(); 119 | _delay_cycles_3(); 120 | } 121 | 122 | inline void _delay_cycles_16(void) { 123 | __asm 124 | push a 125 | push b 126 | div ab 127 | div ab 128 | pop b 129 | pop a 130 | __endasm; 131 | } 132 | 133 | inline void _delay_cycles_17(void) { 134 | _delay_cycles_16(); 135 | _delay_cycles_1(); 136 | } 137 | 138 | inline void _delay_cycles_18(void) { 139 | _delay_cycles_16(); 140 | _delay_cycles_2(); 141 | } 142 | 143 | inline void _delay_cycles_19(void) { 144 | _delay_cycles_16(); 145 | _delay_cycles_3(); 146 | } 147 | 148 | inline void _delay_more_cycles_1(uint8_t n) { 149 | _delay_more_cycles(n); 150 | _delay_cycles_1(); 151 | } 152 | 153 | inline void _delay_more_cycles_2(uint8_t n) { 154 | _delay_more_cycles(n); 155 | _delay_cycles_2(); 156 | } 157 | 158 | inline void _delay_more_cycles_3(uint8_t n) { 159 | _delay_more_cycles(n); 160 | _delay_cycles_3(); 161 | } 162 | -------------------------------------------------------------------------------- /software/mousewheel_knob/mousewheel_knob.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Project: USB Rotary Encoder for CH551, CH552 and CH554 - Mouse Wheel 3 | // Version: v1.0 4 | // Year: 2023 5 | // Author: Stefan Wagner 6 | // Github: https://github.com/wagiminator 7 | // EasyEDA: https://easyeda.com/wagiminator 8 | // License: http://creativecommons.org/licenses/by-sa/3.0/ 9 | // =================================================================================== 10 | // 11 | // Description: 12 | // ------------ 13 | // Turns the rotary encoder into a mouse wheel. 14 | // 15 | // References: 16 | // ----------- 17 | // - Blinkinlabs: https://github.com/Blinkinlabs/ch554_sdcc 18 | // - Deqing Sun: https://github.com/DeqingSun/ch55xduino 19 | // - Ralph Doncaster: https://github.com/nerdralph/ch554_sdcc 20 | // - WCH Nanjing Qinheng Microelectronics: http://wch.cn 21 | // - ATtiny85 TinyKnob: https://github.com/wagiminator/ATtiny85-TinyKnob 22 | // 23 | // Compilation Instructions: 24 | // ------------------------- 25 | // - Chip: CH551, CH552 or CH554 26 | // - Clock: 16 MHz internal 27 | // - Adjust the firmware parameters in src/config.h if necessary. 28 | // - Make sure SDCC toolchain and Python3 with PyUSB is installed. 29 | // - Press BOOT button on the board and keep it pressed while connecting it via USB 30 | // with your PC. 31 | // - Run 'make flash' immediatly afterwards. 32 | // - To compile the firmware using the Arduino IDE, follow the instructions in the 33 | // .ino file. 34 | // 35 | // Operating Instructions: 36 | // ----------------------- 37 | // - Connect the board via USB to your PC. It should be detected as a HID device. 38 | // - Use the rotary encoder like the wheel on your mouse. 39 | // - To enter bootloader hold down the rotary encoder switch while connecting the 40 | // device to USB. The NeoPixels will light up white as long as the device is in 41 | // bootloader mode (about 10 seconds). 42 | 43 | 44 | // =================================================================================== 45 | // Libraries, Definitions and Macros 46 | // =================================================================================== 47 | 48 | // Libraries 49 | #include "src/config.h" // user configurations 50 | #include "src/system.h" // system functions 51 | #include "src/delay.h" // delay functions 52 | #include "src/neo.h" // NeoPixel functions 53 | #include "src/usb_mouse.h" // USB HID mouse functions 54 | 55 | // Prototypes for used interrupts 56 | void USB_interrupt(void); 57 | void USB_ISR(void) __interrupt(INT_NO_USB) { 58 | USB_interrupt(); 59 | } 60 | 61 | // =================================================================================== 62 | // Main Function 63 | // =================================================================================== 64 | void main(void) { 65 | 66 | // Variables 67 | uint8_t i; // temp variable 68 | uint8_t cnt = 1; // hue cycle counter 69 | uint8_t hue = 0; // hue cycle value 70 | __bit isSwitchPressed = 0; // state of rotary encoder switch 71 | 72 | // Setup 73 | NEO_init(); // init NeoPixels 74 | CLK_config(); // configure system clock 75 | DLY_ms(10); // wait for clock to settle 76 | 77 | // Enter bootloader if encoder switch is pressed 78 | if(!PIN_read(PIN_ENC_SW)) { // encoder switch pressed? 79 | for(i=6; i; i--) NEO_sendByte(127); // light up all pixels 80 | BOOT_now(); // enter bootloader 81 | } 82 | 83 | // Init USB keyboard 84 | HID_init(); // init USB HID mouse 85 | DLY_ms(500); // wait for Windows... 86 | WDT_start(); // start watchdog timer 87 | 88 | // Loop 89 | while(1) { 90 | if(!PIN_read(PIN_ENC_A)) { // encoder turned ? 91 | if(PIN_read(PIN_ENC_B)) MOUSE_wheel(-1); // clockwise? 92 | else MOUSE_wheel( 1); // counter-clockwise? 93 | DLY_ms(10); // debounce 94 | while(!PIN_read(PIN_ENC_A)); // wait until next detent 95 | } 96 | else { 97 | if(!isSwitchPressed && !PIN_read(PIN_ENC_SW)) { // switch previously pressed? 98 | MOUSE_press(MOUSE_BUTTON_MIDDLE); 99 | isSwitchPressed = 1; 100 | } 101 | else if(isSwitchPressed && PIN_read(PIN_ENC_SW)) { // switch previously released? 102 | MOUSE_release(MOUSE_BUTTON_MIDDLE); 103 | isSwitchPressed = 0; 104 | } 105 | } 106 | if(!--cnt) { // time to cycle hue? 107 | NEO_writeHue(hue, 0); NEO_writeHue(hue, 0); // set NeoPixels hue value 108 | if(!hue--) hue = 191; // cycle hue value 109 | } 110 | DLY_ms(1); // slow down a little 111 | WDT_reset(); // reset watchdog 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb_composite.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Composite Device Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | #include "usb_hid.h" 8 | 9 | // Functions 10 | void KBD_press(uint8_t key); // press a key on keyboard 11 | void KBD_release(uint8_t key); // release a key on keyboard 12 | void KBD_type(uint8_t key); // press and release a key on keyboard 13 | void KBD_releaseAll(void); // release all keys on keyboard 14 | void KBD_print(char* str); // type some text on the keyboard 15 | 16 | void CON_press(uint8_t key); // press a consumer key on keyboard 17 | void CON_release(void); // release consumer key on keyboard 18 | void CON_type(uint8_t key); // press and release a consumer key 19 | 20 | void MOUSE_press(uint8_t buttons); // press mouse button(s) 21 | void MOUSE_release(uint8_t buttons); // release mouse button(s) 22 | void MOUSE_move(int8_t xrel, int8_t yrel); // move mouse pointer (relative) 23 | void MOUSE_wheel(int8_t rel); // move mouse wheel (relative) 24 | 25 | void JOY_press(uint8_t buttons); // press joystick button(s) 26 | void JOY_release(uint8_t buttons); // release joystick button(s) 27 | void JOY_move(int8_t xrel, int8_t yrel); // move joystick 28 | 29 | #define MOUSE_wheel_up() MOUSE_wheel( 1) 30 | #define MOUSE_wheel_down() MOUSE_wheel(-1) 31 | 32 | #define JOY_center() JOY_move( 0, 0) 33 | #define JOY_up() JOY_move( 0,-127) 34 | #define JOY_down() JOY_move( 0, 127) 35 | #define JOY_left() JOY_move(-127, 0) 36 | #define JOY_right() JOY_move( 127, 0) 37 | 38 | // Keyboard LED states 39 | #define KBD_getState() (EP2_buffer[0]) 40 | #define KBD_NUM_LOCK_state (KBD_getState() & 1) 41 | #define KBD_CAPS_LOCK_state ((KBD_getState() >> 1) & 1) 42 | #define KBD_SCROLL_LOCK_state ((KBD_getState() >> 2) & 1) 43 | #define KBD_COMPOSE_state ((KBD_getState() >> 3) & 1) 44 | #define KBD_KANA_state ((KBD_getState() >> 4) & 1) 45 | 46 | // Modifier keys 47 | #define KBD_KEY_LEFT_CTRL 0x80 48 | #define KBD_KEY_LEFT_SHIFT 0x81 49 | #define KBD_KEY_LEFT_ALT 0x82 50 | #define KBD_KEY_LEFT_GUI 0x83 51 | #define KBD_KEY_RIGHT_CTRL 0x84 52 | #define KBD_KEY_RIGHT_SHIFT 0x85 53 | #define KBD_KEY_RIGHT_ALT 0x86 54 | #define KBD_KEY_RIGHT_GUI 0x87 55 | 56 | // Special keys 57 | #define KBD_KEY_UP_ARROW 0xDA 58 | #define KBD_KEY_DOWN_ARROW 0xD9 59 | #define KBD_KEY_LEFT_ARROW 0xD8 60 | #define KBD_KEY_RIGHT_ARROW 0xD7 61 | #define KBD_KEY_BACKSPACE 0xB2 62 | #define KBD_KEY_TAB 0xB3 63 | #define KBD_KEY_RETURN 0xB0 64 | #define KBD_KEY_ESC 0xB1 65 | #define KBD_KEY_INSERT 0xD1 66 | #define KBD_KEY_DELETE 0xD4 67 | #define KBD_KEY_PAGE_UP 0xD3 68 | #define KBD_KEY_PAGE_DOWN 0xD6 69 | #define KBD_KEY_HOME 0xD2 70 | #define KBD_KEY_END 0xD5 71 | #define KBD_KEY_CAPS_LOCK 0xC1 72 | #define KBD_KEY_F1 0xC2 73 | #define KBD_KEY_F2 0xC3 74 | #define KBD_KEY_F3 0xC4 75 | #define KBD_KEY_F4 0xC5 76 | #define KBD_KEY_F5 0xC6 77 | #define KBD_KEY_F6 0xC7 78 | #define KBD_KEY_F7 0xC8 79 | #define KBD_KEY_F8 0xC9 80 | #define KBD_KEY_F9 0xCA 81 | #define KBD_KEY_F10 0xCB 82 | #define KBD_KEY_F11 0xCC 83 | #define KBD_KEY_F12 0xCD 84 | #define KBD_KEY_F13 0xF0 85 | #define KBD_KEY_F14 0xF1 86 | #define KBD_KEY_F15 0xF2 87 | #define KBD_KEY_F16 0xF3 88 | #define KBD_KEY_F17 0xF4 89 | #define KBD_KEY_F18 0xF5 90 | #define KBD_KEY_F19 0xF6 91 | #define KBD_KEY_F20 0xF7 92 | #define KBD_KEY_F21 0xF8 93 | #define KBD_KEY_F22 0xF9 94 | #define KBD_KEY_F23 0xFA 95 | #define KBD_KEY_F24 0xFB 96 | 97 | // Consumer Keyboard Keycodes 98 | #define CON_SYS_POWER 0x30 99 | #define CON_SYS_RESET 0x31 100 | #define CON_SYS_SLEEP 0x32 101 | 102 | #define CON_VOL_MUTE 0xE2 103 | #define CON_VOL_UP 0xE9 104 | #define CON_VOL_DOWN 0xEA 105 | 106 | #define CON_MEDIA_PLAY 0xB0 107 | #define CON_MEDIA_PAUSE 0xB1 108 | #define CON_MEDIA_RECORD 0xB2 109 | #define CON_MEDIA_FORWARD 0xB3 110 | #define CON_MEDIA_REWIND 0xB4 111 | #define CON_MEDIA_NEXT 0xB5 112 | #define CON_MEDIA_PREV 0xB6 113 | #define CON_MEDIA_STOP 0xB7 114 | #define CON_MEDIA_EJECT 0xB8 115 | #define CON_MEDIA_RANDOM 0xB9 116 | 117 | #define CON_MENU 0x40 118 | #define CON_MENU_PICK 0x41 119 | #define CON_MENU_UP 0x42 120 | #define CON_MENU_DOWN 0x43 121 | #define CON_MENU_LEFT 0x44 122 | #define CON_MENU_RIGHT 0x45 123 | #define CON_MENU_ESCAPE 0x46 124 | #define CON_MENU_INCR 0x47 125 | #define CON_MENU_DECR 0x48 126 | 127 | // Mouse Buttons 128 | #define MOUSE_BUTTON_LEFT 0x01 129 | #define MOUSE_BUTTON_RIGHT 0x02 130 | #define MOUSE_BUTTON_MIDDLE 0x04 131 | -------------------------------------------------------------------------------- /software/volume_knob/volume_knob.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Project: USB Rotary Encoder for CH551, CH552 and CH554 - Volume Control 3 | // Version: v1.4 4 | // Year: 2023 5 | // Author: Stefan Wagner 6 | // Github: https://github.com/wagiminator 7 | // EasyEDA: https://easyeda.com/wagiminator 8 | // License: http://creativecommons.org/licenses/by-sa/3.0/ 9 | // =================================================================================== 10 | // 11 | // Description: 12 | // ------------ 13 | // Controls PC volume via rotary encoder. 14 | // 15 | // References: 16 | // ----------- 17 | // - Blinkinlabs: https://github.com/Blinkinlabs/ch554_sdcc 18 | // - Deqing Sun: https://github.com/DeqingSun/ch55xduino 19 | // - Ralph Doncaster: https://github.com/nerdralph/ch554_sdcc 20 | // - WCH Nanjing Qinheng Microelectronics: http://wch.cn 21 | // - ATtiny85 TinyKnob: https://github.com/wagiminator/ATtiny85-TinyKnob 22 | // 23 | // Compilation Instructions: 24 | // ------------------------- 25 | // - Chip: CH551, CH552 or CH554 26 | // - Clock: 16 MHz internal 27 | // - Adjust the firmware parameters in src/config.h if necessary. 28 | // - Make sure SDCC toolchain and Python3 with PyUSB is installed. 29 | // - Press BOOT button on the board and keep it pressed while connecting it via USB 30 | // with your PC. 31 | // - Run 'make flash' immediatly afterwards. 32 | // - To compile the firmware using the Arduino IDE, follow the instructions in the 33 | // .ino file. 34 | // 35 | // Operating Instructions: 36 | // ----------------------- 37 | // - Connect the board via USB to your PC. It should be detected as a HID device. 38 | // - Turn the rotary encoder to increase/decrease volume. 39 | // - Press rotary encoder button to mute/unmute. 40 | // - To enter bootloader hold down the rotary encoder switch while connecting the 41 | // device to USB. The NeoPixels will light up white as long as the device is in 42 | // bootloader mode (about 10 seconds). 43 | 44 | 45 | // =================================================================================== 46 | // Libraries, Definitions and Macros 47 | // =================================================================================== 48 | 49 | // Libraries 50 | #include "src/config.h" // user configurations 51 | #include "src/system.h" // system functions 52 | #include "src/delay.h" // delay functions 53 | #include "src/neo.h" // NeoPixel functions 54 | #include "src/usb_consumer.h" // USB HID consumer keyboard functions 55 | 56 | // Prototypes for used interrupts 57 | void USB_interrupt(void); 58 | void USB_ISR(void) __interrupt(INT_NO_USB) { 59 | USB_interrupt(); 60 | } 61 | 62 | // =================================================================================== 63 | // Main Function 64 | // =================================================================================== 65 | void main(void) { 66 | 67 | // Variables 68 | uint8_t i; // temp variable 69 | uint8_t cnt = 1; // hue cycle counter 70 | uint8_t hue = 0; // hue cycle value 71 | __bit isSwitchPressed = 0; // state of rotary encoder switch 72 | 73 | // Setup 74 | NEO_init(); // init NeoPixels 75 | CLK_config(); // configure system clock 76 | DLY_ms(10); // wait for clock to settle 77 | 78 | // Enter bootloader if encoder switch is pressed 79 | if(!PIN_read(PIN_ENC_SW)) { // encoder switch pressed? 80 | for(i=6; i; i--) NEO_sendByte(127); // light up all pixels 81 | BOOT_now(); // enter bootloader 82 | } 83 | 84 | // Init USB keyboard 85 | HID_init(); // init USB HID consumer keyboard 86 | DLY_ms(500); // wait for Windows... 87 | WDT_start(); // start watchdog timer 88 | 89 | // Loop 90 | while(1) { 91 | if(!PIN_read(PIN_ENC_A)) { // encoder turned ? 92 | if(PIN_read(PIN_ENC_B)) CON_press(CON_VOL_UP); // clockwise? -> press vol up 93 | else CON_press(CON_VOL_DOWN); // counter-clockwise? -> press vol down 94 | DLY_ms(10); // debounce 95 | CON_release(); // release key 96 | while(!PIN_read(PIN_ENC_A)); // wait until next detent 97 | } 98 | else { 99 | if(!isSwitchPressed && !PIN_read(PIN_ENC_SW)) { // switch previously pressed? 100 | CON_press(CON_VOL_MUTE); // press volume mute key 101 | isSwitchPressed = 1; 102 | } 103 | else if(isSwitchPressed && PIN_read(PIN_ENC_SW)) { // switch previously released? 104 | CON_release(); // release volume mute key 105 | isSwitchPressed = 0; // update switch state 106 | } 107 | } 108 | if(!--cnt) { // time to cycle hue? 109 | NEO_writeHue(hue, 0); NEO_writeHue(hue, 0); // set NeoPixels hue value 110 | if(!hue--) hue = 191; // cycle hue value 111 | } 112 | DLY_ms(1); // slow down a little 113 | WDT_reset(); // reset watchdog 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /software/custom_knob/src/neo.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // NeoPixel (Addressable LED) Functions for CH551, CH552 and CH554 * v1.1 * 3 | // =================================================================================== 4 | // 5 | // Basic control functions for 800kHz addressable LEDs (NeoPixel). A simplified 6 | // protocol is used which should work with most LEDs. 7 | // 8 | // The following must be defined in config.h: 9 | // PIN_NEO - pin connected to DATA-IN of the pixel strip (via a ~330 ohms resistor). 10 | // NEO_GRB - type of pixel: NEO_GRB or NEO_RGB 11 | // System clock frequency must be at least 6 MHz. 12 | // 13 | // Further information: https://github.com/wagiminator/ATtiny13-NeoController 14 | // 2023 by Stefan Wagner: https://github.com/wagiminator 15 | 16 | // =================================================================================== 17 | // Libraries, Variables and Constants 18 | // =================================================================================== 19 | #include "neo.h" 20 | 21 | #define NEOPIN PIN_asm(PIN_NEO) // convert PIN_NEO for inline assembly 22 | 23 | // =================================================================================== 24 | // Protocol Delays 25 | // =================================================================================== 26 | // There are three essential conditions: 27 | // - T0H (HIGH-time for "0"-bit) must be max. 500ns 28 | // - T1H (HIGH-time for "1"-bit) must be min. 625ns 29 | // - TCT (total clock time) must be min. 1150ns 30 | // The bit transmission loop takes 11 clock cycles. 31 | #if F_CPU == 24000000 // 24 MHz system clock 32 | #define T1H_DELAY \ 33 | nop \ 34 | nop \ 35 | nop \ 36 | nop \ 37 | nop \ 38 | nop \ 39 | nop \ 40 | nop \ 41 | nop \ 42 | nop \ 43 | nop // 15 - 4 = 11 clock cycles for min 625ns 44 | #define TCT_DELAY \ 45 | nop \ 46 | nop \ 47 | nop \ 48 | nop \ 49 | nop \ 50 | nop // 28 - 11 - 11 = 6 clock cycles for min 1150ns 51 | #elif F_CPU == 16000000 // 16 MHz system clock 52 | #define T1H_DELAY \ 53 | nop \ 54 | nop \ 55 | nop \ 56 | nop \ 57 | nop \ 58 | nop // 10 - 4 = 6 clock cycles for min 625ns 59 | #define TCT_DELAY \ 60 | nop \ 61 | nop // 19 - 6 - 11 = 2 clock cycles for min 1150ns 62 | #elif F_CPU == 12000000 // 12 MHz system clock 63 | #define T1H_DELAY \ 64 | nop \ 65 | nop \ 66 | nop \ 67 | nop // 8 - 4 = 4 clock cycles for min 625ns 68 | #define TCT_DELAY // 14 - 4 - 11 < 0 clock cycles for min 1150ns 69 | #elif F_CPU == 6000000 // 13 MHz system clock 70 | #define T1H_DELAY // 4 - 4 = 0 clock cycles for min 625ns 71 | #define TCT_DELAY // 7 - 0 - 11 < 0 clock cycles for min 1150ns 72 | #else 73 | #error Unsupported system clock frequency for NeoPixels! 74 | #endif 75 | 76 | // =================================================================================== 77 | // Send a Data Byte to the Pixels String 78 | // =================================================================================== 79 | // This is the most time sensitive part. Outside of the function, it must be 80 | // ensured that interrupts are disabled and that the time between the 81 | // transmission of the individual bytes is less than the pixel's latch time. 82 | void NEO_sendByte(uint8_t data) { 83 | data; // stop unreferenced argument warning 84 | __asm 85 | .even 86 | mov r7, #8 ; 2 CLK - 8 bits to transfer 87 | xch a, dpl ; 2 CLK - data byte -> accu 88 | 01$: 89 | rlc a ; 1 CLK - data bit -> carry (MSB first) 90 | setb NEOPIN ; 2 CLK - NEO pin HIGH 91 | mov NEOPIN, c ; 2 CLK - "0"-bit? -> NEO pin LOW now 92 | T1H_DELAY ; x CLK - TH1 delay 93 | clr NEOPIN ; 2 CLK - "1"-bit? -> NEO pin LOW a little later 94 | TCT_DELAY ; y CLK - TCT delay 95 | djnz r7, 01$ ; 2/4|5|6 CLK - repeat for all bits 96 | __endasm; 97 | } 98 | 99 | // =================================================================================== 100 | // Write Color to a Single Pixel 101 | // =================================================================================== 102 | void NEO_writeColor(uint8_t r, uint8_t g, uint8_t b) { 103 | #if defined (NEO_GRB) 104 | NEO_sendByte(g); NEO_sendByte(r); NEO_sendByte(b); 105 | #elif defined (NEO_RGB) 106 | NEO_sendByte(r); NEO_sendByte(g); NEO_sendByte(b); 107 | #else 108 | #error Wrong or missing NeoPixel type definition! 109 | #endif 110 | } 111 | 112 | // =================================================================================== 113 | // Write Hue Value (0..191) and Brightness (0..2) to a Single Pixel 114 | // =================================================================================== 115 | void NEO_writeHue(uint8_t hue, uint8_t bright) { 116 | uint8_t phase = hue >> 6; 117 | uint8_t step = (hue & 63) << bright; 118 | uint8_t nstep = (63 << bright) - step; 119 | switch(phase) { 120 | case 0: NEO_writeColor(nstep, step, 0); break; 121 | case 1: NEO_writeColor( 0, nstep, step); break; 122 | case 2: NEO_writeColor( step, 0, nstep); break; 123 | default: break; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /software/volume_knob/src/neo.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // NeoPixel (Addressable LED) Functions for CH551, CH552 and CH554 * v1.1 * 3 | // =================================================================================== 4 | // 5 | // Basic control functions for 800kHz addressable LEDs (NeoPixel). A simplified 6 | // protocol is used which should work with most LEDs. 7 | // 8 | // The following must be defined in config.h: 9 | // PIN_NEO - pin connected to DATA-IN of the pixel strip (via a ~330 ohms resistor). 10 | // NEO_GRB - type of pixel: NEO_GRB or NEO_RGB 11 | // System clock frequency must be at least 6 MHz. 12 | // 13 | // Further information: https://github.com/wagiminator/ATtiny13-NeoController 14 | // 2023 by Stefan Wagner: https://github.com/wagiminator 15 | 16 | // =================================================================================== 17 | // Libraries, Variables and Constants 18 | // =================================================================================== 19 | #include "neo.h" 20 | 21 | #define NEOPIN PIN_asm(PIN_NEO) // convert PIN_NEO for inline assembly 22 | 23 | // =================================================================================== 24 | // Protocol Delays 25 | // =================================================================================== 26 | // There are three essential conditions: 27 | // - T0H (HIGH-time for "0"-bit) must be max. 500ns 28 | // - T1H (HIGH-time for "1"-bit) must be min. 625ns 29 | // - TCT (total clock time) must be min. 1150ns 30 | // The bit transmission loop takes 11 clock cycles. 31 | #if F_CPU == 24000000 // 24 MHz system clock 32 | #define T1H_DELAY \ 33 | nop \ 34 | nop \ 35 | nop \ 36 | nop \ 37 | nop \ 38 | nop \ 39 | nop \ 40 | nop \ 41 | nop \ 42 | nop \ 43 | nop // 15 - 4 = 11 clock cycles for min 625ns 44 | #define TCT_DELAY \ 45 | nop \ 46 | nop \ 47 | nop \ 48 | nop \ 49 | nop \ 50 | nop // 28 - 11 - 11 = 6 clock cycles for min 1150ns 51 | #elif F_CPU == 16000000 // 16 MHz system clock 52 | #define T1H_DELAY \ 53 | nop \ 54 | nop \ 55 | nop \ 56 | nop \ 57 | nop \ 58 | nop // 10 - 4 = 6 clock cycles for min 625ns 59 | #define TCT_DELAY \ 60 | nop \ 61 | nop // 19 - 6 - 11 = 2 clock cycles for min 1150ns 62 | #elif F_CPU == 12000000 // 12 MHz system clock 63 | #define T1H_DELAY \ 64 | nop \ 65 | nop \ 66 | nop \ 67 | nop // 8 - 4 = 4 clock cycles for min 625ns 68 | #define TCT_DELAY // 14 - 4 - 11 < 0 clock cycles for min 1150ns 69 | #elif F_CPU == 6000000 // 13 MHz system clock 70 | #define T1H_DELAY // 4 - 4 = 0 clock cycles for min 625ns 71 | #define TCT_DELAY // 7 - 0 - 11 < 0 clock cycles for min 1150ns 72 | #else 73 | #error Unsupported system clock frequency for NeoPixels! 74 | #endif 75 | 76 | // =================================================================================== 77 | // Send a Data Byte to the Pixels String 78 | // =================================================================================== 79 | // This is the most time sensitive part. Outside of the function, it must be 80 | // ensured that interrupts are disabled and that the time between the 81 | // transmission of the individual bytes is less than the pixel's latch time. 82 | void NEO_sendByte(uint8_t data) { 83 | data; // stop unreferenced argument warning 84 | __asm 85 | .even 86 | mov r7, #8 ; 2 CLK - 8 bits to transfer 87 | xch a, dpl ; 2 CLK - data byte -> accu 88 | 01$: 89 | rlc a ; 1 CLK - data bit -> carry (MSB first) 90 | setb NEOPIN ; 2 CLK - NEO pin HIGH 91 | mov NEOPIN, c ; 2 CLK - "0"-bit? -> NEO pin LOW now 92 | T1H_DELAY ; x CLK - TH1 delay 93 | clr NEOPIN ; 2 CLK - "1"-bit? -> NEO pin LOW a little later 94 | TCT_DELAY ; y CLK - TCT delay 95 | djnz r7, 01$ ; 2/4|5|6 CLK - repeat for all bits 96 | __endasm; 97 | } 98 | 99 | // =================================================================================== 100 | // Write Color to a Single Pixel 101 | // =================================================================================== 102 | void NEO_writeColor(uint8_t r, uint8_t g, uint8_t b) { 103 | #if defined (NEO_GRB) 104 | NEO_sendByte(g); NEO_sendByte(r); NEO_sendByte(b); 105 | #elif defined (NEO_RGB) 106 | NEO_sendByte(r); NEO_sendByte(g); NEO_sendByte(b); 107 | #else 108 | #error Wrong or missing NeoPixel type definition! 109 | #endif 110 | } 111 | 112 | // =================================================================================== 113 | // Write Hue Value (0..191) and Brightness (0..2) to a Single Pixel 114 | // =================================================================================== 115 | void NEO_writeHue(uint8_t hue, uint8_t bright) { 116 | uint8_t phase = hue >> 6; 117 | uint8_t step = (hue & 63) << bright; 118 | uint8_t nstep = (63 << bright) - step; 119 | switch(phase) { 120 | case 0: NEO_writeColor(nstep, step, 0); break; 121 | case 1: NEO_writeColor( 0, nstep, step); break; 122 | case 2: NEO_writeColor( step, 0, nstep); break; 123 | default: break; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/neo.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // NeoPixel (Addressable LED) Functions for CH551, CH552 and CH554 * v1.1 * 3 | // =================================================================================== 4 | // 5 | // Basic control functions for 800kHz addressable LEDs (NeoPixel). A simplified 6 | // protocol is used which should work with most LEDs. 7 | // 8 | // The following must be defined in config.h: 9 | // PIN_NEO - pin connected to DATA-IN of the pixel strip (via a ~330 ohms resistor). 10 | // NEO_GRB - type of pixel: NEO_GRB or NEO_RGB 11 | // System clock frequency must be at least 6 MHz. 12 | // 13 | // Further information: https://github.com/wagiminator/ATtiny13-NeoController 14 | // 2023 by Stefan Wagner: https://github.com/wagiminator 15 | 16 | // =================================================================================== 17 | // Libraries, Variables and Constants 18 | // =================================================================================== 19 | #include "neo.h" 20 | 21 | #define NEOPIN PIN_asm(PIN_NEO) // convert PIN_NEO for inline assembly 22 | 23 | // =================================================================================== 24 | // Protocol Delays 25 | // =================================================================================== 26 | // There are three essential conditions: 27 | // - T0H (HIGH-time for "0"-bit) must be max. 500ns 28 | // - T1H (HIGH-time for "1"-bit) must be min. 625ns 29 | // - TCT (total clock time) must be min. 1150ns 30 | // The bit transmission loop takes 11 clock cycles. 31 | #if F_CPU == 24000000 // 24 MHz system clock 32 | #define T1H_DELAY \ 33 | nop \ 34 | nop \ 35 | nop \ 36 | nop \ 37 | nop \ 38 | nop \ 39 | nop \ 40 | nop \ 41 | nop \ 42 | nop \ 43 | nop // 15 - 4 = 11 clock cycles for min 625ns 44 | #define TCT_DELAY \ 45 | nop \ 46 | nop \ 47 | nop \ 48 | nop \ 49 | nop \ 50 | nop // 28 - 11 - 11 = 6 clock cycles for min 1150ns 51 | #elif F_CPU == 16000000 // 16 MHz system clock 52 | #define T1H_DELAY \ 53 | nop \ 54 | nop \ 55 | nop \ 56 | nop \ 57 | nop \ 58 | nop // 10 - 4 = 6 clock cycles for min 625ns 59 | #define TCT_DELAY \ 60 | nop \ 61 | nop // 19 - 6 - 11 = 2 clock cycles for min 1150ns 62 | #elif F_CPU == 12000000 // 12 MHz system clock 63 | #define T1H_DELAY \ 64 | nop \ 65 | nop \ 66 | nop \ 67 | nop // 8 - 4 = 4 clock cycles for min 625ns 68 | #define TCT_DELAY // 14 - 4 - 11 < 0 clock cycles for min 1150ns 69 | #elif F_CPU == 6000000 // 13 MHz system clock 70 | #define T1H_DELAY // 4 - 4 = 0 clock cycles for min 625ns 71 | #define TCT_DELAY // 7 - 0 - 11 < 0 clock cycles for min 1150ns 72 | #else 73 | #error Unsupported system clock frequency for NeoPixels! 74 | #endif 75 | 76 | // =================================================================================== 77 | // Send a Data Byte to the Pixels String 78 | // =================================================================================== 79 | // This is the most time sensitive part. Outside of the function, it must be 80 | // ensured that interrupts are disabled and that the time between the 81 | // transmission of the individual bytes is less than the pixel's latch time. 82 | void NEO_sendByte(uint8_t data) { 83 | data; // stop unreferenced argument warning 84 | __asm 85 | .even 86 | mov r7, #8 ; 2 CLK - 8 bits to transfer 87 | xch a, dpl ; 2 CLK - data byte -> accu 88 | 01$: 89 | rlc a ; 1 CLK - data bit -> carry (MSB first) 90 | setb NEOPIN ; 2 CLK - NEO pin HIGH 91 | mov NEOPIN, c ; 2 CLK - "0"-bit? -> NEO pin LOW now 92 | T1H_DELAY ; x CLK - TH1 delay 93 | clr NEOPIN ; 2 CLK - "1"-bit? -> NEO pin LOW a little later 94 | TCT_DELAY ; y CLK - TCT delay 95 | djnz r7, 01$ ; 2/4|5|6 CLK - repeat for all bits 96 | __endasm; 97 | } 98 | 99 | // =================================================================================== 100 | // Write Color to a Single Pixel 101 | // =================================================================================== 102 | void NEO_writeColor(uint8_t r, uint8_t g, uint8_t b) { 103 | #if defined (NEO_GRB) 104 | NEO_sendByte(g); NEO_sendByte(r); NEO_sendByte(b); 105 | #elif defined (NEO_RGB) 106 | NEO_sendByte(r); NEO_sendByte(g); NEO_sendByte(b); 107 | #else 108 | #error Wrong or missing NeoPixel type definition! 109 | #endif 110 | } 111 | 112 | // =================================================================================== 113 | // Write Hue Value (0..191) and Brightness (0..2) to a Single Pixel 114 | // =================================================================================== 115 | void NEO_writeHue(uint8_t hue, uint8_t bright) { 116 | uint8_t phase = hue >> 6; 117 | uint8_t step = (hue & 63) << bright; 118 | uint8_t nstep = (63 << bright) - step; 119 | switch(phase) { 120 | case 0: NEO_writeColor(nstep, step, 0); break; 121 | case 1: NEO_writeColor( 0, nstep, step); break; 122 | case 2: NEO_writeColor( step, 0, nstep); break; 123 | default: break; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb_descr.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Descriptors 3 | // =================================================================================== 4 | 5 | #include "config.h" 6 | #include "usb_descr.h" 7 | 8 | // =================================================================================== 9 | // Device Descriptor 10 | // =================================================================================== 11 | __code USB_DEV_DESCR DevDescr = { 12 | .bLength = sizeof(DevDescr), // size of the descriptor in bytes: 18 13 | .bDescriptorType = USB_DESCR_TYP_DEVICE, // device descriptor: 0x01 14 | .bcdUSB = 0x0110, // USB specification: USB 1.1 15 | .bDeviceClass = 0, // interface will define class 16 | .bDeviceSubClass = 0, // unused 17 | .bDeviceProtocol = 0, // unused 18 | .bMaxPacketSize0 = EP0_SIZE, // maximum packet size for Endpoint 0 19 | .idVendor = USB_VENDOR_ID, // VID 20 | .idProduct = USB_PRODUCT_ID, // PID 21 | .bcdDevice = USB_DEVICE_VERSION, // device version 22 | .iManufacturer = 1, // index of Manufacturer String Descr 23 | .iProduct = 2, // index of Product String Descriptor 24 | .iSerialNumber = 3, // index of Serial Number String Descr 25 | .bNumConfigurations = 1 // number of possible configurations 26 | }; 27 | 28 | // =================================================================================== 29 | // Configuration Descriptor 30 | // =================================================================================== 31 | __code USB_CFG_DESCR_HID CfgDescr = { 32 | 33 | // Configuration Descriptor 34 | .config = { 35 | .bLength = sizeof(USB_CFG_DESCR), // size of the descriptor in bytes 36 | .bDescriptorType = USB_DESCR_TYP_CONFIG, // configuration descriptor: 0x02 37 | .wTotalLength = sizeof(CfgDescr), // total length in bytes 38 | .bNumInterfaces = 1, // number of interfaces: 1 39 | .bConfigurationValue= 1, // value to select this configuration 40 | .iConfiguration = 0, // no configuration string descriptor 41 | .bmAttributes = 0x80, // attributes = bus powered, no wakeup 42 | .MaxPower = USB_MAX_POWER_mA / 2 // in 2mA units 43 | }, 44 | 45 | // Interface Descriptor 46 | .interface0 = { 47 | .bLength = sizeof(USB_ITF_DESCR), // size of the descriptor in bytes: 9 48 | .bDescriptorType = USB_DESCR_TYP_INTERF, // interface descriptor: 0x04 49 | .bInterfaceNumber = 0, // number of this interface: 0 50 | .bAlternateSetting = 0, // value used to select alternative setting 51 | .bNumEndpoints = 1, // number of endpoints used: 1 52 | .bInterfaceClass = USB_DEV_CLASS_HID, // interface class: HID (0x03) 53 | .bInterfaceSubClass = 1, // boot interface 54 | .bInterfaceProtocol = 1, // keyboard 55 | .iInterface = 4 // interface string descriptor 56 | }, 57 | 58 | // HID Descriptor 59 | .hid0 = { 60 | .bLength = sizeof(USB_HID_DESCR), // size of the descriptor in bytes: 9 61 | .bDescriptorType = USB_DESCR_TYP_HID, // HID descriptor: 0x21 62 | .bcdHID = 0x0110, // HID class spec version (BCD: 1.1) 63 | .bCountryCode = 33, // country code: US 64 | .bNumDescriptors = 1, // number of report descriptors: 1 65 | .bDescriptorTypeX = USB_DESCR_TYP_REPORT, // descriptor type: report (0x22) 66 | .wDescriptorLength = sizeof(ReportDescr) // report descriptor length 67 | }, 68 | 69 | // Endpoint Descriptor: Endpoint 1 (IN, Interrupt) 70 | .ep1IN = { 71 | .bLength = sizeof(USB_ENDP_DESCR), // size of the descriptor in bytes: 7 72 | .bDescriptorType = USB_DESCR_TYP_ENDP, // endpoint descriptor: 0x05 73 | .bEndpointAddress = USB_ENDP_ADDR_EP1_IN, // endpoint: 1, direction: IN (0x01) 74 | .bmAttributes = USB_ENDP_TYPE_INTER, // transfer type: interrupt (0x03) 75 | .wMaxPacketSize = EP1_SIZE, // max packet size 76 | .bInterval = 1 // polling intervall in ms 77 | } 78 | }; 79 | 80 | // =================================================================================== 81 | // HID Report Descriptor 82 | // =================================================================================== 83 | __code uint8_t ReportDescr[] ={ 84 | 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) 85 | 0x09, 0x01, // USAGE (Consumer Control) 86 | 0xa1, 0x01, // COLLECTION (Application) 87 | 0x85, 0x01, // REPORT_ID (1) 88 | 0x19, 0x00, // USAGE_MINIMUM (Unassigned) 89 | 0x2a, 0x3c, 0x02, // USAGE_MAXIMUM (AC Format) 90 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 91 | 0x26, 0x3c, 0x02, // LOGICAL_MAXIMUM (572) 92 | 0x95, 0x01, // REPORT_COUNT (1) 93 | 0x75, 0x10, // REPORT_SIZE (16) 94 | 0x81, 0x00, // INPUT (Data,Var,Abs) 95 | 0xc0 // END_COLLECTION 96 | }; 97 | 98 | __code uint8_t ReportDescrLen = sizeof(ReportDescr); 99 | 100 | // =================================================================================== 101 | // String Descriptors 102 | // =================================================================================== 103 | 104 | // Language Descriptor (Index 0) 105 | __code uint16_t LangDescr[] = { 106 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(LangDescr), 0x0409 }; // US English 107 | 108 | // Manufacturer String Descriptor (Index 1) 109 | __code uint16_t ManufDescr[] = { 110 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(ManufDescr), MANUFACTURER_STR }; 111 | 112 | // Product String Descriptor (Index 2) 113 | __code uint16_t ProdDescr[] = { 114 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(ProdDescr), PRODUCT_STR }; 115 | 116 | // Serial String Descriptor (Index 3) 117 | __code uint16_t SerDescr[] = { 118 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(SerDescr), SERIAL_STR }; 119 | 120 | // Interface String Descriptor (Index 4) 121 | __code uint16_t InterfDescr[] = { 122 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(InterfDescr), INTERFACE_STR }; 123 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/usb_descr.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Descriptors 3 | // =================================================================================== 4 | 5 | #include "config.h" 6 | #include "usb_descr.h" 7 | 8 | // =================================================================================== 9 | // Device Descriptor 10 | // =================================================================================== 11 | __code USB_DEV_DESCR DevDescr = { 12 | .bLength = sizeof(DevDescr), // size of the descriptor in bytes: 18 13 | .bDescriptorType = USB_DESCR_TYP_DEVICE, // device descriptor: 0x01 14 | .bcdUSB = 0x0110, // USB specification: USB 1.1 15 | .bDeviceClass = 0, // interface will define class 16 | .bDeviceSubClass = 0, // unused 17 | .bDeviceProtocol = 0, // unused 18 | .bMaxPacketSize0 = EP0_SIZE, // maximum packet size for Endpoint 0 19 | .idVendor = USB_VENDOR_ID, // VID 20 | .idProduct = USB_PRODUCT_ID, // PID 21 | .bcdDevice = USB_DEVICE_VERSION, // device version 22 | .iManufacturer = 1, // index of Manufacturer String Descr 23 | .iProduct = 2, // index of Product String Descriptor 24 | .iSerialNumber = 3, // index of Serial Number String Descr 25 | .bNumConfigurations = 1 // number of possible configurations 26 | }; 27 | 28 | // =================================================================================== 29 | // Configuration Descriptor 30 | // =================================================================================== 31 | __code USB_CFG_DESCR_HID CfgDescr = { 32 | 33 | // Configuration Descriptor 34 | .config = { 35 | .bLength = sizeof(USB_CFG_DESCR), // size of the descriptor in bytes 36 | .bDescriptorType = USB_DESCR_TYP_CONFIG, // configuration descriptor: 0x02 37 | .wTotalLength = sizeof(CfgDescr), // total length in bytes 38 | .bNumInterfaces = 1, // number of interfaces: 1 39 | .bConfigurationValue= 1, // value to select this configuration 40 | .iConfiguration = 0, // no configuration string descriptor 41 | .bmAttributes = 0x80, // attributes = bus powered, no wakeup 42 | .MaxPower = USB_MAX_POWER_mA / 2 // in 2mA units 43 | }, 44 | 45 | // Interface Descriptor 46 | .interface0 = { 47 | .bLength = sizeof(USB_ITF_DESCR), // size of the descriptor in bytes: 9 48 | .bDescriptorType = USB_DESCR_TYP_INTERF, // interface descriptor: 0x04 49 | .bInterfaceNumber = 0, // number of this interface: 0 50 | .bAlternateSetting = 0, // value used to select alternative setting 51 | .bNumEndpoints = 1, // number of endpoints used: 1 52 | .bInterfaceClass = USB_DEV_CLASS_HID, // interface class: HID (0x03) 53 | .bInterfaceSubClass = 1, // boot interface 54 | .bInterfaceProtocol = 2, // mouse 55 | .iInterface = 4 // interface string descriptor 56 | }, 57 | 58 | // HID Descriptor 59 | .hid0 = { 60 | .bLength = sizeof(USB_HID_DESCR), // size of the descriptor in bytes: 9 61 | .bDescriptorType = USB_DESCR_TYP_HID, // HID descriptor: 0x21 62 | .bcdHID = 0x0111, // HID class spec version (BCD: 1.11) 63 | .bCountryCode = 0, // not supported 64 | .bNumDescriptors = 1, // number of report descriptors: 1 65 | .bDescriptorTypeX = USB_DESCR_TYP_REPORT, // descriptor type: report (0x22) 66 | .wDescriptorLength = sizeof(ReportDescr) // report descriptor length 67 | }, 68 | 69 | // Endpoint Descriptor: Endpoint 1 (IN, Interrupt) 70 | .ep1IN = { 71 | .bLength = sizeof(USB_ENDP_DESCR), // size of the descriptor in bytes: 7 72 | .bDescriptorType = USB_DESCR_TYP_ENDP, // endpoint descriptor: 0x05 73 | .bEndpointAddress = USB_ENDP_ADDR_EP1_IN, // endpoint: 1, direction: IN (0x81) 74 | .bmAttributes = USB_ENDP_TYPE_INTER, // transfer type: interrupt (0x03) 75 | .wMaxPacketSize = EP1_SIZE, // max packet size 76 | .bInterval = 1 // polling intervall in ms 77 | } 78 | }; 79 | 80 | // =================================================================================== 81 | // HID Report Descriptor 82 | // =================================================================================== 83 | __code uint8_t ReportDescr[] ={ 84 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 85 | 0x09, 0x02, // USAGE (Mouse) 86 | 0xa1, 0x01, // COLLECTION (Application) 87 | 0x09, 0x01, // USAGE (Pointer) 88 | 0xa1, 0x00, // COLLECTION (Physical) 89 | 0x05, 0x09, // USAGE_PAGE (Button) 90 | 0x19, 0x01, // USAGE_MINIMUM (Button 1) 91 | 0x29, 0x03, // USAGE_MAXIMUM (Button 3) 92 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 93 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) 94 | 0x75, 0x01, // REPORT_SIZE (1) 95 | 0x95, 0x03, // REPORT_COUNT (3) 96 | 0x81, 0x02, // INPUT (Data,Var,Abs) 97 | 0x75, 0x05, // REPORT_SIZE (5) 98 | 0x95, 0x01, // REPORT_COUNT (1) 99 | 0x81, 0x03, // INPUT (Cnst,Var,Abs) 100 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 101 | 0x09, 0x30, // USAGE (X) 102 | 0x09, 0x31, // USAGE (Y) 103 | 0x09, 0x38, // USAGE (Wheel) 104 | 0x15, 0x81, // LOGICAL_MINIMUM (-127) 105 | 0x25, 0x7f, // LOGICAL_MAXIMUM (127) 106 | 0x75, 0x08, // REPORT_SIZE (8) 107 | 0x95, 0x03, // REPORT_COUNT (3) 108 | 0x81, 0x06, // INPUT (Data,Var,Rel) 109 | 0xc0, // END_COLLECTION 110 | 0xc0 // END_COLLECTION 111 | }; 112 | 113 | __code uint8_t ReportDescrLen = sizeof(ReportDescr); 114 | 115 | // =================================================================================== 116 | // String Descriptors 117 | // =================================================================================== 118 | 119 | // Language Descriptor (Index 0) 120 | __code uint16_t LangDescr[] = { 121 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(LangDescr), 0x0409 }; // US English 122 | 123 | // Manufacturer String Descriptor (Index 1) 124 | __code uint16_t ManufDescr[] = { 125 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(ManufDescr), MANUFACTURER_STR }; 126 | 127 | // Product String Descriptor (Index 2) 128 | __code uint16_t ProdDescr[] = { 129 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(ProdDescr), PRODUCT_STR }; 130 | 131 | // Serial String Descriptor (Index 3) 132 | __code uint16_t SerDescr[] = { 133 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(SerDescr), SERIAL_STR }; 134 | 135 | // Interface String Descriptor (Index 4) 136 | __code uint16_t InterfDescr[] = { 137 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(InterfDescr), INTERFACE_STR }; 138 | -------------------------------------------------------------------------------- /software/custom_knob/custom_knob.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Project: USB Rotary Encoder for CH551, CH552 and CH554 - Custom Control 3 | // Version: v1.0 4 | // Year: 2023 5 | // Author: Stefan Wagner 6 | // Github: https://github.com/wagiminator 7 | // EasyEDA: https://easyeda.com/wagiminator 8 | // License: http://creativecommons.org/licenses/by-sa/3.0/ 9 | // =================================================================================== 10 | // 11 | // Description: 12 | // ------------ 13 | // Customize your USB Rotary Encoder Knob. 14 | // 15 | // References: 16 | // ----------- 17 | // - Blinkinlabs: https://github.com/Blinkinlabs/ch554_sdcc 18 | // - Deqing Sun: https://github.com/DeqingSun/ch55xduino 19 | // - Ralph Doncaster: https://github.com/nerdralph/ch554_sdcc 20 | // - WCH Nanjing Qinheng Microelectronics: http://wch.cn 21 | // - ATtiny85 TinyKnob: https://github.com/wagiminator/ATtiny85-TinyKnob 22 | // 23 | // Compilation Instructions: 24 | // ------------------------- 25 | // - Chip: CH551, CH552 or CH554 26 | // - Clock: 16 MHz internal 27 | // - Adjust the firmware parameters in src/config.h if necessary. 28 | // - Customize the macro functions in the corresponding section below. 29 | // - Make sure SDCC toolchain and Python3 with PyUSB is installed. 30 | // - Press BOOT button on the board and keep it pressed while connecting it via USB 31 | // with your PC. 32 | // - Run 'make flash' immediatly afterwards. 33 | // - To compile the firmware using the Arduino IDE, follow the instructions in the 34 | // .ino file. 35 | // 36 | // Operating Instructions: 37 | // ----------------------- 38 | // - Costomize your rotary encoder knob below in this firmware. 39 | // - Connect the board via USB to your PC. It should be detected as a HID composite 40 | // device with keyboard, mouse and game controller interface. 41 | // - Turn the rotary encoder or press the encoder switch. 42 | // - To enter bootloader hold down the rotary encoder switch while connecting the 43 | // device to USB. The NeoPixels will light up white as long as the device is in 44 | // bootloader mode (about 10 seconds). 45 | 46 | 47 | // =================================================================================== 48 | // Libraries, Definitions and Macros 49 | // =================================================================================== 50 | 51 | // Libraries 52 | #include "src/config.h" // user configurations 53 | #include "src/system.h" // system functions 54 | #include "src/delay.h" // delay functions 55 | #include "src/neo.h" // NeoPixel functions 56 | #include "src/usb_composite.h" // USB HID composite functions 57 | 58 | // Prototypes for used interrupts 59 | void USB_interrupt(void); 60 | void USB_ISR(void) __interrupt(INT_NO_USB) { 61 | USB_interrupt(); 62 | } 63 | 64 | // =================================================================================== 65 | // Macro Functions which associate Actions with Events (Customize your USB Knob here!) 66 | // =================================================================================== 67 | // 68 | // The list of available USB HID functions can be found in src/usb_composite.h 69 | 70 | // Rotary encoder example -> volume control knob 71 | // --------------------------------------------- 72 | 73 | // Define action(s) if encoder was rotated clockwise 74 | inline void ENC_CW_ACTION() { 75 | CON_press(CON_VOL_UP); // press VOLUME UP key 76 | } 77 | 78 | // Define action(s) after encoder was rotated clockwise 79 | inline void ENC_CW_RELEASED() { 80 | CON_release(); // release VOLUME UP KEY 81 | } 82 | 83 | // Define action(s) if encoder was rotated counter-clockwise 84 | inline void ENC_CCW_ACTION() { 85 | CON_press(CON_VOL_DOWN); // press VOLUME DOWN key 86 | } 87 | 88 | // Define action(s) after encoder was rotated counter-clockwise 89 | inline void ENC_CCW_RELEASED() { 90 | CON_release(); // release VOLUME DOWN KEY 91 | } 92 | 93 | // Define action(s) if encoder switch was pressed 94 | inline void ENC_SW_PRESSED() { 95 | CON_press(CON_VOL_MUTE); // press VOLUME MUTE key 96 | } 97 | 98 | // Define action(s) if encoder switch was released 99 | inline void ENC_SW_RELEASED() { 100 | CON_release(); // release VOLUME MUTE key 101 | } 102 | 103 | // =================================================================================== 104 | // Main Function 105 | // =================================================================================== 106 | void main(void) { 107 | 108 | // Variables 109 | uint8_t i; // temp variable 110 | uint8_t cnt = 1; // hue cycle counter 111 | uint8_t hue = 0; // hue cycle value 112 | __bit isSwitchPressed = 0; // state of rotary encoder switch 113 | 114 | // Setup 115 | NEO_init(); // init NeoPixels 116 | CLK_config(); // configure system clock 117 | DLY_ms(10); // wait for clock to settle 118 | 119 | // Enter bootloader if encoder switch is pressed 120 | if(!PIN_read(PIN_ENC_SW)) { // encoder switch pressed? 121 | for(i=6; i; i--) NEO_sendByte(127); // light up all pixels 122 | BOOT_now(); // enter bootloader 123 | } 124 | 125 | // Init USB keyboard 126 | HID_init(); // init USB HID consumer keyboard 127 | DLY_ms(500); // wait for Windows... 128 | WDT_start(); // start watchdog timer 129 | 130 | // Loop 131 | while(1) { 132 | if(!PIN_read(PIN_ENC_A)) { // encoder turned ? 133 | if(PIN_read(PIN_ENC_B)) { // clockwise ? 134 | ENC_CW_ACTION(); // take proper action 135 | DLY_ms(5); // debounce 136 | ENC_CW_RELEASED(); // take proper action 137 | } 138 | else { // counter-clockwise ? 139 | ENC_CCW_ACTION(); // take proper action 140 | DLY_ms(5); // debounce 141 | ENC_CCW_RELEASED(); // take proper action 142 | } 143 | while(!PIN_read(PIN_ENC_A)); // wait until next detent 144 | } 145 | else { 146 | if(!isSwitchPressed && !PIN_read(PIN_ENC_SW)) { // switch previously pressed? 147 | ENC_SW_PRESSED(); // take proper action 148 | isSwitchPressed = 1; 149 | } 150 | else if(isSwitchPressed && PIN_read(PIN_ENC_SW)) { // switch previously released? 151 | ENC_SW_RELEASED(); // take proper action 152 | isSwitchPressed = 0; // update switch state 153 | } 154 | } 155 | if(!--cnt) { // time to cycle hue? 156 | NEO_writeHue(hue, 0); NEO_writeHue(hue, 0); // set NeoPixels hue value 157 | if(!hue--) hue = 191; // cycle hue value 158 | } 159 | DLY_ms(1); // slow down a little 160 | WDT_reset(); // reset watchdog 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CH552E USB Knob - Rotary Encoder with USB Interface 2 | The USB Knob is a versatile device that combines the functionality of a rotary encoder with the convenience of a USB interface. It is based on either the CH552E or CH554E microcontroller and is equipped with addressable LEDs, commonly known as NeoPixels. The unique combination of these components makes the USB Knob an ideal choice for a wide range of applications, including volume control for PCs. 3 | 4 | One of the standout features of the USB Knob is that it requires no driver installation, making it incredibly easy to use. The device acts as a USB human interface device (HID), meaning that it can be recognized and utilized by most computers without the need for additional software. 5 | 6 | ![USB_Knob_pic1.jpg](https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/main/documentation/USB_Knob_pic1.jpg) 7 | 8 | # Hardware 9 | ## Schematic 10 | ![USB_Knob_wiring.png](https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/main/documentation/USB_Knob_wiring.png) 11 | 12 | ## CH552E 8-bit USB Device Microcontroller 13 | The CH552E is a low-cost, enhanced E8051 core microcontroller compatible with the MCS51 instruction set. It has an integrated USB 2.0 controller with full-speed data transfer (12 Mbit/s) and supports up to 64 byte data packets with integrated FIFO and direct memory access (DMA). The CH552E has a factory built-in bootloader so firmware can be uploaded directly via USB without the need for an additional programming device. 14 | 15 | ## Building Instructions 16 | 1. Take the Gerber files and send them to a PCB manufacturer of your choosing. They will use these files to create the circuit board for your device. 17 | 2. Once you have the PCB, you can start soldering the components onto it. Use the BOM (bill of materials) and schematic as a guide to make sure everything is connected correctly. 18 | 3. Upload the firmware by following the instructions in the next section (see below). 19 | 4. To create the case for your device, use the STL files with your 3D printer. Make sure to use transparent filament for the ring. 20 | 5. After printing, secure the PCB to the bottom of the case using four self-tapping M2x5mm screws. 21 | 6. Next, glue the ring from the bottom into the circular recess in the top of the case. 22 | 7. Finally, assemble the case. Place the knob onto the rotary encoder. Your device is now ready to use! 23 | 24 | ![USB_Knob_pic2.jpg](https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/main/documentation/USB_Knob_pic2.jpg) 25 | ![USB_Knob_pic4.jpg](https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/main/documentation/USB_Knob_pic4.jpg) 26 | 27 | # Software 28 | ## Firmware Versions 29 | ### Volume Knob 30 | This firmware enables the USB Knob to control the volume of your computer. By turning the knob, you can increase or decrease the volume, while pressing the knob will mute or unmute the sound. The device is recognized as a USB HID consumer multimedia keyboard and should work immediately without the need for any driver installation. 31 | 32 | ### Mouse Wheel Knob 33 | This firmware is designed to transform the USB Knob into a mouse wheel. By rotating the knob, it emulates the movement of a mouse wheel, allowing users to scroll up and down web pages, among other things. Pressing the knob is equivalent to clicking on the mouse wheel or the middle mouse button. The device registers as a USB HID mouse on the computer and should work immediately without the need for driver installation. 34 | 35 | ### Custom Knob 36 | This firmware is perfect for customizing it according to your own preferences. It allows for the free mapping of USB HID actions to USB Knob events. The firmware is structured and commented in such a way that it should be possible to make adjustments even with basic programming skills. It is designed as a USB HID composite device that combines a keyboard, a mouse, and a game controller. 37 | 38 | ## Compiling and Installing Firmware 39 | ### Preparing the CH55x Bootloader 40 | #### Installing Drivers for the CH55x Bootloader 41 | On Linux you do not need to install a driver. However, by default Linux will not expose enough permission to upload your code with the USB bootloader. In order to fix this, open a terminal and run the following commands: 42 | 43 | ``` 44 | echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="4348", ATTR{idProduct}=="55e0", MODE="666"' | sudo tee /etc/udev/rules.d/99-ch55x.rules 45 | sudo service udev restart 46 | ``` 47 | 48 | For Windows, you need the [CH372 driver](http://www.wch-ic.com/downloads/CH372DRV_EXE.html) (recommended). Alternatively, you can also use the [Zadig Tool](https://zadig.akeo.ie/) to install the correct driver. Here, click "Options" and "List All Devices" to select the USB module, and then install the libusb-win32 driver. To do this, the board must be connected and the CH55x must be in bootloader mode. 49 | 50 | #### Entering CH55x Bootloader Mode 51 | A brand new chip starts automatically in bootloader mode as soon as it is connected to the PC via USB. Once firmware has been uploaded, the bootloader must be started manually for new uploads. To do this, the board must first be disconnected from the USB port and all voltage sources. Now press the BOOT button and keep it pressed while reconnecting the board to the USB port of your PC. The chip now starts again in bootloader mode, the BOOT button can be released and new firmware can be uploaded within the next couple of seconds. 52 | 53 | Once the USB Knob firmware is installed, the bootloader can also be entered by holding down the rotary encoder switch while connecting the device to the USB port. In this way, the case does not have to be opened when new firmware is to be installed. The NeoPixels will then light up white as long as the device is in bootloader mode (approx. 10 seconds). 54 | 55 | ### Compiling and Uploading using the makefile 56 | #### Installing SDCC Toolchain for CH55x 57 | Install the [SDCC Compiler](https://sdcc.sourceforge.net/). In order for the programming tool to work, Python3 must be installed on your system. To do this, follow these [instructions](https://www.pythontutorial.net/getting-started/install-python/). In addition [pyusb](https://github.com/pyusb/pyusb) must be installed. On Linux (Debian-based), all of this can be done with the following commands: 58 | 59 | ``` 60 | sudo apt install build-essential sdcc python3 python3-pip 61 | sudo pip install pyusb 62 | ``` 63 | 64 | #### Compiling and Uploading Firmware 65 | - Open a terminal. 66 | - Navigate to the folder with the makefile. 67 | - Connect the board and make sure the CH55x is in bootloader mode. 68 | - Run ```make flash``` to compile and upload the firmware. 69 | - If you don't want to compile the firmware yourself, you can also upload the precompiled binary. To do this, just run ```python3 ./tools/chprog.py firmware.bin```. 70 | 71 | ### Compiling and Uploading using the Arduino IDE 72 | #### Installing the Arduino IDE and CH55xduino 73 | Install the [Arduino IDE](https://www.arduino.cc/en/software) if you haven't already. Install the [CH55xduino](https://github.com/DeqingSun/ch55xduino) package by following the instructions on the website. 74 | 75 | #### Compiling and Uploading Firmware 76 | - Open the .ino file in the Arduino IDE. 77 | - Go to **Tools -> Board -> CH55x Boards** and select **CH552 Board**. 78 | - Go to **Tools** and choose the following board options: 79 | - **Clock Source:** 16 MHz (internal) 80 | - **Upload Method:** USB 81 | - **USB Settings:** USER CODE /w 266B USB RAM 82 | - Connect the board and make sure the CH55x is in bootloader mode. 83 | - Click **Upload**. 84 | 85 | # References, Links and Notes 86 | 1. [EasyEDA Design Files](https://oshwlab.com/wagiminator) 87 | 2. [CH551/552 Datasheet](http://www.wch-ic.com/downloads/CH552DS1_PDF.html) 88 | 3. [SDCC Compiler](https://sdcc.sourceforge.net/) 89 | 4. [ATtiny85 TinyKnob](https://github.com/wagiminator/ATtiny85-TinyKnob) 90 | 5. [CH552E MacroPad mini](https://github.com/wagiminator/CH552-Macropad-mini) 91 | 6. [CH552G MacroPad plus](https://github.com/wagiminator/CH552-MacroPad-plus) 92 | 93 | ![USB_Knob_pic3.jpg](https://raw.githubusercontent.com/wagiminator/CH552-USB-Knob/main/documentation/USB_Knob_pic3.jpg) 94 | 95 | # License 96 | ![license.png](https://i.creativecommons.org/l/by-sa/3.0/88x31.png) 97 | 98 | This work is licensed under Creative Commons Attribution-ShareAlike 3.0 Unported License. 99 | (http://creativecommons.org/licenses/by-sa/3.0/) 100 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb_composite.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB HID Composite Device Functions for CH551, CH552 and CH554 3 | // =================================================================================== 4 | 5 | #include "usb_composite.h" 6 | #include "usb_hid.h" 7 | #include "usb_handler.h" 8 | 9 | #define KBD_sendReport() HID_sendReport(KBD_report, sizeof(KBD_report)) 10 | #define CON_sendReport() HID_sendReport(CON_report, sizeof(CON_report)) 11 | #define JOY_sendReport() HID_sendReport(JOY_report, sizeof(JOY_report)) 12 | #define MOUSE_sendReport() HID_sendReport(MOUSE_report, sizeof(MOUSE_report)) 13 | 14 | // =================================================================================== 15 | // HID reports 16 | // =================================================================================== 17 | __xdata uint8_t KBD_report[] = {1,0,0,0,0,0,0,0}; 18 | __xdata uint8_t CON_report[] = {2,0,0}; 19 | __xdata uint8_t MOUSE_report[] = {3,0,0,0,0}; 20 | __xdata uint8_t JOY_report[] = {4,0,0,0}; 21 | 22 | // =================================================================================== 23 | // ASCII to keycode mapping table 24 | // =================================================================================== 25 | __code uint8_t KBD_map[128] = { 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x28, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x2c, 0x9e, 0xb4, 0xa0, 0xa1, 0xa2, 0xa4, 0x34, 0xa6, 0xa7, 29 | 0xa5, 0xae, 0x36, 0x2d, 0x37, 0x38, 0x27, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 30 | 0x25, 0x26, 0xb3, 0x33, 0xb6, 0x2e, 0xb7, 0xb8, 0x9f, 0x84, 0x85, 0x86, 0x87, 0x88, 31 | 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 32 | 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x2f, 0x31, 0x30, 0xa3, 0xad, 0x35, 0x04, 33 | 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 34 | 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0xaf, 0xb1, 0xb0, 35 | 0xb5, 0x00 36 | }; 37 | 38 | // =================================================================================== 39 | // Standard Keyboard Functions 40 | // =================================================================================== 41 | 42 | // Press a key on keyboard 43 | void KBD_press(uint8_t key) { 44 | uint8_t i; 45 | 46 | // Convert key for HID report 47 | if(key >= 136) key -= 136; // non-printing key/not a modifier? 48 | else if(key >= 128) { // modifier key? 49 | KBD_report[1] |= (1<<(key-128)); // add modifier to report 50 | key = 0; 51 | } 52 | else { // printing key? 53 | key = KBD_map[key]; // convert ascii to keycode for report 54 | if(!key) return; // no valid key 55 | if(key & 0x80) { // capital letter/shift character? 56 | KBD_report[1] |= 0x02; // add left shift modifier 57 | key &= 0x7F; // remove shift from key itself 58 | } 59 | } 60 | 61 | // Check if key is already present in report 62 | for(i=3; i<8; i++) { 63 | if(KBD_report[i] == key) return; // return if already in report 64 | } 65 | 66 | // Find an empty slot, insert key and transmit report 67 | for(i=3; i<8; i++) { 68 | if(KBD_report[i] == 0) { // empty slot? 69 | KBD_report[i] = key; // insert key 70 | KBD_sendReport(); // send report 71 | return; // and return 72 | } 73 | } 74 | } 75 | 76 | // Release a key on keyboard 77 | void KBD_release(uint8_t key) { 78 | uint8_t i; 79 | 80 | // Convert key for HID report 81 | if(key >= 136) key -= 136; // non-printing key/not a modifier? 82 | else if(key >= 128) { // modifier key? 83 | KBD_report[1] &= ~(1<<(key-128)); // delete modifier in report 84 | key = 0; 85 | } 86 | else { // printing key? 87 | key = KBD_map[key]; // convert ascii to keycode for report 88 | if(!key) return; // no valid key 89 | if(key & 0x80) { // capital letter/shift character? 90 | KBD_report[1] &= ~0x02; // remove shift modifier 91 | key &= 0x7F; // remove shift from key itself 92 | } 93 | } 94 | 95 | // Delete key in report 96 | for(i=3; i<8; i++) { 97 | if(KBD_report[i] == key) KBD_report[i] = 0; // delete key in report 98 | } 99 | KBD_sendReport(); // send report 100 | } 101 | 102 | // Press and release a key on keyboard 103 | void KBD_type(uint8_t key) { 104 | KBD_press(key); 105 | KBD_release(key); 106 | } 107 | 108 | // Release all keys on keyboard 109 | void KBD_releaseAll(void) { 110 | uint8_t i; 111 | for(i=7; i; i--) KBD_report[i] = 0; // delete all keys in report 112 | KBD_sendReport(); // send report 113 | } 114 | 115 | // Write text with keyboard 116 | void KBD_print(char* str) { 117 | while(*str) KBD_type(*str++); 118 | } 119 | 120 | // =================================================================================== 121 | // Consumer Multimedia Keyboard Functions 122 | // =================================================================================== 123 | 124 | // Press a consumer key on keyboard 125 | void CON_press(uint8_t key) { 126 | CON_report[1] = key; 127 | CON_sendReport(); // send report 128 | } 129 | 130 | // Release a consumer key on keyboard 131 | void CON_release(void) { 132 | CON_report[1] = 0; 133 | CON_sendReport(); 134 | } 135 | 136 | // Press and release a consumer key on keyboard 137 | void CON_type(uint8_t key) { 138 | CON_press(key); 139 | CON_release(); 140 | } 141 | 142 | // =================================================================================== 143 | // Mouse Functions 144 | // =================================================================================== 145 | 146 | // Press mouse button(s) 147 | void MOUSE_press(uint8_t buttons) { 148 | MOUSE_report[1] |= buttons; // press button(s) 149 | MOUSE_sendReport(); // send HID report 150 | } 151 | 152 | // Release mouse button(s) 153 | void MOUSE_release(uint8_t buttons) { 154 | MOUSE_report[1] &= ~buttons; // release button(s) 155 | MOUSE_sendReport(); // send HID report 156 | } 157 | 158 | // Move mouse pointer 159 | void MOUSE_move(int8_t xrel, int8_t yrel) { 160 | MOUSE_report[2] = (uint8_t)xrel; // set relative x-movement 161 | MOUSE_report[3] = (uint8_t)yrel; // set relative y-movement 162 | MOUSE_sendReport(); // send HID report 163 | MOUSE_report[2] = 0; // reset movements 164 | MOUSE_report[3] = 0; 165 | } 166 | 167 | // Move mouse wheel 168 | void MOUSE_wheel(int8_t rel) { 169 | MOUSE_report[4] = (uint8_t)rel; // set relative wheel movement 170 | MOUSE_sendReport(); // send HID report 171 | MOUSE_report[4] = 0; // reset movements 172 | } 173 | 174 | // =================================================================================== 175 | // Joystick Functions 176 | // =================================================================================== 177 | 178 | // Press joystick button(s) 179 | void JOY_press(uint8_t buttons) { 180 | JOY_report[1] |= buttons; // press button(s) 181 | JOY_sendReport(); // send HID report 182 | } 183 | 184 | // Release joystick button(s) 185 | void JOY_release(uint8_t buttons) { 186 | JOY_report[1] &= ~buttons; // release button(s) 187 | JOY_sendReport(); // send HID report 188 | } 189 | 190 | // Move joystick 191 | void JOY_move(int8_t xrel, int8_t yrel) { 192 | JOY_report[2] = (uint8_t)xrel; // set x-movement 193 | JOY_report[3] = (uint8_t)yrel; // set y-movement 194 | JOY_sendReport(); // send HID report 195 | } 196 | -------------------------------------------------------------------------------- /software/custom_knob/src/system.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Basic System Functions for CH551, CH552 and CH554 * v1.3 * 3 | // =================================================================================== 4 | // 5 | // Functions available: 6 | // -------------------- 7 | // CLK_config() set system clock frequency according to F_CPU 8 | // CLK_external() set external crystal as clock source 9 | // CLK_internal() set internal oscillator as clock source 10 | // 11 | // WDT_start() start watchdog timer with full period 12 | // WDT_stop() stop watchdog timer 13 | // WDT_reset() reload watchdog timer with full period 14 | // WDT_set(time) reload watchdog timer with specified time in ms 15 | // WDT_feed(value) reload watchdog timer with specified value 16 | // 17 | // BOOT_now() enter bootloader 18 | // SLEEP_now() put device into sleep 19 | // RST_now() perform software reset 20 | // 21 | // RST_keep(value) keep this value after RESET 22 | // RST_getKeep() read the keeped value 23 | // RST_wasWDT() check if last RESET was caused by watchdog timer 24 | // RST_wasPIN() check if last RESET was caused by RST PIN 25 | // RST_wasPWR() check if last RESET was caused by power-on 26 | // RST_wasSOFT() check if last RESET was caused by software 27 | // 28 | // WAKE_enable(source) enable wake-up from sleep source (sources see below) 29 | // WAKE_disable(source) disable wake-up from sleep source 30 | // WAKE_all_disable() disable all wake-up sources 31 | // 32 | // WAKE_USB_enable() enable wake-up by USB event 33 | // WAKE_RXD0_enable() enable wake-up by RXD0 low level 34 | // WAKE_RXD1_enable() enable wake-up by RXD1 low level 35 | // WAKE_P13_enable() enable wake-up by pin P1.3 low level 36 | // WAKE_P14_enable() enable wake-up by pin P1.4 low level 37 | // WAKE_P15_enable() enable wake-up by pin P1.5 low level 38 | // WAKE_RST_enable() enable wake-up by pin RST high level 39 | // WAKE_INT_enable() enable wake-up by pin P3.2 edge or pin P3.3 low level 40 | // 41 | // WAKE_USB_disable() disable wake-up by USB event 42 | // WAKE_RXD0_disable() disable wake-up by RXD0 low level 43 | // WAKE_RXD1_disable() disable wake-up by RXD1 low level 44 | // WAKE_P13_disable() disable wake-up by pin P1.3 low level 45 | // WAKE_P14_disable() disable wake-up by pin P1.4 low level 46 | // WAKE_P15_disable() disable wake-up by pin P1.5 low level 47 | // WAKE_RST_disable() disable wake-up by pin RST high level 48 | // WAKE_INT_disable() disable wake-up by pin P3.2 edge or pin P3.3 low level 49 | // 50 | // Wake-up from SLEEP sources: 51 | // --------------------------- 52 | // WAKE_USB wake-up by USB event 53 | // WAKE_RXD0 wake-up by RXD0 low level 54 | // WAKE_RXD1 wake-up by RXD1 low level 55 | // WAKE_P13 wake-up by pin P1.3 low level 56 | // WAKE_P14 wake-up by pin P1.4 low level 57 | // WAKE_P15 wake-up by pin P1.5 low level 58 | // WAKE_RST wake-up by pin RST high level 59 | // WAKE_INT wake-up by pin P3.2 edge or pin P3.3 low level 60 | // 61 | // 2023 by Stefan Wagner: https://github.com/wagiminator 62 | 63 | #pragma once 64 | #include 65 | #include "ch554.h" 66 | 67 | // =================================================================================== 68 | // System Clock 69 | // =================================================================================== 70 | inline void CLK_config(void) { 71 | SAFE_MOD = 0x55; 72 | SAFE_MOD = 0xAA; // enter safe mode 73 | 74 | #if F_CPU == 32000000 75 | __asm__("orl _CLOCK_CFG, #0b00000111"); // 32MHz 76 | #elif F_CPU == 24000000 77 | __asm__("anl _CLOCK_CFG, #0b11111000"); 78 | __asm__("orl _CLOCK_CFG, #0b00000110"); // 24MHz 79 | #elif F_CPU == 16000000 80 | __asm__("anl _CLOCK_CFG, #0b11111000"); 81 | __asm__("orl _CLOCK_CFG, #0b00000101"); // 16MHz 82 | #elif F_CPU == 12000000 83 | __asm__("anl _CLOCK_CFG, #0b11111000"); 84 | __asm__("orl _CLOCK_CFG, #0b00000100"); // 12MHz 85 | #elif F_CPU == 6000000 86 | __asm__("anl _CLOCK_CFG, #0b11111000"); 87 | __asm__("orl _CLOCK_CFG, #0b00000011"); // 6MHz 88 | #elif F_CPU == 3000000 89 | __asm__("anl _CLOCK_CFG, #0b11111000"); 90 | __asm__("orl _CLOCK_CFG, #0b00000010"); // 3MHz 91 | #elif F_CPU == 750000 92 | __asm__("anl _CLOCK_CFG, #0b11111000"); 93 | __asm__("orl _CLOCK_CFG, #0b00000001"); // 750kHz 94 | #elif F_CPU == 187500 95 | __asm__("anl _CLOCK_CFG, #0b11111000"); // 187.5kHz 96 | #else 97 | #warning F_CPU invalid or not set 98 | #endif 99 | 100 | SAFE_MOD = 0x00; // terminate safe mode 101 | } 102 | 103 | inline void CLK_external(void) { 104 | SAFE_MOD = 0x55; 105 | SAFE_MOD = 0xAA; // enter safe mode 106 | CLOCK_CFG |= bOSC_EN_XT; // enable external crystal 107 | CLOCK_CFG &= ~bOSC_EN_INT; // turn off internal oscillator 108 | SAFE_MOD = 0x00; // terminate safe mode 109 | } 110 | 111 | inline void CLK_inernal(void) { 112 | SAFE_MOD = 0x55; 113 | SAFE_MOD = 0xAA; // enter safe mode 114 | CLOCK_CFG |= bOSC_EN_INT; // turn on internal oscillator 115 | CLOCK_CFG &= ~bOSC_EN_XT; // disable external crystal 116 | SAFE_MOD = 0x00; // terminate safe mode 117 | } 118 | 119 | // =================================================================================== 120 | // Watchdog Timer 121 | // =================================================================================== 122 | #define WDT_reset() WDOG_COUNT = 0 123 | #define WDT_feed(value) WDOG_COUNT = value 124 | #define WDT_set(time) WDOG_COUNT = (uint8_t)(256 - ((F_CPU / 1000) * time / 65536)) 125 | 126 | inline void WDT_start(void) { 127 | WDOG_COUNT = 0; 128 | SAFE_MOD = 0x55; 129 | SAFE_MOD = 0xAA; 130 | GLOBAL_CFG |= bWDOG_EN; 131 | SAFE_MOD = 0x00; 132 | } 133 | 134 | inline void WDT_stop(void) { 135 | SAFE_MOD = 0x55; 136 | SAFE_MOD = 0xAA; 137 | GLOBAL_CFG &= ~bWDOG_EN; 138 | SAFE_MOD = 0x00; 139 | } 140 | 141 | // =================================================================================== 142 | // Reset 143 | // =================================================================================== 144 | #define RST_keep(value) RESET_KEEP = value 145 | #define RST_getKeep() (RESET_KEEP) 146 | #define RST_wasWDT() ((PCON & MASK_RST_FLAG) == RST_FLAG_WDOG) 147 | #define RST_wasPIN() ((PCON & MASK_RST_FLAG) == RST_FLAG_PIN) 148 | #define RST_wasPWR() ((PCON & MASK_RST_FLAG) == RST_FLAG_POR) 149 | #define RST_wasSOFT() ((PCON & MASK_RST_FLAG) == RST_FLAG_SW) 150 | 151 | inline void RST_now(void) { 152 | SAFE_MOD = 0x55; 153 | SAFE_MOD = 0xAA; 154 | GLOBAL_CFG |= bSW_RESET; 155 | } 156 | 157 | // =================================================================================== 158 | // Bootloader 159 | // =================================================================================== 160 | inline void BOOT_now(void) { 161 | USB_CTRL = 0; 162 | EA = 0; 163 | TMOD = 0; 164 | __asm 165 | lcall #BOOT_LOAD_ADDR 166 | __endasm; 167 | } 168 | 169 | // =================================================================================== 170 | // Sleep 171 | // =================================================================================== 172 | #define SLEEP_now() PCON |= PD 173 | 174 | #define WAKE_USB bWAK_BY_USB // wake-up by USB event 175 | #define WAKE_RXD0 bWAK_RXD0_LO // wake-up by RXD0 low level 176 | #define WAKE_RXD1 bWAK_RXD1_LO // wake-up by RXD1 low level 177 | #define WAKE_P13 bWAK_P1_3_LO // wake-up by pin P1.3 low level 178 | #define WAKE_P14 bWAK_P1_4_LO // wake-up by pin P1.4 low level 179 | #define WAKE_P15 bWAK_P1_5_LO // wake-up by pin P1.5 low level 180 | #define WAKE_RST bWAK_RST_HI // wake-up by pin RST high level 181 | #define WAKE_INT bWAK_P3_2E_3L // wake-up by pin P3.2 (INT0) edge or pin P3.3 (INT1) low level 182 | 183 | #define WAKE_enable(source) WAKE_CTRL |= source 184 | #define WAKE_disable(source) WAKE_CTRL &= ~source 185 | #define WAKE_all_disable() WAKE_CTRL = 0 186 | 187 | #define WAKE_USB_enable() WAKE_CTRL |= bWAK_BY_USB 188 | #define WAKE_RXD0_enable() WAKE_CTRL |= bWAK_RXD0_LO 189 | #define WAKE_RXD1_enable() WAKE_CTRL |= bWAK_RXD1_LO 190 | #define WAKE_P13_enable() WAKE_CTRL |= bWAK_P1_3_LO 191 | #define WAKE_P14_enable() WAKE_CTRL |= bWAK_P1_4_LO 192 | #define WAKE_P15_enable() WAKE_CTRL |= bWAK_P1_5_LO 193 | #define WAKE_RST_enable() WAKE_CTRL |= bWAK_RST_HI 194 | #define WAKE_INT_enable() WAKE_CTRL |= bWAK_P3_2E_3L 195 | 196 | #define WAKE_USB_disable() WAKE_CTRL &= ~bWAK_BY_USB 197 | #define WAKE_RXD0_disable() WAKE_CTRL &= ~bWAK_RXD0_LO 198 | #define WAKE_RXD1_disable() WAKE_CTRL &= ~bWAK_RXD1_LO 199 | #define WAKE_P13_disable() WAKE_CTRL &= ~bWAK_P1_3_LO 200 | #define WAKE_P14_disable() WAKE_CTRL &= ~bWAK_P1_4_LO 201 | #define WAKE_P15_disable() WAKE_CTRL &= ~bWAK_P1_5_LO 202 | #define WAKE_RST_disable() WAKE_CTRL &= ~bWAK_RST_HI 203 | #define WAKE_INT_disable() WAKE_CTRL &= ~bWAK_P3_2E_3L 204 | -------------------------------------------------------------------------------- /software/volume_knob/src/system.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Basic System Functions for CH551, CH552 and CH554 * v1.3 * 3 | // =================================================================================== 4 | // 5 | // Functions available: 6 | // -------------------- 7 | // CLK_config() set system clock frequency according to F_CPU 8 | // CLK_external() set external crystal as clock source 9 | // CLK_internal() set internal oscillator as clock source 10 | // 11 | // WDT_start() start watchdog timer with full period 12 | // WDT_stop() stop watchdog timer 13 | // WDT_reset() reload watchdog timer with full period 14 | // WDT_set(time) reload watchdog timer with specified time in ms 15 | // WDT_feed(value) reload watchdog timer with specified value 16 | // 17 | // BOOT_now() enter bootloader 18 | // SLEEP_now() put device into sleep 19 | // RST_now() perform software reset 20 | // 21 | // RST_keep(value) keep this value after RESET 22 | // RST_getKeep() read the keeped value 23 | // RST_wasWDT() check if last RESET was caused by watchdog timer 24 | // RST_wasPIN() check if last RESET was caused by RST PIN 25 | // RST_wasPWR() check if last RESET was caused by power-on 26 | // RST_wasSOFT() check if last RESET was caused by software 27 | // 28 | // WAKE_enable(source) enable wake-up from sleep source (sources see below) 29 | // WAKE_disable(source) disable wake-up from sleep source 30 | // WAKE_all_disable() disable all wake-up sources 31 | // 32 | // WAKE_USB_enable() enable wake-up by USB event 33 | // WAKE_RXD0_enable() enable wake-up by RXD0 low level 34 | // WAKE_RXD1_enable() enable wake-up by RXD1 low level 35 | // WAKE_P13_enable() enable wake-up by pin P1.3 low level 36 | // WAKE_P14_enable() enable wake-up by pin P1.4 low level 37 | // WAKE_P15_enable() enable wake-up by pin P1.5 low level 38 | // WAKE_RST_enable() enable wake-up by pin RST high level 39 | // WAKE_INT_enable() enable wake-up by pin P3.2 edge or pin P3.3 low level 40 | // 41 | // WAKE_USB_disable() disable wake-up by USB event 42 | // WAKE_RXD0_disable() disable wake-up by RXD0 low level 43 | // WAKE_RXD1_disable() disable wake-up by RXD1 low level 44 | // WAKE_P13_disable() disable wake-up by pin P1.3 low level 45 | // WAKE_P14_disable() disable wake-up by pin P1.4 low level 46 | // WAKE_P15_disable() disable wake-up by pin P1.5 low level 47 | // WAKE_RST_disable() disable wake-up by pin RST high level 48 | // WAKE_INT_disable() disable wake-up by pin P3.2 edge or pin P3.3 low level 49 | // 50 | // Wake-up from SLEEP sources: 51 | // --------------------------- 52 | // WAKE_USB wake-up by USB event 53 | // WAKE_RXD0 wake-up by RXD0 low level 54 | // WAKE_RXD1 wake-up by RXD1 low level 55 | // WAKE_P13 wake-up by pin P1.3 low level 56 | // WAKE_P14 wake-up by pin P1.4 low level 57 | // WAKE_P15 wake-up by pin P1.5 low level 58 | // WAKE_RST wake-up by pin RST high level 59 | // WAKE_INT wake-up by pin P3.2 edge or pin P3.3 low level 60 | // 61 | // 2023 by Stefan Wagner: https://github.com/wagiminator 62 | 63 | #pragma once 64 | #include 65 | #include "ch554.h" 66 | 67 | // =================================================================================== 68 | // System Clock 69 | // =================================================================================== 70 | inline void CLK_config(void) { 71 | SAFE_MOD = 0x55; 72 | SAFE_MOD = 0xAA; // enter safe mode 73 | 74 | #if F_CPU == 32000000 75 | __asm__("orl _CLOCK_CFG, #0b00000111"); // 32MHz 76 | #elif F_CPU == 24000000 77 | __asm__("anl _CLOCK_CFG, #0b11111000"); 78 | __asm__("orl _CLOCK_CFG, #0b00000110"); // 24MHz 79 | #elif F_CPU == 16000000 80 | __asm__("anl _CLOCK_CFG, #0b11111000"); 81 | __asm__("orl _CLOCK_CFG, #0b00000101"); // 16MHz 82 | #elif F_CPU == 12000000 83 | __asm__("anl _CLOCK_CFG, #0b11111000"); 84 | __asm__("orl _CLOCK_CFG, #0b00000100"); // 12MHz 85 | #elif F_CPU == 6000000 86 | __asm__("anl _CLOCK_CFG, #0b11111000"); 87 | __asm__("orl _CLOCK_CFG, #0b00000011"); // 6MHz 88 | #elif F_CPU == 3000000 89 | __asm__("anl _CLOCK_CFG, #0b11111000"); 90 | __asm__("orl _CLOCK_CFG, #0b00000010"); // 3MHz 91 | #elif F_CPU == 750000 92 | __asm__("anl _CLOCK_CFG, #0b11111000"); 93 | __asm__("orl _CLOCK_CFG, #0b00000001"); // 750kHz 94 | #elif F_CPU == 187500 95 | __asm__("anl _CLOCK_CFG, #0b11111000"); // 187.5kHz 96 | #else 97 | #warning F_CPU invalid or not set 98 | #endif 99 | 100 | SAFE_MOD = 0x00; // terminate safe mode 101 | } 102 | 103 | inline void CLK_external(void) { 104 | SAFE_MOD = 0x55; 105 | SAFE_MOD = 0xAA; // enter safe mode 106 | CLOCK_CFG |= bOSC_EN_XT; // enable external crystal 107 | CLOCK_CFG &= ~bOSC_EN_INT; // turn off internal oscillator 108 | SAFE_MOD = 0x00; // terminate safe mode 109 | } 110 | 111 | inline void CLK_inernal(void) { 112 | SAFE_MOD = 0x55; 113 | SAFE_MOD = 0xAA; // enter safe mode 114 | CLOCK_CFG |= bOSC_EN_INT; // turn on internal oscillator 115 | CLOCK_CFG &= ~bOSC_EN_XT; // disable external crystal 116 | SAFE_MOD = 0x00; // terminate safe mode 117 | } 118 | 119 | // =================================================================================== 120 | // Watchdog Timer 121 | // =================================================================================== 122 | #define WDT_reset() WDOG_COUNT = 0 123 | #define WDT_feed(value) WDOG_COUNT = value 124 | #define WDT_set(time) WDOG_COUNT = (uint8_t)(256 - ((F_CPU / 1000) * time / 65536)) 125 | 126 | inline void WDT_start(void) { 127 | WDOG_COUNT = 0; 128 | SAFE_MOD = 0x55; 129 | SAFE_MOD = 0xAA; 130 | GLOBAL_CFG |= bWDOG_EN; 131 | SAFE_MOD = 0x00; 132 | } 133 | 134 | inline void WDT_stop(void) { 135 | SAFE_MOD = 0x55; 136 | SAFE_MOD = 0xAA; 137 | GLOBAL_CFG &= ~bWDOG_EN; 138 | SAFE_MOD = 0x00; 139 | } 140 | 141 | // =================================================================================== 142 | // Reset 143 | // =================================================================================== 144 | #define RST_keep(value) RESET_KEEP = value 145 | #define RST_getKeep() (RESET_KEEP) 146 | #define RST_wasWDT() ((PCON & MASK_RST_FLAG) == RST_FLAG_WDOG) 147 | #define RST_wasPIN() ((PCON & MASK_RST_FLAG) == RST_FLAG_PIN) 148 | #define RST_wasPWR() ((PCON & MASK_RST_FLAG) == RST_FLAG_POR) 149 | #define RST_wasSOFT() ((PCON & MASK_RST_FLAG) == RST_FLAG_SW) 150 | 151 | inline void RST_now(void) { 152 | SAFE_MOD = 0x55; 153 | SAFE_MOD = 0xAA; 154 | GLOBAL_CFG |= bSW_RESET; 155 | } 156 | 157 | // =================================================================================== 158 | // Bootloader 159 | // =================================================================================== 160 | inline void BOOT_now(void) { 161 | USB_CTRL = 0; 162 | EA = 0; 163 | TMOD = 0; 164 | __asm 165 | lcall #BOOT_LOAD_ADDR 166 | __endasm; 167 | } 168 | 169 | // =================================================================================== 170 | // Sleep 171 | // =================================================================================== 172 | #define SLEEP_now() PCON |= PD 173 | 174 | #define WAKE_USB bWAK_BY_USB // wake-up by USB event 175 | #define WAKE_RXD0 bWAK_RXD0_LO // wake-up by RXD0 low level 176 | #define WAKE_RXD1 bWAK_RXD1_LO // wake-up by RXD1 low level 177 | #define WAKE_P13 bWAK_P1_3_LO // wake-up by pin P1.3 low level 178 | #define WAKE_P14 bWAK_P1_4_LO // wake-up by pin P1.4 low level 179 | #define WAKE_P15 bWAK_P1_5_LO // wake-up by pin P1.5 low level 180 | #define WAKE_RST bWAK_RST_HI // wake-up by pin RST high level 181 | #define WAKE_INT bWAK_P3_2E_3L // wake-up by pin P3.2 (INT0) edge or pin P3.3 (INT1) low level 182 | 183 | #define WAKE_enable(source) WAKE_CTRL |= source 184 | #define WAKE_disable(source) WAKE_CTRL &= ~source 185 | #define WAKE_all_disable() WAKE_CTRL = 0 186 | 187 | #define WAKE_USB_enable() WAKE_CTRL |= bWAK_BY_USB 188 | #define WAKE_RXD0_enable() WAKE_CTRL |= bWAK_RXD0_LO 189 | #define WAKE_RXD1_enable() WAKE_CTRL |= bWAK_RXD1_LO 190 | #define WAKE_P13_enable() WAKE_CTRL |= bWAK_P1_3_LO 191 | #define WAKE_P14_enable() WAKE_CTRL |= bWAK_P1_4_LO 192 | #define WAKE_P15_enable() WAKE_CTRL |= bWAK_P1_5_LO 193 | #define WAKE_RST_enable() WAKE_CTRL |= bWAK_RST_HI 194 | #define WAKE_INT_enable() WAKE_CTRL |= bWAK_P3_2E_3L 195 | 196 | #define WAKE_USB_disable() WAKE_CTRL &= ~bWAK_BY_USB 197 | #define WAKE_RXD0_disable() WAKE_CTRL &= ~bWAK_RXD0_LO 198 | #define WAKE_RXD1_disable() WAKE_CTRL &= ~bWAK_RXD1_LO 199 | #define WAKE_P13_disable() WAKE_CTRL &= ~bWAK_P1_3_LO 200 | #define WAKE_P14_disable() WAKE_CTRL &= ~bWAK_P1_4_LO 201 | #define WAKE_P15_disable() WAKE_CTRL &= ~bWAK_P1_5_LO 202 | #define WAKE_RST_disable() WAKE_CTRL &= ~bWAK_RST_HI 203 | #define WAKE_INT_disable() WAKE_CTRL &= ~bWAK_P3_2E_3L 204 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/system.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Basic System Functions for CH551, CH552 and CH554 * v1.3 * 3 | // =================================================================================== 4 | // 5 | // Functions available: 6 | // -------------------- 7 | // CLK_config() set system clock frequency according to F_CPU 8 | // CLK_external() set external crystal as clock source 9 | // CLK_internal() set internal oscillator as clock source 10 | // 11 | // WDT_start() start watchdog timer with full period 12 | // WDT_stop() stop watchdog timer 13 | // WDT_reset() reload watchdog timer with full period 14 | // WDT_set(time) reload watchdog timer with specified time in ms 15 | // WDT_feed(value) reload watchdog timer with specified value 16 | // 17 | // BOOT_now() enter bootloader 18 | // SLEEP_now() put device into sleep 19 | // RST_now() perform software reset 20 | // 21 | // RST_keep(value) keep this value after RESET 22 | // RST_getKeep() read the keeped value 23 | // RST_wasWDT() check if last RESET was caused by watchdog timer 24 | // RST_wasPIN() check if last RESET was caused by RST PIN 25 | // RST_wasPWR() check if last RESET was caused by power-on 26 | // RST_wasSOFT() check if last RESET was caused by software 27 | // 28 | // WAKE_enable(source) enable wake-up from sleep source (sources see below) 29 | // WAKE_disable(source) disable wake-up from sleep source 30 | // WAKE_all_disable() disable all wake-up sources 31 | // 32 | // WAKE_USB_enable() enable wake-up by USB event 33 | // WAKE_RXD0_enable() enable wake-up by RXD0 low level 34 | // WAKE_RXD1_enable() enable wake-up by RXD1 low level 35 | // WAKE_P13_enable() enable wake-up by pin P1.3 low level 36 | // WAKE_P14_enable() enable wake-up by pin P1.4 low level 37 | // WAKE_P15_enable() enable wake-up by pin P1.5 low level 38 | // WAKE_RST_enable() enable wake-up by pin RST high level 39 | // WAKE_INT_enable() enable wake-up by pin P3.2 edge or pin P3.3 low level 40 | // 41 | // WAKE_USB_disable() disable wake-up by USB event 42 | // WAKE_RXD0_disable() disable wake-up by RXD0 low level 43 | // WAKE_RXD1_disable() disable wake-up by RXD1 low level 44 | // WAKE_P13_disable() disable wake-up by pin P1.3 low level 45 | // WAKE_P14_disable() disable wake-up by pin P1.4 low level 46 | // WAKE_P15_disable() disable wake-up by pin P1.5 low level 47 | // WAKE_RST_disable() disable wake-up by pin RST high level 48 | // WAKE_INT_disable() disable wake-up by pin P3.2 edge or pin P3.3 low level 49 | // 50 | // Wake-up from SLEEP sources: 51 | // --------------------------- 52 | // WAKE_USB wake-up by USB event 53 | // WAKE_RXD0 wake-up by RXD0 low level 54 | // WAKE_RXD1 wake-up by RXD1 low level 55 | // WAKE_P13 wake-up by pin P1.3 low level 56 | // WAKE_P14 wake-up by pin P1.4 low level 57 | // WAKE_P15 wake-up by pin P1.5 low level 58 | // WAKE_RST wake-up by pin RST high level 59 | // WAKE_INT wake-up by pin P3.2 edge or pin P3.3 low level 60 | // 61 | // 2023 by Stefan Wagner: https://github.com/wagiminator 62 | 63 | #pragma once 64 | #include 65 | #include "ch554.h" 66 | 67 | // =================================================================================== 68 | // System Clock 69 | // =================================================================================== 70 | inline void CLK_config(void) { 71 | SAFE_MOD = 0x55; 72 | SAFE_MOD = 0xAA; // enter safe mode 73 | 74 | #if F_CPU == 32000000 75 | __asm__("orl _CLOCK_CFG, #0b00000111"); // 32MHz 76 | #elif F_CPU == 24000000 77 | __asm__("anl _CLOCK_CFG, #0b11111000"); 78 | __asm__("orl _CLOCK_CFG, #0b00000110"); // 24MHz 79 | #elif F_CPU == 16000000 80 | __asm__("anl _CLOCK_CFG, #0b11111000"); 81 | __asm__("orl _CLOCK_CFG, #0b00000101"); // 16MHz 82 | #elif F_CPU == 12000000 83 | __asm__("anl _CLOCK_CFG, #0b11111000"); 84 | __asm__("orl _CLOCK_CFG, #0b00000100"); // 12MHz 85 | #elif F_CPU == 6000000 86 | __asm__("anl _CLOCK_CFG, #0b11111000"); 87 | __asm__("orl _CLOCK_CFG, #0b00000011"); // 6MHz 88 | #elif F_CPU == 3000000 89 | __asm__("anl _CLOCK_CFG, #0b11111000"); 90 | __asm__("orl _CLOCK_CFG, #0b00000010"); // 3MHz 91 | #elif F_CPU == 750000 92 | __asm__("anl _CLOCK_CFG, #0b11111000"); 93 | __asm__("orl _CLOCK_CFG, #0b00000001"); // 750kHz 94 | #elif F_CPU == 187500 95 | __asm__("anl _CLOCK_CFG, #0b11111000"); // 187.5kHz 96 | #else 97 | #warning F_CPU invalid or not set 98 | #endif 99 | 100 | SAFE_MOD = 0x00; // terminate safe mode 101 | } 102 | 103 | inline void CLK_external(void) { 104 | SAFE_MOD = 0x55; 105 | SAFE_MOD = 0xAA; // enter safe mode 106 | CLOCK_CFG |= bOSC_EN_XT; // enable external crystal 107 | CLOCK_CFG &= ~bOSC_EN_INT; // turn off internal oscillator 108 | SAFE_MOD = 0x00; // terminate safe mode 109 | } 110 | 111 | inline void CLK_inernal(void) { 112 | SAFE_MOD = 0x55; 113 | SAFE_MOD = 0xAA; // enter safe mode 114 | CLOCK_CFG |= bOSC_EN_INT; // turn on internal oscillator 115 | CLOCK_CFG &= ~bOSC_EN_XT; // disable external crystal 116 | SAFE_MOD = 0x00; // terminate safe mode 117 | } 118 | 119 | // =================================================================================== 120 | // Watchdog Timer 121 | // =================================================================================== 122 | #define WDT_reset() WDOG_COUNT = 0 123 | #define WDT_feed(value) WDOG_COUNT = value 124 | #define WDT_set(time) WDOG_COUNT = (uint8_t)(256 - ((F_CPU / 1000) * time / 65536)) 125 | 126 | inline void WDT_start(void) { 127 | WDOG_COUNT = 0; 128 | SAFE_MOD = 0x55; 129 | SAFE_MOD = 0xAA; 130 | GLOBAL_CFG |= bWDOG_EN; 131 | SAFE_MOD = 0x00; 132 | } 133 | 134 | inline void WDT_stop(void) { 135 | SAFE_MOD = 0x55; 136 | SAFE_MOD = 0xAA; 137 | GLOBAL_CFG &= ~bWDOG_EN; 138 | SAFE_MOD = 0x00; 139 | } 140 | 141 | // =================================================================================== 142 | // Reset 143 | // =================================================================================== 144 | #define RST_keep(value) RESET_KEEP = value 145 | #define RST_getKeep() (RESET_KEEP) 146 | #define RST_wasWDT() ((PCON & MASK_RST_FLAG) == RST_FLAG_WDOG) 147 | #define RST_wasPIN() ((PCON & MASK_RST_FLAG) == RST_FLAG_PIN) 148 | #define RST_wasPWR() ((PCON & MASK_RST_FLAG) == RST_FLAG_POR) 149 | #define RST_wasSOFT() ((PCON & MASK_RST_FLAG) == RST_FLAG_SW) 150 | 151 | inline void RST_now(void) { 152 | SAFE_MOD = 0x55; 153 | SAFE_MOD = 0xAA; 154 | GLOBAL_CFG |= bSW_RESET; 155 | } 156 | 157 | // =================================================================================== 158 | // Bootloader 159 | // =================================================================================== 160 | inline void BOOT_now(void) { 161 | USB_CTRL = 0; 162 | EA = 0; 163 | TMOD = 0; 164 | __asm 165 | lcall #BOOT_LOAD_ADDR 166 | __endasm; 167 | } 168 | 169 | // =================================================================================== 170 | // Sleep 171 | // =================================================================================== 172 | #define SLEEP_now() PCON |= PD 173 | 174 | #define WAKE_USB bWAK_BY_USB // wake-up by USB event 175 | #define WAKE_RXD0 bWAK_RXD0_LO // wake-up by RXD0 low level 176 | #define WAKE_RXD1 bWAK_RXD1_LO // wake-up by RXD1 low level 177 | #define WAKE_P13 bWAK_P1_3_LO // wake-up by pin P1.3 low level 178 | #define WAKE_P14 bWAK_P1_4_LO // wake-up by pin P1.4 low level 179 | #define WAKE_P15 bWAK_P1_5_LO // wake-up by pin P1.5 low level 180 | #define WAKE_RST bWAK_RST_HI // wake-up by pin RST high level 181 | #define WAKE_INT bWAK_P3_2E_3L // wake-up by pin P3.2 (INT0) edge or pin P3.3 (INT1) low level 182 | 183 | #define WAKE_enable(source) WAKE_CTRL |= source 184 | #define WAKE_disable(source) WAKE_CTRL &= ~source 185 | #define WAKE_all_disable() WAKE_CTRL = 0 186 | 187 | #define WAKE_USB_enable() WAKE_CTRL |= bWAK_BY_USB 188 | #define WAKE_RXD0_enable() WAKE_CTRL |= bWAK_RXD0_LO 189 | #define WAKE_RXD1_enable() WAKE_CTRL |= bWAK_RXD1_LO 190 | #define WAKE_P13_enable() WAKE_CTRL |= bWAK_P1_3_LO 191 | #define WAKE_P14_enable() WAKE_CTRL |= bWAK_P1_4_LO 192 | #define WAKE_P15_enable() WAKE_CTRL |= bWAK_P1_5_LO 193 | #define WAKE_RST_enable() WAKE_CTRL |= bWAK_RST_HI 194 | #define WAKE_INT_enable() WAKE_CTRL |= bWAK_P3_2E_3L 195 | 196 | #define WAKE_USB_disable() WAKE_CTRL &= ~bWAK_BY_USB 197 | #define WAKE_RXD0_disable() WAKE_CTRL &= ~bWAK_RXD0_LO 198 | #define WAKE_RXD1_disable() WAKE_CTRL &= ~bWAK_RXD1_LO 199 | #define WAKE_P13_disable() WAKE_CTRL &= ~bWAK_P1_3_LO 200 | #define WAKE_P14_disable() WAKE_CTRL &= ~bWAK_P1_4_LO 201 | #define WAKE_P15_disable() WAKE_CTRL &= ~bWAK_P1_5_LO 202 | #define WAKE_RST_disable() WAKE_CTRL &= ~bWAK_RST_HI 203 | #define WAKE_INT_disable() WAKE_CTRL &= ~bWAK_P3_2E_3L 204 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb_descr.c: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB Descriptors 3 | // =================================================================================== 4 | 5 | #include "usb_descr.h" 6 | 7 | // =================================================================================== 8 | // Device Descriptor 9 | // =================================================================================== 10 | __code USB_DEV_DESCR DevDescr = { 11 | .bLength = sizeof(DevDescr), // size of the descriptor in bytes: 18 12 | .bDescriptorType = USB_DESCR_TYP_DEVICE, // device descriptor: 0x01 13 | .bcdUSB = 0x0110, // USB specification: USB 1.1 14 | .bDeviceClass = 0, // interface will define class 15 | .bDeviceSubClass = 0, // unused 16 | .bDeviceProtocol = 0, // unused 17 | .bMaxPacketSize0 = EP0_SIZE, // maximum packet size for Endpoint 0 18 | .idVendor = USB_VENDOR_ID, // VID 19 | .idProduct = USB_PRODUCT_ID, // PID 20 | .bcdDevice = USB_DEVICE_VERSION, // device version 21 | .iManufacturer = 1, // index of Manufacturer String Descr 22 | .iProduct = 2, // index of Product String Descriptor 23 | .iSerialNumber = 3, // index of Serial Number String Descr 24 | .bNumConfigurations = 1 // number of possible configurations 25 | }; 26 | 27 | // =================================================================================== 28 | // Configuration Descriptor 29 | // =================================================================================== 30 | __code USB_CFG_DESCR_HID CfgDescr = { 31 | 32 | // Configuration Descriptor 33 | .config = { 34 | .bLength = sizeof(USB_CFG_DESCR), // size of the descriptor in bytes 35 | .bDescriptorType = USB_DESCR_TYP_CONFIG, // configuration descriptor: 0x02 36 | .wTotalLength = sizeof(CfgDescr), // total length in bytes 37 | .bNumInterfaces = 1, // number of interfaces: 1 38 | .bConfigurationValue= 1, // value to select this configuration 39 | .iConfiguration = 0, // no configuration string descriptor 40 | .bmAttributes = 0x80, // attributes = bus powered, no wakeup 41 | .MaxPower = USB_MAX_POWER_mA / 2 // in 2mA units 42 | }, 43 | 44 | // Interface Descriptor 45 | .interface0 = { 46 | .bLength = sizeof(USB_ITF_DESCR), // size of the descriptor in bytes: 9 47 | .bDescriptorType = USB_DESCR_TYP_INTERF, // interface descriptor: 0x04 48 | .bInterfaceNumber = 0, // number of this interface: 0 49 | .bAlternateSetting = 0, // value used to select alternative setting 50 | .bNumEndpoints = 2, // number of endpoints used: 2 51 | .bInterfaceClass = USB_DEV_CLASS_HID, // interface class: HID (0x03) 52 | .bInterfaceSubClass = 1, // boot interface 53 | .bInterfaceProtocol = 1, // keyboard 54 | .iInterface = 4 // interface string descriptor 55 | }, 56 | 57 | // HID Descriptor 58 | .hid0 = { 59 | .bLength = sizeof(USB_HID_DESCR), // size of the descriptor in bytes: 9 60 | .bDescriptorType = USB_DESCR_TYP_HID, // HID descriptor: 0x21 61 | .bcdHID = 0x0110, // HID class spec version (BCD: 1.1) 62 | .bCountryCode = 33, // country code: US 63 | .bNumDescriptors = 1, // number of report descriptors: 1 64 | .bDescriptorTypeX = USB_DESCR_TYP_REPORT, // descriptor type: report (0x22) 65 | .wDescriptorLength = sizeof(ReportDescr) // report descriptor length 66 | }, 67 | 68 | // Endpoint Descriptor: Endpoint 1 (IN, Interrupt) 69 | .ep1IN = { 70 | .bLength = sizeof(USB_ENDP_DESCR), // size of the descriptor in bytes: 7 71 | .bDescriptorType = USB_DESCR_TYP_ENDP, // endpoint descriptor: 0x05 72 | .bEndpointAddress = USB_ENDP_ADDR_EP1_IN, // endpoint: 1, direction: IN (0x81) 73 | .bmAttributes = USB_ENDP_TYPE_INTER, // transfer type: interrupt (0x03) 74 | .wMaxPacketSize = EP1_SIZE, // max packet size 75 | .bInterval = 1 // polling intervall in ms 76 | }, 77 | 78 | // Endpoint Descriptor: Endpoint 2 (OUT, Interrupt) 79 | .ep2OUT = { 80 | .bLength = sizeof(USB_ENDP_DESCR), // size of the descriptor in bytes: 7 81 | .bDescriptorType = USB_DESCR_TYP_ENDP, // endpoint descriptor: 0x05 82 | .bEndpointAddress = USB_ENDP_ADDR_EP2_OUT, // endpoint: 1, direction: OUT (0x02) 83 | .bmAttributes = USB_ENDP_TYPE_INTER, // transfer type: interrupt (0x03) 84 | .wMaxPacketSize = EP2_SIZE, // max packet size 85 | .bInterval = 10 // polling intervall in ms 86 | } 87 | }; 88 | 89 | // =================================================================================== 90 | // HID Report Descriptor 91 | // =================================================================================== 92 | __code uint8_t ReportDescr[] ={ 93 | // Standard keyboard 94 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 95 | 0x09, 0x06, // USAGE (Keyboard) 96 | 0xa1, 0x01, // COLLECTION (Application) 97 | 0x85, 0x01, // REPORT_ID (1) 98 | 0x05, 0x07, // USAGE_PAGE (Keyboard) 99 | 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 100 | 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 101 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 102 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) 103 | 0x75, 0x01, // REPORT_SIZE (1) 104 | 0x95, 0x08, // REPORT_COUNT (8) 105 | 0x81, 0x02, // INPUT (Data,Var,Abs) 106 | 0x75, 0x08, // REPORT_SIZE (8) 107 | 0x95, 0x01, // REPORT_COUNT (1) 108 | 0x81, 0x03, // INPUT (Cnst,Var,Abs) 109 | 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 110 | 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 111 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 112 | 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 113 | 0x75, 0x08, // REPORT_SIZE (8) 114 | 0x95, 0x05, // REPORT_COUNT (5) 115 | 0x81, 0x00, // INPUT (Data,Ary,Abs) 116 | 0x05, 0x08, // USAGE_PAGE (LEDs) 117 | 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 118 | 0x29, 0x05, // USAGE_MAXIMUM (Kana) 119 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 120 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) 121 | 0x75, 0x01, // REPORT_SIZE (1) 122 | 0x95, 0x05, // REPORT_COUNT (5) 123 | 0x91, 0x02, // OUTPUT (Data,Var,Abs) 124 | 0x75, 0x03, // REPORT_SIZE (3) 125 | 0x95, 0x01, // REPORT_COUNT (1) 126 | 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 127 | 0xc0, // END_COLLECTION 128 | 129 | // Consumer multimedia keyboard 130 | 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) 131 | 0x09, 0x01, // USAGE (Consumer Control) 132 | 0xa1, 0x01, // COLLECTION (Application) 133 | 0x85, 0x02, // REPORT_ID (2) 134 | 0x19, 0x00, // USAGE_MINIMUM (Unassigned) 135 | 0x2a, 0x3c, 0x02, // USAGE_MAXIMUM (AC Format) 136 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 137 | 0x26, 0x3c, 0x02, // LOGICAL_MAXIMUM (572) 138 | 0x75, 0x10, // REPORT_SIZE (16) 139 | 0x95, 0x01, // REPORT_COUNT (1) 140 | 0x81, 0x00, // INPUT (Data,Var,Abs) 141 | 0xc0, // END_COLLECTION 142 | 143 | // Mouse with wheel and 3 buttons 144 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 145 | 0x09, 0x02, // USAGE (Mouse) 146 | 0xa1, 0x01, // COLLECTION (Application) 147 | 0x09, 0x01, // USAGE (Pointer) 148 | 0xa1, 0x00, // COLLECTION (Physical) 149 | 0x85, 0x03, // REPORT_ID (3) 150 | 0x05, 0x09, // USAGE_PAGE (Button) 151 | 0x19, 0x01, // USAGE_MINIMUM (Button 1) 152 | 0x29, 0x03, // USAGE_MAXIMUM (Button 3) 153 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 154 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) 155 | 0x75, 0x01, // REPORT_SIZE (1) 156 | 0x95, 0x03, // REPORT_COUNT (3) 157 | 0x81, 0x02, // INPUT (Data,Var,Abs) 158 | 0x75, 0x05, // REPORT_SIZE (5) 159 | 0x95, 0x01, // REPORT_COUNT (1) 160 | 0x81, 0x03, // INPUT (Cnst,Var,Abs) 161 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 162 | 0x09, 0x30, // USAGE (X) 163 | 0x09, 0x31, // USAGE (Y) 164 | 0x09, 0x38, // USAGE (Wheel) 165 | 0x15, 0x81, // LOGICAL_MINIMUM (-127) 166 | 0x25, 0x7f, // LOGICAL_MAXIMUM (127) 167 | 0x75, 0x08, // REPORT_SIZE (8) 168 | 0x95, 0x03, // REPORT_COUNT (3) 169 | 0x81, 0x06, // INPUT (Data,Var,Rel) 170 | 0xc0, // END_COLLECTION 171 | 0xc0, // END_COLLECTION 172 | 173 | // Joystick with 8 buttons 174 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 175 | 0x09, 0x05, // USAGE (Game Pad) 176 | 0xa1, 0x01, // COLLECTION (Application) 177 | 0xa1, 0x00, // COLLECTION (Physical) 178 | 0x85, 0x04, // REPORT_ID (4) 179 | 0x05, 0x09, // USAGE_PAGE (Button) 180 | 0x19, 0x01, // USAGE_MINIMUM (Button 1) 181 | 0x29, 0x08, // USAGE_MAXIMUM (Button 8) 182 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 183 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) 184 | 0x75, 0x01, // REPORT_SIZE (1) 185 | 0x95, 0x08, // REPORT_COUNT (8) 186 | 0x81, 0x02, // INPUT (Data,Var,Abs) 187 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 188 | 0x09, 0x30, // USAGE (X) 189 | 0x09, 0x31, // USAGE (Y) 190 | 0x15, 0x81, // LOGICAL_MINIMUM (-127) 191 | 0x25, 0x7f, // LOGICAL_MAXIMUM (127) 192 | 0x75, 0x08, // REPORT_SIZE (8) 193 | 0x95, 0x02, // REPORT_COUNT (2) 194 | 0x81, 0x02, // INPUT (Data,Var,Abs) 195 | 0xc0, // END_COLLECTION 196 | 0xc0 // END_COLLECTION 197 | }; 198 | 199 | __code uint8_t ReportDescrLen = sizeof(ReportDescr); 200 | 201 | // =================================================================================== 202 | // String Descriptors 203 | // =================================================================================== 204 | 205 | // Language Descriptor (Index 0) 206 | __code uint16_t LangDescr[] = { 207 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(LangDescr), 0x0409 }; // US English 208 | 209 | // Manufacturer String Descriptor (Index 1) 210 | __code uint16_t ManufDescr[] = { 211 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(ManufDescr), MANUFACTURER_STR }; 212 | 213 | // Product String Descriptor (Index 2) 214 | __code uint16_t ProdDescr[] = { 215 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(ProdDescr), PRODUCT_STR }; 216 | 217 | // Serial String Descriptor (Index 3) 218 | __code uint16_t SerDescr[] = { 219 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(SerDescr), SERIAL_STR }; 220 | 221 | // Interface String Descriptor (Index 4) 222 | __code uint16_t InterfDescr[] = { 223 | ((uint16_t)USB_DESCR_TYP_STRING << 8) | sizeof(InterfDescr), INTERFACE_STR }; 224 | -------------------------------------------------------------------------------- /software/custom_knob/src/usb.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB constant and structure define 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | 8 | // USB PID 9 | #ifndef USB_PID_SETUP 10 | #define USB_PID_NULL 0x00 // reserved PID 11 | #define USB_PID_SOF 0x05 12 | #define USB_PID_SETUP 0x0D 13 | #define USB_PID_IN 0x09 14 | #define USB_PID_OUT 0x01 15 | #define USB_PID_ACK 0x02 16 | #define USB_PID_NAK 0x0A 17 | #define USB_PID_STALL 0x0E 18 | #define USB_PID_DATA0 0x03 19 | #define USB_PID_DATA1 0x0B 20 | #define USB_PID_PRE 0x0C 21 | #endif 22 | 23 | // USB standard device request code 24 | #ifndef USB_GET_DESCRIPTOR 25 | #define USB_GET_STATUS 0x00 26 | #define USB_CLEAR_FEATURE 0x01 27 | #define USB_SET_FEATURE 0x03 28 | #define USB_SET_ADDRESS 0x05 29 | #define USB_GET_DESCRIPTOR 0x06 30 | #define USB_SET_DESCRIPTOR 0x07 31 | #define USB_GET_CONFIGURATION 0x08 32 | #define USB_SET_CONFIGURATION 0x09 33 | #define USB_GET_INTERFACE 0x0A 34 | #define USB_SET_INTERFACE 0x0B 35 | #define USB_SYNCH_FRAME 0x0C 36 | #endif 37 | 38 | // USB hub class request code 39 | #ifndef HUB_GET_DESCRIPTOR 40 | #define HUB_GET_STATUS 0x00 41 | #define HUB_CLEAR_FEATURE 0x01 42 | #define HUB_GET_STATE 0x02 43 | #define HUB_SET_FEATURE 0x03 44 | #define HUB_GET_DESCRIPTOR 0x06 45 | #define HUB_SET_DESCRIPTOR 0x07 46 | #endif 47 | 48 | // USB HID class request code 49 | #ifndef HID_GET_REPORT 50 | #define HID_GET_REPORT 0x01 51 | #define HID_GET_IDLE 0x02 52 | #define HID_GET_PROTOCOL 0x03 53 | #define HID_SET_REPORT 0x09 54 | #define HID_SET_IDLE 0x0A 55 | #define HID_SET_PROTOCOL 0x0B 56 | #endif 57 | 58 | // Bit define for USB request type 59 | #ifndef USB_REQ_TYP_MASK 60 | #define USB_REQ_TYP_IN 0x80 // control IN, device to host 61 | #define USB_REQ_TYP_OUT 0x00 // control OUT, host to device 62 | #define USB_REQ_TYP_READ 0x80 // control read, device to host 63 | #define USB_REQ_TYP_WRITE 0x00 // control write, host to device 64 | #define USB_REQ_TYP_MASK 0x60 // bit mask of request type 65 | #define USB_REQ_TYP_STANDARD 0x00 66 | #define USB_REQ_TYP_CLASS 0x20 67 | #define USB_REQ_TYP_VENDOR 0x40 68 | #define USB_REQ_TYP_RESERVED 0x60 69 | #define USB_REQ_RECIP_MASK 0x1F // bit mask of request recipient 70 | #define USB_REQ_RECIP_DEVICE 0x00 71 | #define USB_REQ_RECIP_INTERF 0x01 72 | #define USB_REQ_RECIP_ENDP 0x02 73 | #define USB_REQ_RECIP_OTHER 0x03 74 | #endif 75 | 76 | // USB request type for hub class request 77 | #ifndef HUB_GET_HUB_DESCRIPTOR 78 | #define HUB_CLEAR_HUB_FEATURE 0x20 79 | #define HUB_CLEAR_PORT_FEATURE 0x23 80 | #define HUB_GET_BUS_STATE 0xA3 81 | #define HUB_GET_HUB_DESCRIPTOR 0xA0 82 | #define HUB_GET_HUB_STATUS 0xA0 83 | #define HUB_GET_PORT_STATUS 0xA3 84 | #define HUB_SET_HUB_DESCRIPTOR 0x20 85 | #define HUB_SET_HUB_FEATURE 0x20 86 | #define HUB_SET_PORT_FEATURE 0x23 87 | #endif 88 | 89 | // Hub class feature selectors 90 | #ifndef HUB_PORT_RESET 91 | #define HUB_C_HUB_LOCAL_POWER 0 92 | #define HUB_C_HUB_OVER_CURRENT 1 93 | #define HUB_PORT_CONNECTION 0 94 | #define HUB_PORT_ENABLE 1 95 | #define HUB_PORT_SUSPEND 2 96 | #define HUB_PORT_OVER_CURRENT 3 97 | #define HUB_PORT_RESET 4 98 | #define HUB_PORT_POWER 8 99 | #define HUB_PORT_LOW_SPEED 9 100 | #define HUB_C_PORT_CONNECTION 16 101 | #define HUB_C_PORT_ENABLE 17 102 | #define HUB_C_PORT_SUSPEND 18 103 | #define HUB_C_PORT_OVER_CURRENT 19 104 | #define HUB_C_PORT_RESET 20 105 | #endif 106 | 107 | // USB descriptor type 108 | #ifndef USB_DESCR_TYP_DEVICE 109 | #define USB_DESCR_TYP_DEVICE 0x01 110 | #define USB_DESCR_TYP_CONFIG 0x02 111 | #define USB_DESCR_TYP_STRING 0x03 112 | #define USB_DESCR_TYP_INTERF 0x04 113 | #define USB_DESCR_TYP_ENDP 0x05 114 | #define USB_DESCR_TYP_QUALIF 0x06 115 | #define USB_DESCR_TYP_SPEED 0x07 116 | #define USB_DESCR_TYP_OTG 0x09 117 | #define USB_DESCR_TYP_IAD 0x0B 118 | #define USB_DESCR_TYP_HID 0x21 119 | #define USB_DESCR_TYP_REPORT 0x22 120 | #define USB_DESCR_TYP_PHYSIC 0x23 121 | #define USB_DESCR_TYP_CS_INTF 0x24 122 | #define USB_DESCR_TYP_CS_ENDP 0x25 123 | #define USB_DESCR_TYP_HUB 0x29 124 | #endif 125 | 126 | // USB device class 127 | #ifndef USB_DEV_CLASS_HUB 128 | #define USB_DEV_CLASS_RESERVED 0x00 129 | #define USB_DEV_CLASS_AUDIO 0x01 130 | #define USB_DEV_CLASS_COMM 0x02 131 | #define USB_DEV_CLASS_HID 0x03 132 | #define USB_DEV_CLASS_MONITOR 0x04 133 | #define USB_DEV_CLASS_PHYSIC_IF 0x05 134 | #define USB_DEV_CLASS_POWER 0x06 135 | #define USB_DEV_CLASS_PRINTER 0x07 136 | #define USB_DEV_CLASS_STORAGE 0x08 137 | #define USB_DEV_CLASS_HUB 0x09 138 | #define USB_DEV_CLASS_DATA 0x0A 139 | #define USB_DEV_CLASS_MISC 0xEF 140 | #define USB_DEV_CLASS_VENDOR 0xFF 141 | #endif 142 | 143 | // USB endpoint type and attributes 144 | #ifndef USB_ENDP_TYPE_MASK 145 | #define USB_ENDP_DIR_MASK 0x80 146 | #define USB_ENDP_ADDR_MASK 0x0F 147 | #define USB_ENDP_TYPE_MASK 0x03 148 | #define USB_ENDP_TYPE_CTRL 0x00 149 | #define USB_ENDP_TYPE_ISOCH 0x01 150 | #define USB_ENDP_TYPE_BULK 0x02 151 | #define USB_ENDP_TYPE_INTER 0x03 152 | #define USB_ENDP_ADDR_EP1_OUT 0x01 153 | #define USB_ENDP_ADDR_EP1_IN 0x81 154 | #define USB_ENDP_ADDR_EP2_OUT 0x02 155 | #define USB_ENDP_ADDR_EP2_IN 0x82 156 | #define USB_ENDP_ADDR_EP3_OUT 0x03 157 | #define USB_ENDP_ADDR_EP3_IN 0x83 158 | #define USB_ENDP_ADDR_EP4_OUT 0x04 159 | #define USB_ENDP_ADDR_EP4_IN 0x84 160 | #endif 161 | 162 | #ifndef USB_DEVICE_ADDR 163 | #define USB_DEVICE_ADDR 0x02 // default USB device address 164 | #endif 165 | #ifndef DEFAULT_ENDP0_SIZE 166 | #define DEFAULT_ENDP0_SIZE 8 // default maximum packet size for endpoint 0 167 | #endif 168 | #ifndef DEFAULT_ENDP1_SIZE 169 | #define DEFAULT_ENDP1_SIZE 8 // default maximum packet size for endpoint 1 170 | #endif 171 | #ifndef MAX_PACKET_SIZE 172 | #define MAX_PACKET_SIZE 64 // maximum packet size 173 | #endif 174 | #ifndef USB_BO_CBW_SIZE 175 | #define USB_BO_CBW_SIZE 0x1F // total length of command block CBW 176 | #define USB_BO_CSW_SIZE 0x0D // total length of command status block CSW 177 | #endif 178 | #ifndef USB_BO_CBW_SIG0 179 | #define USB_BO_CBW_SIG0 0x55 // command block CBW identification flag 'USBC' 180 | #define USB_BO_CBW_SIG1 0x53 181 | #define USB_BO_CBW_SIG2 0x42 182 | #define USB_BO_CBW_SIG3 0x43 183 | #define USB_BO_CSW_SIG0 0x55 // command status block CSW identification flag 'USBS' 184 | #define USB_BO_CSW_SIG1 0x53 185 | #define USB_BO_CSW_SIG2 0x42 186 | #define USB_BO_CSW_SIG3 0x53 187 | #endif 188 | 189 | // USB descriptor type defines 190 | typedef struct _USB_SETUP_REQ { 191 | uint8_t bRequestType; 192 | uint8_t bRequest; 193 | uint8_t wValueL; 194 | uint8_t wValueH; 195 | uint8_t wIndexL; 196 | uint8_t wIndexH; 197 | uint8_t wLengthL; 198 | uint8_t wLengthH; 199 | } USB_SETUP_REQ, *PUSB_SETUP_REQ; 200 | typedef USB_SETUP_REQ __xdata *PXUSB_SETUP_REQ; 201 | 202 | typedef struct _USB_DEVICE_DESCR { 203 | uint8_t bLength; 204 | uint8_t bDescriptorType; 205 | uint16_t bcdUSB; 206 | uint8_t bDeviceClass; 207 | uint8_t bDeviceSubClass; 208 | uint8_t bDeviceProtocol; 209 | uint8_t bMaxPacketSize0; 210 | uint16_t idVendor; 211 | uint16_t idProduct; 212 | uint16_t bcdDevice; 213 | uint8_t iManufacturer; 214 | uint8_t iProduct; 215 | uint8_t iSerialNumber; 216 | uint8_t bNumConfigurations; 217 | } USB_DEV_DESCR, *PUSB_DEV_DESCR; 218 | typedef USB_DEV_DESCR __xdata *PXUSB_DEV_DESCR; 219 | 220 | typedef struct _USB_CONFIG_DESCR { 221 | uint8_t bLength; 222 | uint8_t bDescriptorType; 223 | uint16_t wTotalLength; 224 | uint8_t bNumInterfaces; 225 | uint8_t bConfigurationValue; 226 | uint8_t iConfiguration; 227 | uint8_t bmAttributes; 228 | uint8_t MaxPower; 229 | } USB_CFG_DESCR, *PUSB_CFG_DESCR; 230 | typedef USB_CFG_DESCR __xdata *PXUSB_CFG_DESCR; 231 | 232 | typedef struct _USB_INTERF_DESCR { 233 | uint8_t bLength; 234 | uint8_t bDescriptorType; 235 | uint8_t bInterfaceNumber; 236 | uint8_t bAlternateSetting; 237 | uint8_t bNumEndpoints; 238 | uint8_t bInterfaceClass; 239 | uint8_t bInterfaceSubClass; 240 | uint8_t bInterfaceProtocol; 241 | uint8_t iInterface; 242 | } USB_ITF_DESCR, *PUSB_ITF_DESCR; 243 | typedef USB_ITF_DESCR __xdata *PXUSB_ITF_DESCR; 244 | 245 | typedef struct _USB_ITF_ASS_DESCR { 246 | uint8_t bLength; 247 | uint8_t bDescriptorType; 248 | uint8_t bFirstInterface; 249 | uint8_t bInterfaceCount; 250 | uint8_t bFunctionClass; 251 | uint8_t bFunctionSubClass; 252 | uint8_t bFunctionProtocol; 253 | uint8_t iFunction; 254 | } USB_IAD_DESCR, *PUSB_IAD_DESCR; 255 | typedef USB_IAD_DESCR __xdata *PXUSB_IAD_DESCR; 256 | 257 | typedef struct _USB_ENDPOINT_DESCR { 258 | uint8_t bLength; 259 | uint8_t bDescriptorType; 260 | uint8_t bEndpointAddress; 261 | uint8_t bmAttributes; 262 | uint16_t wMaxPacketSize; 263 | uint8_t bInterval; 264 | } USB_ENDP_DESCR, *PUSB_ENDP_DESCR; 265 | typedef USB_ENDP_DESCR __xdata *PXUSB_ENDP_DESCR; 266 | 267 | typedef struct _USB_CONFIG_DESCR_LONG { 268 | USB_CFG_DESCR cfg_descr; 269 | USB_ITF_DESCR itf_descr; 270 | USB_ENDP_DESCR endp_descr[1]; 271 | } USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG; 272 | typedef USB_CFG_DESCR_LONG __xdata *PXUSB_CFG_DESCR_LONG; 273 | 274 | typedef struct _USB_HUB_DESCR { 275 | uint8_t bDescLength; 276 | uint8_t bDescriptorType; 277 | uint8_t bNbrPorts; 278 | uint16_t wHubCharacteristics; 279 | uint8_t bPwrOn2PwrGood; 280 | uint8_t bHubContrCurrent; 281 | uint8_t DeviceRemovable; 282 | uint8_t PortPwrCtrlMask; 283 | } USB_HUB_DESCR, *PUSB_HUB_DESCR; 284 | typedef USB_HUB_DESCR __xdata *PXUSB_HUB_DESCR; 285 | 286 | typedef struct _USB_HID_DESCR { 287 | uint8_t bLength; 288 | uint8_t bDescriptorType; 289 | uint16_t bcdHID; 290 | uint8_t bCountryCode; 291 | uint8_t bNumDescriptors; 292 | uint8_t bDescriptorTypeX; 293 | uint16_t wDescriptorLength; 294 | } USB_HID_DESCR, *PUSB_HID_DESCR; 295 | typedef USB_HID_DESCR __xdata *PXUSB_HID_DESCR; 296 | 297 | typedef struct _UDISK_BOC_CBW { // command of BulkOnly USB-FlashDisk 298 | uint8_t mCBW_Sig0; 299 | uint8_t mCBW_Sig1; 300 | uint8_t mCBW_Sig2; 301 | uint8_t mCBW_Sig3; 302 | uint8_t mCBW_Tag0; 303 | uint8_t mCBW_Tag1; 304 | uint8_t mCBW_Tag2; 305 | uint8_t mCBW_Tag3; 306 | uint8_t mCBW_DataLen0; 307 | uint8_t mCBW_DataLen1; 308 | uint8_t mCBW_DataLen2; 309 | uint8_t mCBW_DataLen3; // uppest byte of data length, always is 0 310 | uint8_t mCBW_Flag; // transfer direction and etc. 311 | uint8_t mCBW_LUN; 312 | uint8_t mCBW_CB_Len; // length of command block 313 | uint8_t mCBW_CB_Buf[16]; // command block buffer 314 | } UDISK_BOC_CBW, *PUDISK_BOC_CBW; 315 | typedef UDISK_BOC_CBW __xdata *PXUDISK_BOC_CBW; 316 | 317 | typedef struct _UDISK_BOC_CSW { // status of BulkOnly USB-FlashDisk 318 | uint8_t mCSW_Sig0; 319 | uint8_t mCSW_Sig1; 320 | uint8_t mCSW_Sig2; 321 | uint8_t mCSW_Sig3; 322 | uint8_t mCSW_Tag0; 323 | uint8_t mCSW_Tag1; 324 | uint8_t mCSW_Tag2; 325 | uint8_t mCSW_Tag3; 326 | uint8_t mCSW_Residue0; // return: remainder bytes 327 | uint8_t mCSW_Residue1; 328 | uint8_t mCSW_Residue2; 329 | uint8_t mCSW_Residue3; // uppest byte of remainder length, always is 0 330 | uint8_t mCSW_Status; // return: result status 331 | } UDISK_BOC_CSW, *PUDISK_BOC_CSW; 332 | typedef UDISK_BOC_CSW __xdata *PXUDISK_BOC_CSW; 333 | -------------------------------------------------------------------------------- /software/volume_knob/src/usb.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB constant and structure define 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | 8 | // USB PID 9 | #ifndef USB_PID_SETUP 10 | #define USB_PID_NULL 0x00 // reserved PID 11 | #define USB_PID_SOF 0x05 12 | #define USB_PID_SETUP 0x0D 13 | #define USB_PID_IN 0x09 14 | #define USB_PID_OUT 0x01 15 | #define USB_PID_ACK 0x02 16 | #define USB_PID_NAK 0x0A 17 | #define USB_PID_STALL 0x0E 18 | #define USB_PID_DATA0 0x03 19 | #define USB_PID_DATA1 0x0B 20 | #define USB_PID_PRE 0x0C 21 | #endif 22 | 23 | // USB standard device request code 24 | #ifndef USB_GET_DESCRIPTOR 25 | #define USB_GET_STATUS 0x00 26 | #define USB_CLEAR_FEATURE 0x01 27 | #define USB_SET_FEATURE 0x03 28 | #define USB_SET_ADDRESS 0x05 29 | #define USB_GET_DESCRIPTOR 0x06 30 | #define USB_SET_DESCRIPTOR 0x07 31 | #define USB_GET_CONFIGURATION 0x08 32 | #define USB_SET_CONFIGURATION 0x09 33 | #define USB_GET_INTERFACE 0x0A 34 | #define USB_SET_INTERFACE 0x0B 35 | #define USB_SYNCH_FRAME 0x0C 36 | #endif 37 | 38 | // USB hub class request code 39 | #ifndef HUB_GET_DESCRIPTOR 40 | #define HUB_GET_STATUS 0x00 41 | #define HUB_CLEAR_FEATURE 0x01 42 | #define HUB_GET_STATE 0x02 43 | #define HUB_SET_FEATURE 0x03 44 | #define HUB_GET_DESCRIPTOR 0x06 45 | #define HUB_SET_DESCRIPTOR 0x07 46 | #endif 47 | 48 | // USB HID class request code 49 | #ifndef HID_GET_REPORT 50 | #define HID_GET_REPORT 0x01 51 | #define HID_GET_IDLE 0x02 52 | #define HID_GET_PROTOCOL 0x03 53 | #define HID_SET_REPORT 0x09 54 | #define HID_SET_IDLE 0x0A 55 | #define HID_SET_PROTOCOL 0x0B 56 | #endif 57 | 58 | // Bit define for USB request type 59 | #ifndef USB_REQ_TYP_MASK 60 | #define USB_REQ_TYP_IN 0x80 // control IN, device to host 61 | #define USB_REQ_TYP_OUT 0x00 // control OUT, host to device 62 | #define USB_REQ_TYP_READ 0x80 // control read, device to host 63 | #define USB_REQ_TYP_WRITE 0x00 // control write, host to device 64 | #define USB_REQ_TYP_MASK 0x60 // bit mask of request type 65 | #define USB_REQ_TYP_STANDARD 0x00 66 | #define USB_REQ_TYP_CLASS 0x20 67 | #define USB_REQ_TYP_VENDOR 0x40 68 | #define USB_REQ_TYP_RESERVED 0x60 69 | #define USB_REQ_RECIP_MASK 0x1F // bit mask of request recipient 70 | #define USB_REQ_RECIP_DEVICE 0x00 71 | #define USB_REQ_RECIP_INTERF 0x01 72 | #define USB_REQ_RECIP_ENDP 0x02 73 | #define USB_REQ_RECIP_OTHER 0x03 74 | #endif 75 | 76 | // USB request type for hub class request 77 | #ifndef HUB_GET_HUB_DESCRIPTOR 78 | #define HUB_CLEAR_HUB_FEATURE 0x20 79 | #define HUB_CLEAR_PORT_FEATURE 0x23 80 | #define HUB_GET_BUS_STATE 0xA3 81 | #define HUB_GET_HUB_DESCRIPTOR 0xA0 82 | #define HUB_GET_HUB_STATUS 0xA0 83 | #define HUB_GET_PORT_STATUS 0xA3 84 | #define HUB_SET_HUB_DESCRIPTOR 0x20 85 | #define HUB_SET_HUB_FEATURE 0x20 86 | #define HUB_SET_PORT_FEATURE 0x23 87 | #endif 88 | 89 | // Hub class feature selectors 90 | #ifndef HUB_PORT_RESET 91 | #define HUB_C_HUB_LOCAL_POWER 0 92 | #define HUB_C_HUB_OVER_CURRENT 1 93 | #define HUB_PORT_CONNECTION 0 94 | #define HUB_PORT_ENABLE 1 95 | #define HUB_PORT_SUSPEND 2 96 | #define HUB_PORT_OVER_CURRENT 3 97 | #define HUB_PORT_RESET 4 98 | #define HUB_PORT_POWER 8 99 | #define HUB_PORT_LOW_SPEED 9 100 | #define HUB_C_PORT_CONNECTION 16 101 | #define HUB_C_PORT_ENABLE 17 102 | #define HUB_C_PORT_SUSPEND 18 103 | #define HUB_C_PORT_OVER_CURRENT 19 104 | #define HUB_C_PORT_RESET 20 105 | #endif 106 | 107 | // USB descriptor type 108 | #ifndef USB_DESCR_TYP_DEVICE 109 | #define USB_DESCR_TYP_DEVICE 0x01 110 | #define USB_DESCR_TYP_CONFIG 0x02 111 | #define USB_DESCR_TYP_STRING 0x03 112 | #define USB_DESCR_TYP_INTERF 0x04 113 | #define USB_DESCR_TYP_ENDP 0x05 114 | #define USB_DESCR_TYP_QUALIF 0x06 115 | #define USB_DESCR_TYP_SPEED 0x07 116 | #define USB_DESCR_TYP_OTG 0x09 117 | #define USB_DESCR_TYP_IAD 0x0B 118 | #define USB_DESCR_TYP_HID 0x21 119 | #define USB_DESCR_TYP_REPORT 0x22 120 | #define USB_DESCR_TYP_PHYSIC 0x23 121 | #define USB_DESCR_TYP_CS_INTF 0x24 122 | #define USB_DESCR_TYP_CS_ENDP 0x25 123 | #define USB_DESCR_TYP_HUB 0x29 124 | #endif 125 | 126 | // USB device class 127 | #ifndef USB_DEV_CLASS_HUB 128 | #define USB_DEV_CLASS_RESERVED 0x00 129 | #define USB_DEV_CLASS_AUDIO 0x01 130 | #define USB_DEV_CLASS_COMM 0x02 131 | #define USB_DEV_CLASS_HID 0x03 132 | #define USB_DEV_CLASS_MONITOR 0x04 133 | #define USB_DEV_CLASS_PHYSIC_IF 0x05 134 | #define USB_DEV_CLASS_POWER 0x06 135 | #define USB_DEV_CLASS_PRINTER 0x07 136 | #define USB_DEV_CLASS_STORAGE 0x08 137 | #define USB_DEV_CLASS_HUB 0x09 138 | #define USB_DEV_CLASS_DATA 0x0A 139 | #define USB_DEV_CLASS_MISC 0xEF 140 | #define USB_DEV_CLASS_VENDOR 0xFF 141 | #endif 142 | 143 | // USB endpoint type and attributes 144 | #ifndef USB_ENDP_TYPE_MASK 145 | #define USB_ENDP_DIR_MASK 0x80 146 | #define USB_ENDP_ADDR_MASK 0x0F 147 | #define USB_ENDP_TYPE_MASK 0x03 148 | #define USB_ENDP_TYPE_CTRL 0x00 149 | #define USB_ENDP_TYPE_ISOCH 0x01 150 | #define USB_ENDP_TYPE_BULK 0x02 151 | #define USB_ENDP_TYPE_INTER 0x03 152 | #define USB_ENDP_ADDR_EP1_OUT 0x01 153 | #define USB_ENDP_ADDR_EP1_IN 0x81 154 | #define USB_ENDP_ADDR_EP2_OUT 0x02 155 | #define USB_ENDP_ADDR_EP2_IN 0x82 156 | #define USB_ENDP_ADDR_EP3_OUT 0x03 157 | #define USB_ENDP_ADDR_EP3_IN 0x83 158 | #define USB_ENDP_ADDR_EP4_OUT 0x04 159 | #define USB_ENDP_ADDR_EP4_IN 0x84 160 | #endif 161 | 162 | #ifndef USB_DEVICE_ADDR 163 | #define USB_DEVICE_ADDR 0x02 // default USB device address 164 | #endif 165 | #ifndef DEFAULT_ENDP0_SIZE 166 | #define DEFAULT_ENDP0_SIZE 8 // default maximum packet size for endpoint 0 167 | #endif 168 | #ifndef DEFAULT_ENDP1_SIZE 169 | #define DEFAULT_ENDP1_SIZE 8 // default maximum packet size for endpoint 1 170 | #endif 171 | #ifndef MAX_PACKET_SIZE 172 | #define MAX_PACKET_SIZE 64 // maximum packet size 173 | #endif 174 | #ifndef USB_BO_CBW_SIZE 175 | #define USB_BO_CBW_SIZE 0x1F // total length of command block CBW 176 | #define USB_BO_CSW_SIZE 0x0D // total length of command status block CSW 177 | #endif 178 | #ifndef USB_BO_CBW_SIG0 179 | #define USB_BO_CBW_SIG0 0x55 // command block CBW identification flag 'USBC' 180 | #define USB_BO_CBW_SIG1 0x53 181 | #define USB_BO_CBW_SIG2 0x42 182 | #define USB_BO_CBW_SIG3 0x43 183 | #define USB_BO_CSW_SIG0 0x55 // command status block CSW identification flag 'USBS' 184 | #define USB_BO_CSW_SIG1 0x53 185 | #define USB_BO_CSW_SIG2 0x42 186 | #define USB_BO_CSW_SIG3 0x53 187 | #endif 188 | 189 | // USB descriptor type defines 190 | typedef struct _USB_SETUP_REQ { 191 | uint8_t bRequestType; 192 | uint8_t bRequest; 193 | uint8_t wValueL; 194 | uint8_t wValueH; 195 | uint8_t wIndexL; 196 | uint8_t wIndexH; 197 | uint8_t wLengthL; 198 | uint8_t wLengthH; 199 | } USB_SETUP_REQ, *PUSB_SETUP_REQ; 200 | typedef USB_SETUP_REQ __xdata *PXUSB_SETUP_REQ; 201 | 202 | typedef struct _USB_DEVICE_DESCR { 203 | uint8_t bLength; 204 | uint8_t bDescriptorType; 205 | uint16_t bcdUSB; 206 | uint8_t bDeviceClass; 207 | uint8_t bDeviceSubClass; 208 | uint8_t bDeviceProtocol; 209 | uint8_t bMaxPacketSize0; 210 | uint16_t idVendor; 211 | uint16_t idProduct; 212 | uint16_t bcdDevice; 213 | uint8_t iManufacturer; 214 | uint8_t iProduct; 215 | uint8_t iSerialNumber; 216 | uint8_t bNumConfigurations; 217 | } USB_DEV_DESCR, *PUSB_DEV_DESCR; 218 | typedef USB_DEV_DESCR __xdata *PXUSB_DEV_DESCR; 219 | 220 | typedef struct _USB_CONFIG_DESCR { 221 | uint8_t bLength; 222 | uint8_t bDescriptorType; 223 | uint16_t wTotalLength; 224 | uint8_t bNumInterfaces; 225 | uint8_t bConfigurationValue; 226 | uint8_t iConfiguration; 227 | uint8_t bmAttributes; 228 | uint8_t MaxPower; 229 | } USB_CFG_DESCR, *PUSB_CFG_DESCR; 230 | typedef USB_CFG_DESCR __xdata *PXUSB_CFG_DESCR; 231 | 232 | typedef struct _USB_INTERF_DESCR { 233 | uint8_t bLength; 234 | uint8_t bDescriptorType; 235 | uint8_t bInterfaceNumber; 236 | uint8_t bAlternateSetting; 237 | uint8_t bNumEndpoints; 238 | uint8_t bInterfaceClass; 239 | uint8_t bInterfaceSubClass; 240 | uint8_t bInterfaceProtocol; 241 | uint8_t iInterface; 242 | } USB_ITF_DESCR, *PUSB_ITF_DESCR; 243 | typedef USB_ITF_DESCR __xdata *PXUSB_ITF_DESCR; 244 | 245 | typedef struct _USB_ITF_ASS_DESCR { 246 | uint8_t bLength; 247 | uint8_t bDescriptorType; 248 | uint8_t bFirstInterface; 249 | uint8_t bInterfaceCount; 250 | uint8_t bFunctionClass; 251 | uint8_t bFunctionSubClass; 252 | uint8_t bFunctionProtocol; 253 | uint8_t iFunction; 254 | } USB_IAD_DESCR, *PUSB_IAD_DESCR; 255 | typedef USB_IAD_DESCR __xdata *PXUSB_IAD_DESCR; 256 | 257 | typedef struct _USB_ENDPOINT_DESCR { 258 | uint8_t bLength; 259 | uint8_t bDescriptorType; 260 | uint8_t bEndpointAddress; 261 | uint8_t bmAttributes; 262 | uint16_t wMaxPacketSize; 263 | uint8_t bInterval; 264 | } USB_ENDP_DESCR, *PUSB_ENDP_DESCR; 265 | typedef USB_ENDP_DESCR __xdata *PXUSB_ENDP_DESCR; 266 | 267 | typedef struct _USB_CONFIG_DESCR_LONG { 268 | USB_CFG_DESCR cfg_descr; 269 | USB_ITF_DESCR itf_descr; 270 | USB_ENDP_DESCR endp_descr[1]; 271 | } USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG; 272 | typedef USB_CFG_DESCR_LONG __xdata *PXUSB_CFG_DESCR_LONG; 273 | 274 | typedef struct _USB_HUB_DESCR { 275 | uint8_t bDescLength; 276 | uint8_t bDescriptorType; 277 | uint8_t bNbrPorts; 278 | uint16_t wHubCharacteristics; 279 | uint8_t bPwrOn2PwrGood; 280 | uint8_t bHubContrCurrent; 281 | uint8_t DeviceRemovable; 282 | uint8_t PortPwrCtrlMask; 283 | } USB_HUB_DESCR, *PUSB_HUB_DESCR; 284 | typedef USB_HUB_DESCR __xdata *PXUSB_HUB_DESCR; 285 | 286 | typedef struct _USB_HID_DESCR { 287 | uint8_t bLength; 288 | uint8_t bDescriptorType; 289 | uint16_t bcdHID; 290 | uint8_t bCountryCode; 291 | uint8_t bNumDescriptors; 292 | uint8_t bDescriptorTypeX; 293 | uint16_t wDescriptorLength; 294 | } USB_HID_DESCR, *PUSB_HID_DESCR; 295 | typedef USB_HID_DESCR __xdata *PXUSB_HID_DESCR; 296 | 297 | typedef struct _UDISK_BOC_CBW { // command of BulkOnly USB-FlashDisk 298 | uint8_t mCBW_Sig0; 299 | uint8_t mCBW_Sig1; 300 | uint8_t mCBW_Sig2; 301 | uint8_t mCBW_Sig3; 302 | uint8_t mCBW_Tag0; 303 | uint8_t mCBW_Tag1; 304 | uint8_t mCBW_Tag2; 305 | uint8_t mCBW_Tag3; 306 | uint8_t mCBW_DataLen0; 307 | uint8_t mCBW_DataLen1; 308 | uint8_t mCBW_DataLen2; 309 | uint8_t mCBW_DataLen3; // uppest byte of data length, always is 0 310 | uint8_t mCBW_Flag; // transfer direction and etc. 311 | uint8_t mCBW_LUN; 312 | uint8_t mCBW_CB_Len; // length of command block 313 | uint8_t mCBW_CB_Buf[16]; // command block buffer 314 | } UDISK_BOC_CBW, *PUDISK_BOC_CBW; 315 | typedef UDISK_BOC_CBW __xdata *PXUDISK_BOC_CBW; 316 | 317 | typedef struct _UDISK_BOC_CSW { // status of BulkOnly USB-FlashDisk 318 | uint8_t mCSW_Sig0; 319 | uint8_t mCSW_Sig1; 320 | uint8_t mCSW_Sig2; 321 | uint8_t mCSW_Sig3; 322 | uint8_t mCSW_Tag0; 323 | uint8_t mCSW_Tag1; 324 | uint8_t mCSW_Tag2; 325 | uint8_t mCSW_Tag3; 326 | uint8_t mCSW_Residue0; // return: remainder bytes 327 | uint8_t mCSW_Residue1; 328 | uint8_t mCSW_Residue2; 329 | uint8_t mCSW_Residue3; // uppest byte of remainder length, always is 0 330 | uint8_t mCSW_Status; // return: result status 331 | } UDISK_BOC_CSW, *PUDISK_BOC_CSW; 332 | typedef UDISK_BOC_CSW __xdata *PXUDISK_BOC_CSW; 333 | -------------------------------------------------------------------------------- /software/mousewheel_knob/src/usb.h: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // USB constant and structure define 3 | // =================================================================================== 4 | 5 | #pragma once 6 | #include 7 | 8 | // USB PID 9 | #ifndef USB_PID_SETUP 10 | #define USB_PID_NULL 0x00 // reserved PID 11 | #define USB_PID_SOF 0x05 12 | #define USB_PID_SETUP 0x0D 13 | #define USB_PID_IN 0x09 14 | #define USB_PID_OUT 0x01 15 | #define USB_PID_ACK 0x02 16 | #define USB_PID_NAK 0x0A 17 | #define USB_PID_STALL 0x0E 18 | #define USB_PID_DATA0 0x03 19 | #define USB_PID_DATA1 0x0B 20 | #define USB_PID_PRE 0x0C 21 | #endif 22 | 23 | // USB standard device request code 24 | #ifndef USB_GET_DESCRIPTOR 25 | #define USB_GET_STATUS 0x00 26 | #define USB_CLEAR_FEATURE 0x01 27 | #define USB_SET_FEATURE 0x03 28 | #define USB_SET_ADDRESS 0x05 29 | #define USB_GET_DESCRIPTOR 0x06 30 | #define USB_SET_DESCRIPTOR 0x07 31 | #define USB_GET_CONFIGURATION 0x08 32 | #define USB_SET_CONFIGURATION 0x09 33 | #define USB_GET_INTERFACE 0x0A 34 | #define USB_SET_INTERFACE 0x0B 35 | #define USB_SYNCH_FRAME 0x0C 36 | #endif 37 | 38 | // USB hub class request code 39 | #ifndef HUB_GET_DESCRIPTOR 40 | #define HUB_GET_STATUS 0x00 41 | #define HUB_CLEAR_FEATURE 0x01 42 | #define HUB_GET_STATE 0x02 43 | #define HUB_SET_FEATURE 0x03 44 | #define HUB_GET_DESCRIPTOR 0x06 45 | #define HUB_SET_DESCRIPTOR 0x07 46 | #endif 47 | 48 | // USB HID class request code 49 | #ifndef HID_GET_REPORT 50 | #define HID_GET_REPORT 0x01 51 | #define HID_GET_IDLE 0x02 52 | #define HID_GET_PROTOCOL 0x03 53 | #define HID_SET_REPORT 0x09 54 | #define HID_SET_IDLE 0x0A 55 | #define HID_SET_PROTOCOL 0x0B 56 | #endif 57 | 58 | // Bit define for USB request type 59 | #ifndef USB_REQ_TYP_MASK 60 | #define USB_REQ_TYP_IN 0x80 // control IN, device to host 61 | #define USB_REQ_TYP_OUT 0x00 // control OUT, host to device 62 | #define USB_REQ_TYP_READ 0x80 // control read, device to host 63 | #define USB_REQ_TYP_WRITE 0x00 // control write, host to device 64 | #define USB_REQ_TYP_MASK 0x60 // bit mask of request type 65 | #define USB_REQ_TYP_STANDARD 0x00 66 | #define USB_REQ_TYP_CLASS 0x20 67 | #define USB_REQ_TYP_VENDOR 0x40 68 | #define USB_REQ_TYP_RESERVED 0x60 69 | #define USB_REQ_RECIP_MASK 0x1F // bit mask of request recipient 70 | #define USB_REQ_RECIP_DEVICE 0x00 71 | #define USB_REQ_RECIP_INTERF 0x01 72 | #define USB_REQ_RECIP_ENDP 0x02 73 | #define USB_REQ_RECIP_OTHER 0x03 74 | #endif 75 | 76 | // USB request type for hub class request 77 | #ifndef HUB_GET_HUB_DESCRIPTOR 78 | #define HUB_CLEAR_HUB_FEATURE 0x20 79 | #define HUB_CLEAR_PORT_FEATURE 0x23 80 | #define HUB_GET_BUS_STATE 0xA3 81 | #define HUB_GET_HUB_DESCRIPTOR 0xA0 82 | #define HUB_GET_HUB_STATUS 0xA0 83 | #define HUB_GET_PORT_STATUS 0xA3 84 | #define HUB_SET_HUB_DESCRIPTOR 0x20 85 | #define HUB_SET_HUB_FEATURE 0x20 86 | #define HUB_SET_PORT_FEATURE 0x23 87 | #endif 88 | 89 | // Hub class feature selectors 90 | #ifndef HUB_PORT_RESET 91 | #define HUB_C_HUB_LOCAL_POWER 0 92 | #define HUB_C_HUB_OVER_CURRENT 1 93 | #define HUB_PORT_CONNECTION 0 94 | #define HUB_PORT_ENABLE 1 95 | #define HUB_PORT_SUSPEND 2 96 | #define HUB_PORT_OVER_CURRENT 3 97 | #define HUB_PORT_RESET 4 98 | #define HUB_PORT_POWER 8 99 | #define HUB_PORT_LOW_SPEED 9 100 | #define HUB_C_PORT_CONNECTION 16 101 | #define HUB_C_PORT_ENABLE 17 102 | #define HUB_C_PORT_SUSPEND 18 103 | #define HUB_C_PORT_OVER_CURRENT 19 104 | #define HUB_C_PORT_RESET 20 105 | #endif 106 | 107 | // USB descriptor type 108 | #ifndef USB_DESCR_TYP_DEVICE 109 | #define USB_DESCR_TYP_DEVICE 0x01 110 | #define USB_DESCR_TYP_CONFIG 0x02 111 | #define USB_DESCR_TYP_STRING 0x03 112 | #define USB_DESCR_TYP_INTERF 0x04 113 | #define USB_DESCR_TYP_ENDP 0x05 114 | #define USB_DESCR_TYP_QUALIF 0x06 115 | #define USB_DESCR_TYP_SPEED 0x07 116 | #define USB_DESCR_TYP_OTG 0x09 117 | #define USB_DESCR_TYP_IAD 0x0B 118 | #define USB_DESCR_TYP_HID 0x21 119 | #define USB_DESCR_TYP_REPORT 0x22 120 | #define USB_DESCR_TYP_PHYSIC 0x23 121 | #define USB_DESCR_TYP_CS_INTF 0x24 122 | #define USB_DESCR_TYP_CS_ENDP 0x25 123 | #define USB_DESCR_TYP_HUB 0x29 124 | #endif 125 | 126 | // USB device class 127 | #ifndef USB_DEV_CLASS_HUB 128 | #define USB_DEV_CLASS_RESERVED 0x00 129 | #define USB_DEV_CLASS_AUDIO 0x01 130 | #define USB_DEV_CLASS_COMM 0x02 131 | #define USB_DEV_CLASS_HID 0x03 132 | #define USB_DEV_CLASS_MONITOR 0x04 133 | #define USB_DEV_CLASS_PHYSIC_IF 0x05 134 | #define USB_DEV_CLASS_POWER 0x06 135 | #define USB_DEV_CLASS_PRINTER 0x07 136 | #define USB_DEV_CLASS_STORAGE 0x08 137 | #define USB_DEV_CLASS_HUB 0x09 138 | #define USB_DEV_CLASS_DATA 0x0A 139 | #define USB_DEV_CLASS_MISC 0xEF 140 | #define USB_DEV_CLASS_VENDOR 0xFF 141 | #endif 142 | 143 | // USB endpoint type and attributes 144 | #ifndef USB_ENDP_TYPE_MASK 145 | #define USB_ENDP_DIR_MASK 0x80 146 | #define USB_ENDP_ADDR_MASK 0x0F 147 | #define USB_ENDP_TYPE_MASK 0x03 148 | #define USB_ENDP_TYPE_CTRL 0x00 149 | #define USB_ENDP_TYPE_ISOCH 0x01 150 | #define USB_ENDP_TYPE_BULK 0x02 151 | #define USB_ENDP_TYPE_INTER 0x03 152 | #define USB_ENDP_ADDR_EP1_OUT 0x01 153 | #define USB_ENDP_ADDR_EP1_IN 0x81 154 | #define USB_ENDP_ADDR_EP2_OUT 0x02 155 | #define USB_ENDP_ADDR_EP2_IN 0x82 156 | #define USB_ENDP_ADDR_EP3_OUT 0x03 157 | #define USB_ENDP_ADDR_EP3_IN 0x83 158 | #define USB_ENDP_ADDR_EP4_OUT 0x04 159 | #define USB_ENDP_ADDR_EP4_IN 0x84 160 | #endif 161 | 162 | #ifndef USB_DEVICE_ADDR 163 | #define USB_DEVICE_ADDR 0x02 // default USB device address 164 | #endif 165 | #ifndef DEFAULT_ENDP0_SIZE 166 | #define DEFAULT_ENDP0_SIZE 8 // default maximum packet size for endpoint 0 167 | #endif 168 | #ifndef DEFAULT_ENDP1_SIZE 169 | #define DEFAULT_ENDP1_SIZE 8 // default maximum packet size for endpoint 1 170 | #endif 171 | #ifndef MAX_PACKET_SIZE 172 | #define MAX_PACKET_SIZE 64 // maximum packet size 173 | #endif 174 | #ifndef USB_BO_CBW_SIZE 175 | #define USB_BO_CBW_SIZE 0x1F // total length of command block CBW 176 | #define USB_BO_CSW_SIZE 0x0D // total length of command status block CSW 177 | #endif 178 | #ifndef USB_BO_CBW_SIG0 179 | #define USB_BO_CBW_SIG0 0x55 // command block CBW identification flag 'USBC' 180 | #define USB_BO_CBW_SIG1 0x53 181 | #define USB_BO_CBW_SIG2 0x42 182 | #define USB_BO_CBW_SIG3 0x43 183 | #define USB_BO_CSW_SIG0 0x55 // command status block CSW identification flag 'USBS' 184 | #define USB_BO_CSW_SIG1 0x53 185 | #define USB_BO_CSW_SIG2 0x42 186 | #define USB_BO_CSW_SIG3 0x53 187 | #endif 188 | 189 | // USB descriptor type defines 190 | typedef struct _USB_SETUP_REQ { 191 | uint8_t bRequestType; 192 | uint8_t bRequest; 193 | uint8_t wValueL; 194 | uint8_t wValueH; 195 | uint8_t wIndexL; 196 | uint8_t wIndexH; 197 | uint8_t wLengthL; 198 | uint8_t wLengthH; 199 | } USB_SETUP_REQ, *PUSB_SETUP_REQ; 200 | typedef USB_SETUP_REQ __xdata *PXUSB_SETUP_REQ; 201 | 202 | typedef struct _USB_DEVICE_DESCR { 203 | uint8_t bLength; 204 | uint8_t bDescriptorType; 205 | uint16_t bcdUSB; 206 | uint8_t bDeviceClass; 207 | uint8_t bDeviceSubClass; 208 | uint8_t bDeviceProtocol; 209 | uint8_t bMaxPacketSize0; 210 | uint16_t idVendor; 211 | uint16_t idProduct; 212 | uint16_t bcdDevice; 213 | uint8_t iManufacturer; 214 | uint8_t iProduct; 215 | uint8_t iSerialNumber; 216 | uint8_t bNumConfigurations; 217 | } USB_DEV_DESCR, *PUSB_DEV_DESCR; 218 | typedef USB_DEV_DESCR __xdata *PXUSB_DEV_DESCR; 219 | 220 | typedef struct _USB_CONFIG_DESCR { 221 | uint8_t bLength; 222 | uint8_t bDescriptorType; 223 | uint16_t wTotalLength; 224 | uint8_t bNumInterfaces; 225 | uint8_t bConfigurationValue; 226 | uint8_t iConfiguration; 227 | uint8_t bmAttributes; 228 | uint8_t MaxPower; 229 | } USB_CFG_DESCR, *PUSB_CFG_DESCR; 230 | typedef USB_CFG_DESCR __xdata *PXUSB_CFG_DESCR; 231 | 232 | typedef struct _USB_INTERF_DESCR { 233 | uint8_t bLength; 234 | uint8_t bDescriptorType; 235 | uint8_t bInterfaceNumber; 236 | uint8_t bAlternateSetting; 237 | uint8_t bNumEndpoints; 238 | uint8_t bInterfaceClass; 239 | uint8_t bInterfaceSubClass; 240 | uint8_t bInterfaceProtocol; 241 | uint8_t iInterface; 242 | } USB_ITF_DESCR, *PUSB_ITF_DESCR; 243 | typedef USB_ITF_DESCR __xdata *PXUSB_ITF_DESCR; 244 | 245 | typedef struct _USB_ITF_ASS_DESCR { 246 | uint8_t bLength; 247 | uint8_t bDescriptorType; 248 | uint8_t bFirstInterface; 249 | uint8_t bInterfaceCount; 250 | uint8_t bFunctionClass; 251 | uint8_t bFunctionSubClass; 252 | uint8_t bFunctionProtocol; 253 | uint8_t iFunction; 254 | } USB_IAD_DESCR, *PUSB_IAD_DESCR; 255 | typedef USB_IAD_DESCR __xdata *PXUSB_IAD_DESCR; 256 | 257 | typedef struct _USB_ENDPOINT_DESCR { 258 | uint8_t bLength; 259 | uint8_t bDescriptorType; 260 | uint8_t bEndpointAddress; 261 | uint8_t bmAttributes; 262 | uint16_t wMaxPacketSize; 263 | uint8_t bInterval; 264 | } USB_ENDP_DESCR, *PUSB_ENDP_DESCR; 265 | typedef USB_ENDP_DESCR __xdata *PXUSB_ENDP_DESCR; 266 | 267 | typedef struct _USB_CONFIG_DESCR_LONG { 268 | USB_CFG_DESCR cfg_descr; 269 | USB_ITF_DESCR itf_descr; 270 | USB_ENDP_DESCR endp_descr[1]; 271 | } USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG; 272 | typedef USB_CFG_DESCR_LONG __xdata *PXUSB_CFG_DESCR_LONG; 273 | 274 | typedef struct _USB_HUB_DESCR { 275 | uint8_t bDescLength; 276 | uint8_t bDescriptorType; 277 | uint8_t bNbrPorts; 278 | uint16_t wHubCharacteristics; 279 | uint8_t bPwrOn2PwrGood; 280 | uint8_t bHubContrCurrent; 281 | uint8_t DeviceRemovable; 282 | uint8_t PortPwrCtrlMask; 283 | } USB_HUB_DESCR, *PUSB_HUB_DESCR; 284 | typedef USB_HUB_DESCR __xdata *PXUSB_HUB_DESCR; 285 | 286 | typedef struct _USB_HID_DESCR { 287 | uint8_t bLength; 288 | uint8_t bDescriptorType; 289 | uint16_t bcdHID; 290 | uint8_t bCountryCode; 291 | uint8_t bNumDescriptors; 292 | uint8_t bDescriptorTypeX; 293 | uint16_t wDescriptorLength; 294 | } USB_HID_DESCR, *PUSB_HID_DESCR; 295 | typedef USB_HID_DESCR __xdata *PXUSB_HID_DESCR; 296 | 297 | typedef struct _UDISK_BOC_CBW { // command of BulkOnly USB-FlashDisk 298 | uint8_t mCBW_Sig0; 299 | uint8_t mCBW_Sig1; 300 | uint8_t mCBW_Sig2; 301 | uint8_t mCBW_Sig3; 302 | uint8_t mCBW_Tag0; 303 | uint8_t mCBW_Tag1; 304 | uint8_t mCBW_Tag2; 305 | uint8_t mCBW_Tag3; 306 | uint8_t mCBW_DataLen0; 307 | uint8_t mCBW_DataLen1; 308 | uint8_t mCBW_DataLen2; 309 | uint8_t mCBW_DataLen3; // uppest byte of data length, always is 0 310 | uint8_t mCBW_Flag; // transfer direction and etc. 311 | uint8_t mCBW_LUN; 312 | uint8_t mCBW_CB_Len; // length of command block 313 | uint8_t mCBW_CB_Buf[16]; // command block buffer 314 | } UDISK_BOC_CBW, *PUDISK_BOC_CBW; 315 | typedef UDISK_BOC_CBW __xdata *PXUDISK_BOC_CBW; 316 | 317 | typedef struct _UDISK_BOC_CSW { // status of BulkOnly USB-FlashDisk 318 | uint8_t mCSW_Sig0; 319 | uint8_t mCSW_Sig1; 320 | uint8_t mCSW_Sig2; 321 | uint8_t mCSW_Sig3; 322 | uint8_t mCSW_Tag0; 323 | uint8_t mCSW_Tag1; 324 | uint8_t mCSW_Tag2; 325 | uint8_t mCSW_Tag3; 326 | uint8_t mCSW_Residue0; // return: remainder bytes 327 | uint8_t mCSW_Residue1; 328 | uint8_t mCSW_Residue2; 329 | uint8_t mCSW_Residue3; // uppest byte of remainder length, always is 0 330 | uint8_t mCSW_Status; // return: result status 331 | } UDISK_BOC_CSW, *PUDISK_BOC_CSW; 332 | typedef UDISK_BOC_CSW __xdata *PXUDISK_BOC_CSW; 333 | --------------------------------------------------------------------------------