Wed Aug 27 14:24:43 CEST 2008
PICkit2 v2.x support
The v2.x Firmware for Microchip's PICkit2 contains a little script
interpreter used to decouple device support from programmer firmware.
I took this as an opportunity to experiment a bit with a different
flavour of metaprogramming. Since it's not a stack machine, I thought
I'd try something special-purpose.
The scripting language contains two parts:
* Interactive commands. The device responds to a set of bytecode
commands transported in 64byte buffers.
* Scripts. In addition, it is possible to store scripts in
programmer RAM using an extra set of instructions.
The first implementation generated a simple assembler from a byte code
table with names stored in a hash table, and a wrapper macro that
allows composition of commands and scripts. Something in the form of:
(begin-script (PRIM1) (PRIM2 arg1 arg2 arg3))
(begin-command (CMD1) (CMD2 arg1 arg2))
Where the first form would compile a script to a list of numbers and
the second would compile an interactive command list and execute it,
collecting the reply.
The second implementation has the interactive and script commands all
visible in the pk2 module namespace. Since they are all upper case,
they do not collide with scheme code. The big advantage here is that
the names are lexical and represent first class functions, and the
composition is scheme's function nesting and procedure sequencing, not
some special purpose 'begin-xxx macro. This allows things like:
(EXECUTE_SCRIPT ;; interactive command
(PEEK_SFR #x80) ;; script
(PEEK_SFR #x81)) ;; script
(UPLOAD_DATA)) ;; interactive
=> (32 251)
Here 'EXECUTE_SCRIPT refers to a function that concatenates all script
code it receives as an argument, uploads it to the PICkit2 for
execution, and waits for a reply. 'PEEK_SFR refers to a function that
checks its arguments and compiles a byte code list.
The code to generate the functional/procedural representation is
really simple, and deals mostly with special case argument formats and
binary data formatting (64 byte buffers).
Then the byte code specification is just a table:
The part- and family-specifict scripts in the PK2DeviceFile.dat
database are similarly accessible using a single Scheme identifier.
This means they can be passed as arguments to 'EXECUTE_SCRIPT.
=> (250 247 249 245 243 0 232 20 246 251 231 127 247 250 251 246 232 19)
The other properties are available as well too: