mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
USB HID is working!
This commit is contained in:
parent
f01c40a5e0
commit
2d9da87cd7
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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':
|
||||||
|
|||||||
@ -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){
|
||||||
|
/*if (ep.rx_flag){
|
||||||
|
MSG("EP1 OUT: ");
|
||||||
|
#ifdef EBUG
|
||||||
|
printu(ep.rx_cnt);
|
||||||
|
newline();
|
||||||
|
#endif
|
||||||
uint8_t epbuf[10];
|
uint8_t epbuf[10];
|
||||||
if (ep.rx_flag){
|
|
||||||
MSG("EP1 OUT\n");
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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.
Loading…
x
Reference in New Issue
Block a user