📄 main.c
字号:
/* Name: main.c * Project: AVR USB driver for CDC interface on Low-Speed USB * Author: Osamu Tamura * Creation Date: 2006-05-12 * Tabsize: 4 * Copyright: (c) 2006 by Recursion Co., Ltd. * License: Proprietary, free under certain conditions. See Documentation. *
* 2006-07-08 removed zero-sized receive block
* 2006-07-08 adapted to higher baud rate by T.Kitazawa
*
*/#include <avr/io.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/wdt.h>#include "usbdrv.h"#include "oddebug.h"#include "uart.h"enum { SEND_ENCAPSULATED_COMMAND = 0, GET_ENCAPSULATED_RESPONSE, SET_COMM_FEATURE, GET_COMM_FEATURE, CLEAR_COMM_FEATURE, SET_LINE_CODING = 0x20, GET_LINE_CODING, SET_CONTROL_LINE_STATE, SEND_BREAK};char usbDescrConfig[] PROGMEM = { /* USB configuration descriptor */ 9, /* sizeof(usbDescrConfig): length of descriptor in bytes */ USBDESCR_CONFIG, /* descriptor type */ USB_CFG_EXTERNAL_CONFIG_DESCRIPTOR_LENGH, 0, /* total length of data returned (including inlined descriptors) */ 2, /* number of interfaces in this configuration */ 1, /* index of this configuration */ 0, /* configuration name string index */#if USB_CFG_IS_SELF_POWERED USBATTR_SELFPOWER, /* attributes */#else USBATTR_BUSPOWER, /* attributes */#endif USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */ /* interface descriptor follows inline: */ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ USBDESCR_INTERFACE, /* descriptor type */ 0, /* index of this interface */ 0, /* alternate setting for this interface */ USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */ USB_CFG_INTERFACE_CLASS, USB_CFG_INTERFACE_SUBCLASS, USB_CFG_INTERFACE_PROTOCOL, 0, /* string index for interface */ /* CDC Class-Specific descriptor */ 5, /* sizeof(usbDescrCDC_HeaderFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 0, /* header functional descriptor */ 0x10, 0x01, 4, /* sizeof(usbDescrCDC_AcmFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 2, /* abstract control management functional descriptor */ 0x02, /* SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE */ 5, /* sizeof(usbDescrCDC_UnionFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 6, /* union functional descriptor */ 0, /* CDC_COMM_INTF_ID */ 1, /* CDC_DATA_INTF_ID */ 5, /* sizeof(usbDescrCDC_CallMgtFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 1, /* call management functional descriptor */ 3, /* allow management on data interface, handles call management by itself */ 1, /* CDC_DATA_INTF_ID */ /* Endpoint Descriptor */ 7, /* sizeof(usbDescrEndpoint) */ USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 0x83, /* IN endpoint number 3 */ 0x03, /* attrib: Interrupt endpoint */ 8, 0, /* maximum packet size */ 100, /* in ms */ /* Interface Descriptor */ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ 4, /* descriptor type */ 1, /* index of this interface */ 0, /* alternate setting for this interface */ 2, /* endpoints excl 0: number of endpoint descriptors to follow */ 0x0A, /* Data Interface Class Codes */ 0, 0, /* Data Interface Class Protocol Codes */ 0, /* string index for interface */ /* Endpoint Descriptor */ 7, /* sizeof(usbDescrEndpoint) */ USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 0x01, /* OUT endpoint number 1 */ 0x02, /* attrib: Bulk endpoint */#if UART_CFG_HAVE_USART 6, 0, /* maximum packet size 8->6 */#else
1, 0, /* maximum packet size */#endif
0, /* in ms */ /* Endpoint Descriptor */ 7, /* sizeof(usbDescrEndpoint) */ USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 0x81, /* IN endpoint number 1 */ 0x02, /* attrib: Bulk endpoint */ 8, 0, /* maximum packet size */ 0, /* in ms */};static uchar intr3Status; /* used to control interrupt endpoint transmissions */static uchar stopbit, parity, databit;static usbDWord_t baud;static void resetUart(void){ uartInit(baud.dword, parity, stopbit, databit); irptr = 0; iwptr = 0; urptr = 0; uwptr = 0;}/* ------------------------------------------------------------------------- *//* ----------------------------- USB interface ----------------------------- *//* ------------------------------------------------------------------------- */uchar usbFunctionSetup(uchar data[8]){usbRequest_t *rq = (void *)data; if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ if( rq->bRequest==GET_LINE_CODING || rq->bRequest==SET_LINE_CODING ){ return 0xff; /* GET_LINE_CODING -> usbFunctionRead() */ /* SET_LINE_CODING -> usbFunctionWrite() */ } if(rq->bRequest == SET_CONTROL_LINE_STATE){ /* Report serial state (carrier detect). On several Unix platforms, * tty devices can only be opened when carrier detect is set. */ intr3Status = 2; } } return 0;}/*---------------------------------------------------------------------------*//* usbFunctionRead *//*---------------------------------------------------------------------------*/uchar usbFunctionRead( uchar *data, uchar len ){ data[0] = baud.bytes[0]; data[1] = baud.bytes[1]; data[2] = baud.bytes[2];
data[3] = baud.bytes[3];
data[4] = stopbit; data[5] = parity; data[6] = databit; return 7;}/*---------------------------------------------------------------------------*//* usbFunctionWrite *//*---------------------------------------------------------------------------*/uchar usbFunctionWrite( uchar *data, uchar len ){ /* SET_LINE_CODING */ baud.bytes[0] = data[0]; baud.bytes[1] = data[1]; baud.bytes[2] = data[2];
baud.bytes[3] = data[3];
#if USB_CFG_HAVE_USART stopbit = data[4]; parity = data[5]; databit = data[6]; if( parity>2 ) parity = 0; if( stopbit==1 ) stopbit = 0;#endif resetUart(); return 1;}void usbFunctionWriteOut( uchar *data, uchar len ){ /* usb -> rs232c: transmit char */ usbDisableAllRequests(); for( ; len; len-- ) { uartTxBufAppend(*data++); }}static void hardwareInit(void){uchar i, j; /* activate pull-ups except on USB lines */ USB_CFG_IOPORT = (uchar)~((1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT)); /* all pins input except USB (-> USB reset) */#ifdef USB_CFG_PULLUP_IOPORT /* use usbDeviceConnect()/usbDeviceDisconnect() if available */ USBDDR = 0; /* we do RESET by deactivating pullup */ usbDeviceDisconnect();#else USBDDR = (1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT);#endif j = 0; while(--j){ /* USB Reset by device only required on Watchdog Reset */ i = 0; while(--i); /* delay >10ms for USB reset */ }#ifdef USB_CFG_PULLUP_IOPORT usbDeviceConnect();#else USBDDR = 0; /* remove USB reset condition */#endif
/* USART configuration */ baud.dword = UART_DEFAULT_BPS; stopbit = 0; parity = 0; databit = 8; resetUart();}int main(void){// uchar n = 0;
wdt_enable(WDTO_1S); odDebugInit(); hardwareInit();
usbInit();
sei(); usbSetInterrupt(0, 0); /* the host eats the first packet -- don't know why... */ for(;;){ /* main event loop */ uchar bytesRead, *data; wdt_reset(); usbPoll(); uartPoll();
/* usb -> rs232c: ready to receive? */ if( usbAllRequestsAreDisabled() && uartTxBytesFree()>=8 ){ usbEnableAllRequests(); } /* rs232c -> usb: transmit char */ if( usbInterruptIsReady() && (bytesRead = uartRxBytesAvailable(&data)) > 0) {// if( ++n==0 ) {
/* We limit the transaction size to 7 instead of 8 to indicate that * this is the last transaction in the transfer. Otherwise the host * would try to read more transactions which we would answer with NAK * instead of a terminating zero sized block. */ if(bytesRead > 7) {
if(bytesRead == 8)
bytesRead = 7;
else
bytesRead = 8;
}
usbSetInterrupt(data, bytesRead); uartRxDidReadBytes(bytesRead); }
// }
/* We need to report rx and tx carrier after open attempt */ if(intr3Status != 0 && usbInterruptIsReady3()){ static uchar serialStateNotification[10] = {0xa1, 0x20, 0, 0, 0, 0, 2, 0, 3, 0}; if(intr3Status == 2){ usbSetInterrupt3(serialStateNotification, 8); }else{ usbSetInterrupt3(serialStateNotification+8, 2); } intr3Status--; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -