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:
  1. 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.
  2. 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.
  3. 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:

Hints

Suggested Reading and Resources

Part 1: Introduction to SPI

  1. Remove the 7-segment LED display and its resistors from your board.
  2. 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.
  3. Connect the DLP2232M module to your ATmega16 as follows:
    DLP2232M ATmega16
    TCK/SK SCK
    TDI/DU/DO MOSI
    TDO/DI MISO
    TMS/CS ~SS
  4. 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.
  5. 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)
  1. 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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

  1. In this part of the lab, you will make improvements to your PC application to give it a better interface.
  2. 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.)
  3. 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.
  4. 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.
  5. 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.
  1. 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.
  2. 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.
  3. Connect a pushbutton to your circuit and use it to tell the PC to recalibrate the sensor after the program is already running.

Deliverables

  1.  The following files should be turned in:
  2. Submit files to the Catalyst drop box for your section:
  3. 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: