Onto the JTAG ICE
Last month, Fred introduced us to Atmel’s STK500, which is the starter kit for the company’s AVR flash memory microcontrollers. This month, he tackles coding and debugging with Atmel’s JTAG ICE. He’s thrilled with the result, so don’t miss this follow-up.
Between visits from the usual musically inclined guests and deploying the Atmel armed forces camped in the Florida Room, it’s been a busy month. Amidst the hustle, I realized that thus far I’ve had no problems getting help from the Atmel staff and the JTAG ICE and STK500 development board work perfectly together as an AVR microcontroller development system. In addition to the great Atmel hardware, I’m using some awesome supporting software products as well. I’ve installed a new and more helpful version of Atmel AVRStudio, and the ANSI-based ImageCraft AVR C compiler has proven to be just as good as AVR assembler when it comes to generating efficient AVR assembler code. The future’s so bright I need to wear RayBans. Some of the folks back home in Tennessee would say that I’m as happy as a hog loose in the corn crib.
I’ve been working toward putting one or both of the AVR devices I have in the Florida room on the Internet. In addition to the ATmega163 and ATmega16 parts, I’ve acquired some ATmega128 micros as well. I don’t have the STK501 plug-in that allows the STK500 development board to support the ATmega128 right now, but I will try to get my hands on one so I can do something down the road with the heavy-duty ATmega128 micro. At this point in time, I’m sure the ATmega16 and ATmega163 can handle the application at hand. So, with that let’s slip and slide our way towards the Internet on the JTAG ICE.
AVR JTAG ICE
The JTAG ICE functionality is enhanced with the new version 4 of AVRStudio. With an ATmega16 mounted on the STK500 development board and the JTAG ICE connected, I have a full view of the ATmega16 internals. I can also debug my code using ImageCraft’s ICCAVR C source or the AVR assembler generated by the ImageCraft AVR C compiler.
The JTAG ICE works its magic using a concept called on-chip debugging (OCD). Most of the microcontroller emulators that you and I have encountered use a specialized bond-out integrated circuit that contains the CPU and I/O cores of the microcontroller it’s emulating. Thus, the code is actually running on the bond-out device, and the supporting emulator hardware and software have the ability to reach into the bond-out and pull out the microcontroller internals for inspection and debugging. Instead of depending on a bond-out device, the JTAG ICE interfaces with the target AVR’s internal OCD system via the JTAG IEEE 1149.1-compliant interface.
Every AVR microcontroller with a JTAG pin set houses OCD logic. The JTAG ICE takes control of the target AVR and controls the execution of the firmware using the OCD logic via the target’s JTAG interface pin set. Because the code is actually running on the real device, the target device’s original electrical and timing characteristics are retained. The JTAG ICE/OCD combination has several advantages over traditional emulator methods, but there are some things this duo cannot perform. For instance, the trace buffer function is not a part of the OCD.
If you’ve ever had to interface to anyone’s emulator, you know that there are some basic operations common to them all. The JTAG ICE is no different. When the AVR JTAG ICE is in Run mode, code execution is not a JTAG ICE concern. JTAG ICE polls the running target looking for a break condition. When a break is sensed, the OCD goes to work and uses the JTAG interface to reach into the target AVR and pull out the same information a standard emulator would. Remember, the OCD doesn’t incorporate a trace buffer function. So, all you get is information captured at the time of the break event, minus execution history up to that point.
When a break point is encountered, program execution, as far as JTAG ICE is concerned, is halted. But, because the JTAG ICE doesn’t contain the CPU and I/O core of the device it’s attached to, the AVR I/O operations that were executing at the break point continue to run. The best example of this is the ability of a standard emulator to trace a UART transmit function bit by bit. JTAG ICE will only see the result of the operation because the I/O in the target will complete the operation regardless of the break point.
Speaking of break points, the AVR OCD can handle hardware and software break points. AVR software break points are placed in the normal code path. The instruction that resides at the selected software break point location is replaced by the break instruction. When the software break point is reached, the code execution halts. To continue, a start command must be issued to the OCD. At that point, the actual instruction at the break point is executed and the code moves on to completion or the next break point.
The AVR family is flash memory-based as far as program memory is concerned. So, using software break points is not as healthy as using hardware break points, in that every time you change the break point in your code you must reprogram the AVR as well. The AVRs are good for at least 1000 program flash-memory write/erase cycles. Theoretically, you can debug a guaranteed 1000 times using software break points exclusively. In my experience with flash memory-based microcontrollers, this 1000-cycle limit is conservative and I can recall only one time that I may have exhausted a part by reprogramming it beyond the prescribed write/erase limits.
If you feel you will exceed 1000 limit write/erase cycles during the development of your project, go for the hardware break point system offered by the JTAG ICE. The AVR OCD logic has four registers available that can each store one memory address. One of the four registers is reserved by the JTAG ICE for performing the single step function. That leaves three of the registers free for you to use as hardware break point containers.
Before you start to get comfortable with the JTAG ICE, three break point registers doesn’t sound like enough. The unique implementation of the three free hardware break point registers makes up for the seeming lack of break point quantity. You can use each break point as a general-purpose break point, which gives you three traditional set and clear break point types, or you can use up to two of the three break points as data break points with the leftover break points remaining for general-purpose use. If you want to get fancy, you can dedicate two break point locations to a mask that operates against the AVR’s SRAM or flash memory.
A general-purpose break point can be placed anywhere, including anywhere in an assembler program or anywhere a valid statement resides in a C program. The break will occur before the execution of the code at the break location. Data memory break points are a tad more complex. You must select one of three break point modes, which consist of a combination of reading and writing the data memory area (SRAM). Data memory break points are invalid for the Register file.
Because nothing is free, when it comes to embedded computing you pay for the data memory break points by having to use a symbolic variable-capable compiler or assembler. I’m using ICCAVR so I’m covered if data memory break points are in the future. Another difference to note is that the break occurs after executing the instruction when using the data memory break point feature.
Masked break points use an address base and address mask, which are ANDed together to generate the break points. The address base is a symbol name or a memory address. The result of the AND is then compared against the program counter or data address to check for a valid break condition. Setting a bit in the mask to zero makes that a “don’t care” bit position. “Don’t care” bits always generate a valid break point regardless of the logic level of the corresponding program counter or data address bit.
If the mask bit is a one, this forces the program counter or data address bit to be the same logic level as the corresponding bit in the base address. Think of the mask break point mask in this way: If you set all of the bits in the address mask high, only the base address would generate a break point. Conversely, if you set all of the mask bits low, all of the addresses would cause a break point. Like the data memory break points, the masked break points break execution after executing the instruction at the break point address. A real example of a masked break point is depicted in the double-wide screen shot in Photo 1.
There’s one more break point that has absolutely nothing to do with the general-purpose break points: break on branch/skip. This break point works on a change of program flow. That means that anything that interrupts the normal flow of a program such as jumps, branches, calls, skips, or interrupt handling will generate a break point after executing the instruction that caused the break point.
I have used the three general-purpose hardware break points and single stepping for most of the debugging so far. Despite the absence of certain standard emulator features, the JTAG ICE and AVRStudio version 4 do a good job of telling you what’s going on inside that target ATmega micro.
While I’m on the subject of what’s inside, I could not resist taking my JTAG ICE apart to see what makes it tick. From left to right in Photo 2, the first IC is a MAX232 RS-232 interface. The 44-pin TQFP next to it is an ATmega163 running at 7.37 MHz. It really makes me feel good to know that Atmel uses its own stuff to build its development tools. The large IC surrounded by who knows what is a 74HC244D octal buffer that is being protected by a couple of ProTek Devices SM16LC08 high-speed TVS diode arrays. The rest of the high-rise components and their strip malls handle the JTAG ICE power details. The bottom line is that the real tricks are done with AVR firmware and the AVRStudio front-end code.
USING THE JTAG ICE
The JTAG ICE comes with everything you need to get you coding and debugging quickly. Most of the JTAG ICE installation process was a no-brainer. But, the person or machine that assembled the 10-pin JTAG interface ribbon cable had me swinging at a slider. Because the Atmel engineers went to the trouble of color coding the JTAG-to-STK500 development board ribbon cable and meticulously detailing the JTAG ICE JTAG header, it would have been easy to just trust the colors and connect the JTAG ICE to the STK500 development board with the brown lead being pin 1, the red lead pin 2, and so forth.
If this isn’t your first time reading my words in Circuit Cellar, you know that I have an affinity for smoking things. To avoid letting the magic out of the little plastic boxes, I’ve started checking everything and trusting nothing. As it turns out, the ribbon cable was assembled in the reverse order with the brown lead representing pin 10 of the JTAG connector and the black lead posing as pin 1. I scratched my head, gathered my thoughts, hooked the suspect JTAG cable to a VOM, and shot the leads. I wasn’t losing it; the cable was indeed assembled backwards.
I continued on with the installation process and connected the JTAG ribbon cable “backwards” and was able to use the JTAG ICE without melting it. I really don’t think I would have harmed anything if I had not been attentive. It just wouldn’t have worked until I corrected the wiring. That’s really the only problem I had during the JTAG ICE install. I was able to obtain all of the latest firmware and front-end software from the Atmel web site and from there I was off to the races. My AVR development system hardware is shown naked in Photo 3.
I develop with a dual-head monitor system. This allows me to put the ICCAVR application on the right monitor and AVR Studio on the left monitor. The ImageCraft AVR C compiler IDE is excellent. I am able to segregate my code using projects. I created a separate test project to actually code and debug my AVR C code one module or line at a time. In the same ImageCraft IDE window structure, I opened another window of C source that would eventually be the completed working code that would be loaded into the ATmega16. The final working code window code is not included in the test project. I debugged code snippets in the test project and moved the working routines over to the final code window as I finished them. All of the code writing and compilation was performed on the ImageCraft screen.
The left display is where all of the JTAG ICE programming and debugging took place. The STK500 development board has an on-board ISP programming header to allow the socketed AVR to easily be programmed using AVRStudio. The JTAG ICE is a good AVR programmer as well. I’ve included a 10-pin ISP header on the AVR Internet device. This will allow me (and you) to program the ATmega16 in socket using any device that supports AVR ISP, like the Kanda dongle.
I found myself going from datasheet to user’s guide to application notes often during the development process. I was pleased to discover the Info feature of AVRStudio 4. With this feature, I could simply point at an AVR subsystem in the Workspace window and get a short description of what the subsystem was made of and how it worked. Also, being able to see the bit structure for a register or I/O location helped keep the manuals closed. Photo 4 is a doublewide shot of the result of executing a write to the USCRB USART register, while Photo 5 is a panorama of the various windows available to you during code development.
ATMEGA16 IN CHARGE
The final step of the AVR Internet project takes the ATmega16 from the STK500 development board and mates it with an appropriate Internet-capable interface. I’ll couple the ATmega16 loaded with a minimal TCP/IP stack and Telnet application with a Packet Whacker and a backlit LCD. The Packet Whacker is a microcontroller NIC based on the Realtek RTL8019AS that will allow the ATmega16 to interface with a router in the Florida room that is attached to the Internet. For those of you not familiar with the Packet Whacker, there’s lots of Packet Whacker info on the Circuit Cellar web site. The LCD will be accessible to you via a Telnet session from wherever you may be, 24 hours a day, 7 days a week.
I recently installed a higher resolution web cam on my web site at www.edtp.com and have it pointed at the ATmega16 Internet device you see in Photo 6. A server is dedicated to putting pictures of the ATmega16/ Packet Whacker Internet device from that web cam on the Internet for you. The idea is to allow you to use a Telnet session to write to the LCD that is being controlled by the Atmega16/ Packet Whacker Internet device. The web cam puts you there live as you are interfacing with the LCD.
As you can see from Figure 1, the Packet Whacker takes much of the complexity out of the hardware design. I’m using an LCD as an output device, but the idea behind it all is that you can do anything with the output pins that are not being used by the Packet Whacker NIC.
Using the Atmel ATmega series of micros makes this project easy to modify as far as a microcontroller is concerned. You could substitute an ATmega128 in the schematic for the ATmega16. The ATmega128 would give you an additional 23 I/O lines and 3 KB of extra SRAM buffer area, and you wouldn’t have to change a significant amount of the original Internet device code to squeeze it in. If your Internet device doesn’t need the resources of a more complex microcontroller, you don’t have to put them there, but if you really want to rock and roll, you can shoehorn the big ATmega128 motor in.
The final working AVR TCP/IP code is a port of various algorithms I have assembled on other microcontrollers over time. Unlike some of the micros I ported this code from, the AVR ATmega16 architecture is designed to lean towards programs written in high-level languages like C. As a result, I was able to eliminate all of the assembly language routines from the ported code and write them fully in AVR C using ImageCraft’s ICCAVR Professional. The AVR code is basically a combination of modules that perform a specific Internet-related function. All of the basic functions are there including a limited TCP module. For instance, an ARP module is included in the AVR code to allow other devices on the Internet or LAN to establish a communications session with the AVR Internet device.
IN THE PIPE
I’ve enjoyed putting this series on the Atmel development tools and JTAG ICE together. The Atmel gear I’ve been exposed to is inexpensive and top notch. I look forward to seeing you on the AVR Internet device LCD, and when I do, we will have proven that the ATmega16 isn’t complicated. It’s embedded.
STK500 starter kit
ICC AVR Compiler
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • JUNE 2002 #143 – Get a PDF of the issue