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[2]: reserved
* buf[3]..buf[8] - keycodes 1..6 * 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) #define _(x) (x|0x80)
// array for keycodes according to ASCII table; MSB is MOD_SHIFT flag // array for keycodes according to ASCII table; MSB is MOD_SHIFT flag
static const uint8_t keycodes[] = { static const uint8_t keycodes[] = {
// space !"#$%&' // space !"#$%&'
KEY_SPACE, _(KEY_1), _(KEY_QUOTE), _(KEY_3), _(KEY_4), _(KEY_5), _(KEY_7), KEY_QUOTE, 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, _(KEY_9), _(KEY_0), _(KEY_8), _(KEY_EQUAL), KEY_COMMA, KEY_MINUS, KEY_PERIOD, KEY_SLASH,
// 0..9 // 0..9
39, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 30, 31, 32, 33, 34, 35, 36, 37, 38,
// :;<=>?@ // :;<=>?@
_(KEY_SEMICOLON), KEY_SEMICOLON, _(KEY_COMMA), KEY_EQUAL, _(KEY_PERIOD), _(KEY_SLASH), _(KEY_2), _(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 // 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, 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, 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 // 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, 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) _(KEY_LEFT_BRACE), _(KEY_BACKSLASH), _(KEY_RIGHT_BRACE), _(KEY_TILDE)
}; };
uint8_t *set_key_buf(uint8_t MOD, uint8_t KEY){ uint8_t *set_key_buf(uint8_t MOD, uint8_t KEY){
buf[1] = MOD; buf[1] = MOD;
buf[3] = KEY; buf[3] = KEY;
return buf; buf[4] = 0;
return buf;
} }
/** /**
* return buffer for sending symbol "ltr" with addition modificator mod * return buffer for sending symbol "ltr" with addition modificator mod
*/ */
uint8_t *press_key_mod(char ltr, uint8_t mod){ uint8_t *press_key_mod(char ltr, uint8_t mod){
uint8_t MOD = 0; uint8_t MOD = 0;
uint8_t KEY = 0; uint8_t KEY = 0;
if(ltr > 31){ buf[3] = buf[4];
KEY = keycodes[ltr - 32]; if(ltr > 31){
if(KEY & 0x80){ KEY = keycodes[ltr - 32];
MOD = MOD_SHIFT; if(KEY & 0x80){
KEY &= 0x7f; MOD = MOD_SHIFT;
} KEY &= 0x7f;
}else if (ltr == '\n') KEY = KEY_ENTER; }
buf[1] = MOD | mod; }else if (ltr == '\n') KEY = KEY_ENTER;
buf[3] = KEY; buf[1] = MOD | mod;
return buf; 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); uint8_t *press_key_mod(char key, uint8_t mod);
#define press_key(k) press_key_mod(k, 0) #define press_key(k) press_key_mod(k, 0)
#define USB_KEYBOARD_REPORT_SIZE 8
#define MOD_CTRL 0x01 #define MOD_CTRL 0x01
#define MOD_SHIFT 0x02 #define MOD_SHIFT 0x02
#define MOD_ALT 0x04 #define MOD_ALT 0x04

View File

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

View File

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

View File

@ -36,7 +36,7 @@
#define USB_EP0_BASEADDR 64 #define USB_EP0_BASEADDR 64
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303) // for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
#define USB_EP0_BUFSZ 64 #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_TXBUFSZ 10
#define USB_BTABLE_BASE 0x40006000 #define USB_BTABLE_BASE 0x40006000

View File

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

Binary file not shown.