static void ms_ps2_handleEvents(_self) { unsigned char buf[3*8]; int n; if ((n= ms_read(self, buf, sizeof(buf), 3, PS2_READ_DELAY)) >= 3) { unsigned char *cmd= buf; while (n >= 3) { int b= 0, dx, dy; // The protocol requires the top 2 bits clear and bit 3 set. // Some Micro$oft mice violate this, but any luser stupid // enough to buy a M$ mouse deserves what they get. if (0x08 != (cmd[0] & 0xc8)) { fprintf(stderr, "%s: illegal command: %02x %02x %02x\n", self->msName, cmd[0], cmd[1], cmd[2]); ms_ps2_flush(self); // resync the stream return; } if (cmd[0] & 1) b |= RedButtonBit; if (cmd[0] & 2) b |= BlueButtonBit; if (cmd[0] & 4) b |= YellowButtonBit; dx= cmd[1]; if (cmd[0] & 0x10) dx -= 256; dy= cmd[2]; if (cmd[0] & 0x20) dy -= 256; dy= -dy; self->callback(b, dx, dy); n -= 3; cmd += 3; } } }
static int ms_ps2_reset(_self) { unsigned char command[]= { PS2_RESET }, buf[2]; DPRINTF("%s: reset\n", self->msName); if (!ms_ps2_send(self, command, sizeof(command))) return -1; if (2 == ms_read(self, buf, 2, 2, PS2_RESET_DELAY)) { DPRINTF("%s: response %02x %02x\n", self->msName, buf[0], buf[1]); switch (buf[0]) { case PS2_SELFTEST_OK: return buf[1]; // mouse device id break; case PS2_ERROR: fprintf(stderr, "%s: self-test failed\n", self->msName); break; default: DPRINTF("%s: bad response\n", self->msName); break; } } /* /dev/input/mice emulation returns PS2_SELFTEST_OK where send() expects PS2_OK, causing control to fall through to here. we pick up the mouse id immediately in the flush(), so the only harm done is a misleading "reset failed" message while debugging. */ ms_ps2_flush(self); DPRINTF("%s: reset failed\n", self->msName); return -1; }
static void ms_ps2_flush(_self) { unsigned char buf[32]; DPRINTF("%s: flush\n", self->msName); while (ms_read(self, buf, sizeof(buf), 1, PS2_FLUSH_DELAY)) ; }
static int ms_ps2_send(_self, unsigned char *command, int len) { unsigned char buf[1]; int i; DPRINTF("%s: send\n", self->msName); for (i= 0; i < len; ++i) { resend: write(self->fd, command + i, 1); DPRINTF(">%02x\n", command[i]); if (1 != ms_read(self, buf, 1, 1, PS2_SEND_DELAY)) { DPRINTF("%s: send failed\n", self->msName); return 0; } switch (buf[0]) { case PS2_OK: case PS2_SELFTEST_OK: /* /dev/input/mice emulation is broken */ break; case PS2_ERROR: fprintf(stderr, "%s: error response in send\n", self->msName); return 0; case PS2_RESEND: DPRINTF("%s: resend\n", self->msName); goto resend; default: fprintf(stderr, "%s: illegal response %02x in send\n", self->msName, buf[0]); break; } } return 1; }
static void ms_adb_handleEvents(_self) { unsigned char cmd[3]; while (3 == ms_read(self, cmd, 3, 3, 0)) if (0x80 == (cmd[0] & 0xf8)) self->callback((cmd[0] & 7) ^ 7, (signed char)cmd[1], -(signed char)cmd[2]); }
static void ms_ps2_disable(_self) { unsigned char command[]= { PS2_DISABLE }; DPRINTF("%s: disable\n", self->msName); write(self->fd, command, 1); DPRINTF(">%02x\n", command[0]); while (1 == ms_read(self, command, 1, 1, PS2_DISABLE_DELAY)) if (PS2_OK == command[0]) break; }
int MS_to_KBD_Commands(unsigned char command) { unsigned long byte; do { ms_write(STAT_REG, MS_WRITE_BYTE); //first write command 0xD4 to the KBC, i.e. using port 0x64 do { ms_write(OUT_BUF, command); // mouse command to port 0x60 byte = ms_read(); //acknowledgment (message) in the output buffer } while (byte == MS_NACK); //the latest byte should be written again } while (byte == MS_ERROR); }
// main task loop called by yield code void user_loop(void) { extern int connections; uint32_t time1,time2; long t; #ifdef DISPLAY char time_tmp[32]; uint8_t red, blue,green; int touched; uint16_t X,Y; #endif // getinfo.ip.addr, getinfo.gw.addr, getinfo.netmask.addr struct ip_info getinfo; char *ptr; // ======================================================== // Run all remaining tasks once every 1mS t = ms_read(); if((t - last_time10) < 1U) return; last_time10 = t; // ======================================================== // Tasks that must run very fast , once every millisecond should be at the top #ifdef ADF4351 ADF4351_task(); #endif #ifdef XPT2046 XPT2046_task(); #endif // ======================================================== // Only run every 50mS t = ms_read(); if((t - last_time50) < 50U) return; last_time50 = t; // ======================================================== user_tasks(); // NTP state machine ntp_setup(); #ifdef DISPLAY #ifdef XPT2046 if(tft_is_calibrated) { touched = tft_touch_key(master,(uint16_t *)&X, (uint16_t *)&Y); #if XPT2046_DEBUG if(touched) tft_printf(winmsg,"X:%d,Y:%d\n",(int)X,(int)Y); #endif } #endif #ifdef NETWORK_TEST servertest_message(winmsg); #endif #ifdef DEBUG_STATS #ifdef VOLTAGE_TEST #ifdef DEBUG_STATS // Do NOT run adc_read() every millisecond as system_adc_read() blocks WIFI tft_set_textpos(wintop, 0,2); tft_printf(wintop,"Volt:%2.2f\n", (float)adc_read()); #endif #endif // VOLTAGE_TEST count += 1; tft_set_textpos(wintop, 0,0); tft_set_font(wintop,0); tft_font_fixed(wintop); tft_printf(wintop,"Iter:% 10ld, %+7.2f\n", count, degree); #endif #ifdef CIRCLE rad = dscale; // +/- 90 tft_drawCircle(wincube, wincube->w/2, wincube->h/2, rad ,wincube->bg); // RGB #endif // reset cube to background #ifdef WIRECUBE V.x = degree; V.y = degree; V.z = degree; // Cube points were defined with sides of 1.0 // We want a scale of +/- w/2 wire_draw(wincube, cube_points, cube_edges, &V, wincube->w/2, wincube->h/2, dscale, wincube->bg); #endif degree += deg_inc; dscale += dscale_inc; if(degree <= -360) deg_inc = 4; if(degree >= 360) deg_inc = -4; if(dscale < dscale_max/2) { dscale_inc = -dscale_inc; } if(dscale > dscale_max) { dscale_inc = -dscale_inc; } #ifdef WIRECUBE V.x = degree; V.y = degree; V.z = degree; wire_draw(wincube, cube_points, cube_edges, &V, wincube->w/2, wincube->h/2, dscale, ILI9341_WHITE); #endif #ifdef CIRCLE // Display bounding circle that changes color around the cube if(dscale_inc < 0.0) { red = 255; blue = 0; green = 0; } else { red = 0; blue = 0; green = 255; } rad = dscale; // +/- 90 tft_drawCircle(wincube, wincube->w/2, wincube->h/2, rad, tft_RGBto565(red,green,blue)); #endif #endif // DISPLAY // ======================================================== // Tasks run only once every second go after this time(&sec); if(sec == seconds) return; seconds=sec; // ======================================================== #ifdef DISPLAY // ======================================================== // TIME tft_set_textpos(winbottom, 0,0); //Tue May 17 18:56:01 2016 strncpy(time_tmp,ctime(&sec),31); time_tmp[19] = 0; tft_printf(winbottom," %s", time_tmp); tft_cleareol(winbottom); tft_set_textpos(winbottom, 0,1); // ======================================================== // CONNECTION status //tft_printf(winbottom," %s", ip_msg); // IP and disconnected connection state only if(wifi_get_ip_info(0, &getinfo)) tft_printf(winbottom," %s", ipv4_2str(getinfo.ip.addr)); else tft_printf(winbottom," Disconnected"); tft_cleareol(winbottom); #ifdef DEBUG_STATS // ======================================================== // HEAP size tft_set_textpos(wintop, 0,1); tft_printf(wintop,"Heap: %d, Conn:%d\n", system_get_free_heap_size(), connections); // ======================================================== // WIFI status tft_set_textpos(wintop, 0,3); tft_printf(wintop,"CH:%02d, DB:%+02d\n", wifi_get_channel(), wifi_station_get_rssi()); #endif // DEBUG_STATS #endif //DISPLAY }