USB HID is working!

This commit is contained in:
eddyem 2019-04-30 11:49:39 +03:00
parent f01c40a5e0
commit 2d9da87cd7
6 changed files with 79 additions and 19 deletions

View File

@ -8,7 +8,7 @@ MCU = F042x6
# hardware definitions # hardware definitions
DEFS += -DUSARTNUM=1 DEFS += -DUSARTNUM=1
#DEFS += -DCHECK_TMOUT #DEFS += -DCHECK_TMOUT
DEFS += -DEBUG #DEFS += -DEBUG
# change this linking script depending on particular MCU model # change this linking script depending on particular MCU model
LDSCRIPT = stm32f042k.ld LDSCRIPT = stm32f042k.ld

View File

@ -101,7 +101,7 @@ int main(void){
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
USB_setup(); USB_setup();
//iwdg_setup(); iwdg_setup();
while (1){ while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog IWDG->KR = IWDG_REFRESH; // refresh watchdog
@ -123,11 +123,12 @@ int main(void){
SEND("connected\n"); SEND("connected\n");
break; break;
case 'K': case 'K':
send_word("Hello!"); send_word("Hello!\n\n");
SEND("Write hello\n"); SEND("Write hello\n");
break; break;
case 'M': case 'M':
move_mouse(100, 10); move_mouse(100, 10);
move_mouse(0,0);
SEND("Move mouse\n"); SEND("Move mouse\n");
break; break;
case 'R': case 'R':

View File

@ -28,22 +28,45 @@
static int8_t usbON = 0; // ==1 when USB fully configured static int8_t usbON = 0; // ==1 when USB fully configured
// interrupt IN handler (never used?) static volatile uint8_t tx_succesfull = 0;
static uint16_t EP1_Handler(ep_t ep){ static uint16_t EP1_Handler(ep_t ep){
uint8_t epbuf[10]; /*if (ep.rx_flag){
if (ep.rx_flag){ MSG("EP1 OUT: ");
MSG("EP1 OUT\n"); #ifdef EBUG
printu(ep.rx_cnt);
newline();
#endif
uint8_t epbuf[10];
EP_Read(1, epbuf); EP_Read(1, epbuf);
ep.status = SET_VALID_TX(ep.status); ep.status = SET_VALID_TX(ep.status);
ep.status = KEEP_STAT_RX(ep.status); ep.status = KEEP_STAT_RX(ep.status);
}else if (ep.tx_flag){ }else */
MSG("EP1 IN\n"); if (ep.tx_flag){
MSG("EP1 IN: ");
#ifdef EBUG
printu(ep.rx_cnt);
newline();
#endif
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_STALL_TX(ep.status);
} }
return ep.status; return ep.status;
} }
/**
* @brief EP_WaitTransmission - wait until data transmitted (or timeout)
* @param number - EP number
* @return 0 if all OK, 1 if timed out
*/
static uint8_t EP_WaitTransmission(){
uint32_t ctr = 1000000;
while(--ctr && tx_succesfull == 0);
if(!tx_succesfull) return 1;
return 0;
}
void USB_setup(){ void USB_setup(){
RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB
RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB
@ -69,7 +92,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, 10, EP1_Handler); // IN1 - transmit EP_Init(1, EP_TYPE_INTERRUPT, 10, 0, EP1_Handler); // IN1 - transmit
usbON = 1; usbON = 1;
} }
}else{ }else{
@ -81,7 +104,9 @@ 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_TXBUFSZ) ? USB_TXBUFSZ : size;
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");
size -= s; size -= s;
ctr += s; ctr += s;
} }

View File

@ -26,7 +26,7 @@
#include <string.h> // memcpy #include <string.h> // memcpy
#include "usart.h" #include "usart.h"
ep_t endpoints[ENDPOINTS_NUM]; static ep_t endpoints[ENDPOINTS_NUM];
//static uint8_t set_featuring; //static uint8_t set_featuring;
static usb_dev_t USB_Dev; static usb_dev_t USB_Dev;
@ -78,7 +78,7 @@ static const uint8_t USB_DeviceQualifierDescriptor[] = {
bNumConfigurations, // bNumConfigurations bNumConfigurations, // bNumConfigurations
0x00 // Reserved 0x00 // Reserved
}; };
#if 0
static const uint8_t HID_ReportDescriptor[] = { static const uint8_t HID_ReportDescriptor[] = {
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x02, /* Usage (Mouse) */ 0x09, 0x02, /* Usage (Mouse) */
@ -140,8 +140,8 @@ static const uint8_t HID_ReportDescriptor[] = {
0x81, 0x00, /* Input (Data, Array) */ 0x81, 0x00, /* Input (Data, Array) */
0xC0 /* End Collection,End Collection */ 0xC0 /* End Collection,End Collection */
}; };
#endif
#if 0
const uint8_t HID_ReportDescriptor[] = { const uint8_t HID_ReportDescriptor[] = {
0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */ 0x09, 0x06, /* Usage (Keyboard) */
@ -183,6 +183,7 @@ const uint8_t HID_ReportDescriptor[] = {
0xC0 /* End Collection,End Collection */ 0xC0 /* End Collection,End Collection */
}; };
#endif
static const uint8_t USB_ConfigDescriptor[] = { static const uint8_t USB_ConfigDescriptor[] = {
/*Configuration Descriptor*/ /*Configuration Descriptor*/
@ -318,6 +319,37 @@ static inline void std_h2d_req(){
} }
} }
static uint16_t WriteHID_descriptor(uint16_t status){
uint16_t rest = sizeof(HID_ReportDescriptor);
uint8_t *ptr = (uint8_t*)HID_ReportDescriptor;
while(rest){
uint16_t l = rest;
if(l > endpoints[0].txbufsz) l = endpoints[0].txbufsz;
EP_WriteIRQ(0, ptr, l);
ptr += l;
rest -= l;
MSG("Sent\n");
uint8_t needzlp = (l == endpoints[0].txbufsz) ? 1 : 0;
if(rest || needzlp){ // send last data buffer
status = SET_NAK_RX(status);
status = SET_VALID_TX(status);
status = KEEP_DTOG_TX(status);
status = KEEP_DTOG_RX(status);
status = CLEAR_CTR_RX(status);
status = CLEAR_CTR_TX(status);
USB->ISTR = 0;
USB->EPnR[0] = status;
uint32_t ctr = 1000000;
while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0);
if((USB->ISTR & USB_ISTR_CTR) == 0){MSG("ERR\n")};
USB->ISTR = 0;
status = USB->EPnR[0];
if(needzlp) EP_WriteIRQ(0, (uint8_t*)0, 0);
}
}
return status;
}
/* /*
bmRequestType: 76543210 bmRequestType: 76543210
7 direction: 0 - host->device, 1 - device->host 7 direction: 0 - host->device, 1 - device->host
@ -347,11 +379,10 @@ static uint16_t EP0_Handler(ep_t ep){
epstatus = SET_VALID_TX(epstatus); epstatus = SET_VALID_TX(epstatus);
break; break;
case STANDARD_INTERFACE_REQUEST_TYPE: case STANDARD_INTERFACE_REQUEST_TYPE:
WRITEDUMP("IFACE ");
if(dev2host && setup_packet.bRequest == GET_DESCRIPTOR){ if(dev2host && setup_packet.bRequest == GET_DESCRIPTOR){
if(setup_packet.wValue == HID_REPORT_DESCRIPTOR){ if(setup_packet.wValue == HID_REPORT_DESCRIPTOR){
WRITEDUMP("HID_REPORT"); WRITEDUMP("HID_REPORT");
wr0(HID_ReportDescriptor, sizeof(HID_ReportDescriptor)); epstatus = WriteHID_descriptor(epstatus);
} }
} }
epstatus = SET_NAK_RX(epstatus); epstatus = SET_NAK_RX(epstatus);
@ -393,7 +424,9 @@ static uint16_t EP0_Handler(ep_t ep){
// here we can do something with ep.rx_buf - set_feature // here we can do something with ep.rx_buf - set_feature
}*/ }*/
// Close transaction // 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_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus); epstatus = CLEAR_DTOG_TX(epstatus);
// wait for new data from host // wait for new data from host
@ -480,9 +513,9 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t
// standard IRQ handler // standard IRQ handler
void usb_isr(){ void usb_isr(){
// disallow interrupts
USB->CNTR = 0;
if (USB->ISTR & USB_ISTR_RESET){ if (USB->ISTR & USB_ISTR_RESET){
// Reinit registers
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
USB->ISTR = 0; USB->ISTR = 0;
// Endpoint 0 - CONTROL // Endpoint 0 - CONTROL
// ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes! // ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes!
@ -532,6 +565,8 @@ void usb_isr(){
// refresh EPnR // refresh EPnR
USB->EPnR[n] = epstatus; USB->EPnR[n] = epstatus;
} }
// allow interrupts
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
} }
/** /**

View File

@ -189,7 +189,7 @@ typedef struct {
uint16_t wLength; uint16_t wLength;
} __attribute__ ((packed)) usb_cdc_notification; } __attribute__ ((packed)) usb_cdc_notification;
extern ep_t endpoints[]; //extern ep_t endpoints[];
void USB_Init(); void USB_Init();
uint8_t USB_GetState(); uint8_t USB_GetState();
@ -199,7 +199,6 @@ void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size);
int EP_Read(uint8_t number, uint8_t *buf); int EP_Read(uint8_t number, uint8_t *buf);
usb_LineCoding getLineCoding(); usb_LineCoding getLineCoding();
void WEAK linecoding_handler(usb_LineCoding *lc); void WEAK linecoding_handler(usb_LineCoding *lc);
void WEAK clstate_handler(uint16_t val); void WEAK clstate_handler(uint16_t val);
void WEAK break_handler(); void WEAK break_handler();

Binary file not shown.