/* * 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 #include #include #include #include #include #include #include #include #include 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; }