USB IR Receiver

It has long been a goal of mine to create something electronical. The USB-IR-Boy project is interesting. It is an infrared sensor which would allow you to control your computer with a TV remote, but unlike the bulk of other projects, it interfaces via USB. The one problem with the program is it is not really aimed at a complete noob like myself. Fortunately, I'm a reasonably bright noob and I'm writing down what I'm doing as I go along.

DIP IC Pin Numbering

A lesson that I learned completely by accident after I had been wondering at why my designs wouldn't work for a while:

Many schematics group the pins on the IC by function and not by their actual position. Sometimes it is noted, but if you are paying attention to the labels, you can overlook it. So, pins 1 and n are next to each other, not pins 1 and n/2 + 1.

Programming the MC68HC908

The heart of the device is a Freescale MC68HC908 which translates the impulses from a Vishay TSOP 1738 IR receiver into the signalling for USB. The firmware for the microcontroller is produced by SDCC. I couldn't find a package for it, so I built it out from source:

svn co https://svn.sourceforge.net/svnroot/sdcc/trunk/sdcc sdcc
cd sdcc
./configure
make

Then to get the USB-IR-Boy project to build without installing everything, I just had to add sdcc/bin to the path and add -L ../../sdcc/device/lib/build/hc08/ to the linker options in the Makefile.


Testing the MAX232 Serial Driver

The programmer for the microcontroller will receive its instructions from the serial port on the programming computer. After attempting to build the entire thing at once and failing, I decided on an incremental development process. The simpest first step was simply to take the MAX232 serial driver and verify that it works. The serial cable has -25V for logial 0 and +25V for logical 1. This chip converts between those voltages and +5V for 1 and 0V for 0 which is used in the rest of the circuit.

Capacitance (µF)
DeviceC1C2C3C4C5
MAX2204.74.710104.7
MAX2321.01.01.01.01.0
MAX232A0.10.10.10.10.1

The current produced by the serial port should be sufficient to light a LED. This simple circuit was used in testing:

ToDo: MAX232 test circuit and program

Monitor Mode

The HC908 line of microcontrollers includes a "monitor mode" that allows writing the flash memory via routines stored in the ROM. The entirety of the flash may be written, including the IO/ports, making it possible to alter the output pins on the µ directly from the programmer. This test circuit does that:

ToDo: HC908 monitor test circuit and program


The USB specification defines a variety of states that a device can be in:

Hello World

For my first program, I wanted the simplest functional program possible. For USB, this is a program that registers itself with the host controler and goes into the addressed and then configured states. USB has a few different types of connections between the host and device. The simplest of these is a "control pipe" where messages and responses with a predefined structure are exchanged. Each USB device is required to set up a control pipe on endpoint 0. A device may have multiple additional endpoints which specify different data sources or different types of connections. The standard limits low-speed devices to two endpoints beyond endpoint 0 and the HC908JB8 supports an additional out pipe on endpoint one and either an in or an out on endpoint two.


The way that the hello world program works is this:

  1. The user plugs in the device
  2. The device raises the pull up voltage on the data pair
  3. The host issues a reset on the default configuration
  4. In the code there is a function void usb_interrupt_handler(void) interrupt 2. The interrupt 2 tells SDCC to invoke that function when a packet arrives, triggering an interrupt
  5. usb_interrupt_handler checks the USB Interrupt Register (UIR1) and sees the Receive Data flag for Endpoint 0 (RXD0F) is set
  6. The USB Control Register (UCR0) bits RX0E and TX0E are unset to disable send and receive on endpoint 0 for the duration of the exchange
  7. The receive flag is reset (RXD0FR)
  8. The USB Status Register (USR0) is checked and the packet is recognized as a setup packet (SETUP)
  9. The input data buffer (UE0D0) contains a USB_REQUEST packet
  10. The bmRequestType field of that packet is examined and the packet is a REQ_TYPE_STANDARD with a REQ_RECIP_DEVICE recipient
  11. The bRequest field of the packet is examined and it is a REQ_SET_ADDRESS packet
  12. The wValueof the packet is the assigned device address which is stored in the UADDR register
  13. An OUT packet with a length of 0 is sent to the host as an ACK
  14. A new interrupt is processed with another REQ_TYPE_STANDARD REQ_RECIP_DEVICE packet
  15. The bRequest on this packet is REQ_GET_DESCRIPTOR
  16. The high byte of wValue is DESCR_TYPE_DEVICE signaling the device descriptor should be sent
  17. An OUT packet with a length of 0 is sent to the host as an ACK
  18. An IN packet is received and specifies the number of bytes of the device descriptor to send
  19. After the device descriptor is sent, further requests for the manufacturer and product string descriptors referenced in the device descriptor are sent


Now I need to build the programmer. The problem is the original schematic is done in a lovely neon green on black background. When printed it is just about impossible to see the traces. So, I learned that schematic drawing under Linux is pretty crappy, but Kicad does a passable job. I made a schematic and then exported it to SVG. I collected the styles into a stylesheet, moved some elements around and compressed the pathes to produce a passable image:

So far as printing the image or viewing it in something other than Firefox, use Batik web start.


The parts that I bought for the project were mostly from Jameco:

Jameco Part #ItemQuantityUnit PriceTotal
14681Crystal, 6MHz, 50ppm, 18pF3$0.28$0.84
15341Ceramic Disc Capacitor, 100pF, 50V, 20%10$0.05$0.50
15405Ceramic Disc Capacitor, 22pF, 50V, 20% 10$0.07$0.70
17961Grab Bag Diodes, 200pcs1$5.95$5.95
18139Grab Bag Resistors, 1/2W, 200pcs1$5.95$5.95
20773Breadboard, 6.5"x 4.25", 1660pnts1$19.95$19.95
33488Tantalum Capacitor, .1uF, 35V, 10%10$0.25$2.50
106155MAX232EPE IC, DRV/REC, 5V1$3.19$3.19
1076092.2K OHM Resistor, 1/2W, 5%1$0.99$0.99
223052CKD-Sub Connector, Receptacle1$2.35$2.35
223280D-Sub Contact Crimp Pin, Female10$0.43$4.30
230957USB Connector, USB B PCB1$0.99$0.99
248401MC68HC908JB8JP IC, MCU, 8-BIT2$4.95$9.90
Shipping:$6.49
Total:$64.60

This seems a little pricey for an IR sensor, and it is. There are few reasons it is expensive:

  1. I had pretty much no parts to work with. I bought literally hundreds of capacitors and diodes that I will not use in this project
  2. I bought a breadboard to test with that I will reuse in future projects
  3. I have to build a programmer for the Motorola microcontroller. This will also be reusable in the future

The one part that I couldn't find from Jameco was the Vishay tsop1738. Those I ordered for 99¢ apiece from eBay.


For actually getting the firmware on the chip, I used Spgmr08 and followed the steps from the USB-IR-Boy documentation:

  1. su -c "./spgmr -P /dev/ttyS0"
  2. cpu jb8
  3. Power on the prommer
  4. scodes try blank
  5. erase
  6. Power off the prommer
  7. Power on the pormmer
  8. scodes try blank
  9. for new, never programmed chip, repeat steps 4-8 two times
  10. program from ~/hello_world.hc908jb8.s19