mirror of
https://github.com/eddyem/stm32samples.git
synced 2026-03-22 01:31:21 +03:00
almost (for single write < 64 bytes) working PL2303 (both in Linux and game-firmware)
This commit is contained in:
@@ -11,7 +11,7 @@ DEFS += -DUSARTNUM=1
|
||||
#DEFS += -DEBUG
|
||||
# change this linking script depending on particular MCU model,
|
||||
# for example, if you have STM32F103VBT6, you should write:
|
||||
LDSCRIPT = stm32f042k.ld
|
||||
LDSCRIPT = ld/stm32f042k.ld
|
||||
|
||||
INDEPENDENT_HEADERS=
|
||||
|
||||
@@ -48,7 +48,7 @@ STARTUP = $(OBJDIR)/startup.o
|
||||
OBJS += $(STARTUP)
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
|
||||
INC_DIR ?= ../inc
|
||||
INC_DIR ?= ../../inc
|
||||
|
||||
INCLUDE := -I$(INC_DIR)/F0 -I$(INC_DIR)/cm
|
||||
LIB_DIR := $(INC_DIR)/ld
|
||||
|
||||
@@ -136,8 +136,13 @@ int main(void){
|
||||
printuhex(getCANID());
|
||||
newline();
|
||||
break;
|
||||
case 'T':
|
||||
SEND("Time (ms): ");
|
||||
printu(Tms);
|
||||
newline();
|
||||
break;
|
||||
case 'U':
|
||||
USB_send("Test string for USB\n");
|
||||
USB_send("Test string for USB; a very long string that don't fit into one 64-byte buffer, what will be with it?\n");
|
||||
break;
|
||||
case 'W':
|
||||
SEND("Wait for reboot\n");
|
||||
@@ -151,6 +156,7 @@ int main(void){
|
||||
"'G' - get CAN address\n"
|
||||
"'R' - software reset\n"
|
||||
"'S' - reinit CAN (with new address)\n"
|
||||
"'T' - gen time from start (ms)"
|
||||
"'U' - send test string over USB\n"
|
||||
"'W' - test watchdog\n"
|
||||
);
|
||||
@@ -162,6 +168,7 @@ int main(void){
|
||||
if(L){ // text waits for sending
|
||||
txt[L] = 0;
|
||||
usart_send(txt);
|
||||
USB_send(txt);
|
||||
L = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,13 @@ void usart_send(const char *str){
|
||||
}
|
||||
}
|
||||
|
||||
void usart_sendn(const char *str, uint8_t L){
|
||||
for(uint8_t i = 0; i < L; ++i){
|
||||
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
|
||||
tbuf[tbufno][odatalen[tbufno]++] = *str++;
|
||||
}
|
||||
}
|
||||
|
||||
void newline(){
|
||||
usart_putchar('\n');
|
||||
transmit_tbuf();
|
||||
@@ -223,15 +230,21 @@ void printu(uint32_t val){
|
||||
// print 32bit unsigned int as hex
|
||||
void printuhex(uint32_t val){
|
||||
usart_send("0x");
|
||||
uint8_t *ptr = (uint8_t*)&val + 3;
|
||||
uint8_t *ptr = (uint8_t*)&val + 3, start = 1;
|
||||
int i, j;
|
||||
for(i = 0; i < 4; ++i, --ptr){
|
||||
if(!*ptr && start) continue;
|
||||
for(j = 1; j > -1; --j){
|
||||
start = 0;
|
||||
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
|
||||
if(half < 10) usart_putchar(half + '0');
|
||||
else usart_putchar(half - 10 + 'a');
|
||||
}
|
||||
}
|
||||
if(start){
|
||||
usart_putchar('0');
|
||||
usart_putchar('0');
|
||||
}
|
||||
}
|
||||
|
||||
// dump memory buffer
|
||||
|
||||
@@ -50,6 +50,7 @@ void transmit_tbuf();
|
||||
void usart_setup();
|
||||
int usart_getline(char **line);
|
||||
void usart_send(const char *str);
|
||||
void usart_sendn(const char *str, uint8_t L);
|
||||
void newline();
|
||||
void usart_putchar(const char ch);
|
||||
void printu(uint32_t val);
|
||||
|
||||
@@ -83,7 +83,7 @@ const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
0x80, /* bmAttributes - Bus powered */
|
||||
0xa0, /* bmAttributes - Bus powered, Remote wakeup */
|
||||
0x32, /* MaxPower 100 mA */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@@ -127,17 +127,11 @@ const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
};
|
||||
|
||||
const uint8_t USB_StringLangDescriptor[] = {
|
||||
STRING_LANG_DESCRIPTOR_SIZE_BYTE, // bLength
|
||||
0x03, // bDescriptorType
|
||||
0x09, // wLANGID_L
|
||||
0x04 // wLANGID_H
|
||||
};
|
||||
|
||||
_USB_LANG_ID_(LANG_US);
|
||||
// these descriptors are not used in PL2303 emulator!
|
||||
_USB_STRING_(USB_StringSerialDescriptor, L"0.01")
|
||||
_USB_STRING_(USB_StringManufacturingDescriptor, L"Russia, SAO RAS")
|
||||
_USB_STRING_(USB_StringProdDescriptor, L"TSYS01 sensors controller")
|
||||
_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;
|
||||
static ep_t endpoints[MAX_ENDPOINTS];
|
||||
@@ -173,8 +167,26 @@ 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
|
||||
uint8_t c = '?';
|
||||
uint8_t c;
|
||||
switch(packet->wValue){
|
||||
case 0x8484:
|
||||
c = 2;
|
||||
break;
|
||||
case 0x0080:
|
||||
c = 1;
|
||||
break;
|
||||
case 0x8686:
|
||||
c = 0xaa;
|
||||
break;
|
||||
default:
|
||||
c = 0;
|
||||
}
|
||||
EP_WriteIRQ(0, &c, 1);
|
||||
}else{ // write ZLP
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
@@ -218,16 +230,30 @@ uint16_t EP0_Handler(ep_t ep){
|
||||
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
|
||||
break;
|
||||
case STRING_LANG_DESCRIPTOR:
|
||||
wr0(USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
|
||||
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
|
||||
#ifdef EBUG
|
||||
SEND("STRING_LANG_DESCRIPTOR\n");
|
||||
#endif
|
||||
break;
|
||||
case STRING_MAN_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
|
||||
#ifdef EBUG
|
||||
SEND("STRING_MAN_DESCRIPTOR: ");
|
||||
usart_sendn((char*)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength); usart_putchar('\n');
|
||||
#endif
|
||||
break;
|
||||
case STRING_PROD_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
|
||||
#ifdef EBUG
|
||||
SEND("STRING_PROD_DESCRIPTOR: ");
|
||||
usart_sendn((char*)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength); usart_putchar('\n');
|
||||
#endif
|
||||
break;
|
||||
case STRING_SN_DESCRIPTOR:
|
||||
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
|
||||
#ifdef EBUG
|
||||
SEND("STRING_SN_DESCRIPTOR\n");
|
||||
#endif
|
||||
break;
|
||||
case DEVICE_QALIFIER_DESCRIPTOR:
|
||||
wr0(USB_DeviceQualifierDescriptor, DEVICE_QALIFIER_SIZE_BYTE);
|
||||
@@ -280,7 +306,6 @@ uint16_t EP0_Handler(ep_t ep){
|
||||
}
|
||||
}else if((setup_packet.bmRequestType & VENDOR_MASK_REQUEST) == VENDOR_MASK_REQUEST){ // vendor request
|
||||
vendor_handler(&setup_packet);
|
||||
WRITEDUMP("VENDOR");
|
||||
epstatus = SET_NAK_RX(epstatus);
|
||||
epstatus = SET_VALID_TX(epstatus);
|
||||
}else if((setup_packet.bmRequestType & 0x7f) == CONTROL_REQUEST_TYPE){ // control request
|
||||
|
||||
@@ -109,16 +109,29 @@
|
||||
#define EP_TYPE_ISO 0x02
|
||||
#define EP_TYPE_INTERRUPT 0x03
|
||||
|
||||
#define LANG_US (uint16_t)0x0409
|
||||
|
||||
#define _USB_STRING_(name, str) \
|
||||
const struct name \
|
||||
static const struct name \
|
||||
{ \
|
||||
uint8_t bLength; \
|
||||
uint8_t bDescriptorType; \
|
||||
wchar_t bString[(sizeof(str) - 2) / 2]; \
|
||||
uint16_t bString[(sizeof(str) - 2) / 2]; \
|
||||
\
|
||||
} \
|
||||
name = {sizeof(name), 0x03, str};
|
||||
|
||||
#define _USB_LANG_ID_(lng_id) \
|
||||
\
|
||||
static const struct USB_StringLangDescriptor \
|
||||
{ \
|
||||
uint8_t bLength; \
|
||||
uint8_t bDescriptorType; \
|
||||
uint16_t bString; \
|
||||
\
|
||||
} \
|
||||
USB_StringLangDescriptor = {0x04, 0x03, lng_id};
|
||||
|
||||
// EP0 configuration packet
|
||||
typedef struct {
|
||||
uint8_t bmRequestType;
|
||||
|
||||
Reference in New Issue
Block a user