Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5de9c67271 | ||
|
|
e6122b1845 | ||
|
|
81b5955a5c | ||
|
|
03496cb28e | ||
|
|
2d8a534f14 |
@@ -17,7 +17,7 @@ This code implements a [uf2](https://github.com/microsoft/uf2) bootloader for RI
|
|||||||
- Runs off of internal 8 MHz oscillator (despite stability concerns)
|
- Runs off of internal 8 MHz oscillator (despite stability concerns)
|
||||||
- The HSI oscillator's tolerance (-1.0% to +1.6%) is well outside of the range specified for USB full speed ($\pm$ 0.25%), but it seems to work in practice n=1 ¯\\\_(ツ)\_/¯
|
- The HSI oscillator's tolerance (-1.0% to +1.6%) is well outside of the range specified for USB full speed ($\pm$ 0.25%), but it seems to work in practice n=1 ¯\\\_(ツ)\_/¯
|
||||||
- The vendor's ISP ROM bootloader also does this
|
- The vendor's ISP ROM bootloader also does this
|
||||||
- Should work across most of the CH32V2xx and CH32V3xx family with appropriate changes to hardcoded constants.
|
- Should work across CH32V2xx family with appropriate changes to hardcoded constants. Does *not* support CH32V3xx (which doesn't have USBD).
|
||||||
- Allows both download to flash and to SRAM with the "not main flash" flag (this is how the RP2040 bootrom works)
|
- Allows both download to flash and to SRAM with the "not main flash" flag (this is how the RP2040 bootrom works)
|
||||||
- Flash download address must be 08xxxxxx (i.e. not starting at 0)
|
- Flash download address must be 08xxxxxx (i.e. not starting at 0)
|
||||||
- SRAM download address must be 20xxxxxx
|
- SRAM download address must be 20xxxxxx
|
||||||
|
|||||||
+5
-3
@@ -468,10 +468,10 @@ __attribute__((naked)) int main(void) {
|
|||||||
R16_USBD_CNTR = 1;
|
R16_USBD_CNTR = 1;
|
||||||
USB_DESCS[0].addr_tx = 0x30 / 2;
|
USB_DESCS[0].addr_tx = 0x30 / 2;
|
||||||
USB_DESCS[0].addr_rx = 0x20 / 2;
|
USB_DESCS[0].addr_rx = 0x20 / 2;
|
||||||
USB_DESCS[0].count_rx = (8 << 10);
|
USB_DESCS[0].count_rx = ((8 / 2) << 10);
|
||||||
USB_DESCS[1].addr_tx = 0xc0 / 2;
|
USB_DESCS[1].addr_tx = 0xc0 / 2;
|
||||||
USB_DESCS[1].addr_rx = 0x40 / 2;
|
USB_DESCS[1].addr_rx = 0x40 / 2;
|
||||||
USB_DESCS[1].count_rx = (2 << 10) | (1 << 15);
|
USB_DESCS[1].count_rx = (1 << 10) | (1 << 15);
|
||||||
// XXX because the table is at offset 0 don't bother writing this
|
// XXX because the table is at offset 0 don't bother writing this
|
||||||
|
|
||||||
// Attach USB
|
// Attach USB
|
||||||
@@ -995,8 +995,10 @@ __attribute__((naked)) int main(void) {
|
|||||||
while (!(STK_SR & 1)) {}
|
while (!(STK_SR & 1)) {}
|
||||||
STK_CTLR = 0;
|
STK_CTLR = 0;
|
||||||
STK_SR = 0;
|
STK_SR = 0;
|
||||||
R16_USBD_CNTR = 0b11;
|
|
||||||
R32_EXTEN_CTR &= ~(1 << 1);
|
R32_EXTEN_CTR &= ~(1 << 1);
|
||||||
|
R16_USBD_CNTR = 1;
|
||||||
|
R16_USBD_ISTR = 0;
|
||||||
|
R16_USBD_CNTR = 0b11;
|
||||||
if (ADDRESS_HI >> 8 == 0x20) {
|
if (ADDRESS_HI >> 8 == 0x20) {
|
||||||
// ram boot, go back to original clock settings
|
// ram boot, go back to original clock settings
|
||||||
R32_RCC_CFGR0 = (R32_RCC_CFGR0 & ~0b11) | 0b00;
|
R32_RCC_CFGR0 = (R32_RCC_CFGR0 & ~0b11) | 0b00;
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
enum USB_bDescriptorType {
|
||||||
|
DESCRIPTOR_DEVICE = 0x1,
|
||||||
|
DESCRIPTOR_CONFIGURATION = 0x2,
|
||||||
|
DESCRIPTOR_CONFIGURATION = 0x4,
|
||||||
|
DESCRIPTOR_ENDPOINT = 0x5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum USB_Type_BCD {
|
||||||
|
USB20 = 0x0200,
|
||||||
|
USB11 = 0x0110,
|
||||||
|
USB10 = 0x0100
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum USB_PID {
|
||||||
|
// Token Packets
|
||||||
|
OUT_TOKEN = 0b0001,
|
||||||
|
IN_TOKEN = 0b1001,
|
||||||
|
SOF_TOKEN = 0b0101,
|
||||||
|
SETUP_TOKEN = 0b1101,
|
||||||
|
|
||||||
|
// Data Packets
|
||||||
|
DATA0_DATA = 0b0011,
|
||||||
|
DATA1_DATA = 0b1011,
|
||||||
|
DATA2_DATA = 0b0111,
|
||||||
|
MDATA_DATA = 0b1111,
|
||||||
|
|
||||||
|
// Handshake Packets
|
||||||
|
ACK_HANDSHAKE = 0b0010,
|
||||||
|
NAK_HANDSHAKE = 0b1010,
|
||||||
|
STALL_HANDSHAKE = 0b1110,
|
||||||
|
NYET_HANDSHAKE = 0b0110,
|
||||||
|
|
||||||
|
// Special & Other Packets
|
||||||
|
PRE_SPECIAL = 0b1100, // PREamble shares value with ERR
|
||||||
|
ERR_SPECIAL = 0b1100,
|
||||||
|
SPLIT_SPECIAL = 0b1000,
|
||||||
|
PING_SPECIAL = 0b0100
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum Configuration_bmAttributes{
|
||||||
|
USB_BUS_POWERED = (1 << 7),
|
||||||
|
SELF_POWERED = (1 << 6),
|
||||||
|
REMOTE_WAKEUP = (1 << 5),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum Endpoint_bmAttributes {
|
||||||
|
// Bits 1..0: Transfer Type
|
||||||
|
TRANSFER_TYPE_MASK = 0b00000011,
|
||||||
|
TRANSFER_CONTROL = 0b00000000,
|
||||||
|
TRANSFER_ISOCHRONOUS = 0b00000001,
|
||||||
|
TRANSFER_BULK = 0b00000010,
|
||||||
|
TRANSFER_INTERRUPT = 0b00000011,
|
||||||
|
|
||||||
|
// Bits 3..2: Synchronization Type (Isochronous Mode only)
|
||||||
|
SYNC_TYPE_MASK = 0b00001100,
|
||||||
|
SYNC_NOSYNC = (0b00 << 2), // No Synchronization
|
||||||
|
SYNC_ASYNC = (0b01 << 2), // Asynchronous
|
||||||
|
SYNC_ADAPTIVE = (0b10 << 2), // Adaptive
|
||||||
|
SYNC_SYNCHRONOUS = (0b11 << 2), // Synchronous
|
||||||
|
|
||||||
|
// Bits 5..4: Usage Type (Isochronous Mode only)
|
||||||
|
USAGE_TYPE_MASK = 0b00110000,
|
||||||
|
USAGE_DATA = (0b00 << 4), // Data Endpoint
|
||||||
|
USAGE_FEEDBACK = (0b01 << 4), // Feedback Endpoint
|
||||||
|
USAGE_EXPLICIT_FEEDBACK = (0b10 << 4), // Explicit Feedback Data Endpoint
|
||||||
|
USAGE_RESERVED = (0b11 << 4) // Reserved
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Setup_bmRequestType {
|
||||||
|
// Bit 7: Data Phase Transfer Direction
|
||||||
|
DIR_MASK = (1 << 7),
|
||||||
|
HOST_TO_DEVICE = (0 << 7),
|
||||||
|
DEVICE_TO_HOST = (1 << 7),
|
||||||
|
|
||||||
|
// Bits 6..5: Type
|
||||||
|
TYPE_MASK = (0b11 << 5),
|
||||||
|
TYPE_STANDARD = (0b00 << 5),
|
||||||
|
TYPE_CLASS = (0b01 << 5),
|
||||||
|
TYPE_VENDOR = (0b10 << 5),
|
||||||
|
TYPE_RESERVED = (0b11 << 5),
|
||||||
|
|
||||||
|
// Bits 4..0: Recipient
|
||||||
|
RECIPIENT_MASK = 0b11111,
|
||||||
|
RECIPIENT_DEVICE = 0,
|
||||||
|
RECIPIENT_INTERFACE = 1,
|
||||||
|
RECIPIENT_ENDPOINT = 2,
|
||||||
|
RECIPIENT_OTHER = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum Standard__Device_Requests {
|
||||||
|
GET_STATUS = 0x00,
|
||||||
|
/**
|
||||||
|
* GET_STATUS will reuturn a 16bit word.
|
||||||
|
* D0 is "Self Powered" bit, if D0 == 0, then the device is powered by the bus
|
||||||
|
* D1 is the "Remote Wakeup" bit, if D1 == 1, then the host can wake up this device from suspend
|
||||||
|
*/
|
||||||
|
|
||||||
|
CLEAR_FEATURE = 0x01,
|
||||||
|
SET_FEATURE = 0x03,
|
||||||
|
SET_ADDRESS = 0x05,
|
||||||
|
GET_DESCRIPTOR = 0x06,
|
||||||
|
SET_DESCRIPTOR = 0x07,
|
||||||
|
GET_CONFIGURATION = 0x08,
|
||||||
|
SET_CONFIGURATION = 0x09
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Standard_Interface_Requests {
|
||||||
|
GET_STATUS = 0x00,
|
||||||
|
CLEAR_FEATURE = 0x01,
|
||||||
|
SET_FEATURE = 0x03,
|
||||||
|
GET_INTERFACE = 0x0A,
|
||||||
|
SET_INTERFACE = 0x11,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Standard_Endpoint_Requests {
|
||||||
|
GET_STATUS = 0x00,
|
||||||
|
CLEAR_FEATURE = 0x01,
|
||||||
|
SET_FEATURE = 0x03,
|
||||||
|
/**
|
||||||
|
* Clear Feature and Set Feature are used to set Endpoint Features.
|
||||||
|
* The standard currently defines one endpoint feature selector,
|
||||||
|
* ENDPOINT_HALT (0x00) which allows the host to stall and clear an endpoint.
|
||||||
|
*/
|
||||||
|
SYNCH_FRAME = 0x12,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user