mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-16 17:00:38 +02:00
fixes and improvements
This commit is contained in:
parent
df38266bb8
commit
283b97955d
@ -21,7 +21,7 @@
|
|||||||
#include "arch.hh"
|
#include "arch.hh"
|
||||||
|
|
||||||
// Interval between polls for keyboard (when keys are pressed) and battery/power (always) events
|
// Interval between polls for keyboard (when keys are pressed) and battery/power (always) events
|
||||||
#define ALARM_INTERVAL (HZ / 10)
|
#define ALARM_INTERVAL (HZ / 1)
|
||||||
|
|
||||||
// GPIO pins for the devices (port.pin)
|
// GPIO pins for the devices (port.pin)
|
||||||
|
|
||||||
@ -89,75 +89,89 @@ enum battery_type:
|
|||||||
BATTERY_CHARGED
|
BATTERY_CHARGED
|
||||||
|
|
||||||
class Keyboard:
|
class Keyboard:
|
||||||
enum { NUM_COLS = 17 }
|
unsigned keys[GPIO_KBD_NUM_COLS]
|
||||||
enum { COL_MASK = 0x2000ffff }
|
void parse (unsigned col, unsigned data):
|
||||||
enum { ROW_MASK = 0x000000ff }
|
for unsigned row = 0; row < GPIO_KBD_NUM_ROWS; ++row:
|
||||||
|
if (data ^ keys[col]) & (1 << row):
|
||||||
unsigned keys[NUM_COLS]
|
unsigned code = (col << 3) | row
|
||||||
bool scanning
|
if data & (1 << row):
|
||||||
|
code |= 0x10000
|
||||||
|
event (KEYBOARD_EVENT, code)
|
||||||
|
keys[col] = data
|
||||||
public:
|
public:
|
||||||
bool is_scanning ():
|
void scan ():
|
||||||
return scanning
|
kdebug ("keyboard scan\n")
|
||||||
|
// Disable interrupts during scan.
|
||||||
|
GPIO_GPIER (GPIO_KBD_ROW_PORT) &= ~GPIO_KBD_ROW_MASK
|
||||||
|
// All columns are input.
|
||||||
|
GPIO_GPDIR (GPIO_KBD_COL_PORT) &= ~GPIO_KBD_COL_MASK
|
||||||
|
int const cols[GPIO_KBD_NUM_COLS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 29 }
|
||||||
|
unsigned dir = GPIO_GPDIR (GPIO_KBD_COL_PORT) & ~GPIO_KBD_COL_MASK
|
||||||
|
unsigned dat = GPIO_GPDR (GPIO_KBD_COL_PORT) & ~GPIO_KBD_COL_MASK
|
||||||
|
unsigned data
|
||||||
|
for unsigned col = 0; col < GPIO_KBD_NUM_COLS; ++col:
|
||||||
|
// clear pin
|
||||||
|
GPIO_GPDR (GPIO_KBD_COL_PORT) = dat
|
||||||
|
// output
|
||||||
|
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir | (1 << cols[col])
|
||||||
|
// Generate events of previous column. Do that now, so there is a short delay for the data to stabilize.
|
||||||
|
if col != 0:
|
||||||
|
parse (col - 1, data)
|
||||||
|
else:
|
||||||
|
// Add a short delay for stabilization.
|
||||||
|
parse (0, keys[0])
|
||||||
|
data = GPIO_GPDR (GPIO_KBD_ROW_PORT) & GPIO_KBD_ROW_MASK
|
||||||
|
// set pin
|
||||||
|
GPIO_GPDR (GPIO_KBD_COL_PORT) = dat | (1 << cols[col])
|
||||||
|
// input
|
||||||
|
GPIO_GPDIR (GPIO_KBD_COL_PORT) = dir
|
||||||
|
parse (GPIO_KBD_NUM_COLS - 1, data)
|
||||||
|
// 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
|
||||||
|
// clear pending interrupts.
|
||||||
|
for unsigned i = 0; i < 8; ++i:
|
||||||
|
GPIO_GPFR (GPIO_KBD_ROW_PORT) |= 1 << i
|
||||||
|
// Reenable interrupts.
|
||||||
|
GPIO_GPIER (GPIO_KBD_ROW_PORT) |= GPIO_KBD_ROW_MASK
|
||||||
Keyboard ():
|
Keyboard ():
|
||||||
// Set all columns to input and disable the pull-ups.
|
// Set all columns to output without pull-ups when set as input.
|
||||||
GPIO_GPDIR (3) &= ~COL_MASK
|
GPIO_GPPUR (GPIO_KBD_COL_PORT) &= ~GPIO_KBD_COL_MASK
|
||||||
GPIO_GPPUR (3) &= ~COL_MASK
|
GPIO_GPDIR (GPIO_KBD_COL_PORT) |= GPIO_KBD_COL_MASK
|
||||||
|
|
||||||
// Set all rows to input and enable the pull-ups.
|
// Set all rows to input and enable the pull-ups.
|
||||||
GPIO_GPDIR (0) &= ~ROW_MASK
|
GPIO_GPPUR (GPIO_KBD_ROW_PORT) |= GPIO_KBD_ROW_MASK
|
||||||
GPIO_GPPUR (0) |= ROW_MASK
|
GPIO_GPDIR (GPIO_KBD_ROW_PORT) &= ~GPIO_KBD_ROW_MASK
|
||||||
// Enable interrupts on falling edge.
|
// Detect interrupts on falling edge.
|
||||||
GPIO_GPIDLR (0) = (GPIO_GPIDLR (0) & 0xffff) | (GPIO_IRQ_FALLEDG * 0xaaaa)
|
for unsigned i = 0; i < GPIO_KBD_NUM_ROWS; ++i:
|
||||||
GPIO_GPIER (0) |= 0xff
|
gpio_irq_fall (GPIO_KBD_ROW_PORT, i)
|
||||||
scanning = false
|
// Initialize matrix.
|
||||||
|
for unsigned i = 0; i < GPIO_KBD_NUM_COLS; ++i:
|
||||||
for unsigned i = 0; i < NUM_COLS; ++i:
|
|
||||||
keys[i] = 0xff
|
keys[i] = 0xff
|
||||||
|
// Perform initial scan to get real values into matrix and set up the rest.
|
||||||
scan ()
|
scan ()
|
||||||
void scan ():
|
|
||||||
// Set all columns to 0 when they become output.
|
|
||||||
GPIO_GPDR (3) &= ~COL_MASK
|
|
||||||
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)
|
|
||||||
unsigned data = GPIO_GPDR (0) & ROW_MASK
|
|
||||||
// Generate events.
|
|
||||||
for unsigned row = 0; row < 8; ++row:
|
|
||||||
if (data ^ keys[col]) & (1 << row):
|
|
||||||
unsigned code = (row << 8) | col
|
|
||||||
if data & (1 << row):
|
|
||||||
code |= 0x10000
|
|
||||||
event (KEYBOARD_EVENT, code)
|
|
||||||
keys[col] = data
|
|
||||||
if data != ROW_MASK:
|
|
||||||
scanning = true
|
|
||||||
scanning = true
|
|
||||||
if scanning:
|
|
||||||
GPIO_GPDIR (3) &= ~COL_MASK
|
|
||||||
else:
|
|
||||||
GPIO_GPDIR (3) |= COL_MASK
|
|
||||||
|
|
||||||
class Touchpad:
|
class Touchpad:
|
||||||
unsigned old_state
|
unsigned old_state
|
||||||
public:
|
public:
|
||||||
void check_events ():
|
void check_events ():
|
||||||
unsigned state = GPIO_GPDR (0)
|
unsigned state = GPIO_GPDR (GPIO_TP_LEFT_PORT)
|
||||||
if (state ^ old_state) & (1 << GPIO_TP_LEFT):
|
if state & (1 << GPIO_TP_LEFT):
|
||||||
if state & (1 << GPIO_TP_LEFT):
|
gpio_irq_fall (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||||
gpio_irq_fall (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
if (state ^ old_state) & (1 << GPIO_TP_LEFT):
|
||||||
event (TOUCHPAD_EVENT, 0)
|
event (TOUCHPAD_EVENT, 0)
|
||||||
else:
|
else:
|
||||||
gpio_irq_rise (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
gpio_irq_rise (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||||
|
if (state ^ old_state) & (1 << GPIO_TP_LEFT):
|
||||||
event (TOUCHPAD_EVENT, 0x10000)
|
event (TOUCHPAD_EVENT, 0x10000)
|
||||||
if (state ^ old_state) & (1 << GPIO_TP_RIGHT):
|
if state & (1 << GPIO_TP_RIGHT):
|
||||||
if state & (1 << GPIO_TP_RIGHT):
|
gpio_irq_fall (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||||
gpio_irq_fall (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
if (state ^ old_state) & (1 << GPIO_TP_RIGHT):
|
||||||
event (TOUCHPAD_EVENT, 1)
|
event (TOUCHPAD_EVENT, 1)
|
||||||
else:
|
else:
|
||||||
gpio_irq_rise (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
gpio_irq_rise (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||||
|
if (state ^ old_state) & (1 << GPIO_TP_RIGHT):
|
||||||
event (TOUCHPAD_EVENT, 0x10001)
|
event (TOUCHPAD_EVENT, 0x10001)
|
||||||
old_state = state
|
old_state = state
|
||||||
Touchpad ():
|
Touchpad ():
|
||||||
@ -165,20 +179,13 @@ class Touchpad:
|
|||||||
gpio_as_input (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
gpio_as_input (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||||
gpio_as_input (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
gpio_as_input (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||||
GPIO_GPPUR (0) |= (1 << GPIO_TP_LEFT) | (1 << 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
|
old_state = 0
|
||||||
// See if they are already pressed. If so, the interrupt detection is changed.
|
// See if they are already pressed. Also set up interrupts.
|
||||||
check_events ()
|
check_events ()
|
||||||
// Now enable the interrupts.
|
// Now enable the interrupts.
|
||||||
GPIO_GPIER (0) |= (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT)
|
|
||||||
|
|
||||||
class Lockleds:
|
class Lockleds:
|
||||||
// Note that num lock is in port 2. The others are in port 0.
|
// Note that num lock is in port 2. The others are in port 0.
|
||||||
enum { NUM = 1 << 22 }
|
|
||||||
enum { CAPS = 1 << 27 }
|
|
||||||
enum { SCROLL = 1 << 9 }
|
|
||||||
public:
|
public:
|
||||||
Lockleds ():
|
Lockleds ():
|
||||||
gpio_as_output (GPIO_NUM_PORT, GPIO_NUM)
|
gpio_as_output (GPIO_NUM_PORT, GPIO_NUM)
|
||||||
@ -203,13 +210,11 @@ class Lockleds:
|
|||||||
|
|
||||||
class Power:
|
class Power:
|
||||||
// Power out is in port 2, the rest in port 3.
|
// Power out is in port 2, the rest in port 3.
|
||||||
enum { PWR_OUT = 1 << 2 }
|
|
||||||
enum { PWR_IN = 1 << 1 }
|
|
||||||
enum { BATTERY = 1 << 29 }
|
|
||||||
unsigned old_state
|
unsigned old_state
|
||||||
bool was_present
|
bool was_present
|
||||||
public:
|
public:
|
||||||
void poll ():
|
void poll ():
|
||||||
|
#if 0
|
||||||
// Switch off keyboard interrupts, because this may interfere with them.
|
// Switch off keyboard interrupts, because this may interfere with them.
|
||||||
GPIO_GPIER (0) &= ~0xff
|
GPIO_GPIER (0) &= ~0xff
|
||||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||||
@ -237,16 +242,16 @@ class Power:
|
|||||||
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
GPIO_GPDIR (3) &= ~(PWR_IN | BATTERY)
|
||||||
//udelay (100)
|
//udelay (100)
|
||||||
GPIO_GPIER (3) |= 0xff
|
GPIO_GPIER (3) |= 0xff
|
||||||
|
#endif
|
||||||
Power ():
|
Power ():
|
||||||
GPIO_GPDR (2) |= PWR_OUT
|
|
||||||
GPIO_GPDIR (2) |= PWR_OUT
|
|
||||||
was_present = true
|
was_present = true
|
||||||
old_state = BATTERY
|
//old_state = BATTERY
|
||||||
poll ()
|
poll ()
|
||||||
void poweroff ():
|
void poweroff ():
|
||||||
gpio_as_gpio (GPIO_PW_O_PORT, GPIO_PW_O)
|
// TODO: doesn't work.
|
||||||
gpio_as_output (GPIO_PW_O_PORT, GPIO_PW_O)
|
i2c_open ()
|
||||||
GPIO_GPDR (GPIO_PW_O) &= ~(1 << GPIO_PW_O)
|
i2c_write_page (I2C_DEV_MCU, I2C_MCU_SHUTDOWN, "\1", 1)
|
||||||
|
i2c_close ()
|
||||||
while true:
|
while true:
|
||||||
// Do nothing; wait until the device stops running.
|
// Do nothing; wait until the device stops running.
|
||||||
void reboot ():
|
void reboot ():
|
||||||
@ -257,29 +262,27 @@ class Power:
|
|||||||
|
|
||||||
// Not really a gpio device, but it's so small, and uses gpio, so I include it here to avoid ipc.
|
// Not really a gpio device, but it's so small, and uses gpio, so I include it here to avoid ipc.
|
||||||
class Pwm:
|
class Pwm:
|
||||||
// Pin definitions, all in port 2.
|
|
||||||
enum { PWM_ENABLE = 1 << 30 }
|
|
||||||
public:
|
public:
|
||||||
Pwm ():
|
Pwm ():
|
||||||
GPIO_GPDIR (2) |= PWM_ENABLE
|
GPIO_GPDIR (GPIO_PWM_ENABLE_PORT) |= 1 << GPIO_PWM_ENABLE
|
||||||
PWM_PER (0) = 300
|
PWM_PER (0) = 300
|
||||||
void set_backlight (bool state):
|
void set_backlight (unsigned level):
|
||||||
if state:
|
if level > 300:
|
||||||
PWM_DUT (0) = 300
|
level = 300
|
||||||
PWM_CTR (0) = 0xbf
|
PWM_DUT (0) = level
|
||||||
GPIO_GPDR (2) |= PWM_ENABLE
|
if level:
|
||||||
|
PWM_CTR (0) = 0x80
|
||||||
|
GPIO_GPDR (GPIO_PWM_ENABLE_PORT) |= 1 << GPIO_PWM_ENABLE
|
||||||
else:
|
else:
|
||||||
PWM_DUT (0) = 0
|
PWM_CTR (0) = 0x00
|
||||||
PWM_CTR (0) = 0x3f
|
GPIO_GPDR (GPIO_PWM_ENABLE_PORT) &= ~(1 << GPIO_PWM_ENABLE)
|
||||||
GPIO_GPDR (2) &= ~PWM_ENABLE
|
|
||||||
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
|
// TODO: make it really work as a pwm instead of a switch; check if pwm1 is connected to anything.
|
||||||
|
|
||||||
int main ():
|
int main ():
|
||||||
schedule ()
|
|
||||||
|
|
||||||
map_gpio ()
|
map_gpio ()
|
||||||
map_pwm0 ()
|
map_pwm0 ()
|
||||||
map_wdt ()
|
map_wdt ()
|
||||||
|
map_i2c ()
|
||||||
|
|
||||||
Keyboard kbd
|
Keyboard kbd
|
||||||
Touchpad tp
|
Touchpad tp
|
||||||
@ -287,6 +290,8 @@ int main ():
|
|||||||
Power power
|
Power power
|
||||||
Pwm pwm
|
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)
|
register_interrupt (IRQ_GPIO0)
|
||||||
|
|
||||||
Capability cap_kbd = receiver_create_capability (__my_receiver, CAP_KEYBOARD)
|
Capability cap_kbd = receiver_create_capability (__my_receiver, CAP_KEYBOARD)
|
||||||
@ -302,25 +307,27 @@ int main ():
|
|||||||
|
|
||||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||||
while true:
|
while true:
|
||||||
|
schedule ()
|
||||||
Message msg
|
Message msg
|
||||||
wait (&msg)
|
wait (&msg)
|
||||||
switch msg.protected_data:
|
switch msg.protected_data:
|
||||||
case ~0:
|
case ~0:
|
||||||
// Alarm.
|
// Alarm.
|
||||||
if kbd.is_scanning ():
|
kdebug ("alarm\n")
|
||||||
kbd.scan ()
|
// Periodically scan several devices.
|
||||||
//power.poll ()
|
kbd.scan ()
|
||||||
|
power.poll ()
|
||||||
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
receiver_set_alarm (__my_receiver, ALARM_INTERVAL)
|
||||||
break
|
break
|
||||||
case IRQ_GPIO0:
|
case IRQ_GPIO0:
|
||||||
kdebug ("gpio interrupt")
|
kdebug ("gpio interrupt\n")
|
||||||
unsigned irq = GPIO_GPFR (0)
|
//unsigned irq = GPIO_GPFR (0)
|
||||||
// Ack all. This works because they are all edge triggered.
|
// Ack all.
|
||||||
GPIO_GPFR (0) = irq
|
GPIO_GPFR (0) = (1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT) | GPIO_KBD_ROW_MASK
|
||||||
if irq & 0xff:
|
// Always scan keyboard and touchpad on any interrupt.
|
||||||
kbd.scan ()
|
kbd.scan ()
|
||||||
if irq & ((1 << GPIO_TP_LEFT) | (1 << GPIO_TP_RIGHT)):
|
tp.check_events ()
|
||||||
tp.check_events ()
|
// Reregister the interrupt.
|
||||||
register_interrupt (IRQ_GPIO0)
|
register_interrupt (IRQ_GPIO0)
|
||||||
break
|
break
|
||||||
case CAP_KEYBOARD:
|
case CAP_KEYBOARD:
|
||||||
|
@ -39,7 +39,7 @@ static void setup ():
|
|||||||
wait (&msg)
|
wait (&msg)
|
||||||
switch msg.data[0]:
|
switch msg.data[0]:
|
||||||
case INIT_SET_GPIO_0:
|
case INIT_SET_GPIO_0:
|
||||||
kdebug ("gpio 0")
|
kdebug ("gpio 0\n")
|
||||||
kbd = msg.cap[0]
|
kbd = msg.cap[0]
|
||||||
tp = msg.cap[1]
|
tp = msg.cap[1]
|
||||||
poweroff = msg.cap[2]
|
poweroff = msg.cap[2]
|
||||||
@ -47,14 +47,14 @@ static void setup ():
|
|||||||
++state
|
++state
|
||||||
break
|
break
|
||||||
case INIT_SET_GPIO_1:
|
case INIT_SET_GPIO_1:
|
||||||
kdebug ("gpio 1")
|
kdebug ("gpio 1\n")
|
||||||
battery = msg.cap[0]
|
battery = msg.cap[0]
|
||||||
lockleds = msg.cap[1]
|
lockleds = msg.cap[1]
|
||||||
pwm = msg.cap[2]
|
pwm = msg.cap[2]
|
||||||
++state
|
++state
|
||||||
break
|
break
|
||||||
case INIT_SET_LCD:
|
case INIT_SET_LCD:
|
||||||
kdebug ("lcd")
|
kdebug ("lcd\n")
|
||||||
lcd = msg.cap[0]
|
lcd = msg.cap[0]
|
||||||
++state
|
++state
|
||||||
break
|
break
|
||||||
@ -67,10 +67,11 @@ static void setup ():
|
|||||||
invoke_01 (pwm, 1)
|
invoke_01 (pwm, 1)
|
||||||
|
|
||||||
int main ():
|
int main ():
|
||||||
|
// Set up lcd first
|
||||||
schedule ()
|
schedule ()
|
||||||
kdebug ("start init")
|
kdebug ("start init\n")
|
||||||
setup ()
|
setup ()
|
||||||
kdebug ("run init")
|
kdebug ("run init\n")
|
||||||
while true:
|
while true:
|
||||||
Message msg
|
Message msg
|
||||||
wait (&msg)
|
wait (&msg)
|
||||||
@ -81,9 +82,14 @@ int main ():
|
|||||||
kdebug_char ('\n')
|
kdebug_char ('\n')
|
||||||
break
|
break
|
||||||
case TP:
|
case TP:
|
||||||
if msg.data[0] == 0:
|
unsigned leds = 0
|
||||||
// Press left button.
|
if msg.data[0] & 1:
|
||||||
invoke_00 (poweroff)
|
leds |= 0x1
|
||||||
|
else:
|
||||||
|
leds |= 0x4
|
||||||
|
if !(msg.data[0] & 0x10000):
|
||||||
|
leds |= 0x2
|
||||||
|
invoke_01 (lockleds, leds)
|
||||||
break
|
break
|
||||||
case POWERBUTTON:
|
case POWERBUTTON:
|
||||||
kdebug ("powerbutton event\n")
|
kdebug ("powerbutton event\n")
|
||||||
|
17
iris.h
17
iris.h
@ -30,7 +30,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Number of clock interrupts per second.
|
// Number of clock interrupts per second.
|
||||||
#define HZ 10
|
#define HZ 20
|
||||||
|
|
||||||
#define PAGE_BITS (12)
|
#define PAGE_BITS (12)
|
||||||
#define PAGE_SIZE (1 << PAGE_BITS)
|
#define PAGE_SIZE (1 << PAGE_BITS)
|
||||||
@ -441,6 +441,20 @@ static void invoke_41 (Capability t, Capability c0, Capability c1, Capability c2
|
|||||||
invoke (t, &msg);
|
invoke (t, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void call_00 (Capability c)
|
||||||
|
{
|
||||||
|
Message msg;
|
||||||
|
msg.cap[0] = c;
|
||||||
|
msg.data[0] = 0;
|
||||||
|
msg.data[1] = 0;
|
||||||
|
msg.data[2] = 0;
|
||||||
|
msg.data[3] = 0;
|
||||||
|
msg.cap[1] = 0;
|
||||||
|
msg.cap[2] = 0;
|
||||||
|
msg.cap[3] = 0;
|
||||||
|
call (__my_call, &msg);
|
||||||
|
}
|
||||||
|
|
||||||
static Capability call_c01 (Capability c, unsigned d)
|
static Capability call_c01 (Capability c, unsigned d)
|
||||||
{
|
{
|
||||||
Message msg;
|
Message msg;
|
||||||
@ -760,7 +774,6 @@ static unsigned memory_limit (Capability memory, unsigned limit)
|
|||||||
|
|
||||||
static void drop (Capability cap)
|
static void drop (Capability cap)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
invoke_11 (__my_memory, cap, CAP_MEMORY_DROP);
|
invoke_11 (__my_memory, cap, CAP_MEMORY_DROP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1399,8 +1399,15 @@ static void __map_io (unsigned physical, unsigned mapping):
|
|||||||
#define I2C_SR_DRF (1 << 1)
|
#define I2C_SR_DRF (1 << 1)
|
||||||
#define I2C_SR_ACKF (1 << 0)
|
#define I2C_SR_ACKF (1 << 0)
|
||||||
|
|
||||||
|
#define I2C_WRITE 0
|
||||||
|
#define I2C_READ 1
|
||||||
|
|
||||||
|
/* I2C devices */
|
||||||
|
#define I2C_DEV_MCU 0x48
|
||||||
|
/* I2C device registers */
|
||||||
|
#define I2C_MCU_SHUTDOWN 0xd8
|
||||||
|
#define I2C_MCU_BAT_STATUS 0xdb
|
||||||
|
#define I2C_MCU_BAT_CHARGE 0xd9
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* UDC usb device controller (unused in trendtac)
|
* UDC usb device controller (unused in trendtac)
|
||||||
@ -2821,8 +2828,8 @@ static __inline__ unsigned msc_calc_slow_clk_divisor (bool is_sd):
|
|||||||
|
|
||||||
#define GPIO_PW_I_PORT 3
|
#define GPIO_PW_I_PORT 3
|
||||||
#define GPIO_PW_I 1
|
#define GPIO_PW_I 1
|
||||||
#define GPIO_PW_O_PORT 2
|
#define GPIO_MCU_PORT 2
|
||||||
#define GPIO_PW_O 2
|
#define GPIO_MCU 1
|
||||||
#define GPIO_LED_EN_PORT 2
|
#define GPIO_LED_EN_PORT 2
|
||||||
#define GPIO_LED_EN 28
|
#define GPIO_LED_EN 28
|
||||||
#define GPIO_DISP_OFF_N_PORT 2
|
#define GPIO_DISP_OFF_N_PORT 2
|
||||||
@ -2847,6 +2854,15 @@ static __inline__ unsigned msc_calc_slow_clk_divisor (bool is_sd):
|
|||||||
#define GPIO_TP_LEFT 16
|
#define GPIO_TP_LEFT 16
|
||||||
#define GPIO_TP_RIGHT_PORT 0
|
#define GPIO_TP_RIGHT_PORT 0
|
||||||
#define GPIO_TP_RIGHT 13
|
#define GPIO_TP_RIGHT 13
|
||||||
|
#define GPIO_PWM_ENABLE_PORT 2
|
||||||
|
#define GPIO_PWM_ENABLE 30
|
||||||
|
#define GPIO_KBD_NUM_ROWS 8
|
||||||
|
#define GPIO_KBD_NUM_COLS 17
|
||||||
|
#define GPIO_KBD_COL_PORT 3
|
||||||
|
#define GPIO_KBD_COL_MASK 0x2000ffff
|
||||||
|
#define GPIO_KBD_ROW_PORT 0
|
||||||
|
#define GPIO_KBD_ROW_MASK 0x000000ff
|
||||||
|
#define GPIO_KBD_ROW_HALF 0x00005555
|
||||||
|
|
||||||
#define GPIO_HALF(x) (((x) & 0xf) << 1)
|
#define GPIO_HALF(x) (((x) & 0xf) << 1)
|
||||||
|
|
||||||
@ -3012,6 +3028,48 @@ static __inline__ void gpio_as_cim ():
|
|||||||
#define i2c_read() ( I2C_DR )
|
#define i2c_read() ( I2C_DR )
|
||||||
#define i2c_write(val) ( I2C_DR = (val) )
|
#define i2c_write(val) ( I2C_DR = (val) )
|
||||||
|
|
||||||
|
#ifndef __KERNEL
|
||||||
|
static __inline__ void i2c_open ():
|
||||||
|
i2c_set_clk (JZ_EXTAL, 10000)
|
||||||
|
i2c_enable ()
|
||||||
|
|
||||||
|
// Note that this kills messages from the queue.
|
||||||
|
static __inline__ void i2c_close ():
|
||||||
|
Message msg
|
||||||
|
receiver_set_alarm (__my_receiver, 3 * HZ / 10)
|
||||||
|
call_00 (0)
|
||||||
|
i2c_disable ()
|
||||||
|
|
||||||
|
static __inline__ bool i2c_send (unsigned data):
|
||||||
|
unsigned timeout = 10000
|
||||||
|
i2c_write (data)
|
||||||
|
i2c_set_drf ()
|
||||||
|
while i2c_check_drf () != 0:
|
||||||
|
while !i2c_transmit_ended ():
|
||||||
|
while !i2c_received_ack ():
|
||||||
|
if !--timeout:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
static __inline__ unsigned i2c_write_page (unsigned dev, unsigned addr, char const *data, unsigned count):
|
||||||
|
unsigned timeout = 5
|
||||||
|
i2c_send_start ()
|
||||||
|
if !i2c_send ((dev << 1) | I2C_WRITE):
|
||||||
|
i2c_send_stop ()
|
||||||
|
return 0
|
||||||
|
if !i2c_send (addr):
|
||||||
|
i2c_send_stop ()
|
||||||
|
return 0
|
||||||
|
if count > 8:
|
||||||
|
count = 8
|
||||||
|
unsigned i
|
||||||
|
for i = 0; i < count; ++i:
|
||||||
|
if !i2c_send (*data++):
|
||||||
|
break
|
||||||
|
i2c_send_stop ()
|
||||||
|
return i
|
||||||
|
#endif
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* UDC
|
* UDC
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
Loading…
Reference in New Issue
Block a user