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 += -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
|
||||
|
||||
@ -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.
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user