aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2021-12-23 21:42:32 -0800
committerChristian Cunningham <cc@localhost>2021-12-23 21:42:32 -0800
commit9bc94963aefcb5028c3529ff59c974e48d814690 (patch)
treeeb90b58da616bce55176b4f8f72a238cce19cd0d /src
parenta905c499ceddc47a5fcd46f863e453919c196722 (diff)
Intro USB
Diffstat (limited to 'src')
-rw-r--r--src/cpu/atomic/swap.h1
-rw-r--r--src/cpu/irq.c21
-rw-r--r--src/drivers/usb.c55
-rw-r--r--src/drivers/usb.h15
-rw-r--r--src/graphics/lfb.c2
-rw-r--r--src/sys/core.c41
-rw-r--r--src/sys/core.h37
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();