mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
kbd
This commit is contained in:
182
boot-programs/gpio.txt
Normal file
182
boot-programs/gpio.txt
Normal file
@@ -0,0 +1,182 @@
|
||||
GPIO control:
|
||||
|
||||
#define GPIO_BASE 0xB0010000
|
||||
|
||||
#define IRQ_GPIO3 25
|
||||
#define IRQ_GPIO2 26
|
||||
#define IRQ_GPIO1 27
|
||||
#define IRQ_GPIO0 28
|
||||
|
||||
#define GPIO_IRQ_LOLEVEL 0
|
||||
#define GPIO_IRQ_HILEVEL 1
|
||||
#define GPIO_IRQ_FALLEDG 2
|
||||
#define GPIO_IRQ_RAISEDG 3
|
||||
|
||||
// GP ... Registers: one set for each port of 32 pins; total 128 pins means 4 groups. Total size: 4 * 0x30 == 0xc0.
|
||||
#define GPIO_GPDR(n) (GPIO_BASE + (0x00 + (n)*0x30)) // D: data
|
||||
#define GPIO_GPDIR(n) (GPIO_BASE + (0x04 + (n)*0x30)) // DI: data in: 1 is input; 0 is output. Disable interrupts on the pin before touching this.
|
||||
#define GPIO_GPODR(n) (GPIO_BASE + (0x08 + (n)*0x30)) // OD:
|
||||
#define GPIO_GPPUR(n) (GPIO_BASE + (0x0c + (n)*0x30)) // PU: pull-up (1 is enable)
|
||||
#define GPIO_GPALR(n) (GPIO_BASE + (0x10 + (n)*0x30)) // AL: alternate lower: per 2 bit; 00 means use as gpio; other values mean use as alternate function
|
||||
#define GPIO_GPAUR(n) (GPIO_BASE + (0x14 + (n)*0x30)) // AU: alternate upper: same thing, needs 2 registers because it's 2 bits per pin.
|
||||
#define GPIO_GPIDLR(n) (GPIO_BASE + (0x18 + (n)*0x30)) // IDL: interrupt detect lower: per 2 bit (GPIO_IRQ_*)
|
||||
#define GPIO_GPIDUR(n) (GPIO_BASE + (0x1c + (n)*0x30)) // IDU: interrupt detect upper: same thing, upper 16 bit
|
||||
#define GPIO_GPIER(n) (GPIO_BASE + (0x20 + (n)*0x30)) // IE: interrupt enable (0 is disable)
|
||||
#define GPIO_GPIMR(n) (GPIO_BASE + (0x24 + (n)*0x30)) // IM:
|
||||
#define GPIO_GPFR(n) (GPIO_BASE + (0x28 + (n)*0x30)) // F: flag: set on interrupt; cleared by user.
|
||||
|
||||
#define IRQ_GPIO_0 48
|
||||
#define NUM_GPIO 128
|
||||
|
||||
// Pins for alternate functions:
|
||||
|
||||
#define __gpio_as_ssi() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(2) &= 0xFC00FFFF; \
|
||||
REG_GPIO_GPALR(2) |= 0x01550000; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_uart3() \
|
||||
do { \
|
||||
REG_GPIO_GPAUR(0) &= 0xFFFF0000; \
|
||||
REG_GPIO_GPAUR(0) |= 0x00005555; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_uart2() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(3) &= 0x3FFFFFFF; \
|
||||
REG_GPIO_GPALR(3) |= 0x40000000; \
|
||||
REG_GPIO_GPAUR(3) &= 0xF3FFFFFF; \
|
||||
REG_GPIO_GPAUR(3) |= 0x04000000; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_uart1() \
|
||||
do { \
|
||||
REG_GPIO_GPAUR(0) &= 0xFFF0FFFF; \
|
||||
REG_GPIO_GPAUR(0) |= 0x00050000; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_uart0() \
|
||||
do { \
|
||||
REG_GPIO_GPAUR(3) &= 0x0FFFFFFF; \
|
||||
REG_GPIO_GPAUR(3) |= 0x50000000; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define __gpio_as_scc0() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(2) &= 0xFFFFFFCC; \
|
||||
REG_GPIO_GPALR(2) |= 0x00000011; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_scc1() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(2) &= 0xFFFFFF33; \
|
||||
REG_GPIO_GPALR(2) |= 0x00000044; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_scc() \
|
||||
do { \
|
||||
__gpio_as_scc0(); \
|
||||
__gpio_as_scc1(); \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_dma() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(0) &= 0x00FFFFFF; \
|
||||
REG_GPIO_GPALR(0) |= 0x55000000; \
|
||||
REG_GPIO_GPAUR(0) &= 0xFF0FFFFF; \
|
||||
REG_GPIO_GPAUR(0) |= 0x00500000; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_msc() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(1) &= 0xFFFF000F; \
|
||||
REG_GPIO_GPALR(1) |= 0x00005550; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_pcmcia() \
|
||||
do { \
|
||||
REG_GPIO_GPAUR(2) &= 0xF000FFFF; \
|
||||
REG_GPIO_GPAUR(2) |= 0x05550000; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_emc(csmask) \
|
||||
do { \
|
||||
REG_GPIO_GPALR(2) &= 0x3FFFFFFF; \
|
||||
REG_GPIO_GPALR(2) |= 0x40000000; \
|
||||
REG_GPIO_GPAUR(2) &= 0xFFFF0000; \
|
||||
REG_GPIO_GPAUR(2) |= 0x00005555; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_lcd_slave() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(1) &= 0x0000FFFF; \
|
||||
REG_GPIO_GPALR(1) |= 0x55550000; \
|
||||
REG_GPIO_GPAUR(1) &= 0x00000000; \
|
||||
REG_GPIO_GPAUR(1) |= 0x55555555; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_lcd_master() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(1) &= 0x0000FFFF; \
|
||||
REG_GPIO_GPALR(1) |= 0x55550000; \
|
||||
REG_GPIO_GPAUR(1) &= 0x00000000; \
|
||||
REG_GPIO_GPAUR(1) |= 0x556A5555; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_usb() \
|
||||
do { \
|
||||
REG_GPIO_GPAUR(0) &= 0x00FFFFFF; \
|
||||
REG_GPIO_GPAUR(0) |= 0x55000000; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_ac97() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(2) &= 0xC3FF03FF; \
|
||||
REG_GPIO_GPALR(2) |= 0x24005400; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_i2s_slave() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(2) &= 0xC3FF0CFF; \
|
||||
REG_GPIO_GPALR(2) |= 0x14005100; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_i2s_master() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(2) &= 0xC3FF0CFF; \
|
||||
REG_GPIO_GPALR(2) |= 0x28005100; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_eth() \
|
||||
do { \
|
||||
REG_GPIO_GPAUR(3) &= 0xFC000000; \
|
||||
REG_GPIO_GPAUR(3) |= 0x01555555; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_pwm() \
|
||||
do { \
|
||||
REG_GPIO_GPAUR(2) &= 0x0FFFFFFF; \
|
||||
REG_GPIO_GPAUR(2) |= 0x50000000; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_ps2() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(1) &= 0xFFFFFFF0; \
|
||||
REG_GPIO_GPALR(1) |= 0x00000005; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_uprt() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(1) &= 0x0000000F; \
|
||||
REG_GPIO_GPALR(1) |= 0x55555550; \
|
||||
REG_GPIO_GPALR(3) &= 0xC0000000; \
|
||||
REG_GPIO_GPALR(3) |= 0x15555555; \
|
||||
} while (0)
|
||||
|
||||
#define __gpio_as_cim() \
|
||||
do { \
|
||||
REG_GPIO_GPALR(0) &= 0xFF000000; \
|
||||
REG_GPIO_GPALR(0) |= 0x00555555; \
|
||||
} while (0)
|
||||
@@ -18,6 +18,63 @@
|
||||
|
||||
#include "iris.h"
|
||||
|
||||
// GPIO pins for the keyboard: Rows =
|
||||
// Rows = 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 125
|
||||
// Cols = 0, 1, 2, 3, 4, 5, 6, 7
|
||||
|
||||
// Rows: 60...6f; 7d
|
||||
|
||||
// Nicely aligned to a port: use cols as output; rows as input.
|
||||
|
||||
// Map memory from b0010000, which is really 10010000 in kseg1.
|
||||
|
||||
#define D(n) (*(volatile unsigned *)(0x00 + 0x30 * n + address))
|
||||
#define DI(n) (*(volatile unsigned *)(0x04 + 0x30 * n + address))
|
||||
#define AL(n) (*(volatile unsigned *)(0x10 + 0x30 * n + address))
|
||||
#define AU(n) (*(volatile unsigned *)(0x14 + 0x30 * n + address))
|
||||
#define IE(n) (*(volatile unsigned *)(0x20 + 0x30 * n + address))
|
||||
|
||||
void event (bool release, unsigned col, unsigned row):
|
||||
debug_set_led ((col & 1) | (row & 2) | (release ? 4 : 0))
|
||||
|
||||
int main ():
|
||||
// map memory
|
||||
Capability page = memory_create_page (__my_memory)
|
||||
alloc_physical (page, 0x10010000, 0)
|
||||
unsigned const address = 0x00010000
|
||||
memory_map (__my_memory, page, address)
|
||||
|
||||
// Disable all interrupts.
|
||||
IE (3) &= ~0x2000ffff
|
||||
IE (0) &= ~0x000000ff
|
||||
|
||||
// Set all to GPIO
|
||||
AL (3) = 0
|
||||
AU (3) &= ~0x0c000000
|
||||
AL (0) &= ~0x0000ffff
|
||||
|
||||
// Set all to input
|
||||
DI (3) |= 0x2000ffff
|
||||
DI (0) |= 0x000000ff
|
||||
|
||||
unsigned keys[2][8]
|
||||
for unsigned i = 0; i < 8; ++i:
|
||||
keys[1][i] = 0x2000ffff
|
||||
while true:
|
||||
__asm__ volatile ("move $v0, $zero; move $a0, $zero ; move $a1, $zero ; move $a2, $zero ; syscall")
|
||||
// read keyboard
|
||||
for unsigned col = 0; col < 8; ++col:
|
||||
// set col to output, all others to input
|
||||
DI (0) = (DI (0) & ~0x000000ff) | (1 << col)
|
||||
// read input
|
||||
keys[0][col] = D (3) & ~0x2000ffff
|
||||
// Generate events
|
||||
if keys[0][col] == keys[1][col]:
|
||||
continue
|
||||
unsigned bit, b
|
||||
for bit = 1, b = 0; bit < 0x10000; bit <<= 1, ++b:
|
||||
if (keys[0][col] ^ keys[1][col]) & bit:
|
||||
event (keys[0][col] & bit, col, b)
|
||||
if (keys[0][col] ^ keys[1][col]) & 0x20000000:
|
||||
// Not really bit 16, but it's easier to handle.
|
||||
event (keys[0][col] & 0x20000000, col, 16)
|
||||
schedule ()
|
||||
|
||||
Reference in New Issue
Block a user