diff options
author | Christian Cunningham <cc@localhost> | 2021-12-23 21:42:32 -0800 |
---|---|---|
committer | Christian Cunningham <cc@localhost> | 2021-12-23 21:42:32 -0800 |
commit | 9bc94963aefcb5028c3529ff59c974e48d814690 (patch) | |
tree | eb90b58da616bce55176b4f8f72a238cce19cd0d /src | |
parent | a905c499ceddc47a5fcd46f863e453919c196722 (diff) |
Intro USB
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/atomic/swap.h | 1 | ||||
-rw-r--r-- | src/cpu/irq.c | 21 | ||||
-rw-r--r-- | src/drivers/usb.c | 55 | ||||
-rw-r--r-- | src/drivers/usb.h | 15 | ||||
-rw-r--r-- | src/graphics/lfb.c | 2 | ||||
-rw-r--r-- | src/sys/core.c | 41 | ||||
-rw-r--r-- | src/sys/core.h | 37 |
7 files changed, 167 insertions, 5 deletions
diff --git a/src/cpu/atomic/swap.h b/src/cpu/atomic/swap.h index 5e8ff57..374dd97 100644 --- a/src/cpu/atomic/swap.h +++ b/src/cpu/atomic/swap.h @@ -6,6 +6,7 @@ /// https://elixir.bootlin.com/linux/v4.9/source/arch/arm/include/asm/spinlock.h /// https://elixir.bootlin.com/linux/v4.9/source/arch/arm/include/asm/spinlock_types.h#L23 /// https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/3_Processes.html +/// https://developer.arm.com/documentation/dht0008/a/arm-synchronization-primitives/practical-uses/implementing-a-semaphore?lang=en static inline void atm_lock(unsigned long pid, unsigned long* addr) { unsigned long tmp, current_lock_value; diff --git a/src/cpu/irq.c b/src/cpu/irq.c index f2b326e..e99b398 100644 --- a/src/cpu/irq.c +++ b/src/cpu/irq.c @@ -1,5 +1,6 @@ #include "../cpu/irq.h" #include "../drivers/uart.h" +#include "../drivers/usb.h" #include "../graphics/drawer.h" #include "../sys/core.h" #include "../sys/timer.h" @@ -92,6 +93,26 @@ void c_irq_handler(void) { enableirq(); return; } + } else if (load32(IRQ_PENDING1) & (1 << 9)) { + unsigned long reg = *USB_CORE_GINTSTS; + *USB_CORE_GINTSTS = reg; //clear + g_Drawer.y = 20; + write_hex32(&g_Drawer, reg); + g_Drawer.x = 0; + g_Drawer.y = 0; + if (reg & 1 << 28) { uart_string("Connector ID Status Change\n"); } + if (reg & 1 << 27) { uart_string("LPM Transaction Received Interrupt\n"); } + if (reg & 1 << 26) { uart_string("Periodic TxFIFO Empty\n"); } + if (reg & 1 << 25) { uart_string("Host Channels Interrupt\n"); + } + if (reg & 1 << 24) { *USB_HOST_HPRT |= 1 << 1; //clear host port interrupt + uart_string("Host Port Interrupt\n"); } + if (reg & 1 << 6) { uart_string("Global IN Non-periodic NAK Effective\n"); } + if (reg & 1 << 5) { uart_string("Non-periodic TxFIFO Empty\n"); } + if (reg & 1 << 4) { uart_string("Host and Device RxFIFO Non-Empty (RxFLvl) \n"); } + if (reg & 1 << 3) { uart_string("Host and Device Start of Frame\n"); } + if (reg & 1 << 2) { uart_string("OTG Interrupt\n"); } + if (reg & 1 << 1) { uart_string("Mode Mismatch Interrupt\n"); } } } else if (source & (1 << 3)) { c_timer(); diff --git a/src/drivers/usb.c b/src/drivers/usb.c new file mode 100644 index 0000000..c6aa02d --- /dev/null +++ b/src/drivers/usb.c @@ -0,0 +1,55 @@ +#include "../drivers/usb.h" +#include "../sys/core.h" + +#define DRIVERS_USB_C +unsigned char usb_buffer0[256] = {0}; +unsigned char usb_buffer1[256] = {0}; + +static struct UsbDeviceRequest udr = { + .Type = 0xA0, // DEVICE_TO_HOST | STDANDAD | DEVICE + .Request = 0x06, // GET_DESCRIPTOR + .Value = 0x0100, // descriptor.type = 0x01, decriptor.index = 0x00 + .Index = 0, + .Length = 64, +}; + +void my_memcpy(void *dest, void *src, unsigned int n) { + char *src_char = (char *)src; + char *dest_char = (char *)dest; + for (unsigned int i=0; i<n; i++) { + dest_char[i] = src_char[i]; + } +} + +static void txrx_control_msg(uint8_t txlen) +{ + // send setup & control packet + // set dma buffer + *USB_HOST_HCDMA0 = (unsigned long long) usb_buffer0; + *USB_HOST_HCDMA0 |= 0xC0000000; + // HCTSIZ0.Pid = 2'd3 (SETUP) , HCTSIZ0.PktCnt = 10'h1 , HCTSIZ0.XferSize = 18'd8 + *USB_HOST_HCTSIZ0 = 3 << 29 | 1 << 19 | txlen; + // HCCAR1.ChEna = 1'b1 + *USB_HOST_HCCHAR0 |= 1<<31; + + // recieve control packet + // set dma buffer + *USB_HOST_HCDMA1 = (unsigned long long) usb_buffer1; + *USB_HOST_HCDMA1 |= 0xC0000000; + // HCTSIZ1.Pid = 2'd2 (DATA1) , HCTSIZ1.PktCnt = 10'h1 , HCTSIZ1.XferSize = 18'd64 + *USB_HOST_HCTSIZ1 = 2 << 29 | 1 << 19 | 64; + // HCCAR1.ChEna = 1'b1 + *USB_HOST_HCCHAR1 |= 1<<31; +} + +void send_packet(void) +{ + // HCCAR1.EPDir = 1'b0 (OUT) / 1'b01(IN), HCCAR1.MPS = 11'h40 + *USB_HOST_HCCHAR0 |= 0x40; // OUT + *USB_HOST_HCCHAR1 |= 1 << 15 | 0x40; // IN + + // build packet + my_memcpy(usb_buffer0, &udr, 8); + + txrx_control_msg(8); +} diff --git a/src/drivers/usb.h b/src/drivers/usb.h new file mode 100644 index 0000000..abe0133 --- /dev/null +++ b/src/drivers/usb.h @@ -0,0 +1,15 @@ +#ifndef DRIVERS_USB_H +#define DRIVERS_USB_H + +#ifndef DRIVERS_USB_C +extern unsigned char usb_buffer0[256]; +extern unsigned char usb_buffer1[256]; +#endif + +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned long + +void send_packet(void); + +#endif diff --git a/src/graphics/lfb.c b/src/graphics/lfb.c index a693135..6aa6012 100644 --- a/src/graphics/lfb.c +++ b/src/graphics/lfb.c @@ -121,7 +121,7 @@ void draw_cletter(unsigned char lx, unsigned char ly, unsigned char letter, unsi unsigned char ltr = letter & 0x7F; for(y=0; y<GLYPH_Y; y++) { for(x=0; x<GLYPH_X; x++) { - if((0b10000000 >> ((GLYPH_X-1)-x)) & glyphs[y+GLYPH_Y*(ltr)]) { + if((0x80 >> ((GLYPH_X-1)-x)) & glyphs[y+GLYPH_Y*(ltr)]) { *((unsigned int*)ptr) = isrgb ? (unsigned int)((c&0xFF)<<16 | (c&0xFF00) | (c&0xFF0000)>>16) : c; } else { *((unsigned int*)ptr) = 0x000000; diff --git a/src/sys/core.c b/src/sys/core.c index ed88570..3f2d117 100644 --- a/src/sys/core.c +++ b/src/sys/core.c @@ -1,5 +1,6 @@ #include "../cpu/irq.h" #include "../drivers/uart.h" +#include "../drivers/usb.h" #include "../graphics/lfb.h" #include "../graphics/drawer.h" #include "../lib/mem.h" @@ -18,14 +19,44 @@ char* os_info_v = VERSION; // Initialize IRQs void sysinit() { + // Route GPU interrupts to Core 0 + store32(0x00, GPU_INTERRUPTS_ROUTING); + // Mask Overrun of UART0 store32(1<<4, UART0_IMSC); // Enable UART GPU IRQ store32(1<<25, IRQ_ENABLE2); - // Route GPU interrupts to Core 0 - store32(0x00, GPU_INTERRUPTS_ROUTING); + // Enable USB Interrupt + store32(1<<9, IRQ_ENABLE1); + // USB Host power on + // HPRT.PrtPwr = 1'b1 -> HPRT.PrtRst = 1'b1 -> wait 60msec -> HPRT.PrtRst = 1'b0 + *USB_HOST_HPRT |= 1 << 12; + *USB_HOST_HPRT |= 1 << 8; + delay(0x100000); + *USB_HOST_HPRT &= ~(1 << 8); + + // enable irq + // GAHBCFG.GlblIntrMsk = 1'b1 + // GINTMSK.ConIDStsChngMsk = 1'b1, GINTMSK.PrtIntMsk = 1'b1, GINTMSK.SofMsk = 1'b1 + *USB_CORE_GAHBCFG |= 1; + *USB_CORE_GINTMSK = 1 << 28 | 1 << 24 | 0 << 3; + + // port enable and retry detect + // HPRT.PrtPwr = 1'b1, HPRT.PrtEnChng = 1'b1, HPRT.PrtConnDet = 1'b1 + *USB_HOST_HPRT = 1 << 12 | 1 << 3 | 1 << 1; + + // enable channel irq + // HAINTMASK.HAINTMsk = 16'h3 + // HCINTMSK0.XferComplMsk = 1'b1 + *USB_HOST_HAINTMSK |= 0x3; + *USB_HOST_HCINTMSK0 |= 1; + *USB_HOST_HCINTMSK1 |= 1; + + // HCCAR1.EPDir = 1'b0 (OUT) / 1'b01(IN), HCCAR1.MPS = 11'h40 + *USB_HOST_HCCHAR0 |= 0x40; // OUT + *USB_HOST_HCCHAR1 |= 1 << 15 | 0x40; // IN // Enable Timer // As an IRQ @@ -128,4 +159,10 @@ void postinit() { } write_string(&g_Drawer, "\n> "); + + send_packet(); + for (int i = 0; i < 18; i++) { + uart_hex(usb_buffer1[i]); + uart_char('\n'); + } } diff --git a/src/sys/core.h b/src/sys/core.h index 88d4644..b76df1b 100644 --- a/src/sys/core.h +++ b/src/sys/core.h @@ -22,7 +22,7 @@ enum #ifdef BSP23 MMIO_BASE = 0x3F000000, // For Raspberry Pi 2 and 3 #else - MMIO_BASE = 0xFE000000, // For Raspberry Pi 2 and 3 + MMIO_BASE = 0xFE000000, #endif // The offsets for reach register. @@ -110,8 +110,41 @@ enum PM_RSTC_WRCFG_CLR = 0xffffffcf, PM_RSTC_WRCFG_SET = 0x00000030, PM_RSTC_WRCFG_FULL_RESET = 0x00000020, - PM_RSTC_RESET = 0x00000102 + PM_RSTC_RESET = 0x00000102, }; +#define uint32_t unsigned long +#define USB_BASE 0x3F980000 +//CORE +#define USB_CORE_GAHBCFG ((volatile uint32_t *)(0x8 + USB_BASE)) +#define USB_CORE_GINTSTS ((volatile uint32_t *)(0x14 + USB_BASE)) +#define USB_CORE_GINTMSK ((volatile uint32_t *)(0x18 + USB_BASE)) +#define USB_CORE_GUID ((volatile uint32_t *)(0x3C + USB_BASE)) +#define USB_CORE_GSNPSID ((volatile uint32_t *)(0x40 + USB_BASE)) +//HOST +#define USB_HOST_HCFG ((volatile uint32_t *)(0x400 + USB_BASE)) +#define USB_HOST_HAINTMSK ((volatile uint32_t *)(0x418 + USB_BASE)) +#define USB_HOST_HPRT ((volatile uint32_t *)(0x440 + USB_BASE)) +//CHANNEL +#define USB_HOST_HCCHAR0 ((volatile uint32_t *)(0x500 + USB_BASE)) +#define USB_HOST_HCINTMSK0 ((volatile uint32_t *)(0x50C + USB_BASE)) +#define USB_HOST_HCTSIZ0 ((volatile uint32_t *)(0x510 + USB_BASE)) +#define USB_HOST_HCDMA0 ((volatile uint32_t *)(0x514 + USB_BASE)) +#define USB_HOST_HCCHAR1 ((volatile uint32_t *)(0x520 + USB_BASE)) +#define USB_HOST_HCINTMSK1 ((volatile uint32_t *)(0x52C + USB_BASE)) +#define USB_HOST_HCTSIZ1 ((volatile uint32_t *)(0x530 + USB_BASE)) +#define USB_HOST_HCDMA1 ((volatile uint32_t *)(0x534 + USB_BASE)) + +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned long + +struct UsbDeviceRequest { + uint8_t Type; + uint8_t Request; + uint16_t Value; + uint16_t Index; + uint16_t Length; +} __attribute__((__packed__)); void sysinit(); void postinit(); |