mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
semi-working CDC
This commit is contained in:
parent
6df3b9f5c2
commit
8da9cdf51b
@ -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){
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -114,6 +126,29 @@ typedef struct {
|
||||
uint16_t USB_Addr;
|
||||
}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();
|
||||
//ðÏÌÕÞÉÔØ ÓÔÁÔÕÓ ÓÏÅÄÉÎÅÎÉÑ USB
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user