Skip to content

Commit

Permalink
[grifo] add an interrupt driven serial input
Browse files Browse the repository at this point in the history
the code to decode a few escape sequences is included
to all simulated button presses via the serial port

This probably should not be at interrupt state
and maybe there should be a mechanism to turn this on or off

Signed-off-by: Christopher Hall <hsw@openmoko.com>
  • Loading branch information
hxw committed Dec 28, 2010
1 parent b28e527 commit 59da482
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 10 deletions.
128 changes: 128 additions & 0 deletions samo-lib/grifo/src/serial.c
Expand Up @@ -29,16 +29,43 @@
#include <regs.h>

#include "watchdog.h"
#include "vector.h"
#include "interrupt.h"
#include "event.h"
#include "serial.h"


void receive_interrupt(void) __attribute__((interrupt_handler));


void Serial_initialise(void)
{
static bool initialised = false;
if (!initialised) {
initialised = true;
Vector_initialise();
Event_initialise();
Watchdog_initialise();

Interrupt_type state = Interrupt_disable();

SET_BRTRD(0, CALC_BAUD(PLL_CLK, 1, SERIAL_DIVMD, CONSOLE_BPS));

REG_INT_ESIF01 |= ESRX0 | ESERR0;

REG_INT_PLCDC_PSI00 |= SERIAL_CH0_INT_PRI_7;
int i;
for (i = 0; i < 6; ++i) {
// flush FIFO
register uint32_t c = REG_EFSIF0_RXD;
(void)c;
}

REG_INT_FSIF01 = FSTX0 | FSRX0 | FSERR0; // clear the interrupt

Vector_set(VECTOR_Serial_interface_Ch_0_Receive_error, receive_interrupt);
Vector_set(VECTOR_Serial_interface_Ch_0_Receive_buffer_full, receive_interrupt);
Interrupt_enable(state);
}
}

Expand Down Expand Up @@ -180,3 +207,104 @@ void Serial_HexDump(const void *buffer, size_t size)
Serial_print("|\n");
}
}


static int numeric_prefix;
static enum {
state_normal = 0,
state_escape,
state_escape_parameter,
} state;

void receive_interrupt(void)
{
Interrupt_SaveR15(); // must be first

REG_INT_FSIF01 = FSRX0 | FSERR0; // clear the interrupt
REG_EFSIF0_STATUS = 0; // clear errors

while (0 != (REG_EFSIF0_STATUS & RDBFx)) {
register uint32_t keycode = REG_EFSIF0_RXD;

event_t e;

// switch must perform one of the following actions:
// 1. continue
// 2. setup e.*
switch (state) {
case state_normal:
// escape sequence: <esc> ('[' | 'O') <digits> <letter-or-tilde>
if (27 == keycode) {
state = state_escape;
numeric_prefix = 0;
} else {
e.item_type = EVENT_KEY;
e.key.code = keycode;
Event_put(&e);
}
break;

case state_escape: // skip initial '[' or 'O'
state = state_escape_parameter;
break;

case state_escape_parameter: // sequence of digits ending with letter or '~'
if (isdigit(keycode)) {
numeric_prefix *= 10;
numeric_prefix += keycode - '0';
break;
} else {
state = state_normal;
}
e.item_type = EVENT_NONE;
#if 0
// cursor up <esc>[A
if ('A' == keycode) {
//CURSOR_UP
}
// cursor down <esc>[B
else if ('B' == keycode) {
//CURSOR_DOWN
}
// cursor right <esc>[C
else if ('C' == keycode) {
//CURSOR_RIGHT
}
// cursor left <esc>[D
else if ('D' == keycode) {
//CURSOR_LEFT
}
// home <esc>OH
else
#endif
if ('H' == keycode) {
e.item_type = EVENT_BUTTON_DOWN;
e.button.code = BUTTON_SEARCH;
}
// end <esc>OF
else if ('F' == keycode) {
e.item_type = EVENT_BUTTON_DOWN;
e.button.code = BUTTON_HISTORY;
}
// page up <esc>[5~
else if ('~' == keycode && 5 == numeric_prefix) {
e.item_type = EVENT_BUTTON_DOWN;
e.button.code = BUTTON_RANDOM;
}
// send button down/up
if (EVENT_BUTTON_DOWN == e.item_type) {
Event_put(&e);
e.item_type = EVENT_BUTTON_UP;
Event_put(&e);
}
break;

default:
state = state_normal;
break;
}
}
REG_EFSIF0_STATUS = 0; // clear errors

Interrupt_RestoreR15(); // must be last
}
31 changes: 21 additions & 10 deletions samo-lib/include/regs.h
Expand Up @@ -55,7 +55,7 @@
#define REG_INT_P16T01 *((REG_TYPE_8 *) (REG_BASE + 0x266))
#define REG_INT_P16T23 *((REG_TYPE_8 *) (REG_BASE + 0x267))
#define REG_INT_P16T45 *((REG_TYPE_8 *) (REG_BASE + 0x268))
#define REG_INT_PLCDC_PSIO0 *((REG_TYPE_8 *) (REG_BASE + 0x269))
#define REG_INT_PLCDC_PSI00 *((REG_TYPE_8 *) (REG_BASE + 0x269))
#define REG_INT_PSI01_PAD *((REG_TYPE_8 *) (REG_BASE + 0x26a))
#define REG_INT_PRTC *((REG_TYPE_8 *) (REG_BASE + 0x26b))
#define REG_INT_PP45L *((REG_TYPE_8 *) (REG_BASE + 0x26c))
Expand Down Expand Up @@ -909,15 +909,26 @@
#define APPON (1 << 1)
#define IQB (1 << 0)

// Bits for: REG_CH1_INT_PRIORITY
#define SERIAL_CH1_INT_PRI_7 0x7
#define SERIAL_CH1_INT_PRI_6 0x6
#define SERIAL_CH1_INT_PRI_5 0x5
#define SERIAL_CH1_INT_PRI_4 0x4
#define SERIAL_CH1_INT_PRI_3 0x3
#define SERIAL_CH1_INT_PRI_2 0x2
#define SERIAL_CH1_INT_PRI_1 0x1
#define SERIAL_CH1_INT_PRI_0 0x0

// Bits for: REG_INT_PLCDC_PSI00
#define SERIAL_CH0_INT_PRI_7 0x70
#define SERIAL_CH0_INT_PRI_6 0x60
#define SERIAL_CH0_INT_PRI_5 0x50
#define SERIAL_CH0_INT_PRI_4 0x40
#define SERIAL_CH0_INT_PRI_3 0x30
#define SERIAL_CH0_INT_PRI_2 0x20
#define SERIAL_CH0_INT_PRI_1 0x10
#define SERIAL_CH0_INT_PRI_0 0x00

// Bits for: REG_INT_PSI01_PAD
#define SERIAL_CH1_INT_PRI_7 0x07
#define SERIAL_CH1_INT_PRI_6 0x06
#define SERIAL_CH1_INT_PRI_5 0x05
#define SERIAL_CH1_INT_PRI_4 0x04
#define SERIAL_CH1_INT_PRI_3 0x03
#define SERIAL_CH1_INT_PRI_2 0x02
#define SERIAL_CH1_INT_PRI_1 0x01
#define SERIAL_CH1_INT_PRI_0 0x00


/*
Expand Down

0 comments on commit 59da482

Please sign in to comment.