NIEDZIELSKI.COM
 

swankmania

  swankmania was a neat one semester project I did in the Fall of 2007. It was a portable gaming device featuring a liquid crystal display (LCD), vector graphics, and a vintage controller. As I needed to demonstrate the capabilities of swankmania, I also designed BLiT, a small game in the vein
of Asteroids.

  The most interesting and challenging aspect of swankmania was designing the vector graphics controller. This component is responsible for receiving model vertices, color, mode, and other information and rasterizing their representations on the LCD using a double buffered frame. As the throughput needed to update the LCD many times a second was great, I developed the mechanism on a field programmable gate array (FPGA) using synchronous and asynchronous elements. Since there was only room for one frame on the FPGA, I also interfaced with external RAM for the second frame. For line drawing, I implemented a variation of the well known Bresenham algorithm in hardware.

  Design on the FPGA incorporated multiple clock domains for the LCD controller, rasterizer, and communications buffer. At completion, the device was capable of updating every pixel on the 240 x 160 screen about 30 times over without missing a frame at 72 frames per second.

  BLiT was a very simple Asteroids-like game that demonstrated some of the neat lossless aspects of vector graphics like scaling and rotation. I wrote BLiT mostly in C on a microcontroller that interfaced with the vector graphics controller and an old input controller from the Nintendo Entertainment System.

  Special thanks goes to Christopher Theriault for designing the LCD printed circuit board (PCB), Mike Anderson for rendering tips and miscellanies, Cesar Carrasco for soldering components to the LCD PCB, and Todd Seiler for miscellanies.

  Here’s some photos of the project:

External Triggering with the Microchip ICD 2

Important Edit
  I haven’t looked into it in depth but it seems there’s official documentation on this feature in DS51242A, section 6.3.5. Here’s a link to the referencing page too. Thanks, Doug!

Abstract
  The Microchip ICD 2 may be used unconventionally as an external trigger without the use of breakpoints. This allows for extension of the hardware breakpoint limit or adds an extra external trigger to halt the microcontroller asynchronously. In this article, I will demonstrate limitless breakpoints using the Microchip PIC18F4550 microcontroller which normally supports up to three breakpoints and three external triggers.

Hardware Setup
  Little is needed to extend the capabilities of the ICD 2, two diodes and a transistor. That’s it. Here’s a schematic of how to wire the PIC18F4550:

  Please note that in the above schematic, I have the transistor connected to PORTB, pin RB0. If you put everything together, it should look something like this:

Software Setup
  Launch Microchip’s MPLAB IDE and start a C or assembly project. If you chose an assembly project, define the following macro in an assembly:

break macro
  bsf  PORTB, RB0
  bcf  PORTB, RB0
  nop
  nop
  endm

  If you chose a C project, define this macro instead:

#define Break(); \
  PORTBbits.RB0 = 1; \
  PORTBbits.RB0 = 0; \
  Nop(); \
  Nop();

  Before you use these macros, you’ll need to configure PORTB for digital output. This is a four step process. The first three steps I’ll illustrate in the following assembly snippet:

; ****************** Breakpoint setup. ******************
; Turn off RB0.
bcf PORTB, RB0
; PORTB digital IO on all channels.
movlw 0×0F
movwf ADCON1
; RB0 to output.
bcf TRISB, TRISB0

  Or in C:

/****************** Breakpoint setup. ******************/
/* Turn off RB0. */
PORTBbits.RB0 = 0;
/* PORTB digital IO on all channels. */
ADCON1 = 0×0F;
/* RB0 to output. */
TRISBbits.TRISB0 = 0;

  It’s the last step that’s a little confusing. You need to change the PORTB configuration bits so that RB0 is configured for digital IO, not analog input. There’s two ways to do this, compiler directives or IDE menu settings. In the example code bundled with this document, I do it using compiler directives. Here I’ll show how to do it using the IDE.

  In MPLAB, if you click the Configure drop down menu and select Configuration Bits, you should see the following window:

  Two main points here: First, if you’re going to use the IDE to change the configuration bits, you’ll want to make sure the “Configuration Bits set in code” checkbox is unchecked. Second, make sure “PortB A/D enable” is set to “PORTB<4:0> configured as digital I/O on reset.” The default values for all the other configuration bits here should be fine. When you close the window, your changes are automatically saved.

  Time to try it out, in your assembly file write the following:

nop
nop
break
nop ; Pop out of breakpoint here.
nop
nop

  Or in C:

Nop();
Nop();
Break();
Nop(); /* Pop out of breakpoint here. */
Nop();
Nop();

  If you compile and run this code using the debugger, you should find yourself paused at the nop following the break or Break(); macro. You may now have as many breakpoints as you wish by using these macros.

External Triggering
  The above method of pausing MCU execution may also be used by any external device. Instead of wiring a transistor to RB0, the signal is supplied by the external device. This may be very useful in the debugging of larger systems where the state of the microcontroller is unknown during a specific event.

How This Works
  There’s two conditions under which the microcontroller should halt execution during debugging: a user presses the pause button during program execution or a breakpoint is encountered. In the first case, there must be a communication from the computer, to the MCU. In the latter, vice versa. As I am unfamiliar with the ICD 2 communication protocol, I found through experimentation that if a short pulse was applied to both the PGD and PGC lines, that a breakpoint or pause could be emulated. The length doesn’t seem too terribly important, as I’ve had success using pulses from about 250 ns to the hundreds of milliseconds. This is very much a hack, use at your own risk.

Conclusion
  A means of providing infinite breakpoints and an additional trigger has been described. The major benefit this additional external trigger provides is a means of halting microcontroller execution without a single comparison in an interrupt handler, this may prove exceptionally useful when debugging complex systems.

Notes on the Example Code
  The example code bundled with this document differs from that presented in two ways: configuration bits are set using preprocessor directives; the program loops infinitely until a high signal is read on RB1 (not shown in the schematic). Download example code here.

Sources
PIC18F2455/2550/4455/4550 Data Sheet
http://ww1.microchip.com/downloads/en/DeviceDoc/39632b.pdf

hlpPIC18ConfigSet
MPLAB IDE -> Help -> Topics ->Language Tools -> PIC18 Config Settings

Editor’s note: originally discovered in early 2007.