some fixes in pl2303

This commit is contained in:
eddyem 2019-04-26 14:01:40 +03:00
parent f11e5e5b4d
commit 6d50b88096
7 changed files with 257 additions and 168 deletions

View File

@ -9,8 +9,7 @@ MCU = F042x6
DEFS += -DUSARTNUM=1
#DEFS += -DCHECK_TMOUT
#DEFS += -DEBUG
# change this linking script depending on particular MCU model,
# for example, if you have STM32F103VBT6, you should write:
# change this linking script depending on particular MCU model
LDSCRIPT = stm32f042k.ld
INDEPENDENT_HEADERS=
@ -60,11 +59,13 @@ CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration
CFLAGS += -Wredundant-decls $(INCLUDE)
# -Wmissing-prototypes -Wstrict-prototypes
CFLAGS += -fno-common -ffunction-sections -fdata-sections
#CGLAGS += -fno-stack-protector
###############################################################################
# Linker flags
LDFLAGS += --static -nostartfiles
#--specs=nano.specs
#LDFLAGS += -fno-stack-protector
LDFLAGS += -L$(LIB_DIR)
LDFLAGS += -T$(LDSCRIPT)
LDFLAGS += -Wl,-Map=$(OBJDIR)/$(BINARY).map

View File

@ -22,6 +22,7 @@
#include "usart.h"
#include "usb.h"
#include "usb_lib.h"
#include <string.h> // memcpy
volatile uint32_t Tms = 0;
@ -53,18 +54,62 @@ void iwdg_setup(){
IWDG->KR = IWDG_REFRESH; /* (6) */
}
void linecoding_handler(usb_LineCoding *lc){
static usb_LineCoding new_lc;
static uint8_t lcchange = 0;
static void show_new_lc(){
SEND("got new linecoding:");
SEND(" baudrate="); printu(lc->dwDTERate);
SEND(", charFormat="); printu(lc->bCharFormat);
SEND(", parityType="); printu(lc->bParityType);
SEND(", dataBits="); printu(lc->bDataBits);
SEND(" baudrate="); printu(new_lc.dwDTERate);
SEND(", charFormat="); printu(new_lc.bCharFormat);
SEND(" (");
switch(new_lc.bCharFormat){
case USB_CDC_1_STOP_BITS:
usart_putchar('1');
break;
case USB_CDC_1_5_STOP_BITS:
SEND("1.5");
break;
case USB_CDC_2_STOP_BITS:
usart_putchar('2');
break;
default:
usart_putchar('?');
}
SEND(" stop bits), parityType="); printu(new_lc.bParityType);
SEND(" (");
switch(new_lc.bParityType){
case USB_CDC_NO_PARITY:
SEND("no");
break;
case USB_CDC_ODD_PARITY:
SEND("odd");
break;
case USB_CDC_EVEN_PARITY:
SEND("even");
break;
case USB_CDC_MARK_PARITY:
SEND("mark");
break;
case USB_CDC_SPACE_PARITY:
SEND("space");
break;
default:
SEND("unknown");
}
SEND(" parity), dataBits="); printu(new_lc.bDataBits);
usart_putchar('\n');
lcchange = 0;
}
void linecoding_handler(usb_LineCoding *lc){
memcpy(&new_lc, lc, sizeof(usb_LineCoding));
lcchange = 1;
}
void clstate_handler(uint16_t val){
SEND("change control line state to ");
printu(val);
if(val & CONTROL_DTR) SEND(" (DTR)");
if(val & CONTROL_RTS) SEND(" (RTS)");
usart_putchar('\n');
}
@ -120,6 +165,7 @@ int main(void){
case 'L':
USB_send("Very long test string for USB (it's length is more than 64 bytes\n"
"This is another part of the string! Can you see all of this?\n");
SEND("Long test sent\n");
break;
case 'R':
SEND("Soft reset\n");
@ -127,6 +173,7 @@ int main(void){
break;
case 'S':
USB_send("Test string for USB\n");
SEND("Short test sent\n");
break;
case 'W':
SEND("Wait for reboot\n");
@ -150,6 +197,9 @@ int main(void){
usart_send(txt);
L = 0;
}
if(lcchange){
show_new_lc();
}
}
return 0;
}

Binary file not shown.

View File

@ -109,7 +109,7 @@ void USB_setup(){
void usb_proc(){
if(USB_GetState() == USB_CONFIGURE_STATE){ // USB configured - activate other endpoints
if(!usbON){ // endpoints not activated
MSG("Configured; activate other endpoints\n");
SEND("Configure endpoints\n");
// make new BULK endpoint
// Buffer have 1024 bytes, but last 256 we use for CAN bus (30.2 of RM: USB main features)
EP_Init(1, EP_TYPE_INTERRUPT, 10, 0, EP1_Handler); // IN1 - transmit

View File

@ -27,18 +27,21 @@
#include <stm32f0xx.h>
#define USB_BTABLE_BASE 0x40006000
/**
* Buffers size definition
**/
// !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
#define USB_BTABLE_SIZE 1024
// first 64 bytes of USB_BTABLE are registers!
#define USB_EP0_BASEADDR 64
// for USB FS EP0 buffers are from 8 to 64 bytes long
#define USB_EP0_BUFSZ 8
// USB transmit buffer size
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
#define USB_EP0_BUFSZ 64
// USB transmit buffer size (64 for PL2303)
#define USB_TXBUFSZ 64
// USB receive buffer size
// USB receive buffer size (64 for PL2303)
#define USB_RXBUFSZ 64
#define USB_BTABLE_BASE 0x40006000
#undef USB_BTABLE
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
#define USB_ISTR_EPID 0x0000000F

View File

@ -26,6 +26,9 @@
#include <string.h> // memcpy
#include "usart.h"
ep_t endpoints[ENDPOINTS_NUM];
static usb_dev_t USB_Dev;
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
static config_pack_t setup_packet;
static uint8_t ep0databuf[EP0DATABUF_SIZE];
@ -33,15 +36,23 @@ static uint8_t ep0dbuflen = 0;
usb_LineCoding getLineCoding(){return lineCoding;}
const uint8_t USB_DeviceDescriptor[] = {
// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor
#define bcdUSB_L 0x10
#define bcdUSB_H 0x01
#define bDeviceClass 0
#define bDeviceSubClass 0
#define bDeviceProtocol 0
#define bNumConfigurations 1
static const uint8_t USB_DeviceDescriptor[] = {
18, // bLength
0x01, // bDescriptorType - USB_DEVICE_DESC_TYPE
0x10, // bcdUSB_L - 1.10
0x01, // bcdUSB_H
0x00, // bDeviceClass - USB_COMM
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
0x40, // bMaxPacketSize
0x01, // bDescriptorType - Device descriptor
bcdUSB_L, // bcdUSB_L - 1.10
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass - USB_COMM
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
0x06, // idVendor_H
0x03, // idProduct_L
@ -51,23 +62,23 @@ const uint8_t USB_DeviceDescriptor[] = {
0x01, // iManufacturer
0x02, // iProduct
0x00, // iSerialNumber
0x01 // bNumConfigurations
bNumConfigurations // bNumConfigurations
};
const uint8_t USB_DeviceQualifierDescriptor[] = {
static const uint8_t USB_DeviceQualifierDescriptor[] = {
10, //bLength
0x06, // bDescriptorType
0x10, // bcdUSB_L
0x01, // bcdUSB_H
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
0x40, // bMaxPacketSize0
0x01, // bNumConfigurations
0x06, // bDescriptorType - Device qualifier
bcdUSB_L, // bcdUSB_L
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize0
bNumConfigurations, // bNumConfigurations
0x00 // Reserved
};
const uint8_t USB_ConfigDescriptor[] = {
static const uint8_t USB_ConfigDescriptor[] = {
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
0x02, /* bDescriptorType: Configuration */
@ -122,12 +133,9 @@ const uint8_t USB_ConfigDescriptor[] = {
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
// these descriptors are not used in PL2303 emulator!
_USB_STRING_(USB_StringSerialDescriptor, u"0")
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.")
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller")
static usb_dev_t USB_Dev;
ep_t endpoints[ENDPOINTS_NUM];
_USB_STRING_(USB_StringSerialDescriptor, u"0");
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.");
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
/*
* default handlers
@ -149,12 +157,8 @@ void WEAK break_handler(){
// handler of vendor requests
void WEAK vendor_handler(config_pack_t *packet){
/*SEND("Vendor, reqt=");
printuhex(packet->bmRequestType);
SEND(", wval=");
printuhex(packet->wValue);
usart_putchar('\n');*/
if(packet->bmRequestType & 0x80){ // read
//SEND("Read");
uint8_t c;
switch(packet->wValue){
case 0x8484:
@ -171,8 +175,92 @@ void WEAK vendor_handler(config_pack_t *packet){
}
EP_WriteIRQ(0, &c, 1);
}else{ // write ZLP
//SEND("Write");
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
/*SEND(" vendor, reqt=");
printuhex(packet->bmRequestType);
SEND(", wval=");
printuhex(packet->wValue);
usart_putchar('\n');*/
}
#ifdef EBUG
uint8_t _2wr = 0;
#define WRITEDUMP(str) do{MSG(str); _2wr = 1;}while(0)
#else
#define WRITEDUMP(str)
#endif
static void wr0(const uint8_t *buf, uint16_t size){
if(setup_packet.wLength < size) size = setup_packet.wLength;
EP_WriteIRQ(0, buf, size);
}
static inline void get_descriptor(){
switch(setup_packet.wValue){
case DEVICE_DESCRIPTOR:
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
break;
case CONFIGURATION_DESCRIPTOR:
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
break;
case STRING_LANG_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
break;
case STRING_MAN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
break;
case STRING_PROD_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
break;
case STRING_SN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
break;
case DEVICE_QUALIFIER_DESCRIPTOR:
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
break;
default:
WRITEDUMP("UNK_DES");
break;
}
}
static uint8_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
static inline void std_d2h_req(){
uint16_t status = 0; // bus powered
switch(setup_packet.bRequest){
case GET_DESCRIPTOR:
get_descriptor();
break;
case GET_STATUS:
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
break;
case GET_CONFIGURATION:
WRITEDUMP("GET_CONFIGURATION");
EP_WriteIRQ(0, &configuration, 1);
break;
default:
WRITEDUMP("80:WR_REQ");
break;
}
}
static inline void std_h2d_req(){
switch(setup_packet.bRequest){
case SET_ADDRESS:
// new address will be assigned later - after acknowlegement or request to host
USB_Dev.USB_Addr = setup_packet.wValue;
break;
case SET_CONFIGURATION:
// Now device configured
USB_Dev.USB_Status = USB_CONFIGURE_STATE;
configuration = setup_packet.wValue;
break;
default:
WRITEDUMP("0:WR_REQ");
break;
}
}
/*
@ -186,123 +274,70 @@ bmRequestType: 76543210
* @param ep - endpoint state
* @return data written to EP0R
*/
uint16_t EP0_Handler(ep_t ep){
uint16_t status = 0; // bus powered
static uint16_t EP0_Handler(ep_t ep){
uint16_t epstatus = ep.status; // EP0R on input -> return this value after modifications
static uint8_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
void wr0(const uint8_t *buf, uint16_t size){
if(setup_packet.wLength < size) size = setup_packet.wLength;
EP_WriteIRQ(0, buf, size);
}
#ifdef EBUG
uint8_t _2wr = 0;
#define WRITEDUMP(str) do{MSG(str); _2wr = 1;}while(0)
#else
#define WRITEDUMP(str)
#endif
uint8_t reqtype = setup_packet.bmRequestType & 0x7f;
uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0;
if ((ep.rx_flag) && (ep.setup_flag)){
if (setup_packet.bmRequestType == 0x80){ // standard device request (device to host)
switch(setup_packet.bRequest){
case GET_DESCRIPTOR:
switch(setup_packet.wValue){
case DEVICE_DESCRIPTOR:
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
break;
case CONFIGURATION_DESCRIPTOR:
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
break;
case STRING_LANG_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
break;
case STRING_MAN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
break;
case STRING_PROD_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
break;
case STRING_SN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
break;
case DEVICE_QALIFIER_DESCRIPTOR:
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
break;
default:
WRITEDUMP("UNK_DES");
break;
}
break;
case GET_STATUS:
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
break;
case GET_CONFIGURATION:
WRITEDUMP("GET_CONFIGURATION");
EP_WriteIRQ(0, &configuration, 1);
break;
default:
WRITEDUMP("80:WR_REQ");
break;
}
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}else if(setup_packet.bmRequestType == 0x00){ // standard device request (host to device)
switch(setup_packet.bRequest){
case SET_ADDRESS:
// new address will be assigned later - after acknowlegement or request to host
USB_Dev.USB_Addr = setup_packet.wValue;
break;
case SET_CONFIGURATION:
// Now device configured
USB_Dev.USB_Status = USB_CONFIGURE_STATE;
configuration = setup_packet.wValue;
break;
default:
WRITEDUMP("0:WR_REQ");
break;
}
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}else if(setup_packet.bmRequestType == 0x02){ // standard endpoint request (host to device)
if (setup_packet.bRequest == CLEAR_FEATURE){
// send ZLP
switch(reqtype){
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
if(dev2host){
std_d2h_req();
}else{
std_h2d_req();
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
if (setup_packet.bRequest == CLEAR_FEATURE){
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}else{
WRITEDUMP("02:WR_REQ");
}
break;
case VENDOR_REQUEST_TYPE:
vendor_handler(&setup_packet);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
case CONTROL_REQUEST_TYPE:
switch(setup_packet.bRequest){
case GET_LINE_CODING:
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
break;
case SET_LINE_CODING: // omit this for next stage, when data will come
break;
case SET_CONTROL_LINE_STATE:
clstate_handler(setup_packet.wValue);
break;
case SEND_BREAK:
break_handler();
break;
default:
WRITEDUMP("undef control req");
}
if(!dev2host) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
default:
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}else{
WRITEDUMP("02:WR_REQ");
}
}else if((setup_packet.bmRequestType & VENDOR_MASK_REQUEST) == VENDOR_MASK_REQUEST){ // vendor request
vendor_handler(&setup_packet);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}else if((setup_packet.bmRequestType & 0x7f) == CONTROL_REQUEST_TYPE){ // control request
switch(setup_packet.bRequest){
case GET_LINE_CODING:
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
break;
case SET_LINE_CODING:
break;
case SET_CONTROL_LINE_STATE:
clstate_handler(setup_packet.wValue);
break;
case SEND_BREAK:
break_handler();
break;
default:
WRITEDUMP("undef control req");
}
if((setup_packet.bmRequestType & 0x80) == 0) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
}else if (ep.rx_flag){ // got data over EP0 or host acknowlegement
if(ep.rx_cnt){
EP_WriteIRQ(0, (uint8_t *)0, 0);
if(setup_packet.bRequest == SET_LINE_CODING){
//WRITEDUMP("SET_LINE_CODING");
linecoding_handler((usb_LineCoding*)ep0databuf);
}
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
// Close transaction
epstatus = CLEAR_DTOG_RX(epstatus);
@ -348,6 +383,7 @@ uint16_t EP0_Handler(ep_t ep){
#endif
return epstatus;
}
#undef WRITEDUMP
static uint16_t lastaddr = USB_EP0_BASEADDR;
/**
@ -361,6 +397,7 @@ static uint16_t lastaddr = USB_EP0_BASEADDR;
* @return 0 if all OK
*/
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep)){
if(number >= ENDPOINTS_NUM) return 4; // out of configured amount
if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
@ -380,7 +417,7 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr);
lastaddr += rxsz;
// buffer size: Table127 of RM: BL_SIZE=1, NUM_BLOCK=1
// buffer size: Table127 of RM
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
endpoints[number].func = func;
return 0;
@ -388,7 +425,6 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t
// standard IRQ handler
void usb_isr(){
uint8_t n;
if (USB->ISTR & USB_ISTR_RESET){
// Reinit registers
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
@ -404,7 +440,7 @@ void usb_isr(){
}
if(USB->ISTR & USB_ISTR_CTR){
// EP number
n = USB->ISTR & USB_ISTR_EPID;
uint8_t n = USB->ISTR & USB_ISTR_EPID;
// copy status register
uint16_t epstatus = USB->EPnR[n];
// Calculate flags
@ -412,7 +448,7 @@ void usb_isr(){
endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0;
endpoints[n].tx_flag = (epstatus & USB_EPnR_CTR_TX) ? 1 : 0;
// copy received bytes amount
endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX;
endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter
// check direction
if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit)
if(n == 0){ // control endpoint
@ -451,6 +487,7 @@ void usb_isr(){
*/
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
uint8_t i;
if(size > USB_TXBUFSZ) size = USB_TXBUFSZ;
uint16_t N2 = (size + 1) >> 1;
// the buffer is 16-bit, so we should copy data as it would be uint16_t
uint16_t *buf16 = (uint16_t *)buf;

View File

@ -32,6 +32,11 @@
// Max EP amount (EP0 + other used)
#define ENDPOINTS_NUM 4
// bmRequestType & 0x7f
#define STANDARD_DEVICE_REQUEST_TYPE 0
#define STANDARD_ENDPOINT_REQUEST_TYPE 2
#define VENDOR_REQUEST_TYPE 0x40
#define CONTROL_REQUEST_TYPE 0x21
// bRequest, standard; for bmRequestType == 0x80
#define GET_STATUS 0x00
#define GET_DESCRIPTOR 0x06
@ -46,21 +51,14 @@
#define GET_INTERFACE 0x0A // unused
#define SET_INTERFACE 0x0B // unused
#define SYNC_FRAME 0x0C // unused
// vendor requests
#define VENDOR_MASK_REQUEST 0x40
#define VENDOR_READ_REQUEST_TYPE 0xc0
#define VENDOR_WRITE_REQUEST_TYPE 0x40
#define VENDOR_REQUEST 0x01
#define CONTROL_REQUEST_TYPE 0x21
#define VENDOR_REQUEST 0x01 // unused
// Class-Specific Control Requests
#define SEND_ENCAPSULATED_COMMAND 0x00
#define GET_ENCAPSULATED_RESPONSE 0x01
#define SET_COMM_FEATURE 0x02
#define GET_COMM_FEATURE 0x03
#define CLEAR_COMM_FEATURE 0x04
#define SEND_ENCAPSULATED_COMMAND 0x00 // unused
#define GET_ENCAPSULATED_RESPONSE 0x01 // unused
#define SET_COMM_FEATURE 0x02 // unused
#define GET_COMM_FEATURE 0x03 // unused
#define CLEAR_COMM_FEATURE 0x04 // unused
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
@ -77,7 +75,7 @@
#define STRING_MAN_DESCRIPTOR 0x301
#define STRING_PROD_DESCRIPTOR 0x302
#define STRING_SN_DESCRIPTOR 0x303
#define DEVICE_QALIFIER_DESCRIPTOR 0x600
#define DEVICE_QUALIFIER_DESCRIPTOR 0x600
// EPnR bits manipulation
#define CLEAR_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? R : (R & (~USB_EPnR_DTOG_RX))
@ -121,7 +119,7 @@ static const struct name \
uint16_t bString[(sizeof(str) - 2) / 2]; \
\
} \
name = {sizeof(name), 0x03, str};
name = {sizeof(name), 0x03, str}
#define _USB_LANG_ID_(name, lng_id) \
\
@ -132,7 +130,7 @@ static const struct name \
uint16_t bString; \
\
} \
name = {0x04, 0x03, lng_id};
name = {0x04, 0x03, lng_id}
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
// EP0 configuration packet