USB Composite Device Demo (Keyboard, Custom HID and Massive Storage) using CH55x
This demo emulates a USB composite device, which has 3 interface available (????ʾ????ģ????һ??????3???ӿڵ?USB?豸):
Author(????): Rikka0w0 (С????)
keilc51\CH554.H
, Delay.C
and Delay.h
comes from official CH554 demo (WCH), the USB MSD implementation is inspired by the USB MSD demo for STM32 (ST).
(keilc51\CH554.H
, Delay.C
??Delay.h
?Ǵ?WCH?ٷ???ʾ??????????ȡ?ģ?U?̲??ֳ???ο???STM32??USB MSDʾ??)includes
comes from Github repository Blinkinlabs's ch554_sdcc.
(includes
?ļ????е??ļ??Ǵ?Blinkinlabs's ch554_sdcc?︴?Ƶ?)BadApple.zip contains a funny demo which can play the BadApple video on a SDD1306 128x64 OLED screen, the OLED screen is controlled via I2C,
check out I2c.c
for details about hardware configuration. (BadApple.zip????һ????Ȥ????ʾ????????SDD1306 128x64 OLED??Ļ?ϲ???BadApple??Ƶ??OLED??Ļͨ??I2C???ƣ???I2c.c
?а????????????Ļ????Ϣ)
i2c.c
, each pin is pull-up by a 1k resistor to 5V.
(I2C???Ŷ?????i2c.c
???棬ÿ???Ŷ?Ҫһ??1k?????????裬??????5V)U16B0
returns the lowest byte of a 16-bit integer, regardless of endian, similar defination for U16B1
, U32B0
e.t.c
(U16B0
?᷵??һ??16λ?????ĵ??ֽڣ?????أ?U16B1
, U32B0
??Ҳ?????ƹ???)U16_XBig
converts a big-endian 16-bit integer to fit the local endian, vise versa, similar defination for U16_XLittle
, U32_XBig
and U32_XLittle
.
(U16_XBig
???ڽ?һ????˴????16λ??ת???ɵ?ǰ?Ķ˷?ʽ??Ҳ???????ڷ???ת????U16_XLittle
, U32_XBig
??U32_XLittle
??????????)sbit led=P1^1
, use SBIT(var, port, bin)
to declare a bit variable, for example, SBIT(led, GPIO1, 1)
, this facilitates compilation under different compilers.
(?????SBIT(var, port, bin)
??????λ??????????SBIT(led, GPIO1, 1)
??????sbit led=P1^1
?????????????ڲ?ͬ???????±??????)I2C_DELAY(void)
controls the I2C clock frequencyI2C_WriteByte()
sends the data byte in I2C_Buf
to I2C bus and return the ACK status in bit 0 of I2C_Buf
then release the I2C bus,
0 means ACK and 1 means NACK.
(I2C_WriteByte()
???I2C_Buf
???һ???ֽڷ??͵?I2C?????ϲ???I2C_Buf
?????λ????ACK??״̬Ȼ???ͷ?I2C???ߣ?0ΪACK??1ΪNACK)I2C_ReadByte(void)
reads a byte from I2C bus and store it in I2C_Buf
.
(I2C_ReadByte(void)
??I2C?????϶?һ???ֽ?Ȼ?????I2C_Buf
????)USB_EP_HALT_SET(ep)
and USB_EP_HALT_CLEAR(ep)
stall or restore an EndPoint as the host requests
(USB_EP_HALT_SET(ep)
??USB_EP_HALT_CLEAR(ep)
???????????????stall???ָ??˵?)USB_Keyboard_SendKey()
sends a key combination to the host, the first parameter specifies the modifier, e.g. KBD_LCTRL for left control, combination is supported,
the second parameter determines which key is pressed, e.g. 0x04 for letter a on keyboard. Check out HID protocol for details.
(USB_Keyboard_SendKey()
??????????һ????????ϣ???һ???????????????η???????KBD_LCTRL??????CTRL????????֧????ϡ??ڶ????????????????ĸ???????????0x04??Ӧ?ż????ϵ?A??????????????HIDЭ??????)// BOT_USB Config
(ת???˵?Ļ???Ķ??壬????BOT?㣬?μ?// BOT_USB Config
?????Dz???)CBW_Decode
translates USB packets to SCSI instructions (CBW_Decode
??USB??????ΪSCSIָ??)Transfer_Data_Request
sends some data to host as reply (Transfer_Data_Request
??????????һЩ??????Ϊ?ظ?)Reply_Request
sends the content stored in BOT_Tx_Buf
to host as reply (Reply_Request
??BOT_Tx_Buf
???????????????????Ϊ?ظ?)Transfer_Failed_ReadWrite
sends a empty packet to host and the device will send its CSW in the next transaction
(Transfer_Failed_ReadWrite
??????????һ???հ???????һ????????????CSW״̬)Set_CSW
sets the CSW status, by set Send_Permission
to 1, it will send CSW immediately.
(Set_CSW
????????CSW״̬????Send_Permission
??Ϊ1?????̷???CSW)// SCSI R/W state machine
(??д????һ??״̬?????Ƶģ??μ?// SCSI R/W state machine
)usb_mal.h
(ʵ????????usb_mal.h?ﶨ??ĺ???)Inquiry Data
(????Inquiry Data
??????????????Ʒ??֮???)OLDE
(OLED?ļ????е??ļ?)sdd1306.h
and sdd1306.c
provides functions to initialize SDD1306-based OLED screen and chunk programming the display pattern.
(sdd1306.h
??sdd1306.c
?ṩ?˻???SDD1306??OLED??Ļ?ij?ʼ???Ϳ?????ʾģʽ?Ĺ???)sdd1306_ascii.h
and sdd1306_ascii.c
provides functions to display ASCII characters on OLED screen.
(ssd1306 ascii.h
??ssd1306 ascii.c
?ṩ??OLED??Ļ????ʾASCII?ַ??Ĺ???)LUN_Write
and Lun_Read
in usb_mal.c
.
(?????I2C??EEPROM?DZ???ģ?û?????豸???????ö?٣????????????usb_mal.c
ע?͵?LUN_Write
?? Lun_Read
????Ķ?д????)void main(void)
,
otherwise SDCC can not find them. According to official SDCC documentation, it's not a bug but a feature. Keil C51 doesn't have this limitaion.
(SDCCҪ???жϴ????????????main????????һ??.c?ļ??У?????SDCCû?취?ҵ???Щ??????????SDCC?ٷ??ĵ???????һ?????Բ???Bug??Keil C51??????û??????????)