boolean put_handler(TinyWebServer& web_server) { const char* length_str = web_server.get_header_value(PSTR("Content-Length")); long length = atol(length_str); uint32_t start_time = 0; boolean watchdog_start = false; char buffer_[512]; EthernetClient client = web_server.get_client(); if (put_handler_fn) { (*put_handler_fn)(web_server, START, NULL, length); } uint32_t i; for (i = 0; i < length && client.connected();) { // int16_t size = read_chars(web_server, client, (uint8_t*)buffer, 64); int16_t size = read_fast(web_server, client, (uint8_t*)buffer_, sizeof(buffer_)); if (!size) { if (watchdog_start) { if (millis() - start_time > 30000) { // Exit if there has been zero data from connected client // for more than 30 seconds. #if DEBUG Serial << F("TWS:There has been no data for >30 Sec.\n"); #endif break; } } else { // We have hit an empty buffer, start the watchdog. start_time = millis(); watchdog_start = true; } continue; } i += size; // Ensure we re-start the watchdog if we get ANY data input. watchdog_start = false; if (put_handler_fn) { (*put_handler_fn)(web_server, WRITE, buffer_, size); } } if (put_handler_fn) { (*put_handler_fn)(web_server, END, NULL, 0); } client << F("HTTP/1.1 200 OK\r\n"); // web_server.send_error_code(200); web_server.end_headers(); return true; }
int KBM::transform_vk(uint8_t scancode) { if (scancode == 0x0) { return VK_UNKNOWN; } else if (scancode <= 0x0A) { return VK_ESCAPE + scancode - 1; } else if (scancode == 0xE0) { scancode = read_fast(); switch (scancode) { case 0x48: return VK_UP; case 0x4B: return VK_LEFT; case 0x4D: return VK_RIGHT; case 0x50: return VK_DOWN; default: return VK_UNKNOWN; } } switch (scancode) { case 0x0E: return VK_BACK; case 0x0F: return VK_TAB; case 0x1C: return VK_ENTER; case 0x39: return VK_SPACE; } return VK_UNKNOWN; }
void KBM::init() { // disable ports ctl_send(CMD_DISABLE_PORT1); ctl_send(CMD_DISABLE_PORT2); ps2_flush(); // configure controller ctl_send(0x20); uint8_t config = read_data(); bool second_port = config & (1 << 5); (void) second_port; config |= 0x1 | 0x2; // enable interrupts config &= ~(1 << 6); // write config ctl_send(0x60); send_data(config); ps2_flush(); // enable port1 ctl_send(CMD_ENABLE_PORT1); ps2_flush(); // self-test (port1) write_port1(0xFF); uint8_t selftest = read_data(); assert(selftest == 0xAA); write_port1(DEV_IDENTIFY); uint8_t id1 = read_data(); if (id1 == 0xAA || id1 == 0xAB) { // port1 is the keyboard debug("keyboard on port1\n"); keyboard_write = write_port1; mouse_write = write_port2; } else { // port2 is the keyboard debug("keyboard on port2\n"); mouse_write = write_port1; keyboard_write = write_port2; } // enable keyboard keyboard_write(0xF4); // get and set scancode keyboard_write(0xF0); send_data(0x01); keyboard_write(0xF0); send_data(0x00); uint8_t scanset = 0xFA; while (scanset == 0xFA) scanset = read_data(); // route and enable interrupt handlers const uint8_t KEYB_IRQ = (keyboard_write == write_port1) ? PORT1_IRQ : PORT2_IRQ; const uint8_t MOUS_IRQ = (KEYB_IRQ == PORT1_IRQ) ? PORT2_IRQ : PORT1_IRQ; assert(KEYB_IRQ != MOUS_IRQ); // need to route IRQs from IO APIC to BSP LAPIC IRQ_manager::get().enable_irq(KEYB_IRQ); IRQ_manager::get().enable_irq(MOUS_IRQ); IRQ_manager::get().subscribe(KEYB_IRQ, [KEYB_IRQ] { //IRQ_manager::eoi(KEYB_IRQ); uint8_t byte = read_fast(); // transform to virtual key int key = get().transform_vk(byte); // call handler get().on_virtualkey(key); }); IRQ_manager::get().subscribe(MOUS_IRQ, [MOUS_IRQ] { //IRQ_manager::eoi(MOUS_IRQ); get().handle_mouse(read_fast()); }); /* // reset and enable keyboard send_data(0xF6); // enable keyboard scancodes send_data(0xF4); // enable interrupts //ctl_send(0x60, ctl_read(0x20) | 0x1 | 0x2); */ }