140 likes | 215 Views
if(Irq & D11_INT_EP2_OUT) { printf("EP2_OUT<br>"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP2_OUT, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP2_OUT, Buffer, 1); }
E N D
if(Irq & D11_INT_EP2_OUT) { printf("EP2_OUT\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP2_OUT, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP2_OUT, Buffer, 1); } if(Irq & D11_INT_EP2_IN) { printf("EP2_IN\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP2_IN, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP2_IN, Buffer, 1); } if(Irq & D11_INT_EP3_OUT) { printf("EP3_OUT\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP3_OUT, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP3_OUT, Buffer, 1); } if(Irq & D11_INT_EP3_IN) { printf("EP3_IN\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP3_IN, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP3_IN, Buffer, 1); } }if(Irq & D11_INT_EP1_OUT) { printf("EP1_OUT\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_OUT, Buffer, 1); bytes = D11ReadEndpoint(D11_ENDPOINT_EP1_OUT, Buffer); for (count = 0; count < bytes; count++) { circularbuffer[inpointer++] = Buffer[count]; if (inpointer >= MAX_BUFFER_SIZE) inpointer = 0; } loadfromcircularbuffer(); //Kick Start }if(Irq & D11_INT_EP1_IN) { printf("EP1_IN\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_IN, Buffer, 1); loadfromcircularbuffer(); } pPacke upPacket->wLeng ufferToEndPoint(); ase TYPE_DEVICE_DES escri ength) iteBuffe nt(); case TYPE_C ATION fig. pSendBuffer=(const unsigned char *)&DeviceDescriptor;BytesToSe if (BytesToSend>SetupPacket->wLength) BytesToSend= SetupPacket-> SetupPacket->wLength, sizeof(ConfigurationDescriptor));BytesTo Buffer[count rbuff 0x07 (outpoin _SIZE =0xC1|( cket.wInd INT_EP0_IN,Buffer,2 RTB=(PORTB&0x0F)| rolEndPoi const USB_CONFIG_DATA ConfigurationDescriptor = { { /* configuration descriptor */ sizeof(USB_CONFIGURATION_DESCRIPTOR), /* bLength */ TYPE_CONFIGURATION_DESCRIPTOR, /* bDescriptorType */ sizeof(USB_CONFIG_DATA), /* wTotalLength */ 1, /* bNumInterfaces */ 1, /* bConfigurationValue */ 0, /* iConfiguration String Index */ 0x80, /* bmAttributes Bus Powered, No Remote Wakeup */ 0x32 /* bMaxPower, 100mA */ }, { /* interface descriptor */ sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ 0, /* bInterface Number */ 0, /* bAlternateSetting */ 2, /* bNumEndpoints */ 0xFF, /* bInterfaceClass (Vendor specific) */ 0xFF, /* bInterfaceSubClass */ 0xFF, /* bInterfaceProtocol */ 0 /* iInterface String Index */ }, { /* endpoint descriptor */ sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ 0x01, /* bEndpoint Address EP1 OUT */ 0x02, /* bmAttributes - Interrupt */ 0x0008, /* wMaxPacketSize */ 0x00 /* bInterval */ }, { /* endpoint descriptor */ sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ 0x81, /* bEndpoint Address EP1 IN */ 0x02, /* bmAttributes - Interrupt */ 0x0008, /* wMaxPacketSize */ 0x00 /* bInterval */ } }; case TYPE_CONFIGURATION_DESCRIPTOR: printf("\n\rConfiguration Descriptor: Bytes Asked For %d, Size of Descriptor %d\n\r", \ SetupPacket->wLength, sizeof(ConfigurationDescriptor)); pSendBuffer = (const unsigned char *)&ConfigurationDescriptor; BytesToSend = sizeof(ConfigurationDescriptor); if (BytesToSend > SetupPacket->wLength) BytesToSend = SetupPacket->wLength; WriteBufferToEndPoint(); break; } void WriteBufferToEndPoint(void) { if (BytesToSend == 0) { D11WriteEndpoint(D11_ENDPOINT_EP0_IN, NULL, 0); } else if (BytesToSend >= 8) { D11WriteEndpoint(D11_ENDPOINT_EP0_IN, pSendBuffer, 8); pSendBuffer += 8; BytesToSend -= 8; } else { D11WriteEndpoint(D11_ENDPOINT_EP0_IN, pSendBuffer, BytesToSend); BytesToSend = 0; } } void loadfromcircularbuffer(void) { unsigned char Buffer[10]; unsigned char count; D11CmdDataRead(D11_ENDPOINT_EP1_IN, Buffer, 1); if (Buffer[0] == 0){ if (inpointer != outpointer){ count = 0; do { Buffer[count++] = circularbuffer[outpointer++]; if (outpointer >= MAX_BUFFER_SIZE) outpointer = 0; if (outpointer == inpointer) break; // No more data } while (count < 8); // Maximum Buffer Size D11WriteEndpoint(D11_ENDPOINT_EP1_IN, Buffer, count); } } } const USB_DEVICE_DESCRIPTOR DeviceDescriptor = { sizeof(USB_DEVICE_DESCRIPTOR), /* bLength */ TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */ 0x0110, /* bcdUSB USB Version 1.1 */ 0, /* bDeviceClass */ 0, /* bDeviceSubclass */ 0, /* bDeviceProtocol */ 8, /* bMaxPacketSize 8 Bytes */ 0x04B4, /* idVendor (Cypress Semi) */ 0x0002, /* idProduct (USB Thermometer Example) */ 0x0000, /* bcdDevice */ 1, /* iManufacturer String Index */ 0, /* iProduct String Index */ 0, /* iSerialNumber String Index */ 1 /* bNumberConfigurations */ }; __ _______ ____ / / / / ___// __ ) / / / /\__ \/ __ | / /_/ /___/ / /_/ / \____//____/_____/ _____ ____ _____________ _____ ____ ______ / ___// __ \/ ____/_ __/ | / / | / __ \/ ____/ \__ \/ / / / /_ / / | | /| / / /| | / /_/ / __/ ___/ / /_/ / __/ / / | |/ |/ / ___ |/ _, _/ /___ /____/\____/_/ /_/ |__/|__/_/ |_/_/ |_/_____/ ____ / \ / / \____/ Guilherme Krause Valter Toffolo PUCRS 2007/2 Programação de Periféricos - T590 professor Eduardo Bezerra
FUNCTIONS, ENDPOINTS e PIPES • HUBS e FUNCTIONS • dispositivos usb podem ser hub ou function, ou várias functions ligadas a um hub. ex: uma webcam com microfone • cada function corresponde a uma classe usb (mass storage device, HID keyboard, etc) • ENDPOINTS • parte do dispositivo usb onde termina uma conexão lógica • cada function pode ter vários endpoints • em hardware, corresponde a um buffer de I/O • PIPES • conexão lógica entre o host e um endpoint • são unidirecionais, exceto para endpoints de controle
SYNC[8/8/32] PID [4+^4] DATA[8/1023/1024 CRC[16] EOP[3] SYNC[8/8/32] PID [4+^4] ADDR[7] ENDP[4] CRC[5] EOP[3] SYNC[8/8/32] PID [4+^4] EOP[3] • COMUNICAÇÃO - pacotes • TOKEN • PID: pode ser IN, OUT, SETUP, SOF • ADDR: endereço do dispositivo • ENDP: endpoint do dispositivo endereçado • DATA • PID: pode ser DATA0, DATA1, e também DATA2, MDATA para high speed • DATA: • tamanho variável • tamanho menor que o máximo indica que é o ultimo pacote de dados • HANDSHAKE • PID: pode ser ACK, NAK, STALL, NYET • quando a tranferencia termina com sucesso, é enviado ack • nak geralmente informa que não foi possivel transmitir, mas não é erro • quando ocorre um erro, é enviado um stall
token : in data Handshake : ack handshake : nak handshake : stall token : out handshake : nak data Handshake : ack handshake : stall handshake : nak handshake : stall packet from host packet from device • COMUNICAÇÃO - fluxo • Iniciada pelo host, através de um token packet. • O token define a direção da comunicação. • host <- device: • no lugar do data packet, o device pode responder com um handshake do tipo nak caso não tenha dados a enviar, um stall em caso de erro interno. • host <- device: • caso o device não esteja pronto para receber o pacote (buffer cheio), o handshake será do tipo • no caso de receber dados inválidos, não é enviado handshake, e o envio é feito novamente • para isochronous transfers não há handshake
ENDPOINTS - modos de transferencia • CONTROL • permitido somente através de control pipes • geralmente usado para comandos e status, por ter entrega garantida • é o modo usado no endpoint0, para configurar o device e ler os descritores • BULK • usado para grandes quantidades de dados • entrega garantida e integridade verificada por crc • não garante latencia baixa nem transferência rápida • INTERRUPT • baixa latencia, entrega e integridade garantidas • host faz polling em intervalo definido. • ISOCHRONOUS • velocidade garantida, baixa latencia, transferencia contínua • entrega não garantida (não tem pacote de handshake)
DESCRIPTORS • DEFINIÇÃO • estruturas de dados com informações sobre o dispositivo • são requisitadas pelo host na ocasião da enumeração • CARACTERÍSTICAS • permite que o host identifique o dispositivo • possibilita múltiplas configurações
DEVICE USB: 2.0 Class/SubClass: 0 pktsz: 8 VID/PID/rev: NumConfigs: 2 CONFIG CONFIG ID: 0 power: bus maxpower: 255 num_ifaces: 4 ID: 1 power: self maxpower: 0 num_ifaces: 1 INTERFACE INTERFACE INTERFACE INTERFACE INTERFACE class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: cam ID: 1 alt_setting: 0 num_endpoints: 2 class: photo ID: 1 alt_setting: 1 num_endpoints: 2 class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: 0 ID: 2 alt_setting: 0 num_endpoints: 3 EP EP EP EP EP EP EP EP ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: iso pktsz: 64 intfreq: 1 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: - type: ctrl pktsz: 8 intfreq: - ID: 2 inout: in type: int pktsz: 8 intfreq: 50 • DESCRIPTORS - exemplo • CELULAR • mass storage device • webcam modos camera/foto • carga pela usb
DEVICE USB: 2.0 Class/SubClass: 0 pktsz: 8 VID/PID/rev: NumConfigs: 2 CONFIG CONFIG ID: 0 power: bus maxpower: 255 num_ifaces: 4 ID: 1 power: self maxpower: 0 num_ifaces: 1 INTERFACE INTERFACE INTERFACE INTERFACE INTERFACE class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: cam ID: 1 alt_setting: 0 num_endpoints: 2 class: photo ID: 1 alt_setting: 1 num_endpoints: 2 class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: 0 ID: 2 alt_setting: 0 num_endpoints: 3 EP EP EP EP EP EP EP EP ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: iso pktsz: 64 intfreq: 1 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: - type: ctrl pktsz: 8 intfreq: - ID: 2 inout: in type: int pktsz: 8 intfreq: 50 • DESCRIPTORS - exemplo • DEVICE: • apenas um descritor desse tipo • identifica o dispositivo fisico, fabricante e modelo • permite informar classe, para buscar driver • paket size referente aos endpoint0 • exemplo: • usb 2.0, classe será informada nas interfaces, ep0 tem buffer de 8 bytes
DEVICE USB: 2.0 Class/SubClass: 0 pktsz: 8 VID/PID/rev: NumConfigs: 2 CONFIG CONFIG ID: 0 power: bus maxpower: 255 num_ifaces: 4 ID: 1 power: self maxpower: 0 num_ifaces: 1 INTERFACE INTERFACE INTERFACE INTERFACE INTERFACE class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: cam ID: 1 alt_setting: 0 num_endpoints: 2 class: photo ID: 1 alt_setting: 1 num_endpoints: 2 class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: 0 ID: 2 alt_setting: 0 num_endpoints: 3 EP EP EP EP EP EP EP EP ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: iso pktsz: 64 intfreq: 1 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: - type: ctrl pktsz: 8 intfreq: - ID: 2 inout: in type: int pktsz: 8 intfreq: 50 • DESCRIPTORS - exemplo • CONFIGS: • raramente tem mais de um config descriptor • define os requisitos de alimentacao • tem um conjunto especifico de interfaces • exemplo: • configuracao alternativa sem alimentacao pela usb, caso seja um laptop. apenas MSD disponivel nesse modo
DEVICE USB: 2.0 Class/SubClass: 0 pktsz: 8 VID/PID/rev: NumConfigs: 2 CONFIG CONFIG ID: 0 power: bus maxpower: 255 num_ifaces: 4 ID: 1 power: self maxpower: 0 num_ifaces: 1 INTERFACE INTERFACE INTERFACE INTERFACE INTERFACE class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: cam ID: 1 alt_setting: 0 num_endpoints: 2 class: photo ID: 1 alt_setting: 1 num_endpoints: 2 class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: 0 ID: 2 alt_setting: 0 num_endpoints: 3 EP EP EP EP EP EP EP EP ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: iso pktsz: 64 intfreq: 1 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: - type: ctrl pktsz: 8 intfreq: - ID: 2 inout: in type: int pktsz: 8 intfreq: 50 • DESCRIPTORS - exemplo • INTERFACE: • define a classe da function • pode ter uma configuracao alternativa • exemplo: • interface1 tem duas configurações, com endpoints diferentes, permitindo alterar endpoint1 sem interferir no endpoint0
DEVICE USB: 2.0 Class/SubClass: 0 pktsz: 8 VID/PID/rev: NumConfigs: 2 CONFIG CONFIG ID: 0 power: bus maxpower: 255 num_ifaces: 4 ID: 1 power: self maxpower: 0 num_ifaces: 1 INTERFACE INTERFACE INTERFACE INTERFACE INTERFACE class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: cam ID: 1 alt_setting: 0 num_endpoints: 2 class: photo ID: 1 alt_setting: 1 num_endpoints: 2 class: MSD ID: 0 alt_setting: 0 num_endpoints: 3 class: 0 ID: 2 alt_setting: 0 num_endpoints: 3 EP EP EP EP EP EP EP EP ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: iso pktsz: 64 intfreq: 1 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: in type: bulk pktsz: 64 intfreq: 0 ID: 2 inout: out type: bulk pktsz: 64 intfreq: 0 ID: 1 inout: - type: ctrl pktsz: 8 intfreq: - ID: 2 inout: in type: int pktsz: 8 intfreq: 50 • DESCRIPTORS - exemplo • ENDPOINTS: • sempre existe UM endpoint0 por interface • define a direção do pipe e tipo de transação • pktsz corresponde ao buffer em hw • exemplo: • interface msd tem um endpoint de entrada e um de saída.
IMPLEMENTAÇÕES – linux • KERNEL LEVEL • URBS • são USB Request Blocks • API fornecida pelo kernel para comunicar com a usb em um nível mais alto • a comunicação é assíncrona, com handlers para tratar o fim da transferência • TRANSFERS • é o nível mais baixo, que é abstraído pelos URBs • são transferências síncronas • USER LEVEL • LIBUSB • permite a comunicação com dispositivos usb em nível de usuário • ainda não é muito usada • não chegou na versão 1.0 ainda
if(Irq & D11_INT_EP2_OUT) { printf("EP2_OUT\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP2_OUT, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP2_OUT, Buffer, 1); } if(Irq & D11_INT_EP2_IN) { printf("EP2_IN\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP2_IN, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP2_IN, Buffer, 1); } if(Irq & D11_INT_EP3_OUT) { printf("EP3_OUT\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP3_OUT, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP3_OUT, Buffer, 1); } if(Irq & D11_INT_EP3_IN) { printf("EP3_IN\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP3_IN, Buffer, 1); Buffer[0] = 0x01; /* Stall Endpoint */ D11CmdDataWrite(D11_SET_ENDPOINT_STATUS + D11_ENDPOINT_EP3_IN, Buffer, 1); } }if(Irq & D11_INT_EP1_OUT) { printf("EP1_OUT\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_OUT, Buffer, 1); bytes = D11ReadEndpoint(D11_ENDPOINT_EP1_OUT, Buffer); for (count = 0; count < bytes; count++) { circularbuffer[inpointer++] = Buffer[count]; if (inpointer >= MAX_BUFFER_SIZE) inpointer = 0; } loadfromcircularbuffer(); //Kick Start }if(Irq & D11_INT_EP1_IN) { printf("EP1_IN\n\r"); D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_IN, Buffer, 1); loadfromcircularbuffer(); } pPacke upPacket->wLeng ufferToEndPoint(); ase TYPE_DEVICE_DES escri ength) iteBuffe nt(); case TYPE_C ATION fig. pSendBuffer=(const unsigned char *)&DeviceDescriptor;BytesToSe if (BytesToSend>SetupPacket->wLength) BytesToSend= SetupPacket-> SetupPacket->wLength, sizeof(ConfigurationDescriptor));BytesTo Buffer[count rbuff 0x07 (outpoin _SIZE =0xC1|( cket.wInd INT_EP0_IN,Buffer,2 RTB=(PORTB&0x0F)| rolEndPoi const USB_CONFIG_DATA ConfigurationDescriptor = { { /* configuration descriptor */ sizeof(USB_CONFIGURATION_DESCRIPTOR), /* bLength */ TYPE_CONFIGURATION_DESCRIPTOR, /* bDescriptorType */ sizeof(USB_CONFIG_DATA), /* wTotalLength */ 1, /* bNumInterfaces */ 1, /* bConfigurationValue */ 0, /* iConfiguration String Index */ 0x80, /* bmAttributes Bus Powered, No Remote Wakeup */ 0x32 /* bMaxPower, 100mA */ }, { /* interface descriptor */ sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ TYPE_INTERFACE_DESCRIPTOR, /* bDescriptorType */ 0, /* bInterface Number */ 0, /* bAlternateSetting */ 2, /* bNumEndpoints */ 0xFF, /* bInterfaceClass (Vendor specific) */ 0xFF, /* bInterfaceSubClass */ 0xFF, /* bInterfaceProtocol */ 0 /* iInterface String Index */ }, { /* endpoint descriptor */ sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ 0x01, /* bEndpoint Address EP1 OUT */ 0x02, /* bmAttributes - Interrupt */ 0x0008, /* wMaxPacketSize */ 0x00 /* bInterval */ }, { /* endpoint descriptor */ sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ TYPE_ENDPOINT_DESCRIPTOR, /* bDescriptorType */ 0x81, /* bEndpoint Address EP1 IN */ 0x02, /* bmAttributes - Interrupt */ 0x0008, /* wMaxPacketSize */ 0x00 /* bInterval */ } }; case TYPE_CONFIGURATION_DESCRIPTOR: printf("\n\rConfiguration Descriptor: Bytes Asked For %d, Size of Descriptor %d\n\r", \ SetupPacket->wLength, sizeof(ConfigurationDescriptor)); pSendBuffer = (const unsigned char *)&ConfigurationDescriptor; BytesToSend = sizeof(ConfigurationDescriptor); if (BytesToSend > SetupPacket->wLength) BytesToSend = SetupPacket->wLength; WriteBufferToEndPoint(); break; } void WriteBufferToEndPoint(void) { if (BytesToSend == 0) { D11WriteEndpoint(D11_ENDPOINT_EP0_IN, NULL, 0); } else if (BytesToSend >= 8) { D11WriteEndpoint(D11_ENDPOINT_EP0_IN, pSendBuffer, 8); pSendBuffer += 8; BytesToSend -= 8; } else { D11WriteEndpoint(D11_ENDPOINT_EP0_IN, pSendBuffer, BytesToSend); BytesToSend = 0; } } void loadfromcircularbuffer(void) { unsigned char Buffer[10]; unsigned char count; D11CmdDataRead(D11_ENDPOINT_EP1_IN, Buffer, 1); if (Buffer[0] == 0){ if (inpointer != outpointer){ count = 0; do { Buffer[count++] = circularbuffer[outpointer++]; if (outpointer >= MAX_BUFFER_SIZE) outpointer = 0; if (outpointer == inpointer) break; // No more data } while (count < 8); // Maximum Buffer Size D11WriteEndpoint(D11_ENDPOINT_EP1_IN, Buffer, count); } } } const USB_DEVICE_DESCRIPTOR DeviceDescriptor = { sizeof(USB_DEVICE_DESCRIPTOR), /* bLength */ TYPE_DEVICE_DESCRIPTOR, /* bDescriptorType */ 0x0110, /* bcdUSB USB Version 1.1 */ 0, /* bDeviceClass */ 0, /* bDeviceSubclass */ 0, /* bDeviceProtocol */ 8, /* bMaxPacketSize 8 Bytes */ 0x04B4, /* idVendor (Cypress Semi) */ 0x0002, /* idProduct (USB Thermometer Example) */ 0x0000, /* bcdDevice */ 1, /* iManufacturer String Index */ 0, /* iProduct String Index */ 0, /* iSerialNumber String Index */ 1 /* bNumberConfigurations */ }; ____ ____ ______________________ /_/|_|_ _______________ _____ / __ \/ ____/ ____/ ____/ __ \/ ____/ | / / ____/ _/ | / ___/ / /_/ / __/ / /_ / __/ / /_/ / __/ / |/ / / / // /| | \__ \ / _, _/ /___/ __/ / /___/ _, _/ /___/ /| / /____/ // ___ |___/ / /_/ |_/_____/_/ /_____/_/ |_/_____/_/ |_/\____/___/_/ |_/____/ • beyond logic – usb in a nutshell • http://www.beyondlogic.org/usbnutshell • universal serial bus 2.0 specification • http://www.usb.org/developers/docs/usb_20_071607.zip • wikipedia • http://wikipedia.org