mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
fix some bugs with USB HID; increase keyboard speed up to 950 symbols per minute
This commit is contained in:
parent
2d9da87cd7
commit
24b953e3a3
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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':
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
Loading…
x
Reference in New Issue
Block a user