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[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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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':
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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.
Loading…
x
Reference in New Issue
Block a user