For long time, UART is the only and best way to interface with PC. It is easy to adapt and handle. Though some devices (like: GSM modem etc.) have UART on themselves, but for interfacing with PC, there is only one thing now and that is USB
Introduction
The purpose of this article is to explain how to interface a PIC microcontroller to a PC via the USB port. Although the concepts are universal, the examples are specifically for use with
Fig. 1: Screenshot showing detection of PIC USB Device on Windows
MikroElektronika’s ‘MikroC Pro for PIC’. PIC18F2550 and PIC18f4550 are famous for their USB Module. To stay ahead you can start with their datasheets.It is assumed that the reader has gone through the project How to get started with PIC and done all the things discussed in it.
The most difficult part of this project is exactly what is required to get the PIC microcontroller to communicate with the USB port. The two most important things that absolutely have to be correct are the microcontroller configuration, and the USB device descriptor. If even the smallest thing is incorrect about either of these, communication will not occur.
USB Speed
The original USB 1.0 specification, defined data transfer rate of 1.5 Mbit/s “Low Speed” and 12 Mbit/s “Full Speed”. The 12 Mbit/s data rate was intended for higher-speed devices such as disk drives, and the lower 1.5 Mbit/s rate for low data rate devices such as joysticks. The USB 2.0 specification has 480 Mbit/s data transfer rate, which is also known as “High Speed”. The new USB 3.0 specification has up to 5 Gbit/s data transfer rate, known as “Super Speed”.
P18F2550/4550 supports low speed (1.5 Mb/s) and Full Speed (12 Mb/s). So the first thing you have to know is how to set desired clock for USB.
Clock setting
I’ll show you how to configure ‘Full Speed’ i.e. 12 Mb/s. When you use mcu for USB connectivity, it must have either a 6 MHz or 48 MHz clock for USB operation, depending on whether Low-Speed or Full-Speed mode is being used. The first thing you can do is, use a 48MHz crystal (for full speed). But there are two drawbacks:
– 48MHz isn’t available that much and it is costly.
– The higher the crystal, the greater will be the noise.
Microchip really does a great job to solve this problem. They include a phase locked loop (PLL) frequency multiplier, which allows a wide range of clock speeds from 4MHz to 48MHz. Noise cancelation is handled inside it. So we are going to use this feature to produce Full Speed for USB.
The block diagram of clock is shown below: (from datasheet, page 24).
Fig. 2: Internal Block Diagram of PIC 18F2550/4550
P18F2550 have both external and internal oscillator supports. As we are discussing external oscillator that’s why I omitted the down part of the diagram (not shown). From the diagram you see that PLL module actually create 96MHz and after divide by two it is 48MHz. This PLL module must have 4MHz input. So if you use 4MHz crystal then you should set 1(one) as PLL prescaler (PLLDIV = 000). If you use 20MHz then prescaler should be 5 and so on.
That was the end of USB clock settings. Now what about mcu clock source. From the block diagram you can see that either you can use PLL’s output or you can directly use crystal’s output. And they both have some prescaler values.
In this tutorial I am going to use a 20MHz crystal. So for USB, PLL prescaler will be 5. MCU will be running at 20MHz (i.e. prescaler will be 1 [CPUDIV = 00] ).
Clock Settings in MikroC
Clock settings in MikroC
Even before programming the microcontroller, its configuration must be correct. Open a project in MikroC with P18F2550. Go to Project->Edit Project. You will see a window like below:
Fig. 3: Screenshot of clock settings on MikroC
Watch carefully.
PLL Prescaler Selection: As I use 20MHz so prescaler should be 5.
USB Clock Selection: I choose PLL.
Oscillator Selection: I choose HS (High Speed). From datasheet you’ll see 20MHz is under HS. If you want to use PLL as a mcu clock then choose HSPLL.
System Clock Postscaler Selection: As I mentioned earlier mcu scaler will be 1, I choose so.
USB voltage regulator
At the end of the figure, before ‘Watchdog Timer’, there is ‘USB voltage regulator’ and I enabled it. The thing is voltage level of USB data line (D+ and D-) is 3.3 volt. As your mcu works at 5v, so there is a 3.3v regulator for USB. You have to enable it.
Also if you study the pin diagram you’ll see there is a pin called VUSB (pin14). If you don’t want to use internal 3.3v regulator, you can supply a 3.3v source in this pin. And if you use internal regulator then add a 220nF capacitor in this pin with respect to ground to stable the internal source. I usually use two 100nF cap in parallel.
Descriptor
Whenever you plug-in a device in USB, what actually happens? A pop up comes which says you just attach a new device and it ask for a driver, right? Do you really notice what happen when you plug an USB mouse or keyboard? NOTHING!
Do you ever wonder why that is? Because these devices are under ‘HID (Human Interface Device) Protocol’ and Windows has driver of HID by default. So if your device communicate with OS as an HID then you don’t need any driver for your device!!
Typical examples of HID devices include :
1) Keyboards and pointing devices, for example: standard mouse devices and joysticks.
2) Front-panel controls, for example: knobs, switches, buttons.
3) Controls that might be found on devices such as telephones, VCR remote controls, games or simulation devices, for example: throttles, steering wheels.
4) Devices that may not require human interaction but provide data in a similar format to HID class devices, for example, bar-code readers, thermometers, or voltmeters.
In this tutorial I will present my device as and HID and in the subsequent tutorial I will teach you how to make Drivers.
To make your device HID you should include a descriptor source file which contains vendor id and name, product id and name, report length, and other relevant information necessary for HID class. No need to worry. MikroC also handle that too. To create a descriptor file, use the integrated USB HID terminal of MikroC (Go to Tools › USB HID Terminal). This is the same thing as ‘USART Terminal’ (in MikroC) or ‘Hyper Terminal’ (in Windows). If you ever work on serial port you know what I am talking about, otherwise ignore it.
Switch to ‘Descriptor’ tab. You can change product and vendor name. Leave rest as they are and press ‘Save Descriptor’. Save the file in your project’s folder. The default name for descriptor file is USBdsc.c
, but you can rename it.
Fig. 4: Screenshot of Descriptor Tab on MikroC
Project Manager
Now that the USB descriptor is completed you must tell the compiler to use the file. This is done with the Project Manager.
Fig. 5: Screenshot of USB Descriptor on MikroC
On the right side of the compiler screen click on the “Project Manager” tab (red box). This opens the Project Manager. Be sure the descriptor file appears below the Sources folder. If it does not appear, right-click on the Sources folder, click Add File to Project, then select your descriptor file. Now, when your main program compiles, the descriptor file will automatically be included. Be sure to save your project by clicking on Project, Save Project in the menu.
Coding
Coding
Now it’s time for coding. MikroC compiler has an USB library. You can find it in the “Library Manager” (under the “Project Manager” tab). Check it.
For details about the functions go through,
Help->mikroC PRO for PIC Libraries->Hardware Libraries
At the end of the list you’ll find “USB Library”.
MikroC USB Library
MikroC provide two types of USB library. One for general USB communication and other for HID USB communication. I am going to discuss later one.
1) HID Enable: void HID_Enable(char *readbuff, char *writebuff);
Enables USB HID communication. It takes two parameters. ReadBuffer, the variable (more accurately an array) where you want to store the USB data that is come from the PC and WriteBuffer, where you want to store the data that’ll sent to PC.
According to datasheet these variables should be in USB RAM. MCU has 1 Kbyte USB RAM, starting from 400h to 7FFh.
Fig. 6: Diagram showing USB Databanks
From address 400h to 4FFh is for descriptor. So you actually have 500h to 7FFh for data store. So the two variables will be declared like below:
unsigned char readbuff[64] absolute 0x500;
unsigned char writebuff[64] absolute 0x540;
(“absolute” specifies the starting address in RAM for a variable or a starting address in ROM for a constant. If the variable or constant is multi-byte, higher bytes will be stored at the consecutive locations.)
2) HID_Read: char HID_Read(void);
Receives message from host and stores it in the Read Buffer. If the data reading has failed, the function returns 0. Otherwise, it returns number of characters received from the host.
3) HID_Write: char HID_Write(char *writebuff, char len);
Function sends data from Write Buffer to host. It has two parameters. Write buffer’s variable name and length of the data to be transmitted. If the data transmitting has failed, the function returns 0. Otherwise, it returns number of transmitted bytes. Function call needs to be repeated as long as data is not successfully sent.
4) HID_Disable: void HID_Disable(void);
Disables USB HID communication.
5) USB_Interrupt_Proc: void USB_Interrupt_Proc(void);
This routine is used for servicing various USB bus events. Should be called inside USB interrupt routine. Example: void interrupt()
{
USB_Interrupt_Proc();
}
How to Check if Your Descriptor is Working or Can the PC See My Device?
First we are going to simulate it in proteus. Draw the circuit like below.
Fig. 7: Circuit Diagram of PIC 18F2550 based USB device
Change the frequency (20 MHz) and load the hex file.
Fig. 8: Screenshot of Frequency settings for PIC USB Device
Open the USB HID terminal (Tools › USB HID Terminal). Voila!! It detects my device. Now write something at ‘Communication’ box and press send. You will see mcu read and send back the same thing.
Fig. 9: Screenshot USB HID Terminal on MikroC
To see the device info, press the “Info” button (at top right corner). You’ll see a window like below:
Project Source Code
### // MAIN.C unsigned char readbuff[64] absolute 0x500; unsigned char writebuff[64] absolute 0x540; char cnt; char kk; void interrupt() { USB_Interrupt { USB_Interrupt_Proc(); } void main(void) { ADCON1 |= 0x0f; CMCON |= 7; HID _Enable(&readbuff,&writebuff); while(1) { while(!HID_Read()); for(cnt=0;cnt<64;cnt++) writebuff[cnt]=readbuff[cnt]; while(!HID_Write(&writebuff,64)); } } // usb_config.h /******************************************************************** FileName: usb_config.h Dependencies: Always: GenericTypeDefs.h, usb_device.h Situational: usb_function_hid.h, usb_function_cdc.h, usb_function_msd.h, etc. Processor: PIC18 or PIC24 USB Microcontrollers Hardware: The code is natively intended to be used on the following hardware platforms: PICDEM� FS USB Demo Board, PIC18F87J50 FS USB Plug-In Module, or Explorer 16 + PIC24 USB PIM. The firmware may be modified for use on other USB platforms by editing the HardwareProfile.h file. Complier: Microchip C18 (for PIC18) or C30 (for PIC24) Company: Microchip Technology, Inc. Software License Agreement: The software supplied herewith by Microchip Technology Incorporated (the "Company") for its PIC(R) Microcontroller is intended and supplied to you, the Company's customer, for use solely and exclusively on Microchip PIC Microcontroller products. The software is owned by the Company and/or its supplier, and is protected under applicable copyright laws. All rights are reserved. Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil liability for the breach of the terms and conditions of this license. THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIE , WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. ******************************************************************** File Description: Change History: Rev Date Description 1.0 11/19/2004 Initial release 2.1 02/26/2007 Updated for simplicity and to use common coding style *******************************************************************/ /********************************************************************* * Descriptor specific type definitions are defined in: usbd.h ********************************************************************/ #ifndef USBCFG_H #define USBCFG_H /** DEFINITIONS ****************************************************/ #define USB_EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes. // Using larger options take more SRAM, but // does not provide much advantage in most types // of applications. Exceptions to this, are applications // that use EP0 IN or OUT for sending large amounts of // application related data. #define USB_MAX_NUM_INT 1 //Set this number to match the maximum interface number used in the descriptors for this firmware project #define USB_MAX_EP_NUMBER 1 //Set this number to match the maximum endpoint number used in the descriptors for this firmware project //Device descriptor - if these two definitions are not defined then // a ROM USB_DEVICE_DESCRIPTOR variable by the exact name of device_dsc // must exist. #define USB_USER_DEVICE_DESCRIPTOR &device_dsc #define USB_USER_DEVICE_DESCRIPTOR_INCLUDE extern ROM USB_DEVICE_DESCRIPTOR device_dsc //Configuration descriptors - if these two definitions do not exist then // a ROM BYTE *ROM variable named exactly USB_CD_Ptr[] must exist. #define USB_USER_CONFIG_DESCRIPTOR USB_CD_Ptr #define USB_USER_CONFIG_DESCRIPTOR_INCLUDE extern ROM BYTE *ROM USB_CD_Ptr[] //------------------------------------------------------------------------------ //Select an endpoint ping-pong bufferring mode. Some microcontrollers only //support certain modes. For most applications, it is recommended to use either //the USB_PING_PONG__FULL_PING_PONG or USB_PING_PONG__EP0_OUT_ONLY options. //The other settings are supported on some devices, but they are not //recommended, as they offer inferior control transfer timing performance. //See inline code comments in usb_device.c for additional details //Enabling ping pong bufferring on an endpoint generally increases firmware //overhead somewhat, but when both buffers are used simultaneously in the //firmware, can offer better sustained bandwidth, especially for OUT endpoints. //------------------------------------------------------ //#define USB_PING_PONG_MODE USB_PING_PONG__NO_PING_PONG //Not recommended #define USB_PING_PONG_MODE USB_PING_PONG__FULL_PING_PONG //A good all around setting //#define USB_PING_PONG_MODE USB_PING_PONG__EP0_OUT_ONLY //Another good setting //#define USB_PING_PONG_MODE USB_PING_PONG__ALL_BUT_EP0 //Not recommended //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //Select a USB stack operating mode. In the USB_INTERRUPT mode, the USB stack //main task handler gets called only when necessary as an interrupt handler. //This can potentially minimize CPU utilization, but adds context saving //and restoring overhead associated with interrupts, which can potentially //decrease performance. //When the USB_POLLING mode is selected, the USB stack main task handler //(ex: USBDeviceTasks()) must be called periodically by the application firmware //at a minimum rate as described in the inline code comments in usb_device.c. //------------------------------------------------------ //#define USB_POLLING #define USB_INTERRUPT //------------------------------------------------------------------------------ /* Parameter definitions are defined in usb_device.h */ #define USB_PULLUP_OPTION USB_PULLUP_ENABLE //#define USB_PULLUP_OPTION USB_PULLUP_DISABLED #define USB_TRANSCEIVER_OPTION USB_INTERNAL_TRANSCEIVER //External Transceiver support is not available on all product families. Please // refer to the product family datasheet for more information if this feature // is available on the target processor. //#define USB_TRANSCEIVER_OPTION USB_EXTERNAL_TRANSCEIVER #define USB_SPEED_OPTION USB_FULL_SPEED //#define USB_SPEED_OPTION USB_LOW_SPEED //(this mode is only supported on some microcontrollers) //------------------------------------------------------------------------------------------------------------------ //Option to enable auto-arming of the status stage of control transfers, if no //"progress" has been made for the USB_STATUS_STAGE_TIMEOUT value //If progress is made (any successful transactions completing on EP0 IN or OUT) //the timeout counter gets reset to the USB_STATUS_STAGE_TIMEOUT value. //During normal control transfer processing, the USB stack or the application //firmware will call USBCtrlEPAllowStatusStage() as soon as the firmware is finished //processing the control transfer. Therefore, the status stage completes as //quickly as is physically possible. The USB_ENABLE_STATUS_STAGE_TIMEOUTS //feature, and the USB_STATUS_STAGE_TIMEOUT value are only relevant, when: //1. The application uses the USBDeferStatusStage() API function, but never calls // USBCtrlEPAllowStatusStage(). Or: //2. The application uses host to device (OUT) control transfers with data stage, // and some abnormal error occurs, where the host might try to abort the control // transfer, before it has sent all of the data it claimed it was going to send. //If the application firmware never uses the USBDeferStatusStage() API function, //and it never uses host to device control transfers with data stage, then //it is not required to enable the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature. #define USB_ENABLE_STATUS_STAGE_TIMEOUTS //Comment this out to disable this feature. //Section 9.2.6 of the USB 2.0 specifications indicate that: //1. Control transfers with no data stage: Status stage must complete within // 50ms of the start of the control transfer. //2. Control transfers with (IN) data stage: Status stage must complete within // 50ms of sending the last IN data packet in fullfilment of the data stage. //3. Control transfers with (OUT) data stage: No specific status stage timing // requirement. However, the total time of the entire control transfer (ex: // including the OUT data stage and IN status stage) must not exceed 5 seconds. //Therefore, if the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is used, it is suggested //to set the USB_STATUS_STAGE_TIMEOUT value to timeout in less than 50ms. If the //USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is not enabled, then the USB_STATUS_STAGE_TIMEOUT //parameter is not relevant. #define USB_STATUS_STAGE_TIMEOUT (BYTE)45 //Approximate timeout in milliseconds, except when //USB_POLLING mode is used, and USBDeviceTasks() is called at < 1kHz //In this special case, the timeout becomes approximately: //Timeout(in milliseconds) = ((1000 * (USB_STATUS_STAGE_TIMEOUT - 1)) / (USBDeviceTasks() polling frequency in Hz)) //------------------------------------------------------------------------------------------------------------------ #define USB_SUPPORT_DEVICE #define USB_NUM_STRING_DESCRIPTORS 3 //#define USB_INTERRUPT_LEGACY_CALLBACKS #define USB_ENABLE_ALL_HANDLERS //#define USB_ENABLE_SUSPEND_HANDLER //#define USB_ENABLE_WAKEUP_FROM_SUSPEND_HANDLER //#define USB_ENABLE_SOF_HANDLER //#define USB_ENABLE_ERROR_HANDLER //#define USB_ENABLE_OTHER_REQUEST_HANDLER //#define USB_ENABLE_SET_DESCRIPTOR_HANDLER //#define USB_ENABLE_INIT_EP_HANDLER //#define USB_ENABLE_EP0_DATA_HANDLER //#define USB_ENABLE_TRANSFER_COMPLETE_HANDLER /** DEVICE CLASS USAGE *********************************************/ #define USB_USE_HID /** ENDPOINTS ALLOCATION *******************************************/ /* HID */ #define HID_INTF_ID 0x00 #define HID_EP 1 #define HID_INT_OUT_EP_SIZE 3 #define HID_INT_IN_EP_SIZE 3 #define HID_NUM_OF_DSC 1 #define HID_RPT01_SIZE 28 /** DEFINITIONS ****************************************************/ #endif //USBCFG_H // USBdsc.c const unsigned int USB_VENDOR_ID = 0x1234; const unsigned int USB_PRODUCT_ID = 0x0001; const char USB_SELF_POWER = 0x80; // Self powered 0xC0, 0x80 bus powered const char USB_MAX_POWER = 50; // Bus power required in units of 2 mA const char HID_INPUT_REPORT_BYTES = 64; const char HID_OUTPUT_REPORT_BYTES = 64; const char USB_TRANSFER_TYPE = 0x03; //0x03 Interrupt const char EP_IN_INTERVAL = 1; const char EP_OUT_INTERVAL = 1; const char USB_INTERRUPT = 1; const char USB_HID_EP = 1; const char USB_HID_RPT_SIZE = 33; /* Device Descriptor */ const struct { char bLength; // bLength - Descriptor size in bytes (12h) char bDescriptorType; // bDescriptorType - The constant DEVICE (01h) unsigned int bcdUSB; // bcdUSB - USB specification release number (BCD) char bDeviceClass; // bDeviceClass - Class Code char bDeviceSubClass; // bDeviceSubClass - Subclass code char bDeviceProtocol; // bDeviceProtocol - Protocol code char bMaxPacketSize0; // bMaxPacketSize0 - Maximum packet size for endpoint 0 unsigned int idVendor; // idVendor - Vendor ID unsigned int idProduct; // idProduct - Product ID unsigned int bcdDevice; // bcdDevice - Device release number (BCD) char iManufacturer; // iManufacturer - Index of string descriptor for the manufacturer char iProduct; // iProduct - Index of string descriptor for the product. char iSerialNumber; // iSerialNumber - Index of string descriptor for the serial number. char bNumConfigurations; // bNumConfigurations - Number of possible configurations } device_dsc = { 0x12, // bLength 0x01, // bDescriptorType 0x0200, // bcdUSB 0x00, // bDeviceClass 0x00, // bDeviceSubClass 0x00, // bDeviceProtocol 8, // bMaxPacketSize0 USB_VENDOR_ID, // idVendor USB_PRODUCT_ID, // idProduct 0x0001, // bcdDevice 0x01, // iManufacturer 0x02, // iProduct 0x00, // iSerialNumber 0x01 // bNumConfigurations }; /* Configuration 1 Descriptor */ const char configDescriptor1[]= { // Configuration Descriptor 0x09, // bLength - Descriptor size in bytes 0x02, // bDescriptorType - The constant CONFIGURATION (02h) 0x29,0x00, // wTotalLength - The number of bytes in the configuration descriptor and all of its subordinate descriptors 1, // bNumInterfaces - Number of interfaces in the configuration 1, // bConfigurationValue - Identifier for Set Configuration and Get Configuration requests 0, // iConfiguration - Index of string descriptor for the configuration USB_SELF_POWER, // bmAttributes - Self/bus power and remote wakeup settings USB_MAX_POWER, // bMaxPower - Bus power required in units of 2 mA // Interface Descriptor 0x09, // bLength - Descriptor size in bytes (09h) 0x04, // bDescriptorType - The constant Interface (04h) 0, // bInterfaceNumber - Number identifying this interface 0, // bAlternateSetting - A number that identifies a descriptor with alternate settings for this bInterfaceNumber. 2, // bNumEndpoint - Number of endpoints supported not counting endpoint zero 0x03, // bInterfaceClass - Class code 0, // bInterfaceSubclass - Subclass code 0, // bInterfaceProtocol - Protocol code 0, // iInterface - Interface string index // HID Class-Specific Descriptor 0x09, // bLength - Descriptor size in bytes 0x21, // bDescriptorType - This descriptor's type: 21h to indicate the HID class. 0x01,0x01, // bcdHID - HID specification release number (BCD). 0x00, // bCountryCode - Numeric expression identifying the country for localized hardware (BCD) or 00h. 1, // bNumDescriptors - Number of subordinate report and physical descriptors. 0x22, // bDescriptorType - The type of a class-specific descriptor that follows USB_HID_RPT_SIZE,0x00, // wDescriptorLength - Total length of the descriptor identified above. // Endpoint Descriptor 0x07, // bLength - Descriptor size in bytes (07h) 0x05, // bDescriptorType - The constant Endpoint (05h) USB_HID_EP | 0x80, // bEndpointAddress - Endpoint number and direction USB_TRANSFER_TYPE, // bmAttributes - Transfer type and supplementary information 0x40,0x00, // wMaxPacketSize - Maximum packet size supported EP_IN_INTERVAL, // bInterval - Service interval or NAK rate // Endpoint Descriptor 0x07, // bLength - Descriptor size in bytes (07h) 0x05, // bDescriptorType - The constant Endpoint (05h) USB_HID_EP, // bEndpointAddress - Endpoint number and direction USB_TRANSFER_TYPE, // bmAttributes - Transfer type and supplementary information 0x40,0x00, // wMaxPacketSize - Maximum packet size supported EP_OUT_INTERVAL // bInterval - Service interval or NAK rate }; const struct { char report[USB_HID_RPT_SIZE]; }hid_rpt_desc = { {0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1) 0x09, 0x01, // Usage (Vendor Usage 1) 0xA1, 0x01, // Collection (Application) // Input report 0x19, 0x01, // Usage Minimum 0x29, 0x40, // Usage Maximum 0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00) 0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255) 0x75, 0x08, // Report Size: 8-bit field size 0x95, HID_INPUT_REPORT_BYTES,// Report Count 0x81, 0x02, // Input (Data, Array, Abs) // Output report 0x19, 0x01, // Usage Minimum 0x29, 0x40, // Usage Maximum 0x75, 0x08, // Report Size: 8-bit field size 0x95, HID_OUTPUT_REPORT_BYTES,// Report Count 0x91, 0x02, // Output (Data, Array, Abs) 0xC0} // End Collection }; //Language code string descriptor const struct { char bLength; char bDscType; unsigned int string[1]; } strd1 = { 4, 0x03, {0x0409} }; //Manufacturer string descriptor const struct{ char bLength; char bDscType; unsigned int string[23]; }strd2={ 48, //sizeof this descriptor string 0x03, {'E','n','g','i','n','e','e','r','s',' ','G','a','r','a','g','e',' ','D','e','v','i','c','e'} }; //Product string descriptor const struct{ char bLength; char bDscType; unsigned int string[19]; }strd3={ 40, //sizeof this descriptor string 0x03, {'I','n','s','p','i','r','i','n','g',' ','c','r','e','a','t','i','o','n','s'} }; //Array of configuration descriptors const char* USB_config_dsc_ptr[1]; //Array of string descriptors const char* USB_string_dsc_ptr[3]; void USB_Init_Desc(){ USB_config_dsc_ptr[0] = &configDescriptor1; USB_string_dsc_ptr[0] = (const char*)&strd1; USB_string_dsc_ptr[1] = (const char*)&strd2; USB_string_dsc_ptr[2] = (const char*)&strd3; } ###
Circuit Diagrams
Project Video
Filed Under: Electronic Projects
Filed Under: Electronic Projects
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.