mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
some fixes in pl2303
This commit is contained in:
parent
f11e5e5b4d
commit
6d50b88096
@ -9,8 +9,7 @@ MCU = F042x6
|
|||||||
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
|
||||||
# for example, if you have STM32F103VBT6, you should write:
|
|
||||||
LDSCRIPT = stm32f042k.ld
|
LDSCRIPT = stm32f042k.ld
|
||||||
|
|
||||||
INDEPENDENT_HEADERS=
|
INDEPENDENT_HEADERS=
|
||||||
@ -60,11 +59,13 @@ CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration
|
|||||||
CFLAGS += -Wredundant-decls $(INCLUDE)
|
CFLAGS += -Wredundant-decls $(INCLUDE)
|
||||||
# -Wmissing-prototypes -Wstrict-prototypes
|
# -Wmissing-prototypes -Wstrict-prototypes
|
||||||
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
||||||
|
#CGLAGS += -fno-stack-protector
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Linker flags
|
# Linker flags
|
||||||
LDFLAGS += --static -nostartfiles
|
LDFLAGS += --static -nostartfiles
|
||||||
#--specs=nano.specs
|
#--specs=nano.specs
|
||||||
|
#LDFLAGS += -fno-stack-protector
|
||||||
LDFLAGS += -L$(LIB_DIR)
|
LDFLAGS += -L$(LIB_DIR)
|
||||||
LDFLAGS += -T$(LDSCRIPT)
|
LDFLAGS += -T$(LDSCRIPT)
|
||||||
LDFLAGS += -Wl,-Map=$(OBJDIR)/$(BINARY).map
|
LDFLAGS += -Wl,-Map=$(OBJDIR)/$(BINARY).map
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "usb_lib.h"
|
#include "usb_lib.h"
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
|
||||||
volatile uint32_t Tms = 0;
|
volatile uint32_t Tms = 0;
|
||||||
|
|
||||||
@ -53,18 +54,62 @@ void iwdg_setup(){
|
|||||||
IWDG->KR = IWDG_REFRESH; /* (6) */
|
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("got new linecoding:");
|
||||||
SEND(" baudrate="); printu(lc->dwDTERate);
|
SEND(" baudrate="); printu(new_lc.dwDTERate);
|
||||||
SEND(", charFormat="); printu(lc->bCharFormat);
|
SEND(", charFormat="); printu(new_lc.bCharFormat);
|
||||||
SEND(", parityType="); printu(lc->bParityType);
|
SEND(" (");
|
||||||
SEND(", dataBits="); printu(lc->bDataBits);
|
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');
|
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){
|
void clstate_handler(uint16_t val){
|
||||||
SEND("change control line state to ");
|
SEND("change control line state to ");
|
||||||
printu(val);
|
printu(val);
|
||||||
|
if(val & CONTROL_DTR) SEND(" (DTR)");
|
||||||
|
if(val & CONTROL_RTS) SEND(" (RTS)");
|
||||||
usart_putchar('\n');
|
usart_putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +165,7 @@ int main(void){
|
|||||||
case 'L':
|
case 'L':
|
||||||
USB_send("Very long test string for USB (it's length is more than 64 bytes\n"
|
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");
|
"This is another part of the string! Can you see all of this?\n");
|
||||||
|
SEND("Long test sent\n");
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
SEND("Soft reset\n");
|
SEND("Soft reset\n");
|
||||||
@ -127,6 +173,7 @@ int main(void){
|
|||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
USB_send("Test string for USB\n");
|
USB_send("Test string for USB\n");
|
||||||
|
SEND("Short test sent\n");
|
||||||
break;
|
break;
|
||||||
case 'W':
|
case 'W':
|
||||||
SEND("Wait for reboot\n");
|
SEND("Wait for reboot\n");
|
||||||
@ -150,6 +197,9 @@ int main(void){
|
|||||||
usart_send(txt);
|
usart_send(txt);
|
||||||
L = 0;
|
L = 0;
|
||||||
}
|
}
|
||||||
|
if(lcchange){
|
||||||
|
show_new_lc();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@ -109,7 +109,7 @@ void USB_setup(){
|
|||||||
void usb_proc(){
|
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
|
||||||
MSG("Configured; activate other endpoints\n");
|
SEND("Configure endpoints\n");
|
||||||
// make new BULK endpoint
|
// make new BULK endpoint
|
||||||
// Buffer have 1024 bytes, but last 256 we use for CAN bus (30.2 of RM: USB main features)
|
// 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
|
EP_Init(1, EP_TYPE_INTERRUPT, 10, 0, EP1_Handler); // IN1 - transmit
|
||||||
|
|||||||
@ -27,18 +27,21 @@
|
|||||||
|
|
||||||
#include <stm32f0xx.h>
|
#include <stm32f0xx.h>
|
||||||
|
|
||||||
#define USB_BTABLE_BASE 0x40006000
|
/**
|
||||||
|
* Buffers size definition
|
||||||
|
**/
|
||||||
// !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
|
// !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
|
||||||
#define USB_BTABLE_SIZE 1024
|
#define USB_BTABLE_SIZE 1024
|
||||||
// first 64 bytes of USB_BTABLE are registers!
|
// first 64 bytes of USB_BTABLE are registers!
|
||||||
#define USB_EP0_BASEADDR 64
|
#define USB_EP0_BASEADDR 64
|
||||||
// for USB FS EP0 buffers are from 8 to 64 bytes long
|
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
|
||||||
#define USB_EP0_BUFSZ 8
|
#define USB_EP0_BUFSZ 64
|
||||||
// USB transmit buffer size
|
// USB transmit buffer size (64 for PL2303)
|
||||||
#define USB_TXBUFSZ 64
|
#define USB_TXBUFSZ 64
|
||||||
// USB receive buffer size
|
// USB receive buffer size (64 for PL2303)
|
||||||
#define USB_RXBUFSZ 64
|
#define USB_RXBUFSZ 64
|
||||||
|
|
||||||
|
#define USB_BTABLE_BASE 0x40006000
|
||||||
#undef USB_BTABLE
|
#undef USB_BTABLE
|
||||||
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
|
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
|
||||||
#define USB_ISTR_EPID 0x0000000F
|
#define USB_ISTR_EPID 0x0000000F
|
||||||
|
|||||||
@ -26,6 +26,9 @@
|
|||||||
#include <string.h> // memcpy
|
#include <string.h> // memcpy
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
|
ep_t endpoints[ENDPOINTS_NUM];
|
||||||
|
|
||||||
|
static usb_dev_t USB_Dev;
|
||||||
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
|
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
|
||||||
static config_pack_t setup_packet;
|
static config_pack_t setup_packet;
|
||||||
static uint8_t ep0databuf[EP0DATABUF_SIZE];
|
static uint8_t ep0databuf[EP0DATABUF_SIZE];
|
||||||
@ -33,15 +36,23 @@ static uint8_t ep0dbuflen = 0;
|
|||||||
|
|
||||||
usb_LineCoding getLineCoding(){return lineCoding;}
|
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
|
18, // bLength
|
||||||
0x01, // bDescriptorType - USB_DEVICE_DESC_TYPE
|
0x01, // bDescriptorType - Device descriptor
|
||||||
0x10, // bcdUSB_L - 1.10
|
bcdUSB_L, // bcdUSB_L - 1.10
|
||||||
0x01, // bcdUSB_H
|
bcdUSB_H, // bcdUSB_H
|
||||||
0x00, // bDeviceClass - USB_COMM
|
bDeviceClass, // bDeviceClass - USB_COMM
|
||||||
0x00, // bDeviceSubClass
|
bDeviceSubClass, // bDeviceSubClass
|
||||||
0x00, // bDeviceProtocol
|
bDeviceProtocol, // bDeviceProtocol
|
||||||
0x40, // bMaxPacketSize
|
USB_EP0_BUFSZ, // bMaxPacketSize
|
||||||
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
|
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
|
||||||
0x06, // idVendor_H
|
0x06, // idVendor_H
|
||||||
0x03, // idProduct_L
|
0x03, // idProduct_L
|
||||||
@ -51,23 +62,23 @@ const uint8_t USB_DeviceDescriptor[] = {
|
|||||||
0x01, // iManufacturer
|
0x01, // iManufacturer
|
||||||
0x02, // iProduct
|
0x02, // iProduct
|
||||||
0x00, // iSerialNumber
|
0x00, // iSerialNumber
|
||||||
0x01 // bNumConfigurations
|
bNumConfigurations // bNumConfigurations
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t USB_DeviceQualifierDescriptor[] = {
|
static const uint8_t USB_DeviceQualifierDescriptor[] = {
|
||||||
10, //bLength
|
10, //bLength
|
||||||
0x06, // bDescriptorType
|
0x06, // bDescriptorType - Device qualifier
|
||||||
0x10, // bcdUSB_L
|
bcdUSB_L, // bcdUSB_L
|
||||||
0x01, // bcdUSB_H
|
bcdUSB_H, // bcdUSB_H
|
||||||
0x00, // bDeviceClass
|
bDeviceClass, // bDeviceClass
|
||||||
0x00, // bDeviceSubClass
|
bDeviceSubClass, // bDeviceSubClass
|
||||||
0x00, // bDeviceProtocol
|
bDeviceProtocol, // bDeviceProtocol
|
||||||
0x40, // bMaxPacketSize0
|
USB_EP0_BUFSZ, // bMaxPacketSize0
|
||||||
0x01, // bNumConfigurations
|
bNumConfigurations, // bNumConfigurations
|
||||||
0x00 // Reserved
|
0x00 // Reserved
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t USB_ConfigDescriptor[] = {
|
static const uint8_t USB_ConfigDescriptor[] = {
|
||||||
/*Configuration Descriptor*/
|
/*Configuration Descriptor*/
|
||||||
0x09, /* bLength: Configuration Descriptor size */
|
0x09, /* bLength: Configuration Descriptor size */
|
||||||
0x02, /* bDescriptorType: Configuration */
|
0x02, /* bDescriptorType: Configuration */
|
||||||
@ -122,12 +133,9 @@ const uint8_t USB_ConfigDescriptor[] = {
|
|||||||
|
|
||||||
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
|
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
|
||||||
// these descriptors are not used in PL2303 emulator!
|
// these descriptors are not used in PL2303 emulator!
|
||||||
_USB_STRING_(USB_StringSerialDescriptor, u"0")
|
_USB_STRING_(USB_StringSerialDescriptor, u"0");
|
||||||
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.")
|
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.");
|
||||||
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller")
|
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
|
||||||
|
|
||||||
static usb_dev_t USB_Dev;
|
|
||||||
ep_t endpoints[ENDPOINTS_NUM];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* default handlers
|
* default handlers
|
||||||
@ -149,12 +157,8 @@ void WEAK break_handler(){
|
|||||||
|
|
||||||
// handler of vendor requests
|
// handler of vendor requests
|
||||||
void WEAK vendor_handler(config_pack_t *packet){
|
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
|
if(packet->bmRequestType & 0x80){ // read
|
||||||
|
//SEND("Read");
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
switch(packet->wValue){
|
switch(packet->wValue){
|
||||||
case 0x8484:
|
case 0x8484:
|
||||||
@ -171,8 +175,92 @@ void WEAK vendor_handler(config_pack_t *packet){
|
|||||||
}
|
}
|
||||||
EP_WriteIRQ(0, &c, 1);
|
EP_WriteIRQ(0, &c, 1);
|
||||||
}else{ // write ZLP
|
}else{ // write ZLP
|
||||||
|
//SEND("Write");
|
||||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
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
|
* @param ep - endpoint state
|
||||||
* @return data written to EP0R
|
* @return data written to EP0R
|
||||||
*/
|
*/
|
||||||
uint16_t EP0_Handler(ep_t ep){
|
static uint16_t EP0_Handler(ep_t ep){
|
||||||
uint16_t status = 0; // bus powered
|
|
||||||
uint16_t epstatus = ep.status; // EP0R on input -> return this value after modifications
|
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)
|
uint8_t reqtype = setup_packet.bmRequestType & 0x7f;
|
||||||
void wr0(const uint8_t *buf, uint16_t size){
|
uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0;
|
||||||
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
|
|
||||||
if ((ep.rx_flag) && (ep.setup_flag)){
|
if ((ep.rx_flag) && (ep.setup_flag)){
|
||||||
if (setup_packet.bmRequestType == 0x80){ // standard device request (device to host)
|
switch(reqtype){
|
||||||
switch(setup_packet.bRequest){
|
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
|
||||||
case GET_DESCRIPTOR:
|
if(dev2host){
|
||||||
switch(setup_packet.wValue){
|
std_d2h_req();
|
||||||
case DEVICE_DESCRIPTOR:
|
}else{
|
||||||
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
|
std_h2d_req();
|
||||||
break;
|
// send ZLP
|
||||||
case CONFIGURATION_DESCRIPTOR:
|
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||||
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
|
}
|
||||||
break;
|
epstatus = SET_NAK_RX(epstatus);
|
||||||
case STRING_LANG_DESCRIPTOR:
|
epstatus = SET_VALID_TX(epstatus);
|
||||||
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
|
break;
|
||||||
break;
|
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
|
||||||
case STRING_MAN_DESCRIPTOR:
|
if (setup_packet.bRequest == CLEAR_FEATURE){
|
||||||
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
|
// send ZLP
|
||||||
break;
|
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||||
case STRING_PROD_DESCRIPTOR:
|
epstatus = SET_NAK_RX(epstatus);
|
||||||
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
|
epstatus = SET_VALID_TX(epstatus);
|
||||||
break;
|
}else{
|
||||||
case STRING_SN_DESCRIPTOR:
|
WRITEDUMP("02:WR_REQ");
|
||||||
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
|
}
|
||||||
break;
|
break;
|
||||||
case DEVICE_QALIFIER_DESCRIPTOR:
|
case VENDOR_REQUEST_TYPE:
|
||||||
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
|
vendor_handler(&setup_packet);
|
||||||
break;
|
epstatus = SET_NAK_RX(epstatus);
|
||||||
default:
|
epstatus = SET_VALID_TX(epstatus);
|
||||||
WRITEDUMP("UNK_DES");
|
break;
|
||||||
break;
|
case CONTROL_REQUEST_TYPE:
|
||||||
}
|
switch(setup_packet.bRequest){
|
||||||
break;
|
case GET_LINE_CODING:
|
||||||
case GET_STATUS:
|
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
|
||||||
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
|
break;
|
||||||
break;
|
case SET_LINE_CODING: // omit this for next stage, when data will come
|
||||||
case GET_CONFIGURATION:
|
break;
|
||||||
WRITEDUMP("GET_CONFIGURATION");
|
case SET_CONTROL_LINE_STATE:
|
||||||
EP_WriteIRQ(0, &configuration, 1);
|
clstate_handler(setup_packet.wValue);
|
||||||
break;
|
break;
|
||||||
default:
|
case SEND_BREAK:
|
||||||
WRITEDUMP("80:WR_REQ");
|
break_handler();
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
epstatus = SET_NAK_RX(epstatus);
|
WRITEDUMP("undef control req");
|
||||||
epstatus = SET_VALID_TX(epstatus);
|
}
|
||||||
}else if(setup_packet.bmRequestType == 0x00){ // standard device request (host to device)
|
if(!dev2host) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
|
||||||
switch(setup_packet.bRequest){
|
epstatus = SET_VALID_RX(epstatus);
|
||||||
case SET_ADDRESS:
|
epstatus = SET_VALID_TX(epstatus);
|
||||||
// new address will be assigned later - after acknowlegement or request to host
|
break;
|
||||||
USB_Dev.USB_Addr = setup_packet.wValue;
|
default:
|
||||||
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
|
|
||||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||||
epstatus = SET_NAK_RX(epstatus);
|
epstatus = SET_NAK_RX(epstatus);
|
||||||
epstatus = SET_VALID_TX(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
|
}else if (ep.rx_flag){ // got data over EP0 or host acknowlegement
|
||||||
if(ep.rx_cnt){
|
if(ep.rx_cnt){
|
||||||
|
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||||
if(setup_packet.bRequest == SET_LINE_CODING){
|
if(setup_packet.bRequest == SET_LINE_CODING){
|
||||||
//WRITEDUMP("SET_LINE_CODING");
|
//WRITEDUMP("SET_LINE_CODING");
|
||||||
linecoding_handler((usb_LineCoding*)ep0databuf);
|
linecoding_handler((usb_LineCoding*)ep0databuf);
|
||||||
}
|
}
|
||||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
|
||||||
}
|
}
|
||||||
// Close transaction
|
// Close transaction
|
||||||
epstatus = CLEAR_DTOG_RX(epstatus);
|
epstatus = CLEAR_DTOG_RX(epstatus);
|
||||||
@ -348,6 +383,7 @@ uint16_t EP0_Handler(ep_t ep){
|
|||||||
#endif
|
#endif
|
||||||
return epstatus;
|
return epstatus;
|
||||||
}
|
}
|
||||||
|
#undef WRITEDUMP
|
||||||
|
|
||||||
static uint16_t lastaddr = USB_EP0_BASEADDR;
|
static uint16_t lastaddr = USB_EP0_BASEADDR;
|
||||||
/**
|
/**
|
||||||
@ -361,6 +397,7 @@ static uint16_t lastaddr = USB_EP0_BASEADDR;
|
|||||||
* @return 0 if all OK
|
* @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)){
|
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(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
|
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable
|
||||||
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
|
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;
|
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
|
||||||
endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr);
|
endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr);
|
||||||
lastaddr += rxsz;
|
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;
|
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
|
||||||
endpoints[number].func = func;
|
endpoints[number].func = func;
|
||||||
return 0;
|
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
|
// standard IRQ handler
|
||||||
void usb_isr(){
|
void usb_isr(){
|
||||||
uint8_t n;
|
|
||||||
if (USB->ISTR & USB_ISTR_RESET){
|
if (USB->ISTR & USB_ISTR_RESET){
|
||||||
// Reinit registers
|
// Reinit registers
|
||||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
|
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
|
||||||
@ -404,7 +440,7 @@ void usb_isr(){
|
|||||||
}
|
}
|
||||||
if(USB->ISTR & USB_ISTR_CTR){
|
if(USB->ISTR & USB_ISTR_CTR){
|
||||||
// EP number
|
// EP number
|
||||||
n = USB->ISTR & USB_ISTR_EPID;
|
uint8_t n = USB->ISTR & USB_ISTR_EPID;
|
||||||
// copy status register
|
// copy status register
|
||||||
uint16_t epstatus = USB->EPnR[n];
|
uint16_t epstatus = USB->EPnR[n];
|
||||||
// Calculate flags
|
// Calculate flags
|
||||||
@ -412,7 +448,7 @@ void usb_isr(){
|
|||||||
endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0;
|
endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0;
|
||||||
endpoints[n].tx_flag = (epstatus & USB_EPnR_CTR_TX) ? 1 : 0;
|
endpoints[n].tx_flag = (epstatus & USB_EPnR_CTR_TX) ? 1 : 0;
|
||||||
// copy received bytes amount
|
// 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
|
// 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(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
|
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){
|
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
if(size > USB_TXBUFSZ) size = USB_TXBUFSZ;
|
||||||
uint16_t N2 = (size + 1) >> 1;
|
uint16_t N2 = (size + 1) >> 1;
|
||||||
// the buffer is 16-bit, so we should copy data as it would be uint16_t
|
// the buffer is 16-bit, so we should copy data as it would be uint16_t
|
||||||
uint16_t *buf16 = (uint16_t *)buf;
|
uint16_t *buf16 = (uint16_t *)buf;
|
||||||
|
|||||||
@ -32,6 +32,11 @@
|
|||||||
|
|
||||||
// Max EP amount (EP0 + other used)
|
// Max EP amount (EP0 + other used)
|
||||||
#define ENDPOINTS_NUM 4
|
#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
|
// bRequest, standard; for bmRequestType == 0x80
|
||||||
#define GET_STATUS 0x00
|
#define GET_STATUS 0x00
|
||||||
#define GET_DESCRIPTOR 0x06
|
#define GET_DESCRIPTOR 0x06
|
||||||
@ -46,21 +51,14 @@
|
|||||||
#define GET_INTERFACE 0x0A // unused
|
#define GET_INTERFACE 0x0A // unused
|
||||||
#define SET_INTERFACE 0x0B // unused
|
#define SET_INTERFACE 0x0B // unused
|
||||||
#define SYNC_FRAME 0x0C // unused
|
#define SYNC_FRAME 0x0C // unused
|
||||||
|
#define VENDOR_REQUEST 0x01 // 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
|
|
||||||
|
|
||||||
// Class-Specific Control Requests
|
// Class-Specific Control Requests
|
||||||
#define SEND_ENCAPSULATED_COMMAND 0x00
|
#define SEND_ENCAPSULATED_COMMAND 0x00 // unused
|
||||||
#define GET_ENCAPSULATED_RESPONSE 0x01
|
#define GET_ENCAPSULATED_RESPONSE 0x01 // unused
|
||||||
#define SET_COMM_FEATURE 0x02
|
#define SET_COMM_FEATURE 0x02 // unused
|
||||||
#define GET_COMM_FEATURE 0x03
|
#define GET_COMM_FEATURE 0x03 // unused
|
||||||
#define CLEAR_COMM_FEATURE 0x04
|
#define CLEAR_COMM_FEATURE 0x04 // unused
|
||||||
#define SET_LINE_CODING 0x20
|
#define SET_LINE_CODING 0x20
|
||||||
#define GET_LINE_CODING 0x21
|
#define GET_LINE_CODING 0x21
|
||||||
#define SET_CONTROL_LINE_STATE 0x22
|
#define SET_CONTROL_LINE_STATE 0x22
|
||||||
@ -77,7 +75,7 @@
|
|||||||
#define STRING_MAN_DESCRIPTOR 0x301
|
#define STRING_MAN_DESCRIPTOR 0x301
|
||||||
#define STRING_PROD_DESCRIPTOR 0x302
|
#define STRING_PROD_DESCRIPTOR 0x302
|
||||||
#define STRING_SN_DESCRIPTOR 0x303
|
#define STRING_SN_DESCRIPTOR 0x303
|
||||||
#define DEVICE_QALIFIER_DESCRIPTOR 0x600
|
#define DEVICE_QUALIFIER_DESCRIPTOR 0x600
|
||||||
|
|
||||||
// EPnR bits manipulation
|
// EPnR bits manipulation
|
||||||
#define CLEAR_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? R : (R & (~USB_EPnR_DTOG_RX))
|
#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]; \
|
uint16_t bString[(sizeof(str) - 2) / 2]; \
|
||||||
\
|
\
|
||||||
} \
|
} \
|
||||||
name = {sizeof(name), 0x03, str};
|
name = {sizeof(name), 0x03, str}
|
||||||
|
|
||||||
#define _USB_LANG_ID_(name, lng_id) \
|
#define _USB_LANG_ID_(name, lng_id) \
|
||||||
\
|
\
|
||||||
@ -132,7 +130,7 @@ static const struct name \
|
|||||||
uint16_t bString; \
|
uint16_t bString; \
|
||||||
\
|
\
|
||||||
} \
|
} \
|
||||||
name = {0x04, 0x03, lng_id};
|
name = {0x04, 0x03, lng_id}
|
||||||
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
|
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
|
||||||
|
|
||||||
// EP0 configuration packet
|
// EP0 configuration packet
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user