semi-working CDC

This commit is contained in:
eddyem 2018-10-17 18:26:13 +03:00
parent 6df3b9f5c2
commit 8da9cdf51b
7 changed files with 286 additions and 235 deletions

View File

@ -185,7 +185,7 @@ void can_proc(){
CAN_setup();
}
LED_off(LED1);
#ifdef EBUG
#if 0
static uint32_t esr, msr, tsr;
uint32_t msr_now = CAN->MSR & 0xf;
if(esr != CAN->ESR || msr != msr_now || tsr != CAN->TSR){

View File

@ -86,6 +86,7 @@ int main(void){
if(lastT > Tms || Tms - lastT > 499){
LED_blink(LED0);
lastT = Tms;
transmit_tbuf(); // non-blocking transmission of data from UART buffer every 0.5s
}
can_proc();
usb_proc();
@ -109,6 +110,9 @@ int main(void){
if(L == 2 && txt[1] == '\n'){
L = 0;
switch(_1st){
case 'f':
transmit_tbuf();
break;
case 'B':
can_send_broadcast();
break;
@ -136,6 +140,7 @@ int main(void){
break;
default: // help
SEND(
"'f' - flush UART buffer\n"
"'B' - send broadcast dummy byte\n"
"'C' - send dummy byte over CAN\n"
"'G' - get CAN address\n"
@ -148,7 +153,8 @@ int main(void){
}
}
if(L){ // text waits for sending
while(LINE_BUSY == usart_send(txt, L));
txt[L] = 0;
usart_send(txt);
L = 0;
}
}

View File

@ -24,7 +24,8 @@
#include <string.h>
extern volatile uint32_t Tms;
static int datalen[2] = {0,0}; // received data line length (including '\n')
static volatile int idatalen[2] = {0,0}; // received data line length (including '\n')
static volatile int odatalen[2] = {0,0};
volatile int linerdy = 0, // received data ready
dlen = 0, // length of data (including '\n') in current buffer
@ -33,8 +34,8 @@ volatile int linerdy = 0, // received data ready
;
int rbufno = 0; // current rbuf number
static char rbuf[UARTBUFSZ][2], tbuf[UARTBUFSZ]; // receive & transmit buffers
int rbufno = 0, tbufno = 0; // current rbuf/tbuf numbers
static char rbuf[2][UARTBUFSZI], tbuf[2][UARTBUFSZO]; // receive & transmit buffers
static char *recvdata = NULL;
/**
@ -51,46 +52,44 @@ int usart_getline(char **line){
return dlen;
}
TXstatus usart_send(const char *str, int len){
if(!txrdy) return LINE_BUSY;
if(len > UARTBUFSZ) return STR_TOO_LONG;
// transmit current tbuf and swap buffers
void transmit_tbuf(){
while(!txrdy); // wait for previos buffer transmission
register int l = odatalen[tbufno];
if(!l) return;
txrdy = 0;
memcpy(tbuf, str, len);
odatalen[tbufno] = 0;
#if USARTNUM == 2
DMA1_Channel4->CCR &= ~DMA_CCR_EN;
DMA1_Channel4->CNDTR = len;
DMA1_Channel4->CMAR = (uint32_t) tbuf[tbufno]; // mem
DMA1_Channel4->CNDTR = l;
DMA1_Channel4->CCR |= DMA_CCR_EN; // start transmission
#elif USARTNUM == 1
DMA1_Channel2->CCR &= ~DMA_CCR_EN;
DMA1_Channel2->CNDTR = len;
DMA1_Channel2->CMAR = (uint32_t) tbuf[tbufno]; // mem
DMA1_Channel2->CNDTR = l;
DMA1_Channel2->CCR |= DMA_CCR_EN;
#else
#error "Not implemented"
#endif
return ALL_OK;
}
TXstatus usart_send_blocking(const char *str, int len){
while(!txrdy);
int i;
bufovr = 0;
for(i = 0; i < len; ++i){
USARTX->TDR = *str++;
while(!(USARTX->ISR & USART_ISR_TXE));
}
return ALL_OK;
tbufno = !tbufno;
}
void usart_putchar(const char ch){
while(!txrdy);
USARTX->TDR = ch;
while(!(USARTX->ISR & USART_ISR_TXE));
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
tbuf[tbufno][odatalen[tbufno]++] = ch;
}
void usart_send(const char *str){
while(*str){
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
tbuf[tbufno][odatalen[tbufno]++] = *str++;
}
}
void newline(){
while(!txrdy);
USARTX->TDR = '\n';
while(!(USARTX->ISR & USART_ISR_TXE));
usart_putchar('\n');
transmit_tbuf();
}
@ -105,7 +104,6 @@ void usart_setup(){
GPIOA->AFR[1] = (GPIOA->AFR[1] &~GPIO_AFRH_AFRH7) | 1 << (7 * 4); // PA15
// DMA: Tx - Ch4
DMA1_Channel4->CPAR = (uint32_t) &USART2->TDR; // periph
DMA1_Channel4->CMAR = (uint32_t) tbuf; // mem
DMA1_Channel4->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq
// Tx CNDTR set @ each transmission due to data size
NVIC_SetPriority(DMA1_Channel4_5_IRQn, 3);
@ -166,22 +164,22 @@ void usart1_isr(){
#ifdef CHECK_TMOUT
if(tmout && Tms >= tmout){ // set overflow flag
bufovr = 1;
datalen[rbufno] = 0;
idatalen[rbufno] = 0;
}
tmout = Tms + TIMEOUT_MS;
if(!tmout) tmout = 1; // prevent 0
#endif
// read RDR clears flag
uint8_t rb = USARTX->RDR;
if(datalen[rbufno] < UARTBUFSZ){ // put next char into buf
rbuf[rbufno][datalen[rbufno]++] = rb;
if(idatalen[rbufno] < UARTBUFSZI){ // put next char into buf
rbuf[rbufno][idatalen[rbufno]++] = rb;
if(rb == '\n'){ // got newline - line ready
linerdy = 1;
dlen = datalen[rbufno];
dlen = idatalen[rbufno];
recvdata = rbuf[rbufno];
// prepare other buffer
rbufno = !rbufno;
datalen[rbufno] = 0;
idatalen[rbufno] = 0;
#ifdef CHECK_TMOUT
// clear timeout at line end
tmout = 0;
@ -189,7 +187,7 @@ void usart1_isr(){
}
}else{ // buffer overrun
bufovr = 1;
datalen[rbufno] = 0;
idatalen[rbufno] = 0;
#ifdef CHECK_TMOUT
tmout = 0;
#endif
@ -215,12 +213,13 @@ void printu(uint32_t val){
bufa[--bpos] = bufb[i];
}
}
while(LINE_BUSY == usart_send_blocking(bufa, l+bpos));
bufa[l + bpos] = 0;
usart_send(bufa);
}
// print 32bit unsigned int as hex
void printuhex(uint32_t val){
SEND("0x");
usart_send("0x");
uint8_t *ptr = (uint8_t*)&val + 3;
int i, j;
for(i = 0; i < 4; ++i, --ptr){

View File

@ -25,36 +25,36 @@
#include "hardware.h"
// input and output buffers size
#define UARTBUFSZ (64)
#define UARTBUFSZI (32)
#define UARTBUFSZO (512)
// timeout between data bytes
#ifndef TIMEOUT_MS
#define TIMEOUT_MS (1500)
#endif
// macro for static strings
#define SEND(str) do{}while(LINE_BUSY == usart_send_blocking(str, sizeof(str)-1))
#define SEND(str) usart_send(str)
#ifdef EBUG
#define MSG(str) do{SEND(__FILE__ " (L" STR(__LINE__) "): " str);}while(0)
#else
#define MSG(str)
#endif
/*
typedef enum{
ALL_OK,
LINE_BUSY,
STR_TOO_LONG
} TXstatus;
LINE_BUSY
} TXstatus;*/
#define usartrx() (linerdy)
#define usartovr() (bufovr)
extern volatile int linerdy, bufovr, txrdy;
void transmit_tbuf();
void usart_setup();
int usart_getline(char **line);
TXstatus usart_send(const char *str, int len);
TXstatus usart_send_blocking(const char *str, int len);
void usart_send(const char *str);
void newline();
void usart_putchar(const char ch);
void printu(uint32_t val);

View File

@ -32,69 +32,69 @@ static uint8_t buffer[64];
static uint8_t len, rcvflag = 0;
static uint16_t EP1_Handler(ep_t ep){
MSG("EP1 ");
if (ep.rx_flag){ //Пришли новые данные
MSG("read");
MSG("read\n");
EP_Read(1, buffer);
EP_WriteIRQ(1, buffer, ep.rx_cnt);
//EP_WriteIRQ(1, buffer, ep.rx_cnt);
ep.status = SET_VALID_TX(ep.status); //TX
ep.status = KEEP_STAT_RX(ep.status); //RX оставляем в NAK
} else
if (ep.tx_flag){ //Данные успешно переданы
MSG("write");
MSG("write\n");
ep.status = SET_VALID_RX(ep.status); //RX в VALID
ep.status = SET_STALL_TX(ep.status); //TX в STALL
}
MSG("; end\n");
return ep.status;
}
// write handler
static uint16_t EP2_Handler(ep_t ep){
MSG("EP2 ");
if (ep.rx_flag){ //Пришли новые данные
MSG("read");
#ifdef EBUG
printu(ep.rx_cnt);
#endif
if(ep.rx_cnt > 2){
if(ep.rx_flag){
MSG("RX\n");
if(ep.rx_cnt > 0){
len = ep.rx_cnt;
rcvflag = 1;
EP_Read(2, buffer);
buffer[len] = 0;
}
//EP_WriteIRQ(3, buffer, ep.rx_cnt);
//Так как потверждение от хоста завершает транзакцию
//то сбрасываем DTOGи
ep.status = CLEAR_DTOG_RX(ep.status);
ep.status = CLEAR_DTOG_TX(ep.status);
//Так как мы ожидаем новый запрос от хоста, устанавливаем
//ep.status = SET_VALID_RX(ep.status);
ep.status = SET_STALL_TX(ep.status);
}else if (ep.tx_flag){
MSG("TX\n");
ep.status = KEEP_STAT_TX(ep.status);
/* //Ожидаем новый запрос, или повторное чтение данных (ошибка при передаче)
//поэтому Rx и Tx в VALID
ep.status = SET_VALID_RX(ep.status);
//ep.status = SET_STALL_TX(ep.status);
//ep.status = SET_VALID_TX(ep.status); //TX
//ep.status = KEEP_STAT_RX(ep.status); //RX оставляем в NAK
} else
if (ep.tx_flag){ //Данные успешно переданы
MSG("write");
ep.status = SET_VALID_RX(ep.status); //RX в VALID
ep.status = SET_STALL_TX(ep.status); //TX в STALL
ep.status = SET_STALL_TX(ep.status);*/
}
MSG("; end\n");
ep.status = SET_VALID_RX(ep.status);
return ep.status;
}
/*
// read handler
static uint16_t EP3_Handler(ep_t ep){
MSG("EP3 ");
if (ep.rx_flag){ //Пришли новые данные
MSG("read");
EP_Read(3, buffer);
//EP_Read(3, buffer);
ep.status = SET_VALID_TX(ep.status); //TX
ep.status = KEEP_STAT_RX(ep.status); //RX оставляем в NAK
} else
if (ep.tx_flag){ //Данные успешно переданы
MSG("write");
ep.status = SET_VALID_RX(ep.status); //RX в VALID
ep.status = SET_STALL_TX(ep.status); //TX в STALL
ep.status = SET_STALL_TX(ep.status);
//ep.status = SET_VALID_RX(ep.status); //RX в VALID
//ep.status = SET_STALL_TX(ep.status); //TX в STALL
}
MSG("; end\n");
return ep.status;
}
}*/
void USB_setup(){
RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB
@ -127,14 +127,15 @@ void usb_proc(){
// free: 64 128 192 256 320 384 448 512 576 640 704
// (first 192 free bytes are for EP0)
EP_Init(1, EP_TYPE_INTERRUPT, 256, 320, EP1_Handler);
EP_Init(2, EP_TYPE_BULK, 384, 448, EP2_Handler);
EP_Init(3, EP_TYPE_BULK, 512, 576, EP3_Handler);
EP_Init(2, EP_TYPE_BULK, 384, 448, EP2_Handler); // out
EP_Init(3, EP_TYPE_BULK, 512, 576, EP2_Handler); // in
usbON = 1;
}else{
if(rcvflag){
EP_Write(3, buffer, len);
MSG("read: ");
if(len > 2) while(LINE_BUSY == usart_send((char*)&buffer[2], len-2));
if(len) SEND((char*)buffer);
SEND("\nNow write the data back\n");
EP_Write(3, buffer, len);
rcvflag = 0;
}
}

View File

@ -10,11 +10,13 @@
#define DEVICE_QALIFIER_SIZE_BYTE (10)
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
const uint8_t USB_DeviceDescriptor[] = {
DEVICE_DESCRIPTOR_SIZE_BYTE, // bLength
0x01, // bDescriptorType - USB_DEVICE_DESC_TYPE
0x00, // bcdUSB_L
0x02, // bcdUSB_H
0x10, // bcdUSB_L - 1.10
0x01, // bcdUSB_H
0x00, // bDeviceClass - USB_COMM
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
@ -24,7 +26,7 @@ const uint8_t USB_DeviceDescriptor[] = {
0x03, // idProduct_L
0x23, // idProduct_H
0x00, // bcdDevice_Ver_L
0x01, // bcdDevice_Ver_H
0x03, // bcdDevice_Ver_H
0x01, // iManufacturer
0x02, // iProduct
0x00, // iSerialNumber
@ -34,8 +36,8 @@ const uint8_t USB_DeviceDescriptor[] = {
const uint8_t USB_DeviceQualifierDescriptor[] = {
DEVICE_QALIFIER_SIZE_BYTE, //bLength
0x06, // bDescriptorType
0x00, // bcdUSB_L
0x02, // bcdUSB_H
0x10, // bcdUSB_L
0x01, // bcdUSB_H
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
@ -44,106 +46,12 @@ const uint8_t USB_DeviceQualifierDescriptor[] = {
0x00 // Reserved
};
#if 0
const uint8_t USB_ConfigDescriptor[] = {
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
0x02, /* bDescriptorType: Configuration */
39, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x80, /* bmAttributes - Bus powered */
0x32, /* MaxPower 100 mA */
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress IN1 */
0x03, /* bmAttributes: Interrupt */
0x08, /* wMaxPacketSize LO: */
0x00, /* wMaxPacketSize HI: */
0x10, /* bInterval: */
/*---------------------------------------------------------------------------*/
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
0x04, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x02, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/*Endpoint IN2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x82, /* bEndpointAddress IN2 */
0x02, /* bmAttributes: Bulk */
64, /* wMaxPacketSize: */
0x00,
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint OUT3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x03, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
64, /* wMaxPacketSize: */
0,
0x00 /* bInterval: ignore for Bulk transfer */
};
#endif
const uint8_t USB_ConfigDescriptor[] = {
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
0x02, /* bDescriptorType: Configuration */
53, /* wTotalLength:no of returned bytes */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
@ -158,11 +66,48 @@ const uint8_t USB_ConfigDescriptor[] = {
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: 3 endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
//0x02, /* bInterfaceClass: Communication Interface Class */
//0x02, /* bInterfaceSubClass: Abstract Control Model */
//0x01, /* bInterfaceProtocol: Common AT commands */
0xff,
0x00,
0x00,
0x00, /* iInterface: */
///////////////////////////////////////////////////
/*Endpoint 1 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress IN1 */
0x03, /* bmAttributes: Interrupt */
//0x40, /* wMaxPacketSize LO: */
//0x00, /* wMaxPacketSize HI: */
0x0a,
0x00,
//0x10, /* bInterval: */
0x01,
/*---------------------------------------------------------------------------*/
/*Endpoint OUT2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x02, /* bEndpointAddress: OUT2 */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize: */
0x00,
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
//0x82, /* bEndpointAddress IN2 */
0x83, // IN3
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize: 64 */
0x00,
0x00, /* bInterval: ignore for Bulk transfer */
};
#if 0
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
@ -182,35 +127,7 @@ const uint8_t USB_ConfigDescriptor[] = {
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Endpoint 1 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress IN1 */
0x03, /* bmAttributes: Interrupt */
64, /* wMaxPacketSize LO: */
0x00, /* wMaxPacketSize HI: */
0x10, /* bInterval: */
/*---------------------------------------------------------------------------*/
/*Endpoint IN3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x83, /* bEndpointAddress IN3 */
0x02, /* bmAttributes: Bulk */
64, /* wMaxPacketSize: */
0x00,
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint OUT2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x02, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
64, /* wMaxPacketSize: */
0x00,
0x00 /* bInterval: ignore for Bulk transfer */
};
#endif
const uint8_t USB_StringLangDescriptor[] = {
STRING_LANG_DESCRIPTOR_SIZE_BYTE, //bLength
@ -219,12 +136,6 @@ const uint8_t USB_StringLangDescriptor[] = {
0x04 //wLANGID_H
};
//~ typedef struct{
//~ uint8_t bLength;
//~ uint8_t bDescriptorType;
//~ uint16_t bString[];
//~ } StringDescriptor;
#define _USB_STRING_(name, str) \
const struct name \
{ \
@ -242,6 +153,25 @@ _USB_STRING_(USB_StringProdDescriptor, L"TSYS01 sensors controller")
usb_dev_t USB_Dev;
ep_t endpoints[MAX_ENDPOINTS];
static void EP_Readx(uint8_t number, uint8_t *buf){
uint32_t timeout = 100000;
uint16_t status, i;
status = USB -> EPnR[number];
status = SET_VALID_RX(status);
status = SET_NAK_TX(status);
status = KEEP_DTOG_TX(status);
status = KEEP_DTOG_RX(status);
USB -> EPnR[number] = status;
endpoints[number].rx_flag = 0;
while (!endpoints[number].rx_flag){
if (timeout) timeout--;
else break;
}
for (i = 0; i < endpoints[number].rx_cnt; i++){
buf[i] = endpoints[number].rx_buf[i];
}
}
/*
bmRequestType: 76543210
7 direction: 0 - host->device, 1 - device->host
@ -260,8 +190,11 @@ uint16_t Enumerate_Handler(ep_t ep){
if(packet->wLength < size) size = packet->wLength;
EP_WriteIRQ(0, buf, size);
}
uint8_t _2wr = 0;
if ((ep.rx_flag) && (ep.setup_flag)){
if (packet -> bmRequestType == 0x80){ // get device properties
if (packet -> bmRequestType == 0x80){ // standard device request (device to host)
switch(packet->bRequest){
case GET_DESCRIPTOR:
switch(packet->wValue){
@ -287,23 +220,23 @@ uint16_t Enumerate_Handler(ep_t ep){
wr0(USB_DeviceQualifierDescriptor, DEVICE_QALIFIER_SIZE_BYTE);
break;
default:
MSG("val");
printuhex(packet->wValue);
newline();
SEND("UNK_DES");
_2wr = 1;
break;
}
break;
case GET_STATUS:
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
break;
default:
MSG("req");
printuhex(packet->bRequest);
newline();
SEND("80:WR_REQ");
_2wr = 1;
break;
}
//ôÁË ËÁË ÍÙ ÎÅ ÏÖÉÄÁÅÍ ÐÒÉÅÍÁ É ÚÁÎÉÍÁÅÍÓÑ ÔÏÌØËÏ ÐÅÒÅÄÁÞÅÊ, ÔÏ ÕÓÔÁÎÁ×ÌÉ×ÁÅÍ
ep.status = SET_NAK_RX(ep.status);
ep.status = SET_VALID_TX(ep.status);
}else if(packet->bmRequestType == 0x00){ // set device properties
}else if(packet->bmRequestType == 0x00){ // standard device request (host to device)
switch(packet->bRequest){
case SET_ADDRESS:
//óÒÁÚÕ ÐÒÉÓ×ÏÉÔØ ÁÄÒÅÓ × DADDR ÎÅÌØÚÑ, ÔÁË ËÁË ÈÏÓÔ ÏÖÉÄÁÅÔ ÐÏÄÔ×ÅÒÖÄÅÎÉÑ
@ -315,16 +248,16 @@ uint16_t Enumerate_Handler(ep_t ep){
USB_Dev.USB_Status = USB_CONFIGURE_STATE;
break;
default:
MSG("req");
printuhex(packet->bRequest);
newline();
SEND("0:WR_REQ");
_2wr = 1;
break;
}
//ÏÔÐÒÁ×ÌÑÅÍ ÐÏÄÔ×ÅÒÖÄÅÎÉÅ ÐÒÉÅÍÁ
EP_WriteIRQ(0, (uint8_t *)0, 0);
//ôÁË ËÁË ÍÙ ÎÅ ÏÖÉÄÁÅÍ ÐÒÉÅÍÁ É ÚÁÎÉÍÁÅÍÓÑ ÔÏÌØËÏ ÐÅÒÅÄÁÞÅÊ, ÔÏ ÕÓÔÁÎÁ×ÌÉ×ÁÅÍ
ep.status = SET_NAK_RX(ep.status);
ep.status = SET_VALID_TX(ep.status);
}else if(packet -> bmRequestType == 0x02){
}else if(packet -> bmRequestType == 0x02){ // standard endpoint request (host to device)
if (packet->bRequest == CLEAR_FEATURE){
//ÏÔÐÒÁ×ÌÑÅÍ ÐÏÄÔ×ÅÒÖÄÅÎÉÅ ÐÒÉÅÍÁ
EP_WriteIRQ(0, (uint8_t *)0, 0);
@ -332,13 +265,76 @@ uint16_t Enumerate_Handler(ep_t ep){
ep.status = SET_NAK_RX(ep.status);
ep.status = SET_VALID_TX(ep.status);
}else{
MSG("req");
printuhex(packet->bRequest);
newline();
SEND("02:WR_REQ");
_2wr = 1;
}
}else if((packet->bmRequestType & VENDOR_MASK_REQUEST) == VENDOR_MASK_REQUEST){ // vendor request
SEND("vendor ");
if(packet->bmRequestType & 0x80){ // read
SEND("read: ");
uint8_t c = '?';
EP_WriteIRQ(0, &c, 1);
}else{ // write
SEND("write: ");
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
} else
if (ep.rx_flag){ //鹣脑着抑盼膳 幸膳土 认釉贤
printuhex(packet->wValue);
_2wr = 1;
ep.status = SET_NAK_RX(ep.status);
ep.status = SET_VALID_TX(ep.status);
}else if((packet->bmRequestType & 0x7f) == CONTROL_REQUEST_TYPE){ // control request
_2wr = 1;
//usb_LineCoding c;
//uint8_t lbuf[10];
//usb_cdc_notification *notif = (usb_cdc_notification*) lbuf;
switch(packet->bRequest){
case GET_LINE_CODING:
SEND("GET_LINE_CODING");
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
break;
case SET_LINE_CODING:
SEND("SET_LINE_CODING");
EP_Readx(0, (uint8_t*)&lineCoding);
printuhex(lineCoding.dwDTERate);
//EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
//memcpy(&c, endpoints[0].rx_buf, sizeof(usb_LineCoding));
/*SEND("len: ");
printu(endpoints[0].rx_cnt);
printu(endpoints[0].rx_buf[6]);
SEND(", want baudrate: "); printuhex(c.dwDTERate);
SEND(", charFormat: "); printu(c.bCharFormat);
SEND(", parityType: "); printu(c.bParityType);
SEND(", dataBits: "); printu(c.bDataBits);*/
break;
case SET_CONTROL_LINE_STATE:
SEND("SET_CONTROL_LINE_STATE");
/*
* This Linux cdc_acm driver requires this to be implemented
* even though it's optional in the CDC spec, and we don't
* advertise it in the ACM functional descriptor.
*/
/* We echo signals back to host as notification. *
notif->bmRequestType = CONTROL_REQUEST_TYPE | 0x80;
notif->bNotificationType = SET_LINE_CODING;
notif->wValue = 0;
notif->wIndex = 0;
notif->wLength = 2;
lbuf[8] = packet->wValue & 3;
lbuf[9] = 0;
EP_WriteIRQ(3, lbuf, 10);*/
//EP_WriteIRQ(0, (uint8_t *)0, 0);
break;
case SEND_BREAK:
SEND("SEND_BREAK");
break;
default:
SEND("undef control req");
}
if((packet->bmRequestType & 0x80) == 0) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
ep.status = SET_NAK_RX(ep.status);
ep.status = SET_VALID_TX(ep.status);
}
} else if (ep.rx_flag){ //鹣脑着抑盼膳 幸膳土 认釉贤
//ôÁË ËÁË ÐÏÔ×ÅÒÖÄÅÎÉÅ ÏÔ ÈÏÓÔÁ ÚÁ×ÅÒÛÁÅÔ ÔÒÁÎÚÁËÃÉÀ
//ÔÏ ÓÂÒÁÓÙ×ÁÅÍ DTOGÉ
ep.status = CLEAR_DTOG_RX(ep.status);
@ -346,8 +342,7 @@ uint16_t Enumerate_Handler(ep_t ep){
//ôÁË ËÁË ÍÙ ÏÖÉÄÁÅÍ ÎÏ×ÙÊ ÚÁÐÒÏÓ ÏÔ ÈÏÓÔÁ, ÕÓÔÁÎÁ×ÌÉ×ÁÅÍ
ep.status = SET_VALID_RX(ep.status);
ep.status = SET_STALL_TX(ep.status);
} else
if (ep.tx_flag){ //跤信畚裂 信遗牧蘖 辛伺粤
} else if (ep.tx_flag){ //跤信畚裂 信遗牧蘖 辛伺粤
//åÓÌÉ ÐÏÌÕÞÅÎÎÙÊ ÏÔ ÈÏÓÔÁ ÁÄÒÅÓ ÎÅ ÓÏ×ÐÁÄÁÅÔ Ó ÁÄÒÅÓÏÍ ÕÓÔÒÏÊÓÔ×Á
if ((USB -> DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
//ðÒÉÓ×ÁÉ×ÁÅÍ ÎÏ×ÙÊ ÁÄÒÅÓ ÕÓÔÒÏÊÓÔ×Õ
@ -363,6 +358,21 @@ uint16_t Enumerate_Handler(ep_t ep){
ep.status = SET_VALID_RX(ep.status);
ep.status = SET_VALID_TX(ep.status);
}
if(_2wr){
usart_putchar(' ');
if (ep.rx_flag) usart_putchar('r');
else usart_putchar('t');
printu(packet->wLength);
if(ep.setup_flag) usart_putchar('s');
usart_putchar(' ');
usart_putchar('R');
printu(packet->bRequest);
usart_putchar('V');
printu(packet->wValue);
usart_putchar('T');
printu(packet->bmRequestType);
usart_putchar('\n');
}
//ÚÎÁÞÅÎÉÅ ep.status ÂÕÄÅÔ ÚÁÐÉÓÁÎÏ × EPnR É ÓÏÏÔ×ÅÔ×Ó×ÅÎÎÏ ÓÂÒÏÛÅÎÙ ÉÌÉ ÕÓÔÁÎÏ×ÌÅÎÙ
//ÓÏÏÔ×ÅÔÓ×ÕÀÝÉÅ ÂÉÔÙ
return ep.status;

View File

@ -5,7 +5,7 @@
#include "usb_defs.h"
//íÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓ×Ï ËÏÎÅÞÎÙÈ ÔÏÞÅË
#define MAX_ENDPOINTS 2
#define MAX_ENDPOINTS 4
// bRequest, standard; for bmRequestType == 0x80
#define GET_STATUS 0x00
#define GET_DESCRIPTOR 0x06
@ -21,6 +21,14 @@
#define SET_INTERFACE 0x0B //ÎÅ ÒÅÁÌÉÚÏ×ÁÎ
#define SYNC_FRAME 0x0C //ÎÅ ÒÅÁÌÉÚÏ×ÁÎ
// vendor
#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
#define SEND_ENCAPSULATED_COMMAND 0x00
#define GET_ENCAPSULATED_RESPONSE 0x01
@ -32,6 +40,10 @@
#define SET_CONTROL_LINE_STATE 0x22
#define SEND_BREAK 0x23
// control line states
#define CONTROL_DTR 0x01
#define CONTROL_RTS 0x02
/* Line Coding Structure from CDC spec 6.2.13
struct usb_cdc_line_coding {
__le32 dwDTERate;
@ -112,7 +124,30 @@ typedef struct __ep_t{
typedef struct {
uint8_t USB_Status;
uint16_t USB_Addr;
} usb_dev_t;
}usb_dev_t;
typedef struct {
uint32_t dwDTERate;
uint8_t bCharFormat;
#define USB_CDC_1_STOP_BITS 0
#define USB_CDC_1_5_STOP_BITS 1
#define USB_CDC_2_STOP_BITS 2
uint8_t bParityType;
#define USB_CDC_NO_PARITY 0
#define USB_CDC_ODD_PARITY 1
#define USB_CDC_EVEN_PARITY 2
#define USB_CDC_MARK_PARITY 3
#define USB_CDC_SPACE_PARITY 4
uint8_t bDataBits;
} __attribute__ ((packed)) usb_LineCoding;
typedef struct {
uint8_t bmRequestType;
uint8_t bNotificationType;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} __attribute__ ((packed)) usb_cdc_notification;
//éÎÉÃÉÁÌÉÚÁÃÉÑ USB
void USB_Init();