Sie sind auf Seite 1von 106

INTERFACING OF USB DEVICE WITH LABVIEW

NUR SYIFA BT ZAINAL ABIDIN

A report submitted in partial fulfillment of the


requirements for the award of the degree of
Bachelor of Engineering (Electrical - Electronics)

Faculty of Electrical Engineering


Universiti Teknologi Malaysia

May 2011
v

ABSTRACT

Universal Serial Bus or USB is a common serial bus interface which allows high-
speed and easy connection of peripherals to a PC (Personal Computer). With USB
implementation, users can transfer any data to or from a USB device and host PC.
LabVIEW is a software used to design an user application normally used for data
acquisition, test and measurements. This project has been carried out to interface a USB
device with LabVIEW software to enable USB communication between both
components so that the data can be transferred directly through a USB cable. In order to
create a USB device, a PIC18F4550 microcontroller is used because of the USB module
built within it. LabVIEW user application or also known as Graphical User Interface
(GUI) is built within LabVIEW software and NI-VISA software has been used for the
interfacing of USB device and LabVIEW. Based on the result obtained, the USB device
has been successfully communicate with the LabVIEW user application designed.
vii

TABLE OF CONTENTS

CHAPTER TITLE PAGE

DECLARATION ii
DEDICATION iii
ACKNOWLEDGEMENTS iv
ABSTRACT v
ABSTRAK vi
TABLE OF CONTENTS vii
LIST OF TABLES x
LIST OF FIGURES xi
LIST OF ABBREVIATIONS xiii
LIST OF APPENDICES xv

1 INTRODUCTION
1.1 Background of Study 1
1.2 Problem of Statement 2
1.3 Objective 3
1.4 Scope 3
1.5 Thesis Outline 3

2 LITERATURE REVIEW
2.1 Universal Serial Bus 5
2.1.1 USB Architecture 7
2.1.2 USB Transactions 7
viii

2.1.3 Data Flow Types 9


2.1.4 USB 2.0 and 3.0 12
2.1.5 Physical Connection of USB 13
2.1.6 USB Software Driver 14
2.1.7 Device Drivers 15
2.2 Graphical User Interface and LabVIEW 15
2.2.1 NI-VISA 17
2.3 PIC Microcontroller 18
2.3.1 PIC18F4550 19
2.4 MPLab IDE Software 21

3 METHODOLOGY
3.1 Project Overview 22
3.2 Hardware (USB Device) 23
3.2.1 PIC18F4550 25
3.3 USB Firmware 26
3.3.1 USB Firmware into PIC 28
3.4 Interfacing of LabVIEW Software Using NI-VISA 30
3.5 LabVIEW Application (GUI) 32

4 RESULT AND DISCUSSION


4.1 USB Device 38
4.2 USB Device with LabVIEW Software 39
4.3 LabVIEW Application (GUI) 41

5 CONCLUSION
5.1 Project Summary 46
5.2 Problems Encountered 47
5.3 Recommendation 47
ix

REFERENCES 49

APPENDICES A 51
x

LIST OF TABLES

TABLE NO. TITLE PAGE

2.1 Type of packet Format with PID Values 8

2.2 Characteristics and Applications of Data Transfer 10

Types

2.3 USB Specifications (Partial) 11

2.4 USB Pin-Out Connections 13

3.1 USB Specification Request 33


xi

LIST OF FIGURES

FIGURE NO. TITLE PAGE

2.1 USB Type A Plug (Commonly Used USB Plug) 6

2.2 USB Pin-out for Standard USB Plug A and Plug B 14

2.3 Example of LabVIEW GUI 16

2.4 PIC 18F4550 USB Interface 19

2.5 44-Pin TQFP PIC18F4550 Microcontroller 20

2.6 PIC18F4550 Microcontroller USB Overview 20

3.1 Project Block Diagram 22

3.2 Methodology Approach 23

3.3 Portable e-Mucosa 24

3.4 Input/Output Pins for 44-pin TQFP PIC18F4550 25

3.5 Snippet Preview of MikroC PIC18F4550 USB-HID 27

Firmware

3.6 MPLab IDE Window with Snippet Code of the USB 28

Firmware

3.7 ICSP Connector 29

3.8 Microchip MPLab ICD 2 Debugger 30

3.9 USB Device and NI-VISA Configuration Steps 31


xii

3.10 Driver Development Wizard 32

3.11 Flowchart of LabVIEW Application 34

3.12 VISA USB Control In Function 35

3.13 Block Diagram Part A 35

3.14 Block Diagram Part B 36

3.15 Full Block Diagram 36

4.1 Found New Hardware Wizard 38

4.2 Detaching the USB Device 39

4.3 Device Manager Explorer 40

4.4 Measurement and Automation Explorer 41

4.5 LabVIEW User Application 42

4.6 USB RAW VISA Resource Name List 43

4.7 Request Type, Request, Value and Index for Standard 43

Request

4.8 Data Transferred by the USB Device 44


xiii

LIST OF ABBREVIATIONS

USB - Universal Serial Bus

LabVIEW - Laboratory Virtual Instrument Engineering Workbench

GUI - Graphical User Interface

PC - Personal Computer

NI-DAQ - National Instrument-Data Acquisition

PIC - Programmable Interface Controller

NI-VISA - National Instrument-Virtual Instrument Software Architecture

PDA - Portable

SOF - Start of Packet

PID - Packet Identifier

ID - Identifier

HID - Human Interface Device

ICSP - In Circuit Serial Programming

IDE - Integrated Development Environment

ICD - In Circuit Debugger

I/O - Input/Output

MAX - Measurement and Automation


xiv

LIST OF APPENDICES

APPENDIX TITLE PAGE

A USB Firmware of PIC18F4550 Microcontroller 51


1

CHAPTER 1

INTRODUCTION

1.1 Background of Study

This project is basically about the development of USB device using a


microcontroller and the need to interface the USB device with a Graphical User
Interface (GUI) application of LabVIEW software. A USB device is a device that uses
the USB bus topology making it easier to connect to a personal computer or any other
host devices. USB can connect computer peripherals such as mice, keyboards, digital
cameras, printers, personal media players, flash drives, network adapters, and external
hard drives. For many of those devices, USB has become a standard connection method.

USB allows data transfer between the USB device and the host PC. There are
four types of data transfer which are control transfer, isynchronous transfer, bulk transfer
and interrupt transfer. The data is transferred using USB data lines through a USB cable
or directly connection to the USB port. Finally, the data that has been transferred to the
PC needs an application to be interfaced with and use the data according to the design
needs.
2

There are various software that can be used to build a Graphical User Interface
application. For example, we can use Microsoft Visual Studio, Visual Basic, QT SDK
and also LabVIEW software. For this project, we only concern with LabVIEW software
to interface with the USB device which specifically for data acquisition. Data acquisition
is the process of sampling signals for real world physical conditions measurement. Its
typically convert analog signals into digital waveforms for processing. The purpose of
data acquisition is to measure electrical or physical quantities such as voltage, current,
temperature, pressure or sound. Data acquisition systems incorporate signals, sensors,
actuators, signal conditioning, data acquisition devices, and application software.

1.2 Problems Statement

Normally for data acquisition purposes, NI-DAQ card is used. NI-DAQ stands
for National Instrument-Data Acquisition which is a device specifically used to acquisite
data from any devices or signals from components such as sensors. However, this card is
quite expensive for a single purpose use. The lowest price in the market now is around
RM400. Hence, the other alternative for data acquisition without the need to use NI-
DAQ card is to implement a USB module within the device by using USB architecture.
With the USB module integration, we can directly acquisite data to the PC which is
more convenient. Moreover, the USB implementation also allows real time data
monitoring. Hence, USB is a great communication method for most applications.
3

1.3 Objective

For this project, there are two objectives to be achieved. The first objective is to
implement an interfacing between a USB device with LabVIEW Software. In other
words is to enable USB communication between the host PC and the USB device. Once
the interfacing is succeed, the follows objective is to send dummy data directly through a
USB cable from the USB Device to Labview application (GUI) as for mimicking data
acquisition system.

1.4 Scope

In order to achieve both of the objectives for this project, several scopes have
been identified. The scopes can be divided into two major parts which are the hardware
and software parts. The hardware part only involves on the programming of the PIC
18F4550 in MPLab software or creating the USB firmware to be functioned as a USB
device. While, the software part considers about the design of a LabVIEW application in
order to interface with the hardware.

1.5 Thesis Outline

In this thesis, there are basically five chapters to go through. The first chapter
introduces about the project that will be implemented which is interfacing of USB
Device with LabVIEW Software, including the background of study which discussing
4

about the related field upon the project. Next, the problem of statement regarding to the
project, objective needed to be achieved and related scope.

The second chapter will discuss the research done over the related field of the
project which mainly about the study of Universal Serial Bus (USB) architecture, PIC
18F4550 microcontroller, NI-VISA and also LabVIEW software to design the GUI to be
interfaced with the hardware.

Chapter 3 is about the methodology taken in order to achieve the objectives


stated. Basically, the project involves on programming the PIC 18F4550 using MPLab
IDE (using USB firmware), making a USB interface between the device and PC host.
After that, the USB device will be interfaced with the LabVIEW application using NI-
VISA and lastly designing a graphical user interface (GUI) using LabVIEW version 9.

Next is Chapter 4 which will discuss about the results obtained for the project
and some of the discussions of the results. The results are the USB interface
implementation and the GUI application for LabVIEW software. Lastly, Chapter 5 will
conclude all of the findings and some recommendations for future developments.
5

CHAPTER 2

LITERATURE REVIEW

2.1 Universal Serial Bus

Universal Serial Bus or commonly known as USB is a very famous and standard
PC connection peripheral. Each PCs, Laptops, PDAs and electronic devices are
equipped with the USB port for easy connection between the devices. Intel Corporation
[12] stated that,

“Universal Serial Bus (USB) is a set of connectivity specifications developed by


Intel in collaboration with industry leaders. USB allows high-speed, easy
connection of peripherals to a PC. When plugged in, everything configures
automatically. USB is the most successful interconnect in the history of personal
computing and has migrated into consumer electronics (CE) and mobile
products.”
6

USB allowing the devices to be connected and disconnected easily without


rebooting or restarting the PC, just using plug-and-play capabilities. Devices such as
mice, keyboard, printers, flash drives and many more devices have come with a built in
USB plug and user just needs to connect them with any USB port available at the PC.
Nowadays, any electronic device that uses PC connection will be equipped with the
USB module.

USB is a master/slave, half duplex, timed communication bus system that can
connect close peripherals and hubs to a compatible PC. The device connected on the
USB bus will be sent a data packets created by the device drivers by a PC’s software
programs. It supports every peripheral that can be connected to PC [2].

Figure 2.1 USB Type A Plug (Commonly Used USB Plug)


7

2.1.1 USB Architecture

The USB is based on a 'tiered star topology' in which there is a single host
controller and up to 127 'slave' devices. The host controller is PC and the slaves are the
USB devices which can be connected to USB port or USB hubs. The USB hubs are used
when there is not enough USB port for the USB connection. The hub can be plugged
into another hub and so on however the maximum number of tier allowed is six.

All the communications on the USB bus are initiated by the host (PC) meaning
that, only PC can enumerate the communication with its USB device connected to it.
The USB device cannot initiate a transfer, but must wait to be asked by the host PC to
transfer data. The only exception to this is when a device has been put into 'suspend' (a
low power state) by the host then the device can signal a 'remote wakeup'.

2.1.2 USB Transactions

Transactions are simple transfer of data which are built using packets. The
packets are the smallest element of data transmission. The packet can be categorized by
its format. There are four types of packet format which are token packet, data packet,
handshake packet and SOF (Start of Frame) packet. Each of the packets has its own
function and the difference between them is based on the PID (Packet Identifier) the
packet starts with (refer Table 2.2).

A successful transaction is a sequence of three packets which perform a simple


but secure data transfer. There are three types of transactions which are OUT
transaction, IN transaction and SETUP transaction with four different ways to transfer
8

the data (data flow types). OUT is always mean from host to device while IN means
from device to host. All of the transactions are met at the endpoints. The endpoints are
the source or sink of data. A device can have up to 16 IN and 16 OUT endpoints. Each
of endpoints is connected to pipes to transfer the data.

Table 2.1: Type of Packet Format with PID Values


9

2.1.3 Data Flow Types

There are four types of data transfer and each of the data flow (transfer) types is
made by more than one or more transaction type. They are bulk transfer, isynchronous
transfer, interrupt transfer and control transfer.

Bulk transfer is used to transfer large amounts of data, as fast as possible. The
host will schedule bulk transfer after the other transfer types has been allocated. If an
OUT endpoint has been defined to use bulk transfer then the host will transfer the data
through it. Similarly for IN transaction, if the IN endpoint is defined to use bulk transfer.

Isynchronous transfer is used for applications such as audio data transfer where it
is important to maintain the data flow. Compared to bulk transfer, isynchronous transfer
has a guaranteed bandwidth. Isynchronous packet may contain up to 1023 bytes at full
speed or 1024 bytes at high speed and it is not allowed at low speed data transfer.

Interrupt transfer is used when we need to regularly update any changes in the
device status. For application example is mouse or a keyboard. It is regularly scheduled
the IN and OUT transactions and typically the host will fetch only one packet at an
interval. Interrupt packets can have any size from 1 to 8 bytes at low speed, 1 to 64 bytes
at full speed and 1 to 1024 bytes at high speed.

The last data flow type is control transfer which is a bi-directional transfer
because it uses both IN and OUT endpoints. Each of USB devices must have this type of
transfer as the control transfer will be used for initial configuration of the device
(enumeration). It uses special endpoints which are Endpoint 0 that is made of the
combination of Endpoint 0 OUT and Endpoint 0 IN. They may be used (on the same
endpoints) after configuration as part of the device-specific control protocol, if required.
10

During enumeration process, the host will retrieve vendor ID, product ID and other
information using control transfer. This data is retrievable as a group of standard
requests for testing whether communication is working or not. The standard request can
be found in the USB specifications (refer Table 2.3).

Table 2.2: Characteristics and Applications of Data Transfer Types

Transfer Type Characteristics Applications

Control -Up to 15.8MB/s Everything

-Every Device must


support these

-Used for Enumeration

-Extendable : Custom
functions

Interrupt -Up to 49MB/s HID (mouse, Keyboard)

-Asynchronous

-Guaranteed low latency

-Guaranteed throughput

Isochronous -Up to 49MB/s Audio

-High speed Video

-No Error-correction

-Guaranteed bandwidth

Bulk -Up to 53MB/s Test & Measurement

-High speed (on unused Mass Storage


bus)
11

-Error Correction

-Low priority on bus

Table 2.3: USB Specifications (Partial)


12

2.1.4 USB 2.0 and USB 3.0

Nowadays, USB has become a specified industry-standard extension to the PC


architecture. Many applications use the USB technology especially in industrial and
business areas that enable a rapid development of USB. The current USB technology
uses a standard hi-speed USB 2.0 with the data rate up to 480Megabits per second. The
USB 2.0 architecture would define the following criteria [3],

 Ease-of-use for PC Peripheral expansion


 Low-cost solution that supports transfer rates up to 480 Mb/s
 Full support for real-time data for voice, audio, and video
 Protocol flexibility for mixed-mode isochronous data transfer and
asynchronous messaging
 Integration in commodity device technology
 Comprehension of various PC configurations and form factors
 Provision of a standard interface capable of quick diffusion into product
 Enabling new classes of devices that augment the PC’s capability
 Full backward compatibility of USB 2.0 for devices built to previous
versions of the specification

The next USB standards will be USB 3.0 with faster speed and low power
consumption. Intel [11] gives some review of USB 3.0,

“Released in November 2008, the USB 3.0 specification provides performance


increases to data transfer speeds and improved power efficiency, while retaining
backward compatibility. People can still connect USB 1.0 and USB 2.0 devices
through USB 3.0 ports on upcoming PCs and other devices. Much more exciting
though is what happens when USB 3.9 compliant devices are connected to a USB
3.0 port using the new USB 3.0 cable. Performance is up to 10 times faster than
13

USB 2.0. The commercial name for USB 3.0 is “SuperSpeed USB” and PC and
devices using this specification should be available by 2010.”

2.1.5 Physical Connection of USB

There are several types of USB connector but the common plug used are the
standard type A and type B as in Figure 2.2. A USB cable consists of a four-wire cable
to connect the device with the PC host. One pair of twisted-pair wire is the differential
data lines (D+ and D-) while the other two lines are 5V supply (VCC) and GND [5].

Table 2.4: USB Pin-Out Connections

Contact Signal Name Description Typical


Number Cable Colour

1 Vcc 5VDC Red

2 D- Data- White

3 D+ Data+ Green

4 GND Ground Black


14

Figure 2.2 USB Pin-out for Standard USB Plug A and Plug B

When a device is connected to a USB port, the port will immediately determine
the speed of the device by looking at the data lines D- and D+. The high speed device
will pull the data line D+ to high and if the data line D- goes high, the port knows that
the connected device is a low-speed device. If both voltages fall below 0.8V for more
than 2.5 microseconds, the port will assume the device is being disconnected. If both
voltages rise up to 2.5V for more than 2.5 microseconds, the device is being plugged in
[2].

2.1.6 USB Software Driver

The USB software driver handles the USB interface between the USB devices,
the device drivers and host hub driver. It receives the information of the USB device
during the device configuration and tells the hub controller on how to communicate with
the device [2]. Microchip provides a number of application specific resources, such as
USB firmware and driver support [6].
15

2.1.7 Device Drivers

Every device that has the USB interface needs to have a device driver that will
load into a PC. It is a software interface between the external USB device and the
application software, the USB software driver and the host hub controller driver [2]. A
device driver simplifies programming by acting as translator between the hardware
device with the applications or operating system.

The application software will read or receive the signals or data from the USB
device through the device driver. The device driver needs to be created together with the
USB device on its operating system.

However, to create a device driver needs a deep understanding of the device and
both of its hardware and software operations. Thus the task of writing drivers usually
falls to software engineers who work for hardware-development companies. This is
because they have better information than most outsiders about the design of their
hardware.

2.2 Graphical User Interface and LabVIEW

Graphical User Interface or GUI is a friendly user interaction with software


programs/applications such as computers, PDAs, MP3 players, household appliances
and office equipments. It is more to graphical and visual indicators rather than typing or
text commands.
16

There are many software that can develop a GUI with whatever function needed
to be implemented such as Visual Basic, Qt Creator and also LabVIEW. These software
offer the GUI design by full visual programming language or half visual programming
language and half programming code language. Other software such as Basic C and C++
offer full programming code writing of GUI design that is usually used by a
programmer.

LabVIEW is a short form for Laboratory Virtual Instrument Engineering


Workbench which used a full virtual programming language [7]. This software is
common software used for data acquisition, instrument control and automation control
because of its key feature such as simple network communication, turnkey
implementation of common communication protocols (RS232, GPIB, etc.), powerful
toolsets for process control and data fitting, fast and easy user interface construction and
an efficient code executive environment [7].

Figure 2.3 Example of LabVIEW GUI


17

2.2.1 NI-VISA

NI-VISA stands for National Instrument-Virtual Instrument Software


Architecture. It is one of the National Instrument software together with LabVIEW
software. NI-VISA is a high-level API mainly used to communicate with a USB device.
It is platform, bus and environment independent which means the same API
(Application Programming Interface) is used regardless the operating system used to
communicate the USB device with LabVIEW [1].

NI-VISA provides some functions such as NI-VISA Read and Write to be used
as commands for interfacing. There are two types of classes resources supported by
VISA which are USB INSTR and USB RAW. These classes will determine the type of
USB device that we want to communicate with LabVIEW software and each type will
use different protocols. USB INSTR resource class is for instrument control while USB
RAW is a USB device that uses its own communication protocol defined by the
manufacturer. For the USB device used in this project, the type of resource class is USB
RAW device.

It is more complicated to communicate with USB RAW device as it has its own
protocol. As mentioned earlier, USB used four types of communications which are
control, interrupt, bulk and isynchronous endpoints. However, NI-VISA only supports
for three types of communication that are control, bulk and interrupt transfer types.
When NI-VISA detects the USB device, it automatically scans for the lowest available
endpoint for each type [8].
18

2.3 PIC Microcontroller

Microcontroller is a small computer on a single integrated circuit that contains a


processor core, memory and programmable input/output peripherals designed for
embedded system applications. Embedded system is very sophisticated that requires
minimal memory and program length, no operating system and less software
complexity.

Actually, in our daily life, we are interacting with the devices that embedded
with microcontrollers inside. For example, washing machines, microwaves, radios, cell
phones and lot more. Consumer appliances aren’t the only things that contain
microcontrollers [9]. Robots, machinery, aerospace designs and other high-tech devices
are also built with microcontrollers [9].

PIC stands for Programmable Interface Controller originally developed by


General Instrument’s Microelectronic Division. It is a popular for both industrial and
personal purposes because of its lower cost, wide availability and serial programming
capability [10]. PIC need to be programmed in order to operate the designed function.
Some of the software that can be used for the PIC programming are MikroC, MPlab and
ICSP.

PIC microcontroller has many families that categorized due to its function,
ability and features. The PIC 18 series is a popular PIC microcontroller with many
applications and functions. The PIC18F microcontrollers offer cost efficient solutions
for general purpose applications written in C that use a real-time operating system
(RTOS) and require a complex communication protocol stack such as TCP/IP, CAN,
USB, or ZigBee [1]. Its features include high pin count, high density and complex
applications.
19

2.3.1 PIC 18F4550

The PIC 18F4550 supports USB interface directly which contains a full speed
and low speed compatible USB interface that allows communication between the host
PC and the devices that contain the microcontroller [1]. This PIC only support USB 2.0
features only. The addition of the USB module, with its unique requirements for a stable
clock source, make it necessary to provide a separate clock source that is compliant with
both USB low-speed and full-speed specifications [6]. When the PIC18F4550 is used 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 [6].

Figure 2.4 PIC 18F4550 USB Interface

From the figure above, the pins 23 and 24 are used for USB transactions. Pin 23
is connected to D- data line and pin 24 is connected to D+ data line. From Figure 2.4, the
PIC18F4550 above is a 28-pin. PIC18F4550 has five different types of chips according
to the number of pins that the chip possesses and their functions. There are 28-Pin PDIP,
SOIC, 40-Pin PDIP, 44-Pin TQFP and 44-Pin QFN. For USB module operation, it
requires three control registers and twenty-two registers for USB transactions [1].
20

Figure 2.5 44-Pin TQFP PIC18F4550 Microcontroller

Figure 2.6 PIC18F4550 Microcontroller USB Overview


21

2.4 MPLab IDE Software

MPLab IDE software is free, integrated toolset used to program the PIC
microcontroller for the development of embedded applications. The free MPlab
integrated development environment from Microchip supports software development for
these microcontrollers and includes free USB-software stacks and USB-class drivers that
developers can use with the microcontrollers [4]. The USB-host-stack, device- stack,
and class drivers are available as full source code as a download from Microchip [4].

The latest version of MPLab software is version 8. MPLab software consists of


several free software components such as application development, hardware emulation
and debugging. It is a 32-bit application on operating system like Microsoft Windows.
For application development, both assembly and C programming languages can be used
with MPLab IDE.
22

CHAPTER 3

METHODOLOGY

3.1 Project Overview

This project is basically consists of three parts which are hardware, firmware and
software (GUI). The hardware is already exists which is an electronic nose called
Portable e-Mucosa. The USB firmware is modified from Microchip source code
example and the Graphical User Interface is designed using LabVIEW software.

Figure 3.1 Project Block Diagram


23

Figure 3.1 shows the project block diagram which consists of USB device
(Portable e-Mucosa) connecting to LabVIEW application via a USB cable. The
methodology approach to achieve the goals for this project is simplified in Figure 3.2.

USB Device
1) Build a USB firmware for the device using 2) Burn the program code using ICD2
MPLab Software (Microchip) programmer

Interfacing

3) Interface the USB device with NI-VISA software

Labview Application
6) Send data from USB devise to the Labview
5) Build a Labview User Application
application using control transfer

Figure 3.2 Methodology Approach

3.2 Hardware (USB Device)

Portable e-Mucosa is used for mimicking human olfactory system. This device
can discriminate between simple odours such as ethanol, ethyl acetate and acetone or
complex odours such as cinnamon, ylang ylang lavender and lemon grass essential oils.
It comprises of 3 sensor arrays each containing 200 carbon black composite
24

chemoresistive sensors which making the total of 600 sensors to react with the analytes
tested. The data which are the response from the gas sensors will be collected with the
data acquisition system built in the device. The data acquisition system of the PeM
supports both multimedia memory card and USB for easy connection with the PC.

Figure 3.3 Portable e-Mucosa

For this project, we will only focus on the USB module built in the device. This
device has been equipped with USB circuitry with PIC18F4550 microcontroller and the
USB module has been tested to be working fine. The PIC18F4550 microcontroller inside
the Portable e-Mucosa was programmed to be functioned as a USB device.
25

3.2.1 PIC18F4550

The type of PIC18F4550 microcontroller used for this project is 44-pins TQFP.
This PIC contains of 44 input/output pins and the pins for USB data lines are pin 42 (D-)
and pin 43 (D+) as in Figure 3.2.

Figure 3.4 Input/Output Pins for 44-pin TQFP PIC18F4550

There are five ports for analog or digital input and output which defined as Port
A, Port B, Port C, Port D and Port E. All of these ports had been used for the data
acquisition of the electronic nose. Hence, this project did not concern on the input output
port of the device instead of the data lines only.
26

3.3 USB Firmware

In order to design the firmware for USB implementation, the manufacturer of the
microcontroller, Microchip Inc. has provided firmware example for PICDEM FS USB
Demo Board which contains all the USB specifications and requirements for a USB
device. This firmware example consists of everything a USB device needs, hence some
modification was made to suit with the project requirement. The firmware is designed
using MPLab IDE software which is manufactured by Microchip Inc. and the complete
firmware codes will be burnt into the PIC microcontroller selected. There is other
software that performs similar functions which is MikroC software by Mikroelektronika
for microcontroller programming purposes. Both of the software used different
programming language.

At first, the USB device has been developed using MikroC software. The
firmware is designed base on the MikroC library for Human Interface Device (HID) and
USB developments. However, once the USB device is connected to a PC host via a USB
cable, it cannot be detected at all. Hence, the USB firmware designed is changed to
MPLab programming language.

For the firmware designed using MPLab IDE software, the code has been
modified by removing unused functions such as power sensing, some code definitions
and source code that are specific to the PICDEM FS USB Demo application such as
temperature sensor, potentiometer and board-depending configurations. The remaining
functions for the USB device are “ProcessIO” and “Service Request” in the main user
code and the custom USB configuration code. The “ProcessIO” and “Service Request”
functions are for the user to implement their own code according to their requirement
and they also need to modify the input and output configuration.
27

Figure 3.5 Snippet Preview of MikroC PIC18F4550 USB-HID Firmware


28

Figure 3.6 MPLab IDE Window with Snippet Code of the USB Firmware

3.3.1 USB Firmware into PIC

Once the codes have been successfully generated with no error, the codes will be
compiled using Microchip C18 Compiler. The code will be downloaded to PIC18F4550
using ICD (In-Circuit Debug) 2 Programmer in Figure 3.8. The ICD 2 Programmer is
connected to the PC using USB cable and it is also connected to the target circuit
(hardware development) through the In Circuit Serial Programming (ICSP) [10]
29

connector. ICSP gives a convenient way to program the microcontroller chip without
removing the chip from the development board. Figure 3.7 shows the ICSP port
connection.

ICSP connector consists of 6 connections which are:

1. VPP – Programming voltage (usually 13V)


2. VCC – Power (usually 5V)
3. GND – Ground (0V)
4. PGD – Usual port for data transfer
5. PGC – Usual port for clock
6. PGM – Usual port for LVP enable

Figure 3.7 ICSP Connector


30

Figure 3.8 Microchip MPLab ICD 2 Debugger

3.4 Interfacing of LabVIEW Software Using NI-VISA

After a USB device has been successfully created, it needs to be interfaced with
LabVIEW software so that they can communicate with each other. In order to interface
the device with LabVIEW software, NI-VISA software was used. There are two steps
taken in order to configure the USB device with NI-VISA.
31

• Create INF file using Driver development


Wizard
1

• Install INF file and USB device


2

Figure 3.9 USB Device and NI-VISA Configuration Steps

By referring to Figure 3.9, the INF file is created by using Driver Development
Wizard. This step is to tell the operating system (Windows) to use NI-VISA as the
default driver for the device. The wizard gathers the information that is necessary to
allow NI-VISA to control the USB device. The wizard will generate an INF file for use
with the compatible Windows.

Once the INF file is generated at the specific path, the file was installed followed
by installing the device driver. In order to install the device driver, once the USB device
is connected to the USB port, Windows will automatically search for the device driver
and will suggest the default driver to be used with the device. By default, the device
driver used for the USB device was the driver provided by Microchip Inc. The
Microchip Inc. driver is for general used meaning that any USB device created by using
PIC microcontroller can use the driver provided by the manufacturer.

Hence, in order to use NI-VISA as the default driver, the device driver was
updated in the Device Manager window. Now, the USB device is ready to communicate
with LabVIEW application.
32

Figure 3.10 Driver Development Wizard

3.5 LabVIEW Application (GUI)

Once the USB firmware has been completely done, the LabVIEW design process
was took place. In order to design the LabVIEW GUI, we need to determine the type of
USB transfer to be used. For this project, the type of transfer used is control transfer
because all of the USB device use control transfer during enumeration process.
33

The LabVIEW application was designed to test the communication between the
USB device and LabVIEW software. A host PC will retrieve vendor ID, product ID and
other information via control transfer during the enumeration. This data is retrievable as
a group of standard requests. Each and every USB device will respond to the standard
requests in order to test whether the communication is working or not.

The standard requests that we can obtain from a USB device can be seen in Table
3.1 while the request type can be seen in Table 2.3 in Chapter 2.

Table 3.1: USB Specification Request

Hence, a flowchart has been designed to understand the flow of the LabVIEW
application design process.
34

START

USB device initialization

NO
USB RAW device connected?

YES

Open Session

Define Request Type, Request,


Value, Index and Buffer Value

NO
All values inserted valid?

YES

Transfer data according


to the user request to data ERROR
USB Specification
Standar Requests array (Control In Buffer)

Return the data length


RETURN value

STOP

Figure 3.11 Flowchart of LabVIEW Application


35

In order to establish the communication between the USB device and LabVIEW
application, a VISA function need to be used which is VISA USB Control In. This
function performs a USB control pipe transfer from the USB device and takes the values
of the data payload in the setup stage of the control transfer as parameters. This function
reads the data buffer for a data stage for control transfer.

Figure 3.12 VISA USB Control In Function

Figure 3.13 Block Diagram Part A


36

Figure 3.14 Block Diagram Part B

Figure 3.15 Full Block Diagram


37

In LabVIEW software, there are two windows to be used for the design process.
First window is the Front Panel window and the second window is the Block Diagram
window. Both of the windows have different functions. The front panel window shows
the actual GUI and actual user application once the design is complete while the block
diagram shows the behind code that controls the program.

From Figure 3.13, the part A of the block diagram shows the functions for
choosing the USB RAW device, open session for the USB device selected, control in
push button, clear push button, an array to combine all the elements and a merge error of
I/O clusters for different functions. Figure 3.14 is the part B of the block diagram
consists of the VISA USB Control In function that needs to be connected with the input
control such as Request Type, Request, Value, Index and Length that use numeric
control functions. All of the input controls contain the value as in the USB specification
tables. Hence, the user just need to type the correct standard request values specifies.
38

CHAPTER 4

RESULT AND DISCUSSION

4.1 USB Device

A USB device has been successfully created by using the modified USB
firmware. Once the device is connected to one of the USB port on the PC host via a USB
cable, Windows asks to locate and install the device driver.

Figure 4.1 Found New Hardware Wizard


39

It means that a new device has been identified and the need to install the device
driver in order to locate and communicate with the device in the operating system. As
mentioned earlier, the device driver for this device is provided by Microchip Inc. and
later updated by NI-VISA to interface with LabVIEW software. Once the device driver
has been successfully installed, the device can be attached and detached from the USB
port anytime like a normal USB device like flash drive.

Figure 4.2 Detaching the USB Device

4.2 USB Device with LabVIEW Software

By referring to Figure 4.3, the device also appears in the Device Manager
explorer as one of the NI-VISA USB devices. This means that the USB device also
successfully configured as one of the device to be used with LabVIEW software. All of
the USB devices that has already configured by NI-VISA will appear in Measurement
and Automation Explorer (MAX). MAX is used to manage all the devices and
interfaces, to configure the National Instrument hardware and software, use as a backup
or duplicate configuration data, view devices and instruments connected to the system,
40

execute system diagnostics and update the National Instrument software. Hence, the
USB device is ready to be tested for the communication with LabVIEW software.

Figure 4.3 Device Manager Explorer


41

Figure 4.4 Measurement and Automation Explorer

4.3 LabVIEW Application (GUI)

As mentioned earlier, the LabVIEW application is designed to test the


communication of the USB device with LabVIEW software. Figure 4.5 shows the
Graphical User Interface designed for the communication test.
42

Figure 4.5 LabVIEW User Application

By referring to Figure 4.5 above, the USB RAW VISA resource name function is
used to choose a VISA USB device that has been configured earlier. The user needs to
click the drop down button to choose the USB device. If there is no device connected,
there will be no device in the list.
43

Figure 4.6 USB RAW VISA Resource Name List

Once the USB device has been chosen, the user needs to click the ‘Open Session’
push button to start the communication session. After that, the user needs to insert the
standard request parameters to establish the data transfer between the USB device and
LabVIEW application.

Figure 4.7 Request Type, Request, Value and Index for Standard Request

Remember that the data will be transferred only when the host starts the
enumeration. Hence, the host PC needs to ask the device on what data should be
transferred. In order to test whether the communication is working or not, we can try
asking the device to send the device descriptor. From the USB specification tables, to
request for device descriptor, the request type value is 80, the request is 6, the value is
44

100 and the index is 0. Once the values have been inserted, the ‘Control In’ push button
is clicked so that the transaction is established and the USB device will send the
descriptor of the device.

Figure 4.8 Data Transferred by the USB Device

Figure 4.8 shows the data that has been transferred. This means that the
communication between the USB device and the LabVIEW application is working. The
data transferred is the product ID and the vendor ID of the device. Every USB device
need to have the product ID and the vendor ID. These numbers identify the device when
we install it and address the device when we want to communicate with it [1]. Both
numbers are 16-bit hexadecimal numbers and should be provided by the device
manufacturer [1]. For this project, the product ID and the vendor ID is given by
Microchip Inc. which are 04D8 for the vendor ID and 000C for the product ID. As we
can see from the Figure 4.8, the product ID and the vendor ID are appeared in the
‘Control In Buffer’ fields. The ‘Control In Buffer’ will show and hold the data that has
been transferred and the total data that has been transferred is shown in ‘Length
returned’ numeric control.
45

Other functions that the user can interact are the ‘Clear Control In Buffer Text’
and ‘STOP’ buttons. The ‘Control In Buffer’ fields is cleared when the user click the
clear function and the LabVIEW application is stopped when the stop button is
executed. Hence, the result shows that the communication between the USB device and
the LabVIEW application has been established.
46

CHAPTER 5

CONCLUSION

5.1 Project Summary

In conclusion, the interfacing of the USB device created has been successfully
implemented. The USB firmware used is able to create the USB device to be used for
the interfacing with PC and LabVIEW software. Once the USB device is connected to
one of the USB port on the PC, the device has been recognized and ready for the
communication or data transfer with LabVIEW software application.

However, the implementation for transferring any data for example for data
acquisition system requires a lot of understanding in the USB architecture. The USB
firmware design needs many considerations on both GUI application and hardware
interface. Hence, the first objective which is to implement an interfacing between a USB
device and LabVIEW software has been successfully achieved while the other objective
is still can be improved.
47

5.2 Problems Encountered

For this project, there are several problems encountered for the project
accomplishment. Firstly, the USB firmware for USB architecture which is related with
the programming for PIC18F4550 is quite complex and hard to understand. For a first
time programmer needs a full understanding of the firmware which related to both
hardware and software interface. Hence to design USB firmware for data acquisition
needs to carry out more research.

The other problem is the LabVIEW GUI application designed cannot received all
of the USB standard requests meaning that, it only views the product and vendor ID of
the USB device (device descriptor). There are several more on the standard request
which the user can get for examples the device configuration, device interface and
status.

5.3 Recommendation

For future development, there are several recommendations to improve the


project. Firstly, the USB firmware can be modified and upgraded to suit the hardware
and software requirements. For example, if we want to upgrade the hardware to perform
specific task or function, we need to modify the firmware code so that the task or
function can be performed.

Lastly, the design of the GUI application can be upgraded and modified based on
the application of the USB device needs to perform. This project only provides a way on
48

how to interface a USB device with labVIEW software. Hence, more studies should be
done to improve this kind of project.
49

REFERENCES

1. Ibrahim, D., Advanced PIC microcontroller projects in C: from USB to RTOS


with the PIC18F series. 2008, Oxford: Newnes.

2. Park, J. and S. Mackay, Practical data acquisition for instrumentation and


control systems. 2003, Burlington: Newnes.

3. Universal Serial Bus Specification, in Universal Serial Bus Specification


Revision 2.0, J. Garney, Editor. 2000, Compaq Computer Corporation,

Hewlett-Packard Company, Intel Corporation, Lucent Technologies Inc,

Microsoft Corporation, NEC Corporation, Koninklijke Philips Electronics N.V.


p. 11.

4. Cravotta, R. (2008) PIC architecture supports USB across 8-, 16-, and 32-bit
devices. EDN EUROPE.

5. Buchanan, W., Computer Busses. USB and Firewire. 2000: CRC Press.

6. PIC18F2455/2550/4455/4550 Data Sheet. 2006, Microchip Technology Inc.

7. Elliot, C., et al., National Instruments LabVIEW, in A Programming


Environment for Laboratory Automation and Measurement. 2007: San
Francisco. p. 1.

8. USB Instrument Control Tutorial, National Instrument. p. 1.

9. Lindsay, A., What's a Microcontroller. Student Guide Version 2.2. 2004:


Parallax Inc.

10. Che Harun, F.K., Mimicking Human Olfactory System: A Portable e-Mucosa.
2009, University of Warwick.
50

11. Intel and USB. Helping Make it Easier to Connect Devices to PC [cited 2010 6
October 2010]; Available from:
www.intel.com/standards/case/Intel_and_USB_Case_Study.pdf.

12. Universal Serial Bus (USB). [cited 2010 6 October 2010]; Available from:
http://www.intel.com/technology/usb/.
51

APPENDIX A

USB Firmware of PIC18F4550 Microcontroller

/*****************************************************************
* Microchip USB C18 Firmware Version 1.2
*******************************************************************
* FileName: io_cfg.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
* FS USB Plug In Module board.
******************************************************************/
#ifndef IO_CFG_H
#define IO_CFG_H
/** I N C L U D E S *************************************************/
#include "autofiles\usbcfg.h"
/** T R I S *********************************************************/
#define INPUT_PIN 1
#define OUTPUT_PIN 0
/** U S B ***********************************************************/
#define tris_usb_bus_sense TRISAbits.TRISA1 // Input
#define usb_bus_sense 1
#define tris_self_power TRISAbits.TRISA2 // Input
#define self_power 1

/*******************************************************************
* Microchip USB C18 Firmware Version 1.0
********************************************************************
* FileName: typedefs.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
*******************************************************************/
#ifndef TYPEDEFS_H
#define TYPEDEFS_H
52

typedef unsigned char byte; // 8-bit


typedef unsigned int word; // 16-bit
typedef unsigned long dword; // 32-bit
typedef union _BYTE
{
byte _byte;
struct
{
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
};
} BYTE;
typedef union _WORD
{
word _word;
struct
{
byte byte0;
byte byte1;
};
struct
{
BYTE Byte0;
BYTE Byte1;
};
struct
{
BYTE LowB;
BYTE HighB;
};
struct
{
byte v[2];
};
} WORD;
#define LSB(a) ((a).v[0])
#define MSB(a) ((a).v[1])
53

typedef union _DWORD


{
dword _dword;
struct
{
byte byte0;
byte byte1;
byte byte2;
byte byte3;
};
struct
{
byte bLow;
byte bHigh;
//byte bUpper;
};
word _word; // bLow & bHigh

//pFunc _pFunc; // Usage: ptr.pFunc(); Init: ptr.pFunc =


&<Function>;

byte* bRam; // Ram byte pointer: 2 bytes pointer pointing


// to 1 byte of data
word* wRam; // Ram word poitner: 2 bytes poitner pointing
// to 2 bytes of data

rom byte* bRom; // Size depends on compiler setting


rom word* wRom;
//rom near byte* nbRom; // Near = 2 bytes pointer
//rom near word* nwRom;
//rom far byte* fbRom; // Far = 3 bytes pointer
//rom far word* fwRom;

} POINTER;

typedef enum _BOOL { FALSE = 0, TRUE } BOOL;

#define OK TRUE
#define FAIL FALSE

#endif //TYPEDEFS_H
54

/*******************************************************************
* Microchip USB C18 Firmware Version 1.0
********************************************************************
* FileName: usb.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
*******************************************************************/
#ifndef USB_H
#define USB_H

#include "autofiles\usbcfg.h"
#include "system\usb\usbdefs\usbdefs_std_dsc.h"
#include "autofiles\usbdsc.h"

#include "system\usb\usbdefs\usbdefs_ep0_buff.h"
#include "system\usb\usbmmap.h"

#include "system\usb\usbdrv\usbdrv.h"
#include "system\usb\usbctrltrf\usbctrltrf.h"
#include "system\usb\usb9\usb9.h"

#if defined(USB_USE_GEN) // See autofiles\usbcfg.h


#include "system\usb\class\generic\usbgen.h"
#endif

#endif //USB_H

/******************************************************************
* Microchip USB C18 Firmware Version 1.0
*******************************************************************
* FileName: usb9.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
******************************************************************/
#ifndef USB9_H
#define USB9_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"
55

/** D E F I N I T I O N S ****************************************************/
/******************************************************************
* Standard Request Codes
* USB 2.0 Spec Ref Table 9-4
******************************************************************/
#define GET_STATUS 0
#define CLR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADR 5
#define GET_DSC 6
#define SET_DSC 7
#define GET_CFG 8
#define SET_CFG 9
#define GET_INTF 10
#define SET_INTF 11
#define SYNCH_FRAME 12
/* Standard Feature Selectors */
#define DEVICE_REMOTE_WAKEUP 0x01
#define ENDPOINT_HALT 0x00
*******************************************************************/
#define mUSBCheckAdrPendingState() if(usb_device_state==ADR_PENDING_STATE)\
{ \
UADDR = SetupPkt.bDevADR._byte; \
if(UADDR > 0) \
usb_device_state=ADDRESS_STATE; \
else \
usb_device_state=DEFAULT_STATE; \
}//end if
/** E X T E R N S ************************************************************/

/** P U B L I C P R O T O T Y P E S *****************************************/
void USBCheckStdRequest(void);

#endif //USB9_H

/******************************************************************
* Microchip USB C18 Firmware Version 1.2
********************************************************************
* FileName: usbcfg.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
******************************************************************/
56

#ifndef USBCFG_H
#define USBCFG_H

/** D E F I N I T I O N S *******************************************/
#define MAX_NUM_INT 1 // For tracking Alternate Setting
#define EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes.
// There is very little advantage in using
// more than 8 bytes on EP0 IN/OUT, so 8 is the
// recommended value.
/* Parameter definitions are defined in usbdrv.h */
#define MODE_PP _PPBM0
#define UCFG_VAL _PUEN|_TRINT|_FS|MODE_PP

/** D E V I C E C L A S S U S A G E *******************************/
#define USB_USE_GEN
/*
* MUID = Microchip USB Class ID
* Used to identify which of the USB classes owns the current
* session of control transfer over EP0
*/
#define MUID_NULL 0
#define MUID_USB9 1

/** E N D P O I N T S A L L O C A T I O N **************************/
/*
* See usbmmap.c for an explanation of how the endpoint allocation works
*/
/* PICDEM FS USB Demo (using generic usb class template) */
#define USBGEN_INTF_ID 0x00
#define USBGEN_UEP UEP1
#define USBGEN_BD_OUT ep1Bo
#define USBGEN_BD_IN ep1Bi
#define USBGEN_EP_SIZE 64
#define MAX_EP_NUMBER 2 // UEP2
#endif //USBCFG_H

/* PICDEM FS USB Demo (using generic usb class template) */


#define USBGEN_INTF_ID 0x00
#define USBGEN_UEP UEP1
#define USBGEN_BD_OUT ep1Bo
#define USBGEN_BD_IN ep1Bi
#define USBGEN_EP_SIZE 64
#define MAX_EP_NUMBER 2 // UEP2
#endif //USBCFG_H
57

/******************************************************************
* Microchip USB C18 Firmware Version 1.2
*******************************************************************
* FileName: usbctrltrf.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
*******************************************************************/
#ifndef USBCTRLTRF_H
#define USBCTRLTRF_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"

/** D E F I N I T I O N S ****************************************************/
/* Control Transfer States */
#define WAIT_SETUP 0
#define CTRL_TRF_TX 1
#define CTRL_TRF_RX 2
/******************************************************************
/* Short Packet States - Used by Control Transfer Read - CTRL_TRF_TX */
#define SHORT_PKT_NOT_USED 0
#define SHORT_PKT_PENDING 1
#define SHORT_PKT_SENT 2

/* USB PID: Token Types - See chapter 8 in the USB specification */


#define SETUP_TOKEN 0b00001101
#define OUT_TOKEN 0b00000001
#define IN_TOKEN 0b00001001

/* bmRequestType Definitions */
#define HOST_TO_DEV 0
#define DEV_TO_HOST 1

#define STANDARD 0x00


#define CLASS 0x01
#define VENDOR 0x02

#define RCPT_DEV 0
#define RCPT_INTF 1
#define RCPT_EP 2
#define RCPT_OTH 3
58

/** E X T E R N S ************************************************************/
extern byte ctrl_trf_session_owner;

extern POINTER pSrc;


extern POINTER pDst;
extern WORD wCount;

/** P U B L I C P R O T O T Y P E S *****************************************/
byte USBCtrlEPService(void); // Bug Fix - Work around, void->byte
void USBCtrlTrfTxService(void);
void USBCtrlTrfRxService(void);
void USBCtrlEPServiceComplete(void);
void USBPrepareForNextSetupTrf(void);

#endif //USBCTRLTRF_H

/*****************************************************************
* Microchip USB C18 Firmware Version 1.0
*******************************************************************
* FileName: usbdefs_ep0_buff.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
/******************************************************************
* USB Definitions: Endpoint 0 Buffer
******************************************************************/
#ifndef USBDEFS_EP0_BUFF_H
#define USBDEFS_EP0_BUFF_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"
#include "autofiles\usbcfg.h" // usbcfg.h contains required definitions
typedef union _CTRL_TRF_SETUP

{ /** Array for indirect addressing ****************************************/


struct
{
byte _byte[EP0_BUFF_SIZE];
};
/** Standard Device Requests *********************************************/
struct
59

{
byte bmRequestType;
byte bRequest;
word wValue;
word wIndex;
word wLength;
};
struct
{
unsigned :8;
unsigned :8;
WORD W_Value;
WORD W_Index;
WORD W_Length;
};
struct
{
unsigned Recipient:5; //Device,Interface,Endpoint,Other
unsigned RequestType:2; //Standard,Class,Vendor,Reserved
unsigned DataDir:1; //Host-to-device,Device-to-host
unsigned :8;
byte bFeature; //DEVICE_REMOTE_WAKEUP,ENDPOINT_HALT
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
};
struct
{ unsigned :8;
unsigned :8;
byte bDscIndex; //For Configuration and String DSC Only
byte bDscType; //Device,Configuration,String
word wLangID; //Language ID
unsigned :8;
unsigned :8; };
struct
{ unsigned :8;
unsigned :8;
BYTE bDevADR; //Device Address 0-127
byte bDevADRH; //Must equal zero
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8; };
60

struct
{ unsigned :8;
unsigned :8;
byte bCfgValue; //Configuration Value 0-255
byte bCfgRSD; //Must equal zero (Reserved)
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8; };
struct
{
unsigned :8;
unsigned :8;
byte bAltID; //Alternate Setting Value 0-255
byte bAltID_H; //Must equal zero
byte bIntfID; //Interface Number Value 0-255
byte bIntfID_H; //Must equal zero
unsigned :8;
unsigned :8;
};
struct
{
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
byte bEPID; //Endpoint ID (Number & Direction)
byte bEPID_H; //Must equal zero
unsigned :8;
unsigned :8;
};
struct
{ unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
unsigned EPNum:4; //Endpoint Number 0-15
unsigned :3;
unsigned EPDir:1; //Endpoint Direction: 0-OUT, 1-IN
unsigned :8;
unsigned :8;
unsigned :8; };
/** End: Standard Device Requests ****************************************/

} CTRL_TRF_SETUP;
61

typedef union _CTRL_TRF_DATA


{
/** Array for indirect addressing ****************************************/
struct
{
byte _byte[EP0_BUFF_SIZE];
};

/** First 8-byte direct addressing ***************************************/


struct
{
byte _byte0;
byte _byte1;
byte _byte2;
byte _byte3;
byte _byte4;
byte _byte5;
byte _byte6;
byte _byte7;
};
struct
{
word _word0;
word _word1;
word _word2;
word _word3;
};

} CTRL_TRF_DATA;

#endif //USBDEFS_EP0_BUFF_H

/******************************************************************
* Microchip USB C18 Firmware Version 1.0
********************************************************************
* FileName: usbdefs_std_dsc.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
/*******************************************************************
* USB Definitions: Standard Descriptors
*******************************************************************/
62

#ifndef USBDEFS_STD_DSC_H
#define USBDEFS_STD_DSC_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"

/** D E F I N I T I O N S ****************************************************/
/* Descriptor Types */
#define DSC_DEV 0x01
#define DSC_CFG 0x02
#define DSC_STR 0x03
#define DSC_INTF 0x04
#define DSC_EP 0x05
/*******************************************************************
* USB Endpoint Definitions
* USB Standard EP Address Format: DIR:X:X:X:EP3:EP2:EP1:EP0
* This is used in the descriptors. See autofiles\usbdsc.c
*******************************************************************/
#define _EP01_OUT 0x01
#define _EP01_IN 0x81
#define _EP02_OUT 0x02
#define _EP02_IN 0x82
#define _EP03_OUT 0x03
#define _EP03_IN 0x83
#define _EP04_OUT 0x04
#define _EP04_IN 0x84
#define _EP05_OUT 0x05
#define _EP05_IN 0x85
#define _EP06_OUT 0x06
#define _EP06_IN 0x86
#define _EP07_OUT 0x07
#define _EP07_IN 0x87
#define _EP08_OUT 0x08
#define _EP08_IN 0x88
#define _EP09_OUT 0x09
#define _EP09_IN 0x89
#define _EP10_OUT 0x0A
#define _EP10_IN 0x8A
#define _EP11_OUT 0x0B
#define _EP11_IN 0x8B
#define _EP12_OUT 0x0C
#define _EP12_IN 0x8C
#define _EP13_OUT 0x0D
#define _EP13_IN 0x8D
63

#define _EP14_OUT 0x0E


#define _EP14_IN 0x8E
#define _EP15_OUT 0x0F
#define _EP15_IN 0x8F

/* Configuration Attributes */
#define _DEFAULT 0x01<<7 //Default Value (Bit 7 is set)
#define _SELF 0x01<<6 //Self-powered (Supports if set)
#define _RWU 0x01<<5 //Remote Wakeup (Supports if set)

/* Endpoint Transfer Type */


#define _CTRL 0x00 //Control Transfer
#define _ISO 0x01 //Isochronous Transfer
#define _BULK 0x02 //Bulk Transfer
#define _INT 0x03 //Interrupt Transfer

/* Isochronous Endpoint Synchronization Type */


#define _NS 0x00<<2 //No Synchronization
#define _AS 0x01<<2 //Asynchronous
#define _AD 0x02<<2 //Adaptive
#define _SY 0x03<<2 //Synchronous
/* Isochronous Endpoint Usage Type */
#define _DE 0x00<<4 //Data endpoint
#define _FE 0x01<<4 //Feedback endpoint
#define _IE 0x02<<4 //Implicit feedback Data endpoint

/** S T R U C T U R E ********************************************************/
/*******************************************************************
* USB Device Descriptor Structure
*******************************************************************/
typedef struct _USB_DEV_DSC
{ byte bLength; byte bDscType; word bcdUSB;
byte bDevCls; byte bDevSubCls; byte bDevProtocol;
byte bMaxPktSize0; word idVendor; word idProduct;
word bcdDevice; byte iMFR; byte iProduct;
byte iSerialNum; byte bNumCfg;
} USB_DEV_DSC;
/******************************************************************
* USB Configuration Descriptor Structure
*******************************************************************/
typedef struct _USB_CFG_DSC
{ byte bLength; byte bDscType; word wTotalLength;
byte bNumIntf; byte bCfgValue; byte iCfg;
byte bmAttributes; byte bMaxPower;
} USB_CFG_DSC;
64

/*******************************************************************
* USB Interface Descriptor Structure
*******************************************************************/
typedef struct _USB_INTF_DSC
{ byte bLength; byte bDscType; byte bIntfNum;
byte bAltSetting; byte bNumEPs; byte bIntfCls;
byte bIntfSubCls; byte bIntfProtocol; byte iIntf;
} USB_INTF_DSC;
/*******************************************************************
* USB Endpoint Descriptor Structure
*******************************************************************/
typedef struct _USB_EP_DSC
{ byte bLength; byte bDscType; byte bEPAdr;
byte bmAttributes; word wMaxPktSize; byte bInterval;
} USB_EP_DSC;
#endif //USBDEFS_STD_DSC_H

/*********************************************************************
* Microchip USB C18 Firmware Version 1.2
*********************************************************************
* FileName: usbdrv.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/
#ifndef USBDRV_H
#define USBDRV_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"
#include "system\usb\usb.h"

/** D E F I N I T I O N S ****************************************************/
/* UCFG Initialization Parameters */
#define _PPBM0 0x00 // Pingpong Buffer Mode 0
#define _PPBM1 0x01 // Pingpong Buffer Mode 1
#define _PPBM2 0x02 // Pingpong Buffer Mode 2
#define _LS 0x00 // Use Low-Speed USB Mode
#define _FS 0x04 // Use Full-Speed USB Mode
#define _TRINT 0x00 // Use internal transceiver
#define _TREXT 0x08 // Use external transceiver
#define _PUEN 0x10 // Use internal pull-up resistor
#define _OEMON 0x40 // Use SIE output indicator
#define _UTEYE 0x80 // Use Eye-Pattern test
65

/* UEPn Initialization Parameters */


#define EP_CTRL 0x06 // Cfg Control pipe for this ep
#define EP_OUT 0x0C // Cfg OUT only pipe for this ep
#define EP_IN 0x0A // Cfg IN only pipe for this ep
#define EP_OUT_IN 0x0E // Cfg both OUT & IN pipes for this ep
#define HSHK_EN 0x10 // Enable handshake packet
// Handshake should be disable for isoch
#define OUT 0
#define IN 1

#define PIC_EP_NUM_MASK 0b01111000


#define PIC_EP_DIR_MASK 0b00000100

#define EP00_OUT ((0x00<<3)|(OUT<<2))


#define EP00_IN ((0x00<<3)|(IN<<2))
#define EP01_OUT ((0x01<<3)|(OUT<<2))
#define EP01_IN ((0x01<<3)|(IN<<2))
#define EP02_OUT ((0x02<<3)|(OUT<<2))
#define EP02_IN ((0x02<<3)|(IN<<2))
#define EP03_OUT ((0x03<<3)|(OUT<<2))
#define EP03_IN ((0x03<<3)|(IN<<2))
#define EP04_OUT ((0x04<<3)|(OUT<<2))
#define EP04_IN ((0x04<<3)|(IN<<2))
#define EP05_OUT ((0x05<<3)|(OUT<<2))
#define EP05_IN ((0x05<<3)|(IN<<2))
#define EP06_OUT ((0x06<<3)|(OUT<<2))
#define EP06_IN ((0x06<<3)|(IN<<2))
#define EP07_OUT ((0x07<<3)|(OUT<<2))
#define EP07_IN ((0x07<<3)|(IN<<2))
#define EP08_OUT ((0x08<<3)|(OUT<<2))
#define EP08_IN ((0x08<<3)|(IN<<2))
#define EP09_OUT ((0x09<<3)|(OUT<<2))
#define EP09_IN ((0x09<<3)|(IN<<2))
#define EP10_OUT ((0x0A<<3)|(OUT<<2))
#define EP10_IN ((0x0A<<3)|(IN<<2))
#define EP11_OUT ((0x0B<<3)|(OUT<<2))
#define EP11_IN ((0x0B<<3)|(IN<<2))
#define EP12_OUT ((0x0C<<3)|(OUT<<2))
#define EP12_IN ((0x0C<<3)|(IN<<2))
#define EP13_OUT ((0x0D<<3)|(OUT<<2))
#define EP13_IN ((0x0D<<3)|(IN<<2))
#define EP14_OUT ((0x0E<<3)|(OUT<<2))
#define EP14_IN ((0x0E<<3)|(IN<<2))
#define EP15_OUT ((0x0F<<3)|(OUT<<2))
#define EP15_IN ((0x0F<<3)|(IN<<2))
66

#define mInitializeUSBDriver() {UCFG = UCFG_VAL; \


usb_device_state = DETACHED_STATE; \
usb_stat._byte = 0x00; \
usb_active_cfg = 0x00;}
#define mDisableEP1to15() ClearArray((byte*)&UEP1,15);
/*
#define mDisableEP1to15() UEP1=0x00;UEP2=0x00;UEP3=0x00;\
UEP4=0x00;UEP5=0x00;UEP6=0x00;UEP7=0x00;\
UEP8=0x00;UEP9=0x00;UEP10=0x00;UEP11=0x00;\
UEP12=0x00;UEP13=0x00;UEP14=0x00;UEP15=0x00;
*/
#define mUSBBufferReady(buffer_dsc) \
{ \
buffer_dsc.Stat._byte &= _DTSMASK; /* Save only DTS bit */ \
buffer_dsc.Stat.DTS = !buffer_dsc.Stat.DTS; /* Toggle DTS bit */ \
buffer_dsc.Stat._byte |= _USIE|_DTSEN; /* Turn ownership to SIE */ \
}

/** T Y P E S ****************************************************************/

/** E X T E R N S ************************************************************/

/** P U B L I C P R O T O T Y P E S *****************************************/
void USBCheckBusStatus(void);
void USBDriverService(void);
void USBRemoteWakeup(void);
void USBSoftDetach(void);

void ClearArray(byte* startAdr,byte count);


#endif //USBDRV_H

/********************************************************************
* Microchip USB C18 Firmware Version 1.0
*********************************************************************
* FileName: usbdsc.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
********************************************************************/

/*********************************************************************
* Descriptor specific type definitions are defined in:
* system\usb\usbdefs\usbdefs_std_dsc.h
********************************************************************/
67

#ifndef USBDSC_H
#define USBDSC_H

/** I N C L U D E S *************************************************/
#include "system\typedefs.h"
#include "autofiles\usbcfg.h"

#include "system\usb\usb.h"

/** D E F I N I T I O N S *******************************************/

#define CFG01 rom struct \


{ USB_CFG_DSC cd01; \
USB_INTF_DSC i00a00; \
USB_EP_DSC ep01o_i00a00; \
USB_EP_DSC ep01i_i00a00; \
} cfg01

/** E X T E R N S ***************************************************/
extern rom USB_DEV_DSC device_dsc;
extern CFG01;
extern rom const unsigned char *rom USB_CD_Ptr[];
extern rom const unsigned char *rom USB_SD_Ptr[];

#endif //USBDSC_H

/*********************************************************************
* Microchip USB C18 Firmware - Generic
*********************************************************************
* FileName: usbgen.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.

********************************************************************/
#ifndef USBGEN_H
#define USBGEN_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"

/** D E F I N I T I O N S ****************************************************/
68

#define mUSBGenRxIsBusy() USBGEN_BD_OUT.Stat.UOWN


#define mUSBGenTxIsBusy() USBGEN_BD_IN.Stat.UOWN
#define mUSBGenGetRxLength() usbgen_rx_len

/** S T R U C T U R E S ******************************************************/

/** E X T E R N S ************************************************************/
extern byte usbgen_rx_len;

/** P U B L I C P R O T O T Y P E S *****************************************/
void USBGenInitEP(void);
void USBGenWrite(byte *buffer, byte len);
byte USBGenRead(byte *buffer, byte len);

#endif //USBGEN_H

/*********************************************************************
* Microchip USB C18 Firmware Version 1.0
*********************************************************************
* FileName: usbmmap.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
********************************************************************/
#ifndef USBMMAP_H
#define USBMMAP_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"

/** D E F I N I T I O N S ****************************************************/

/* Buffer Descriptor Status Register Initialization Parameters */


#define _BSTALL 0x04 //Buffer Stall enable
#define _DTSEN 0x08 //Data Toggle Synch enable
#define _INCDIS 0x10 //Address increment disable
#define _KEN 0x20 //SIE keeps buff descriptors enable
#define _DAT0 0x00 //DATA0 packet expected next
#define _DAT1 0x40 //DATA1 packet expected next
#define _DTSMASK 0x40 //DTS Mask
#define _USIE 0x80 //SIE owns buffer
#define _UCPU 0x00 //CPU owns buffer
69

/* USB Device States - To be used with [byte usb_device_state] */


#define DETACHED_STATE 0
#define ATTACHED_STATE 1
#define POWERED_STATE 2
#define DEFAULT_STATE 3
#define ADR_PENDING_STATE 4
#define ADDRESS_STATE 5
#define CONFIGURED_STATE 6

/* Memory Types for Control Transfer - used in USB_DEVICE_STATUS */


#define _RAM 0
#define _ROM 1

/** T Y P E S ****************************************************************/
typedef union _USB_DEVICE_STATUS
{
byte _byte;
struct
{
unsigned RemoteWakeup:1;// [0]Disabled [1]Enabled: See usbdrv.c,usb9.c
unsigned ctrl_trf_mem:1;// [0]RAM [1]ROM
};
} USB_DEVICE_STATUS;

typedef union _BD_STAT


{ byte _byte;
struct{
unsigned BC8:1;
unsigned BC9:1;
unsigned BSTALL:1; //Buffer Stall Enable
unsigned DTSEN:1; //Data Toggle Synch Enable
unsigned INCDIS:1; //Address Increment Disable
unsigned KEN:1; //BD Keep Enable
unsigned DTS:1; //Data Toggle Synch Value
unsigned UOWN:1; //USB Ownership
};
struct{
unsigned BC8:1;
unsigned BC9:1;
unsigned PID0:1;
unsigned PID1:1;
unsigned PID2:1;
unsigned PID3:1;
unsigned :1;
unsigned UOWN:1; };
70

struct{
unsigned :2;
unsigned PID:4; //Packet Identifier
unsigned :2;
};
} BD_STAT; //Buffer Descriptor Status Register

typedef union _BDT


{
struct
{
BD_STAT Stat;
byte Cnt;
byte ADRL; //Buffer Address Low
byte ADRH; //Buffer Address High
};
struct
{
unsigned :8;
unsigned :8;
byte* ADR; //Buffer Address
};
} BDT; //Buffer Descriptor Table

/** E X T E R N S ************************************************************/
extern byte usb_device_state;
extern USB_DEVICE_STATUS usb_stat;
extern byte usb_active_cfg;
extern byte usb_alt_intf[MAX_NUM_INT];

extern volatile far BDT ep0Bo; //Endpoint #0 BD Out


extern volatile far BDT ep0Bi; //Endpoint #0 BD In
extern volatile far BDT ep1Bo; //Endpoint #1 BD Out
extern volatile far BDT ep1Bi; //Endpoint #1 BD In
extern volatile far BDT ep2Bo; //Endpoint #2 BD Out
extern volatile far BDT ep2Bi; //Endpoint #2 BD In
extern volatile far BDT ep3Bo; //Endpoint #3 BD Out
extern volatile far BDT ep3Bi; //Endpoint #3 BD In
extern volatile far BDT ep4Bo; //Endpoint #4 BD Out
extern volatile far BDT ep4Bi; //Endpoint #4 BD In
extern volatile far BDT ep5Bo; //Endpoint #5 BD Out
extern volatile far BDT ep5Bi; //Endpoint #5 BD In
extern volatile far BDT ep6Bo; //Endpoint #6 BD Out
extern volatile far BDT ep6Bi; //Endpoint #6 BD In
71

extern volatile far BDT ep7Bo; //Endpoint #7 BD Out


extern volatile far BDT ep7Bi; //Endpoint #7 BD In
extern volatile far BDT ep8Bo; //Endpoint #8 BD Out
extern volatile far BDT ep8Bi; //Endpoint #8 BD In
extern volatile far BDT ep9Bo; //Endpoint #9 BD Out
extern volatile far BDT ep9Bi; //Endpoint #9 BD In
extern volatile far BDT ep10Bo; //Endpoint #10 BD Out
extern volatile far BDT ep10Bi; //Endpoint #10 BD In
extern volatile far BDT ep11Bo; //Endpoint #11 BD Out
extern volatile far BDT ep11Bi; //Endpoint #11 BD In
extern volatile far BDT ep12Bo; //Endpoint #12 BD Out
extern volatile far BDT ep12Bi; //Endpoint #12 BD In
extern volatile far BDT ep13Bo; //Endpoint #13 BD Out
extern volatile far BDT ep13Bi; //Endpoint #13 BD In
extern volatile far BDT ep14Bo; //Endpoint #14 BD Out
extern volatile far BDT ep14Bi; //Endpoint #14 BD In
extern volatile far BDT ep15Bo; //Endpoint #15 BD Out
extern volatile far BDT ep15Bi; //Endpoint #15 BD In

extern volatile far CTRL_TRF_SETUP SetupPkt;


extern volatile far CTRL_TRF_DATA CtrlTrfData;

extern volatile far byte usbgen_out[USBGEN_EP_SIZE];


extern volatile far byte usbgen_in[USBGEN_EP_SIZE];

#endif //USBMMAP_H

/*********************************************************************
* Microchip USB C18 Firmware Version 1.2
*********************************************************************
* FileName: user.h
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/
#ifndef PICDEM_FS_DEMO_H
#define PICDEM_FS_DEMO_H

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"

/** D E F I N I T I O N S ****************************************************/
//Your definitions
72

/** S T R U C T U R E S ******************************************************/
typedef union DATA_PACKET
{
byte _byte[USBGEN_EP_SIZE]; //For byte access
word _word[USBGEN_EP_SIZE/2];//For word access(USBGEN_EP_SIZE msut be even)
//other access
} DATA_PACKET;

/** P U B L I C P R O T O T Y P E S *****************************************/
void UserInit(void);
void ProcessIO(void);

#endif //PICDEM_FS_DEMO_H

/*********************************************************************
* Microchip USB C18 Firmware Version 1.2
*********************************************************************
* FileName: main.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/

/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "system\typedefs.h" // Required
#include "system\usb\usb.h" // Required
#include "io_cfg.h" // Required

#include "system\usb\usb_compile_time_validation.h" // Optional


#include "user\user.h" // Modifiable

/** C O N F I G U R A T I O N ************************************************/

#pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board)


#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
#pragma config FOSC = HSPLL_HS
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = ON
#pragma config BORV = 3
#pragma config VREGEN = ON //USB Voltage Regulator
73

#pragma config WDT = OFF


#pragma config WDTPS = 32768
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = OFF
#pragma config CCP2MX = ON
#pragma config STVREN = ON
#pragma config LVP = OFF
#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming
#pragma config XINST = OFF // Extended Instruction Set
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
#pragma config CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
#pragma config WRT3 = OFF
#pragma config WRTB = ON // Boot Block Write Protection
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
#pragma config EBTR3 = OFF
#pragma config EBTRB = OFF

/** V A R I A B L E S ********************************************************/
#pragma udata

/** P R I V A T E P R O T O T Y P E S ***************************************/
static void InitializeSystem(void);
void USBTasks(void);

/** V E C T O R R E M A P P I N G *******************************************/

extern void _startup (void); // See c018i.c in your C18 compiler dir
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
void _reset (void)
{
_asm goto _startup _endasm
}
#pragma code
74

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808


void _high_ISR (void)
{
;
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000818


void _low_ISR (void)
{
;
}
#pragma code

/** D E C L A R A T I O N S **************************************************/
#pragma code

void main(void)
{
InitializeSystem();
while(1)
{
USBTasks(); // USB Tasks
ProcessIO(); // See user\user.c & .h
}//end while
}//end main

static void InitializeSystem(void)


{ PORTA = 0x00;
LATA = 0x00;
PORTE = 0x00;
LATE = 0x00;

ADCON1 |= 0x0F; // Default all pins to digital


TRISA = 0x00;
TRISE = 0x00;

PORTB = 0x00;
LATB = 0x00;
TRISB = 0x00;
PORTC = 0x00;
LATC = 0x00;
TRISC = 0x00;
PORTD = 0x00;
LATD = 0x00;
TRISD = 0x00;
75

#if defined(USE_USB_BUS_SENSE_IO)
tris_usb_bus_sense = INPUT_PIN; // See io_cfg.h
#endif

#if defined(USE_SELF_POWER_SENSE_IO)
tris_self_power = INPUT_PIN;
#endif
mInitializeUSBDriver(); // See usbdrv.h
UserInit(); // See user.c & .h
}//end InitializeSystem

void USBTasks(void)
{
/*
* Servicing Hardware
*/
USBCheckBusStatus(); // Must use polling method
if(UCFGbits.UTEYE!=1)
USBDriverService(); // Interrupt or polling method

}// end USBTasks

/** EOF main.c ***************************************************************/

/*********************************************************************
* Microchip USB C18 Firmware Version 1.3
*********************************************************************
* FileName: usb9.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/

/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"
#include "io_cfg.h" // Required for self_power status

/** V A R I A B L E S ********************************************************/
#pragma udata
76

/** P R I V A T E P R O T O T Y P E S ***************************************/
void USBStdGetDscHandler(void);
void USBStdSetCfgHandler(void);
void USBStdGetStatusHandler(void);
void USBStdFeatureReqHandler(void);

/** D E C L A R A T I O N S **************************************************/
#pragma code

void USBCheckStdRequest(void)
{
if(SetupPkt.RequestType != STANDARD) return;

switch(SetupPkt.bRequest)
{
case SET_ADR:
ctrl_trf_session_owner = MUID_USB9;
usb_device_state = ADR_PENDING_STATE; // Update state only
/* See USBCtrlTrfInHandler() in usbctrltrf.c for the next step */
break;
case GET_DSC:
USBStdGetDscHandler();
break;
case SET_CFG:
USBStdSetCfgHandler();
break;
case GET_CFG:
ctrl_trf_session_owner = MUID_USB9;
pSrc.bRam = (byte*)&usb_active_cfg; // Set Source
usb_stat.ctrl_trf_mem = _RAM; // Set memory type
LSB(wCount) = 1; // Set data count
break;
case GET_STATUS:
USBStdGetStatusHandler();
break;
case CLR_FEATURE:
case SET_FEATURE:
USBStdFeatureReqHandler();
break;
case GET_INTF:
ctrl_trf_session_owner = MUID_USB9;
pSrc.bRam = (byte*)&usb_alt_intf+SetupPkt.bIntfID; // Set source
usb_stat.ctrl_trf_mem = _RAM; // Set memory type
LSB(wCount) = 1; // Set data count
break;
77

case SET_INTF:
ctrl_trf_session_owner = MUID_USB9;
usb_alt_intf[SetupPkt.bIntfID] = SetupPkt.bAltID;
break;
case SET_DSC:
case SYNCH_FRAME:
default:
break;
}//end switch
}//end USBCheckStdRequest

void USBStdGetDscHandler(void)
{
if(SetupPkt.bmRequestType == 0x80)
{
switch(SetupPkt.bDscType)
{
case DSC_DEV:
ctrl_trf_session_owner = MUID_USB9;
pSrc.bRom = (rom byte*)&device_dsc;
wCount._word = sizeof(device_dsc); // Set data count
break;
case DSC_CFG:
ctrl_trf_session_owner = MUID_USB9;
pSrc.bRom = *(USB_CD_Ptr+SetupPkt.bDscIndex);
wCount._word = *(pSrc.wRom+1); // Set data count
break;
case DSC_STR:
ctrl_trf_session_owner = MUID_USB9;
pSrc.bRom = *(USB_SD_Ptr+SetupPkt.bDscIndex);
wCount._word = *pSrc.bRom; // Set data count
break;
}//end switch

usb_stat.ctrl_trf_mem = _ROM; // Set memory type


}//end if
}//end USBStdGetDscHandler

void USBStdSetCfgHandler(void)
{ ctrl_trf_session_owner = MUID_USB9;
mDisableEP1to15(); // See usbdrv.h
ClearArray((byte*)&usb_alt_intf,MAX_NUM_INT);
usb_active_cfg = SetupPkt.bCfgValue;
if(SetupPkt.bCfgValue == 0)
78

usb_device_state = ADDRESS_STATE;
else
{
usb_device_state = CONFIGURED_STATE;

/* Modifiable Section */

#if defined(USB_USE_GEN) // See autofiles\usbcfg.h


USBGenInitEP();
#endif

/* End modifiable section */

}//end if(SetupPkt.bcfgValue == 0)
}//end USBStdSetCfgHandler

void USBStdGetStatusHandler(void)
{
CtrlTrfData._byte0 = 0; // Initialize content
CtrlTrfData._byte1 = 0;

switch(SetupPkt.Recipient)
{
case RCPT_DEV:
ctrl_trf_session_owner = MUID_USB9;
/*
* _byte0: bit0: Self-Powered Status [0] Bus-Powered [1] Self-Powered
* bit1: RemoteWakeup [0] Disabled [1] Enabled
*/
if(self_power == 1) // self_power defined in io_cfg.h
CtrlTrfData._byte0|=0b00000001; // Set bit0

if(usb_stat.RemoteWakeup == 1) // usb_stat defined in usbmmap.c


CtrlTrfData._byte0|=0b00000010; // Set bit1
break;
case RCPT_INTF:
ctrl_trf_session_owner = MUID_USB9; // No data to update
break;
case RCPT_EP:
ctrl_trf_session_owner = MUID_USB9;
pDst.bRam = (byte*)&ep0Bo+(SetupPkt.EPNum*8)+(SetupPkt.EPDir*4);
if(*pDst.bRam & _BSTALL) // Use _BSTALL as a bit mask
CtrlTrfData._byte0=0x01;// Set bit0
break;
}//end switch
79

if(ctrl_trf_session_owner == MUID_USB9)
{
pSrc.bRam = (byte*)&CtrlTrfData; // Set Source
usb_stat.ctrl_trf_mem = _RAM; // Set memory type
LSB(wCount) = 2; // Set data count
}//end if(...)
}//end USBStdGetStatusHandler

void USBStdFeatureReqHandler(void)
{
if((SetupPkt.bFeature == DEVICE_REMOTE_WAKEUP)&&
(SetupPkt.Recipient == RCPT_DEV))
{
ctrl_trf_session_owner = MUID_USB9;
if(SetupPkt.bRequest == SET_FEATURE)
usb_stat.RemoteWakeup = 1;
else
usb_stat.RemoteWakeup = 0;
}//end if

if((SetupPkt.bFeature == ENDPOINT_HALT)&&
(SetupPkt.Recipient == RCPT_EP)&&
(SetupPkt.EPNum != 0))
{
ctrl_trf_session_owner = MUID_USB9;
/* Must do address calculation here */
pDst.bRam = (byte*)&ep0Bo+(SetupPkt.EPNum*8)+(SetupPkt.EPDir*4);

if(SetupPkt.bRequest == SET_FEATURE)
*pDst.bRam = _USIE|_BSTALL;
else
{

if(SetupPkt.EPDir == 1) // IN
*pDst.bRam = _UCPU|_DAT1;
else
*pDst.bRam = _USIE|_DAT0|_DTSEN;

}//end if
}//end if
}//end USBStdFeatureReqHandler

/** EOF usb9.c ***************************************************************/


80

/*********************************************************************
* Microchip USB C18 Firmware Version 1.2
*********************************************************************
* FileName: usbctrltrf.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/

/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"

/** V A R I A B L E S ********************************************************/
#pragma udata
byte ctrl_trf_state; // Control Transfer State
byte ctrl_trf_session_owner; // Current transfer session owner

POINTER pSrc; // Data source pointer


POINTER pDst; // Data destination pointer
WORD wCount; // Data counter

/** P R I V A T E P R O T O T Y P E S ***************************************/
void USBCtrlTrfSetupHandler(void);
void USBCtrlTrfOutHandler(void);
void USBCtrlTrfInHandler(void);

/** D E C L A R A T I O N S **************************************************/
#pragma code

byte USBCtrlEPService(void)
{ if(USTAT == EP00_OUT)
{
UIRbits.TRNIF = 0;
if(ep0Bo.Stat.PID == SETUP_TOKEN) // EP0 SETUP
USBCtrlTrfSetupHandler();
else // EP0 OUT
USBCtrlTrfOutHandler(); }
else if(USTAT == EP00_IN) // EP0 IN
{ UIRbits.TRNIF = 0;
USBCtrlTrfInHandler();
}
81

else
{
return 0; // Return '0', if not an EP0 transaction
}
return 1; // Return '1', if TRNIF has been cleared
}//end USBCtrlEPService

void USBCtrlTrfSetupHandler(void)
{
byte i;

if(ep0Bi.Stat.UOWN != 0)
ep0Bi.Stat._byte = _UCPU; // Compensate for after a STALL
short_pkt_status = SHORT_PKT_NOT_USED;

/* Stage 1 */
ctrl_trf_state = WAIT_SETUP;
ctrl_trf_session_owner = MUID_NULL; // Set owner to NULL
wCount._word = 0;

/* Stage 2 */
USBCheckStdRequest(); // See system\usb9\usb9.c

/* Modifiable Section */
// Insert other USB Device Class Request Handlers here
/* End Modifiable Section */

/* Stage 3 */
USBCtrlEPServiceComplete();
}//end USBCtrlTrfSetupHandler

void USBCtrlTrfOutHandler(void)
{
if(ctrl_trf_state == CTRL_TRF_RX)
{
USBCtrlTrfRxService();
if(ep0Bo.Stat.DTS == 0)
ep0Bo.Stat._byte = _USIE|_DAT1|_DTSEN;
else
ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN;
}
else // CTRL_TRF_TX
USBPrepareForNextSetupTrf();

}//end USBCtrlTrfOutHandler
82

void USBCtrlTrfInHandler(void)
{
mUSBCheckAdrPendingState(); // Must check if in ADR_PENDING_STATE

if(ctrl_trf_state == CTRL_TRF_TX)
{
USBCtrlTrfTxService();

if(short_pkt_status == SHORT_PKT_SENT)
{
// If a short packet has been sent, don't want to send any more,
// stall next time if host is still trying to read.
ep0Bi.Stat._byte = _USIE|_BSTALL;
}
else
{
if(ep0Bi.Stat.DTS == 0)
ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
else
ep0Bi.Stat._byte = _USIE|_DAT0|_DTSEN;
}//end if(...)else
}
else // CTRL_TRF_RX
USBPrepareForNextSetupTrf();

}//end USBCtrlTrfInHandler

void USBCtrlTrfTxService(void)
{
WORD byte_to_send;
if(wCount._word < EP0_BUFF_SIZE)
{
byte_to_send._word = wCount._word;

if(short_pkt_status == SHORT_PKT_NOT_USED)
{
short_pkt_status = SHORT_PKT_PENDING;
}
else if(short_pkt_status == SHORT_PKT_PENDING)
{
short_pkt_status = SHORT_PKT_SENT;
}//end if
}
else
byte_to_send._word = EP0_BUFF_SIZE;
83

ep0Bi.Stat.BC9 = 0;
ep0Bi.Stat.BC8 = 0;
ep0Bi.Stat._byte |= MSB(byte_to_send);
ep0Bi.Cnt = LSB(byte_to_send);
wCount._word = wCount._word - byte_to_send._word;

pDst.bRam = (byte*)&CtrlTrfData; // Set destination pointer

if(usb_stat.ctrl_trf_mem == _ROM) // Determine type of memory source


{
while(byte_to_send._word)
{
*pDst.bRam = *pSrc.bRom;
pDst.bRam++;
pSrc.bRom++;
byte_to_send._word--;
}//end while(byte_to_send._word)
}
else // RAM
{
while(byte_to_send._word)
{
*pDst.bRam = *pSrc.bRam;
pDst.bRam++;
pSrc.bRam++;
byte_to_send._word--;
}//end while(byte_to_send._word)
}//end if(usb_stat.ctrl_trf_mem == _ROM)
}//end USBCtrlTrfTxService

void USBCtrlTrfRxService(void)
{
WORD byte_to_read;
MSB(byte_to_read) = 0x03 & ep0Bo.Stat._byte; // Filter out last 2 bits
LSB(byte_to_read) = ep0Bo.Cnt;
wCount._word = wCount._word + byte_to_read._word;
pSrc.bRam = (byte*)&CtrlTrfData;
while(byte_to_read._word)
{ *pDst.bRam = *pSrc.bRam;
pDst.bRam++;
pSrc.bRam++;
byte_to_read._word--;
}//end while(byte_to_read._word)
}//end USBCtrlTrfRxService
84

void USBCtrlEPServiceComplete(void)
{
UCONbits.PKTDIS = 0;
if(ctrl_trf_session_owner == MUID_NULL)
{
ep0Bo.Cnt = EP0_BUFF_SIZE;
ep0Bo.ADR = (byte*)&SetupPkt;
ep0Bo.Stat._byte = _USIE|_BSTALL;
ep0Bi.Stat._byte = _USIE|_BSTALL;
}
else // A module has claimed ownership of the control transfer session.
{
if(SetupPkt.DataDir == DEV_TO_HOST)
{
if(SetupPkt.wLength < wCount._word)
wCount._word = SetupPkt.wLength;
USBCtrlTrfTxService();
ctrl_trf_state = CTRL_TRF_TX;
ep0Bo.Cnt = EP0_BUFF_SIZE;
ep0Bo.ADR = (byte*)&SetupPkt;
ep0Bo.Stat._byte = _USIE; // Note: DTSEN is 0!
ep0Bi.ADR = (byte*)&CtrlTrfData;
ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
}
else // (SetupPkt.DataDir == HOST_TO_DEV)
{
ctrl_trf_state = CTRL_TRF_RX;
ep0Bi.Cnt = 0;
ep0Bi.Stat._byte = _USIE|_DAT1|_DTSEN;
ep0Bo.Cnt = EP0_BUFF_SIZE;
ep0Bo.ADR = (byte*)&CtrlTrfData;
ep0Bo.Stat._byte = _USIE|_DAT1|_DTSEN;
}//end if(SetupPkt.DataDir == DEV_TO_HOST)
}//end if(ctrl_trf_session_owner == MUID_NULL)
}//end USBCtrlEPServiceComplete

void USBPrepareForNextSetupTrf(void)
{
if((ctrl_trf_state == CTRL_TRF_RX) &&
(UCONbits.PKTDIS == 1) &&
(ep0Bo.Cnt == sizeof(CTRL_TRF_SETUP)) &&
(ep0Bo.Stat.PID == SETUP_TOKEN) &&
(ep0Bo.Stat.UOWN == 0))
{ unsigned char setup_cnt;
ep0Bo.ADR = (byte*)&SetupPkt;
85

{
*(((byte*)&SetupPkt)+setup_cnt) = *(((byte*)&CtrlTrfData)+setup_cnt);
}//end for
}
else
{
ctrl_trf_state = WAIT_SETUP; // See usbctrltrf.h
ep0Bo.Cnt = EP0_BUFF_SIZE; // Defined in usbcfg.h
ep0Bo.ADR = (byte*)&SetupPkt;
ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN|_BSTALL;
ep0Bi.Stat._byte = _UCPU; // Should be removed
//ep0Bi.Stat._byte = _USIE|_BSTALL; // Should be added #F3
}//end if(...)else(...)

}//end USBPrepareForNextSetupTrf

/** EOF usbctrltrf.c *********************************************************/

/*********************************************************************
* Microchip USB C18 Firmware Version 1.2
*********************************************************************
* FileName: usbdrv.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/

/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"
#include "io_cfg.h" // Required for USBCheckBusStatus()

/** V A R I A B L E S ********************************************************/
#pragma udata
byte bTRNIFCount; // Bug fix - Work around.

/** P R I V A T E P R O T O T Y P E S ***************************************/
void USBModuleEnable(void);
void USBModuleDisable(void);

void USBSuspend(void);
void USBWakeFromSuspend(void);
86

void USBProtocolResetHandler(void);
void USB_SOF_Handler(void);
void USBStallHandler(void);
void USBErrorHandler(void);

/** D E C L A R A T I O N S **************************************************/
#pragma code

void USBCheckBusStatus(void)
{
#define USB_BUS_ATTACHED 1
#define USB_BUS_DETACHED 0

if(usb_bus_sense == USB_BUS_ATTACHED) // Is USB bus attached?


{
if(UCONbits.USBEN == 0) // Is the module off?
USBModuleEnable(); // Is off, enable it
}
else
{
if(UCONbits.USBEN == 1) // Is the module on?
USBModuleDisable(); // Is on, disable it
}//end if(usb_bus_sense...)

if(usb_device_state == ATTACHED_STATE)
{
if(!UCONbits.SE0)
{
UIR = 0; // Clear all USB interrupts
UIE = 0; // Mask all USB interrupts
UIEbits.URSTIE = 1; // Unmask RESET interrupt
UIEbits.IDLEIE = 1; // Unmask IDLE interrupt
usb_device_state = POWERED_STATE;
}//end if // else wait until SE0 is cleared
}//end if(usb_device_state == ATTACHED_STATE)
}//end USBCheckBusStatus

void USBModuleEnable(void)
{
UCON = 0;
UIE = 0; // Mask all USB interrupts
UCONbits.USBEN = 1; // Enable module & attach to bus
usb_device_state = ATTACHED_STATE; // Defined in usbmmap.c & .h
}//end USBModuleEnable
87

void USBModuleDisable(void)
{
UCON = 0; // Disable module & detach from bus
UIE = 0; // Mask all USB interrupts
usb_device_state = DETACHED_STATE; // Defined in usbmmap.c & .h
}//end USBModuleDisable

void USBSoftDetach(void)
{
USBModuleDisable();
}//end USBSoftDetach

void USBDriverService(void)
{
if(usb_device_state == DETACHED_STATE) return;
if(UIRbits.ACTVIF && UIEbits.ACTVIE) USBWakeFromSuspend();
if(UCONbits.SUSPND==1) return;
if(UIRbits.URSTIF && UIEbits.URSTIE) USBProtocolResetHandler();
if(UIRbits.IDLEIF && UIEbits.IDLEIE) USBSuspend();
if(UIRbits.SOFIF && UIEbits.SOFIE) USB_SOF_Handler();
if(UIRbits.STALLIF && UIEbits.STALLIE) USBStallHandler();
if(UIRbits.UERRIF && UIEbits.UERRIE) USBErrorHandler();
if(usb_device_state < DEFAULT_STATE) return;
for(bTRNIFCount = 0; bTRNIFCount < 4; bTRNIFCount++)
{
if(UIRbits.TRNIF && UIEbits.TRNIE)
{
if(USBCtrlEPService() == 0) // If not an EP0 transaction, then clear TRNIF.
{
UIRbits.TRNIF = 0;
}
}//end if(UIRbits.TRNIF && UIEbits.TRNIE)
else
break;
}// end for(bTRNIFCount = 0; bTRNIFCount < 4; bTRNIFCount++)
}//end USBDriverService

void USBSuspend(void)
{
UIEbits.ACTVIE = 1; // Enable bus activity interrupt
UIRbits.IDLEIF = 0;
UCONbits.SUSPND = 1; // Put USB module in power conserve
// mode, SIE clock inactive
}//end USBSuspend
88

void USBWakeFromSuspend(void)
{
UCONbits.SUSPND = 0;
UIEbits.ACTVIE = 0;
while(UIRbits.ACTVIF){UIRbits.ACTVIF = 0;} // Added
}//end USBWakeFromSuspend

void USBRemoteWakeup(void)
{
static word delay_count;
if(usb_stat.RemoteWakeup == 1) // Check if RemoteWakeup function
{ // has been enabled by the host.
UCONbits.SUSPND = 0;
UCONbits.RESUME = 1; // Start RESUME signaling
delay_count = 1800U; // Set RESUME line for 1-13 ms
do
{
delay_count--;
}while(delay_count);
UCONbits.RESUME = 0;
}//endif
}//end USBRemoteWakeup

void USB_SOF_Handler(void)
{
UIRbits.SOFIF = 0;
}//end USB_SOF_Handler

void USBStallHandler(void)
{
if(UEP0bits.EPSTALL == 1)
{
if((ep0Bo.Stat._byte == _USIE) && (ep0Bi.Stat._byte == (_USIE|_BSTALL)))
{
// Set ep0Bo to stall also
ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN|_BSTALL;
}//end if
UEP0bits.EPSTALL = 0; // Clear STALL status
}
UIRbits.STALLIF = 0;
}//end USBStallHandler

void USBErrorHandler(void)
{
UEIR = 0;
89

}//end USBErrorHandler

void USBProtocolResetHandler(void)
{
UEIR = 0; // Clear all USB error flags
UIR = 0; // Clears all USB interrupts
UEIE = 0b10011111; // Unmask all USB error interrupts
UIE = 0b01111011; // Enable all interrupts except ACTVIE
UADDR = 0x00; // Reset to default address
mDisableEP1to15(); // Reset all non-EP0 UEPn registers
UEP0 = EP_CTRL|HSHK_EN; // Init EP0 as a Ctrl EP, see usbdrv.h
while(UIRbits.TRNIF == 1) // Flush any pending transactions
{
UIRbits.TRNIF = 0;
Nop(); Nop(); Nop();
Nop(); Nop(); Nop();
}

UCONbits.PKTDIS = 0; // Make sure packet processing is enabled


USBPrepareForNextSetupTrf(); // Declared in usbctrltrf.c

usb_stat.RemoteWakeup = 0; // Default status flag to disable


usb_active_cfg = 0; // Clear active configuration
usb_device_state = DEFAULT_STATE;
}//end USBProtocolResetHandler

/* Auxiliary Function */
void ClearArray(byte* startAdr,byte count)
{
*startAdr;
while(count)
{
_asm
clrf POSTINC0,0
_endasm
count--;
}//end while
}//end ClearArray

/** EOF usbdrv.c *************************************************************/


90

/********************************************************************
* Microchip USB C18 Firmware Version 1.2
*********************************************************************
* FileName: usbdsc.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/
/** I N C L U D E S *************************************************/
#include "system\typedefs.h"
#include "system\usb\usb.h"

/** C O N S T A N T S ************************************************/
#pragma romdata

/* Device Descriptor */
rom USB_DEV_DSC device_dsc=
{
sizeof(USB_DEV_DSC), // Size of this descriptor in bytes
DSC_DEV, // DEVICE descriptor type
0x0200, // USB Spec Release Number in BCD format
0x00, // Class Code
0x00, // Subclass code
0x00, // Protocol code
EP0_BUFF_SIZE, // Max packet size for EP0, see usbcfg.h
0x04D8, // Vendor ID
0x000C, // Product ID: PICDEM FS USB (DEMO Mode)
0x0001, // Device release number in BCD format
0x01, // Manufacturer string index
0x02, // Product string index
0x00, // Device serial number string index
0x01 // Number of possible configurations
};

/* Configuration 1 Descriptor */
CFG01=
{
/* Configuration Descriptor */
sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
DSC_CFG, // CONFIGURATION descriptor type
sizeof(cfg01), // Total length of data for this cfg
1, // Number of interfaces in this cfg
1, // Index value of this configuration
91

0, // Configuration string index


_DEFAULT|_SELF, // Attributes, see usbdefs_std_dsc.h
50, // Max power consumption (2X mA)

/* Interface Descriptor */
sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
DSC_INTF, // INTERFACE descriptor type
0, // Interface Number
0, // Alternate Setting Number
2, // Number of endpoints in this intf
0x00, // Class code
0x00, // Subclass code
0x00, // Protocol code
0, // Interface string index

/* Endpoint Descriptors */
sizeof(USB_EP_DSC),DSC_EP,_EP01_OUT,_INT,USBGEN_EP_SIZE,32,
sizeof(USB_EP_DSC),DSC_EP,_EP01_IN,_INT,USBGEN_EP_SIZE,32
};
rom struct{byte bLength;byte bDscType;word string[1];}sd000={
sizeof(sd000),DSC_STR,0x0409};
rom struct{byte bLength;byte bDscType;word string[25];}sd001={
sizeof(sd001),DSC_STR,
'M','i','c','r','o','c','h','i','p',' ',
'T','e','c','h','n','o','l','o','g','y',' ','I','n','c','.'};

rom struct{byte bLength;byte bDscType;word string[33];}sd002={


sizeof(sd002),DSC_STR,
'M','i','c','r','o','c','h','i','p',' ','U','S','B',' ',
'D','e','m','o',' ','B','o','a','r','d',' ','(','C',')',
' ','2','0','0','7'};

rom const unsigned char *rom USB_CD_Ptr[]=


{
(rom const unsigned char *rom)&cfg01,
(rom const unsigned char *rom)&cfg01
};
rom const unsigned char *rom USB_SD_Ptr[]=
{
(rom const unsigned char *rom)&sd000,
(rom const unsigned char *rom)&sd001,
(rom const unsigned char *rom)&sd002
};
#pragma code
/** EOF usbdsc.c ****************************************************/
92

/*********************************************************************
* Microchip USB C18 Firmware - Generic
*********************************************************************
* FileName: usbgen.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
********************************************************************/

/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"

#ifdef USB_USE_GEN

/** V A R I A B L E S ********************************************************/
#pragma udata
byte usbgen_rx_len;

/** D E C L A R A T I O N S **************************************************/
#pragma code

/** U S E R A P I ***********************************************************/
void USBGenInitEP(void)
{
usbgen_rx_len = 0;
USBGEN_UEP = EP_OUT_IN|HSHK_EN; // Enable 2 data pipes
USBGEN_BD_OUT.Cnt = sizeof(usbgen_out); // Set buffer size
USBGEN_BD_OUT.ADR = (byte*)&usbgen_out; // Set buffer address
USBGEN_BD_OUT.Stat._byte = _USIE|_DAT0|_DTSEN;// Set status
USBGEN_BD_IN.ADR = (byte*)&usbgen_in; // Set buffer address
USBGEN_BD_IN.Stat._byte = _UCPU|_DAT1; // Set buffer status
}//end USBGenInitEP

void USBGenWrite(byte *buffer, byte len)


{ byte i;
if(len > USBGEN_EP_SIZE)
len = USBGEN_EP_SIZE;
for (i = 0; i < len; i++)
usbgen_in[i] = buffer[i];
USBGEN_BD_IN.Cnt = len;
mUSBBufferReady(USBGEN_BD_IN);
}//end USBGenWrite
93

byte USBGenRead(byte *buffer, byte len)


{
usbgen_rx_len = 0;
if(!mUSBGenRxIsBusy())
{
if(len > USBGEN_BD_OUT.Cnt)
len = USBGEN_BD_OUT.Cnt;
for(usbgen_rx_len = 0; usbgen_rx_len < len; usbgen_rx_len++)
buffer[usbgen_rx_len] = usbgen_out[usbgen_rx_len];
USBGEN_BD_OUT.Cnt = sizeof(usbgen_out);
mUSBBufferReady(USBGEN_BD_OUT);
}//end if
return usbgen_rx_len;
}//end USBGenRead
#endif //def USB_USE_GEN

/** EOF usbgen.c *************************************************************/

/*********************************************************************
* Microchip USB C18 Firmware Version 1.0
*********************************************************************
* FileName: usbmmap.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
*****************************************************************************/

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"
#include "system\usb\usb.h"

/** U S B G L O B A L V A R I A B L E S ************************************/
#pragma udata
byte usb_device_state; // Device States: DETACHED, ATTACHED, ...
USB_DEVICE_STATUS usb_stat; // Global USB flags
byte usb_active_cfg; // Value of current configuration
byte usb_alt_intf[MAX_NUM_INT]; // Array to keep track of the current alternate
// setting for each interface ID
/** U S B F I X E D L O C A T I O N V A R I A B L E S *********************/
#pragma udata usbram4=0x400 //See Linker Script,usb4:0x400-0x4FF(256-byte)
#if(0 <= MAX_EP_NUMBER)
volatile far BDT ep0Bo; //Endpoint #0 BD Out
volatile far BDT ep0Bi; //Endpoint #0 BD In
#endif
94

#if(1 <= MAX_EP_NUMBER)


volatile far BDT ep1Bo; //Endpoint #1 BD Out
volatile far BDT ep1Bi; //Endpoint #1 BD In
#endif

#if(2 <= MAX_EP_NUMBER)


volatile far BDT ep2Bo; //Endpoint #2 BD Out
volatile far BDT ep2Bi; //Endpoint #2 BD In
#endif

#if(3 <= MAX_EP_NUMBER)


volatile far BDT ep3Bo; //Endpoint #3 BD Out
volatile far BDT ep3Bi; //Endpoint #3 BD In
#endif

#if(4 <= MAX_EP_NUMBER)


volatile far BDT ep4Bo; //Endpoint #4 BD Out
volatile far BDT ep4Bi; //Endpoint #4 BD In
#endif

#if(5 <= MAX_EP_NUMBER)


volatile far BDT ep5Bo; //Endpoint #5 BD Out
volatile far BDT ep5Bi; //Endpoint #5 BD In
#endif

#if(6 <= MAX_EP_NUMBER)


volatile far BDT ep6Bo; //Endpoint #6 BD Out
volatile far BDT ep6Bi; //Endpoint #6 BD In
#endif

#if(7 <= MAX_EP_NUMBER)


volatile far BDT ep7Bo; //Endpoint #7 BD Out
volatile far BDT ep7Bi; //Endpoint #7 BD In
#endif

#if(8 <= MAX_EP_NUMBER)


volatile far BDT ep8Bo; //Endpoint #8 BD Out
volatile far BDT ep8Bi; //Endpoint #8 BD In
#endif

#if(9 <= MAX_EP_NUMBER)


volatile far BDT ep9Bo; //Endpoint #9 BD Out
volatile far BDT ep9Bi; //Endpoint #9 BD In
#endif
95

#if(10 <= MAX_EP_NUMBER)


volatile far BDT ep10Bo; //Endpoint #10 BD Out
volatile far BDT ep10Bi; //Endpoint #10 BD In
#endif

#if(11 <= MAX_EP_NUMBER)


volatile far BDT ep11Bo; //Endpoint #11 BD Out
volatile far BDT ep11Bi; //Endpoint #11 BD In
#endif

#if(12 <= MAX_EP_NUMBER)


volatile far BDT ep12Bo; //Endpoint #12 BD Out
volatile far BDT ep12Bi; //Endpoint #12 BD In
#endif

#if(13 <= MAX_EP_NUMBER)


volatile far BDT ep13Bo; //Endpoint #13 BD Out
volatile far BDT ep13Bi; //Endpoint #13 BD In
#endif

#if(14 <= MAX_EP_NUMBER)


volatile far BDT ep14Bo; //Endpoint #14 BD Out
volatile far BDT ep14Bi; //Endpoint #14 BD In
#endif

#if(15 <= MAX_EP_NUMBER)


volatile far BDT ep15Bo; //Endpoint #15 BD Out
volatile far BDT ep15Bi; //Endpoint #15 BD In
#endif

volatile far CTRL_TRF_SETUP SetupPkt;


volatile far CTRL_TRF_DATA CtrlTrfData;

volatile far byte usbgen_out[USBGEN_EP_SIZE];


volatile far byte usbgen_in[USBGEN_EP_SIZE];

#pragma udata

/** EOF usbmmap.c ************************************************************/


96

/*********************************************************************
* Microchip USB C18 Firmware Version 1.2
*********************************************************************
* FileName: user.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 3.11+
* Company: Microchip Technology, Inc.
********************************************************************/
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include <usart.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"
#include "io_cfg.h" // I/O pin mapping
#include "user\user.h"
/** V A R I A B L E S ********************************************************/
#pragma udata
byte counter;
DATA_PACKET dataPacket;
/** P R I V A T E P R O T O T Y P E S ***************************************/
void ServiceRequests(void);
/** D E C L A R A T I O N S **************************************************/
#pragma code
void UserInit(void)
{
;
}//end UserInit
void ProcessIO(void)
{
if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
ServiceRequests();
}//end ProcessIO
void ServiceRequests(void)
{
if(USBGenRead((byte*)&dataPacket,sizeof(dataPacket)))
{
counter = 0;
if(counter != 0)
{if(!mUSBGenTxIsBusy())
USBGenWrite((byte*)&dataPacket,counter);
}//end if
}//end if
}//end ServiceRequests
/** EOF user.c ***************************************************************/

Das könnte Ihnen auch gefallen