1/* 2 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7/* CAmkES provides a generated header that prototypes all the relevant generated 8 * symbols. 9 */ 10#include <camkes.h> 11#include <camkes/io.h> 12 13#include <assert.h> 14#include <keyboard/codes.h> 15#include <keyboard/keyboard.h> 16#include <ringbuffer/ringbuffer.h> 17#include <utils/util.h> 18#include <stdbool.h> 19#include <stdint.h> 20#include <stdlib.h> 21 22static ps_io_port_ops_t io_port_ops; 23 24static uint8_t in8(uint16_t port) 25{ 26 uint32_t result = 0; 27 int error = ps_io_port_in(&io_port_ops, port, IOSIZE_8, &result); 28 if (error) { 29 return 0; 30 } 31 return (uint8_t) result; 32} 33 34static void out8(uint16_t port, uint8_t value) 35{ 36 ps_io_port_out(&io_port_ops, port, IOSIZE_8, value); 37} 38 39int run(void) 40{ 41 int error = camkes_io_port_ops(&io_port_ops); 42 assert(!error); 43 44 sel4keyboard_init(0, in8, out8); 45 46 ringbuffer_t *output = rb_new((void *)char_out, sizeof(*char_out)); 47 if (output == NULL) { 48 abort(); 49 } 50 51 /* Take each received character and pass it on to the switch. */ 52 while (true) { 53 int c; 54 55 /* do basic tracking of multi byte sequences */ 56 static int escape_code = 0; 57 static int escape_state = 0; 58 static int break_code = 0; 59 60 while (!sel4keyboard_get_scancode(&c)); 61 62 /* first parse escape codes etc */ 63 switch (c) { 64 case 0xf0: 65 break_code = 0xf0; 66 continue; 67 case 0xe0: 68 case 0xe1: 69 escape_code = c; 70 escape_state = 0; 71 continue; 72 default: 73 /* need to do actual parsing */ 74 switch (escape_code) { 75 case 0xe1: 76 /* need to ignore two scancodes */ 77 escape_state++; 78 if (escape_state == 2) { 79 escape_code = 0; 80 break_code = 0; 81 } 82 continue; 83 case 0xe0: 84 /* key down */ 85 break_code = 0; 86 escape_code = 0; 87 continue; 88 default: 89 if (!break_code) { 90 break_code = 0; 91 escape_code = 0; 92 continue; 93 } 94 /* key up */ 95 break_code = 0; 96 escape_code = 0; 97 break; 98 } 99 break; 100 } 101 102 char c1 = sel4keyboard_code_to_char(c); 103 if (c1 != 0) { 104 rb_transmit_byte(output, (unsigned char)c1); 105 } 106 } 107 108 return 0; 109} 110