~foura/uxn900

612e4d885283caa9a1950e2f185e8ec30ba562c3 — james palmer 2 months ago 7a02d9a
controller: mostly complete implementation. works mostly as expected.

in the future i would like the camera button on the back of the n900
to function as the start button. it's a gpio rather than being connected
as part of the keyboard matrix, so it would need some extra logic.
2 files changed, 78 insertions(+), 20 deletions(-)

M src/dev/controller.c
M src/inc/dev/controller.h
M src/dev/controller.c => src/dev/controller.c +76 -16
@@ 23,6 23,28 @@ enum {
	Rsih  = 0xe9,
};

static char keymap[256] = {
	'q', 'o', 'p',  ',', '\b',   0, 'a', 's',
	'w', 'd', 'f',  'g',  'h', 'j', 'k', 'l',
	'e', '.',   0, '\r',    0, 'z', 'x', 'c',
	'r', 'v', 'b', 'n',   'm',   0, ' ',   0,
	't',   0,   0,   0,     0,   0,   0,   0,
	'y',   0,   0,   0,     0,   0,   0,   0,
	'u',   0,   0,   0,     0,   0,   0,   0,
	'i',   0,   0,   0,     0,   0,   0,   0,
};

static char keymap_fn[] = {
	'1', '9',  '0',  '=', '\b',   0, '*', '+',
	'2', '#',  '-',  '_',  '(', ')', '&', '!',
	'3', '?',  '^', '\r',    0,   0, '$',   0,
	'4', '/', '\\',  '"', '\'', '@',   0, '<',
	'5', '|',  '>',    0,    0,   0,   0,   0,
	'6',   0,    0,    0,    0,   0,   0,   0,
	'7',   0,    0,    0,    0,   0,   0,   0,
	'8',   0,    0,    0,    0,   0,   0,   0,
};

void
controller_init(Controller *ctrl)
{


@@ 57,8 79,7 @@ controller_init(Controller *ctrl)
	i2c_write(PHYSI2C1, Ckp, buf, 1, 1);

	/* clear state */
	ctrl->raw.curmods = 0;
	ctrl->raw.prevmods = 0;
	ctrl->raw.mods = 0;
	for(i = 0; i < 8; i++) {
		ctrl->raw.cur[i] = 0;
		ctrl->raw.prev[i] = 0;


@@ 76,19 97,15 @@ controller_button(Controller *ctrl, Uxn *u, Uint8 code)
	case 0x1f: ctrl->buttons |= 0x40; break; /* left */
	case 0x22: ctrl->buttons |= 0x80; break; /* right */
	}

	/* arrow keys should not trigger if fn is pressed (says u-boot) */
	if(ctrl->raw.curmods & 2)
		ctrl->buttons &= 0x0f;
}

static void
controller_process_buttons(Controller *ctrl, Uxn *u)
{
	int col, row;
	Uint8 c, last;
	Uint8 c;

	last = ctrl->buttons;
	ctrl->prevbuttons = ctrl->buttons;
	ctrl->buttons = 0;

	/* scan the keyboard matrix */


@@ 103,22 120,59 @@ controller_process_buttons(Controller *ctrl, Uxn *u)
		}
	}

	if(ctrl->buttons != last)
		uxn_eval(u, ctrl->vector);
	/* ctrl must be a for keyboard shortcuts */
	if(ctrl->raw.mods & 1)
		ctrl->buttons |= 0x01;

	/* shift must be select for keyboard shortcuts */
	if(ctrl->raw.mods & 4)
		ctrl->buttons |= 0x04;

	/* arrow keys should not trigger if fn is pressed (says u-boot) */
	if(ctrl->raw.mods & 2)
		ctrl->buttons &= 0x0f;
}

static void
static int
controller_key(Controller *ctrl, Uxn *u, Uint8 code)
{
	Uint8 k;
	Uint8 mods = ctrl->raw.mods;

	k = 0;
	if(mods & 2) {
		k = keymap_fn[code];
	} else {
		k = keymap[code];

		/* shift key pressed */
		if(mods & 4) {
			if (k >= 'a' && k <= 'z')
				k += 'A' - 'a';
			if (k == '.')
				k = ':';
			else if (k == ',')
				k = ';';
		}
	}

	ctrl->key = k;
	if(ctrl->key) {
		uxn_eval(u, ctrl->vector);
		return 1;
	}

	return 0;
}

static void
controller_process_keys(Controller *ctrl, Uxn *u)
{
	int col, row;
	Uint8 c;
	Uint8 c, nkeys;

	/* scan the keyboard matrix */
	nkeys = 0;
	for(col = 0; col < 8; col++) {
		/* newly pressed keys only */
		c  = ctrl->raw.cur[col];


@@ 127,11 181,18 @@ controller_process_keys(Controller *ctrl, Uxn *u)

		for(row = 0; row < 8; row++) {
			if(c & 1)
				controller_key(ctrl, u, col * 8 + row);
				nkeys += controller_key(ctrl, u, col * 8 + row);

			c = c >> 1;
		}
	}

	/* funny place to do this but hey.
	   if no keys are pressed but the button state changed, eval anyway */
	if(nkeys == 0 && ctrl->prevbuttons != ctrl->buttons) {
		ctrl->key = 0;
		uxn_eval(u, ctrl->vector);
	}
}

void


@@ 154,9 215,8 @@ controller_poll(Controller *ctrl, Uxn *u)
			i2c_read(PHYSI2C1, Ckp, buf, 1, 1);

			/* extract modifiers */
			if(j == 5) {
				ctrl->raw.prevmods = ctrl->raw.curmods;
				ctrl->raw.curmods  = buf[1] >> 4;
			if(j == 4) {
				ctrl->raw.mods = buf[1] >> 4;
				buf[1] &= 0x0f;
			}


M src/inc/dev/controller.h => src/inc/dev/controller.h +2 -4
@@ 1,15 1,13 @@
typedef struct Controller Controller;
struct Controller {
	Uint16 vector;
	Uint8 buttons;
	Uint8 buttons, prevbuttons;
	Uint8 key;

	struct {
		Uint8 mods;
		Uint8 cur[8];
		Uint8 curmods;

		Uint8 prev[8];
		Uint8 prevmods;
	} raw;
};