mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
reorganize capabilities; doesn't work yet
This commit is contained in:
@@ -30,16 +30,6 @@ __hack_label:
|
||||
.word _gp
|
||||
1:
|
||||
lw $gp, 0($ra)
|
||||
la $v0, __my_receiver
|
||||
sw $a0, ($v0)
|
||||
la $v0, __my_thread
|
||||
sw $a1, ($v0)
|
||||
la $v0, __my_memory
|
||||
sw $a2, ($v0)
|
||||
la $v0, __my_call
|
||||
sw $a3, ($v0)
|
||||
la $v0, __my_parent
|
||||
sw $t0, ($v0)
|
||||
la $t9, main
|
||||
la $ra, 1f
|
||||
jr $t9
|
||||
@@ -49,9 +39,3 @@ __hack_label:
|
||||
// This should not be reached: generate an address fault.
|
||||
b 1b
|
||||
lw $a0, -4($zero)
|
||||
|
||||
.comm __my_receiver, 4
|
||||
.comm __my_thread, 4
|
||||
.comm __my_memory, 4
|
||||
.comm __my_call, 4
|
||||
.comm __my_parent, 4
|
||||
|
||||
@@ -24,19 +24,25 @@
|
||||
// This shouldn't really be here. But where should it be?
|
||||
// Requests made by initial threads to tell init about themselves.
|
||||
enum init_requests:
|
||||
INIT_SET_GPIO_0
|
||||
INIT_SET_GPIO_1
|
||||
INIT_SET_GPIO
|
||||
INIT_SET_LCD
|
||||
|
||||
|
||||
// Keyboard interface.
|
||||
// Startup: kbd_set_cb
|
||||
enum Keyboard_request:
|
||||
KEYBOARD_SET_CB
|
||||
KEYBOARD_GET_KEYS
|
||||
|
||||
// Set the event callback. Currently pressed keys emit a key press event to the new callback immediately, plus a ~0 to signal the end of such events.
|
||||
static __inline__ void keyboard_set_cb (Capability kbd_set_cb, Capability cb):
|
||||
invoke_10 (kbd_set_cb, cb)
|
||||
static __inline__ void keyboard_set_cb (Capability kbd, Capability cb):
|
||||
invoke_11 (kbd, cb, KEYBOARD_SET_CB)
|
||||
// At event: the callback is called with a keycode. One bit defines if it's a press or release event.
|
||||
#define KEYBOARD_RELEASE (1 << 31)
|
||||
|
||||
// Get a list of keys on this keyboard. The key codes start at zero with no gaps. The returned capability is a read-only list of strings.
|
||||
static __inline__ void keyboard_get_keys (Capability target, Capability kbd):
|
||||
call_c01 (kbd, target, KEYBOARD_GET_KEYS)
|
||||
|
||||
|
||||
|
||||
// Display interface.
|
||||
@@ -93,8 +99,8 @@ static __inline__ unsigned long long file_get_info (Capability file, unsigned ty
|
||||
static __inline__ void file_close (Capability file):
|
||||
invoke_01 (file, FILE_CLOSE)
|
||||
// Copy a file handle. This can be useful for closing all children at once. The new handle itself is a child of the original handle.
|
||||
static __inline__ Capability file_copy_handle (Capability file):
|
||||
return call_c01 (file, FILE_COPY_HANDLE)
|
||||
static __inline__ void file_copy_handle (Capability target, Capability file):
|
||||
call_c01 (file, target, FILE_COPY_HANDLE)
|
||||
|
||||
// Directory interface.
|
||||
// Get the number of entries in this directory.
|
||||
@@ -104,17 +110,17 @@ static __inline__ unsigned long long directory_get_size (Capability dir):
|
||||
static __inline__ unsigned directory_get_name (Capability dir, unsigned long long idx, Capability page):
|
||||
return call_n13 (dir, page, DIRECTORY_GET_NAME, idx & 0xffffffff, idx >> 32)
|
||||
// Get the file.
|
||||
static __inline__ Capability directory_get_file (Capability dir, unsigned long long idx, Capability page):
|
||||
return call_c03 (dir, DIRECTORY_GET_FILE, idx & 0xffffffff, idx >> 32)
|
||||
static __inline__ void directory_get_file (Capability target, Capability dir, unsigned long long idx, Capability page):
|
||||
call_c03 (dir, target, DIRECTORY_GET_FILE, idx & 0xffffffff, idx >> 32)
|
||||
// Get file info. This returns the same information as file_get_info, without opening the file.
|
||||
static __inline__ unsigned long long directory_get_file_info (Capability dir, unsigned long long idx, unsigned type):
|
||||
return call_l04 (dir, DIRECTORY_GET_FILE_INFO, idx & 0xffffffff, idx >> 32, type)
|
||||
// Create a new file. After this, any index may map to a different file.
|
||||
static __inline__ Capability directory_create_file (Capability dir, unsigned long long idx, Capability page):
|
||||
return call_c03 (dir, DIRECTORY_CREATE_FILE, idx & 0xffffffff, idx >> 32)
|
||||
static __inline__ void directory_create_file (Capability target, Capability dir, unsigned long long idx, Capability page):
|
||||
call_c03 (dir, target, DIRECTORY_CREATE_FILE, idx & 0xffffffff, idx >> 32)
|
||||
// Delete a file. After this, any index may map to a different file.
|
||||
static __inline__ Capability directory_delete_file (Capability dir, unsigned long long idx, Capability page):
|
||||
return call_c03 (dir, DIRECTORY_DELETE_FILE, idx & 0xffffffff, idx >> 32)
|
||||
static __inline__ void directory_delete_file (Capability target, Capability dir, unsigned long long idx, Capability page):
|
||||
call_c03 (dir, target, DIRECTORY_DELETE_FILE, idx & 0xffffffff, idx >> 32)
|
||||
|
||||
// Stream interface.
|
||||
// Try to read size bytes. Returns the number of bytes successfully read. It cannot be more than PAGE_SIZE.
|
||||
@@ -148,8 +154,8 @@ static __inline__ unsigned block_get_size (Capability blk_get_size):
|
||||
return call_n00 (blk_get_size)
|
||||
|
||||
// Get file capability. Returns a seekable mappable non-stream file.
|
||||
static __inline__ Capability block_get_file (Capability blk_get_file):
|
||||
call_c00 (blk_get_file)
|
||||
static __inline__ void block_get_file (Capability target, Capability blk_get_file):
|
||||
call_c00 (blk_get_file, target)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#define ARCH
|
||||
#include "arch.hh"
|
||||
|
||||
// Interval between polls for keyboard (when keys are pressed) and battery/power (always) events
|
||||
#define ALARM_INTERVAL (HZ / 20)
|
||||
// Interval between polls for keyboard events (when keys are pressed)
|
||||
#define ALARM_INTERVAL (HZ / 50)
|
||||
|
||||
// GPIO pins for the devices (port.pin)
|
||||
|
||||
@@ -42,13 +42,6 @@
|
||||
// Scroll lock: 0.9
|
||||
// interrupts: no, output only.
|
||||
|
||||
// Power output (setting to 0 switches off the machine): 2.2
|
||||
// interrupts: no, output only.
|
||||
|
||||
// Power button: 3.1 (note that this is also a keyboard column.)
|
||||
// Battery presence and charge detection: 3.29 (note that this is also a keyboard column.)
|
||||
// interrupts: no; it would be possible, but setting these to input makes it impossible to detect certain key presses as interrupts.
|
||||
|
||||
// interrupt summary
|
||||
// Port 0: pin 0, 1, 2, 3, 4, 5, 6, 7: keyboard; 13, 16: touchpad
|
||||
// Port 1: None.
|
||||
@@ -58,43 +51,28 @@
|
||||
enum event_type:
|
||||
KEYBOARD_EVENT
|
||||
TOUCHPAD_EVENT
|
||||
POWERBUTTON_EVENT
|
||||
BATTERY_EVENT
|
||||
NUM_EVENTS
|
||||
|
||||
enum cap_type:
|
||||
CAP_KEYBOARD = 32
|
||||
CAP_TOUCHPAD
|
||||
CAP_POWEROFF
|
||||
CAP_POWERBUTTON
|
||||
CAP_BATTERY
|
||||
CAP_LOCKLEDS
|
||||
CAP_PWM
|
||||
|
||||
static Capability cbs[NUM_EVENTS]
|
||||
|
||||
static void event (event_type type, unsigned data):
|
||||
if !cbs[type]:
|
||||
return
|
||||
invoke_01 (cbs[type], data)
|
||||
invoke_01 (11 + type, data)
|
||||
|
||||
static void set_cb (event_type type, Capability cb):
|
||||
if cbs[type]:
|
||||
drop (cbs[type])
|
||||
cbs[type] = cb
|
||||
|
||||
enum battery_type:
|
||||
BATTERY_ABSENT
|
||||
BATTERY_CHARGING
|
||||
BATTERY_CHARGED
|
||||
static void set_cb (event_type type):
|
||||
capability_clone (11 + type, 6)
|
||||
|
||||
class Keyboard:
|
||||
static unsigned const encode[GPIO_KBD_NUM_COLS][GPIO_KBD_NUM_ROWS]
|
||||
unsigned keys[GPIO_KBD_NUM_COLS]
|
||||
bool scanning
|
||||
void parse (unsigned col, unsigned data):
|
||||
for unsigned row = 0; row < GPIO_KBD_NUM_ROWS; ++row:
|
||||
if (data ^ keys[col]) & (1 << row):
|
||||
unsigned code = (col << 3) | row
|
||||
unsigned code = encode[col][row]
|
||||
if data & (1 << row):
|
||||
code |= KEYBOARD_RELEASE
|
||||
event (KEYBOARD_EVENT, code)
|
||||
@@ -115,32 +93,38 @@ class Keyboard:
|
||||
unsigned dat = GPIO_GPDR (GPIO_KBD_COL_PORT) & ~GPIO_KBD_COL_MASK
|
||||
// Set scanning to false before first parse.
|
||||
scanning = false
|
||||
// Clear all pins. This is only required once, because it's done at the end of the loop as well.
|
||||
GPIO_GPDR (GPIO_KBD_COL_PORT) = dat
|
||||
for unsigned col = 0; col < GPIO_KBD_NUM_COLS; ++col:
|
||||
// clear pin
|
||||
GPIO_GPDR (GPIO_KBD_COL_PORT) = dat
|
||||
// output
|
||||
// Set pin to output.
|
||||
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir | (1 << cols[col])
|
||||
for unsigned i = 0; i < 100000; ++i:
|
||||
// Delay for stabalization.
|
||||
for unsigned i = 0; i < 100; ++i:
|
||||
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir | (1 << cols[col])
|
||||
// Read the result.
|
||||
unsigned data = GPIO_GPDR (GPIO_KBD_ROW_PORT) & GPIO_KBD_ROW_MASK
|
||||
// Generate events.
|
||||
parse (col, data)
|
||||
// set pin
|
||||
// Set pin to get rid of capacitance effects.
|
||||
GPIO_GPDR (GPIO_KBD_COL_PORT) = dat | (1 << cols[col])
|
||||
// input
|
||||
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir
|
||||
// Delay to make the above trick work.
|
||||
for unsigned i = 0; i < 100; ++i:
|
||||
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir | (1 << cols[col])
|
||||
// Pin is set to input at the start of the loop.
|
||||
// set all to 0.
|
||||
GPIO_GPDR (GPIO_KBD_COL_PORT) = dat
|
||||
// set all to output.
|
||||
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir | GPIO_KBD_COL_MASK
|
||||
// Set interrupts on change.
|
||||
// Delay for stabalization.
|
||||
for unsigned i = 0; i < 100; ++i:
|
||||
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir | GPIO_KBD_COL_MASK
|
||||
// Set interrupts.
|
||||
unsigned data = GPIO_GPDR (GPIO_KBD_ROW_PORT)
|
||||
for unsigned i = 0; i < 8; ++i:
|
||||
if data & (1 << i):
|
||||
gpio_irq_fall (GPIO_KBD_ROW_PORT, i)
|
||||
gpio_irq_low (GPIO_KBD_ROW_PORT, i)
|
||||
else:
|
||||
gpio_irq_rise (GPIO_KBD_ROW_PORT, i)
|
||||
// Clear pending interrupts.
|
||||
GPIO_GPFR (GPIO_KBD_ROW_PORT) |= GPIO_KBD_ROW_MASK
|
||||
gpio_irq_high (GPIO_KBD_ROW_PORT, i)
|
||||
// Reenable interrupts.
|
||||
GPIO_GPIER (GPIO_KBD_ROW_PORT) |= GPIO_KBD_ROW_MASK
|
||||
Keyboard ():
|
||||
@@ -151,11 +135,43 @@ class Keyboard:
|
||||
// Set all rows to input and enable the pull-ups.
|
||||
GPIO_GPPUR (GPIO_KBD_ROW_PORT) |= GPIO_KBD_ROW_MASK
|
||||
GPIO_GPDIR (GPIO_KBD_ROW_PORT) &= ~GPIO_KBD_ROW_MASK
|
||||
// Initialize matrix.
|
||||
for unsigned i = 0; i < GPIO_KBD_NUM_COLS; ++i:
|
||||
keys[i] = 0xff
|
||||
// Perform initial scan to get real values into matrix and set up the rest.
|
||||
// Initialize things in the same way as when a new callback is set up.
|
||||
send_initial ()
|
||||
void send_initial ():
|
||||
for unsigned col = 0; col < GPIO_KBD_NUM_COLS; ++col:
|
||||
keys[col] = 0xff
|
||||
scan ()
|
||||
event (KEYBOARD_EVENT, ~0)
|
||||
|
||||
enum Keys:
|
||||
N0, N1, N2, N3, N4, N5, N6, N7, N8, N9
|
||||
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10
|
||||
SPACE, TAB, ENTER, LBRACE, RBRACE, COMMA, PERIOD, MINUS, EQUAL, SLASH, BACKSLASH, SEMICOLON, EXTRA, BACKQUOTE, QUOTE
|
||||
UP, DOWN, LEFT, RIGHT
|
||||
ESC, INSERT, DELETE, BACKSPACE, PAUSE, FN, ZZZ, MENU, SYSRQ
|
||||
LSHIFT, RSHIFT, CTRL, ALT
|
||||
CAPS, NUM
|
||||
NONE = ~0 & ~KEYBOARD_RELEASE
|
||||
|
||||
unsigned const Keyboard::encode[GPIO_KBD_NUM_COLS][GPIO_KBD_NUM_ROWS] = {
|
||||
{ PAUSE, NONE, NONE, NONE, NONE, NONE, CTRL, F5 },
|
||||
{ Q, TAB, A, ESC, Z, NONE, BACKQUOTE, N1 },
|
||||
{ W, CAPS, S, EXTRA, X, NONE, NONE, N2 },
|
||||
{ E, F3, D, F4, C, NONE, NONE, N3 },
|
||||
{ R, T, F, G, V, B, N5, N4 },
|
||||
{ U, Y, J, H, M, N, N6, N7 },
|
||||
{ I, RBRACE, K, F6, COMMA, NONE, EQUAL, N8 },
|
||||
{ O, F7, L, NONE, PERIOD, MENU, F8, N9 },
|
||||
{ NONE, NONE, NONE, SPACE, NUM, NONE, DELETE, NONE },
|
||||
{ NONE, BACKSPACE, NONE, NONE, ENTER, NONE, F9, NONE },
|
||||
{ NONE, NONE, NONE, ALT, NONE, NONE, NONE, SYSRQ },
|
||||
{ P, LBRACE, SEMICOLON, QUOTE, BACKSLASH, SLASH, MINUS, N0 },
|
||||
{ NONE, ZZZ, NONE, NONE, NONE, NONE, NONE, F10 },
|
||||
{ NONE, NONE, NONE, NONE, NONE, NONE, F2, NONE },
|
||||
{ NONE, NONE, NONE, NONE, NONE, NONE, INSERT, NONE },
|
||||
{ NONE, NONE, UP, DOWN, LEFT, RIGHT, NONE, NONE },
|
||||
{ NONE, LSHIFT, RSHIFT, NONE, NONE, NONE, F1, FN }}
|
||||
|
||||
class Touchpad:
|
||||
unsigned old_state
|
||||
@@ -163,33 +179,35 @@ class Touchpad:
|
||||
void check_events ():
|
||||
unsigned state = GPIO_GPDR (GPIO_TP_LEFT_PORT)
|
||||
if state & (1 << GPIO_TP_LEFT):
|
||||
gpio_irq_fall (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
gpio_irq_low (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
if (state ^ old_state) & (1 << GPIO_TP_LEFT):
|
||||
event (TOUCHPAD_EVENT, 0)
|
||||
else:
|
||||
gpio_irq_rise (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
gpio_irq_high (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
if (state ^ old_state) & (1 << GPIO_TP_LEFT):
|
||||
event (TOUCHPAD_EVENT, 0x10000)
|
||||
if state & (1 << GPIO_TP_RIGHT):
|
||||
gpio_irq_fall (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
gpio_irq_low (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
if (state ^ old_state) & (1 << GPIO_TP_RIGHT):
|
||||
event (TOUCHPAD_EVENT, 1)
|
||||
else:
|
||||
gpio_irq_rise (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
gpio_irq_high (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
if (state ^ old_state) & (1 << GPIO_TP_RIGHT):
|
||||
event (TOUCHPAD_EVENT, 0x10001)
|
||||
old_state = state
|
||||
// Ack interrupts.
|
||||
GPIO_GPFR (GPIO_TP_LEFT_PORT) = (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT)
|
||||
//GPIO_GPFR (GPIO_TP_LEFT_PORT) = (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT)
|
||||
Touchpad ():
|
||||
// Set pins to input with pull-ups.
|
||||
gpio_as_input (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
gpio_as_input (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
GPIO_GPPUR (0) |= (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT)
|
||||
// See if they are already pressed. Also set up interrupts. This is done like when a new callback is registered.
|
||||
send_initial ()
|
||||
void send_initial ():
|
||||
old_state = 0
|
||||
// See if they are already pressed. Also set up interrupts.
|
||||
check_events ()
|
||||
// Now enable the interrupts.
|
||||
event (TOUCHPAD_EVENT, ~0)
|
||||
|
||||
class Lockleds:
|
||||
// Note that num lock is in port 2. The others are in port 0.
|
||||
@@ -215,58 +233,6 @@ class Lockleds:
|
||||
else:
|
||||
GPIO_GPDR (GPIO_SCROLL_PORT) |= 1 << GPIO_SCROLL
|
||||
|
||||
class Power:
|
||||
// Power out is in port 2, the rest in port 3.
|
||||
unsigned old_state
|
||||
bool was_present
|
||||
public:
|
||||
void poll ():
|
||||
#if 0
|
||||
// Switch off keyboard interrupts, because this may interfere with them.
|
||||
GPIO_GPIER (0) &= ~0xff
|
||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||
GPIO_GPPUR (3) &= ~(PWR_IN | BATTERY)
|
||||
//udelay (100)
|
||||
unsigned state = GPIO_GPDR (3)
|
||||
if (state ^ old_state) & PWR_IN:
|
||||
event (POWERBUTTON_EVENT, state & PWR_IN ? 0 : 0x10000)
|
||||
if (state ^ old_state) & BATTERY:
|
||||
if !(state & BATTERY):
|
||||
GPIO_GPPUR (3) |= BATTERY
|
||||
//udelay (100)
|
||||
if GPIO_GPDR (3) & BATTERY:
|
||||
if !was_present:
|
||||
event (BATTERY_EVENT, BATTERY_CHARGED)
|
||||
was_present = true
|
||||
else:
|
||||
if was_present:
|
||||
event (BATTERY_EVENT, BATTERY_ABSENT)
|
||||
was_present = false
|
||||
else:
|
||||
event (BATTERY_EVENT, BATTERY_CHARGING)
|
||||
old_state = state
|
||||
GPIO_GPPUR (3) &= ~BATTERY
|
||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||
//udelay (100)
|
||||
GPIO_GPIER (3) |= 0xff
|
||||
#endif
|
||||
Power ():
|
||||
was_present = true
|
||||
//old_state = BATTERY
|
||||
poll ()
|
||||
void poweroff ():
|
||||
// TODO: doesn't work.
|
||||
i2c_open ()
|
||||
i2c_write_page (I2C_DEV_MCU, I2C_MCU_SHUTDOWN, "\1", 1)
|
||||
i2c_close ()
|
||||
while true:
|
||||
// Do nothing; wait until the device stops running.
|
||||
void reboot ():
|
||||
wdt_set_count (0xffffffff - 32)
|
||||
wdt_start ()
|
||||
while true:
|
||||
// Do nothing; wait until the device reboots.
|
||||
|
||||
// Not really a gpio device, but it's so small, and uses gpio, so I include it here to avoid ipc.
|
||||
class Pwm:
|
||||
public:
|
||||
@@ -288,43 +254,39 @@ class Pwm:
|
||||
int main ():
|
||||
map_gpio ()
|
||||
map_pwm0 ()
|
||||
map_wdt ()
|
||||
map_i2c ()
|
||||
|
||||
Keyboard kbd
|
||||
Touchpad tp
|
||||
Lockleds leds
|
||||
Power power
|
||||
Pwm pwm
|
||||
|
||||
// Enable interrupts. All are in port 0.
|
||||
GPIO_GPIER (GPIO_KBD_ROW_PORT) = (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT) | GPIO_KBD_ROW_MASK
|
||||
register_interrupt (IRQ_GPIO0)
|
||||
|
||||
Capability cap_kbd = receiver_create_capability (__my_receiver, CAP_KEYBOARD)
|
||||
Capability cap_tp = receiver_create_capability (__my_receiver, CAP_TOUCHPAD)
|
||||
Capability cap_poweroff = receiver_create_capability (__my_receiver, CAP_POWEROFF)
|
||||
Capability cap_powerbutton = receiver_create_capability (__my_receiver, CAP_POWERBUTTON)
|
||||
Capability cap_battery = receiver_create_capability (__my_receiver, CAP_BATTERY)
|
||||
Capability cap_lockleds = receiver_create_capability (__my_receiver, CAP_LOCKLEDS)
|
||||
Capability cap_pwm = receiver_create_capability (__my_receiver, CAP_PWM)
|
||||
Capability cap_kbd = 7
|
||||
Capability cap_tp = 8
|
||||
Capability cap_lockleds = 9
|
||||
Capability cap_pwm = 10
|
||||
receiver_create_capability (cap_kbd, __my_receiver, CAP_KEYBOARD)
|
||||
receiver_create_capability (cap_tp, __my_receiver, CAP_TOUCHPAD)
|
||||
receiver_create_capability (cap_lockleds, __my_receiver, CAP_LOCKLEDS)
|
||||
receiver_create_capability (cap_pwm, __my_receiver, CAP_PWM)
|
||||
|
||||
invoke_41 (__my_parent, cap_copy (cap_kbd), cap_copy (cap_tp), cap_copy (cap_poweroff), cap_copy (cap_powerbutton), INIT_SET_GPIO_0)
|
||||
invoke_31 (__my_parent, cap_copy (cap_battery), cap_copy (cap_lockleds), cap_copy (cap_pwm), INIT_SET_GPIO_1)
|
||||
invoke_41 (__my_parent, cap_copy (cap_kbd), cap_copy (cap_tp), cap_copy (cap_lockleds), cap_copy (cap_pwm), INIT_SET_GPIO)
|
||||
|
||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||
if kbd.is_scanning ():
|
||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||
while true:
|
||||
schedule ()
|
||||
Message msg
|
||||
wait (&msg)
|
||||
wait (&msg, 6, CAPABILITY_NONE, CAPABILITY_NONE, CAPABILITY_NONE)
|
||||
switch msg.protected_data:
|
||||
case ~0:
|
||||
// Alarm.
|
||||
// Periodically scan several devices.
|
||||
kbd.scan ()
|
||||
if kbd.is_scanning ():
|
||||
kbd.scan ()
|
||||
power.poll ()
|
||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||
break
|
||||
case IRQ_GPIO0:
|
||||
// Always scan keyboard and touchpad on any interrupt.
|
||||
@@ -334,22 +296,12 @@ int main ():
|
||||
register_interrupt (IRQ_GPIO0)
|
||||
break
|
||||
case CAP_KEYBOARD:
|
||||
set_cb (KEYBOARD_EVENT, msg.cap[0])
|
||||
set_cb (KEYBOARD_EVENT)
|
||||
kbd.send_initial ()
|
||||
break
|
||||
case CAP_TOUCHPAD:
|
||||
set_cb (TOUCHPAD_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_POWEROFF:
|
||||
if msg.data[0]:
|
||||
power.poweroff ()
|
||||
else:
|
||||
power.reboot ()
|
||||
break
|
||||
case CAP_POWERBUTTON:
|
||||
set_cb (POWERBUTTON_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_BATTERY:
|
||||
set_cb (BATTERY_EVENT, msg.cap[0])
|
||||
set_cb (TOUCHPAD_EVENT)
|
||||
tp.send_initial ()
|
||||
break
|
||||
case CAP_LOCKLEDS:
|
||||
leds.set (msg.data[0])
|
||||
|
||||
@@ -19,53 +19,46 @@
|
||||
#include "devices.hh"
|
||||
#include "iris.h"
|
||||
|
||||
static Capability kbd, tp, poweroff, powerbutton, battery, lockleds, pwm, lcd
|
||||
static Capability kbd, tp, lockleds, pwm, lcd
|
||||
|
||||
enum type:
|
||||
KBD = 0x10000
|
||||
TP
|
||||
POWERBUTTON
|
||||
BATTERY
|
||||
|
||||
static void send (Capability c, unsigned d):
|
||||
Capability n = receiver_create_capability (__my_receiver, d)
|
||||
invoke_10 (c, cap_copy (n))
|
||||
drop (n)
|
||||
receiver_create_capability (6, __my_receiver, d)
|
||||
invoke_10 (c, cap_copy (6))
|
||||
|
||||
static void setup ():
|
||||
unsigned state = 0
|
||||
Capability base = 7
|
||||
while true:
|
||||
Message msg
|
||||
wait (&msg)
|
||||
wait (&msg, base, base + 1, base + 2, base + 3)
|
||||
switch msg.data[0]:
|
||||
case INIT_SET_GPIO_0:
|
||||
kdebug ("gpio 0\n")
|
||||
kbd = msg.cap[0]
|
||||
tp = msg.cap[1]
|
||||
poweroff = msg.cap[2]
|
||||
powerbutton = msg.cap[3]
|
||||
++state
|
||||
break
|
||||
case INIT_SET_GPIO_1:
|
||||
kdebug ("gpio 1\n")
|
||||
battery = msg.cap[0]
|
||||
lockleds = msg.cap[1]
|
||||
pwm = msg.cap[2]
|
||||
case INIT_SET_GPIO:
|
||||
kdebug ("gpio\n")
|
||||
kbd = base
|
||||
tp = base + 1
|
||||
lockleds = base + 2
|
||||
pwm = base + 3
|
||||
base += 4
|
||||
++state
|
||||
break
|
||||
case INIT_SET_LCD:
|
||||
kdebug ("lcd\n")
|
||||
lcd = msg.cap[0]
|
||||
lcd = base
|
||||
++base
|
||||
++state
|
||||
break
|
||||
if state == 3:
|
||||
if state == 2:
|
||||
break
|
||||
send (kbd, KBD)
|
||||
send (tp, TP)
|
||||
send (powerbutton, POWERBUTTON)
|
||||
send (battery, BATTERY)
|
||||
invoke_01 (pwm, 1)
|
||||
|
||||
char const *decode_kbd = "0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*() T\n[],.-=/\\;|`'UDLREIKBPFZMS{}CA\":"
|
||||
|
||||
int main ():
|
||||
// Set up lcd first
|
||||
schedule ()
|
||||
@@ -74,12 +67,13 @@ int main ():
|
||||
kdebug ("run init\n")
|
||||
while true:
|
||||
Message msg
|
||||
wait (&msg)
|
||||
wait (&msg, CAPABILITY_NONE, CAPABILITY_NONE, CAPABILITY_NONE, CAPABILITY_NONE)
|
||||
switch msg.protected_data:
|
||||
case KBD:
|
||||
kdebug ("keyboard event: ")
|
||||
kdebug_num (msg.data[0])
|
||||
kdebug_char ('\n')
|
||||
unsigned code = msg.data[0]
|
||||
if code & KEYBOARD_RELEASE:
|
||||
break
|
||||
kdebug_char (decode_kbd[code])
|
||||
break
|
||||
case TP:
|
||||
unsigned leds = 0
|
||||
@@ -91,9 +85,3 @@ int main ():
|
||||
leds |= 0x2
|
||||
invoke_01 (lockleds, leds)
|
||||
break
|
||||
case POWERBUTTON:
|
||||
kdebug ("powerbutton event\n")
|
||||
break
|
||||
case BATTERY:
|
||||
kdebug ("battery event\n")
|
||||
break
|
||||
|
||||
@@ -121,30 +121,23 @@ static void log_msg (Message *msg):
|
||||
log_char ('\n')
|
||||
|
||||
int main ():
|
||||
__asm__ volatile ("break")
|
||||
|
||||
map_lcd ()
|
||||
map_cpm ()
|
||||
|
||||
Descriptor descriptor __attribute__ ((aligned (16)))
|
||||
unsigned pages = (frame_size + ~PAGE_MASK) >> PAGE_BITS
|
||||
assert (pages > CAPPAGE_SIZE && pages <= 2 * CAPPAGE_SIZE)
|
||||
unsigned physical = alloc_range (__my_memory, pages)
|
||||
assert (physical)
|
||||
//Capability cappage[2]
|
||||
//unsigned base[2]
|
||||
//cappage[0] = memory_create_cappage (__my_memory, &base[0])
|
||||
//cappage[1] = memory_create_cappage (__my_memory, &base[1])
|
||||
for unsigned i = 0; i < CAPPAGE_SIZE; ++i:
|
||||
Capability page = memory_create_page (__my_memory)
|
||||
//cappage_set (cappage[0], page, i)
|
||||
alloc_physical (page, physical + i * PAGE_SIZE, 0, 1)
|
||||
memory_map (__my_memory, page, (unsigned)LCD_FRAMEBUFFER_BASE + i * PAGE_SIZE, 1)
|
||||
drop (page)
|
||||
for unsigned i = 0; i < pages - CAPPAGE_SIZE; ++i:
|
||||
Capability page = memory_create_page (__my_memory)
|
||||
//cappage_set (cappage[1], page, i)
|
||||
alloc_physical (page, physical + (i + CAPPAGE_SIZE) * PAGE_SIZE, 0, 1)
|
||||
memory_map (__my_memory, page, (unsigned)LCD_FRAMEBUFFER_BASE + (i + CAPPAGE_SIZE) * PAGE_SIZE, 1)
|
||||
drop (page)
|
||||
for unsigned i = 0; i < pages; ++i:
|
||||
memory_create_page (6, __my_memory)
|
||||
alloc_physical (6, physical + i * PAGE_SIZE, 0, 1)
|
||||
memory_map (__my_memory, 6, (unsigned)LCD_FRAMEBUFFER_BASE + i * PAGE_SIZE, 1)
|
||||
for unsigned y = 0; y < 480; ++y:
|
||||
unsigned g = (y << 6) / 480
|
||||
unsigned olr = 0, ob = ((25 * y * y) << 5) / (9 * 800 * 800 + 25 * 480 * 480)
|
||||
@@ -161,8 +154,8 @@ int main ():
|
||||
ob = b
|
||||
b = 0x1f
|
||||
LCD_FRAMEBUFFER_BASE[y * 800 + x] = (r << 11) | (g << 5) | (b)
|
||||
Capability page = memory_mapping (__my_memory, &descriptor)
|
||||
unsigned physical_descriptor = page_physical_address (page) + ((unsigned)&descriptor & ~PAGE_MASK)
|
||||
memory_mapping (6, __my_memory, &descriptor)
|
||||
unsigned physical_descriptor = page_physical_address (cap_copy (6)) + ((unsigned)&descriptor & ~PAGE_MASK)
|
||||
descriptor.next = physical_descriptor
|
||||
descriptor.frame = physical
|
||||
descriptor.id = 0xdeadbeef
|
||||
@@ -173,16 +166,15 @@ int main ():
|
||||
|
||||
Capability eof_cb = 0
|
||||
|
||||
Capability cap = receiver_create_capability (__my_receiver, LCD_EOF_CB)
|
||||
invoke_11 (__my_parent, cap, INIT_SET_LCD)
|
||||
drop (cap)
|
||||
receiver_create_capability (6, __my_receiver, LCD_EOF_CB)
|
||||
invoke_11 (__my_parent, cap_copy (6), INIT_SET_LCD)
|
||||
|
||||
Capability logcap = receiver_create_capability (__my_receiver, LCD_LOG)
|
||||
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap) : "a0", "a1", "memory")
|
||||
receiver_create_capability (15, __my_receiver, LCD_LOG)
|
||||
__asm__ volatile ("li $a0, 1\nlw $a1, 15\nbreak" ::: "a0", "a1", "memory")
|
||||
|
||||
while true:
|
||||
Message msg
|
||||
wait (&msg)
|
||||
wait (&msg, CAPABILITY_NONE, CAPABILITY_NONE, CAPABILITY_NONE, CAPABILITY_NONE)
|
||||
//log_msg (&msg)
|
||||
switch msg.protected_data:
|
||||
case IRQ_LCD:
|
||||
@@ -192,8 +184,6 @@ int main ():
|
||||
invoke_00 (eof_cb)
|
||||
break
|
||||
case LCD_EOF_CB:
|
||||
if eof_cb:
|
||||
drop (eof_cb)
|
||||
eof_cb = msg.cap[0]
|
||||
if eof_cb:
|
||||
register_interrupt (IRQ_LCD)
|
||||
|
||||
Reference in New Issue
Block a user