blob: 0642f29b66bd4f5efede13f14a2bf82b2af9cc81 [file] [edit]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/* CAmkES provides a generated header that prototypes all the relevant generated
* symbols.
*/
#include <camkes.h>
#include <camkes/io.h>
#include <assert.h>
#include <keyboard/codes.h>
#include <keyboard/keyboard.h>
#include <ringbuffer/ringbuffer.h>
#include <utils/util.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
static ps_io_port_ops_t io_port_ops;
static uint8_t in8(uint16_t port)
{
uint32_t result = 0;
int error = ps_io_port_in(&io_port_ops, port, IOSIZE_8, &result);
if (error) {
return 0;
}
return (uint8_t) result;
}
static void out8(uint16_t port, uint8_t value)
{
ps_io_port_out(&io_port_ops, port, IOSIZE_8, value);
}
int run(void)
{
int error = camkes_io_port_ops(&io_port_ops);
assert(!error);
sel4keyboard_init(0, in8, out8);
ringbuffer_t *output = rb_new((void *)char_out, sizeof(*char_out));
if (output == NULL) {
abort();
}
/* Take each received character and pass it on to the switch. */
while (true) {
int c;
/* do basic tracking of multi byte sequences */
static int escape_code = 0;
static int escape_state = 0;
static int break_code = 0;
while (!sel4keyboard_get_scancode(&c));
/* first parse escape codes etc */
switch (c) {
case 0xf0:
break_code = 0xf0;
continue;
case 0xe0:
case 0xe1:
escape_code = c;
escape_state = 0;
continue;
default:
/* need to do actual parsing */
switch (escape_code) {
case 0xe1:
/* need to ignore two scancodes */
escape_state++;
if (escape_state == 2) {
escape_code = 0;
break_code = 0;
}
continue;
case 0xe0:
/* key down */
break_code = 0;
escape_code = 0;
continue;
default:
if (!break_code) {
break_code = 0;
escape_code = 0;
continue;
}
/* key up */
break_code = 0;
escape_code = 0;
break;
}
break;
}
char c1 = sel4keyboard_code_to_char(c);
if (c1 != 0) {
rb_transmit_byte(output, (unsigned char)c1);
}
}
return 0;
}