fix some bugs with USB HID; increase keyboard speed up to 950 symbols per minute

This commit is contained in:
eddyem 2019-04-30 14:48:01 +03:00
parent 2d9da87cd7
commit 24b953e3a3
7 changed files with 80 additions and 59 deletions

View File

@ -26,49 +26,51 @@
* buf[2]: reserved
* buf[3]..buf[8] - keycodes 1..6
*/
static uint8_t buf[9] = {2,0,0,0,0,0,0,0,0};
static uint8_t buf[USB_KEYBOARD_REPORT_SIZE] = {2,0,0,0,0,0,0,0};
#define _(x) (x|0x80)
// array for keycodes according to ASCII table; MSB is MOD_SHIFT flag
static const uint8_t keycodes[] = {
// space !"#$%&'
KEY_SPACE, _(KEY_1), _(KEY_QUOTE), _(KEY_3), _(KEY_4), _(KEY_5), _(KEY_7), KEY_QUOTE,
// ()*+,-./
_(KEY_9), _(KEY_0), _(KEY_8), _(KEY_EQUAL), KEY_COMMA, KEY_MINUS, KEY_PERIOD, KEY_SLASH,
// 0..9
39, 30, 31, 32, 33, 34, 35, 36, 37, 38,
// :;<=>?@
_(KEY_SEMICOLON), KEY_SEMICOLON, _(KEY_COMMA), KEY_EQUAL, _(KEY_PERIOD), _(KEY_SLASH), _(KEY_2),
// A..Z: for a in $(seq 0 25); do printf "$((a+132)),"; done
132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,
// [\]^_`
KEY_LEFT_BRACE, KEY_BACKSLASH, KEY_RIGHT_BRACE, _(KEY_6), _(KEY_MINUS), KEY_TILDE,
// a..z: for a in $(seq 0 25); do printf "$((a+4)),"; done
4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,
// {|}~
_(KEY_LEFT_BRACE), _(KEY_BACKSLASH), _(KEY_RIGHT_BRACE), _(KEY_TILDE)
// space !"#$%&'
KEY_SPACE, _(KEY_1), _(KEY_QUOTE), _(KEY_3), _(KEY_4), _(KEY_5), _(KEY_7), KEY_QUOTE,
// ()*+,-./
_(KEY_9), _(KEY_0), _(KEY_8), _(KEY_EQUAL), KEY_COMMA, KEY_MINUS, KEY_PERIOD, KEY_SLASH,
// 0..9
39, 30, 31, 32, 33, 34, 35, 36, 37, 38,
// :;<=>?@
_(KEY_SEMICOLON), KEY_SEMICOLON, _(KEY_COMMA), KEY_EQUAL, _(KEY_PERIOD), _(KEY_SLASH), _(KEY_2),
// A..Z: for a in $(seq 0 25); do printf "$((a+132)),"; done
132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,
// [\]^_`
KEY_LEFT_BRACE, KEY_BACKSLASH, KEY_RIGHT_BRACE, _(KEY_6), _(KEY_MINUS), KEY_TILDE,
// a..z: for a in $(seq 0 25); do printf "$((a+4)),"; done
4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,
// {|}~
_(KEY_LEFT_BRACE), _(KEY_BACKSLASH), _(KEY_RIGHT_BRACE), _(KEY_TILDE)
};
uint8_t *set_key_buf(uint8_t MOD, uint8_t KEY){
buf[1] = MOD;
buf[3] = KEY;
return buf;
buf[1] = MOD;
buf[3] = KEY;
buf[4] = 0;
return buf;
}
/**
* return buffer for sending symbol "ltr" with addition modificator mod
*/
uint8_t *press_key_mod(char ltr, uint8_t mod){
uint8_t MOD = 0;
uint8_t KEY = 0;
if(ltr > 31){
KEY = keycodes[ltr - 32];
if(KEY & 0x80){
MOD = MOD_SHIFT;
KEY &= 0x7f;
}
}else if (ltr == '\n') KEY = KEY_ENTER;
buf[1] = MOD | mod;
buf[3] = KEY;
return buf;
uint8_t MOD = 0;
uint8_t KEY = 0;
buf[3] = buf[4];
if(ltr > 31){
KEY = keycodes[ltr - 32];
if(KEY & 0x80){
MOD = MOD_SHIFT;
KEY &= 0x7f;
}
}else if (ltr == '\n') KEY = KEY_ENTER;
buf[1] = MOD | mod;
buf[4] = KEY;
return buf;
}

View File

@ -30,6 +30,8 @@ uint8_t *set_key_buf(uint8_t MOD, uint8_t KEY);
uint8_t *press_key_mod(char key, uint8_t mod);
#define press_key(k) press_key_mod(k, 0)
#define USB_KEYBOARD_REPORT_SIZE 8
#define MOD_CTRL 0x01
#define MOD_SHIFT 0x02
#define MOD_ALT 0x04

View File

@ -74,11 +74,16 @@ void move_mouse(int8_t x, int8_t y){
* buf[2]: reserved
* buf[3]..buf[8] - keycodes 1..6
*/
void send_word(char *wrd){
void send_word(const char *wrd){
char last = 0;
do{
USB_send(press_key(*wrd), 9);
USB_send(release_key(), 9);
// release key before pressing it again
if(last == *wrd) USB_send(release_key(), USB_KEYBOARD_REPORT_SIZE);
last = *wrd;
USB_send(press_key(last), USB_KEYBOARD_REPORT_SIZE);
IWDG->KR = IWDG_REFRESH;
}while(*(++wrd));
USB_send(release_key(), USB_KEYBOARD_REPORT_SIZE);
}
int main(void){
@ -102,13 +107,25 @@ int main(void){
USB_setup();
iwdg_setup();
//int N = 0;
while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog
if(lastT > Tms || Tms - lastT > 499){
LED_blink(LED0);
lastT = Tms;
transmit_tbuf(); // non-blocking transmission of data from UART buffer every 0.5s
/*if(N){
SEND("start: ");
printu(Tms);
for(int i = 0; i < 100; ++i){
IWDG->KR = IWDG_REFRESH;
send_word("0123456789abcdefghi\n");
}
SEND("stop: ");
printu(Tms);
newline();
--N;
}*/
}
usb_proc();
if(usartrx()){ // usart1 received data, store in in buffer
@ -123,7 +140,8 @@ int main(void){
SEND("connected\n");
break;
case 'K':
send_word("Hello!\n\n");
send_word("Hello, weird and cruel world!\n\n");
//N = 2;
SEND("Write hello\n");
break;
case 'M':

View File

@ -21,6 +21,7 @@
*
*/
#include "keycodes.h"
#include "usb.h"
#include "usb_lib.h"
#include "usart.h"
@ -50,7 +51,7 @@ static uint16_t EP1_Handler(ep_t ep){
#endif
tx_succesfull = 1;
ep.status = SET_VALID_RX(ep.status);
ep.status = SET_STALL_TX(ep.status);
ep.status = SET_VALID_TX(ep.status);
}
return ep.status;
}
@ -92,7 +93,7 @@ void usb_proc(){
if(USB_GetState() == USB_CONFIGURE_STATE){ // USB configured - activate other endpoints
if(!usbON){ // endpoints not activated
SEND("Configure endpoints\n");
EP_Init(1, EP_TYPE_INTERRUPT, 10, 0, EP1_Handler); // IN1 - transmit
EP_Init(1, EP_TYPE_INTERRUPT, USB_TXBUFSZ, 0, EP1_Handler); // IN1 - transmit
usbON = 1;
}
}else{
@ -103,7 +104,7 @@ void usb_proc(){
void USB_send(uint8_t *buf, uint16_t size){
uint16_t ctr = 0;
while(size){
uint16_t s = (size > USB_TXBUFSZ) ? USB_TXBUFSZ : size;
uint16_t s = (size > USB_KEYBOARD_REPORT_SIZE) ? USB_KEYBOARD_REPORT_SIZE : size;
tx_succesfull = 0;
EP_Write(1, (uint8_t*)&buf[ctr], s);
if(EP_WaitTransmission()) SEND("Err\n");

View File

@ -36,7 +36,7 @@
#define USB_EP0_BASEADDR 64
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
#define USB_EP0_BUFSZ 64
// USB transmit buffer size
// USB transmit buffer size (larger than keyboard report to prevent need of ZLP!)
#define USB_TXBUFSZ 10
#define USB_BTABLE_BASE 0x40006000

View File

@ -390,6 +390,7 @@ static uint16_t EP0_Handler(ep_t ep){
break;
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
if (setup_packet.bRequest == CLEAR_FEATURE){
printu(setup_packet.wValue);
//WRITEDUMP("CLEAR_FEATURE");
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
@ -418,26 +419,23 @@ static uint16_t EP0_Handler(ep_t ep){
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
}else if (ep.rx_flag){ // got data over EP0 or host acknowlegement
/*if (set_featuring){
set_featuring = 0;
// here we can do something with ep.rx_buf - set_feature
}*/
// Close transaction
}else if (ep.rx_flag || ep.tx_flag){ // got data over EP0 or host acknowlegement || package transmitted
if(ep.rx_flag){
/*if (set_featuring){
set_featuring = 0;
// here we can do something with ep.rx_buf - set_feature
}*/
// Close transaction
#ifdef EBUG
hexdump(ep.rx_buf, ep.rx_cnt);
hexdump(ep.rx_buf, ep.rx_cnt);
#endif
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus);
// wait for new data from host
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_STALL_TX(epstatus);
} else if (ep.tx_flag){ // package transmitted
// now we can change address after enumeration
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
// change state to ADRESSED
USB_Dev.USB_Status = USB_ADRESSED_STATE;
}else{ // tx
// now we can change address after enumeration
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
// change state to ADRESSED
USB_Dev.USB_Status = USB_ADRESSED_STATE;
}
}
// end of transaction
epstatus = CLEAR_DTOG_RX(epstatus);

Binary file not shown.