CSE 466 Lab 4: SPI and USB
Introduction
In this lab, you will interface your electric field sensor to a PC over
a USB connection. You will use the PC to calibrate the data
received from the sensor and provide a simple graphical interface that
plots the position of a hand relative to the sensor over time.
Important
Warnings:
- Do not plug more than one DLP2232M USB module into the
same computer. To make sure that the lab drivers work
properly on all of the lab machines, all of the DLP2232M modules have
been set up with the same serial number. This ensures that
Windows will recognize the device and will automatically load the
correct drivers. However, Windows will crash if it sees
two active USB devices with the same serial number.
- DO NOT CONNECT POWER
DIRECTLY TO THE DLP2232M. It will get its power
from the USB connection. You should, however, connect the
DLP2232M's ground to your circuit's ground.
- Do not try to run the PC-side application that is
provided from your Z: drive (or any other network drive.) The
.NET applications must be run from a local drive (C:) or you will get
JIT compilation errors.
Objectives
In this lab, you will learn:
- how to use SPI to transfer data to and from a
microcontroller and a peripheral device
- how to use a USB controller chip and use it to interface a
microcontroller to a PC
- how to develop a reasonable communication protocol
- how to build a complete USB device
Hints
- Practice
incremental design. Take this lab step by step and test
along the way to make sure you understand your code and verify that it
is working as you expected. Coding the entire project then trying to
debug a problem can be challenging. Make sure to test pieces
of the assignment one at a time and convince yourself that they are
working before moving on to another piece.
- Utilize the tri-color LED and JTAG for debugging. WARNING: If you
update the tri-color LED each time through your main loop you might not
be able to see individual color changes because they will be changing
too rapidly.
- Focus on making your system have a reasonable
interface. The electric field sensor is inherently somewhat
noisy; try to create an interface that feels right to a human.
The user will not notice timing delays of a few milliseconds
between changing hand position and updating the LED.
Suggested Reading and Resources
Part 1: Introduction to SPI
- Remove the 7-segment LED display and its resistors from
your board.
- Add the USB interface to your breadboard. Review the important warnings,
and DO NOT connect the 5V power supply on your breadboard to the USB
module! (Do, however, connect ground.) Refer to
Page 14 of the DLP2232M
datasheet to see how to wire the device in a USB bus-powered
configuration.
- Connect the DLP2232M module to your ATmega16 as follows:
DLP2232M |
ATmega16 |
TCK/SK |
SCK |
TDI/DU/DO |
MOSI |
TDO/DI |
MISO |
TMS/CS |
~SS |
- Download the sample
SPI/USB code for the PC. You should only need to modify
SPI-USB.cpp for Part 1. FTDI466API was created to abstract
away setup and DLL details. The sample code will configure the USB
device to act as an SPI master and send bytes using SPI protocol. The
clock rate of the transmission is initially set to 200kHz and with a
latency timer of 5ms (not exposed outside of FTDI466API) that will
cause the USB chip to flush information to the buffers. The latency
timer bounds the amount of time your code has to wait to receive
information back from the USB chip. Refer to the FTDI Chip
Application Note AN2232C-01 for information about the byte commands
being issued in the sample SPI/USB program. NOTE: The command byte 0x35
sends and receives bytes. It clocks data bytes out on the falling edge
of the clock and clocks data bytes in on the falling edge of the clock.
- Download connection-check.hex
and load it onto your Atmega chip. Run it in conjunction with the
SPI/USB code provided. Remember
you need to run the .exe file on the C: drive for it to run properly.
For every byte sent to the Atmega chip, a byte is recieved, which
starts at 0 and is incremented by 1 for each transmission. Change the
PC side byte values and the returned values will change as well. Once
you have verified that you wired up the connection between the PC and
your board, continue on to the next steps.
Question 1: How many ATmega16 cycles theoretically should
occur between
received SPI bytes? Assume the SPI is sending bytes continuously.
Question 2: What
command
byte would you use to only send information on
the negative clock edge (not receive anything at the same time)? What
command byte would you use to only receive information on the negative
clock edge (not send anything at the same time)? (Hint: refer to the
FT2232C Application Note AN2232C-01)
- Now that you have the hardware wired up correctly, you can
implement SPI slave functionality for your ATmega16, refer to the
datasheet. Test your code using the provided sample SPI/USB code.
Verify your SPI slave code is working by displaying the low 3 bits of
the last byte sent by the PC in binary on your tri-color LED (e.g. if
red=high bit, green=middle bit, blue=low bit then 0 = off, 1 = blue, 2
= green, etc) and by sending bytes back to the PC over the
SPI.
NOTE: The datasheet states: "The Slave may continue to
place new data
to be sent into the SPDR before reading the incoming data" It also
states: " The system is single buffered in the transmit direction and
double buffered in the receive direction" This single buffer can cause
a problem if the master is constantly sending bytes and your program
does not update the SPDR in time before the next shift sends (while the
send is occurring you cannot update the buffer). Some groups will not
experience this problem because they designed their program so that
they are updating SPDR fast enough. Others will have a problem because
their protocol does not cause them to send a byte in the middle of
packet. You will need to be able to consistently update the value to
the SPDR at the right time to send the data.
Part 2: Interfacing your sensor to a PC
- In this part of the lab, you will use what you learned in
Part 1 to interface your electric field sensor to the PC. You
will develop a pair of applications: one on the ATmega16, and one on
the PC. The ATmega16 program will make measurements from the
sensor and send them to the PC. The PC application will
receive the readings from the sensor, scale the measurements to an
appropriate range, and display the measurement on a graph.
- Download the USB-SPI
starter code for the PC application located here. This code
is a slightly modified version of the SPI-USB sample code you used
earlier. In this lab you will be sending multiple bytes in multiple
directions so you will need to develop
and implement a protocol. Your protocol will need to
operate under a polling
model initiated by the PC master.
- Implement a program on the ATmega16 to take readings from
the electric field sensor and communicate these values back to the PC
via SPI and the DLP2232M module. It may be helpful to start
with your code from Lab 3, Part 5, where you should have already
written code to read from the sensor.
- Note that you will need to send 16-bit sensor readings to
the PC, so your communications protocol will need to take this into
account.
- Don't worry about doing any scaling of the measurements on
the ATmega16. You can do this on the PC where you have more
processing power and floating-point capability.
- Fill in your own code in processByte() in the USB-SPI PC
application to request values from the ATmega16 and print out the
values it receives. Experiment with the sensor and verify
that it works as intended and that the values on the PC change as you
move your hand up and down.
NOTE: As in the previous lab, other
tasks executing on the microcontroller
can affect the accuracy of the e-field sensor. Try to keep
interrupt service routines short and only as frequent as necessary, and
consider the timing of how various events can occur. Think
about how SPI communication that occurs during a reading might affect
the reading.
Part 3: Finishing touches
- In this part of the lab, you will make improvements to your
PC application to give it a better interface.
- Write a simple calibration routine that executes when you
start your program. You can set it up so that the first n samples that you
read from the sensor are used to calibrate it, and subsequent samples
are displayed normally. Choose n such that the
user has enough time to calibrate the sensor, but calibration doesn't
take longer than necessary. Your program should print a
message that informs the user that calibration is occurring and
explains what he or she needs to do (e.g. move his or her hand up and
down.)
- Your calibration should provide a baseline so that you can
scale the readings from your sensor between 0 and 80. 80
should correspond to a hand that is far away from the sensor, and 0
should be very close to the sensor.
- Modify your program to print out an asterisk (or some other
character of your choice) in the column that corresponds to the scaled
value for each reading you take from the sensor, after calibration is
complete. For example, if the scaled reading was 76, you
would print 75 spaces and then an asterisk, followed by a newline.
This will produce a crude, continuously scrolling graph, with
time on the Y-axis and the sensor reading on the X-axis. You
should plot a new "point" approximately ten times per second.
- Finally, send information back to the ATmega16 so that the
RGB LED is blue when your hand is far away, green when your hand is
moderately close to the sensor, and red when your hand is very close.
You only need to display pure colors at set thresholds; you
do not need to use PWM. Try to incorporate some hysteresis so
that the LED does not flicker between two colors if your hand is
positioned right on the boundary.
Question
3: Describe your protocol for sending bytes back and forth
on
the SPI interface. Include descriptions of all command bytes
used in your protocol and sketches of any relevant state machines.
Part 4: Other things to try
There are several more features
that you can try adding to your USB device. These are not
required, but may be worth some extra credit if they are implemented
well.
- Use PWM to set the color of the LED, so that there is a smooth transition between colors. In previous quarters, Lab 3 included a discussion of color spaces. These lecture slides
from Winter 2007 include some information that may help you adjust the
color (hue) of the LED without changing its brightness or saturation.
- Make
the PC application take a command line argument that sets the number of
samples to use for each measurement from the e-field sensor.
- Connect a pushbutton to your circuit and use it to tell the PC to recalibrate the sensor after the program is already running.
Deliverables
- The following files should be turned in:
- Your ATmega16 code for Part 3 (include comments!)
- Any files you modifed in your PC application (include comments!)
- Your answers to the questions (.txt, .rtf, .pdf, or .doc; NO .docx)
- Submit files to the Catalyst drop box for your section:
- Demonstrate
your complete system from Part 3 to a TA during the first half-hour of
next week's lab period. Grading will focus on the following
considerations:
- whether or not the system works
- whether the interface is reasonable for the user
- minimizing code in the interrupt handlers