mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
things are working
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
#define ARCH
|
||||
#include "arch.hh"
|
||||
|
||||
// Interval between polls for keyboard (when keys are pressed) and battery/power (always) events
|
||||
#define ALARM_INTERVAL (HZ / 10)
|
||||
|
||||
// GPIO pins for the devices (port.pin)
|
||||
|
||||
// keyboard
|
||||
@@ -111,14 +114,15 @@ class Keyboard:
|
||||
|
||||
for unsigned i = 0; i < NUM_COLS; ++i:
|
||||
keys[i] = 0xff
|
||||
scan ()
|
||||
void scan ():
|
||||
// Set all columns to 0 when the become output.
|
||||
// Set all columns to 0 when they become output.
|
||||
GPIO_GPDR (3) &= ~COL_MASK
|
||||
bool key_pressed = false
|
||||
scanning = false
|
||||
int const cols[NUM_COLS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 29 }
|
||||
for unsigned col = 0; col < NUM_COLS; ++col:
|
||||
GPIO_GPDIR (3) = (GPIO_GPDIR (3) & ~COL_MASK) | (1 << cols[col])
|
||||
udelay (100)
|
||||
//udelay (100)
|
||||
unsigned data = GPIO_GPDR (0) & ROW_MASK
|
||||
// Generate events.
|
||||
for unsigned row = 0; row < 8; ++row:
|
||||
@@ -129,45 +133,46 @@ class Keyboard:
|
||||
event (KEYBOARD_EVENT, code)
|
||||
keys[col] = data
|
||||
if data != ROW_MASK:
|
||||
key_pressed = true
|
||||
if key_pressed:
|
||||
scanning = true
|
||||
scanning = true
|
||||
scanning = true
|
||||
if scanning:
|
||||
GPIO_GPDIR (3) &= ~COL_MASK
|
||||
else:
|
||||
GPIO_GPDIR (3) |= COL_MASK
|
||||
|
||||
class Touchpad:
|
||||
unsigned old_state
|
||||
public:
|
||||
enum buttons:
|
||||
LEFT = 1 << 16
|
||||
RIGHT = 1 << 13
|
||||
void check_events ():
|
||||
unsigned state = GPIO_GPDR (0)
|
||||
if (state ^ old_state) & LEFT:
|
||||
if state & LEFT:
|
||||
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_FALLEDG << (2 * 0))
|
||||
if (state ^ old_state) & (1 << GPIO_TP_LEFT):
|
||||
if state & (1 << GPIO_TP_LEFT):
|
||||
gpio_irq_fall (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
event (TOUCHPAD_EVENT, 0)
|
||||
else:
|
||||
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_RAISEDG << (2 * 0))
|
||||
gpio_irq_rise (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
event (TOUCHPAD_EVENT, 0x10000)
|
||||
if (state ^ old_state) & RIGHT:
|
||||
if state & RIGHT:
|
||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_FALLEDG << (2 * 13))
|
||||
if (state ^ old_state) & (1 << GPIO_TP_RIGHT):
|
||||
if state & (1 << GPIO_TP_RIGHT):
|
||||
gpio_irq_fall (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
event (TOUCHPAD_EVENT, 1)
|
||||
else:
|
||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_RAISEDG << (2 * 13))
|
||||
gpio_irq_rise (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
event (TOUCHPAD_EVENT, 0x10001)
|
||||
old_state = state
|
||||
Touchpad ():
|
||||
// Set pins to input with pull-ups.
|
||||
GPIO_GPDIR (0) &= ~(LEFT | RIGHT)
|
||||
GPIO_GPPUR (0) |= LEFT | RIGHT
|
||||
// Enable interrupts.
|
||||
GPIO_GPIDUR (0) = (GPIO_GPIDUR (0) & (3 << (2 * 0))) | (GPIO_IRQ_FALLEDG << (2 * 0))
|
||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & (3 << (2 * 13))) | (GPIO_IRQ_FALLEDG << (2 * 13))
|
||||
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)
|
||||
// Set up interrupts.
|
||||
gpio_irq_rise (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||
gpio_irq_rise (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||
old_state = 0
|
||||
// See if they are already pressed. If so, the interrupt detection is changed.
|
||||
check_events ()
|
||||
// Now enable the interrupts.
|
||||
GPIO_GPIER (0) |= LEFT | RIGHT
|
||||
GPIO_GPIER (0) |= (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT)
|
||||
|
||||
class Lockleds:
|
||||
// Note that num lock is in port 2. The others are in port 0.
|
||||
@@ -176,23 +181,25 @@ class Lockleds:
|
||||
enum { SCROLL = 1 << 9 }
|
||||
public:
|
||||
Lockleds ():
|
||||
GPIO_GPDR (2) &= ~NUM
|
||||
GPIO_GPDR (0) &= ~(SCROLL | CAPS)
|
||||
GPIO_GPDIR (2) |= NUM
|
||||
GPIO_GPDIR (0) |= CAPS | SCROLL
|
||||
gpio_as_output (GPIO_NUM_PORT, GPIO_NUM)
|
||||
gpio_as_output (GPIO_CAPS_PORT, GPIO_CAPS)
|
||||
gpio_as_output (GPIO_SCROLL_PORT, GPIO_SCROLL)
|
||||
GPIO_GPDR (GPIO_NUM_PORT) |= 1 << GPIO_NUM
|
||||
GPIO_GPDR (GPIO_CAPS_PORT) |= 1 << GPIO_CAPS
|
||||
GPIO_GPDR (GPIO_SCROLL_PORT) |= 1 << GPIO_SCROLL
|
||||
void set (unsigned state):
|
||||
if state & 4:
|
||||
GPIO_GPDR (2) &= ~NUM
|
||||
GPIO_GPDR (GPIO_NUM_PORT) &= ~(1 << GPIO_NUM)
|
||||
else:
|
||||
GPIO_GPDR (2) |= NUM
|
||||
GPIO_GPDR (GPIO_NUM_PORT) |= 1 << GPIO_NUM
|
||||
if state & 2:
|
||||
GPIO_GPDR (0) &= ~CAPS
|
||||
GPIO_GPDR (GPIO_CAPS_PORT) &= ~(1 << GPIO_CAPS)
|
||||
else:
|
||||
GPIO_GPDR (0) |= CAPS
|
||||
GPIO_GPDR (GPIO_CAPS_PORT) |= 1 << GPIO_CAPS
|
||||
if state & 1:
|
||||
GPIO_GPDR (0) &= ~SCROLL
|
||||
GPIO_GPDR (GPIO_SCROLL_PORT) &= ~(1 << GPIO_SCROLL)
|
||||
else:
|
||||
GPIO_GPDR (0) |= SCROLL
|
||||
GPIO_GPDR (GPIO_SCROLL_PORT) |= 1 << GPIO_SCROLL
|
||||
|
||||
class Power:
|
||||
// Power out is in port 2, the rest in port 3.
|
||||
@@ -207,14 +214,14 @@ class Power:
|
||||
GPIO_GPIER (0) &= ~0xff
|
||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||
GPIO_GPPUR (3) &= ~(PWR_IN | BATTERY)
|
||||
udelay (100)
|
||||
//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)
|
||||
//udelay (100)
|
||||
if GPIO_GPDR (3) & BATTERY:
|
||||
if !was_present:
|
||||
event (BATTERY_EVENT, BATTERY_CHARGED)
|
||||
@@ -228,7 +235,7 @@ class Power:
|
||||
old_state = state
|
||||
GPIO_GPPUR (3) &= ~BATTERY
|
||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||
udelay (100)
|
||||
//udelay (100)
|
||||
GPIO_GPIER (3) |= 0xff
|
||||
Power ():
|
||||
GPIO_GPDR (2) |= PWR_OUT
|
||||
@@ -237,10 +244,16 @@ class Power:
|
||||
old_state = BATTERY
|
||||
poll ()
|
||||
void poweroff ():
|
||||
GPIO_GPDR (2) &= ~PWR_OUT
|
||||
GPIO_GPDIR (2) |= PWR_OUT
|
||||
gpio_as_gpio (GPIO_PW_O_PORT, GPIO_PW_O)
|
||||
gpio_as_output (GPIO_PW_O_PORT, GPIO_PW_O)
|
||||
GPIO_GPDR (GPIO_PW_O) &= ~(1 << GPIO_PW_O)
|
||||
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:
|
||||
@@ -263,14 +276,14 @@ class Pwm:
|
||||
|
||||
int main ():
|
||||
schedule ()
|
||||
*(unsigned *)~3 = 0
|
||||
|
||||
map_gpio ()
|
||||
map_pwm0 ()
|
||||
map_wdt ()
|
||||
|
||||
Keyboard kbd
|
||||
Touchpad tp
|
||||
//Lockleds leds
|
||||
Lockleds leds
|
||||
Power power
|
||||
Pwm pwm
|
||||
|
||||
@@ -287,7 +300,7 @@ int main ():
|
||||
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)
|
||||
|
||||
receiver_set_alarm (__my_receiver, HZ / 5)
|
||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||
while true:
|
||||
Message msg
|
||||
wait (&msg)
|
||||
@@ -296,17 +309,20 @@ int main ():
|
||||
// Alarm.
|
||||
if kbd.is_scanning ():
|
||||
kbd.scan ()
|
||||
power.poll ()
|
||||
receiver_set_alarm (__my_receiver, HZ / 5)
|
||||
//power.poll ()
|
||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||
break
|
||||
case IRQ_GPIO0:
|
||||
kdebug ("gpio interrupt")
|
||||
unsigned irq = GPIO_GPFR (0)
|
||||
// Ack all. This works because they are all edge triggered.
|
||||
GPIO_GPFR (0) = irq
|
||||
if irq & 0xff:
|
||||
kbd.scan ()
|
||||
if irq & (Touchpad::LEFT | Touchpad::RIGHT):
|
||||
if irq & ((1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT)):
|
||||
tp.check_events ()
|
||||
register_interrupt (IRQ_GPIO0)
|
||||
break
|
||||
case CAP_KEYBOARD:
|
||||
set_cb (KEYBOARD_EVENT, msg.cap[0])
|
||||
break
|
||||
@@ -314,7 +330,10 @@ int main ():
|
||||
set_cb (TOUCHPAD_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_POWEROFF:
|
||||
power.poweroff ()
|
||||
if msg.data[0]:
|
||||
power.poweroff ()
|
||||
else:
|
||||
power.reboot ()
|
||||
break
|
||||
case CAP_POWERBUTTON:
|
||||
set_cb (POWERBUTTON_EVENT, msg.cap[0])
|
||||
@@ -323,7 +342,7 @@ int main ():
|
||||
set_cb (BATTERY_EVENT, msg.cap[0])
|
||||
break
|
||||
case CAP_LOCKLEDS:
|
||||
//leds.set (msg.data[0])
|
||||
leds.set (msg.data[0])
|
||||
break
|
||||
case CAP_PWM:
|
||||
pwm.set_backlight (msg.data[0])
|
||||
|
||||
@@ -76,14 +76,18 @@ int main ():
|
||||
wait (&msg)
|
||||
switch msg.protected_data:
|
||||
case KBD:
|
||||
kdebug ("keyboard event")
|
||||
kdebug ("keyboard event: ")
|
||||
kdebug_num (msg.data[0])
|
||||
kdebug_char ('\n')
|
||||
break
|
||||
case TP:
|
||||
kdebug ("touchpad event")
|
||||
if msg.data[0] == 0:
|
||||
// Press left button.
|
||||
invoke_00 (poweroff)
|
||||
break
|
||||
case POWERBUTTON:
|
||||
kdebug ("powerbutton event")
|
||||
kdebug ("powerbutton event\n")
|
||||
break
|
||||
case BATTERY:
|
||||
kdebug ("battery event")
|
||||
kdebug ("battery event\n")
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user