A Forth-based Embedded Controller Development SystemFollow project
|1||MikroElektronika Clicker 2 for dsPIC33 MCU Add On Board MIKROE-2567||144-8343|
|1||Development Kit USB to UART Interface for use with CP2102N USB Bridge||184-0913|
|1||Microchip Microstick II MCU Development Kit DM330013-2||749-6445|
|1||FTDI Chip USB to UART Cable for Raspberry Pi - TTL-232R-Rpi||767-6200|
|1||Parallax Inc, BoE Prototyping Shield for Arduino - 35000||781-3027|
This write-up will be a repository for FORTHdsPIC documents such as the latest User Manual and source code (see Downloads below). The source code is fully annotated and may yield some useful assembler-language routines to anyone working with the Microchip dsPIC33 digital signal controller chip. I’ll also add FORTH source code for my various robotic projects as and when.
The FORTH Programming Language
In the early 1970’s a computer language appeared that bore little resemblance to the heavyweight mainframe languages available at the time, such as FORTRAN, ALGOL and COBOL. Called FORTH, it had a number of features making it very popular amongst engineers seeking a high-level language compiler able to create code for real-time applications running on the early microprocessors. These features included:
- Does not need an operating system (OS) - simple development board required, not an SBC.
- High-level compiled structures such as BEGIN….UNTIL and BEGIN….WHILE…. REPEAT.
- 16-bit single-precision numbers with 32-bit double-precision available.
- High-speed (for the time) program execution.
- It has both an interpreter to execute a line of code immediately, and a compiler to create new 'words'.
- Stack-oriented operation for maximum efficiency (as in LIFO push-down stack).
Professional software engineers saw no problem with the last item in the list above, but the non-algebraic source code format (Reverse-Polish Notation) ensured that those new to programming would stick to BASIC or Pascal! To find out more about Forth and its origins, see this excellent website. Also look at the Forth Interest Group Archive and the Jupiter Ace Archive. Both contain lots of useful, downloadable material including original manuals and free ebooks.
Forth's ability to create new commands or 'words' beyond the basic set is considered to be one of its most powerful features. Type VLIST at the console command prompt of any version of Forth and you will get a list of all the words it 'understands'. Look at the screen dump for FORTHdsPIC below. A program for making a simple humanoid robot walk has just been downloaded and compiled. The first block of core words may be executed immediately from a command prompt or used to create new word definitions. The second block provide the structure of a compiled program and cannot be executed directly. The third set of words were created when the user program was compiled.
Each of the words LEANLEFT, ROTATELEFT and LEANLEFTBACK defines a single movement of a particular joint servomotor on the left leg. They are combined in the definition for STEPLEFT which causes the left leg to move forward by one step. The other words do the same for the right leg. STEPLEFT and STEPRIGHT are used in the definition for STEP which moves the whole robot one step forward. Finally, STEP is executed repeatedly by a loop in WALK, making the robot 'walk' forward continuously. These new words could become the 'core' words of a robot programming language. ROBOFORTH from ST Robotics is a commercial robot arm programming language that was created in just this way.
What is FORTHdsPIC?
FORTHdsPIC has its origin back in 1982 when I was designing a portable instrument for measuring battery state-of-charge. The complex algorithm made it an ideal candidate for using digital processing, so a design emerged based on the then-ubiquitous Zilog Z80 chip. Forth was all the rage then; articles appearing regularly in computer magazines. There was even a home computer on the market - the Jupiter Ace - that ran Forth rather than the usual BASIC, from the designers of the Sinclair ZX Spectrum. After finding some outline code for a Z80-based compiler in a computer journal, I created LUT-Forth which fitted into a 4KB UV EPROM. The same code also ran on a Kemitron computer under the 8-bit operating system CP/M. The compiled code it produced was blown into another 4KB EPROM which was then plugged into a second socket on the instrument PCB. I didn’t know it at the time, but the result was what we now call an ‘embedded’ computer!
Many years later I gave in to an impulse to convert my original LUT-Forth Z80 code (actually a subset: 8085 code) to a more modern processor and see how it performed. I chose the dsPIC33 and FORTHdsPIC was born. Current microcontrollers have many features that the poor old microprocessors of the 1970/1980's didn't, so it wasn't going to be too difficult to create a better Forth:
- On-chip non-volatile programmable Flash memory. And lots of it.
- Huge variety of on-chip peripheral hardware interfaces.
- Powerful instruction set with hardware multiply/divide instructions.
- And a whole lot more besides.
First version: 40MIPS dsPIC33FJ128MC802 in 28-pin DIL package
Flash memory: 128KB RAM: 16KB
The first host I used for this project was an Arduino-format board made by a firm in Hong Kong and obtained via eBay. It was perfect for this job as it had a USB-UART Bridge chip on board - a Silicon Labs CP2102, and a USB-B connector. This device is so common, all I had to do was connect the USB to a PC with Internet access and the driver was downloaded and installed automatically. The USB link supplies the all-important terminal or console connection needed by FORTHdsPIC for program entry and display.
The board also featured a Microchip PICkit 3 compatible ICSP header. A PICkit 3 provides the programming/debug interface and link to the MPLAB IDE running on the PC.
By the time I'd got to version 0.5 of the firmware I realised that it would be a good idea to switch to a more widely-available development platform. The Microchip MicroStick II seemed ideal as it retained nearly all the functionality of the old board and came with a built-in programmer/debug tool. The latter eliminated the need for the PICkit 3. I described the transition in this DS blog post.
Of course you lose the convenient Arduino header sockets, but gain header pins which will plug into any standard prototyping breadboard block. The USB connector provides a link to the PC running MPLAB IDE and the solder pads at the opposite end give access to the chip's UART1 used for the console. Very few PCs have serial COM ports nowadays, so to provide a console, a UART-USB bridge cable (767-6200) is needed together with terminal emulator software. I used (and still do) the freely available TeraTerm.
It's amazing what you can do with 28 pins, but I began to realise that FORTHdsPIC was starting to out-grow the SPDIP package. At least as a development tool. A specific application might make do with an 8-pin chip and a 2-wire I2C bus to drive external peripherals. See my blog post on I2C serial communication. The 28-pin dsPIC33 device contains far more peripheral function modules than external connections, and pin assignments are programmable by the user. But I wanted all functions to be available at the same time, necessitating the change to a chip with many more pins.
Second version: 70MIPS dsPIC33EP512MU810 in 100-pin TQFP package
Flash memory: 512KB RAM: 52KB
The new home for the current (I hesitate to say final) version of FORTHdsPIC: 0.9, is a MikroElektronika Clicker 2 development board featuring a 70MIPS dsPIC33EP part replacing the old 40MIPS FJ.
Like its predecessors, this is not a Single-Board Computer (SBC) as it does not have the DDR RAM, GPU and other paraphernalia necessary to support an operating system such as Linux or Windows. In fact the only other major chip present, besides the dsPIC itself, is a power management device (PMIC) which reconciles the various power sources available including an optional Li-Polymer rechargeable battery.
Porting the code from MicroStick to Clicker 2 was not without a few niggling problems causing some frustration, but I got there in the end. Two recent DS blog posts here and here document the journey.
Click and the mikroBUS
A microcontroller development board is no earthly use to a designer unless the attachment of, and communication with, application-specific sensor/actuator circuits is both quick and easy. For me, that means at least one pair of parallel socket headers per expansion board should be provided, allowing matching peripheral modules to be mounted. This twin-header approach makes for a mechanically stable arrangement and is featured on Arduino, Beaglebone and MikroElektronika processor boards which take expansion modules called Shields, Capes and Clicks respectively. I’ve always thought the GPIO connector on one side only of the Raspberry Pi was a weak point in the design. Old-timers like me may remember the notorious 16K RAM Pack of the Sinclair ZX81 that flapped about in the breeze losing all your code just after you’d spent ages typing it in….
The Clicker 2 boards have a ‘belt and braces’ approach to expansion connectors: as well as sockets for two Click modules, there is provision for a 26-way GPIO header along each side of the board (See picture above). The functions of the 16-pin headers on a Click module are defined by the mikroBUS standard. Half of them are dedicated to communication: UART, I2C and SPI buses. Four are for power supply: +3.3V, +5V and two Gnd connections. The remaining four are given specific functions, but as they are tied to GPIO pins, they can be assigned for any purpose.
Forth functions available on Clicker 2 mikroBUS sockets
mikroBUS 1: UART channel 1 (Console), ADC channel 1, PWM channel 1
mikroBUS 2: UART channel 2, SPI channel 2, ADC channel 2, PWM channel 2
Forth functions available on Clicker 2 26-way headers
LH header: I2C channel 2, Servo channels 1 to 4, Tacho channels 1 & 2, SPI channel 3 CS 1 & 2
RH header: SPI channel 3, ADC channels 3 & 4
As it stands, the Clicker 2 board only supports two Click peripheral device modules. Even a moderate-sized development project is likely to need more than that. Here’s where those 26-way connectors come in. I soldered stacking headers to each side of the board: these are socket headers with extended solder pins enabling the Clicker 2 to take an expansion board on top and plug in to another underneath. The hand controller for my wireless mobile robot project needed four Click modules: two joysticks, a wireless module and a UART-USB bridge for program development. The mikroBUS Shield provided the answer: it has two sets of Click headers and a useful ‘prototyping’ area as well.
MikroElektronika’s modular system based on Click boards with their mikroBUS connectors is well thought out and allows robust prototypes to be built without the need for fragile wire links. My robot wireless remote-control unit is a good example: it’s strong enough to be tested without any danger of it falling to bits! The only precaution necessary is to keep fingers off the wireless module and its antenna.
The mikroBUS Shield provides two more Click sockets yielding access to different channels of UART, SPI and I2C communication to those on the Clicker 2 board itself.
Forth functions available on mikroBUS Shield sockets
mikroBUS 1: SPI channel 3 (CS1), I2C channel 2, ADC channel 4, Servo channel 1
mikroBUS 2: SPI channel 3 (CS2), I2C channel 2, ADC channel 3, Servo channel 2
Forth functions available on mikroBUS Shield 26-way headers
As for Clicker 2 board.
Not all projects can be constructed entirely from Click modules, so I use the 26-way socket headers on the Clicker 2 for making single-wire connections to other boards. The mobile robot on the other end of the wireless link from the remote-control unit needs just such a connection for its two ultrasonic rangefinders. The SRF08 device is ‘intelligent’, receiving commands and sending back distance data via an I2C bus. I2C is a genuine ‘2-wire’ communication system with a complex protocol that can handle over a hundred addressable devices with just those two wires: one for data (SDA) and the other for the data clock (SCL). The dsPIC has two independent I2C channels: channel 1 appears on both mikroBUS connectors of the Clicker 2 board, channel 2 feeds the sockets on the mikroBUS Shield board (if fitted). For the time being, I’ve only written the driver for channel 2 as the Clicker 2 sockets only need UART or SPI comms, with channel 2 available on the 26-way header for off-board peripherals. My blog post on the wireless robot contains a lot more practical info on the I2C bus, including how to avoid some of those niggling design errors that can drive you crazy!
Benchmarks - how fast does it go?
A set of 16 benchmark routines were developed a long time ago for the purpose of comparing the performance of different Forth implementations. I recently came across the figures for my 1982 4MHz Z80 version and took the opportunity for comparison with FORTHdsPIC.
In order to time each Z80 test with a stopwatch, it was repeated 10000 times giving a result measured in seconds. The overhead of the 'Magnifier' DO...LOOP (BM1) is subtracted from the other tests BM2 to BM16. FORTHdsPIC is timed with the on-chip USER timer and the results are rather more accurate as a result!
The modern chip provides an average speed improvement of around 150 times. The maths routines are around 350 times faster, but that's no surprise as the old Z80 was only an 8-bit machine and featured no multiply or divide hardware. LUT-Forth did, however, acquit itself very well when pitted against many of its contemporaries that were also based on the Z80.