├── .gitignore ├── Firmware └── CH592F │ ├── .cproject │ ├── .mrs │ └── CH592F.mrs-workspace │ ├── .project │ ├── .template │ ├── CH592F.launch │ ├── CH592F.wvproj │ ├── Ld │ └── Link.ld │ ├── RVMSIS │ ├── core_riscv.c │ └── core_riscv.h │ ├── Startup │ └── startup_CH592.S │ ├── StdPeriphDriver │ ├── CH59x_adc.c │ ├── CH59x_clk.c │ ├── CH59x_flash.c │ ├── CH59x_gpio.c │ ├── CH59x_i2c.c │ ├── CH59x_lcd.c │ ├── CH59x_pwm.c │ ├── CH59x_pwr.c │ ├── CH59x_spi0.c │ ├── CH59x_sys.c │ ├── CH59x_timer0.c │ ├── CH59x_timer1.c │ ├── CH59x_timer2.c │ ├── CH59x_timer3.c │ ├── CH59x_uart0.c │ ├── CH59x_uart1.c │ ├── CH59x_uart2.c │ ├── CH59x_uart3.c │ ├── CH59x_usbdev.c │ ├── CH59x_usbhostBase.c │ ├── CH59x_usbhostClass.c │ └── inc │ │ ├── CH592SFR.h │ │ ├── CH59x_adc.h │ │ ├── CH59x_clk.h │ │ ├── CH59x_common.h │ │ ├── CH59x_flash.h │ │ ├── CH59x_gpio.h │ │ ├── CH59x_i2c.h │ │ ├── CH59x_lcd.h │ │ ├── CH59x_pwm.h │ │ ├── CH59x_pwr.h │ │ ├── CH59x_spi.h │ │ ├── CH59x_sys.h │ │ ├── CH59x_timer.h │ │ ├── CH59x_uart.h │ │ ├── CH59x_usbdev.h │ │ ├── CH59x_usbhost.h │ │ └── ISP592.h │ └── User │ └── Main.c ├── LICENSE ├── README.md └── UI └── binary-keyboard-studio-ui ├── .gitignore ├── README.md ├── components.d.ts ├── env.d.ts ├── index.html ├── package.json ├── pnpm-lock.yaml ├── public └── favicon.ico ├── src ├── App.vue ├── assets │ └── main.css ├── components │ ├── AppFooter.vue │ ├── DataInfoCard.vue │ ├── DeviceFinder.vue │ ├── DeviceInfoCard.vue │ └── keyboards │ │ ├── BasicKeyboard.vue │ │ ├── FiveKeysKeyboard.vue │ │ └── KnobKeyboard.vue ├── main.ts ├── stores │ ├── counter.ts │ └── deviceStore.ts ├── types │ ├── index.ts │ └── webhid.d.ts ├── utils │ ├── WebHidTools.ts │ ├── deviceConstants.ts │ ├── hidConverters │ │ ├── keyMappingConverter.ts │ │ ├── keyboardHIDConverter.ts │ │ ├── mediaHIDConverter.ts │ │ └── mouseHIDConverter.ts │ └── keyboardHidTools.ts └── widgets │ ├── buttons │ ├── KnobButton.vue │ └── NormalButton.vue │ └── selector │ ├── KeyboardSelector.vue │ ├── MediaSelector.vue │ ├── MouseSelector.vue │ └── Selector.vue ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | .vscode/ 54 | 55 | # Logs 56 | logs 57 | *.log 58 | npm-debug.log* 59 | yarn-debug.log* 60 | yarn-error.log* 61 | pnpm-debug.log* 62 | lerna-debug.log* 63 | 64 | node_modules 65 | .DS_Store 66 | dist 67 | dist-ssr 68 | coverage 69 | *.local 70 | 71 | /cypress/videos/ 72 | /cypress/screenshots/ 73 | 74 | # Editor directories and files 75 | .vscode/* 76 | !.vscode/extensions.json 77 | .idea 78 | *.suo 79 | *.ntvs* 80 | *.njsproj 81 | *.sln 82 | *.sw? 83 | 84 | *.tsbuildinfo 85 | 86 | #wch mounstudio 87 | obj/ 88 | -------------------------------------------------------------------------------- /Firmware/CH592F/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /Firmware/CH592F/.mrs/CH592F.mrs-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | }, 6 | { 7 | "name": "CH592F", 8 | "path": "../" 9 | } 10 | ], 11 | "settings": { 12 | "mrs.workspace.type": "project", 13 | "files.associations": { 14 | "*.c": "c", 15 | "*.h": "cpp", 16 | "*.hxx": "cpp", 17 | "*.hpp": "cpp", 18 | "*.c++": "cpp", 19 | "*.cpp": "cpp", 20 | "*.cxx": "cpp", 21 | "*.cc": "cpp", 22 | "*.hh": "cpp", 23 | "*.h++": "cpp" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Firmware/CH592F/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | CH592F 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 24 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 25 | 26 | 27 | 28 | 1595986042669 29 | 30 | 22 31 | 32 | org.eclipse.ui.ide.multiFilter 33 | 1.0-name-matches-false-false-*.wvproj 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Firmware/CH592F/.template: -------------------------------------------------------------------------------- 1 | Mcu Type=CH59x 2 | Address=0x00000000 3 | Target Path=obj/CH592F.hex 4 | Erase All=true 5 | Program=true 6 | Verify=true 7 | Reset=true 8 | 9 | Vendor=WCH 10 | Link=WCH-Link 11 | Toolchain=RISC-V 12 | Series=CH59X 13 | RTOS=NoneOS 14 | MCU=CH592F 15 | Description=Website: https://www.wch.cn/products/CH592.html?\nROM(byte): 448K, SRAM(byte): 26K, CHIP PINS: 28, GPIO PORTS: 20\nCH592 integrates BLE 32-bit RISC-V microcontroller MCU, 448K ROM, 24K SRAM, low average power consumption, power-off mode is only 0.3uA. Integrate USB host and device, segment LCD driver, ADC, 4-way serial port, SPI, I2C, touch key detection module, RTC, power management, etc, provide Bluetooth protocol stack and APP support. 16 | 17 | PeripheralVersion=1.5 18 | -------------------------------------------------------------------------------- /Firmware/CH592F/CH592F.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Firmware/CH592F/CH592F.wvproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/CH592F.wvproj -------------------------------------------------------------------------------- /Firmware/CH592F/Ld/Link.ld: -------------------------------------------------------------------------------- 1 | ENTRY( _start ) 2 | 3 | __stack_size = 512; 4 | 5 | PROVIDE( _stack_size = __stack_size ); 6 | 7 | MEMORY 8 | { 9 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 448K 10 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 26K 11 | } 12 | 13 | SECTIONS 14 | { 15 | .init : 16 | { 17 | _sinit = .; 18 | . = ALIGN(4); 19 | KEEP(*(SORT_NONE(.init))) 20 | . = ALIGN(4); 21 | _einit = .; 22 | } >FLASH AT>FLASH 23 | 24 | /* .vector : 25 | { 26 | *(.vector); 27 | } >FLASH AT>FLASH */ 28 | 29 | .highcodelalign : 30 | { 31 | . = ALIGN(4); 32 | PROVIDE(_highcode_lma = .); 33 | } >FLASH AT>FLASH 34 | 35 | .highcode : 36 | { 37 | . = ALIGN(4); 38 | PROVIDE(_highcode_vma_start = .); 39 | *(.vector); 40 | KEEP(*(SORT_NONE(.vector_handler))) 41 | *(.highcode); 42 | *(.highcode.*); 43 | . = ALIGN(4); 44 | PROVIDE(_highcode_vma_end = .); 45 | } >RAM AT>FLASH 46 | 47 | .text : 48 | { 49 | . = ALIGN(4); 50 | KEEP(*(SORT_NONE(.handle_reset))) 51 | *(.text) 52 | *(.text.*) 53 | *(.rodata) 54 | *(.rodata*) 55 | *(.sdata2.*) 56 | *(.glue_7) 57 | *(.glue_7t) 58 | *(.gnu.linkonce.t.*) 59 | . = ALIGN(4); 60 | } >FLASH AT>FLASH 61 | 62 | .fini : 63 | { 64 | KEEP(*(SORT_NONE(.fini))) 65 | . = ALIGN(4); 66 | } >FLASH AT>FLASH 67 | 68 | PROVIDE( _etext = . ); 69 | PROVIDE( _eitcm = . ); 70 | 71 | .preinit_array : 72 | { 73 | PROVIDE_HIDDEN (__preinit_array_start = .); 74 | KEEP (*(.preinit_array)) 75 | PROVIDE_HIDDEN (__preinit_array_end = .); 76 | } >FLASH AT>FLASH 77 | 78 | .init_array : 79 | { 80 | PROVIDE_HIDDEN (__init_array_start = .); 81 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 82 | KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) 83 | PROVIDE_HIDDEN (__init_array_end = .); 84 | } >FLASH AT>FLASH 85 | 86 | .fini_array : 87 | { 88 | PROVIDE_HIDDEN (__fini_array_start = .); 89 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 90 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 91 | PROVIDE_HIDDEN (__fini_array_end = .); 92 | } >FLASH AT>FLASH 93 | 94 | .ctors : 95 | { 96 | /* gcc uses crtbegin.o to find the start of 97 | the constructors, so we make sure it is 98 | first. Because this is a wildcard, it 99 | doesn't matter if the user does not 100 | actually link against crtbegin.o; the 101 | linker won't look for a file to match a 102 | wildcard. The wildcard also means that it 103 | doesn't matter which directory crtbegin.o 104 | is in. */ 105 | KEEP (*crtbegin.o(.ctors)) 106 | KEEP (*crtbegin?.o(.ctors)) 107 | /* We don't want to include the .ctor section from 108 | the crtend.o file until after the sorted ctors. 109 | The .ctor section from the crtend file contains the 110 | end of ctors marker and it must be last */ 111 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 112 | KEEP (*(SORT(.ctors.*))) 113 | KEEP (*(.ctors)) 114 | } >FLASH AT>FLASH 115 | 116 | .dtors : 117 | { 118 | KEEP (*crtbegin.o(.dtors)) 119 | KEEP (*crtbegin?.o(.dtors)) 120 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 121 | KEEP (*(SORT(.dtors.*))) 122 | KEEP (*(.dtors)) 123 | } >FLASH AT>FLASH 124 | 125 | .dalign : 126 | { 127 | . = ORIGIN(RAM) + SIZEOF(.highcode); 128 | } >RAM AT>FLASH 129 | 130 | .dlalign : 131 | { 132 | . = ALIGN(4); 133 | PROVIDE(_data_lma = .); 134 | } >FLASH AT>FLASH 135 | 136 | .data : 137 | { 138 | . = ALIGN(4); 139 | PROVIDE(_data_vma = .); 140 | *(.gnu.linkonce.r.*) 141 | *(.data .data.*) 142 | *(.gnu.linkonce.d.*) 143 | . = ALIGN(8); 144 | PROVIDE( __global_pointer$ = . + 0x800 ); 145 | *(.sdata .sdata.*) 146 | *(.gnu.linkonce.s.*) 147 | . = ALIGN(8); 148 | *(.srodata.cst16) 149 | *(.srodata.cst8) 150 | *(.srodata.cst4) 151 | *(.srodata.cst2) 152 | *(.srodata .srodata.*) 153 | . = ALIGN(4); 154 | PROVIDE( _edata = .); 155 | } >RAM AT>FLASH 156 | 157 | .bss : 158 | { 159 | . = ALIGN(4); 160 | PROVIDE( _sbss = .); 161 | *(.sbss*) 162 | *(.gnu.linkonce.sb.*) 163 | *(.bss*) 164 | *(.gnu.linkonce.b.*) 165 | *(COMMON*) 166 | . = ALIGN(4); 167 | PROVIDE( _ebss = .); 168 | } >RAM AT>FLASH 169 | 170 | PROVIDE( _end = _ebss); 171 | PROVIDE( end = . ); 172 | 173 | .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : 174 | { 175 | PROVIDE( _heap_end = . ); 176 | . = ALIGN(4); 177 | PROVIDE(_susrstack = . ); 178 | . = . + __stack_size; 179 | PROVIDE( _eusrstack = .); 180 | } >RAM 181 | } 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /Firmware/CH592F/RVMSIS/core_riscv.c: -------------------------------------------------------------------------------- 1 | /********************************** (C) COPYRIGHT ******************************* 2 | * File Name : core_riscv.c 3 | * Author : WCH 4 | * Version : V1.1.0 5 | * Date : 2021/06/06 6 | * Description : RISC-V Core Peripheral Access Layer Source File 7 | ********************************************************************************* 8 | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. 9 | * Attention: This software (modified or not) and binary are used for 10 | * microcontroller manufactured by Nanjing Qinheng Microelectronics. 11 | *******************************************************************************/ 12 | #include 13 | 14 | /* define compiler specific symbols */ 15 | #if defined ( __CC_ARM ) 16 | #define __ASM __asm /*!< asm keyword for ARM Compiler */ 17 | #define __INLINE __inline /*!< inline keyword for ARM Compiler */ 18 | 19 | #elif defined ( __ICCARM__ ) 20 | #define __ASM __asm /*!< asm keyword for IAR Compiler */ 21 | #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ 22 | 23 | #elif defined ( __GNUC__ ) 24 | #define __ASM __asm /*!< asm keyword for GNU Compiler */ 25 | #define __INLINE inline /*!< inline keyword for GNU Compiler */ 26 | 27 | #elif defined ( __TASKING__ ) 28 | #define __ASM __asm /*!< asm keyword for TASKING Compiler */ 29 | #define __INLINE inline /*!< inline keyword for TASKING Compiler */ 30 | 31 | #endif 32 | 33 | 34 | 35 | /********************************************************************* 36 | * @fn __get_MSTATUS 37 | * 38 | * @brief Return the Machine Status Register 39 | * 40 | * @return mstatus value 41 | */ 42 | uint32_t __get_MSTATUS(void) 43 | { 44 | uint32_t result; 45 | 46 | __ASM volatile ( "csrr %0," "mstatus" : "=r" (result) ); 47 | return (result); 48 | } 49 | 50 | /********************************************************************* 51 | * @fn __set_MSTATUS 52 | * 53 | * @brief Set the Machine Status Register 54 | * 55 | * @param value - set mstatus value 56 | * 57 | * @return none 58 | */ 59 | void __set_MSTATUS(uint32_t value) 60 | { 61 | __ASM volatile ("csrw mstatus, %0" : : "r" (value) ); 62 | } 63 | 64 | /********************************************************************* 65 | * @fn __get_MISA 66 | * 67 | * @brief Return the Machine ISA Register 68 | * 69 | * @return misa value 70 | */ 71 | uint32_t __get_MISA(void) 72 | { 73 | uint32_t result; 74 | 75 | __ASM volatile ( "csrr %0," "misa" : "=r" (result) ); 76 | return (result); 77 | } 78 | 79 | /********************************************************************* 80 | * @fn __set_MISA 81 | * 82 | * @brief Set the Machine ISA Register 83 | * 84 | * @param value - set misa value 85 | * 86 | * @return none 87 | */ 88 | void __set_MISA(uint32_t value) 89 | { 90 | __ASM volatile ("csrw misa, %0" : : "r" (value) ); 91 | } 92 | 93 | /********************************************************************* 94 | * @fn __get_MTVEC 95 | * 96 | * @brief Return the Machine Trap-Vector Base-Address Register 97 | * 98 | * @return mtvec value 99 | */ 100 | uint32_t __get_MTVEC(void) 101 | { 102 | uint32_t result; 103 | 104 | __ASM volatile ( "csrr %0," "mtvec" : "=r" (result) ); 105 | return (result); 106 | } 107 | 108 | /********************************************************************* 109 | * @fn __set_MTVEC 110 | * 111 | * @brief Set the Machine Trap-Vector Base-Address Register 112 | * 113 | * @param value - set mtvec value 114 | * 115 | * @return none 116 | */ 117 | void __set_MTVEC(uint32_t value) 118 | { 119 | __ASM volatile ("csrw mtvec, %0" : : "r" (value) ); 120 | } 121 | 122 | /********************************************************************* 123 | * @fn __get_MSCRATCH 124 | * 125 | * @brief Return the Machine Seratch Register 126 | * 127 | * @return mscratch value 128 | */ 129 | uint32_t __get_MSCRATCH(void) 130 | { 131 | uint32_t result; 132 | 133 | __ASM volatile ( "csrr %0," "mscratch" : "=r" (result) ); 134 | return (result); 135 | } 136 | 137 | /********************************************************************* 138 | * @fn __set_MSCRATCH 139 | * 140 | * @brief Set the Machine Seratch Register 141 | * 142 | * @param value - set mscratch value 143 | * 144 | * @return none 145 | */ 146 | void __set_MSCRATCH(uint32_t value) 147 | { 148 | __ASM volatile ("csrw mscratch, %0" : : "r" (value) ); 149 | } 150 | 151 | /********************************************************************* 152 | * @fn __get_MEPC 153 | * 154 | * @brief Return the Machine Exception Program Register 155 | * 156 | * @return mepc value 157 | */ 158 | uint32_t __get_MEPC(void) 159 | { 160 | uint32_t result; 161 | 162 | __ASM volatile ( "csrr %0," "mepc" : "=r" (result) ); 163 | return (result); 164 | } 165 | 166 | /********************************************************************* 167 | * @fn __set_MEPC 168 | * 169 | * @brief Set the Machine Exception Program Register 170 | * 171 | * @return mepc value 172 | */ 173 | void __set_MEPC(uint32_t value) 174 | { 175 | __ASM volatile ("csrw mepc, %0" : : "r" (value) ); 176 | } 177 | 178 | /********************************************************************* 179 | * @fn __get_MCAUSE 180 | * 181 | * @brief Return the Machine Cause Register 182 | * 183 | * @return mcause value 184 | */ 185 | uint32_t __get_MCAUSE(void) 186 | { 187 | uint32_t result; 188 | 189 | __ASM volatile ( "csrr %0," "mcause" : "=r" (result) ); 190 | return (result); 191 | } 192 | 193 | /********************************************************************* 194 | * @fn __set_MEPC 195 | * 196 | * @brief Set the Machine Cause Register 197 | * 198 | * @return mcause value 199 | */ 200 | void __set_MCAUSE(uint32_t value) 201 | { 202 | __ASM volatile ("csrw mcause, %0" : : "r" (value) ); 203 | } 204 | 205 | /********************************************************************* 206 | * @fn __get_MTVAL 207 | * 208 | * @brief Return the Machine Trap Value Register 209 | * 210 | * @return mtval value 211 | */ 212 | uint32_t __get_MTVAL(void) 213 | { 214 | uint32_t result; 215 | 216 | __ASM volatile ( "csrr %0," "mtval" : "=r" (result) ); 217 | return (result); 218 | } 219 | 220 | /********************************************************************* 221 | * @fn __set_MTVAL 222 | * 223 | * @brief Set the Machine Trap Value Register 224 | * 225 | * @return mtval value 226 | */ 227 | void __set_MTVAL(uint32_t value) 228 | { 229 | __ASM volatile ("csrw mtval, %0" : : "r" (value) ); 230 | } 231 | 232 | /********************************************************************* 233 | * @fn __get_MVENDORID 234 | * 235 | * @brief Return Vendor ID Register 236 | * 237 | * @return mvendorid value 238 | */ 239 | uint32_t __get_MVENDORID(void) 240 | { 241 | uint32_t result; 242 | 243 | __ASM volatile ( "csrr %0," "mvendorid" : "=r" (result) ); 244 | return (result); 245 | } 246 | 247 | /********************************************************************* 248 | * @fn __get_MARCHID 249 | * 250 | * @brief Return Machine Architecture ID Register 251 | * 252 | * @return marchid value 253 | */ 254 | uint32_t __get_MARCHID(void) 255 | { 256 | uint32_t result; 257 | 258 | __ASM volatile ( "csrr %0," "marchid" : "=r" (result) ); 259 | return (result); 260 | } 261 | 262 | /********************************************************************* 263 | * @fn __get_MIMPID 264 | * 265 | * @brief Return Machine Implementation ID Register 266 | * 267 | * @return mimpid value 268 | */ 269 | uint32_t __get_MIMPID(void) 270 | { 271 | uint32_t result; 272 | 273 | __ASM volatile ( "csrr %0," "mimpid" : "=r" (result) ); 274 | return (result); 275 | } 276 | 277 | /********************************************************************* 278 | * @fn __get_MHARTID 279 | * 280 | * @brief Return Hart ID Register 281 | * 282 | * @return mhartid value 283 | */ 284 | uint32_t __get_MHARTID(void) 285 | { 286 | uint32_t result; 287 | 288 | __ASM volatile ( "csrr %0," "mhartid" : "=r" (result) ); 289 | return (result); 290 | } 291 | 292 | /********************************************************************* 293 | * @fn __get_SP 294 | * 295 | * @brief Return SP Register 296 | * 297 | * @return SP value 298 | */ 299 | uint32_t __get_SP(void) 300 | { 301 | uint32_t result; 302 | 303 | __ASM volatile ( "mv %0," "sp" : "=r"(result) : ); 304 | return (result); 305 | } 306 | 307 | -------------------------------------------------------------------------------- /Firmware/CH592F/RVMSIS/core_riscv.h: -------------------------------------------------------------------------------- 1 | /********************************** (C) COPYRIGHT ******************************* 2 | * File Name : core_riscv.h 3 | * Author : WCH 4 | * Version : V1.1.0 5 | * Date : 2023/04/10 6 | * Description : CH592 RISC-V Core Peripheral Access Layer Header File 7 | ********************************************************************************* 8 | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. 9 | * Attention: This software (modified or not) and binary are used for 10 | * microcontroller manufactured by Nanjing Qinheng Microelectronics. 11 | *******************************************************************************/ 12 | #ifndef __CORE_RV3A_H__ 13 | #define __CORE_RV3A_H__ 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /* IO definitions */ 20 | #ifdef __cplusplus 21 | #define __I volatile /*!< defines 'read only' permissions */ 22 | #else 23 | #define __I volatile const /*!< defines 'read only' permissions */ 24 | #endif 25 | #define __O volatile /*!< defines 'write only' permissions */ 26 | #define __IO volatile /*!< defines 'read / write' permissions */ 27 | #define RV_STATIC_INLINE static inline 28 | 29 | //typedef enum {SUCCESS = 0, ERROR = !SUCCESS} ErrorStatus; 30 | 31 | typedef enum 32 | { 33 | DISABLE = 0, 34 | ENABLE = !DISABLE 35 | } FunctionalState; 36 | typedef enum 37 | { 38 | RESET = 0, 39 | SET = !RESET 40 | } FlagStatus, ITStatus; 41 | 42 | /* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ 43 | typedef struct 44 | { 45 | __I uint32_t ISR[8]; // 0 46 | __I uint32_t IPR[8]; // 20H 47 | __IO uint32_t ITHRESDR; // 40H 48 | uint8_t RESERVED[4]; // 44H 49 | __O uint32_t CFGR; // 48H 50 | __I uint32_t GISR; // 4CH 51 | __IO uint8_t VTFIDR[4]; // 50H 52 | uint8_t RESERVED0[0x0C]; // 54H 53 | __IO uint32_t VTFADDR[4]; // 60H 54 | uint8_t RESERVED1[0x90]; // 70H 55 | __O uint32_t IENR[8]; // 100H 56 | uint8_t RESERVED2[0x60]; // 120H 57 | __O uint32_t IRER[8]; // 180H 58 | uint8_t RESERVED3[0x60]; // 1A0H 59 | __O uint32_t IPSR[8]; // 200H 60 | uint8_t RESERVED4[0x60]; // 220H 61 | __O uint32_t IPRR[8]; // 280H 62 | uint8_t RESERVED5[0x60]; // 2A0H 63 | __IO uint32_t IACTR[8]; // 300H 64 | uint8_t RESERVED6[0xE0]; // 320H 65 | __IO uint8_t IPRIOR[256]; // 400H 66 | uint8_t RESERVED7[0x810]; // 500H 67 | __IO uint32_t SCTLR; // D10H 68 | } PFIC_Type; 69 | 70 | /* memory mapped structure for SysTick */ 71 | typedef struct 72 | { 73 | __IO uint32_t CTLR; 74 | __IO uint32_t SR; 75 | __IO uint64_t CNT; 76 | __IO uint64_t CMP; 77 | } SysTick_Type; 78 | 79 | #define PFIC ((PFIC_Type *)0xE000E000) 80 | #define SysTick ((SysTick_Type *)0xE000F000) 81 | 82 | #define PFIC_KEY1 ((uint32_t)0xFA050000) 83 | #define PFIC_KEY2 ((uint32_t)0xBCAF0000) 84 | #define PFIC_KEY3 ((uint32_t)0xBEEF0000) 85 | 86 | /* ########################## define #################################### */ 87 | #define __nop() __asm__ volatile("nop") 88 | 89 | #define read_csr(reg) ({unsigned long __tmp; \ 90 | __asm__ volatile ("csrr %0, " #reg : "=r"(__tmp)); \ 91 | __tmp; }) 92 | 93 | #define write_csr(reg, val) ({ \ 94 | if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ 95 | __asm__ volatile ("csrw " #reg ", %0" :: "i"(val)); \ 96 | else \ 97 | __asm__ volatile ("csrw " #reg ", %0" :: "r"(val)); }) 98 | 99 | #define PFIC_EnableAllIRQ() {write_csr(0x800, 0x88);} 100 | #define PFIC_DisableAllIRQ() {write_csr(0x800, 0x80);asm volatile("fence.i");} 101 | /* ########################## PFIC functions #################################### */ 102 | 103 | /********************************************************************* 104 | * @fn __risc_v_enable_irq 105 | * 106 | * @brief recover Global Interrupt 107 | * 108 | * @return mpie and mie bit in mstatus. 109 | */ 110 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __risc_v_enable_irq(uint32_t mpie_mie) 111 | { 112 | uint32_t result; 113 | 114 | __asm volatile ("csrrs %0, 0x800, %1" : \ 115 | "=r"(result): "r"(mpie_mie) : "memory"); 116 | return result; 117 | } 118 | 119 | /********************************************************************* 120 | * @fn __disable_irq 121 | * 122 | * @brief Disable Global Interrupt 123 | * 124 | * @return mpie and mie bit in mstatus. 125 | */ 126 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __risc_v_disable_irq(void) 127 | { 128 | uint32_t result; 129 | 130 | __asm volatile ("csrrc %0, 0x800, %1" : \ 131 | "=r"(result): "r"(0x88) : "memory"); 132 | return result & 0x88; 133 | } 134 | 135 | /******************************************************************************* 136 | * @fn PFIC_EnableIRQ 137 | * 138 | * @brief Enable Interrupt 139 | * 140 | * @param IRQn - Interrupt Numbers 141 | */ 142 | __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_EnableIRQ(IRQn_Type IRQn) 143 | { 144 | PFIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F)); 145 | } 146 | 147 | /******************************************************************************* 148 | * @fn PFIC_DisableIRQ 149 | * 150 | * @brief Disable Interrupt 151 | * 152 | * @param IRQn - Interrupt Numbers 153 | */ 154 | __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_DisableIRQ(IRQn_Type IRQn) 155 | { 156 | PFIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F)); 157 | asm volatile("fence.i"); 158 | } 159 | 160 | /******************************************************************************* 161 | * @fn PFIC_GetStatusIRQ 162 | * 163 | * @brief Get Interrupt Enable State 164 | * 165 | * @param IRQn - Interrupt Numbers 166 | * 167 | * @return 1: Interrupt Enable 168 | * 0: Interrupt Disable 169 | */ 170 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetStatusIRQ(IRQn_Type IRQn) 171 | { 172 | return ((uint32_t)((PFIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0)); 173 | } 174 | 175 | /******************************************************************************* 176 | * @fn PFIC_GetPendingIRQ 177 | * 178 | * @brief Get Interrupt Pending State 179 | * 180 | * @param IRQn - Interrupt Numbers 181 | * 182 | * @return 1: Interrupt Pending Enable 183 | * 0: Interrupt Pending Disable 184 | */ 185 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetPendingIRQ(IRQn_Type IRQn) 186 | { 187 | return ((uint32_t)((PFIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0)); 188 | } 189 | 190 | /******************************************************************************* 191 | * @fn PFIC_SetPendingIRQ 192 | * 193 | * @brief Set Interrupt Pending 194 | * 195 | * @param IRQn - Interrupt Numbers 196 | */ 197 | __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SetPendingIRQ(IRQn_Type IRQn) 198 | { 199 | PFIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F)); 200 | } 201 | 202 | /******************************************************************************* 203 | * @fn PFIC_ClearPendingIRQ 204 | * 205 | * @brief Clear Interrupt Pending 206 | * 207 | * @param IRQn - Interrupt Numbers 208 | */ 209 | __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_ClearPendingIRQ(IRQn_Type IRQn) 210 | { 211 | PFIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn)&0x1F)); 212 | } 213 | 214 | /******************************************************************************* 215 | * @fn PFIC_GetActive 216 | * 217 | * @brief Get Interrupt Active State 218 | * 219 | * @param IRQn - Interrupt Numbers 220 | * 221 | * @return 1: Interrupt Active 222 | * 0: Interrupt No Active. 223 | */ 224 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t PFIC_GetActive(IRQn_Type IRQn) 225 | { 226 | return ((uint32_t)((PFIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn)&0x1F))) ? 1 : 0)); 227 | } 228 | 229 | /******************************************************************************* 230 | * @fn PFIC_SetPriority 231 | * 232 | * @brief Set Interrupt Priority 233 | * 234 | * @param IRQn - Interrupt Numbers 235 | * @param priority - bit7-bit4: priority 236 | */ 237 | __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SetPriority(IRQn_Type IRQn, uint8_t priority) 238 | { 239 | PFIC->IPRIOR[(uint32_t)(IRQn)] = priority; 240 | } 241 | 242 | /********************************************************************* 243 | * @fn SetVTFIRQ 244 | * 245 | * @brief Set VTF Interrupt 246 | * 247 | * @param addr - VTF interrupt service function base address. 248 | * IRQn - Interrupt Numbers 249 | * num - VTF Interrupt Numbers 250 | * NewState - DISABLE or ENABLE 251 | * 252 | * @return none 253 | */ 254 | __attribute__((always_inline)) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ 255 | if(num > 3) return ; 256 | 257 | if (NewState != DISABLE) 258 | { 259 | PFIC->VTFIDR[num] = IRQn; 260 | PFIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); 261 | } 262 | else{ 263 | PFIC->VTFIDR[num] = IRQn; 264 | PFIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); 265 | } 266 | } 267 | 268 | /********************************************************************* 269 | * @fn _SEV 270 | * 271 | * @brief Set Event 272 | * 273 | * @return none 274 | */ 275 | __attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void) 276 | { 277 | 278 | PFIC->SCTLR |= (1<<3)|(1<<5); 279 | 280 | } 281 | 282 | /********************************************************************* 283 | * @fn _WFE 284 | * 285 | * @brief Wait for Events 286 | * 287 | * @return none 288 | */ 289 | __attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void) 290 | { 291 | PFIC->SCTLR |= (1<<3); 292 | asm volatile ("wfi"); 293 | } 294 | 295 | 296 | /********************************************************************* 297 | * @fn __WFE 298 | * 299 | * @brief Wait for Events 300 | * 301 | * @return None 302 | */ 303 | __attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) 304 | { 305 | _SEV(); 306 | _WFE(); 307 | _WFE(); 308 | } 309 | 310 | /********************************************************************* 311 | * @fn __WFI 312 | * 313 | * @brief Wait for Interrupt 314 | */ 315 | __attribute__((always_inline)) RV_STATIC_INLINE void __WFI(void) 316 | { 317 | PFIC->SCTLR &= ~(1 << 3); // wfi 318 | __asm__ volatile("wfi"); 319 | } 320 | 321 | /********************************************************************* 322 | * @fn PFIC_SystemReset 323 | * 324 | * @brief Initiate a system reset request 325 | */ 326 | __attribute__((always_inline)) RV_STATIC_INLINE void PFIC_SystemReset(void) 327 | { 328 | PFIC->CFGR = PFIC_KEY3 | (1 << 7); 329 | } 330 | 331 | /********************************************************************* 332 | * @fn __AMOADD_W 333 | * 334 | * @brief Atomic Add with 32bit value 335 | * Atomically ADD 32bit value with value in memory using amoadd.d. 336 | * addr Address pointer to data, address need to be 4byte aligned 337 | * value value to be ADDed 338 | * 339 | * 340 | * @return return memory value + add value 341 | */ 342 | __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) 343 | { 344 | int32_t result; 345 | 346 | __asm volatile ("amoadd.w %0, %2, %1" : \ 347 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 348 | return *addr; 349 | } 350 | 351 | /********************************************************************* 352 | * @fn __AMOAND_W 353 | * 354 | * @brief Atomic And with 32bit value 355 | * Atomically AND 32bit value with value in memory using amoand.d. 356 | * addr Address pointer to data, address need to be 4byte aligned 357 | * value value to be ANDed 358 | * 359 | * 360 | * @return return memory value & and value 361 | */ 362 | __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) 363 | { 364 | int32_t result; 365 | 366 | __asm volatile ("amoand.w %0, %2, %1" : \ 367 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 368 | return *addr; 369 | } 370 | 371 | /********************************************************************* 372 | * @fn __AMOMAX_W 373 | * 374 | * @brief Atomic signed MAX with 32bit value 375 | * @details Atomically signed max compare 32bit value with value in memory using amomax.d. 376 | * addr Address pointer to data, address need to be 4byte aligned 377 | * value value to be compared 378 | * 379 | * 380 | * @return the bigger value 381 | */ 382 | __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) 383 | { 384 | int32_t result; 385 | 386 | __asm volatile ("amomax.w %0, %2, %1" : \ 387 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 388 | return *addr; 389 | } 390 | 391 | /********************************************************************* 392 | * @fn __AMOMAXU_W 393 | * 394 | * @brief Atomic unsigned MAX with 32bit value 395 | * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. 396 | * addr Address pointer to data, address need to be 4byte aligned 397 | * value value to be compared 398 | * 399 | * @return return the bigger value 400 | */ 401 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) 402 | { 403 | uint32_t result; 404 | 405 | __asm volatile ("amomaxu.w %0, %2, %1" : \ 406 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 407 | return *addr; 408 | } 409 | 410 | /********************************************************************* 411 | * @fn __AMOMIN_W 412 | * 413 | * @brief Atomic signed MIN with 32bit value 414 | * Atomically signed min compare 32bit value with value in memory using amomin.d. 415 | * addr Address pointer to data, address need to be 4byte aligned 416 | * value value to be compared 417 | * 418 | * 419 | * @return the smaller value 420 | */ 421 | __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) 422 | { 423 | int32_t result; 424 | 425 | __asm volatile ("amomin.w %0, %2, %1" : \ 426 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 427 | return *addr; 428 | } 429 | 430 | /********************************************************************* 431 | * @fn __AMOMINU_W 432 | * 433 | * @brief Atomic unsigned MIN with 32bit value 434 | * Atomically unsigned min compare 32bit value with value in memory using amominu.d. 435 | * addr Address pointer to data, address need to be 4byte aligned 436 | * value value to be compared 437 | * 438 | * 439 | * @return the smaller value 440 | */ 441 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) 442 | { 443 | uint32_t result; 444 | 445 | __asm volatile ("amominu.w %0, %2, %1" : \ 446 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 447 | return *addr; 448 | } 449 | 450 | /********************************************************************* 451 | * @fn __AMOOR_W 452 | * 453 | * @brief Atomic OR with 32bit value 454 | * @details Atomically OR 32bit value with value in memory using amoor.d. 455 | * addr Address pointer to data, address need to be 4byte aligned 456 | * value value to be ORed 457 | * 458 | * 459 | * @return return memory value | and value 460 | */ 461 | __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) 462 | { 463 | int32_t result; 464 | 465 | __asm volatile ("amoor.w %0, %2, %1" : \ 466 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 467 | return *addr; 468 | } 469 | 470 | /********************************************************************* 471 | * @fn __AMOSWAP_W 472 | * 473 | * @brief Atomically swap new 32bit value into memory using amoswap.d. 474 | * addr Address pointer to data, address need to be 4byte aligned 475 | * newval New value to be stored into the address 476 | * 477 | * @return return the original value in memory 478 | */ 479 | __attribute__((always_inline)) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) 480 | { 481 | uint32_t result; 482 | 483 | __asm volatile ("amoswap.w %0, %2, %1" : \ 484 | "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); 485 | return result; 486 | } 487 | 488 | /********************************************************************* 489 | * @fn __AMOXOR_W 490 | * 491 | * @brief Atomic XOR with 32bit value 492 | * @details Atomically XOR 32bit value with value in memory using amoxor.d. 493 | * addr Address pointer to data, address need to be 4byte aligned 494 | * value value to be XORed 495 | * 496 | * 497 | * @return return memory value ^ and value 498 | */ 499 | __attribute__((always_inline)) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) 500 | { 501 | int32_t result; 502 | 503 | __asm volatile ("amoxor.w %0, %2, %1" : \ 504 | "=r"(result), "+A"(*addr) : "r"(value) : "memory"); 505 | return *addr; 506 | } 507 | 508 | /** 509 | * @brief Return the Machine Status Register 510 | * 511 | * @return mstatus value 512 | */ 513 | uint32_t __get_MSTATUS(void); 514 | 515 | /** 516 | * @brief Return the Machine ISA Register 517 | * 518 | * @return misa value 519 | */ 520 | uint32_t __get_MISA(void); 521 | 522 | /*** 523 | * @brief Return the Machine Trap-Vector Base-Address Register 524 | * 525 | * @return mtvec value 526 | */ 527 | uint32_t __get_MTVEC(void); 528 | 529 | /** 530 | * @brief Return the Machine Seratch Register 531 | * 532 | * @return mscratch value 533 | */ 534 | uint32_t __get_MSCRATCH(void); 535 | 536 | /** 537 | * @brief Return the Machine Exception Program Register 538 | * 539 | * @return mepc value 540 | */ 541 | uint32_t __get_MEPC(void); 542 | 543 | /** 544 | * @brief Return the Machine Cause Register 545 | * 546 | * @return mcause value 547 | */ 548 | uint32_t __get_MCAUSE(void); 549 | 550 | /** 551 | * @brief Return the Machine Trap Value Register 552 | * 553 | * @return mtval value 554 | */ 555 | uint32_t __get_MTVAL(void); 556 | 557 | /** 558 | * @brief Return Vendor ID Register 559 | * 560 | * @return mvendorid value 561 | */ 562 | uint32_t __get_MVENDORID(void); 563 | 564 | /** 565 | * @brief Return Machine Architecture ID Register 566 | * 567 | * @return marchid value 568 | */ 569 | uint32_t __get_MARCHID(void); 570 | 571 | /** 572 | * @brief Return Machine Implementation ID Register 573 | * 574 | * @return mimpid value 575 | */ 576 | uint32_t __get_MIMPID(void); 577 | 578 | /** 579 | * @brief Return Hart ID Register 580 | * 581 | * @return mhartid value 582 | */ 583 | uint32_t __get_MHARTID(void); 584 | 585 | /** 586 | * @brief Return SP Register 587 | * 588 | * @return SP value 589 | */ 590 | uint32_t __get_SP(void); 591 | 592 | #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFFFFFFFFFFF) 593 | #define SysTick_CTLR_SWIE (1 << 31) 594 | #define SysTick_CTLR_INIT (1 << 5) 595 | #define SysTick_CTLR_MODE (1 << 4) 596 | #define SysTick_CTLR_STRE (1 << 3) 597 | #define SysTick_CTLR_STCLK (1 << 2) 598 | #define SysTick_CTLR_STIE (1 << 1) 599 | #define SysTick_CTLR_STE (1 << 0) 600 | 601 | #define SysTick_SR_CNTIF (1 << 0) 602 | 603 | RV_STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks) 604 | { 605 | if((ticks - 1) > SysTick_LOAD_RELOAD_Msk) 606 | return (1); /* Reload value impossible */ 607 | 608 | SysTick->CMP = ticks - 1; /* set reload register */ 609 | PFIC_EnableIRQ(SysTick_IRQn); 610 | SysTick->CTLR = SysTick_CTLR_INIT | 611 | SysTick_CTLR_STRE | 612 | SysTick_CTLR_STCLK | 613 | SysTick_CTLR_STIE | 614 | SysTick_CTLR_STE; /* Enable SysTick IRQ and SysTick Timer */ 615 | return (0); /* Function successful */ 616 | } 617 | 618 | RV_STATIC_INLINE uint32_t __SysTick_Config(uint64_t ticks) 619 | { 620 | if((ticks - 1) > SysTick_LOAD_RELOAD_Msk) 621 | return (1); /* Reload value impossible */ 622 | 623 | SysTick->CMP = ticks - 1; /* set reload register */ 624 | SysTick->CTLR = SysTick_CTLR_INIT | 625 | SysTick_CTLR_STRE | 626 | SysTick_CTLR_STCLK | 627 | SysTick_CTLR_STIE | 628 | SysTick_CTLR_STE; /* Enable SysTick IRQ and SysTick Timer */ 629 | return (0); /* Function successful */ 630 | } 631 | 632 | #ifdef __cplusplus 633 | } 634 | #endif 635 | 636 | #endif /* __CORE_RV3A_H__ */ 637 | -------------------------------------------------------------------------------- /Firmware/CH592F/Startup/startup_CH592.S: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/Startup/startup_CH592.S -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_adc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_adc.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_clk.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_clk.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_flash.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_flash.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_gpio.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_gpio.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_i2c.c: -------------------------------------------------------------------------------- 1 | /********************************** (C) COPYRIGHT ******************************* 2 | * File Name : CH59x_i2c.c 3 | * Author : WCH 4 | * Version : V1.0 5 | * Date : 2021/03/15 6 | * Description 7 | ********************************************************************************* 8 | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. 9 | * Attention: This software (modified or not) and binary are used for 10 | * microcontroller manufactured by Nanjing Qinheng Microelectronics. 11 | *******************************************************************************/ 12 | 13 | #include "CH59x_common.h" 14 | 15 | /********************************************************************* 16 | * @fn I2C_Init 17 | * 18 | * @brief Initializes the I2Cx peripheral according to the specified 19 | * parameters in the I2C_InitStruct. 20 | * 21 | * @param I2C_Mode - refer to I2C_ModeTypeDef 22 | * @param I2C_ClockSpeed - Specifies the clock frequency(Hz). 23 | * This parameter must be set to a value lower than 400kHz 24 | * @param I2C_DutyCycle - Specifies the I2C fast mode duty cycle.refer to I2C_DutyTypeDef 25 | * @param I2C_Ack - Enables or disables the acknowledgement.refer to I2C_AckTypeDef 26 | * @param I2C_AckAddr - Specifies if 7-bit or 10-bit address is acknowledged.refer to I2C_AckAddrTypeDef 27 | * @param I2C_OwnAddress1 - Specifies the first device own address. 28 | * This parameter can be a 7-bit or 10-bit address. 29 | * 30 | * @return none 31 | */ 32 | void I2C_Init(I2C_ModeTypeDef I2C_Mode, UINT32 I2C_ClockSpeed, I2C_DutyTypeDef I2C_DutyCycle, 33 | I2C_AckTypeDef I2C_Ack, I2C_AckAddrTypeDef I2C_AckAddr, UINT16 I2C_OwnAddress1) 34 | { 35 | uint32_t sysClock; 36 | uint16_t tmpreg; 37 | 38 | I2C_SoftwareResetCmd(ENABLE); 39 | I2C_SoftwareResetCmd(DISABLE); 40 | 41 | sysClock = GetSysClock(); 42 | 43 | R16_I2C_CTRL2 &= ~RB_I2C_FREQ; 44 | R16_I2C_CTRL2 |= (sysClock / 1000000); 45 | 46 | R16_I2C_CTRL1 &= ~RB_I2C_PE; 47 | 48 | if(I2C_ClockSpeed <= 100000) 49 | { 50 | tmpreg = (sysClock / (I2C_ClockSpeed << 1)) & RB_I2C_CCR; 51 | 52 | if(tmpreg < 0x04) 53 | tmpreg = 0x04; 54 | 55 | R16_I2C_RTR = (((sysClock / 1000000) + 1) > 0x3F) ? 0x3F : ((sysClock / 1000000) + 1); 56 | } 57 | else 58 | { 59 | if(I2C_DutyCycle == I2C_DutyCycle_2) 60 | { 61 | tmpreg = (sysClock / (I2C_ClockSpeed * 3)) & RB_I2C_CCR; 62 | } 63 | else 64 | { 65 | tmpreg = (sysClock / (I2C_ClockSpeed * 25)) & RB_I2C_CCR; 66 | tmpreg |= I2C_DutyCycle_16_9; 67 | } 68 | 69 | if(tmpreg == 0) 70 | { 71 | tmpreg |= (uint16_t)0x0001; 72 | } 73 | 74 | tmpreg |= RB_I2C_F_S; 75 | R16_I2C_RTR = (uint16_t)((((sysClock / 1000000) * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); 76 | } 77 | R16_I2C_CKCFGR = tmpreg; 78 | 79 | R16_I2C_CTRL1 |= RB_I2C_PE; 80 | 81 | R16_I2C_CTRL1 &= ~(RB_I2C_SMBUS | RB_I2C_SMBTYPE | RB_I2C_ACK); 82 | R16_I2C_CTRL1 |= I2C_Mode | I2C_Ack; 83 | 84 | R16_I2C_OADDR1 &= ~0xFFFF; 85 | R16_I2C_OADDR1 |= I2C_AckAddr | I2C_OwnAddress1; 86 | } 87 | 88 | /********************************************************************* 89 | * @fn I2C_Cmd 90 | * 91 | * @brief Enables or disables the specified I2C peripheral. 92 | * 93 | * @param NewState - ENABLE or DISABLE. 94 | * 95 | * @return none 96 | */ 97 | void I2C_Cmd(FunctionalState NewState) 98 | { 99 | if(NewState != DISABLE) 100 | R16_I2C_CTRL1 |= RB_I2C_PE; 101 | else 102 | R16_I2C_CTRL1 &= ~RB_I2C_PE; 103 | } 104 | 105 | /********************************************************************* 106 | * @fn I2C_GenerateSTART 107 | * 108 | * @brief Generates I2Cx communication START condition. 109 | * 110 | * @param NewState - ENABLE or DISABLE. 111 | * 112 | * @return none 113 | */ 114 | void I2C_GenerateSTART(FunctionalState NewState) 115 | { 116 | if(NewState != DISABLE) 117 | R16_I2C_CTRL1 |= RB_I2C_START; 118 | else 119 | R16_I2C_CTRL1 &= ~RB_I2C_START; 120 | } 121 | 122 | /********************************************************************* 123 | * @fn I2C_GenerateSTOP 124 | * 125 | * @brief Generates I2Cx communication STOP condition. 126 | * 127 | * @param NewState - ENABLE or DISABLE. 128 | * 129 | * @return none 130 | */ 131 | void I2C_GenerateSTOP(FunctionalState NewState) 132 | { 133 | if(NewState != DISABLE) 134 | R16_I2C_CTRL1 |= RB_I2C_STOP; 135 | else 136 | R16_I2C_CTRL1 &= ~RB_I2C_STOP; 137 | } 138 | 139 | /********************************************************************* 140 | * @fn I2C_AcknowledgeConfig 141 | * 142 | * @brief Enables or disables the specified I2C acknowledge feature. 143 | * 144 | * @param NewState - ENABLE or DISABLE. 145 | * 146 | * @return none 147 | */ 148 | void I2C_AcknowledgeConfig(FunctionalState NewState) 149 | { 150 | if(NewState != DISABLE) 151 | R16_I2C_CTRL1 |= RB_I2C_ACK; 152 | else 153 | R16_I2C_CTRL1 &= ~RB_I2C_ACK; 154 | } 155 | 156 | /********************************************************************* 157 | * @fn I2C_OwnAddress2Config 158 | * 159 | * @brief Configures the specified I2C own address2. 160 | * 161 | * @param Address - specifies the 7bit I2C own address2. 162 | * 163 | * @return none 164 | */ 165 | void I2C_OwnAddress2Config(uint8_t Address) 166 | { 167 | R16_I2C_OADDR2 &= ~RB_I2C_ADD2; 168 | R16_I2C_OADDR2 |= (uint16_t)(Address & RB_I2C_ADD2); 169 | } 170 | 171 | /********************************************************************* 172 | * @fn I2C_DualAddressCmd 173 | * 174 | * @brief Enables or disables the specified I2C dual addressing mode. 175 | * 176 | * @param NewState - ENABLE or DISABLE. 177 | * 178 | * @return none 179 | */ 180 | void I2C_DualAddressCmd(FunctionalState NewState) 181 | { 182 | if(NewState != DISABLE) 183 | R16_I2C_OADDR2 |= RB_I2C_ENDUAL; 184 | else 185 | R16_I2C_OADDR2 &= ~RB_I2C_ENDUAL; 186 | } 187 | 188 | /********************************************************************* 189 | * @fn I2C_GeneralCallCmd 190 | * 191 | * @brief Enables or disables the specified I2C general call feature. 192 | * 193 | * @param NewState - ENABLE or DISABLE. 194 | * 195 | * @return none 196 | */ 197 | void I2C_GeneralCallCmd(FunctionalState NewState) 198 | { 199 | if(NewState != DISABLE) 200 | R16_I2C_CTRL1 |= RB_I2C_ENGC; 201 | else 202 | R16_I2C_CTRL1 &= ~RB_I2C_ENGC; 203 | } 204 | 205 | /********************************************************************* 206 | * @fn I2C_ITConfig 207 | * 208 | * @brief Enables or disables the specified I2C interrupts. 209 | * 210 | * @param I2C_IT - specifies the I2C interrupts sources to be enabled or disabled. 211 | * I2C_IT_BUF - Buffer interrupt mask. 212 | * I2C_IT_EVT - Event interrupt mask. 213 | * I2C_IT_ERR - Error interrupt mask. 214 | * @param NewState - ENABLE or DISABLE. 215 | * 216 | * @return none 217 | */ 218 | void I2C_ITConfig(I2C_ITTypeDef I2C_IT, FunctionalState NewState) 219 | { 220 | if(NewState != DISABLE) 221 | R16_I2C_CTRL2 |= I2C_IT; 222 | else 223 | R16_I2C_CTRL2 &= (uint16_t)~I2C_IT; 224 | } 225 | 226 | /********************************************************************* 227 | * @fn I2C_SendData 228 | * 229 | * @brief Sends a data byte through the I2Cx peripheral. 230 | * 231 | * @param Data - Byte to be transmitted. 232 | * 233 | * @return none 234 | */ 235 | void I2C_SendData(uint8_t Data) 236 | { 237 | R16_I2C_DATAR = Data; 238 | } 239 | 240 | /********************************************************************* 241 | * @fn I2C_ReceiveData 242 | * 243 | * @brief Returns the most recent received data by the I2Cx peripheral. 244 | * 245 | * @return The value of the received data. 246 | */ 247 | uint8_t I2C_ReceiveData(void) 248 | { 249 | return (uint8_t)R16_I2C_DATAR; 250 | } 251 | 252 | /********************************************************************* 253 | * @fn I2C_Send7bitAddress 254 | * 255 | * @brief Transmits the address byte to select the slave device. 256 | * 257 | * @param Address - specifies the slave address which will be transmitted. 258 | * @param I2C_Direction - specifies whether the I2C device will be a Transmitter or a Receiver. 259 | * I2C_Direction_Transmitter - Transmitter mode. 260 | * I2C_Direction_Receiver - Receiver mode. 261 | * 262 | * @return none 263 | */ 264 | void I2C_Send7bitAddress(uint8_t Address, uint8_t I2C_Direction) 265 | { 266 | if(I2C_Direction != I2C_Direction_Transmitter) 267 | Address |= OADDR1_ADD0_Set; 268 | else 269 | Address &= OADDR1_ADD0_Reset; 270 | 271 | R16_I2C_DATAR = Address; 272 | } 273 | 274 | /********************************************************************* 275 | * @fn I2C_SoftwareResetCmd 276 | * 277 | * @brief Enables or disables the specified I2C software reset. 278 | * 279 | * @param NewState - ENABLE or DISABLE. 280 | * 281 | * @return none 282 | */ 283 | void I2C_SoftwareResetCmd(FunctionalState NewState) 284 | { 285 | if(NewState != DISABLE) 286 | R16_I2C_CTRL1 |= RB_I2C_SWRST; 287 | else 288 | R16_I2C_CTRL1 &= ~RB_I2C_SWRST; 289 | } 290 | 291 | /********************************************************************* 292 | * @fn I2C_NACKPositionConfig 293 | * 294 | * @brief Selects the specified I2C NACK position in master receiver mode. 295 | * 296 | * @param I2C_NACKPosition - specifies the NACK position. 297 | * I2C_NACKPosition_Next - indicates that the next byte will be the last received byte. 298 | * I2C_NACKPosition_Current - indicates that current byte is the last received byte. 299 | * 300 | * @return none 301 | */ 302 | void I2C_NACKPositionConfig(uint16_t I2C_NACKPosition) 303 | { 304 | if(I2C_NACKPosition == I2C_NACKPosition_Next) 305 | R16_I2C_CTRL1 |= I2C_NACKPosition_Next; 306 | else 307 | R16_I2C_CTRL1 &= I2C_NACKPosition_Current; 308 | } 309 | 310 | /********************************************************************* 311 | * @fn I2C_SMBusAlertConfig 312 | * 313 | * @brief Drives the SMBusAlert pin high or low for the specified I2C. 314 | * 315 | * @param I2C_SMBusAlert - specifies SMBAlert pin level. 316 | * I2C_SMBusAlert_Low - SMBAlert pin driven low. 317 | * I2C_SMBusAlert_High - SMBAlert pin driven high. 318 | * 319 | * @return none 320 | */ 321 | void I2C_SMBusAlertConfig(uint16_t I2C_SMBusAlert) 322 | { 323 | if(I2C_SMBusAlert == I2C_SMBusAlert_Low) 324 | R16_I2C_CTRL1 |= I2C_SMBusAlert_Low; 325 | else 326 | R16_I2C_CTRL1 &= I2C_SMBusAlert_High; 327 | } 328 | 329 | /********************************************************************* 330 | * @fn I2C_TransmitPEC 331 | * 332 | * @brief Enables or disables the specified I2C PEC transfer. 333 | * 334 | * @param NewState - ENABLE or DISABLE. 335 | * 336 | * @return none 337 | */ 338 | void I2C_TransmitPEC(FunctionalState NewState) 339 | { 340 | if(NewState != DISABLE) 341 | R16_I2C_CTRL1 |= RB_I2C_PEC; 342 | else 343 | R16_I2C_CTRL1 &= ~RB_I2C_PEC; 344 | } 345 | 346 | /********************************************************************* 347 | * @fn I2C_PECPositionConfig 348 | * 349 | * @brief Selects the specified I2C PEC position. 350 | * 351 | * @param I2C_PECPosition - specifies the PEC position. 352 | * I2C_PECPosition_Next - indicates that the next byte is PEC. 353 | * I2C_PECPosition_Current - indicates that current byte is PEC. 354 | * 355 | * @return none 356 | */ 357 | void I2C_PECPositionConfig(uint16_t I2C_PECPosition) 358 | { 359 | if(I2C_PECPosition == I2C_PECPosition_Next) 360 | R16_I2C_CTRL1 |= I2C_PECPosition_Next; 361 | else 362 | R16_I2C_CTRL1 &= I2C_PECPosition_Current; 363 | } 364 | 365 | /********************************************************************* 366 | * @fn I2C_CalculatePEC 367 | * 368 | * @brief Enables or disables the PEC value calculation of the transferred bytes. 369 | * 370 | * @param NewState - ENABLE or DISABLE. 371 | * 372 | * @return none 373 | */ 374 | void I2C_CalculatePEC(FunctionalState NewState) 375 | { 376 | if(NewState != DISABLE) 377 | R16_I2C_CTRL1 |= RB_I2C_ENPEC; 378 | else 379 | R16_I2C_CTRL1 &= ~RB_I2C_ENPEC; 380 | } 381 | 382 | /********************************************************************* 383 | * @fn I2C_GetPEC 384 | * 385 | * @brief Returns the PEC value for the specified I2C. 386 | * 387 | * @return The PEC value. 388 | */ 389 | uint8_t I2C_GetPEC(void) 390 | { 391 | return (R16_I2C_STAR2 >> 8); 392 | } 393 | 394 | /********************************************************************* 395 | * @fn I2C_ARPCmd 396 | * 397 | * @brief Enables or disables the specified I2C ARP. 398 | * 399 | * @param NewState - ENABLE or DISABLE. 400 | * 401 | * @return none 402 | */ 403 | void I2C_ARPCmd(FunctionalState NewState) 404 | { 405 | if(NewState != DISABLE) 406 | R16_I2C_CTRL1 |= RB_I2C_EBARP; 407 | else 408 | R16_I2C_CTRL1 &= ~RB_I2C_EBARP; 409 | } 410 | 411 | /********************************************************************* 412 | * @fn I2C_StretchClockCmd 413 | * 414 | * @brief Enables or disables the specified I2C Clock stretching. 415 | * 416 | * @param NewState - ENABLE or DISABLE. 417 | * 418 | * @return none 419 | */ 420 | void I2C_StretchClockCmd(FunctionalState NewState) 421 | { 422 | if(NewState == DISABLE) 423 | R16_I2C_CTRL1 |= RB_I2C_NOSTRETCH; 424 | else 425 | R16_I2C_CTRL1 &= ~RB_I2C_NOSTRETCH; 426 | } 427 | 428 | /********************************************************************* 429 | * @fn I2C_FastModeDutyCycleConfig 430 | * 431 | * @brief Selects the specified I2C fast mode duty cycle. 432 | * 433 | * @param I2C_DutyCycle - specifies the fast mode duty cycle. 434 | * I2C_DutyCycle_2 - I2C fast mode Tlow/Thigh = 2. 435 | * I2C_DutyCycle_16_9 - I2C fast mode Tlow/Thigh = 16/9. 436 | * 437 | * @return none 438 | */ 439 | void I2C_FastModeDutyCycleConfig(uint16_t I2C_DutyCycle) 440 | { 441 | if(I2C_DutyCycle != I2C_DutyCycle_16_9) 442 | R16_I2C_CKCFGR &= ~I2C_DutyCycle_16_9; 443 | else 444 | R16_I2C_CKCFGR |= I2C_DutyCycle_16_9; 445 | } 446 | 447 | /********************************************************************* 448 | * @fn I2C_CheckEvent 449 | * 450 | * @brief Checks whether the last I2Cx Event is equal to the one passed as parameter. 451 | * 452 | * @param I2C_EVENT - specifies the event to be checked. 453 | * I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : EV1. 454 | * I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : EV1. 455 | * I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED : EV1. 456 | * I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED : EV1. 457 | * I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED : EV1. 458 | * I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2. 459 | * (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) : EV2. 460 | * (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) : EV2. 461 | * I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3. 462 | * (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) : EV3. 463 | * (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3. 464 | * I2C_EVENT_SLAVE_ACK_FAILURE : EV3_2. 465 | * I2C_EVENT_SLAVE_STOP_DETECTED : EV4. 466 | * I2C_EVENT_MASTER_MODE_SELECT : EV5. 467 | * I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6. 468 | * I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6. 469 | * I2C_EVENT_MASTER_BYTE_RECEIVED : EV7. 470 | * I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8. 471 | * I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2. 472 | * I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9. 473 | * 474 | * @return 1 - SUCCESS or 0 - ERROR. 475 | */ 476 | uint8_t I2C_CheckEvent(uint32_t I2C_EVENT) 477 | { 478 | uint32_t lastevent = 0; 479 | uint32_t flag1 = 0, flag2 = 0; 480 | uint8_t status = 0; 481 | 482 | flag1 = R16_I2C_STAR1; 483 | flag2 = R16_I2C_STAR2; 484 | flag2 = flag2 << 16; 485 | 486 | lastevent = (flag1 | flag2) & FLAG_Mask; 487 | 488 | if((lastevent & I2C_EVENT) == I2C_EVENT) 489 | { 490 | status = !0; 491 | } 492 | else 493 | { 494 | status = 0; 495 | } 496 | 497 | return status; 498 | } 499 | 500 | /********************************************************************* 501 | * @fn I2C_GetLastEvent 502 | * 503 | * @brief Returns the last I2Cx Event. 504 | * 505 | * @return The last event. 506 | */ 507 | uint32_t I2C_GetLastEvent(void) 508 | { 509 | uint32_t lastevent = 0; 510 | uint32_t flag1 = 0, flag2 = 0; 511 | 512 | flag1 = R16_I2C_STAR1; 513 | flag2 = R16_I2C_STAR2; 514 | flag2 = flag2 << 16; 515 | lastevent = (flag1 | flag2) & FLAG_Mask; 516 | 517 | return lastevent; 518 | } 519 | 520 | /********************************************************************* 521 | * @fn I2C_GetFlagStatus 522 | * 523 | * @brief Checks whether the last I2Cx Event is equal to the one passed as parameter. 524 | * 525 | * @param I2C_FLAG - specifies the flag to check. 526 | * I2C_FLAG_DUALF - Dual flag (Slave mode). 527 | * I2C_FLAG_SMBHOST - SMBus host header (Slave mode). 528 | * I2C_FLAG_SMBDEFAULT - SMBus default header (Slave mode). 529 | * I2C_FLAG_GENCALL - General call header flag (Slave mode). 530 | * I2C_FLAG_TRA - Transmitter/Receiver flag. 531 | * I2C_FLAG_BUSY - Bus busy flag. 532 | * I2C_FLAG_MSL - Master/Slave flag. 533 | * I2C_FLAG_SMBALERT - SMBus Alert flag. 534 | * I2C_FLAG_TIMEOUT - Timeout or Tlow error flag. 535 | * I2C_FLAG_PECERR - PEC error in reception flag. 536 | * I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode). 537 | * I2C_FLAG_AF - Acknowledge failure flag. 538 | * I2C_FLAG_ARLO - Arbitration lost flag (Master mode). 539 | * I2C_FLAG_BERR - Bus error flag. 540 | * I2C_FLAG_TXE - Data register empty flag (Transmitter). 541 | * I2C_FLAG_RXNE - Data register not empty (Receiver) flag. 542 | * I2C_FLAG_STOPF - Stop detection flag (Slave mode). 543 | * I2C_FLAG_ADD10 - 10-bit header sent flag (Master mode). 544 | * I2C_FLAG_BTF - Byte transfer finished flag. 545 | * I2C_FLAG_ADDR - Address sent flag (Master mode) "ADSL" 546 | * Address matched flag (Slave mode)"ENDA". 547 | * I2C_FLAG_SB - Start bit flag (Master mode). 548 | * 549 | * @return FlagStatus - SET or RESET. 550 | */ 551 | FlagStatus I2C_GetFlagStatus(uint32_t I2C_FLAG) 552 | { 553 | FlagStatus bitstatus = RESET; 554 | __IO uint32_t i2creg = 0, i2cxbase = 0; 555 | 556 | i2cxbase = (uint32_t)BA_I2C; 557 | i2creg = I2C_FLAG >> 28; 558 | I2C_FLAG &= FLAG_Mask; 559 | 560 | if(i2creg != 0) 561 | { 562 | i2cxbase += 0x14; 563 | } 564 | else 565 | { 566 | I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); 567 | i2cxbase += 0x18; 568 | } 569 | 570 | if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) 571 | { 572 | bitstatus = SET; 573 | } 574 | else 575 | { 576 | bitstatus = RESET; 577 | } 578 | 579 | return bitstatus; 580 | } 581 | 582 | /********************************************************************* 583 | * @fn I2C_ClearFlag 584 | * 585 | * @brief Clears the I2Cx's pending flags. 586 | * 587 | * @param I2C_FLAG - specifies the flag to clear. 588 | * I2C_FLAG_SMBALERT - SMBus Alert flag. 589 | * I2C_FLAG_TIMEOUT - Timeout or Tlow error flag. 590 | * I2C_FLAG_PECERR - PEC error in reception flag. 591 | * I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode). 592 | * I2C_FLAG_AF - Acknowledge failure flag. 593 | * I2C_FLAG_ARLO - Arbitration lost flag (Master mode). 594 | * I2C_FLAG_BERR - Bus error flag. 595 | * 596 | * @return none 597 | */ 598 | void I2C_ClearFlag(uint32_t I2C_FLAG) 599 | { 600 | uint32_t flagpos = 0; 601 | 602 | flagpos = I2C_FLAG & FLAG_Mask; 603 | R16_I2C_STAR1 = (uint16_t)~flagpos; 604 | } 605 | 606 | /********************************************************************* 607 | * @fn I2C_GetITStatus 608 | * 609 | * @brief Checks whether the specified I2C interrupt has occurred or not. 610 | * 611 | * @param II2C_IT - specifies the interrupt source to check. 612 | * I2C_FLAG_SMBALERT - SMBus Alert flag. 613 | * I2C_FLAG_TIMEOUT - Timeout or Tlow error flag. 614 | * I2C_FLAG_PECERR - PEC error in reception flag. 615 | * I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode). 616 | * I2C_FLAG_AF - Acknowledge failure flag. 617 | * I2C_FLAG_ARLO - Arbitration lost flag (Master mode). 618 | * I2C_FLAG_BERR - Bus error flag. 619 | * I2C_FLAG_TXE - Data register empty flag (Transmitter). 620 | * I2C_FLAG_RXNE - Data register not empty (Receiver) flag. 621 | * I2C_FLAG_STOPF - Stop detection flag (Slave mode). 622 | * I2C_FLAG_ADD10 - 10-bit header sent flag (Master mode). 623 | * I2C_FLAG_BTF - Byte transfer finished flag. 624 | * I2C_FLAG_ADDR - Address sent flag (Master mode) "ADSL" 625 | * Address matched flag (Slave mode)"ENDA". 626 | * I2C_FLAG_SB - Start bit flag (Master mode). 627 | * 628 | * @return none 629 | */ 630 | ITStatus I2C_GetITStatus(uint32_t I2C_IT) 631 | { 632 | ITStatus bitstatus = RESET; 633 | uint32_t enablestatus = 0; 634 | 635 | enablestatus = (uint32_t)(((I2C_IT & ITEN_Mask) >> 16) & (R16_I2C_CTRL2)); 636 | I2C_IT &= FLAG_Mask; 637 | 638 | if(((R16_I2C_STAR1 & I2C_IT) != (uint32_t)RESET) && enablestatus) 639 | { 640 | bitstatus = SET; 641 | } 642 | else 643 | { 644 | bitstatus = RESET; 645 | } 646 | 647 | return bitstatus; 648 | } 649 | 650 | /********************************************************************* 651 | * @fn I2C_ClearITPendingBit 652 | * 653 | * @brief Clears the I2Cx interrupt pending bits. 654 | * 655 | * @param I2C_IT - specifies the interrupt pending bit to clear. 656 | * I2C_IT_SMBALERT - SMBus Alert interrupt. 657 | * I2C_IT_TIMEOUT - Timeout or Tlow error interrupt. 658 | * I2C_IT_PECERR - PEC error in reception interrupt. 659 | * I2C_IT_OVR - Overrun/Underrun interrupt (Slave mode). 660 | * I2C_IT_AF - Acknowledge failure interrupt. 661 | * I2C_IT_ARLO - Arbitration lost interrupt (Master mode). 662 | * I2C_IT_BERR - Bus error interrupt. 663 | * 664 | * @return none 665 | */ 666 | void I2C_ClearITPendingBit(uint32_t I2C_IT) 667 | { 668 | uint32_t flagpos = 0; 669 | 670 | flagpos = I2C_IT & FLAG_Mask; 671 | R16_I2C_STAR1 = (uint16_t)~flagpos; 672 | } 673 | -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_lcd.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_lcd.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_pwm.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_pwm.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_pwr.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_pwr.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_spi0.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_spi0.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_sys.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_sys.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_timer0.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_timer0.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_timer1.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_timer1.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_timer2.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_timer2.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_timer3.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_timer3.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_uart0.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_uart0.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_uart1.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_uart1.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_uart2.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_uart2.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_uart3.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_uart3.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_usbdev.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_usbdev.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_usbhostBase.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_usbhostBase.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/CH59x_usbhostClass.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/CH59x_usbhostClass.c -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH592SFR.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH592SFR.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_adc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_adc.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_clk.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_clk.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_common.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_common.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_flash.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_flash.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_gpio.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_gpio.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_i2c.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef __CH59x_I2C_H__ 4 | #define __CH59x_I2C_H__ 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* I2C_transfer_direction */ 11 | #define I2C_Direction_Transmitter ((uint8_t)0x00) 12 | #define I2C_Direction_Receiver ((uint8_t)0x01) 13 | 14 | /* I2C ADD0 mask */ 15 | #define OADDR1_ADD0_Set ((uint16_t)0x0001) 16 | #define OADDR1_ADD0_Reset ((uint16_t)0xFFFE) 17 | 18 | /* I2C_NACK_position */ 19 | #define I2C_NACKPosition_Next ((uint16_t)RB_I2C_POS) 20 | #define I2C_NACKPosition_Current ((uint16_t)~RB_I2C_POS) 21 | 22 | /* I2C_PEC_position */ 23 | #define I2C_PECPosition_Next ((uint16_t)RB_I2C_POS) 24 | #define I2C_PECPosition_Current ((uint16_t)~RB_I2C_POS) 25 | 26 | /* I2C_SMBus_alert_pin_level */ 27 | #define I2C_SMBusAlert_Low ((uint16_t)RB_I2C_ALERT) 28 | #define I2C_SMBusAlert_High ((uint16_t)~RB_I2C_ALERT) 29 | 30 | /* I2C FLAG mask */ 31 | #define FLAG_Mask ((uint32_t)0x00FFFFFF) 32 | 33 | /* I2C Interrupt Enable mask */ 34 | #define ITEN_Mask ((uint32_t)0x07000000) 35 | 36 | /* I2C_mode */ 37 | typedef enum 38 | { 39 | I2C_Mode_I2C = 0x0000, 40 | I2C_Mode_SMBusDevice = 0x0002, 41 | I2C_Mode_SMBusHost = 0x000A, 42 | } I2C_ModeTypeDef; 43 | 44 | /* I2C_duty_cycle_in_fast_mode */ 45 | typedef enum 46 | { 47 | I2C_DutyCycle_16_9 = RB_I2C_DUTY, /* I2C fast mode Tlow/Thigh = 16/9 */ 48 | I2C_DutyCycle_2 = 0x0000, /* I2C fast mode Tlow/Thigh = 2 */ 49 | } I2C_DutyTypeDef; 50 | 51 | /* I2C_acknowledgement - Enables or disables the acknowledgement.*/ 52 | typedef enum 53 | { 54 | I2C_Ack_Enable = RB_I2C_ACK, 55 | I2C_Ack_Disable = 0x0000, 56 | } I2C_AckTypeDef; 57 | 58 | /* I2C_acknowledged_address - Specifies if 7-bit or 10-bit address is acknowledged. */ 59 | typedef enum 60 | { 61 | I2C_AckAddr_7bit = 0x4000, 62 | I2C_AckAddr_10bit = 0xC000, 63 | } I2C_AckAddrTypeDef; 64 | 65 | /* I2C_interrupts_definition */ 66 | typedef enum 67 | { 68 | I2C_IT_BUF = 0x0400, /* Buffer interrupt mask. */ 69 | I2C_IT_EVT = 0x0200, /* Event interrupt mask. */ 70 | I2C_IT_ERR = 0x0100, /* Error interrupt mask. */ 71 | } I2C_ITTypeDef; 72 | 73 | /* I2C_interrupts_definition */ 74 | #define I2C_IT_SMBALERT ((uint32_t)0x01008000) 75 | #define I2C_IT_TIMEOUT ((uint32_t)0x01004000) 76 | #define I2C_IT_PECERR ((uint32_t)0x01001000) 77 | #define I2C_IT_OVR ((uint32_t)0x01000800) 78 | #define I2C_IT_AF ((uint32_t)0x01000400) 79 | #define I2C_IT_ARLO ((uint32_t)0x01000200) 80 | #define I2C_IT_BERR ((uint32_t)0x01000100) 81 | #define I2C_IT_TXE ((uint32_t)0x06000080) 82 | #define I2C_IT_RXNE ((uint32_t)0x06000040) 83 | #define I2C_IT_STOPF ((uint32_t)0x02000010) 84 | #define I2C_IT_ADD10 ((uint32_t)0x02000008) 85 | #define I2C_IT_BTF ((uint32_t)0x02000004) 86 | #define I2C_IT_ADDR ((uint32_t)0x02000002) 87 | #define I2C_IT_SB ((uint32_t)0x02000001) 88 | 89 | /* SR2 register flags */ 90 | #define I2C_FLAG_DUALF ((uint32_t)0x00800000) 91 | #define I2C_FLAG_SMBHOST ((uint32_t)0x00400000) 92 | #define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000) 93 | #define I2C_FLAG_GENCALL ((uint32_t)0x00100000) 94 | #define I2C_FLAG_TRA ((uint32_t)0x00040000) 95 | #define I2C_FLAG_BUSY ((uint32_t)0x00020000) 96 | #define I2C_FLAG_MSL ((uint32_t)0x00010000) 97 | 98 | /* SR1 register flags */ 99 | #define I2C_FLAG_SMBALERT ((uint32_t)0x10008000) 100 | #define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000) 101 | #define I2C_FLAG_PECERR ((uint32_t)0x10001000) 102 | #define I2C_FLAG_OVR ((uint32_t)0x10000800) 103 | #define I2C_FLAG_AF ((uint32_t)0x10000400) 104 | #define I2C_FLAG_ARLO ((uint32_t)0x10000200) 105 | #define I2C_FLAG_BERR ((uint32_t)0x10000100) 106 | #define I2C_FLAG_TXE ((uint32_t)0x10000080) 107 | #define I2C_FLAG_RXNE ((uint32_t)0x10000040) 108 | #define I2C_FLAG_STOPF ((uint32_t)0x10000010) 109 | #define I2C_FLAG_ADD10 ((uint32_t)0x10000008) 110 | #define I2C_FLAG_BTF ((uint32_t)0x10000004) 111 | #define I2C_FLAG_ADDR ((uint32_t)0x10000002) 112 | #define I2C_FLAG_SB ((uint32_t)0x10000001) 113 | 114 | /****************I2C Master Events (Events grouped in order of communication)********************/ 115 | 116 | #define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ 117 | #define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ 118 | #define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ 119 | #define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ 120 | #define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ 121 | #define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ 122 | #define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ 123 | 124 | /******************I2C Slave Events (Events grouped in order of communication)******************/ 125 | 126 | #define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */ 127 | #define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */ 128 | #define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */ 129 | #define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */ 130 | #define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */ 131 | #define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */ 132 | #define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */ 133 | #define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */ 134 | #define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */ 135 | #define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */ 136 | 137 | void I2C_Init(I2C_ModeTypeDef I2C_Mode, UINT32 I2C_ClockSpeed, I2C_DutyTypeDef I2C_DutyCycle, 138 | I2C_AckTypeDef I2C_Ack, I2C_AckAddrTypeDef I2C_AckAddr, UINT16 I2C_OwnAddress1); 139 | void I2C_Cmd(FunctionalState NewState); 140 | void I2C_GenerateSTART(FunctionalState NewState); 141 | void I2C_GenerateSTOP(FunctionalState NewState); 142 | void I2C_AcknowledgeConfig(FunctionalState NewState); 143 | void I2C_OwnAddress2Config(uint8_t Address); 144 | void I2C_DualAddressCmd(FunctionalState NewState); 145 | void I2C_GeneralCallCmd(FunctionalState NewState); 146 | void I2C_ITConfig(I2C_ITTypeDef I2C_IT, FunctionalState NewState); 147 | void I2C_SendData(uint8_t Data); 148 | 149 | uint8_t I2C_ReceiveData(void); 150 | 151 | void I2C_Send7bitAddress(uint8_t Address, uint8_t I2C_Direction); 152 | void I2C_SoftwareResetCmd(FunctionalState NewState); 153 | void I2C_NACKPositionConfig(uint16_t I2C_NACKPosition); 154 | void I2C_SMBusAlertConfig(uint16_t I2C_SMBusAlert); 155 | void I2C_TransmitPEC(FunctionalState NewState); 156 | void I2C_PECPositionConfig(uint16_t I2C_PECPosition); 157 | void I2C_CalculatePEC(FunctionalState NewState); 158 | 159 | uint8_t I2C_GetPEC(void); 160 | 161 | void I2C_ARPCmd(FunctionalState NewState); 162 | void I2C_StretchClockCmd(FunctionalState NewState); 163 | void I2C_FastModeDutyCycleConfig(uint16_t I2C_DutyCycle); 164 | 165 | /**************************************************************************************** 166 | * I2C State Monitoring Functions 167 | ****************************************************************************************/ 168 | uint8_t I2C_CheckEvent(uint32_t I2C_EVENT); 169 | uint32_t I2C_GetLastEvent(void); 170 | FlagStatus I2C_GetFlagStatus(uint32_t I2C_FLAG); 171 | 172 | void I2C_ClearFlag(uint32_t I2C_FLAG); 173 | ITStatus I2C_GetITStatus(uint32_t I2C_IT); 174 | void I2C_ClearITPendingBit(uint32_t I2C_IT); 175 | 176 | #ifdef __cplusplus 177 | } 178 | #endif 179 | 180 | #endif // __CH59x_I2C_H__ 181 | -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_lcd.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_lcd.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_pwm.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_pwm.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_pwr.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_pwr.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_spi.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_spi.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_sys.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_sys.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_timer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_timer.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_uart.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_uart.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_usbdev.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_usbdev.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/CH59x_usbhost.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/CH59x_usbhost.h -------------------------------------------------------------------------------- /Firmware/CH592F/StdPeriphDriver/inc/ISP592.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/StdPeriphDriver/inc/ISP592.h -------------------------------------------------------------------------------- /Firmware/CH592F/User/Main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/Firmware/CH592F/User/Main.c -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | ✨ BinaryKeyboard ✨ 7 |

8 | 9 |
10 | 11 | # 配置开发环境 12 | 13 | ## 1. 安装 Arduino IDE 14 | 本程序推荐使用 Arduino IDE 作为开发环境。 15 | 16 | ## 2. 使用 Arduino IDE 打开 `main.ino` 17 | 在 Arduino IDE 中打开你的项目文件 `main.ino`。 18 | 19 | ## 3. 添加 CH55x 的板卡管理器 URL 20 | 21 | 1. 点击菜单栏上的 **文件** -> **首选项** -> **其他开发板管理器地址**。 22 | 2. 在弹出的窗口中,添加以下链接: 23 | https://cos.thinkcreate.us/package_ch55xduino_mcs51_newest_cloudflare_index.json 24 | 25 | 3. 然后点击 **确定**。 26 | 27 | ## 4. 安装 CH55xDuino 包 28 | 29 | 1. 在菜单栏点击 **工具** -> **开发板** -> **开发板管理器**。 30 | 2. 在搜索框中输入 `ch`,查找 `Ch55xDuino` 包。 31 | 3. 找到 `Ch55xDuino` 后,点击 **安装** 按钮。 32 | 33 | ## 5. 选择开发板 34 | 35 | 1. 点击 **工具** -> **开发板**,选择 **CH552Board**,然后点击 **确定**。 36 | 37 | ## 6. 设置 USB 配置 38 | 39 | 1. 点击 **工具** -> **USB Setting**,选择 **USER CODE w/148B USB ram**。 40 | 41 | ## 7. 配置按键版本 | Key Version Configuration 42 | 43 | 根据你使用的不同按键版本,修改 `config.h` 文件中的注释来启用对应的版本: 44 | 45 | ```c 46 | // 基础款 47 | //#define USE_BASIC 48 | 49 | // 旋钮款 50 | //#define USE_KNOB 51 | 52 | // 五键款 53 | //#define USE_5KEYS 54 | ``` 55 | 56 | ## 8. 上传代码 57 | 58 | 初次使用时,可能需要断开板子与电脑的连接,然后按住 **BOOT** 按钮 ( 距离边缘更近的那个 ) 的同时连接到电脑从而进入 Bootloader 模式。你可以编译并上传代码到开发板。 59 | 60 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/README.md: -------------------------------------------------------------------------------- 1 | # binary-keyboard-studio-ui 2 | 3 | This template should help get you started developing with Vue 3 in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). 8 | 9 | ## Type Support for `.vue` Imports in TS 10 | 11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. 12 | 13 | ## Customize configuration 14 | 15 | See [Vite Configuration Reference](https://vite.dev/config/). 16 | 17 | ## Project Setup 18 | 19 | ```sh 20 | pnpm install 21 | ``` 22 | 23 | ### Compile and Hot-Reload for Development 24 | 25 | ```sh 26 | pnpm dev 27 | ``` 28 | 29 | ### Type-Check, Compile and Minify for Production 30 | 31 | ```sh 32 | pnpm build 33 | ``` 34 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | // biome-ignore lint: disable 6 | export {} 7 | 8 | /* prettier-ignore */ 9 | declare module 'vue' { 10 | export interface GlobalComponents { 11 | AppFooter: typeof import('./src/components/AppFooter.vue')['default'] 12 | Badge: typeof import('primevue/badge')['default'] 13 | BasicKeyboard: typeof import('./src/components/keyboards/BasicKeyboard.vue')['default'] 14 | Button: typeof import('primevue/button')['default'] 15 | Card: typeof import('primevue/card')['default'] 16 | Checkbox: typeof import('primevue/checkbox')['default'] 17 | Column: typeof import('primevue/column')['default'] 18 | DataInfoCard: typeof import('./src/components/DataInfoCard.vue')['default'] 19 | DataTable: typeof import('primevue/datatable')['default'] 20 | DeviceFinder: typeof import('./src/components/DeviceFinder.vue')['default'] 21 | DeviceInfoCard: typeof import('./src/components/DeviceInfoCard.vue')['default'] 22 | Dialog: typeof import('primevue/dialog')['default'] 23 | Divider: typeof import('primevue/divider')['default'] 24 | FiveKeysKeyboard: typeof import('./src/components/keyboards/FiveKeysKeyboard.vue')['default'] 25 | Knob: typeof import('primevue/knob')['default'] 26 | KnobKeyboard: typeof import('./src/components/keyboards/KnobKeyboard.vue')['default'] 27 | ProgressSpinner: typeof import('primevue/progressspinner')['default'] 28 | Select: typeof import('primevue/select')['default'] 29 | SelectButton: typeof import('primevue/selectbutton')['default'] 30 | Skeleton: typeof import('primevue/skeleton')['default'] 31 | Tab: typeof import('primevue/tab')['default'] 32 | TabList: typeof import('primevue/tablist')['default'] 33 | TabPanel: typeof import('primevue/tabpanel')['default'] 34 | TabPanels: typeof import('primevue/tabpanels')['default'] 35 | Tabs: typeof import('primevue/tabs')['default'] 36 | Tag: typeof import('primevue/tag')['default'] 37 | Toast: typeof import('primevue/toast')['default'] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | BinaryKeyboard按键映射修改 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "binary-keyboard-studio-ui", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "run-p type-check \"build-only {@}\" --", 9 | "preview": "vite preview", 10 | "build-only": "vite build", 11 | "type-check": "vue-tsc --build" 12 | }, 13 | "dependencies": { 14 | "@primeuix/themes": "^1.0.0", 15 | "pinia": "^3.0.1", 16 | "primeflex": "^4.0.0", 17 | "primeicons": "^7.0.0", 18 | "primevue": "^4.3.1", 19 | "vue": "^3.5.13" 20 | }, 21 | "devDependencies": { 22 | "@primevue/auto-import-resolver": "^4.3.1", 23 | "@tsconfig/node22": "^22.0.0", 24 | "@types/node": "^22.13.4", 25 | "@vitejs/plugin-vue": "^5.2.1", 26 | "@vue/tsconfig": "^0.7.0", 27 | "npm-run-all2": "^7.0.2", 28 | "typescript": "~5.7.3", 29 | "unplugin-vue-components": "^28.4.1", 30 | "vite": "^6.1.0", 31 | "vite-plugin-vue-devtools": "^7.7.2", 32 | "vue-tsc": "^2.2.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/UI/binary-keyboard-studio-ui/public/favicon.ico -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/App.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 129 | 130 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/assets/main.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MeowKJ/BinaryKeyboard/873822382e81feb8d4ffef49fd8ed1a69d750109/UI/binary-keyboard-studio-ui/src/assets/main.css -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/components/AppFooter.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 65 | 66 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/components/DataInfoCard.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 62 | 63 | 79 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/components/DeviceFinder.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 50 | 51 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/components/DeviceInfoCard.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 27 | 28 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/components/keyboards/BasicKeyboard.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 45 | 46 | 60 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/components/keyboards/FiveKeysKeyboard.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 45 | 46 | 60 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/components/keyboards/KnobKeyboard.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 42 | 43 | 57 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import "./assets/main.css"; 2 | import "primeflex/primeflex.css"; 3 | import "primeicons/primeicons.css"; 4 | 5 | import { createApp } from "vue"; 6 | import { createPinia } from "pinia"; 7 | import App from "./App.vue"; 8 | 9 | import PrimeVue from "primevue/config"; 10 | import Aura from "@primeuix/themes/aura"; 11 | import ToastService from "primevue/toastservice"; 12 | 13 | const app = createApp(App); 14 | app.use(createPinia()); 15 | app.use(PrimeVue, { 16 | theme: { 17 | preset: Aura, 18 | }, 19 | }); 20 | app.use(ToastService); 21 | 22 | app.mount("#app"); 23 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/stores/counter.ts: -------------------------------------------------------------------------------- 1 | import { ref, computed } from "vue"; 2 | import { defineStore } from "pinia"; 3 | 4 | export const useCounterStore = defineStore("counter", () => { 5 | const count = ref(0); 6 | const doubleCount = computed(() => count.value * 2); 7 | function increment() { 8 | count.value++; 9 | } 10 | 11 | return { count, doubleCount, increment }; 12 | }); 13 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/stores/deviceStore.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | import { ref } from "vue"; 3 | import { 4 | parseKeyMappingsFromUint8Array, 5 | convertKeyMappingsToUint8Array, 6 | } from "@/utils/hidConverters/keyMappingConverter"; 7 | 8 | import { mediaDescriptions } from "@/utils/hidConverters/mediaHIDConverter"; 9 | 10 | import type { KeyMapping, ComparedKeyMappingString } from "@/types"; 11 | import { KeyType } from "@/types"; 12 | import { getKeyNameCombination } from "@/utils/hidConverters/keyboardHIDConverter"; 13 | import { getMouseConfigString } from "@/utils/hidConverters/mouseHIDConverter"; 14 | 15 | export const useDeviceStore = defineStore("device", () => { 16 | // 设备信息 17 | const device = ref(null); 18 | const deviceFirmwareVersion = ref(0); 19 | const deviceModelNumber = ref(0); 20 | 21 | // 按键映射配置(初始化 8 个空配置) 22 | const keyMappingsList = ref( 23 | Array(8).fill({ type: 0, modifier: 0, key: 0 }) 24 | ); 25 | 26 | const keyMappingsListOriginal = ref( 27 | Array(8).fill({ type: 0, modifier: 0, key: 0 }) 28 | ); 29 | /** 30 | * 获取设备型号名称 31 | * @returns {string} 设备型号名称 32 | */ 33 | const getDeviceModelName = () => { 34 | if (!deviceModelNumber.value) { 35 | return "未知设备"; 36 | } 37 | switch (deviceModelNumber.value) { 38 | case 1: 39 | return "基础款"; 40 | case 2: 41 | return "旋钮款"; 42 | case 3: 43 | return "五键款"; 44 | default: 45 | return "未知型号"; 46 | } 47 | }; 48 | 49 | /** 50 | * 获取设备信息列表 51 | * @returns {Array} 设备信息列表 52 | */ 53 | const getDeviceInfoList = () => { 54 | return [ 55 | { key: "型号名称", value: getDeviceModelName() }, 56 | { 57 | key: "型号代码", 58 | value: `0x${deviceModelNumber.value 59 | .toString(16) 60 | .toUpperCase() 61 | .padStart(2, "0")}`, 62 | }, 63 | { 64 | key: "固件版本", 65 | value: `0x${deviceFirmwareVersion.value 66 | .toString(16) 67 | .toUpperCase() 68 | .padStart(2, "0")}`, 69 | }, 70 | ]; 71 | }; 72 | 73 | /** 74 | * 从 Uint8Array 数据设置按键映射 75 | * @param {Uint8Array} data 数据数组 76 | */ 77 | const setkeyMappingsListFromUint8Array = (data: Uint8Array) => { 78 | keyMappingsList.value = parseKeyMappingsFromUint8Array(data); 79 | keyMappingsListOriginal.value = parseKeyMappingsFromUint8Array(data); 80 | }; 81 | 82 | /** 83 | * 获取当前的按键映射数据 84 | * @returns {Uint8Array} 当前的按键映射数据 85 | */ 86 | const getkeyMappingsListAsUint8Array = () => { 87 | return convertKeyMappingsToUint8Array(keyMappingsList.value); 88 | }; 89 | 90 | /** 91 | * 获取当前的按键映射数据的字符串表示 92 | */ 93 | const getComparedKeyMappingsListAsString = (): ComparedKeyMappingString[] => { 94 | let KeyMappingStringList: ComparedKeyMappingString[] = []; 95 | const length = keyMappingsListOriginal.value.length; 96 | 97 | for (let i = 0; i < length; i++) { 98 | const km = keyMappingsListOriginal.value[i]; 99 | const kmNew = keyMappingsList.value[i]; 100 | 101 | const oldMapping: ComparedKeyMappingString = { 102 | index: i, 103 | oldTypeString: "", 104 | oldValue: "", 105 | newTypeString: "", 106 | newValue: "", 107 | }; 108 | 109 | switch (km.type) { 110 | case KeyType.KEBOARD: 111 | oldMapping.oldTypeString = "键盘"; 112 | oldMapping.oldValue = getKeyNameCombination(km.value); 113 | break; 114 | case KeyType.MEDIA: 115 | oldMapping.oldTypeString = "多媒体"; 116 | oldMapping.oldValue = mediaDescriptions[km.value.key]; 117 | break; 118 | case KeyType.MOUSE: 119 | oldMapping.oldTypeString = "鼠标"; 120 | oldMapping.oldValue = getMouseConfigString(km.value); 121 | break; 122 | default: 123 | oldMapping.oldTypeString = "未知"; 124 | oldMapping.oldValue = ""; 125 | break; 126 | } 127 | 128 | switch (kmNew.type) { 129 | case KeyType.KEBOARD: 130 | oldMapping.newTypeString = "键盘"; 131 | oldMapping.newValue = getKeyNameCombination(kmNew.value); 132 | break; 133 | case KeyType.MEDIA: 134 | oldMapping.newTypeString = "多媒体"; 135 | oldMapping.newValue = mediaDescriptions[kmNew.value.key]; 136 | break; 137 | case KeyType.MOUSE: 138 | oldMapping.newTypeString = "鼠标"; 139 | oldMapping.newValue = getMouseConfigString(kmNew.value); 140 | break; 141 | default: 142 | oldMapping.newTypeString = "未知"; 143 | oldMapping.newValue = ""; 144 | break; 145 | } 146 | 147 | KeyMappingStringList.push(oldMapping); 148 | } 149 | 150 | return KeyMappingStringList; 151 | }; 152 | 153 | return { 154 | device, 155 | deviceFirmwareVersion, 156 | deviceModelNumber, 157 | keyMappingsList, 158 | keyMappingsListOriginal, 159 | getDeviceModelName, 160 | getDeviceInfoList, 161 | setkeyMappingsListFromUint8Array, 162 | getkeyMappingsListAsUint8Array, 163 | getComparedKeyMappingsListAsString, 164 | }; 165 | }); 166 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export type ButtonType = 2 | | "circle" 3 | | "square" 4 | | "horizontal-bar" 5 | | "vertical-bar"; 6 | 7 | export enum KeyboardType { 8 | BASIC = 0x01, 9 | KNOB = 0x02, 10 | FIVE_KEYS = 0x03, 11 | } 12 | 13 | export enum KeyType { 14 | KEBOARD = 0x01, 15 | MEDIA = 0x02, 16 | MOUSE = 0x03, 17 | } 18 | 19 | export interface KeyboardConfig { 20 | key: string; // 原始按键字符(无法通过 HID 完全还原时置为空) 21 | code: string; // 对应 event.code 22 | leftMetaKey: boolean; 23 | leftCtrlKey: boolean; 24 | leftAltKey: boolean; 25 | leftShiftKey: boolean; 26 | rightMetaKey: boolean; 27 | rightCtrlKey: boolean; 28 | rightAltKey: boolean; 29 | rightShiftKey: boolean; 30 | str?: string; 31 | } 32 | 33 | /** 原始 HID 数据类型:包含一个8位修饰键编码和一个8位 HID 编码 */ 34 | export interface KeyBoardRawHIDData { 35 | modifier: number; // 8 位修饰键编码 36 | hid: number; // 8 位 HID 键码 37 | } 38 | 39 | export interface MediaConfig { 40 | key: MediaHIDCode; 41 | } 42 | 43 | export interface MouseConfig { 44 | button: MouseButtonHID; 45 | wheel: number; 46 | } 47 | 48 | export type KeyMapping = 49 | | { type: 1; value: KeyboardConfig } 50 | | { type: 2; value: MediaConfig } 51 | | { type: 3; value: MouseConfig }; 52 | 53 | export interface ComparedKeyMappingString { 54 | index: number; 55 | oldTypeString: string; 56 | oldValue: string; 57 | newTypeString: string; 58 | newValue: string; 59 | } 60 | 61 | export enum MouseButtonHID { 62 | None = 0x00, // 无按键 63 | LeftButton = 0x01, // 左键 64 | RightButton = 0x02, // 右键 65 | MiddleButton = 0x04, // 中键 66 | BackButton = 0x08, // 侧键1(后退) 67 | ForwardButton = 0x10, // 侧键2(前进) 68 | } 69 | 70 | export enum MediaHIDCode { 71 | // 多媒体控制 72 | None = 0x00, // 无按键 73 | Play = 0xb0, // 播放 74 | Pause = 0xb1, // 暂停 75 | PlayPause = 0xcd, // 播放/暂停 76 | Stop = 0xb7, // 停止 77 | NextTrack = 0xb5, // 下一曲 78 | PrevTrack = 0xb6, // 上一曲 79 | FastForward = 0xb3, // 快进 80 | Rewind = 0xb4, // 倒带 81 | 82 | // 音量控制 83 | Mute = 0xe2, // 静音 84 | VolumeUp = 0xe9, // 音量增加 85 | VolumeDown = 0xea, // 音量减少 86 | 87 | // 频道控制(适用于电视/机顶盒) 88 | ChannelUp = 0x9c, // 频道增加 89 | ChannelDown = 0x9d, // 频道减少 90 | 91 | // 设备电源控制 92 | Power = 0x30, // 设备电源 93 | Sleep = 0x32, // 休眠 94 | WakeUp = 0x33, // 唤醒 95 | 96 | // 设备菜单/导航 97 | Menu = 0x40, // 进入菜单 98 | Home = 0x223, // 主页 99 | Back = 0x224, // 返回 100 | Exit = 0x94, // 退出 101 | Select = 0x41, // 确认/选择 102 | Up = 0x42, // 向上 103 | Down = 0x43, // 向下 104 | Left = 0x44, // 向左 105 | Right = 0x45, // 向右 106 | 107 | // 应用程序快捷键 108 | Calculator = 0x192, // 计算器 109 | FileExplorer = 0x194, // 文件资源管理器 110 | 111 | BrowserForward = 0x225, // 浏览器前进 112 | BrowserRefresh = 0x227, // 刷新 113 | BrowserFavorites = 0x22a, // 收藏夹 114 | Email = 0x18a, // 电子邮件应用 115 | } 116 | 117 | /** 修饰键的 HID 标准编码(8位,每一位代表一个修饰键) 118 | * 通常: 119 | * bit0: LeftCtrl 120 | * bit1: LeftShift 121 | * bit2: LeftAlt 122 | * bit3: LeftMeta 123 | * bit4: RightCtrl 124 | * bit5: RightShift 125 | * bit6: RightAlt 126 | * bit7: RightMeta 127 | */ 128 | export enum KeyboardKeyModifier { 129 | LeftCtrl = 0x01, 130 | LeftShift = 0x02, 131 | LeftAlt = 0x04, 132 | LeftMeta = 0x08, 133 | RightCtrl = 0x10, 134 | RightShift = 0x20, 135 | RightAlt = 0x40, 136 | RightMeta = 0x80, 137 | } 138 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/types/webhid.d.ts: -------------------------------------------------------------------------------- 1 | /*~ https://wicg.github.io/webhid/#hiddevicefilter-dictionary */ 2 | interface HIDDeviceFilter { 3 | vendorId?: number | undefined; 4 | productId?: number | undefined; 5 | usagePage?: number | undefined; 6 | usage?: number | undefined; 7 | } 8 | 9 | /*~ https://wicg.github.io/webhid/#hiddevicerequestoptions-dictionary */ 10 | interface HIDDeviceRequestOptions { 11 | filters: HIDDeviceFilter[]; 12 | } 13 | 14 | /*~ https://wicg.github.io/webhid/#hid-interface */ 15 | declare class HID extends EventTarget { 16 | onconnect: ((this: this, ev: Event) => any) | null; 17 | ondisconnect: ((this: this, ev: Event) => any) | null; 18 | 19 | getDevices(): Promise; 20 | 21 | requestDevice(options?: HIDDeviceRequestOptions): Promise; 22 | 23 | addEventListener( 24 | type: "connect" | "disconnect", 25 | listener: (this: this, ev: HIDConnectionEvent) => any, 26 | useCapture?: boolean 27 | ): void; 28 | addEventListener( 29 | type: string, 30 | listener: EventListenerOrEventListenerObject | null, 31 | options?: boolean | AddEventListenerOptions 32 | ): void; 33 | 34 | removeEventListener( 35 | type: "connect" | "disconnect", 36 | callback: (this: this, ev: HIDConnectionEvent) => any, 37 | useCapture?: boolean 38 | ): void; 39 | removeEventListener( 40 | type: string, 41 | callback: EventListenerOrEventListenerObject | null, 42 | options?: EventListenerOptions | boolean 43 | ): void; 44 | } 45 | 46 | /*~ https://wicg.github.io/webhid/#extensions-to-the-navigator-interface */ 47 | interface Navigator { 48 | readonly hid: HID; 49 | } 50 | 51 | /*~ https://wicg.github.io/webhid/#hidconnectioneventinit-dictionary */ 52 | interface HIDConnectionEventInit { 53 | device: HIDDevice; 54 | } 55 | 56 | /*~ https://wicg.github.io/webhid/#hidconnectionevent-interface */ 57 | declare class HIDConnectionEvent extends Event { 58 | constructor(type: string, eventInitDict: HIDConnectionEventInit); 59 | 60 | readonly device: HIDDevice; 61 | } 62 | 63 | /*~ https://wicg.github.io/webhid/#hidinputreporteventinit-dictionary */ 64 | interface HIDInputReportEventInit extends EventInit { 65 | device: HIDDevice; 66 | reportId: number; 67 | data: DataView; 68 | } 69 | 70 | /*~ https://wicg.github.io/webhid/#hidinputreportevent-interface */ 71 | declare class HIDInputReportEvent extends Event { 72 | constructor(type: string, eventInitDict: HIDInputReportEventInit); 73 | 74 | readonly device: HIDDevice; 75 | readonly reportId: number; 76 | readonly data: DataView; 77 | } 78 | 79 | /*~ https://wicg.github.io/webhid/#hidunitsystem-enum */ 80 | type HIDUnitSystem = 81 | | "none" 82 | | "si-linear" 83 | | "si-rotation" 84 | | "english-linear" 85 | | "english-rotation" 86 | | "vendor-defined" 87 | | "reserved"; 88 | 89 | /*~ https://wicg.github.io/webhid/#hidreportitem-dictionary */ 90 | interface HIDReportItem { 91 | isAbsolute?: boolean | undefined; 92 | isArray?: boolean | undefined; 93 | isBufferedBytes?: boolean | undefined; 94 | isConstant?: boolean | undefined; 95 | isLinear?: boolean | undefined; 96 | isRange?: boolean | undefined; 97 | isVolatile?: boolean | undefined; 98 | hasNull?: boolean | undefined; 99 | hasPreferredState?: boolean | undefined; 100 | wrap?: boolean | undefined; 101 | usages?: number[] | undefined; 102 | usageMinimum?: number | undefined; 103 | usageMaximum?: number | undefined; 104 | reportSize?: number | undefined; 105 | reportCount?: number | undefined; 106 | unitExponent?: number | undefined; 107 | unitSystem?: HIDUnitSystem | undefined; 108 | unitFactorLengthExponent?: number | undefined; 109 | unitFactorMassExponent?: number | undefined; 110 | unitFactorTimeExponent?: number | undefined; 111 | unitFactorTemperatureExponent?: number | undefined; 112 | unitFactorCurrentExponent?: number | undefined; 113 | unitFactorLuminousIntensityExponent?: number | undefined; 114 | logicalMinimum?: number | undefined; 115 | logicalMaximum?: number | undefined; 116 | physicalMinimum?: number | undefined; 117 | physicalMaximum?: number | undefined; 118 | strings?: string[] | undefined; 119 | } 120 | 121 | /*~ https://wicg.github.io/webhid/#hidreportinfo-dictionary */ 122 | interface HIDReportInfo { 123 | reportId?: number | undefined; 124 | items?: HIDReportItem[] | undefined; 125 | } 126 | 127 | /*~ https://wicg.github.io/webhid/#hidcollectioninfo-dictionary */ 128 | interface HIDCollectionInfo { 129 | usagePage?: number | undefined; 130 | usage?: number | undefined; 131 | type?: number | undefined; 132 | children?: HIDCollectionInfo[] | undefined; 133 | inputReports?: HIDReportInfo[] | undefined; 134 | outputReports?: HIDReportInfo[] | undefined; 135 | featureReports?: HIDReportInfo[] | undefined; 136 | } 137 | 138 | /*~ https://wicg.github.io/webhid/#hiddevice-interface */ 139 | declare class HIDDevice extends EventTarget { 140 | oninputreport: ((this: this, ev: HIDInputReportEvent) => any) | null; 141 | readonly opened: boolean; 142 | readonly vendorId: number; 143 | readonly productId: number; 144 | readonly productName: string; 145 | readonly collections: HIDCollectionInfo[]; 146 | 147 | open(): Promise; 148 | 149 | close(): Promise; 150 | 151 | forget(): Promise; 152 | 153 | sendReport(reportId: number, data: BufferSource): Promise; 154 | 155 | sendFeatureReport(reportId: number, data: BufferSource): Promise; 156 | 157 | receiveFeatureReport(reportId: number): Promise; 158 | 159 | addEventListener( 160 | type: "inputreport", 161 | listener: (this: this, ev: HIDInputReportEvent) => any 162 | ): void; 163 | addEventListener( 164 | type: string, 165 | listener: EventListenerOrEventListenerObject | null, 166 | options?: boolean | AddEventListenerOptions 167 | ): void; 168 | 169 | removeEventListener( 170 | type: "inputreport", 171 | callback: (this: this, ev: HIDInputReportEvent) => any 172 | ): void; 173 | removeEventListener( 174 | type: string, 175 | callback: EventListenerOrEventListenerObject | null, 176 | options?: EventListenerOptions | boolean 177 | ): void; 178 | } 179 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/utils/WebHidTools.ts: -------------------------------------------------------------------------------- 1 | export class WebHidTools { 2 | // 请求并连接 HID 设备 3 | static async requestDevice( 4 | filters: HIDDeviceFilter[] = [] 5 | ): Promise { 6 | try { 7 | const devices = await navigator.hid.requestDevice({ filters }); 8 | if (devices.length === 0) { 9 | console.error("No HID devices found."); 10 | return null; 11 | } 12 | const device = devices[0]; 13 | console.log("HID device selected:", device); 14 | return device; 15 | } catch (error) { 16 | console.error("Error requesting HID device:", error); 17 | return null; 18 | } 19 | } 20 | 21 | // 打开 HID 设备 22 | static async openDevice(device: HIDDevice): Promise { 23 | try { 24 | await device.open(); 25 | console.log("HID device opened successfully:", device); 26 | return true; 27 | } catch (error) { 28 | console.error("Error opening HID device:", error); 29 | return false; 30 | } 31 | } 32 | 33 | // 发送 Output Report 到 HID 设备 34 | static async sendData( 35 | device: HIDDevice, 36 | reportId: number, 37 | data: Uint8Array 38 | ): Promise { 39 | try { 40 | await device.sendReport(reportId, data); 41 | console.log("Data sent to HID device:", data); 42 | return true; 43 | } catch (error) { 44 | console.error("Error sending data to HID device:", error); 45 | return false; 46 | } 47 | } 48 | 49 | // 发送 Feature Report 到 HID 设备 50 | static async sendFeatureReport( 51 | device: HIDDevice, 52 | reportId: number, 53 | data: Uint8Array 54 | ): Promise { 55 | try { 56 | await device.sendFeatureReport(reportId, data); 57 | console.log("Feature report sent to HID device:", data); 58 | return true; 59 | } catch (error) { 60 | console.error("Error sending feature report to HID device:", error); 61 | return false; 62 | } 63 | } 64 | 65 | // 监听 Input Report 66 | static listenInputReport( 67 | device: HIDDevice, 68 | callback: (event: HIDInputReportEvent) => void 69 | ): void { 70 | const listener = (event: HIDInputReportEvent) => { 71 | console.log("Received input report:", event); 72 | callback(event); 73 | }; 74 | device.addEventListener("inputreport", listener); 75 | console.log("Input report listener added."); 76 | } 77 | 78 | // 关闭 HID 设备 79 | static async closeDevice(device: HIDDevice): Promise { 80 | try { 81 | await device.close(); 82 | console.log("HID device closed successfully."); 83 | return true; 84 | } catch (error) { 85 | console.error("Error closing HID device:", error); 86 | return false; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/utils/deviceConstants.ts: -------------------------------------------------------------------------------- 1 | import { KeyboardType } from "@/types"; 2 | 3 | export const KEYBOARD_FILTER: HIDDeviceFilter = { 4 | vendorId: 0x1209, 5 | productId: 0xc55d, 6 | }; 7 | 8 | export const REPORT_ID_SEND = 4; // 发送数据的报告 ID 9 | export const REPORT_ID_RECEIVE = 5; // 接收数据的报告 ID 10 | 11 | export const CMD_KEYBOARD_ACK = 0x01; // 键盘确认(ACK) 12 | export const CMD_KEYBOARD_SEND = 0x02; // 键盘发送数据 13 | 14 | export const CMD_HOST_REQUEST = 0x03; // 主机请求数据 15 | export const CMD_HOST_SEND = 0x04; // 主机发送数据 16 | 17 | // export const BASIC_KEY_COUNT = 4; // 基础键盘可配置按键数量 18 | // export const KNOB_KEY_COUNT = 7; // 旋钮键盘可配置按键数量 19 | // export const FIVE_KEY_COUNT = 5; // 五键键盘可配置按键数量 20 | 21 | export const KeyboardKeyCount = { 22 | [KeyboardType.BASIC]: 4, 23 | [KeyboardType.KNOB]: 7, 24 | [KeyboardType.FIVE_KEYS]: 5, 25 | }; 26 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/utils/hidConverters/keyMappingConverter.ts: -------------------------------------------------------------------------------- 1 | import { type KeyMapping } from "@/types"; 2 | 3 | import { 4 | keyboardConfigToRawHID, 5 | rawHIDToKeyboardConfig, 6 | } from "./keyboardHIDConverter"; 7 | 8 | /** 9 | * 将包含 8 个键、每键 3 字节数据的 Uint8Array 解析为 KeyMapping 数组 10 | * @param data Uint8Array 数据,长度必须为 24 字节 11 | * @returns KeyMapping 数组,共 8 个元素 12 | */ 13 | export function parseKeyMappingsFromUint8Array(data: Uint8Array): KeyMapping[] { 14 | if (data.length !== 24) { 15 | throw new Error("数据长度错误,期望 24 个字节"); 16 | } 17 | const mappings: KeyMapping[] = []; 18 | for (let i = 0; i < 8; i++) { 19 | const offset = i * 3; 20 | const type = data[offset]; 21 | const byte2 = data[offset + 1]; 22 | const byte3 = data[offset + 2]; 23 | if (type === 0x01) { 24 | // 键盘:第二字节为修饰符,第三字节为按键 25 | const KeyboardConfig = rawHIDToKeyboardConfig({ 26 | modifier: byte2, 27 | hid: byte3, 28 | }); 29 | mappings.push({ type: 0x01, value: KeyboardConfig }); 30 | } else if (type === 0x02) { 31 | // 媒体:将第二、第三字节组合成一个 16 位数字(高位在前) 32 | const mediaData = (byte2 << 8) | byte3; 33 | const MediaConfig = { key: mediaData }; 34 | 35 | mappings.push({ type: 0x02, value: MediaConfig }); 36 | } else if (type === 0x03) { 37 | // 鼠标:第二字节为滚轮数据(int8有符号),第三字节为鼠标数据 38 | const wheel = new Int8Array([byte2])[0]; // 将 byte2 转换为有符号的 int8 39 | const MouseConfig = { button: byte3, wheel }; 40 | mappings.push({ type: 0x03, value: MouseConfig }); 41 | } else { 42 | console.warn(`未知的按键类型, 初始化为键盘类型`); 43 | mappings.push({ 44 | type: 0x01, 45 | value: { 46 | key: "", 47 | code: "KeyA", 48 | leftMetaKey: false, 49 | leftCtrlKey: false, 50 | leftAltKey: false, 51 | leftShiftKey: false, 52 | rightMetaKey: false, 53 | rightCtrlKey: false, 54 | rightAltKey: false, 55 | rightShiftKey: false, 56 | }, 57 | }); 58 | } 59 | } 60 | return mappings; 61 | } 62 | 63 | /** 64 | * 将 KeyMapping 数组转换为 Uint8Array 数据 65 | * @param mappings 包含 8 个 KeyMapping 的数组 66 | * @returns Uint8Array 数据,共 24 字节 67 | */ 68 | export function convertKeyMappingsToUint8Array( 69 | mappings: KeyMapping[] 70 | ): Uint8Array { 71 | if (mappings.length !== 8) { 72 | throw new Error("按键映射数组必须包含 8 个键"); 73 | } 74 | const data = new Uint8Array(24); 75 | for (let i = 0; i < mappings.length; i++) { 76 | const offset = i * 3; 77 | const mapping = mappings[i]; 78 | data[offset] = mapping.type; 79 | if (mapping.type === 0x01) { 80 | const rawHid = keyboardConfigToRawHID(mapping.value); 81 | data[offset + 1] = rawHid.modifier; 82 | data[offset + 2] = rawHid.hid; 83 | } else if (mapping.type === 0x02) { 84 | data[offset + 1] = mapping.value.key >> 8; // 高字节 85 | data[offset + 2] = mapping.value.key & 0xff; // 低字节 86 | } else if (mapping.type === 0x03) { 87 | const wheel = mapping.value.wheel; 88 | data[offset + 1] = new Int8Array([wheel])[0]; 89 | data[offset + 2] = mapping.value.button; 90 | } else { 91 | data[offset] = 0x01; 92 | data[offset + 1] = 0; 93 | data[offset + 2] = 0; 94 | console.warn(`未知的按键类型, 初始化为键盘类型`); 95 | } 96 | } 97 | return data; 98 | } 99 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/utils/hidConverters/keyboardHIDConverter.ts: -------------------------------------------------------------------------------- 1 | import type { KeyboardConfig, KeyBoardRawHIDData } from "@/types"; 2 | import { KeyboardKeyModifier } from "@/types"; 3 | 4 | /** 完整的 HID 映射表,将 event.code 映射为 HID 键码(8位数字) */ 5 | export const HID_KEY_MAP: Record = { 6 | // 错误及保留项 7 | ErrorRollOver: 0x01, 8 | POSTFail: 0x02, 9 | ErrorUndefined: 0x03, 10 | // 字母 A-Z 11 | KeyA: 0x04, 12 | KeyB: 0x05, 13 | KeyC: 0x06, 14 | KeyD: 0x07, 15 | KeyE: 0x08, 16 | KeyF: 0x09, 17 | KeyG: 0x0a, 18 | KeyH: 0x0b, 19 | KeyI: 0x0c, 20 | KeyJ: 0x0d, 21 | KeyK: 0x0e, 22 | KeyL: 0x0f, 23 | KeyM: 0x10, 24 | KeyN: 0x11, 25 | KeyO: 0x12, 26 | KeyP: 0x13, 27 | KeyQ: 0x14, 28 | KeyR: 0x15, 29 | KeyS: 0x16, 30 | KeyT: 0x17, 31 | KeyU: 0x18, 32 | KeyV: 0x19, 33 | KeyW: 0x1a, 34 | KeyX: 0x1b, 35 | KeyY: 0x1c, 36 | KeyZ: 0x1d, 37 | // 数字(主键盘部分) 38 | Digit1: 0x1e, 39 | Digit2: 0x1f, 40 | Digit3: 0x20, 41 | Digit4: 0x21, 42 | Digit5: 0x22, 43 | Digit6: 0x23, 44 | Digit7: 0x24, 45 | Digit8: 0x25, 46 | Digit9: 0x26, 47 | Digit0: 0x27, 48 | // 控制键及标点符号 49 | Enter: 0x28, 50 | Escape: 0x29, 51 | Backspace: 0x2a, 52 | Tab: 0x2b, 53 | Space: 0x2c, 54 | Minus: 0x2d, 55 | Equal: 0x2e, 56 | BracketLeft: 0x2f, 57 | BracketRight: 0x30, 58 | Backslash: 0x31, 59 | NonUSHash: 0x32, 60 | Semicolon: 0x33, 61 | Quote: 0x34, 62 | Backquote: 0x35, 63 | Comma: 0x36, 64 | Period: 0x37, 65 | Slash: 0x38, 66 | CapsLock: 0x39, 67 | // 功能键 F1-F12 68 | F1: 0x3a, 69 | F2: 0x3b, 70 | F3: 0x3c, 71 | F4: 0x3d, 72 | F5: 0x3e, 73 | F6: 0x3f, 74 | F7: 0x40, 75 | F8: 0x41, 76 | F9: 0x42, 77 | F10: 0x43, 78 | F11: 0x44, 79 | F12: 0x45, 80 | // 系统及导航键 81 | PrintScreen: 0x46, 82 | ScrollLock: 0x47, 83 | Pause: 0x48, 84 | Insert: 0x49, 85 | Home: 0x4a, 86 | PageUp: 0x4b, 87 | Delete: 0x4c, 88 | End: 0x4d, 89 | PageDown: 0x4e, 90 | ArrowRight: 0x4f, 91 | ArrowLeft: 0x50, 92 | ArrowDown: 0x51, 93 | ArrowUp: 0x52, 94 | // 数字键盘区 95 | NumLock: 0x53, 96 | KeypadDivide: 0x54, 97 | KeypadMultiply: 0x55, 98 | KeypadSubtract: 0x56, 99 | KeypadAdd: 0x57, 100 | KeypadEnter: 0x58, 101 | Keypad1: 0x59, 102 | Keypad2: 0x5a, 103 | Keypad3: 0x5b, 104 | Keypad4: 0x5c, 105 | Keypad5: 0x5d, 106 | Keypad6: 0x5e, 107 | Keypad7: 0x5f, 108 | Keypad8: 0x60, 109 | Keypad9: 0x61, 110 | Keypad0: 0x62, 111 | KeypadDecimal: 0x63, 112 | // 国际化及扩展键 113 | IntlBackslash: 0x64, 114 | ContextMenu: 0x65, 115 | Power: 0x66, 116 | KeypadEqual: 0x67, 117 | F13: 0x68, 118 | F14: 0x69, 119 | F15: 0x6a, 120 | F16: 0x6b, 121 | F17: 0x6c, 122 | F18: 0x6d, 123 | F19: 0x6e, 124 | F20: 0x6f, 125 | F21: 0x70, 126 | F22: 0x71, 127 | F23: 0x72, 128 | F24: 0x73, 129 | Open: 0x74, 130 | Help: 0x75, 131 | Select: 0x76, 132 | Again: 0x77, 133 | Undo: 0x78, 134 | Cut: 0x79, 135 | Copy: 0x7a, 136 | Paste: 0x7b, 137 | Find: 0x7c, 138 | AudioVolumeMute: 0x7f, 139 | AudioVolumeUp: 0x80, 140 | AudioVolumeDown: 0x81, 141 | LockingCapsLock: 0x82, 142 | LockingNumLock: 0x83, 143 | LockingScrollLock: 0x84, 144 | KeypadComma: 0x85, 145 | KeypadEqualSign: 0x86, 146 | International1: 0x87, 147 | International2: 0x88, 148 | International3: 0x89, 149 | International4: 0x8a, 150 | International5: 0x8b, 151 | International6: 0x8c, 152 | International7: 0x8d, 153 | International8: 0x8e, 154 | International9: 0x8f, 155 | Lang1: 0x90, 156 | Lang2: 0x91, 157 | Lang3: 0x92, 158 | Lang4: 0x93, 159 | Lang5: 0x94, 160 | Lang6: 0x95, 161 | Lang7: 0x96, 162 | Lang8: 0x97, 163 | Lang9: 0x98, 164 | AlternateErase: 0x99, 165 | "SysReq/Attention": 0x9a, 166 | Cancel: 0x9b, 167 | Clear: 0x9c, 168 | Prior: 0x9d, 169 | Return: 0x9e, 170 | Separator: 0x9f, 171 | Out: 0xa0, 172 | Oper: 0xa1, 173 | "Clear/Again": 0xa2, 174 | "CrSel/Props": 0xa3, 175 | ExSel: 0xa4, 176 | // 修饰键(包含在内,但一般单独处理) 177 | ControlLeft: 0xe0, 178 | ShiftLeft: 0xe1, 179 | AltLeft: 0xe2, 180 | MetaLeft: 0xe3, 181 | ControlRight: 0xe4, 182 | ShiftRight: 0xe5, 183 | AltRight: 0xe6, 184 | MetaRight: 0xe7, 185 | }; 186 | 187 | /** 生成 HID 的反向映射表,从 HID 数值到 event.code 字符串 */ 188 | const REVERSE_HID_KEY_MAP: Record = {}; 189 | for (const code in HID_KEY_MAP) { 190 | const value = HID_KEY_MAP[code]; 191 | REVERSE_HID_KEY_MAP[value] = code; 192 | } 193 | 194 | /** 195 | * 将 KeyboardConfig 转换为 RawHIDData(包含修饰键和主键 HID 码) 196 | * @param config KeyboardConfig 对象 197 | * @returns RawHIDData 对象,其中 modifier 为修饰键编码(uint8),hid 为主键的 HID 数值 198 | */ 199 | export function keyboardConfigToRawHID( 200 | config: KeyboardConfig 201 | ): KeyBoardRawHIDData { 202 | let modifier = 0; 203 | if (config.leftCtrlKey) modifier |= KeyboardKeyModifier.LeftCtrl; 204 | if (config.leftShiftKey) modifier |= KeyboardKeyModifier.LeftShift; 205 | if (config.leftAltKey) modifier |= KeyboardKeyModifier.LeftAlt; 206 | if (config.leftMetaKey) modifier |= KeyboardKeyModifier.LeftMeta; 207 | if (config.rightCtrlKey) modifier |= KeyboardKeyModifier.RightCtrl; 208 | if (config.rightShiftKey) modifier |= KeyboardKeyModifier.RightShift; 209 | if (config.rightAltKey) modifier |= KeyboardKeyModifier.RightAlt; 210 | if (config.rightMetaKey) modifier |= KeyboardKeyModifier.RightMeta; 211 | 212 | const hid = HID_KEY_MAP[config.code] || 0; 213 | return { modifier, hid }; 214 | } 215 | 216 | /** 217 | * 将 RawHIDData 转换为 KeyboardConfig 对象 218 | * 由于 HID 数据无法还原出原始按键字符,故 key 字段置为空字符串 219 | * @param raw RawHIDData 对象 220 | * @returns KeyboardConfig 对象,其中 code 根据反向映射表还原,key 为空 221 | */ 222 | export function rawHIDToKeyboardConfig( 223 | raw: KeyBoardRawHIDData 224 | ): KeyboardConfig { 225 | const code = REVERSE_HID_KEY_MAP[raw.hid] || ""; 226 | return { 227 | key: "", 228 | code, 229 | leftCtrlKey: !!(raw.modifier & KeyboardKeyModifier.LeftCtrl), 230 | leftShiftKey: !!(raw.modifier & KeyboardKeyModifier.LeftShift), 231 | leftAltKey: !!(raw.modifier & KeyboardKeyModifier.LeftAlt), 232 | leftMetaKey: !!(raw.modifier & KeyboardKeyModifier.LeftMeta), 233 | rightCtrlKey: !!(raw.modifier & KeyboardKeyModifier.RightCtrl), 234 | rightShiftKey: !!(raw.modifier & KeyboardKeyModifier.RightShift), 235 | rightAltKey: !!(raw.modifier & KeyboardKeyModifier.RightAlt), 236 | rightMetaKey: !!(raw.modifier & KeyboardKeyModifier.RightMeta), 237 | }; 238 | } 239 | 240 | /** 241 | * 将 KeyboardConfig 的修饰键部分转换为 8 位修饰键编码 (uint8) 242 | * @param config KeyboardConfig 对象 243 | * @returns 8 位修饰键编码 244 | */ 245 | export function keyboardConfigToKeyboardKeyModifier( 246 | config: KeyboardConfig 247 | ): number { 248 | let modifier = 0; 249 | if (config.leftCtrlKey) modifier |= KeyboardKeyModifier.LeftCtrl; 250 | if (config.leftShiftKey) modifier |= KeyboardKeyModifier.LeftShift; 251 | if (config.leftAltKey) modifier |= KeyboardKeyModifier.LeftAlt; 252 | if (config.leftMetaKey) modifier |= KeyboardKeyModifier.LeftMeta; 253 | if (config.rightCtrlKey) modifier |= KeyboardKeyModifier.RightCtrl; 254 | if (config.rightShiftKey) modifier |= KeyboardKeyModifier.RightShift; 255 | if (config.rightAltKey) modifier |= KeyboardKeyModifier.RightAlt; 256 | if (config.rightMetaKey) modifier |= KeyboardKeyModifier.RightMeta; 257 | return modifier; 258 | } 259 | 260 | /** 261 | * 将 8 位修饰键编码转换为 KeyboardConfig 部分(仅包含修饰键布尔值) 262 | * @param modifier 8 位修饰键编码 (uint8) 263 | * @returns 包含修饰键状态的 KeyboardConfig 部分 264 | */ 265 | export function modifierToKeyboardConfig( 266 | modifier: number 267 | ): Partial { 268 | return { 269 | leftCtrlKey: !!(modifier & KeyboardKeyModifier.LeftCtrl), 270 | leftShiftKey: !!(modifier & KeyboardKeyModifier.LeftShift), 271 | leftAltKey: !!(modifier & KeyboardKeyModifier.LeftAlt), 272 | leftMetaKey: !!(modifier & KeyboardKeyModifier.LeftMeta), 273 | rightCtrlKey: !!(modifier & KeyboardKeyModifier.RightCtrl), 274 | rightShiftKey: !!(modifier & KeyboardKeyModifier.RightShift), 275 | rightAltKey: !!(modifier & KeyboardKeyModifier.RightAlt), 276 | rightMetaKey: !!(modifier & KeyboardKeyModifier.RightMeta), 277 | }; 278 | } 279 | 280 | export const getKeyNameCombination = (keyConfig: KeyboardConfig) => { 281 | const keys = new Set(); // 使用 Set 自动去重 282 | let leftModifierKeysValue = new Set(); 283 | let rightModifierKeysValue = new Set(); 284 | 285 | if (keyConfig.leftCtrlKey) leftModifierKeysValue.add("Ctrl"); 286 | if (keyConfig.leftShiftKey) leftModifierKeysValue.add("Shift"); 287 | if (keyConfig.leftAltKey) leftModifierKeysValue.add("Alt"); 288 | if (keyConfig.leftMetaKey) leftModifierKeysValue.add("Meta"); 289 | if (keyConfig.rightCtrlKey) rightModifierKeysValue.add("Ctrl"); 290 | if (keyConfig.rightShiftKey) rightModifierKeysValue.add("Shift"); 291 | if (keyConfig.rightAltKey) rightModifierKeysValue.add("Alt"); 292 | if (keyConfig.rightMetaKey) rightModifierKeysValue.add("Meta"); 293 | 294 | leftModifierKeysValue.forEach((key) => keys.add(`L${key}`)); 295 | rightModifierKeysValue.forEach((key) => keys.add(`R${key}`)); 296 | 297 | if (keyConfig.code) { 298 | keys.add(keyConfig.code); // 加入主按键 299 | } 300 | return Array.from(keys).join(" + "); 301 | }; 302 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/utils/hidConverters/mediaHIDConverter.ts: -------------------------------------------------------------------------------- 1 | import { MediaHIDCode } from "@/types"; 2 | 3 | // 说明映射 4 | export const mediaDescriptions: Record = { 5 | [MediaHIDCode.None]: "无", 6 | [MediaHIDCode.Play]: "播放", 7 | [MediaHIDCode.Pause]: "暂停", 8 | [MediaHIDCode.PlayPause]: "播放/暂停", 9 | [MediaHIDCode.Stop]: "停止", 10 | [MediaHIDCode.NextTrack]: "下一曲", 11 | [MediaHIDCode.PrevTrack]: "上一曲", 12 | [MediaHIDCode.FastForward]: "快进", 13 | [MediaHIDCode.Rewind]: "倒带", 14 | [MediaHIDCode.Mute]: "静音", 15 | [MediaHIDCode.VolumeUp]: "音量增加", 16 | [MediaHIDCode.VolumeDown]: "音量减少", 17 | [MediaHIDCode.ChannelUp]: "频道增加", 18 | [MediaHIDCode.ChannelDown]: "频道减少", 19 | [MediaHIDCode.Power]: "设备电源", 20 | [MediaHIDCode.Sleep]: "休眠", 21 | [MediaHIDCode.WakeUp]: "唤醒", 22 | [MediaHIDCode.Menu]: "进入菜单", 23 | [MediaHIDCode.Home]: "主页", 24 | [MediaHIDCode.Back]: "返回", 25 | [MediaHIDCode.Exit]: "退出", 26 | [MediaHIDCode.Select]: "确认/选择", 27 | [MediaHIDCode.Up]: "向上", 28 | [MediaHIDCode.Down]: "向下", 29 | [MediaHIDCode.Left]: "向左", 30 | [MediaHIDCode.Right]: "向右", 31 | [MediaHIDCode.Calculator]: "计算器", 32 | [MediaHIDCode.FileExplorer]: "文件资源管理器", 33 | [MediaHIDCode.BrowserForward]: "浏览器前进", 34 | [MediaHIDCode.BrowserRefresh]: "浏览器刷新", 35 | [MediaHIDCode.BrowserFavorites]: "浏览器收藏夹", 36 | [MediaHIDCode.Email]: "电子邮件应用", 37 | }; 38 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/utils/hidConverters/mouseHIDConverter.ts: -------------------------------------------------------------------------------- 1 | import type { MouseConfig } from "@/types"; 2 | 3 | export const getMouseConfigString = (config: MouseConfig): string => { 4 | const { button, wheel } = config; 5 | 6 | // 按位解析鼠标按键是否按下 7 | const buttonDescriptions = [ 8 | (button & 0b0001) !== 0 ? "左键" : "", 9 | (button & 0b0010) !== 0 ? "右键" : "", 10 | (button & 0b0100) !== 0 ? "中键" : "", 11 | (button & 0b1000) !== 0 ? "后退" : "", 12 | (button & 0b10000) !== 0 ? "前进" : "", 13 | ].filter(Boolean); // 过滤掉空字符串 14 | 15 | // 如果滚轮值不为 0,则添加滚轮信息 16 | if (wheel !== 0) { 17 | buttonDescriptions.push(`滚轮: ${wheel}`); 18 | } 19 | 20 | // 将按键描述数组用 " + " 连接成字符串 21 | return buttonDescriptions.join(" + "); 22 | }; 23 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/utils/keyboardHidTools.ts: -------------------------------------------------------------------------------- 1 | import { WebHidTools } from "./WebHidTools"; 2 | 3 | // 发送请求键盘数据(Report ID 5) 4 | export const sendInitData = async (device: HIDDevice, reportId: number = 5) => { 5 | if (!device) throw new Error("设备未连接"); 6 | // 构造数据包:31字节,第二位为0x01 7 | const data = new Uint8Array(31); 8 | data[0] = 0x01; 9 | const success = await WebHidTools.sendData(device, reportId, data); 10 | if (!success) { 11 | throw new Error("初始化数据发送失败"); 12 | } 13 | }; 14 | 15 | export const sendData = async ( 16 | device: HIDDevice, 17 | reportId: number, 18 | data: Uint8Array 19 | ) => { 20 | if (!device) throw new Error("设备未连接"); 21 | const success = await WebHidTools.sendData(device, reportId, data); 22 | if (!success) { 23 | throw new Error("数据发送失败"); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/widgets/buttons/KnobButton.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 33 | 34 | 90 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/widgets/buttons/NormalButton.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 27 | 28 | 56 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/widgets/selector/KeyboardSelector.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/widgets/selector/MediaSelector.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/widgets/selector/MouseSelector.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 74 | 75 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/src/widgets/selector/Selector.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 156 | 171 | 172 | 182 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 7 | 8 | "paths": { 9 | "@/*": ["./src/*"] 10 | 11 | }, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node22/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*", 9 | "eslint.config.*" 10 | ], 11 | "compilerOptions": { 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"], 18 | "lib": ["ESNext", "DOM"] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /UI/binary-keyboard-studio-ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from "node:url"; 2 | 3 | import { defineConfig } from "vite"; 4 | import vue from "@vitejs/plugin-vue"; 5 | import vueDevTools from "vite-plugin-vue-devtools"; 6 | import Components from "unplugin-vue-components/vite"; 7 | import { PrimeVueResolver } from "@primevue/auto-import-resolver"; 8 | 9 | // https://vite.dev/config/ 10 | export default defineConfig({ 11 | plugins: [ 12 | vue(), 13 | vueDevTools(), 14 | Components({ 15 | resolvers: [PrimeVueResolver()], 16 | }), 17 | ], 18 | resolve: { 19 | alias: { 20 | "@": fileURLToPath(new URL("./src", import.meta.url)), 21 | }, 22 | }, 23 | }); 24 | --------------------------------------------------------------------------------