I'm trying something slightly crazy, and progress is going slowly. I want to get Forth and a simple USB bootloader running on Freescale's S08JM parts. But instead of doing that the easy way, and buying P+E Micro's USB Mulitlink programmer, I decided it would be interesting to see if I can bootstrap from nothing. Well, not quite nothing. But to explain that I have to explain some history. The HC08 is really two sub-families: the original HC08 and the newer HCS08. I refer to these here as "908" and "S08". (The "9" means Flash memory, rather than ROM or OTP EPROM. The 908 and S08 parts both use the same Flash.) The S08s are nicer in almost every respect than the 908s, but they are harder to bootstrap. In fact, without the use of another microcontroller they are basically impossible to bootstrap. Rather than having a bootloader in ROM, like the 908s, they have a piece of hardware on-chip - the background debug controller (BDC). This bit of logic is really a poor man's JTAG. It allows access to the CPU registers, can start and stop the core, read and write memory, and because it can do all these things, it can run code that writes to Flash. These are really nice features, but the downside is that the custom protocol required to talk to the BDC needs to be driven, with fairly tight timing, by another microcontroller. Could I use a 908 to bootstrap an S08? In 2006 I sampled two flavors of 8k Flash, DIP16 parts: the 908QB8, and the S08QG8. Since the 908 has a built-in bootloader, I thought I would start by talking to it, then put just enough code on the 908 to talk the BDC protocol to program the S08... Then put a nice, simple, UART-based bootloader on that chip that I could use to program the S08JM parts - my eventual goal. A long road, but mostly an interesting one. I met with some initial success. Using two resistors and an HCT244 I was able to connect an RS232 level converter to the 908's PTA0, which the bootloader bitbangs at 9600 bps. I wrote a bit of Forth code that allowed me to read and write memory, the registers on the stack, and was able within a couple of days of fiddling around to download code into RAM and run it successfully. Flushed with success, I breadboarded an S08QG8 next to the 908QB8. Since most of the S08 families run at 3v (1.8 to 3.6), I had a voltage-conversion problem. Since I already had an HCT244 on the breadboard, I thought I would use that in the S08 to 908 direction, since the HCT input levels will be just about right for 3v logic. Driving the S08's BKGD pin to 3v is a bit trickier, and I'm not sure I've come up with a good way to do it. Freescale describe the BDC protocol as "quasi-open-drain". Since it's a one-wire protocol with multiple senders, it needs to have a pullup to Vdd (which is internal to the S08), and the senders need to be able to drive it high, drive it low, and 3-state it. My approach involved using three port pins: one directly connected to BKGD to pull it low; and a voltage divider between two others - one driven high and one low - that would put approx 3v on BKGD. This doesn't seem to work, and I'm not sure why. Of course, there is another issue that I haven't mentioned that consumed quite a bit of time to debug. Since the BDC protocol is based on the target's clock speed - each bit transmitted taking 16 BDC cycles - I need to drive BKGD fast enough to keep up with the target. The "host" - in this case the 908QB8 - has an internal oscillator that at the fastest setting yields a bus clock (instruction clock) of 3.2MHz. The 9S08QG8 runs its BDC clock at 8MHz. The tightest code I could write for sending and receiving bits was too slow, so I spent a bunch of time debugging oscillator settings. After finding a 25Mhz crystal, I'm now running the 908 with a 6.25MHz bus clock, which is fast enough to keep up - but it still doesn't work. Which is why I thought I'd take a break and document my progress, instead of driving myself crazy. |