Evie Beer: Episode 9 – Doh! and Happy Ending

As we saw last time, I had been having trouble getting meaningful measurements of joystick position using the ADC. It only goes to show few many readers this blog has, because the circuit diagram showed exactly what the problem was, quite clearly, yet no-one commented!

And of course all that impedance-limit waffle I spouted last time was just that – waffle. Google to the rescue.

World Record?
Given that the X pot of the very old and battered joystick I had was iffy, I decided to call on eBay to get another PC analogue joystick.

I placed the order at 09:00am on the dot, and got a message from eBay at 09:02am stating that the item had shipped. Jeepers, that’s quick! Even though what it really means is “we’ve handed it off to a delivery agent, so it’s out of our hands now”, that speed is still darned impressive.

Even more amazingly, the joystick turned up at my front door on the Isle of Man the following day – now *that* is a world record, it usually takes 2 days minimum from UK for a courier delivery, with an overnight stop off in Liverpool…

Ground Dog
In a PC analogue-interface joystick, the axis potentiometers are wired as variable-resistors (ie: with one of the outer pins completely unconnected), rather than as a variable-voltage-divider, which would be the more traditional use of a potentiometer. You would have thought I might have noticed that only two of the three lugs were connected when I disassembled the old joystick, but no, I was just too slow on the uptake. Doh!

Thus there is a “missing” ground connection that I must provide myself on the external breakout board. This makes sense, as in the PC analogue joystick interface, the host is (effectively) an RC timer circuit used to trigger a 555 timer, for which a variable-resistor is exactly what is needed. For a hook-up to an ADC, that of course won’t do.

Backwards
Note that most PC joysticks are wired with 5V power to the *center* pin of the pots, and output signal on an outer pin, which is exactly the reverse of what would be needed to wire it as a voltage-divider by adding a ground wire to the unused pin.

Convert to Voltage-Divider
Digital voltmeter showed the new joystick with a resistance-to-power-line of between zero and 80Kohms, on both axes. Thus to get the widest most-nearly-linear spread of voltages to measure, I added a 40Kohm (80/2) resistor to the breakout board from each axis-pin to ground. There are be a lot of resistors piling up on that little board!

Of course, using a fixed external resistor means the stick response is not going to be linear, you would have to take the joystick apart and wire the unconnected pot pins directly to ground to get a truly linear response (assuming linear pots of course). But with a *half-range* fixed resistor, its’ as close as we’re going to get without opening up the joystick.

So does the measurement-circuit/ADC work now?
It sure does! Let’s end with the usual gratuitous video to demonstrate how well it works.

Retrochallenge Project Conclusions
This “muck about with a 6811 SBC” project turned out to be both fun, illuminating and very frustrating – I learned quite a bit about electronics, after some stupid mistakes. But there are some important conclusions about working in such a constrained minimal environment:

Debugging with LEDs
…is way useful, I’ll be sure to add at least a couple of LEDs to my next electronic hardware.
Learning an Assembly-Code
…is not really much easier for having learned a different one a long time ago: each has its’ own idiosyncracies and cute op-code wierdnesses.
68hc11 Good
It is easy to see why the 68hc11 was so popular in its’ day, it is a very cleverly thought-out MCU. The shed-load of on-chip devices (SCI, SPI, 8-channel ADC, 8-bit parallel-I/O, 8 timer-I/Os, on-chip RAM, EEPROM, ROM and monitor, etc, etc), the fact that it can program its’ own EEPROM (even external EEPROM) without needed strange supply voltages, it all adds up. The other beauty is the on-chip ROM monitor (in bootstrap mode) – this means that you don’t need any special “Development Environment” package or kit: just an assembler, a C or BASIC compiler if you really have to, and a dumb-terminal emulator that can blindly “cat” a file via the serial-port. My development environment was Solaris “tip” on an old Sun workstation, together with the public-domain command-line 68hc11 assembler: pretty minimal, but no less effective for that. I suppose the most telling facet is that the official Motorola “universal” evaluation board contains *only* a 68hc11 MCU and a combined RTC/low-voltage-reset chip and a dozen or so resistors and capacitors: quite literally, nothing else is needed built-in, for smallish systems.

68hc11 Bad
As a small self-contained 8-bit MCU, there are of course some compromises: the lack of stack-indexed addressing can take some getting used-to, as can the lack of computed-offset indexed addressing and the very limited 16-bit arithmetic instructions. For larger programs, there is the I/O compromise: if your program is large enough to require external RAM or ROM then you lose two of the I/O ports. Finally, the fact that most 68hc11 chips are packaged PLCC-52, PLCC-68 or PLCC-84 rather than DIP makes amateur hand-construction of SBC boards somewhat harder.
Squeezing It In
I was surprised how much program functionality you can squeeze into 364 bytes of RAM and 512 bytes of EEPROM. Honestly, I just wasn’t expecting it.
Learning
Although the EVBU SBC is a great board for learning embedded system interfacing, my basic electronics knowledge was the limiting factor – but I’ve learned quite a bit doing the project, and will be in much better shape next time around.

I originally expected to use this SBC for the month of retrochallenge, than pass it on to someone else. But no, I have instead added the EVBU and documentaion to my “permanent collection” – there’s plenty more mucking about that can still be accomplished!

And finally, the most promising thing to come out of it all is that I have convinced myself that it *is* possible, in the far future, for a klutz like me to successfully build a “StickyMouse“…

Evie Beer: Episode 8 – RTFM!

This time, we’re looking at the built-in analogue-to-digital convertor on the 68hc11. In principle, this should be quite easy, but in practice there turned out to be some caveats.

First problem was that I had assumed that the breakout connector on the evaluation board SBC had port E wired in the same sequence as ports B and C, so it might not be all that surprising that I was only able to get stable results from one ADC channel – the other was always a bit arbitrary… because I had connected one jumper to the wrong pin. I spent a couple of days testing with the ADC inputs shorted to ground, to +5V supply, swapped over; checked and rechecked the wiring and soldering on the breakout board; tested with a single-channel program and a multi-channel sampling program. It all seemed very mysterious and inexplicable!

Eventually, having exhausted all other possibilities, I was skipping through the EVBU manual just looking for *something*, *anything*, when I noticed that the CPU port E pins are not pinned-out on the connector in the same sequence as the other ports. Darn!!!

Rule two of electronic tinkering: RTFM!

Iffy Levels
Mind you, even when connected to the right pins, I was still unable to get meaningful ADC results for the X- and Y-axes of the external joystick. When the ADC inputs were connected directly to +5V or GND, I got solid repeatable 0xFF or 0x00 (sometime 0x01) results, on both channels and on each independantly.
20150728_080550
How about measuring an intermediate voltage? A 1.5V battery might be interesting…
20150728_082009
Even without a current-limiting resistor (EEK!), that actually works fine: a solid reliable 0x51 value. OK, so the ADC response is not perfectly linear with my circuit, but it’s darned close.

So why wasn’t the joystick output giving meaningful values? After all, it’s just a simple varistor between +5V and GND, should be no problem at all… was there something wrong with the very old joystick?

Desperation Will Tear Us Apart
Have you ever noticed that the amount of gratuitous hardware disassembly is directly proportional to the amount of project desperation? Thus:
20150728_101022

Although the small internal straight-through junction-board inside this joystick was mislabelled (Fr and Fr2 were not the button lines, “X” was not the X-axis output, and so on), the wiring inside was correct and sound – no solder breaks, the wires from the plug pins go where they really should do.

A digital meter showed that the Y-pot was fine: in centre-adjusted trim setting, resistance varies between 140K and 0, with a centre at roughly 65K – it’s one of those 150Kohm slightly-more-recent joysticks, not the original 100Kohm IBM one.

However, the X-pot was a bit of a mess: resistance varies between 110K and 174K with a centre at 164K. Holy Cow!!

As you may have noticed, this joystick has “trimmers” on it – to adjust the true centre-position. Analogue joysticks were notorious for requiring calibration, often painfully done in host software in the early days – in the latter half of the 80s, joysticks with trimming-sliders became more common, to handle calibration on the hardware side without needing the host software (every game, etc) to have its’ own calibration routines.

Careful inspection shows that the X trimmer on the joystick was centred, and had not “slipped” inside the case. In the process of testing response to the trim setting, I twisted the pot a bit too far and managed to break the spot of factory-melted plastic that held the pot body in a fixed rotational position on the trimmer-slider.
potspota
However, this allowed me to play even further with the trim setting, which comes into play later on.

Impy Dance
Somewhat naively, I had assumed I could read voltages directly off the joystick outputs:
axis_schematic
It turns out that the maximum source impedance for the 68hc11 ADC is (quote) 10Kohms, not the 100K or more that an analogue PC joystick uses. I could get correct and repeatable 0xFF,0xFF reading of X and Y when the stick was at top-right, but it would never read less than 0xFD,0xFD nomatter how the stick was positioned. Needless to say a swing count of 3 (at best, with a following wind) is a pretty poor resolution, compared to the 256-count swing I was hoping for.

A False Hope
I toyed with the idea of a fixed series 10K resistor input to the ADC, with the joystick varistor in parallel to ground (in turn with a series 1K current-limitor) – some of the current would go each way, right? Ah, but I’m measuring voltage, not current, so even that ain’t gonna work:
axis_schematic2
At this point it becomes clear that I am going to need an *active* external component: either a unity-gain op-amp impedance-reduction circuit (with caps and resistors et al et al), or revert to the PC-style 555-based capacitor-charge polled-timing circuit – which would be *way* more complex on the software-side.

And that’s after fixing the iffy X-axis potentiometer in the joystick.

Leftovers
A bit of extreme over-rotation of the X-axis pot body, as hinted at above, in an attempt to reduce the total resistance-swing, showed that wouldn’t do either: once past the factory default spotted position, the thing goes massively non-linear. From a centre-position 10K, minimum is 0K (good!) but maximum-displacement resistance is still 160K (bad, way to high!). Either this pot is compleletly stuffed, or an active external circuit would be needed.

Looks like this project may have reached its’ natural end, due mainly due to my lack of electronics experience and knowledge.

But with two days to go, the fat lady hasn’t sung the Wonder Woman theme-tune just yet. I am going to rummage in my box of old scavenged circuit-boards to see if there are a couple of low-range-resistance potentiometers in there somewhere…

And of course, there’s always the project summary to write.

Evie Beer: Episode 7 – It’s A Stick-Up

The Other End
Now that RetroChallenge is in the closing week, it is time to take a look at the *other* end of my breakout-board:
20150726_154821
That thar be a retro “Gameport” socket. I guess that gives a good indication of the next piece of hardware that I am attempting to interface to the 68hc11 SBC…
stickappears
Yes, I’m afraid so – an old-style 1980s PC analogue joystick.

Button Down
First job was the “fire” buttons. On this kind of joystick, the buttons are wired as simple “direct-short-to-ground” SPST. So there need to be external pull-up resistors on the breakout board for the buttons.button_schematicI had originally used 10M pull-ups, thinking that would minimise the “idle” current-flow, but that turned out to be a bad idea.

Initially, when reading the PORTC pins on the 68hc11, I was getting alternative correct values then zero, tick-tock tick-tock. Even with a 1-second delay between each read. What on Earth was going on? After spending quite a while double- and triple-checking the wiring on the breakout board (it was correct, if messy, and no unintentional breaks or shorts), and wading through the copious Motorola 68hc11 technical manuals, there still didn’t seem to be any logical explanation.

Eventually, on a hunch, I figured that there was interference between the pin-buffers on PORTC, and the only plausible explanation was that those pull-up resistors were too high-impedance (too weak a pull-up effect). Although I wasn’t sure, I eventually bit the bullet and replaced the 10M pull-ups with 10K ones: a quick calculation indicated that the idle voltage would still be high enough to read as a valid high level on the MCU pins…

Desoldering partially-obscured resistors and patch-wires is one heck of a job to tackle with a cheap hand-iron, it took *ages* and plenty of sweat, but eventually I got there at the cost of an even more messy-looking breakout-board.
20150726_154809

Button-Up
With the stronger pull-ups, the buttons now read reliably! The minimal program to read the button-states, and then display the results on the LEDs is:

include(board.def)
include(hc11e.def)
include(buffalo.def)
include(lib.def)

        ORG     HIRAM
; X points to control-register block
sysinit: ldx    #CSREGS

; to avoid floating CMOS-input (near-short to ground),
; configure PORTC for *output*, except those pins that
; we have pull-ups on: C4-C7 for buttons 1-4
        ldaa    #$0f
        staa    DDRC,X

; continuously read buttons and display
main:   ldaa    PORTC,X ; read raw button state
        lsra            ; shift high-nibble to low-nibble
        lsra
        lsra
        lsra
        eora    #$ff    ; invert bits to get 1=on 0=off
        staa    PORTB,X ; show button-state on the LEDs

        bra     main    ; repeat until bored

Those “include” statements pull in static definitions for the EVBU, the MC68HC11E-series MCUs, the BUFFALO monitor (which isn’t used by this program) and my EEPROM-resident library routines (which also aren’t needed here). Let’s see whether it works… check the Button Show video. To please those readers disappointed by the previous video, this one does feature 1970s Wonder Woman in the background audio.

Note that this particular joystick has a hardware “auto-repeat-mode” switch, and both one-shot and auto-repeat operation show nice and clearly.

Of course, the buttons are not debounced in any way, so there may be more programming work to do, but due to the slow semi-synchronous final application I have in mind for this circuit, I believe that debouncing may be completely unnecessary! I know, that seems crazy, but… we will see how that works out in a later episode.

Fingers Crossed!

Evie Beer: Episode 6 – An Illuminating Debugging Method

Now that loading into on-chip EEPROM is working, I have written a few standalone utility routines so that the final program will not need to
rely on the BUFFALO monitor (which isn’t available in some operating modes).

Simple things, such as output via the serial-port, analogue-to-digital sampling, digital input port reading and so on. This allows me to test and debug other parts of the program in the (measly) 326 bytes of available RAM, without having to download the utility routines: once debugged, I load them into EEPROM where they remain even across power-cycles.

However, this assembly-code lark is not as easy as it could be – I am making very few mistakes, but when you make one it can take ages to track it down – no GUI debuggers here, and I still haven’t quite adjusted to this level of programming. Getting there, but still occasionally dropping into inappropriate “high-level programming” habits.

The BUFFALO monitor has some debugging facilities: line-by-line assembler/disassembler, single-step, trace-until-address, register-dump to terminal, line-by-line interactive memory-modify, interactive register-tweaking, and even a breakpoint facility. Given that the on-chip BUFFALO ROM also includes the downloader, terminal routines, 4 different host-port device-drivers (SCI, SPI, ACIA, DUART), command-parser, EEPROM programming routines, S-record decoder, et al, it really is a remarkably compact program.

Whilst writing a standalone function to convert binary register contents into ASCII hexadecimal, I needed to be able to inspect the ALU condition-codes at specific points, which would have been somewhat cumbersome. Fortunately, the LEDs on the breakout board I built earlier can be used for exactly this, even though I had originally intended them just for playing about with, for fun. It only takes a couple of instructions to dump a nibble to the 4 LEDs, so I could use a technique a little like the old “insert a few printf() calls” method (which I cannot use here as there is no printf() in this deliberately minimal environment), but instead of printing trace messages to the terminal, we display bit-patterns on the LEDs. Of course, it also required inserting the occasional delays, otherwise the patterns would flash by too quickly to be seen: but that was easy too thanks to the programmable-delay routine I wrote earlier (which now lives permanently in EEPROM)… this “illuminating” debugging technique is quite useful, and has the advantage of a certain amount of prettiness, it’s almost hypnotic. Reminds me of watching the changing front-panel lights on an old huge PDP-11 I timeshared in the early 80s…

A 68hc11 Idiosyncracy
trying to squeeze 68hc11 program-code to the smallest size possible, so that it will fit into the small on-chip memory, led to an interesting discovery: indexed addressing using the Y index-register makes instructions 1 byte bigger than when using the X index-register.

One of the “selling points” of the 68hc11 was that it had *two* index-registers (block-pointer registers) instead of the single one available on the older 6800 and 6805 processors. Experience had shown Motorola that a single index-register on the older parts had been quite limiting and inconvenient to application programmers…

On the 68hc11, Y-register indexing is signalled by a constant instruction-prefix byte, which can be very wasteful of memory-space in a highly-constrained environment. Thus I have discovered the 68hc11 “rule-of-thumb”: use Y-register for indexed addressing only sparingly, try to get all the frequently-accessed data either in zero-page RAM (8-bit absolute address) or within range of an 8-bit offset from the X register (8-bit offset address).

Of course, I had initially used Y-indexed addressing everywhere, so was running out of RAM… now fixed to do it the “other way around”, amazing how much smaller everything has become!

Evie Beer: Episode 5 – EEPROM Tribulations

The last week of fiddling with the 68hc11 EVBU SBC has been a bit of a slog, with not much productive output…

Bicycle Count
The first task was to write a reliable parameterised “delay” routine, so I could ditch the awful mechanical workaround (wedge a keyboard key down!) I had previously used for the LED-flasher program.

This took a bit of trial-and-error, but made it in the end: a routine that sleeps for the number of milliseconds passed in the 16-bit X index register. The timing is based on a cycle-counted loop rather than the on-chip hardware-timers, but it is accurate, reliable, and scales from 1ms to over a minute. It was quite fun to play with programmable delays for the LED-flasher program, you can get some funky visual effects that way.

EEPROM Greens
The 68hc11 has a *very* nice feature – on-board EEPROM, which can be used for program storage, static data, dynamic data or all three. On the 68hc11E1, there is 512 bytes of EEPROM, plenty for what I have in mind, given that 68hc11 object-code can be very “dense” if you avoid floating-point or excessively 16-/32-bit operations.

The 68hc11 was the first commercial CPU/MCU to contain on-chip EEPROM, and Motorola implemented it very well. Unlike Flash memory, EEPROM can be erased/written a byte at a time, but requires quite a bit more than 5V to do so. Many early EEPROM-containing CPUs required the chip to have auxiliary 9V (or 12V or even 20V) power-supply lines to provide the voltage needed to erase/write/rewrite EPPROM cells.

Motorola avoided the need for wacky power voltages by implementing on-chip charge-pumps, so the 68hc11 chip can directly program both internal and even external parallel EEPROM, using the chips’ normal 5V power input line. Neat!

The slight drawback is that there is a specific sequence of events needed to program an EEPROM cell, particularly a 10ms delay needed for the charge-pumps to charge on each erase/write operation. Fortunately, Motorola had the sense to make the EEPROM erase/write operations controllable directly under program control, so you can write a 68hc11 subroutine to perform EEPROM-modification operations – no special auxiliary hardware needed, it’s all internal.

So, armed with a mini-application that runs from on-chip RAM, the next step for me was to get the program into EEPROM, so that I don’t have to keep downloading it to the chip, which can become very tiresome after a while…

EEPROM Blues
The on-chip BUFFALO ROM monitor can in principle directly load a download into EEPROM, but the BUFFALO implementation is quite slow, and as the 68hc11 built-in serial (5V RS-232) interface has *no* flow-control, when downloading at the default slow speed of 1200 baud, the BUFFALO S-record-conversion-and-EEPROM-rewrite routine stalls hard, requiring a reset.

For very small programs, such as the LED-flasher from the last episode, I was able to use the BUFFALO “modify memory” command to program the EEPROM bytes one at a time by typing each MM command “by hand” at the terminal. This worked OK, but there is no way such a method is going to be feasible for anything but utterly trivial programs.

A common alternative is to download a (custom) EEPROM-programming program into RAM, and execute it there. Such a program can be written in such a way as to read address/data values from eg: the serial-port, and to then program the requested bytes from that data.
Of course, you are still faced with the “no-flow-control” and potential serial-overrun problem, and would also have to code-up your own “protocol”, such as an S-record decoder, for the download format. Although there are examples of such 68hc11 programs around on the ‘net, none of the ones I could find could deal with the flow-control issue without requiring custom or special host-resident software or full UART external hardware; plain-old terminal-emulator host software talking to an EVBU just isn’t going to cut it for EEPROM programming. It’s fine for RAM programming using BUFFALO, as that is very fast, way fast enough to keep up with download speed.

Time to look for other alternatives…

PCBUG11
The EVBU comes with Motorola-written DOS software that provides a character-mode GUI (!) for talking to the 68hc11, including download-to-EEPROM commands. These download a special program to RAM, that then uses a mysterious (undocumented) protocol to sequence the download of EEPROM data. Let’s give it a bash!

First problem: PCBUG11 is only provided on 800k Mac Classic floppies or 5.25-inch DOS floppies – and I do not have such ancient drives. Fortunately, it can also be found on third-party sites on the ‘net, so one quick download later and I was ready to rock.

I had planned to use an old 1998 Toshiba laptop to run PCBUG11, but it has no Ethernet interface. No problem, let’s use 3.5-inch sneakernet to get the software over… ouch, the diskette drive on my SPARCstation is dead. Plan B: I have a USB 3.5-inch diskette drive, so could copy over from the modern home PC. OK!

Unfortunately, the ancient PCBUG11 software was written using 8086 blind timing-loops for synchronising communication with the EVBU, and therefore fails utterly on any PC running at more than 80MHz.
I suppose that in 1985, the idea of a PC running at more than 16MHz seemed pretty remote, and speeds above 200MHz was surely several decades away (ha!); I’m still upset with Motorola about this daft way PCBUG11 was written.

On the ‘net, from a 1998 Motorola listserv, there is a binary patch for the PCBUG11 executable that relieves the issue, and allows PCBUG11 to work on 166MHz PCs, but it was still no-go on my 233MHz Pentium-II.

As Dick Dastardly would say: “Drat! And double-drat!”

Back to The Job
OK, we’ll defer the bulk-load-to-EEPROM for now, and get back to a bit of assembly-language programming again.

Although the 68hc11 is quite a capable 8-bit CPU, the lack of stack-indexed addressing is a royal pain: the only explicit stack-relative memory-operations available are PUSH/PULL of an 8-bit acculumulator or 16-bit index-register. For someone like me, coming from a C background, it required quite a head-switch to get used to passing function-parameters in registers or even fixed memory, rather than “just push it all on the stack and access it from there”. The very few registers available (A, B, X, Y), and the “syntax style” of the 68hc11 standard assembly language made it all the more confusing at first.

Obvious examples are that “inc b” and “incb” are not the same operation at all: the first increments an 8-bit memory-location, the other (implicitly) increments the B register, and I frequently got it the wrong way around. I’m just not used to that kind of thing: in SPARC-land, general registers are *always* explicit, and direct memory operands typically use explicit register-indirect index-notation. I should not have been troubled by this head-switch, because I used to program in Z80, 7809, 68000, NS32016, and a few other assembly languages, all with their own idiosyncratic ways of looking at things: but that was all over 25 years ago, and I have just become unacclimatised!

Lesson: having programmed in a couple of 8-bit assembly-languages a few decades ago does not mean you’ll pick up a new one at all quickly.

The other “Doh!” moment I kept having when using the BUFFALO “load” command, was downloading the assembly-code file instead of the assembled object-code, which of course sends BUFFALO into fits, requiring a reset. The tell-tale sign is when the terminal emulator reports “123 lines downloaded” for what should be a tiny program (compiled to 7 object-code S-records)… “Darn! I didn’t mean to do that… again!”

More Progress At Last
Back in RAM-land, the next task was to write a program to demonstrate (1) ability to report binary byte-values in ASCII hex to the terminal, and (2) a sounder grasp of conditional logic in assembly: a program to output a formatted, line-wrapped, block of all 8-bit binary values in ASCII hex.

NOLF    EQU     1       * if host is tip or minicom, then
                        * we don't need line-feeds
putc    EQU     $ffb8
getc    EQU     $ffcd

include(lib.asm)
CR      EQU     $0D
LF      EQU     $0A

        ORG     $0100
init    ldab    #$0
        bra     body
loop    pshb
        pula
        anda    #$FF
        beq     nextblk
        anda    #$0F
        beq     nextlin
body    pshb
        pula
        anda    #$07
        bne     report
        ldy     #3
loopy   ldaa    #' '
        jsr     putc
        dey
        bne     loopy
        ldx     #500
        jsr     delayms
report  pshb
        pula
        jsr     puthex
        ldaa    #' '
        jsr     putc
        incb
        jmp     loop
nextlin jsr     newline
        bra     body
nextblk jsr     newline
        ldx     #750
        jsr     delayms
        jsr     newline
        bra     body
newline ldaa    #CR
        jsr     putc
        ldaa    #NOLF
        bne     skiplf
        ldaa    #LF
        jsr     putc
skiplf  ldx     #333
        jsr     delayms
        rts
* print register A value to terminal as 2 hex-digits
* NOTE: the BUFFALO nibble-hexification routines
* trash the A register!!!
puthex  psha
        jsr     $ffb2
        pula
        jsr     $ffb5
        rts

This went quite quickly, although it still leans on BUFFALO subroutines more than I would ideally like, rather than being more self-contained. However, the conditional bits are good, as can be seen in the video (the background sound is “Special Ops Force” on TV, but count yourselves lucky – earlier on today it was 1977-vintage “Wonder Woman“…)

Stop Press!
Breakthrough: we have reliable download to EEPROM, even using dumb terminal emulator (Solaris “tip”)!

The trick is to use a BUFFALO “modify memory” command to update one of the 68hc11 memory-mapped control-registers to set the on-chip SCI baud-rate to just 300 baud. It means having to connect at the default baud-rate (1200), then switch, disconnect then reconnect at 300 baud, before downloading, but that’s way easier than typing the object-code bytes in by hand one at a time:

sol% tip evbu
connected

>MM 102B

102B 30 35@^%^[
[EOT]
sol% tip evbu -300
connected

>load t
^[>Local file name? eel.s19
4 lines transferred in 0 seconds 
!

done
>

As shown, this slow speed gives the BUFFALO “load” command has enough inter-byte time to program each EEPROM location. The LED-flasher is now running directly from EEPROM without having to type in the object-code a byte-at-a-time.

Sorted!

Evie Beer: Episode 4 – External Hardware

The last week has been very busy with non-project stuff, but I have managed to make progress on constructing some simple external hardware for the 68hc11 EVB to interface to. For most starter “microcontroller mucking about” projects, playing with a few LEDs is de riguer, and Evie Beer is no exception:

xboard_top_ledsxboard_bottom

You can ignore the funny connector on the other end of the board, that is a topic for another time. Although, if you recognise the connector, you just might have a clue as to what else I will be getting up to this month.

Those pin-headers on the board are chopped-up IDE male-male gender-changers… which seemed like a good idea at the time, but when soldering to the underside pin, the plastic on the top of the board would melt and the pins fall out! Lacking any alternative, I had to resort to very-quick-and-hasty soldering. Talk about pressure!

I also spent rather too much time calculating resistor values, for sure, but needed to make sure that the loads on the 68hc11 MCU pins could never exceed 25mA, which is the Motorola documented “safe limit” for continuous operation – the pins, input-buffers and CMOS drivers will happily source or sink over 100mA per pin, but are heavily margined to allow for eg: automotive EMI, unintentional inductive coupling to vacuum-cleaner motors, and so on. At 25ma *nominal*, it is extremely unlikely that permanent damage to pins/drivers/buffers will occur.

A Shortcut that Went On Too Long

A while back, I saw an advert for some “LED with built-in series resistor”, and though that that would be a great way to save time, effort and brainpower. The LEDs sure work, tested with a 250mA 5V wall-wart power-supply (and no external resistors, you catch my drift?). Unfortunately, when designing a circuit-segment to limit the power-draw, you need to know the rated resistance of that hidden internal resistor, and the <u>only</u> specifications for these LEDs are:

  • Maximum Forward Voltage: +7.5V
  • Reverse Breakdown Voltage: -5V
  • Forward Current at +5V: 10-15 mA

From Ohms laws, that means the resistance is anywhere between 500-333 Ohms; and the “illuminated” power-draw is 50-75mW per LED on my 5V circuit, crikey! Ouch!!! There is a 50% uncertainty on the current drawn (and therefore logically on the effective internal series resistance too). So the calculations had to be done using interval-arithmetic, to get the outer maximum/minimum results. Yep, results plural.

Why is power-draw so important anyway? Well, Motorola have never specified the maximum power that any of the 68hc11 MCUs can dissipate – they have formally specified the maximum that some models of the MCU chip itself is responsible for, in both single-chip (68HC11E1 = 139mW, 68HC11F1=150mW) and expended-mode operation, but have left designers and users to make a “wild finger in the air” guess as to how much externally-sourced/sunk peripheral power the MCU can dissipate. Apart from commercial embedded-systems manufacturers that were able to bulk-test 10s of thousands of units and apply statistical methods to the results, no-one actually knows.

Thus, allowing for 15mA for each of potentially 8 LEDs, together with all the other circuitry on my external board, seemed a little bit uncomfortable. So interval-arithmetic and testing was needed, to try and get the LED power-draw down without making the LEDs too dim. OK, so the results are in:

led_tune_results

An additional 220 Ohm resistor drops the drawn current down to 7-9mA, whilst still keeping the LEDs reasonably bright. They are still really bright enough even with a 470 Ohm external resistor at 5-6mA – they are pretty darned good LEDs, but I have decided not to use these beasties again – fully separate resistors and plain-old LEDs actually *is* easier in the end!

Brute Force Animation

Next job was to get the LEDs driven from the 68hc11, controlled by a program. I had intended to use jumper-leads to connect the LED positive terminals to four of the 68hc11 Port B pins, and the common ground to the EVBU ground. Unfortunately, I needed female-to-female leads and I only have female-to-male. Darn! So the first piece of brute-forcing: use an old 50-pin SCSI cable as a gender-changer!

xboard_jumpercable1

On the 68hc11, direct control of the on/off digital state of pins is easy: the 8 “Port B” pins are set/reset by writing an 8-bit mask to the on-board memory-mapped port B data register, ie: writing 0xff to address 0x1004 (the port B data register) would turn on all 8 port B pins, and so on, and so on. So a program to display a counter pattern would be something like:

       ldab #0     # initialise counter (accumulator B)
loop   stab $1004  # store counter to port B data-register
       incb        # increment counter
       <delay for a noticeable fraction of a second, somehow>
       jmp loop    # go round again

Given that I only have 4 LEDs currently, I figured that connecting them to the high-order pins of port B would have them change only every 16 times round the loop, so could avoid the need to come up with a timed delay mechanism. However, with the 68hc11 running at 2MHz clock, even an “update only once-out-of-every-16″ was still waaaaaaay to fast – the LEDs all just appear to be constantly on.

The BUFFALO ROM provides a user-callable routine to wait for an incoming character from the console terminal (at 1200 baud), store the ASCII code in accumulator A, then echo it back. I rather liked the idea of being able to step the program by typing on the keyboard, as that would allow me to check that the LEDs were really turning on and off, and in the expected sequence. Which gives the following program:

      ldab #0       # initialise counter (accumulator B)
loop  stab $1004    # store counter to port B data-register
      incb          # increment counter
      jsr $ffcd     # call BUFFALO to wait for console keypress
      jmp loop      # go round again

Well, this worked and proved the counter was incrementing and the writes to the port data register were really controlling the LEDs, but required a keypress for every change of LED state.

The lightbulb moment: the console terminal has an auto-repeat for keyboard keys, so I could convert that call to BUFFALO into a noticable delay instead – by using the utter brute force approach: wedge the console RETURN key down with a folded piece of paper…

And it worked beatifully. OK, so it’s not the “proper” way to do it, which would be to use the very flexible built-in timer system on the 68hc11, but I quite liked this solution – a quick, dirty, indirect hardware solution to a software problem.

Evie Beer – Episode 3: SBC is Alive

Well, well, well, the 68hc11 EVBU SBC is alive, and the CPUs’ built-in ROM monitor is talking to me.

This SBC has no RAM chips, no ROM chips – none, zip, zilch; just the CPU, an RS-232 level convertor and an RTC (date/time clock) chip. All the rest is built into the CPU chip itself, including RAM, EEPROM, the nano-operating-system ROM, OTPROM, and a whole slew of “peripheral” I/O devices (a bit of a misnomer in this case: on the 68hc11, they are not really “peripheral” at all, they are part of the CPU).

I decided not to cut the cable on the 5VDC wall-wart I obtained yesterday: instead I made my own custom adaptor to connect the drop-lead to the power-input of the SBC, usimg a couple of old PC-PSU cables from the junk-box and some epoxy to make the “plug”.psu_serial_hookup.

Note I am using an UTP Ethernet cable as the serial-port cable, via a precooked adaptor I made several years ago (I have quite a few of these, including some null-modem ones and a special one for an especially wierd serial printer). On the other end, these is an old Sun workstation, with its’ own unusual RS-232 feature: it has a single 25-pin port, that provides a *pair* of RS-232 interfaces – thus the custom splitter-cable to split that into two independant DB25 connectors… that arrangement is common to most 1990s Sun workstations, but it confused the heck out of the PC crowd at the time (“but I can only see one port, where’s the other one?”).host_serial

The SBC “operating-system” is called BUFFALO, a very strained acronym: Bit-User Fast Friendly Aid to Logical Operation. Ouch!

The First Program
Using the built-in line-at-a-time assembler in BUFFALO, my first program is about as basic as possible. Assembling program code into RAM at address 0x100, print “Hello” to the serial port, than wait for a keypress, and then start over. For this very first version, I used a couple of subroutines in the BUFFALO ROM: print an ascii character from the A register to the serial-port, and read a character from the serial-port into the A register. Using these two subroutines, the program is just a sequence of instructions to load values into the A register interleaved with a sequence of subroutine calls (to a fixed address), and a jump instruction to start over. This sure ain’t going to win any awards, but at least it proves the CPU is alive and working.buffalo2

Nice!