Thursday, July 5, 2012

Implementing Artcfox's TLC5940 code on an Arduino, Part 2

In my last post I detailed the basic hardware and software setup for getting Matt's TLC5940 chapter 3 code working on an Arduino. The the code doesn't do too much, but with the hardware and software working we can start to explore later chapters (where the interesting stuff happens).

At this point there is one more hardware obstacle to overcome. Matt makes use of an interesting feature of the Atmega328p called CKOUT. This is a chip level setting that can (according to the 328p datasheet) "output the system clock on the CLKO pin". Matt uses this to drive the TLC5940's GSCLK pin, a very clever way of handling the timing between the two chips.

Unfortunately the Arduino is not configured to support this by default and in order to switch on this feature, special configuration values in the 328p's flash known as "fuses" need to be be set. To do that, you need a chip level programmer.

The programmer I use is an USBtiny2 clone that I got off eBay for about 10 USD (search for "usbtiny" or "usbtinyasp" and you should get many results). Alternatively you can use a second Arduino to accomplish the same thing as per this link. Lastly, if you want to support a really fantastic company and get a great programmer with a nice case, please consider this one from Adafruit.
From this point on I will be assuming that you are using the USBtiny programmer, are on a Windows machine and are intending to program the fuses of an Arduino UNO.

At this point I am assuming that you have managed to install the drivers for your programmer. If you are using the USBtiny and are on Windows7 64-bit, this link may be helpful. If not, visit this excellent tutorial at Adafruit and get the drivers installed.


Once you have the hardware, you need to get hold of AVRDUDE. This is the software that will talk to your programmer and allow you to set the fuse bits. As of this article the latest AVRDUDE version is 5.1.1 and can be found here. If you are using an alternative programmer, please check compatibility with AVRDUDE at this page (look for the "-c programmer-id" reference).

Grab the windows archive (avrdude-5.11-Patch7610-win32.zip) and extract to a convenient location. I used "C:\temp\avrdude". Now you will need to connect your programmer to your Arduino.

Arduino ICSP port

Using the supplied 6 pin cable connect the programmer to the ICSP port on your Arduino, making sure you have:

  • disconnected your Arduino from USB and any other circuitry.
  • correctly identified the polarity and orientation of the programming cable and pin 1 on the ICSP port of the Arduino.

Once you have the cable correctly connected, connect the programmer to usb and the Arduino should power on.

Assuming everything is good to go: open a command prompt, change to the directory you extracted the AVRDUDE software into earlier ("c:\temp\avrdude" for me) and type:

avrdude -p m328p -c usbtiny 

See the advanced notes for additional information.

This command should print out something pretty much like this:

AVRDUDE basic output

If you get this result, add a "-v" to the command:

avrdude -p m328p -c usbtiny -v

which should spew out a whole load of text ending in something that looks like this:

Standard Arduino UNO fuse settings

What we want to do is to change the value of the lfuse from 0xFF to 0xBF to enable CKOUT.

To verify this, open this awesome AVR fuse calculator in another tab / window and check the lfuse checkbox that reads "Clock output on PORTB0; [CKOUT=0]". You should see the calculated value for lfuse change from 0xFF to 0xBF (and back when you uncheck the option).

Before we proceed any further, a word of caution:

Incorrect fuse settings can brick your Arduino!!!

If your fuse settings are not the same as the screenshot above you probably shouldn't proceed unless you are sure you know what you are doing.

Some clarification: You need to know that you have a good fuse read at this point. Your values may be different to mine but as long as they are good values you'll be okay.

Thanks to +Al McElmon who reported his hfuse value as D6 not DE. In the fuse calculator you can see that this is because EESAVE has been enabled. This could possibly be a setting on later Arduino Models?

Finally, if everything checks out and you are 100% sure of this, we are one command away from completion:
avrdude -p m328p -c usbtiny -U lfuse:w:0xBF:m -u

This command will write the value 0xBF to the lfuse and set CKOUT.
For a breakdown the "-U" command above, the command:
  • selects the lfuse memory for the operation
  • writes (use r for read and v for verify)
  • the value 0xBF
  • in immediate mode (i.e. write the value specified directly)
"-u" turns off safe mode which should enable the actual write.

And there we have it. Your Arduino should now be in a state where we can move onto the more advanced chapters of Matt's book.

Next time we are going to do exactly that, I hope you've enjoyed this post.
Until then, happy hacking!
-(e)

p.s. If you get stuck, I can attempt to help you out, circle me on G+ and send me a message via Messenger, or post a comment and I'll see what I can do.


Advanced Notes:

Perhaps you have a different model of Arduino? (e.g. ATMega168 e.t.c.):

The "-p m328p" switch for AVRDUDE specifies what chip your Arduino has. The "m328p" value is valid for the Arduino UNO and several other models, but will have to be changed for alternative models.

In this case, when using the fuse calculator please input your values for lfuse, hfuse and efuse into the fuse calculator, ensure that you have the correct AVR chip selected and note the change in the lfuse value when CKOUT is selected. The point here is that we wish to change ONLY this value. You can also confirm default board fuse settings in the "boards.txt" file located in the "hardware\arduino" directory of the Arduino IDE installation.

AVRDUDE has many other switches and supports many other programmers. I would suggest that you check out the command line in the documentation.