mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
fixed USB: add iInterface, remove trash
This commit is contained in:
parent
6832befb4a
commit
dba4cdf515
@ -19,7 +19,7 @@
|
|||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
int LEDsON = 0;
|
int LEDsON = 1;
|
||||||
|
|
||||||
// setup here ALL GPIO pins (due to table in Readme.md)
|
// setup here ALL GPIO pins (due to table in Readme.md)
|
||||||
// leave SWD as default AF; high speed for CLK and some other AF; med speed for some another AF
|
// leave SWD as default AF; high speed for CLK and some other AF; med speed for some another AF
|
||||||
|
|||||||
@ -87,7 +87,6 @@ int main(void){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
i2c_have_DMA_Rx(); // check if there's DMA Rx complete
|
i2c_have_DMA_Rx(); // check if there's DMA Rx complete
|
||||||
USB_proc();
|
|
||||||
int l = USB_receivestr(inbuff, MAXSTRLEN);
|
int l = USB_receivestr(inbuff, MAXSTRLEN);
|
||||||
if(l < 0) USB_sendstr("ERROR: USB buffer overflow or string was too long\n");
|
if(l < 0) USB_sendstr("ERROR: USB buffer overflow or string was too long\n");
|
||||||
else if(l){
|
else if(l){
|
||||||
|
|||||||
Binary file not shown.
@ -19,23 +19,22 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "ringbuffer.h"
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "usb_lib.h"
|
#include "usb_lib.h"
|
||||||
|
|
||||||
static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data
|
static volatile uint8_t usbbuff[USB_TXBUFSZ]; // temporary buffer for sending data
|
||||||
// ring buffers for incoming and outgoing data
|
// ring buffers for incoming and outgoing data
|
||||||
static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ];
|
static uint8_t obuf[RBOUTSZ], ibuf[RBINSZ];
|
||||||
static volatile ringbuffer out = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0};
|
volatile ringbuffer rbout = {.data = obuf, .length = RBOUTSZ, .head = 0, .tail = 0};
|
||||||
static volatile ringbuffer in = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0};
|
volatile ringbuffer rbin = {.data = ibuf, .length = RBINSZ, .head = 0, .tail = 0};
|
||||||
// transmission is succesfull
|
// transmission is succesfull
|
||||||
static volatile uint8_t bufisempty = 1;
|
volatile uint8_t bufisempty = 1;
|
||||||
static volatile uint8_t bufovrfl = 0;
|
volatile uint8_t bufovrfl = 0;
|
||||||
|
|
||||||
static void send_next(){
|
void send_next(){
|
||||||
if(bufisempty) return;
|
if(bufisempty) return;
|
||||||
static int lastdsz = 0;
|
static int lastdsz = 0;
|
||||||
int buflen = RB_read((ringbuffer*)&out, (uint8_t*)usbbuff, USB_TXBUFSZ);
|
int buflen = RB_read((ringbuffer*)&rbout, (uint8_t*)usbbuff, USB_TXBUFSZ);
|
||||||
if(!buflen){
|
if(!buflen){
|
||||||
if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send
|
if(lastdsz == 64) EP_Write(3, NULL, 0); // send ZLP after 64 bits packet when nothing more to send
|
||||||
lastdsz = 0;
|
lastdsz = 0;
|
||||||
@ -58,7 +57,7 @@ int USB_sendall(){
|
|||||||
int USB_send(const uint8_t *buf, int len){
|
int USB_send(const uint8_t *buf, int len){
|
||||||
if(!buf || !usbON || !len) return 0;
|
if(!buf || !usbON || !len) return 0;
|
||||||
while(len){
|
while(len){
|
||||||
int a = RB_write((ringbuffer*)&out, buf, len);
|
int a = RB_write((ringbuffer*)&rbout, buf, len);
|
||||||
len -= a;
|
len -= a;
|
||||||
buf += a;
|
buf += a;
|
||||||
if(bufisempty){
|
if(bufisempty){
|
||||||
@ -71,7 +70,7 @@ int USB_send(const uint8_t *buf, int len){
|
|||||||
|
|
||||||
int USB_putbyte(uint8_t byte){
|
int USB_putbyte(uint8_t byte){
|
||||||
if(!usbON) return 0;
|
if(!usbON) return 0;
|
||||||
while(0 == RB_write((ringbuffer*)&out, &byte, 1)){
|
while(0 == RB_write((ringbuffer*)&rbout, &byte, 1)){
|
||||||
if(bufisempty){
|
if(bufisempty){
|
||||||
bufisempty = 0;
|
bufisempty = 0;
|
||||||
send_next();
|
send_next();
|
||||||
@ -96,9 +95,9 @@ int USB_sendstr(const char *string){
|
|||||||
* @return amount of received bytes (negative, if overfull happened)
|
* @return amount of received bytes (negative, if overfull happened)
|
||||||
*/
|
*/
|
||||||
int USB_receive(uint8_t *buf, int len){
|
int USB_receive(uint8_t *buf, int len){
|
||||||
int sz = RB_read((ringbuffer*)&in, buf, len);
|
int sz = RB_read((ringbuffer*)&rbin, buf, len);
|
||||||
if(bufovrfl){
|
if(bufovrfl){
|
||||||
RB_clearbuf((ringbuffer*)&in);
|
RB_clearbuf((ringbuffer*)&rbin);
|
||||||
if(!sz) sz = -1;
|
if(!sz) sz = -1;
|
||||||
else sz = -sz;
|
else sz = -sz;
|
||||||
bufovrfl = 0;
|
bufovrfl = 0;
|
||||||
@ -113,9 +112,9 @@ int USB_receive(uint8_t *buf, int len){
|
|||||||
* @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared)
|
* @return strlen or negative value indicating overflow (if so, string won't be ends with 0 and buffer should be cleared)
|
||||||
*/
|
*/
|
||||||
int USB_receivestr(char *buf, int len){
|
int USB_receivestr(char *buf, int len){
|
||||||
int l = RB_readto((ringbuffer*)&in, '\n', (uint8_t*)buf, len);
|
int l = RB_readto((ringbuffer*)&rbin, '\n', (uint8_t*)buf, len);
|
||||||
if(l == 0) return 0;
|
if(l == 0) return 0;
|
||||||
if(--l < 0 || bufovrfl) RB_clearbuf((ringbuffer*)&in);
|
if(--l < 0 || bufovrfl) RB_clearbuf((ringbuffer*)&rbin);
|
||||||
else buf[l] = 0; // replace '\n' with strend
|
else buf[l] = 0; // replace '\n' with strend
|
||||||
if(bufovrfl){
|
if(bufovrfl){
|
||||||
if(l > 0) l = -l;
|
if(l > 0) l = -l;
|
||||||
@ -125,53 +124,3 @@ int USB_receivestr(char *buf, int len){
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interrupt IN handler (never used?)
|
|
||||||
static void EP1_Handler(){
|
|
||||||
uint16_t epstatus = KEEP_DTOG(USB->EPnR[1]);
|
|
||||||
if(RX_FLAG(epstatus)) epstatus = (epstatus & ~USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_RX; // set valid RX
|
|
||||||
else epstatus = epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_STAT_RX);
|
|
||||||
// clear CTR
|
|
||||||
epstatus = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX));
|
|
||||||
USB->EPnR[1] = epstatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
// data IN/OUT handlers
|
|
||||||
static void transmit_Handler(){ // EP3IN
|
|
||||||
uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[3]);
|
|
||||||
// clear CTR keep DTOGs & STATs
|
|
||||||
USB->EPnR[3] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr
|
|
||||||
send_next();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void receive_Handler(){ // EP2OUT
|
|
||||||
uint8_t buf[USB_RXBUFSZ];
|
|
||||||
uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]);
|
|
||||||
uint8_t sz = EP_Read(2, (uint8_t*)buf);
|
|
||||||
if(sz){
|
|
||||||
if(RB_write((ringbuffer*)&in, buf, sz) != sz) bufovrfl = 1;
|
|
||||||
}
|
|
||||||
// keep stat_tx & set ACK rx, clear RX ctr
|
|
||||||
USB->EPnR[2] = (epstatus & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USB_proc(){
|
|
||||||
switch(USB_Dev.USB_Status){
|
|
||||||
case USB_STATE_CONFIGURED:
|
|
||||||
// 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, USB_EP1BUFSZ, 0, EP1_Handler); // IN1 - transmit
|
|
||||||
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, receive_Handler); // OUT2 - receive data
|
|
||||||
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, transmit_Handler); // IN3 - transmit data
|
|
||||||
USB_Dev.USB_Status = USB_STATE_CONNECTED;
|
|
||||||
break;
|
|
||||||
case USB_STATE_DEFAULT:
|
|
||||||
case USB_STATE_ADDRESSED:
|
|
||||||
if(usbON){
|
|
||||||
usbON = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: // USB_STATE_CONNECTED - send next data portion
|
|
||||||
// if(!usbON) return; // WTF?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ringbuffer.h"
|
||||||
#include "usbhw.h"
|
#include "usbhw.h"
|
||||||
|
|
||||||
// sizes of ringbuffers for outgoing and incoming data
|
// sizes of ringbuffers for outgoing and incoming data
|
||||||
@ -36,7 +37,10 @@
|
|||||||
#define DBG(str)
|
#define DBG(str)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void USB_proc();
|
extern volatile ringbuffer rbout, rbin;
|
||||||
|
extern volatile uint8_t bufisempty, bufovrfl;
|
||||||
|
|
||||||
|
void send_next();
|
||||||
int USB_sendall();
|
int USB_sendall();
|
||||||
int USB_send(const uint8_t *buf, int len);
|
int USB_send(const uint8_t *buf, int len);
|
||||||
int USB_putbyte(uint8_t byte);
|
int USB_putbyte(uint8_t byte);
|
||||||
|
|||||||
@ -17,14 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "usb.h"
|
||||||
#include "usb_lib.h"
|
#include "usb_lib.h"
|
||||||
|
#include "usbhw.h"
|
||||||
|
|
||||||
ep_t endpoints[STM32ENDPOINTS];
|
ep_t endpoints[STM32ENDPOINTS];
|
||||||
|
|
||||||
usb_dev_t USB_Dev;
|
static uint16_t USB_Addr = 0;
|
||||||
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
|
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
|
||||||
config_pack_t setup_packet;
|
uint8_t ep0databuf[EP0DATABUF_SIZE], setupdatabuf[EP0DATABUF_SIZE];
|
||||||
uint8_t ep0databuf[EP0DATABUF_SIZE];
|
config_pack_t *setup_packet = (config_pack_t*) setupdatabuf;
|
||||||
|
|
||||||
usb_LineCoding getLineCoding(){return lineCoding;}
|
usb_LineCoding getLineCoding(){return lineCoding;}
|
||||||
|
|
||||||
@ -53,9 +55,9 @@ static const uint8_t USB_DeviceDescriptor[] = {
|
|||||||
0x23, // idProduct_H
|
0x23, // idProduct_H
|
||||||
0x00, // bcdDevice_Ver_L
|
0x00, // bcdDevice_Ver_L
|
||||||
0x03, // bcdDevice_Ver_H
|
0x03, // bcdDevice_Ver_H
|
||||||
0x01, // iManufacturer
|
iMANUFACTURER_DESCR, // iManufacturer
|
||||||
0x02, // iProduct
|
iPRODUCT_DESCR, // iProduct
|
||||||
0x00, // iSerialNumber
|
iSERIAL_DESCR, // iSerialNumber
|
||||||
bNumConfigurations // bNumConfigurations
|
bNumConfigurations // bNumConfigurations
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -95,7 +97,7 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
|||||||
0xff, /* bInterfaceClass */
|
0xff, /* bInterfaceClass */
|
||||||
0x00, /* bInterfaceSubClass */
|
0x00, /* bInterfaceSubClass */
|
||||||
0x00, /* bInterfaceProtocol */
|
0x00, /* bInterfaceProtocol */
|
||||||
0x00, /* iInterface: */
|
iINTERFACE_DESCR, /* iInterface: */
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
/*Endpoint 1 Descriptor*/
|
/*Endpoint 1 Descriptor*/
|
||||||
0x07, /* bLength: Endpoint Descriptor size */
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
@ -125,11 +127,19 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
|||||||
0x00, /* bInterval: ignore for Bulk transfer */
|
0x00, /* bInterval: ignore for Bulk transfer */
|
||||||
};
|
};
|
||||||
|
|
||||||
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
|
_USB_LANG_ID_(LD, LANG_US);
|
||||||
// these descriptors are not used in PL2303 emulator!
|
_USB_STRING_(SD, u"0.0.1");
|
||||||
_USB_STRING_(USB_StringSerialDescriptor, u"0");
|
_USB_STRING_(MD, u"Prolific Technology Inc.");
|
||||||
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.");
|
_USB_STRING_(PD, u"USB-Serial Controller");
|
||||||
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
|
_USB_STRING_(ID, u"nitrogen_flooding");
|
||||||
|
static void const *StringDescriptor[iDESCR_AMOUNT] = {
|
||||||
|
[iLANGUAGE_DESCR] = &LD,
|
||||||
|
[iMANUFACTURER_DESCR] = &MD,
|
||||||
|
[iPRODUCT_DESCR] = &PD,
|
||||||
|
[iSERIAL_DESCR] = &SD,
|
||||||
|
[iINTERFACE_DESCR] = &ID
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* default handlers
|
* default handlers
|
||||||
@ -171,7 +181,7 @@ void WEAK vendor_handler(config_pack_t *packet){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void wr0(const uint8_t *buf, uint16_t size){
|
static void wr0(const uint8_t *buf, uint16_t size){
|
||||||
if(setup_packet.wLength < size) size = setup_packet.wLength; // shortened request
|
if(setup_packet->wLength < size) size = setup_packet->wLength; // shortened request
|
||||||
if(size < endpoints[0].txbufsz){
|
if(size < endpoints[0].txbufsz){
|
||||||
EP_WriteIRQ(0, buf, size);
|
EP_WriteIRQ(0, buf, size);
|
||||||
return;
|
return;
|
||||||
@ -199,24 +209,18 @@ static void wr0(const uint8_t *buf, uint16_t size){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void get_descriptor(){
|
static inline void get_descriptor(){
|
||||||
switch(setup_packet.wValue){
|
uint8_t descrtype = setup_packet->wValue >> 8,
|
||||||
|
descridx = setup_packet->wValue & 0xff;
|
||||||
|
switch(descrtype){
|
||||||
case DEVICE_DESCRIPTOR:
|
case DEVICE_DESCRIPTOR:
|
||||||
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
|
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
|
||||||
break;
|
break;
|
||||||
case CONFIGURATION_DESCRIPTOR:
|
case CONFIGURATION_DESCRIPTOR:
|
||||||
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
|
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
|
||||||
break;
|
break;
|
||||||
case STRING_LANG_DESCRIPTOR:
|
case STRING_DESCRIPTOR:
|
||||||
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
|
if(descridx < iDESCR_AMOUNT) wr0((const uint8_t *)StringDescriptor[descridx], *((uint8_t*)StringDescriptor[descridx]));
|
||||||
break;
|
else EP_WriteIRQ(0, (uint8_t*)0, 0);
|
||||||
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;
|
break;
|
||||||
case DEVICE_QUALIFIER_DESCRIPTOR:
|
case DEVICE_QUALIFIER_DESCRIPTOR:
|
||||||
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
|
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
|
||||||
@ -229,7 +233,7 @@ static inline void get_descriptor(){
|
|||||||
static uint16_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
|
static uint16_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
|
||||||
static inline void std_d2h_req(){
|
static inline void std_d2h_req(){
|
||||||
uint16_t status = 0; // bus powered
|
uint16_t status = 0; // bus powered
|
||||||
switch(setup_packet.bRequest){
|
switch(setup_packet->bRequest){
|
||||||
case GET_DESCRIPTOR:
|
case GET_DESCRIPTOR:
|
||||||
get_descriptor();
|
get_descriptor();
|
||||||
break;
|
break;
|
||||||
@ -244,16 +248,47 @@ static inline void std_d2h_req(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// interrupt IN handler (never used?)
|
||||||
|
static void EP1_Handler(){
|
||||||
|
uint16_t epstatus = KEEP_DTOG(USB->EPnR[1]);
|
||||||
|
if(RX_FLAG(epstatus)) epstatus = (epstatus & ~USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_RX; // set valid RX
|
||||||
|
else epstatus = epstatus & ~(USB_EPnR_STAT_TX|USB_EPnR_STAT_RX);
|
||||||
|
// clear CTR
|
||||||
|
epstatus = (epstatus & ~(USB_EPnR_CTR_RX|USB_EPnR_CTR_TX));
|
||||||
|
USB->EPnR[1] = epstatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// data IN/OUT handlers
|
||||||
|
static void transmit_Handler(){ // EP3IN
|
||||||
|
uint16_t epstatus = KEEP_DTOG_STAT(USB->EPnR[3]);
|
||||||
|
// clear CTR keep DTOGs & STATs
|
||||||
|
USB->EPnR[3] = (epstatus & ~(USB_EPnR_CTR_TX)); // clear TX ctr
|
||||||
|
send_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void receive_Handler(){ // EP2OUT
|
||||||
|
uint8_t buf[USB_RXBUFSZ];
|
||||||
|
uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]);
|
||||||
|
uint8_t sz = EP_Read(2, (uint8_t*)buf);
|
||||||
|
if(sz){
|
||||||
|
if(RB_write((ringbuffer*)&rbin, buf, sz) != sz) bufovrfl = 1;
|
||||||
|
}
|
||||||
|
// keep stat_tx & set ACK rx, clear RX ctr
|
||||||
|
USB->EPnR[2] = (epstatus & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void std_h2d_req(){
|
static inline void std_h2d_req(){
|
||||||
switch(setup_packet.bRequest){
|
switch(setup_packet->bRequest){
|
||||||
case SET_ADDRESS:
|
case SET_ADDRESS:
|
||||||
// new address will be assigned later - after acknowlegement or request to host
|
// new address will be assigned later - after acknowlegement or request to host
|
||||||
USB_Dev.USB_Addr = setup_packet.wValue;
|
USB_Addr = setup_packet->wValue;
|
||||||
break;
|
break;
|
||||||
case SET_CONFIGURATION:
|
case SET_CONFIGURATION:
|
||||||
// Now device configured
|
// Now device configured
|
||||||
USB_Dev.USB_Status = USB_STATE_CONFIGURED;
|
configuration = setup_packet->wValue;
|
||||||
configuration = setup_packet.wValue;
|
EP_Init(1, EP_TYPE_INTERRUPT, USB_EP1BUFSZ, 0, EP1_Handler); // IN1 - transmit
|
||||||
|
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, receive_Handler); // OUT2 - receive data
|
||||||
|
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, transmit_Handler); // IN3 - transmit data
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -271,8 +306,8 @@ bmRequestType: 76543210
|
|||||||
*/
|
*/
|
||||||
void EP0_Handler(){
|
void EP0_Handler(){
|
||||||
uint16_t epstatus = USB->EPnR[0]; // EP0R on input -> return this value after modifications
|
uint16_t epstatus = USB->EPnR[0]; // EP0R on input -> return this value after modifications
|
||||||
uint8_t reqtype = setup_packet.bmRequestType & 0x7f;
|
uint8_t reqtype = setup_packet->bmRequestType & 0x7f;
|
||||||
uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0;
|
uint8_t dev2host = (setup_packet->bmRequestType & 0x80) ? 1 : 0;
|
||||||
int rxflag = RX_FLAG(epstatus);
|
int rxflag = RX_FLAG(epstatus);
|
||||||
if(rxflag && SETUP_FLAG(epstatus)){
|
if(rxflag && SETUP_FLAG(epstatus)){
|
||||||
switch(reqtype){
|
switch(reqtype){
|
||||||
@ -285,15 +320,15 @@ void EP0_Handler(){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
|
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
|
||||||
if(setup_packet.bRequest == CLEAR_FEATURE){
|
if(setup_packet->bRequest == CLEAR_FEATURE){
|
||||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VENDOR_REQUEST_TYPE:
|
case VENDOR_REQUEST_TYPE:
|
||||||
vendor_handler(&setup_packet);
|
vendor_handler(setup_packet);
|
||||||
break;
|
break;
|
||||||
case CONTROL_REQUEST_TYPE:
|
case CONTROL_REQUEST_TYPE:
|
||||||
switch(setup_packet.bRequest){
|
switch(setup_packet->bRequest){
|
||||||
case GET_LINE_CODING:
|
case GET_LINE_CODING:
|
||||||
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
|
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
|
||||||
break;
|
break;
|
||||||
@ -301,7 +336,7 @@ void EP0_Handler(){
|
|||||||
break;
|
break;
|
||||||
case SET_CONTROL_LINE_STATE:
|
case SET_CONTROL_LINE_STATE:
|
||||||
usbON = 1;
|
usbON = 1;
|
||||||
clstate_handler(setup_packet.wValue);
|
clstate_handler(setup_packet->wValue);
|
||||||
break;
|
break;
|
||||||
case SEND_BREAK:
|
case SEND_BREAK:
|
||||||
usbON = 0;
|
usbON = 0;
|
||||||
@ -310,23 +345,22 @@ void EP0_Handler(){
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(setup_packet.bRequest != GET_LINE_CODING) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
|
if(setup_packet->bRequest != GET_LINE_CODING) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||||
}
|
}
|
||||||
}else if(rxflag){ // got data over EP0 or host acknowlegement
|
}else if(rxflag){ // got data over EP0 or host acknowlegement
|
||||||
if(endpoints[0].rx_cnt){
|
if(endpoints[0].rx_cnt){
|
||||||
if(setup_packet.bRequest == SET_LINE_CODING){
|
if(setup_packet->bRequest == SET_LINE_CODING){
|
||||||
linecoding_handler((usb_LineCoding*)ep0databuf);
|
linecoding_handler((usb_LineCoding*)ep0databuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(TX_FLAG(epstatus)){ // package transmitted
|
} else if(TX_FLAG(epstatus)){ // package transmitted
|
||||||
// now we can change address after enumeration
|
// now we can change address after enumeration
|
||||||
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
|
if ((USB->DADDR & USB_DADDR_ADD) != USB_Addr){
|
||||||
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
|
USB->DADDR = USB_DADDR_EF | USB_Addr;
|
||||||
// change state to ADRESSED
|
usbON = 0;
|
||||||
USB_Dev.USB_Status = USB_STATE_ADDRESSED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
epstatus = KEEP_DTOG(USB->EPnR[0]);
|
epstatus = KEEP_DTOG(USB->EPnR[0]);
|
||||||
|
|||||||
@ -60,14 +60,21 @@
|
|||||||
#define CONTROL_DTR 0x01
|
#define CONTROL_DTR 0x01
|
||||||
#define CONTROL_RTS 0x02
|
#define CONTROL_RTS 0x02
|
||||||
|
|
||||||
// wValue
|
// string descriptors
|
||||||
#define DEVICE_DESCRIPTOR 0x100
|
enum{
|
||||||
#define CONFIGURATION_DESCRIPTOR 0x200
|
iLANGUAGE_DESCR,
|
||||||
#define STRING_LANG_DESCRIPTOR 0x300
|
iMANUFACTURER_DESCR,
|
||||||
#define STRING_MAN_DESCRIPTOR 0x301
|
iPRODUCT_DESCR,
|
||||||
#define STRING_PROD_DESCRIPTOR 0x302
|
iSERIAL_DESCR,
|
||||||
#define STRING_SN_DESCRIPTOR 0x303
|
iINTERFACE_DESCR,
|
||||||
#define DEVICE_QUALIFIER_DESCRIPTOR 0x600
|
iDESCR_AMOUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
// Types of descriptors
|
||||||
|
#define DEVICE_DESCRIPTOR 0x01
|
||||||
|
#define CONFIGURATION_DESCRIPTOR 0x02
|
||||||
|
#define STRING_DESCRIPTOR 0x03
|
||||||
|
#define DEVICE_QUALIFIER_DESCRIPTOR 0x06
|
||||||
|
|
||||||
#define RX_FLAG(epstat) (epstat & USB_EPnR_CTR_RX)
|
#define RX_FLAG(epstat) (epstat & USB_EPnR_CTR_RX)
|
||||||
#define TX_FLAG(epstat) (epstat & USB_EPnR_CTR_TX)
|
#define TX_FLAG(epstat) (epstat & USB_EPnR_CTR_TX)
|
||||||
@ -77,14 +84,6 @@
|
|||||||
#define KEEP_DTOG_STAT(EPnR) (EPnR & ~(USB_EPnR_STAT_RX|USB_EPnR_STAT_TX|USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
|
#define KEEP_DTOG_STAT(EPnR) (EPnR & ~(USB_EPnR_STAT_RX|USB_EPnR_STAT_TX|USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
|
||||||
#define KEEP_DTOG(EPnR) (EPnR & ~(USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
|
#define KEEP_DTOG(EPnR) (EPnR & ~(USB_EPnR_DTOG_RX|USB_EPnR_DTOG_TX))
|
||||||
|
|
||||||
// USB state: uninitialized, addressed, ready for use
|
|
||||||
typedef enum{
|
|
||||||
USB_STATE_DEFAULT,
|
|
||||||
USB_STATE_ADDRESSED,
|
|
||||||
USB_STATE_CONFIGURED,
|
|
||||||
USB_STATE_CONNECTED
|
|
||||||
} USB_state;
|
|
||||||
|
|
||||||
// EP types
|
// EP types
|
||||||
#define EP_TYPE_BULK 0x00
|
#define EP_TYPE_BULK 0x00
|
||||||
#define EP_TYPE_CONTROL 0x01
|
#define EP_TYPE_CONTROL 0x01
|
||||||
@ -93,6 +92,16 @@ typedef enum{
|
|||||||
|
|
||||||
#define LANG_US (uint16_t)0x0409
|
#define LANG_US (uint16_t)0x0409
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
typedef struct{
|
||||||
|
uint8_t bLength;
|
||||||
|
uint8_t bDescriptorType;
|
||||||
|
uint16_t *bString;
|
||||||
|
} string_descriptor_t;
|
||||||
|
|
||||||
|
#define _USB_STRING_(name, str) string_descriptor_t name = {(sizeof(str) + 2), STRING_DESCRIPTOR, str}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _USB_STRING_(name, str) \
|
#define _USB_STRING_(name, str) \
|
||||||
static const struct name \
|
static const struct name \
|
||||||
{ \
|
{ \
|
||||||
@ -113,7 +122,6 @@ static const struct name \
|
|||||||
\
|
\
|
||||||
} \
|
} \
|
||||||
name = {0x04, 0x03, lng_id}
|
name = {0x04, 0x03, lng_id}
|
||||||
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
|
|
||||||
|
|
||||||
// EP0 configuration packet
|
// EP0 configuration packet
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -133,12 +141,6 @@ typedef struct{
|
|||||||
unsigned rx_cnt : 10; // received data counter
|
unsigned rx_cnt : 10; // received data counter
|
||||||
} ep_t;
|
} ep_t;
|
||||||
|
|
||||||
// USB status & its address
|
|
||||||
typedef struct {
|
|
||||||
uint8_t USB_Status;
|
|
||||||
uint16_t USB_Addr;
|
|
||||||
}usb_dev_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t dwDTERate;
|
uint32_t dwDTERate;
|
||||||
uint8_t bCharFormat;
|
uint8_t bCharFormat;
|
||||||
@ -163,10 +165,9 @@ typedef struct {
|
|||||||
} __attribute__ ((packed)) usb_cdc_notification;
|
} __attribute__ ((packed)) usb_cdc_notification;
|
||||||
|
|
||||||
extern ep_t endpoints[];
|
extern ep_t endpoints[];
|
||||||
extern usb_dev_t USB_Dev;
|
|
||||||
extern volatile uint8_t usbON;
|
extern volatile uint8_t usbON;
|
||||||
extern config_pack_t setup_packet;
|
extern config_pack_t *setup_packet;
|
||||||
extern uint8_t ep0databuf[];
|
extern uint8_t ep0databuf[], setupdatabuf[];
|
||||||
|
|
||||||
void EP0_Handler();
|
void EP0_Handler();
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,6 @@ void usb_lp_isr(){
|
|||||||
lastaddr = LASTADDR_DEFAULT;
|
lastaddr = LASTADDR_DEFAULT;
|
||||||
// clear address, leave only enable bit
|
// clear address, leave only enable bit
|
||||||
USB->DADDR = USB_DADDR_EF;
|
USB->DADDR = USB_DADDR_EF;
|
||||||
USB_Dev.USB_Status = USB_STATE_DEFAULT;
|
|
||||||
if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){
|
if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -101,10 +100,10 @@ void usb_lp_isr(){
|
|||||||
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
|
||||||
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
|
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
|
||||||
EP_Read(0, (uint8_t*)&setup_packet);
|
EP_Read(0, setupdatabuf);
|
||||||
// interrupt handler will be called later
|
// interrupt handler will be called later
|
||||||
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
|
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
|
||||||
EP_Read(0, (uint8_t*)&ep0databuf);
|
EP_Read(0, ep0databuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "24"
|
#define BUILD_NUMBER "52"
|
||||||
#define BUILD_DATE "2023-03-22"
|
#define BUILD_DATE "2023-04-10"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user