Darshil Arvindbhai Shah

advertisement
PIC MICROCONTROLLER BASED USB STORAGE
Darshil Arvindbhai Shah
B.E., Gujarat University, India, 2007
PROJECT
Submitted in partial satisfaction of
the requirements for the degree of
MASTER OF SCIENCE
in
ELECTRICAL AND ELECTRONIC ENGINEERING
at
CALIFORNIA STATE UNIVERSITY, SACRAMENTO
SPRING
2011
PIC MICROCONTROLLER BASED USB STORAGE
A Project
by
Darshil Arvindbhai Shah
Approved by:
_______________________________, Committee Chair
Jing Pang, Ph.D.
_______________________________, Second Reader
Fethi Belkhouche, Ph.D.
__________________________
Date
ii
Student:
Darshil Arvindbhai Shah
I certify that this student has met the requirements for format contained in the University
format manual, and that this project is suitable for shelving in the Library and credit is to
be awarded for the project
_________________________, Graduate Coordinator
Preetham Kumar, Ph.D.
Department of Electrical and Electronic Engineering
iii
________________
Date
Abstract
of
PIC MICROCONTROLLER BASED USB STORAGE
By
Darshil Arvindbhai Shah
USB (Universal Serial Bus) is most popular peripheral interface in the computer
industry today. USB is plug and play communication. The user doesn’t have to initialize
USB compliant device on the computer. Computer will detect the USB device. The older
connection standards such as RS-232 or parallel port require external power supply. USB
connector also supplies power to the connected devices, so the devices connected to it
don’t require external power supply for operation.
USB has become standard connection method for many computer peripherals
such as mice, keyboards, digital cameras, printers, personal media players, flash drives.
USB was designed for personal computers. But nowadays because of the features such
as speed, no external power supply requirement, easy to implement have made USB
common in smartphones, PDA and video game consoles.
This project is an embedded system implementation that communicates with the
personal computer using USB as an interface. This embedded system can be divided in
two parts. First part is hardware design. The hardware part of the system is implemented
iv
using the PIC microcontroller. Second part is software implementation. The software
implementation of the system is done using Visual C# language.
________________________________________________, Committee Chair
Jing Pang, Ph.D.
_________________________
Date
v
ACKNOWLEDGMENTS
I would like to thank everybody who has helped me in this project .Specially, I
would thank my advisor Dr. Jing Pang, and without her it was not possible to complete
this project. It was her idea of doing this wonderful project. Dr. Pang has given
encouragement and support throughout the project implementation. She has also given
her valuable suggestion in writing the report. It was a great learning experience to work
with her. I have learnt many practical aspects of research from her.
In addition, I would like to thank Professor Dr. Fethi Belkhouche, the second
reader of the project report, for his crucial guidance in writing this project report. I would
like to thank Dr. Preetham Kumar for his advising throughout Master’s as Graduate
Coordinator. I would also like to thank, Dr.Suresh Vadhva, Department Chair of the
Electrical and Electronic Engineering Department, for his strong leadership and immense
support throughout my masters.
Also, I am thankful for all faculty members of the Electrical and Electronic
Engineering Department for helping me finish my requirements for graduation at
California State University, Sacramento.
vi
TABLE OF CONTENTS
Page
Acknowledgements ............................................................................................................ vi
List of Tables ..................................................................................................................... ix
List of Figures ......................................................................................................................x
Chapter
1. INTRODUCTION ...........................................................................................................1
2. UNIVERSAL SERIAL BUS ...........................................................................................3
2.1 USB Protocol .....................................................................................................4
2.2 USB Connector ..................................................................................................6
2.3 USB Transfer Types ..........................................................................................7
2.4 USB Descriptors ................................................................................................9
3. HARDWARE OVERVIEW ..........................................................................................16
3.1 PIC Microcontroller .........................................................................................16
3.2 PIC18F4550 Microcontroller ...........................................................................16
3.3 Oscillator ..........................................................................................................18
3.4 PICKit 2 ...........................................................................................................20
4. DESIGN IMPLEMENTATION AND FINAL RESULTS ...........................................22
4.1 Block Diagram of the Design ..........................................................................22
4.2 Hardware Implementation ...............................................................................23
4.3 Software Implementation .................................................................................24
vii
4.4 Results ..............................................................................................................28
5. CONCLUSION AND FUTURE DEVELOPMENT .....................................................33
5.1 Future Development.........................................................................................33
Appendix ............................................................................................................................34
References ..........................................................................................................................51
viii
LIST OF TABLES
Page
1. Table 2.1.1.1 Token Packets Format……………………………………..........5
2. Table 2.1.2.1 Data Packets Format…………………………………...………. 5
3. Table 2.1.3.1 Handshake Packets Format………………………..........…........ 6
4. Table 2.2.1 USB Pin Description…………………..………………………..... 7
5. Table 2.4.1.1 Device Descriptor Fields………………………………….……. 11
6. Table 2.4.2.1 Configuration Descriptor Fields……………………………….. 12
7. Table 2.4.3.1 Interface Descriptor Fields………………...………….……....... 13
8. Table 2.4.4.1 Endpoint Descriptor Fields……………………..…………........ 14
9. Table 2.4.5.1 String Descriptor Fields…………………..……......................... 15
10. Table 3.2.1 PIC18F4550 Pin Description…………………….......................... 18
11. Table 3.3.1 Various Capacitor and Crystal Combination……...………........... 20
ix
LIST OF FIGURES
Page
1. Figure 2.1 Tier Star Topology...............................................................................3
2. Figure 2.2.1 USB Type A connector………………………………………........ 6
3. Figure 2.2.2 USB Type B connector……………………………….………….... 6
4. Figure 2.4.1 USB Descriptors…………………………......…….....…................ 10
5. Figure 3.2.1 PIC18F4550 ................................………………………..…........... 17
6. Figure 3.3.1 Oscillator Connection to the PIC18F4550………………………....19
7. Figure 3.4.1 PICKit 2……………………………….....………........................... 21
8. Figure 3.4.2 PICKit 2 Pin Description………………………………………...... 21
9. Figure 4.1.1 Block Diagram of the Design……………………………............... 22
10. Figure 4.3.1.1 Flowchart of Firmware Development............................................26
11. Figure 4.4.1.1 Final Hardware……………………..………………...……......... 28
12. Figure 4.4.2.1 GUI When USB Device Is not Connected…………………….... 29
13. Figure 4.4.2.2 GUI After USB Device Is Connected……………………...….....30
14. Figure 4.4.2.3 GUI After First 3 Tests Are Passed............................................... 31
15. Figure 4.4.2.4 GUI After All The Tests Are Done……………………............... 32
x
1
Chapter 1
INTRODUCTION
The focus of this project is to implement USB protocol and read/ write different
size packets in the Peripheral Interface Controller (PIC) microcontroller’s memory. Some
test cases have been implemented,

Single packet write to device

Single packet read/write

Single packet write, 128 packets read

128 packet write, single packet read

Single packet write, timeout on read
The project is combination of the software and hardware co-design. The software is
implemented using Visual C#. The software part includes Graphical User Interface (GUI)
implementation. It gives debugging capabilities. The hardware is implemented using the
PIC microcontroller 18F4550, PIC Kit 2, Saronix 20MHz oscillator. The hardware is
connected using the USB interface to the computer.
Chapter 2 of the report discusses about USB protocol, types of packets in USB
protocol. Different USB transfers types and USB descriptors fields are explained in this
chapter.
Chapter 3 explains different hardware components of the design and also discusses
programming of PIC 18F4550 using PICKit 2.
2
Chapter 4 focuses on the hardware implementation of the design. This chapter
shows block diagram of the design. It also discusses things need to be checked during
hardware implementation. This chapter explains the software development process and
PIC18F4550 firmware development.
Chapter 5 discusses conclusion of the project and explores future improvements
of the project.
3
Chapter 2
UNIVERSAL SERIAL BUS
This Chapter discusses USB protocol, types of packets in USB protocol. There are
3 types of packets in the USB protocol. It also discusses different USB transfers types
and USB descriptors fields.
USB stands for Universal Serial Bus. USB has tiered star topology. This is similar
to the 10BaseT Ethernet cable. The tier star topology is shown in Figure 2.1. USB has
one central hub controller. This hub controller allows filtering of the different speeds
transaction; therefore the low speed devices don’t receive the high or full speed
transactions. Up to 127 devices can be connected to a USB bus.
Figure 2.1 Tier Star Topology [1]
The Universal Serial Bus (USB) has following excellent qualities. That makes it
designers first choice. The USB is easy to use. There is no need to configuration and set
up. It is fast. It doesn’t become communication bottleneck. The USB is reliable interface.
4
Errors are rare, with automatic retries when errors occur. It is versatile. Many different
kinds of peripheral can use the USB.USB is inexpensive. The manufacturers and users
don’t have to pay huge price. It is power conserving. Therefore it has been extensively
used to save energy and extend battery life in portable computers and devices. USB is
supported by both Windows and Mac operating systems. Therefore the developers don’t
have to write low level drivers to communicate with the peripherals.
2.1 USB Protocol
USB is a host centric bus. The host initiates all transactions. USB transaction is
made up of several layers of protocol. USB has defined format for the data transfer. USB
controller takes care of the lower level of protocol.
The host generates token packet to describe type of transaction, the target device
address and endpoint design.
After token, host generates the data packet carrying
payload. At last it generates the handshaking packet to report if the token and data was
received completely.
2.1.1 Token Packets
There are 3 types of token packet.

In: This informs USB device that host has initiated read transaction.

Out: Out informs USB device that host has initiated write transaction.

Setup: Setup is used to begin control transfer.
5
Sync PID ADDR ENDP CRC5 EOP
Table 2.1.1.1 Token Packets format
2.1.2 Data Packets
There are 2 types of Data packets. Each data packet is capable of transferring up
to 1024 bytes.
1. Data0
2. Data1
The maximum data payload for the low speed devices is 8 bytes, for full speed
devices is 1023 bytes and for the high speed devices is 1024 bytes.
Sync PID Data CRC16 EOP
Table 2.1.2.1 Data Packets Format
2.1.3 Handshake Packets
There are 3 types of handshake packets. The handshake packet contains only PID.

ACK: The packet has been received successfully is acknowledged by ACK.

NAK: NAK is used to let host that it cannot send or receive data. This
situation can be because of the interrupt transactions.

STALL: STALL informs host that device requires the host intervention.
6
Sync PID EOP
Table 2.1.3.1 Handshake Packets Format
2.2 USB Connector
There are two types of connectors, called Type A and Type B.USB connectors
have four pins. USB connector pin description is shown in table 2.2.1.
Figure 2.2.1 USB Type A connector
Type A connector used for the upstream connection and they are usually mounted
on the host devices like PC .Figure 2.2.1 shows USB Type A connector
Figure 2.2.2 USB Type B connector
Type B connector used for the downstream connection and they are usually
mounted on the USB devices such as printers, faxes. In this project USB type B
connector is used.
7
Pin number Function Color
1
Vbus
Red
2
D-
White
3
D+
Green
4
Ground
Black
Table 2.2.1 USB Pin Description
2.3 USB Transfer Types
The USB specifies 4 different types of transfers.
2.3.1 Control Transfers
The control transfers are used to set up a USB device. All enumeration functions
are performed during control transfer. They are all burst transfers. The control transfer
packets are initiated by the host. Packet size in of control transfer is 8 bytes for low speed
devices, 8,16,32,64 bytes for the high speed devices and 64 bytes for the full speed
devices.
2.3.2 Interrupt Transfers
Interrupt transfers have guaranteed latency, unidirectional stream pipe and error
detection capabilities. Interrupt transfers are non-periodic. The device queues its interrupt
requests’ until the host polls for the data. The maximum data payload size is 8 bytes for
the low speed devices. Full speed devices have the maximum data payload size of 64
8
bytes. And high speed devices have maximum data payload size of 1024 bytes. There are
two types of interrupt transaction.
IN: Each time the host polls device it will send IN tokens to device.
OUT: Host sends data followed by the OUT token.
2.3.3 Isochronous Transfers
Isochronous transfers contain time sensitive information such as video and audio
streaming. These transfers occur periodically and continuously. Isochronous transfers
have guaranteed bandwidth with bounded latency and error detection. These type of
transfers are not supported for the low speed devices, they are only supported by the full
and high speed devices.
2.3.4 Bulk Transfer
Bulk transfers are used for time insensitive transaction like printing, scanning.
The bulk transfers have no guaranteed latency. They provide error detection with 16 CRC
field on data. Bulk transfers are schedule after the isochronous transfers and interrupt
transfers in USB. They are usually done when the bus doesn’t have any other transfers
left to do. The bulk transfers have been used in this project for transferring large amount
of data.
2.3.5 Bus Bandwidth Management
The bandwidth management on the bus is host’s responsibility. This is done
during enumeration. When end point is configured as isochronous or interrupts host sets
9
bandwidth management function. The isochronous transfers and interrupt transfers are
called periodic transfers. On the high speed , the periodic transfers get around 90% of bus
time. The remaining 10 % time is used by for control transfer. The remaining time is
allocated for the bulk transfer. On the full speed bus, the 80 % time is allocated for the
periodic transfers.
2.4 USB Descriptors
USB descriptors are very important in any USB compatible device. The USB
descriptors describe the host information. The host information includes device’s version,
how many USB device can be configured on the host, number of endpoints host supports
and types of endpoint host supports. All the descriptors have common format. The first
field specifies descriptor length, second field defines descriptor type. The host will ignore
the descriptor, if the length field is smaller than what is required. If the descriptor length
field is longer than what is required than host will remove extra bits.
10
bNumConfigurations
bNumberInterfaces
Interface
Descriptor
bNumEndpoints
Endpoint
Descriptor
Configuration
Descriptor
Endpoint
Descriptor
bNumConfigurations
Same as
the other side
bNumInterfaces
bNumEndpoints bNumEndpoints
Endpoint
Descriptor
Device
Descriptor
Interface
Descriptor
bNumEndpoints
Endpoint
Descriptor
Figure 2.4.1 USB Descriptors [3]
2.4.1 Device Descriptors
USB devices can have one device descriptor field per device. The device
descriptor contains information about the USB version it compiles to, product ID and
vendor ID and how many configuration devices can be connected to it. The product ID
and vendor ID combination is used to load the appropriate drivers. Table 2.4.1.1 explains
various device descriptor fields.
11
Field
Offset
Field
Size Value
Description
Size of the descriptor in bytes (18
bytes)
Device Descriptor(0x01)
0
bLength
1
Number
1
BDescriptortype
1
Constant
2
bcdUSB
2
BCD
4
bDeviceClass
1
Class
5
bDeviceSubClass
1
6
bDeviceProtocol
1
7
bMaxPacketSize
1
8
idVendor
2
10
idProduct
2
12
bcdDevice
2
SubClass Subclass Code (Assigned by USB
Org)
Protocol Protocol Code (Assigned by USB
Org)
Number Maximum Packet Size for Zero
Endpoint. Valid Sizes are 8, 16,
32, 64
ID
Vendor ID( Assigned by the USB
Org)
ID
Product ID( Assigned by the USB
org)
BCD
Device Release Number
14
iManufacturer
1
Index
15
iProduct
1
Index
16
iSerialNumber
1
Index
17
bNumbConfigurations 1
Integer
USB specification number which
device complies.
Class code
Index of Manufacturer String
Descriptor
Index of Product String Descriptor
Index of Serial Number String
Descriptor
Number
of
Possible
Configurations
Table 2.4.1.1 Device Descriptor Fields [3]
2.4.2 Configuration Descriptors
The amount of power the particular configuration requires is specified using the
configuration descriptor. The configuration field also specifies that device is self or bus
powered. During the device enumeration process host read the device configuration
12
descriptor and decides on which configuration to enable. The host enables only one
configuration at time for each device. Table 2.4.2.1 explains various configuration
descriptor fields.
Offset Field
Size Value
Description
0
bLength
1
Number
Size of Descriptor in Bytes
1
bDescriptorType
1
Constant Configuration Descriptor(0x02)
2
wTotalLength
2
Number
4
bNumberInterfaces
1
Number
5
bConfigurationValue 1
Number
6
iConfiguration
1
Index
7
bmAttributes
1
Bitmap
9
bMaxPower
1
mA
Total Length in bytes of data
returned
Number of Interfaces
Value to use as an argument to
select this configuration
Index
of
String
Descriptor
describing this configuration
D7 Reserved, set to 1. (USB 1.0
Bus Powered)
D6 Self Powered
D5 Remote Wakeup
D4..0 Reserved, set to 0.
Maximum Power Consumption in
2mA Units
Table 2.4.2.1 Configuration Descriptor Fields [3]
2.4.3 Interface Descriptors
The interface descriptors describe a functional group of endpoints that are related
to single feature of the device. The device could have more than one interface descriptor
enabled at a time, unlike the configuration descriptor where only one configuration
descriptor could be enable at any time. For example a device like printer can perform
printing, scanning, copying functions. It can give different interface descriptors to all this
13
functions and they all can be enabled at the same time. Table 2.4.3.1 explains various
interface descriptor fields.
Offset Field
Size Value
Description
0
bLength
1
Number
Size of Description in Bytes (9 bytes)
1
bDescriptionType
1
Constant
Interface Descriptor(0x04)
2
bInterfaceNumber
1
Number
Number of Interface
3
bAlternateSetting
1
Number
Value used to select alternative setting
4
bNumEndpoints
1
Number
Number of endpoints used for this
interface
5
bInterfaceClass
1
Class
Class code ( Assigned by the USB
org)
6
bInterfaceSubClass 1
SubClass Subclass Code (Assigned by USB org)
7
bInterfaceProtocol
1
Protocol
Protocol Code(Assigned by USB org)
8
iInterface
1
Index
Index of String Descriptor Describing
this interface
Table 2.4.3.1 Interface Descriptor Fields [3]
2.4.4 Endpoint Descriptors
The type of transfer, direction, polling interval and the maximum packet size for
the each end point is defined by the endpoint descriptor. Endpoint zero is by default for
the control endpoint. The endpoint descriptor is configured before any descriptors are
requested by the host. The host will use endpoint descriptor information to determine the
bandwidth of the bus. Table 2.4.4.1 explains various endpoint descriptor fields.
14
Offset Field
Size Value
Description
0
bLength
1
Number
Size of the Descriptor in Bytes(7 bytes)
1
bDescriptorType
1
Constant
Endpoint Descriptor(0x05)
2
bEndpointAddress 1
3
bmAttributes
1
4
wMaxPacketSize
2
Number
6
bInterval
2
Number
Endpoint Endpoint Address
Bits 0..3b Endpoint Number.
Bits 4..6b Reserved. Set to Zero
Bits 7 Direction 0 = Out, 1 = In
(Ignored for Control Endpoints)
Bitmap
Bits 0..1 Transfer Type
00= Control
01= Isochronous
10 = Bulk
11 = Interrupt
Bits 2..7 are reserved. If Isochronous
endpoint,
Bits 3..2 = Synchronization Type (Iso
Mode)
00 = No Synchronization
01 = Asynchronous
10 = Adaptive
11 = Synchronous
Bits 5..4 = Usage Type (Iso Mode)
00 = Data Endpoint
01 = Feedback Endpoint
10 = Explicit Feedback Data
Endpoint
11 = Reserved
Maximum Packet Size this endpoint
is capable of sending or receiving
Interval for polling endpoint data
transfers.
Value in frame counts.
Ignored for Bulk & Control Endpoints.
Isochronous must equal 1 and field may
range from 1 to 255 for interrupt
endpoints.
Table 2.4.4.1 Endpoint Descriptor Fields [3]
15
2.4.5 String Descriptors
These descriptors provide information to the user. The string descriptor is an
optional field. Whenever it is not used it should be specified as 0.Table 2.4.5.1 explains
various string descriptor fields
Offset Field
Size Value
Description
0
bLength
1
Size of Descriptor in Bytes
1
bDescriptorType 1
Constant String Descriptor(0x03)
2
wLANGID[0]
2
Number
4
wLANGID[1]
2
Number
N
wLANGID[x]
2
Number
Number
Supported Language Code Zero
(e.g. 0x0409 English - United States)
Supported Language Code One
(e.g. 0x0c09 English - Australian)
Supported Language Code x
(e.g. 0x0407 German - Standard)
Table 2.4.5.1 String Descriptor Fields [3]
16
Chapter 3
HARDWARE OVERVIEW
This chapter focuses on hardware components such as PIC microcontroller,
PIC18F4550 Microcontroller, Saronix oscillator and also discusses programming of PIC
18F4550 using PICKit 2.
3.1 PIC Microcontroller
PIC stands for the “Peripheral Interface Controller”. PIC is family of high
performance, low cost microcontrollers developed by the Microchip Technology. They
are based on the Harvard architecture for microcontrollers. Due to their low cost, wide
availability, extensive collection of application notes, availability of free development
tools and serial programming capability, they have become the first choice for the
developers.
PIC microcontroller’s architectures have many features such as small instruction
set, RISC architecture, built in oscillator with selectable speeds, easy entry level in circuit
programming and debugging kit.
3.2 PIC18F4550 Microcontroller
PIC18F4550 is high performance microcontroller at economical price. It has
enhanced flash memory as program memory. It is fully compliant to the USB
communication module. It supports low speed and full speed USB transactions. It
17
supports control, interrupt, isochronous and bulk transfers. PIC18F4550 can be connected
up to 16 bidirectional endpoints.PIC18F4550’s pin diagram is shown in figure 3.2.1.
PIC18F4550 chip has 40 pins for connection. It has dual in package and has five
input/output ports. Figure 3.2.1 show PIC18F4550 IC.
Figure 3.2.1 PIC18F4550 [2]
18
Pin Name
Pin
Number
MCLR/VPP/RE3 1
I/O
Description
I
Master Clear or programming voltage
RA0-RA5
2-7
I/O
Bidirectional I/O port
RE0-RE2
8-10
I/O
Bidirectional I/O port.
VDD
11,32
Power Positive supply for logic
VSS
12,31
Power Ground reference for the logic
OSC/CLK1
13
I
Oscillator crystal or external clock input
OSC2/CLK0
14
O
Oscillator crystal or external clock output
RC0-PC7
15-17,
23-26
18
I/O
Bidirectional I/O port.
O
Internal USB 3.3 voltage regulator output
RD0-RD7
19-22,
27-30
I/O
Bidirectional I/O port or
Streaming Parallel Port (SPP)
RB0-RB7
33-40
I/O
Bidirectional I/O port.
PORT B can be software programmed for the
internal weak pull ups on the inputs
VUSB
Table 3.2.1 PIC18F4550 Pin Description [2]
3.3 Oscillator
The PIC18F4550 device can be operated in twelve different oscillator modes. In
HS, HSPLL, XT and XTPLL oscillator modes, a crystal is connected to the OSC1 and
OSC2 pins to establish oscillation. Table 3.3.1 provides various capacitor and crystal
combinations for design. An internal postscaler allow users to select a clock frequency
other than that of the crystal. The frequency division is determined by the CPUDIV
19
configuration bits. Users may select a clock frequency of the oscillator frequency or 1/2,
1/3 or 1/4 of the oscillator frequency. An external clock may be used when the
microcontroller is in HS mode. In this case the OSC2 pin is left open. Figure 3.3.1 shows
the crystal connection with the PIC microcontroller.
Figure 3.3.1 Oscillator Connection to the PIC18F4550 [2]
When the PIC18F4550 is used for the USB connectivity, it must have either 6
MHz or 48MHz clock for USB operation, depending on whether Low-speed or Full
speed mode is being used. Because of the unique requirements of the USB module must
be clocked using the primary clock source. The USB module, in either mode can run
asynchronously with respect to the microcontroller core and other peripherals. This
means that the USB module can runs on the primary oscillator and the other application
can use different clock frequency at lower speed. If require to run entire application from
only one clock source, full speed provides a greater selection of the microcontroller
frequencies.
20
Crystal frequency Capacitor C1 Value Capacitor C2 Value
4 MHz
27 pF
27 pF
8 MHz
22 pF
22 pF
20 MHz
15 pF
15 pF
Table 3.3.1 Various Capacitor and Crystal Combination [2]
In our design we are using 20 MHz Saronix oscillator. The oscillator has 4 pins
such as ground, output, Vcc and N/C.
3.4 PICKit 2
PICKit 2 is low cost PIC microcontroller programmer device. It is capable of
programming most of Microchip’s flash microcontroller.
The Status LEDs indicate the status.

Power (green): Power is applied to the PICKit 2 microcontroller programmer
via USB port.

Target (yellow): The PICKIt2 microcontroller programmer is powering the
target device.

Busy (red): The PICKit 2 microcontroller programmer is busy with a function.
The Push button is used for initiating a function that will be implemented in near
future.
21
Figure 3.4.1 PICKit 2 [5]
PICKit 2 has 6 pins. These pins connect programmer to the microcontroller
device. The power to the programmer device is supplied using the USB port. The USB
port connection is a USB `mini-B connector. Connect the PICKit 2 microcontroller
programmer to the PC using the USB cable. Figure 3.4.2 shows pin description of the
PICKit 2.
Figure 3.4.2 PICKit 2 Pin Description [5]
22
Chapter 4
DESIGN IMPLEMENTATION AND FINAL RESULTS
This chapter focuses on the hardware implementation of the design. This chapter
explains block diagram of the design. It also discusses things need to be checked during
hardware implementation, software development process and PIC18F4550 firmware
development.
4.1 Block Diagram of the Design
Figure 4.1.1 Block Diagram of the Design
23
4.2 Hardware Implementation
To implement the PIC18F4550 based USB storage, the components such as
breadboard, PIC18F4550 microcontroller IC, PICKit 2 programmer, Saronix 20 MHz
oscillator, USB type B connector, 4 LEDs, registers, capacitors and wires are required.
All these components are connected as per the block diagram in the Figure 4.1.1.
The Microchip PIC18F4550 microcontroller is used in the design. It has in built
circuit programmer (ICSP). The microcontroller is programmed using the PICKit 2
programmer. In the design Saronix 20 MHz crystal is used for the clocking the circuit.
Two 20 pF capacitors are connected to stabilize output of the oscillator. Two 100 pF
capacitors are connected to VSS and VCC. These capacitors are used as protection for the
circuit against sudden power supply swings. The circuit is USB bus powered. It draws
required voltage supply from the USB bus itself. Therefor it doesn’t require external
power supply for operation. One 470pF capacitor is connected to the VBUS pin of the
microcontroller. This capacitor regulates the voltage supplied by the USB bus.
USB
type B connector is used to connect the circuit to the computer. This connector has four
pins, supply, ground, data in and data out. 4 LEDs are also used to check the status of the
circuit. The first LED indicates the circuit is ready for the communication. The second
LED blinks when the device is successfully enumerated on the host. The third LED
indicates commands are correctly processed. The fourth LED indicates failure in
communication.
24
After mounting all the components on the breadboard, the circuit is checked for
connectivity using the buzzer to makes sure there is no loose connection between
components. All pin connections of PIC18F4550 microcontroller are checked. The wrong
pin connections can severely damage the circuit and lots of designer time could be wasted
in debugging circuit. The oscillator connection is double checked because that is one of
the most important parts of the circuit. The microcontroller won’t work without the clock.
Connection for the USB type B connector also checked. Once all the connections are
checked, device is connected to computer using the USB cable.
4.3 Software Implementation
The software implementation part can be divided in PIC18F4550 firmware
development and C# Graphical User Interface (GUI) development.
4.3.1 Firmware development
The firmware is based on the Microchip USB stack. The main file (main.c) is
shown in the appendix. All the transactions in the project are implemented as bulk data
transfers. Figure 4.3.1.1 shows flowchart of the firmware development. In the firmware I
have implemented various commands for the different test cases. These commands are
implemented in the processIO function as shown Figure 4.3.1.1

Test-1: “The single packet write to device” has been implemented by
command 0x80.This command receives a single command and data packet
25
from the host. It contains the command byte and then the number 1-63 in the
remaining bytes.

Test 2: “The single packet read/write” is implemented by command 0x81.The
firmware generates return packet and passes it back to the host.

Test 3: “The single packet write and 128 packet read” is implemented with the
command 0x82. This command receives a command from the host following
128 64 byte packet containing data. In this the host is bulk transferring data to
the USB device.

Test 4: “The 128 packet write and single packet read” is implemented using
the command 0x83.This command receives a command from the host
followed by the 128 64 bytes packet containing data. In this command the
device is bulk transferring data to the host.

Test 5: “The single packet write and time out on read” is implemented using
the 0x84 command. This commands implementation is different than the other
command implementation. On the host side it simulates failure scenario when
device doesn’t respond to command. This is useful for the testing the Visual
C# GUI.
26
Include header files
Configure the 18F4550 Fuse
Success indicator
Global Variable
Failure indicator
Global Variable
Declare the
Variable required for the keeping
track a bulk receive command
Declare the
Variables required for the keeping
track of a bulk send command
Main Function
Main()
Process input and output
ProcessIO()
Intialize system
InitializeSystem()
Figure 4.3.1.1 Flowchart of Firmware Development
27
4.3.2 Graphic User Interface Development
The GUI is developed using the Visual C#. It uses the C# class library to
communicate with the PIC18F4550 firmware. It provides a simple five tests. It allows
user to choose between the different test options. The application implements commands
and data to send device. It also interprets the data and responses received from the device
firmware as an acknowledgement.
The Visual C# class library provides USB device ‘events’. It will let application
know when the USB device is connected and disconnected from the host. The GUI
window will show “device attached” when USB device is connected and “device
detached” when the USB device is disconnected from. And also the C# USB device
events disable the application buttons when no device is found on the host.
The tests in GUI window correspond to the five commands implemented in the
firmware. When you click a test button on the GUI, the command is sent to the firmware.
Then both the host and firmware respond with the result of the command. If the
command has passed through successfully than GUI will show “test passed" otherwise it
will show “test failed”.
The application is built on the C# USB generic Human Interface Device (HID)
class library. This HID class library provides the base classes for the application building.
The application defines a custom class for its own device. This class inherits all the
functions from the base-class. Then it extends base-class to include its own custom
28
methods for communicating with the device. In this project, custom class has interface
from the commands such as 0x80, 0x81, 0x82, 0x83, and 0x84.
4.4 Results
This section discusses final hardware and software implementation results.
4.4.1 Hardware implementation Results
Figure 4.4.1.1 shows picture of final hardware. It has been mounted on the
breadboard. It is connected to the computer via USB.
Figure 4.4.1.1 Final Hardware
29
4.4.2 Software Implementation Results
This section shows GUI after different test cases has been applied. Figure 4.4.2.1
shows GUI when there is no device connected. At the bottom right corner, GUI shows
“USB Device Status Unknown”.
Figure 4.4.2.1 GUI When USB Device Is not Connected
30
Figure 4.4.2.2 shows GUI after, USB device is detected on the personal computer.
At the bottom right corner, GUI shows “USB Device is attached”.
Figure 4.4.2.2 GUI After USB Device Is Connected
31
Figure 4.4.2.3 shows GUI after, first three tests are successfully done. It also
displays first 3 test as passed and rest as test not performed.
Figure 4.4.2.3 GUI After First 3 Tests Are Passed
32
Figure 4.4.2.4 displays GUI after, the test 5 is done. Test 5 disconnects the USB
on the PC. At bottom right corner, it shows “USB device is detached”. The buttons will
be deactivated.
Figure 4.4.2.4 GUI After All The Tests Are Done
33
Chapter 5
CONCLUSION AND FUTURE DEVELOPMENT
The project has successfully achieved its goal of communicating with the
computer and reading and writing bytes of data using USB interface. In the project five
different test cases have been tested.

Single packet write to device

Single packet read/write

Single packet write, 128 packets read

128 packet write, single packet read

Single packet write, timeout on read
The implantation of the USB device was very good learning experience for me. I
have understood USB protocol, how to implement firmware for the PIC microcontroller
and how to design GUI in Visual C#.
5.1 Future Development:
USB is very popular serial bus. PIC microcontroller has USB 2.0 built in. That’s
an advantage for the PIC18F4550 Microcontroller. Variety of different applications can
be developed using wonderful features of the PIC18F4550. As during project we have
developed a C# GUI, different graphic user interface can also be developed for those
applications.
34
APPENDIX
#ifndef MAIN_C
#define MAIN_C
//Global includes
#include <htc.h>
// Local includes
#include "usb.h"
#include "HardwareProfile.h"
#include "usb_function_hid.h"
#include "genericHID.h"
#include "debug.h"
// Ensure we have the correct target PIC device family
#if !defined(__18F4550)
#error "This firmware only supports either the PIC18F4550”
#endif
// PIC18F4550 fuse configuration
// Config word 1 (Oscillator configuration)
// 20Mhz crystal input scaled to 48Mhz and configured for USB operation
__CONFIG(1, USBPLL & IESODIS & FCMDIS & HSPLL & CPUDIV1 & PLLDIV5);
// Config word 2
__CONFIG(2, VREGEN & PWRTDIS & BOREN& BORV20 & WDTDIS &
WDTPS32K);
// Config word 3
35
__CONFIG(3, PBDIGITAL & LPT1DIS & MCLREN);
// Config word 4
__CONFIG(4, XINSTDIS & STVREN & LVPDIS & ICPORTDIS & DEBUGDIS);
// Config word 5, 6 and 7 (protection configuration)
__CONFIG(5, UNPROTECT);
__CONFIG(6, UNPROTECT);
__CONFIG(7, UNPROTECT);
// Globals
// Success indication globals (used to keep the success LED on so you can see it)
long intsuccessIndicatorCounter = 0;
unsigned char successIndicatorFlag = FALSE;
// Failure indication globals (used to keep the failure LED on so you can see it)
long intfailureIndicatorCounter = 0;
unsigned char failureIndicatorFlag = FALSE;
// Variables required for keeping track of a bulk receive command
unsigned char bulkReceiveFlag = FALSE;
intbulkReceivePacketCounter = 0;
intbulkReceiveExpectedPackets = 0;
// Variables required for keeping track of a bulk send command
unsigned char bulkSendFlag = FALSE;
intbulkSendPacketCounter = 0;
intbulkSendExpectedPackets = 0;
36
// Initialize system
static void InitialiseSystem(void)
{
// PIC port set up --------------------------------------------------------
// Default all pins to digital
ADCON1 = 0x0F;
// Configure ports as inputs (1) or outputs(0)
TRISA = 0b00000000;
TRISB = 0b00000000;
TRISC = 0b00000000;
#if defined(__18F4550)
TRISD = 0b00000000;
TRISE = 0b00000000;
#endif
// Clear all ports
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
#if defined(__18F4550)
PORTD = 0b00000000;
PORTE = 0b00000000;
#endif
37
// USB set up -------------------------------------------------------------
// USB stack and parameter initialization
#if defined(USE_SELF_POWER_SENSE_IO)
tris_self_power = INPUT_PIN;
#endif
// Initialize the variable holding the handle for the last
// transmission
USBOutHandle = 0;
USBInHandle = 0;
// Call the stack initialisation functions
USBDeviceInit();
}
// Process input and output
void ProcessIO(void)
{
// If we are not in the configured state just return
if((USBDeviceState< CONFIGURED_STATE)||(USBSuspendControl==1))
{
// We are not configured, set LED1 to off to show status
LED1 = OFF;
38
return;
}
// We are configured, show state in LED1
LED1 = ON;
// Check to see if the success indicator is on and update the delay counter
if (successIndicatorFlag == TRUE)
{
LED2 = ON;
successIndicatorCounter++;
if (successIndicatorCounter == 20000)
{
LED2 = OFF;
successIndicatorCounter = 0;
successIndicatorFlag = FALSE;
}
}
// Check to see if the failure indicator is on and update the delay counter
if (failureIndicatorFlag == TRUE)
{
LED3 = ON;
failureIndicatorCounter++;
if (failureIndicatorCounter == 80000)
{
39
LED3 = OFF;
failureIndicatorCounter = 0;
failureIndicatorFlag = FALSE;
}
}
// Note: For all tests we expect to receive a 64 byte packet containing
// the command in byte[0] and then the numbers 0-62 in bytes 1-63.
unsigned charbufferPointer;
unsigned char expectedData;
unsigned char dataReceivedOk;
unsigned char dataSentOk;
// Check if data was received from the host.
if(!HIDRxHandleBusy(USBOutHandle))
{
// Test to see if we are in bulk send/receieve mode, or if we are waiting for a
command
if (bulkSendFlag == TRUE || bulkReceiveFlag == TRUE)
{
// We are either bulk sending or receieving
// If we are bulk sending, check that we are not busy and send the next
packet
if (bulkSendFlag == TRUE &&
!HIDTxHandleBusy(USBInHandle))
{
40
// Send the next packet
expectedData = bulkSendPacketCounter;
for (bufferPointer = 0; bufferPointer< 64; bufferPointer++)
{
ToSendDataBuffer[bufferPointer] = expectedData;
}
// Transmit the response to the host
USBInHandle =
HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64);
// Add this following delay in if you want to simulate a slow transfer
// from a busy PIC when testing bulk sends:
// for (long int counter = 0; counter < 1000; counter++) __delay_us(100);
bulkSendPacketCounter++; // Next packet
// Are we done yet?
if (bulkSendPacketCounter == bulkSendExpectedPackets)
{
// All done, indicate success and go back to command mode
bulkSendFlag = FALSE;
successIndicatorFlag = TRUE;
}
}
41
// If we are bulk receiving get the next packet
if (bulkReceiveFlag == TRUE)
{
// The received data buffer is already filled by the USB stack
// we just have to confirm the data integrity
expectedData = bulkReceivePacketCounter;
for (bufferPointer = 0; bufferPointer< 64; bufferPointer++)
{
// If the data isn't what we expected, turn on the failure light
if (ReceivedDataBuffer[bufferPointer] != expectedData)
failureIndicatorFlag = TRUE;
}
bulkReceivePacketCounter++;
// Are we done yet?
if (bulkReceivePacketCounter == bulkReceiveExpectedPackets)
{
// All done, indicate success and go back to command mode
bulkReceiveFlag = FALSE;
successIndicatorFlag = TRUE;
}
}
}
42
else
{
// Command mode
switch(ReceivedDataBuffer[0])
{
// Debug information request from host
case 0x10:
// Copy any waiting debug text to the send data buffer
copyDebugToSendBuffer();
// Transmit the response to the host
if(!HIDTxHandleBusy(USBInHandle))
{
USBInHandle =
HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64);
}
break;
// Place application specific commands here:
// Test 1 - Single packet write to device
case 0x80:
debugOut("Received command 0x80 from host");
// Test the receieved data
expectedData = 0;
dataReceivedOk = TRUE;
43
for (bufferPointer = 1; bufferPointer< 64; bufferPointer++)
{
if (ReceivedDataBuffer[bufferPointer] != expectedData)
dataReceivedOk = FALSE;
expectedData++;
}
// Display the test result
if (dataReceivedOk == TRUE)
{
successIndicatorFlag = TRUE;
debugOut("Successfully received 63 bytes of data from
command 0x80");
}
else
{
failureIndicatorFlag = TRUE;
debugOut("Failed to receive 63 bytes of data from command
0x80");
}
break;
// Test 2 - Single packet read/write
case 0x81:
debugOut("Received command 0x81 from host");
// Test the receieved data
44
expectedData = 0;
dataReceivedOk = TRUE;
for (bufferPointer = 1; bufferPointer< 64; bufferPointer++)
{
if (ReceivedDataBuffer[bufferPointer] != expectedData)
dataReceivedOk = FALSE;
expectedData++;
}
// If we got the data correctly, send the response packet
if (dataReceivedOk == TRUE)
{
debugOut("Successfully received 63 bytes of data from command
0x81");
expectedData = 0;
dataSentOk = TRUE;
for (bufferPointer = 0; bufferPointer< 64; bufferPointer++)
{
ToSendDataBuffer[bufferPointer] = expectedData;
expectedData++;
}
// Transmit the response to the host
if(!HIDTxHandleBusy(USBInHandle))
{
45
USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64);
}
debugOut("Sent 64 bytes of data to the host from command
0x81");
// Show our success
successIndicatorFlag = TRUE;
}
else
{
failureIndicatorFlag = TRUE;
debugOut("Failed to receive 63 bytes of data from command
0x81");
}
break;
// Test 3 - Single packet write, 128 packets read
case 0x82:
debugOut("Received command 0x82 from host");
// Test the receieved data
expectedData = 0;
dataReceivedOk = TRUE;
for (bufferPointer = 1; bufferPointer< 64; bufferPointer++)
{
if (ReceivedDataBuffer[bufferPointer] != expectedData)
46
dataReceivedOk = FALSE;
expectedData++;
}
// If the receive was ok, go into bulk sending mode
if (dataReceivedOk == TRUE)
{
debugOut("Successfully received 63 bytes of data from command
0x82, now bulk sending");
// Go into bulk sending mode...
bulkSendExpectedPackets = 128;
bulkSendFlag = TRUE;
bulkSendPacketCounter = 0;
}
else
{
failureIndicatorFlag = TRUE;
debugOut("Failed to receive 63 bytes of data from command
0x82");
}
break;
// Test 4 - 128 packets write, single packet read
case 0x83:
47
debugOut("Received command 0x83 from host");
// Test the receieved data
expectedData = 0;
dataReceivedOk = TRUE;
for (bufferPointer = 1; bufferPointer< 64; bufferPointer++)
{
if (ReceivedDataBuffer[bufferPointer] != expectedData)
dataReceivedOk = FALSE;
expectedData++;
}
// If the receive was ok, go into bulk receiving mode
if (dataReceivedOk == TRUE)
{
debugOut("Successfully received 63 bytes of data from command
0x83, now bulk sending");
// Go into bulk sending mode...
bulkReceiveExpectedPackets = 127;
bulkReceiveFlag = TRUE;
bulkReceivePacketCounter = 0;
}
else
failureIndicatorFlag = TRUE;
48
break;
// Test 5 - Single Packet write, timeout on read
case 0x84:
debugOut("Received command 0x84 from host");
// Here we receive a command which expects a reply, but we
// deliberately don't send one to test the timeout mechanisms
// in the communication class
// Test the receieved data
expectedData = 0;
dataReceivedOk = TRUE;
for (bufferPointer = 1; bufferPointer< 64; bufferPointer++)
{
if (ReceivedDataBuffer[bufferPointer] != expectedData)
dataReceivedOk = FALSE;
expectedData++;
}
// Display the test result
if (dataReceivedOk == TRUE) successIndicatorFlag = TRUE;
else failureIndicatorFlag = TRUE;
// Now we quit without replying
break;
default:
// Unknown command received
49
break;
}
}
// Only rearm the OUT endpoint if we are not bulk sending
if (bulkSendFlag == FALSE)
{
// Re-arm the OUT endpoint for the next packet
USBOutHandle =
HIDRxPacket(HID_EP,(BYTE*)&ReceivedDataBuffer,64);
}
}
}
// Main function
void main(void)
{
// Initialise the microcontroller
InitialiseSystem();
// Initialise the debug log functions
debugInitialise();
// Show that we are up and running
LED0 = 1;
debugOut("USB Generic firmware started");
50
debugOut("USB Device Initialised...");
while(1)
{
// Check bus status and service USB interrupts
USBDeviceTasks();
// Application-specific tasks
ProcessIO();
}
}
#endif
51
REFERENCES
[1]
Craig Peacock, “USB in a nutShell”, Release 4th edition, September 2010
[2]
Microchip Techonology, “PIC18F2455/2550/4455/4550 Data Sheet”, Version C
Document Number DS39632
[3]
Don Anderson,”USB System Architecture”, MindShare, Inc, 1997
[4]
Jan Axelson, “USB Mass Storage: Designing and Programming Device and
Embedded Hosts”, Lakeview Research (September 1, 2006)
[5]
Microchip Technology “PICKit. 2 Programmer/Debugger User’s Guide”,
Document Number DS51553E, 2008
[6]
Technical Data, “Saronix Crystal Clock Oscillator”, Document Number DS-183.
Revision C
Download