⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_uart.c

📁 可用来自做的AVR-USB-ISP的源码,内符电路图,用AVR M8来模拟USB接口
💻 C
字号:
/************************************************************************************************ * Project: generic * Author: Christian Ulrich
 * Contact: christian at ullihome dot de
 * * Creation Date: 2007-03-22 * Copyright: (c) 2007 by Christian Ulrich * License: GPLv2 ***********************************************************************************************/#include <avr/io.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/wdt.h>
#include <string.h>#include "oddebug.h"#include "usb_uart.h"
#include "usbconfig.h"#include "usbdrv.h"
#include "buffer.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};


/* Size of bulk transfer packets. The standard demands 8 bytes, but we may
 * be better off with less. Try smaller values if the communication hangs.
 */

#define HW_CDC_PACKET_SIZE      8

/* UART buffer */
//uint8_t rxinptr,rxoutptr;
//uint8_t rx_buf[RX_BUFSIZE];
//uint8_t tx_buf[HW_CDC_PACKET_SIZE2];
//uint8_t txptr = 0;
uint8_t rxbuf_bd[RX_BUFSIZE];
uint8_t txbuf_bd[HW_CDC_PACKET_SIZE];
BUF_t rxbuffer;
BUF_t txbuffer;

uint8_t CDC_mode[7] = {0x80, 0x25, 0, 0, 0, 0, 8};  /* default: 9600 bps, 8n1 */ 
static PROGMEM char deviceDescrCDC[] = {    /* USB device descriptor */
    18,         /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
    USBDESCR_DEVICE,        /* descriptor type */
    0x01, 0x01,             /* USB version supported */
    0x02,                   /* device class: CDC */
    0,                      /* subclass */
    0,                      /* protocol */
    8,                      /* max packet size */
    USB_CFG_VENDOR_ID,      /* 2 bytes */
    USB_CFG_DEVICE_ID,      /* 2 bytes: shared PID for CDC-ACM devices */
    USB_CFG_DEVICE_VERSION, /* 2 bytes */
    1,                      /* manufacturer string index */
    2,                      /* product string index */
    0,                      /* serial number string index */
    1,                      /* number of configurations */
};
static PROGMEM char configDescrCDC[] = {   /* USB configuration descriptor */
    9,          /* sizeof(usbDescrConfig): length of descriptor in bytes */
    USBDESCR_CONFIG,    /* descriptor type */
    67,
    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 */
    HW_CDC_BULK_OUT_SIZE, 0,        /* maximum packet size */




    0,           /* in ms */

    /* Endpoint Descriptor */
    7,           /* sizeof(usbDescrEndpoint) */
    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
    0x81,        /* IN endpoint number 1 */
    0x02,        /* attrib: Bulk endpoint */
    HW_CDC_BULK_IN_SIZE, 0,        /* maximum packet size */
    0,           /* in ms */
};

static uint8_t        intr3Status;    /* used to control interrupt endpoint transmissions *//* ------------------------------------------------------------------------- *//* ----------------------------- USB interface ----------------------------- *//* ------------------------------------------------------------------------- */
uint8_t CDC_usbFunctionDescriptor(usbRequest_t *rq)
{
uint8_t *p = NULL, len = 0;

    if(rq->wValue.bytes[1] == USBDESCR_DEVICE)
	  {
        p = (uint8_t *)deviceDescrCDC;
        len = sizeof(deviceDescrCDC);
      }
	else
	  {  /* must be config descriptor */
        p = (uint8_t *)configDescrCDC;
        len = sizeof(configDescrCDC);
      }
    usbMsgPtr = p;
    return len;
}
uint8_t CDC_usbFunctionSetup(uint8_t 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                                                          *//*---------------------------------------------------------------------------*/uint8_t CDC_usbFunctionRead( uint8_t *data, uint8_t len ){
  memcpy(data, CDC_mode, 7); 
  return 7;}/*---------------------------------------------------------------------------*//* usbFunctionWrite                                                          *//*---------------------------------------------------------------------------*/uint8_t CDC_usbFunctionWrite( uint8_t *data, uint8_t len ){  /* enforce DATA0 token for next transfer */
  USB_SET_DATATOKEN1(USBPID_DATA1);

  memcpy(CDC_mode, data, 7);
  if (*CDC_uartreset != NULL)
    CDC_uartreset();
  return 1;
}void CDC_usbFunctionWriteOut( uint8_t *data, uint8_t len ){//  usbDisableAllRequests();
  for( ; len; len-- ) 
    BUF_put(*data++,&rxbuffer);
//  usbEnableAllRequests();
}
void CDC_init(void)
{
  uint8_t    i, j;
  
  BUF_init(&rxbuffer,rxbuf_bd,RX_BUFSIZE);
  BUF_init(&txbuffer,txbuf_bd,HW_CDC_PACKET_SIZE);

  /* activate pull-ups except on USB lines */  USB_CFG_IOPORT   = (uint8_t)~((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
  usbSetInterrupt(0, 0);  /* the host eats the first packet -- don't know why... */
  usbInit();
  sei();//  wdt_enable(WDTO_1S);}
void CDC_poll(void){//  wdt_reset();  usbPoll();
  /*    usb -> rs232c:  ready to receive?    *///  if( usbAllRequestsAreDisabled() /*&& uartRxBytesFree()>=8 */) //TODo
//     usbEnableAllRequests();

  if( usbInterruptIsReady() ) 
    {
	  static uchar sendEmptyFrame = 1;
      if ( txbuffer.n || sendEmptyFrame ) 
	    {
	      usbSetInterrupt((uchar *)txbuffer.buf, txbuffer.n);		  /* send an empty block after last data block to indicate transfer end */
          sendEmptyFrame = txbuffer.n==HW_CDC_PACKET_SIZE? 1:0;
	 	}
      BUF_flush(&txbuffer);    }
  /*rs232 -> usb*/
  if (rxbuffer.n > 0)
    if (*CDC_charrecived != NULL)
	  CDC_charrecived(BUF_get(&rxbuffer));
  /* We need to report rx and tx carrier after open attempt */  if(intr3Status != 0 && usbInterruptIsReady3())
    {      static uint8_t serialStateNotification[10] = {0xa1, 0x20, 0, 0, 0, 0, 2, 0, 3, 0};      if(intr3Status == 2)
        usbSetInterrupt3(serialStateNotification, 8);      else
        usbSetInterrupt3(serialStateNotification+8, 2);      intr3Status--;
      if (*CDC_ondisconnect != NULL)
	    CDC_ondisconnect();     }}void UART_putc(uint8_t data)
{
  BUF_put(data,&txbuffer);
  while (txbuffer.n == 8)
    CDC_poll();
}
void UART_puts(const char *s )
{
  while (*s) 
    UART_putc(*s++);
}

void UART_puts_P(const char *s )
{
  char c;
  while ((c = pgm_read_byte(s++)) ) 
    {
      UART_putc(c);
    }
}

uint16_t UART_getc(void)
{    
  if (rxbuffer.n)
    return BUF_get(&rxbuffer);
  else
    return UART_NO_DATA;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -