FlashForth: Simple Setup

7 minute read

UPDATED: Where I describe how to use FlashForth, a phenomenal version of Forth for the ATmega328P to learn how to use Forth in an embedded system.

Notes for Video

  1. Copy the required .hex files to your desktop.
  • FlashForth: flashforth/avr/hex/328-16MHz-38400.hex
  • Optiboot: optiboot/optiboot/bootloaders/optiboot/optiboot_atmega328.hex
  1. Commands for loading respective programs:
avrdude -p m328p -c snap_isp -e -U flash:w:optiboot_atmega328.hex:i -U efuse:w:0xff:m -U hfuse:w:0xda:m -U lfuse:w:0xff:m
avrdude -p m328p -c snap_isp -e -U flash:w:328-16MHz-38400.hex:i -U efuse:w:0xff:m -U hfuse:w:0xda:m -U lfuse:w:0xff:m


A More Powerful Forth

I really like FlashForth. It is extremely well documented thanks to the developer, a few college papers, a board manufacturer and a great site. All of those sites have been incredibly helpful and I strongly recommend you spend time on those sites to better understand FlashForth. I have yet to find a bug and it is amazingly fast on an 8-bit processor such as the ATmega328.

FlashForth and the ATmega328P are perfect for the beginner to explore writing firmware for embedded processors. As the tutorials show, its extremely simple to build a system using either the PIC microcontrollers or the ATmega328P. I’d recommend the latter as the tools and information are widely available due to the ubiquity of the Arduino. The speed, age and 8-bit size of the 328P are an advantage, not a problem. Forth depends on understanding the microcontroller extremely well, as this is its strength. And the ATmega family might be one of the most well-documented microcontroller product lines ever.

What’s Required:

  1. Arduino UNO or compatible board (target system) - this can be any version of the Arduino UNO and it doesn’t have to have the 28 pin integrated circuit (IC chip), it can have the surface mount version. Or the Arduino Nano, any Arduino-compatible ATmega328P microcontroller board will work. Microchip also has a ATmega328PB Xplained Mini for about $13 which is phenomenal. It has both a 328PB chip and an ATmega32U4 for serial communications and a hardware debugger (mEDBG). I have written about it here. $13-$25
  2. AVR-compatible ICSP programmer (used to load code on to 328P chip). For example, another UNO, or the Microchip MPLAB Snap. I was using the AVR Dragon as I have had it for years, however, the board is “no longer available”. I just started using the Snap, and it works quite well with avrdude or the Microchip IPE software. Or if you have the ATmega328PB Xplained Mini, it can program itself! $0(ATmega328PB Xplained Mini)-$34(Microchip Snap)
  3. FlashForth on Github Free

1. Load FlashForth on Uno

Using avrdude

This process will assume the command line using either Linux or Mac. Using Windows with Atmel Studio will be dramatically different. If you are using Windows, I’d encourage to visit Arduino-Forth, as he covers FlashForth incredibly well and is Windows-based.

Using Microchip Snap

# Assume you have cloned or downloaded FlashForth from GitHub
# do everything from the hex folder 
cd flashforth/avr/hex
2560-16MHz-38400.hex     328-16MHz-38400.hex      32u4-16MHz-UART38400.hex 32u4-16MHz-USB.hex
# Connect the programmer (Microchip Snap) to the UNO using an ISP cable (See link below)
# A good initial command is to confirm your programmer can "see" the UNO
avrdude -p m328p -P usb  -c snap_isp -t
# interactive mode, enter the command part to confirm ISP sees a 328P
# then quit to exit
avrdude> part
avrdude> quit
# command to write code
avrdude -p m328p -c snap_isp -e -U flash:w:328-16MHz-38400.hex:i -U efuse:w:0xff:m -U hfuse:w:0xda:m -U lfuse:w:0xff:m
# connect with a serial program like screen, serial, moserial etc

Using Microchip ATmega328PB Xplained Mini

cd flashforth/avr/hex
avrdude -p m328pb -P usb  -c xplainedmini -t
avrdude -p atmega328pb  -c xplainedmini -P usb -U ./328-16MHz-38400.hex

Using Microchip IPE and Snap

  1. Download the Microchip IDE. The IPE (Integrated Programming Environment) works quite well for programming boards on Windows/macOS/Linux. It appears you can only install the IPE via the IDE installation. It’s a pain. I selected only IPE and 8-bit processors and still ended up with over 2GB of bloat. I spent a little bit of time removing packs I didn’t use and was able to get it down to 1.46GB. Small victory. In the meantime, install the IDE…and only use the IPE for programming. I have instructions here for using the IDE to compile a new version of Flashfort.
  2. Here’s the IPE programming window:
    Using Microchips IPE and Snap

    Using Microchips IPE and Snap

    Large Version to see detail

With the IPE, you select your device, tool and add the hex file in the hex file: location. Click program and the IPE/Snap or IPE/Xplained Mini will take care of the rest.

2. Connect to Uno with a Serial program

Use a serial program such as Windows/CoolTerm, Linux/moserial or macOS/CoolTerm and connect your Uno with FlashForth to your computer. The connection for FlashForth is 38400 baud, 8 bits/No parity/1 stop bit, XON/XOFF is on.

If all goes well, you’ll end up with a line which looks like this and enter a simple test to show that Forth is working:

E FlashForth 5 ATmega328 14.04.2022

2 3 + . 5  ok<#,ram> 

and enter words to see all of the words in FlashForth: (your line-endings might differ)

p2+ pc@ @p ddrb portb hi unused d. ud. d> d< d= d0< d0= dinvert d2* d2/ d- d+ 
dabs ?dnegate dnegate s>d rdrop endit next for in, inline repeat while again 
 until begin then else if zfl pfl xa> >xa x>r dump .s words >pr .id ms ticks r0 s0  
 latest state bl 2- ['] -@ ; :noname : ] [ does> postpone create cr [char]  
 ihere ( char ' lit abort" ?abort ?abort? abort prompt quit true false .st  
 inlined  immediate shb interpret 'source >in tiu tib ti# number? >number ud/mod  
 ud* sign? digit? find immed? (f) c>n n>c @+ c@+ place cmove word parse \ / 
 string  source user base pad hp task ulink rsave bin hex decimal . u.r u. sign
  #> #s #  digit <# hold up min max ?negate tuck nip / u*/mod u/ * u/mod um/mod 
 um* 'key?  'key 'emit p++ p+ pc! p! p@ r>p !p>r !p u> u< > < = 0< 0= <> within
 +! 2/ 2* > body 2+ 1- 1+ negate invert xor or and - m+ + abs dup r@ r> >r rot 
 over swap drop  allot ." ," s" (s" type accept 1 umax umin spaces space 2swap
  2dup 2drop 2! 2@ cf, chars char+ cells cell+ aligned align cell c, , here dp 
  ram eeprom flash  >< rp@ sp! sp@ 2constant constant 2variable variable @ex 
  execute key? key emit  Fcy mtst scan skip n= rshift lshift mclr mset ic, i,
   operator iflush cwd wd- wd+  pause turnkey to is defer value fl+ fl- c! c@ @
    a> ! >a literal int! ;i di ei 
ver warm empty rx0? rx0 tx0 load- load+ busy idle exit 
marker  ok<#,ram> 

3. Editing and Uploading Forth programs

The final step once you have a working serial connection is to begin writing Forth programs and uploading them to the Uno. For editing, any programming editor will work. I use Sublime Text, others could be Windows/Notepad+, macOS/Atom and Linux/Kate.

For uploading, I use a program I wrote called up.py. It is designed to load a line, wait for a response from FF then upload the next line. It works fairly fast, given its 38400 baud. For example the almost 300-line 328PHAL file will load in approximately 4 seconds. This is comparable in speed to a similar sized C file getting compiled and uploaded using the Arduino IDE.

Add an .env file

The up.py program uses a environmental variables file called .env. The program looks for it in the same folder as the execution. For example if I am using the repository AVR_FF, the .env file is at the root level. It is simple file which contains the USB port address required to communicate with the board. The serial port is typically called:

  • macOS - /dev/cu.usbmodem3101 or /dev/cu.usbserial-01D5BFFC
  • Linux - /dev/ttyACM0 or /dev/ttyUSB0
  • Windows - COM3 or COM5

And the single line in the folder is


Be sure to change the port designation to the USB port on your system!

For example, when I upload the HAL, I do this with the following response: (The -e or –empty option is new, it will send an empty word prior to upload, this is helpful when uploading a file like a HAL.)

$ up.py -e Library/328P_HAL.fs

*** lines read: 227
*** elapsed time: 0:00:03.872066 (1190 bytes/s) ***

If I have an error, then I will see a window which appears like this:

FlashForth error listing when using up.py

FlashForth error listing when using up.py

Large Version to see detail

The errors found will be in red. I recommend solving the first error found as the ripple effect in Forth is extensive (errors cause more errors etc). To accelerate your ability to work with the Uno and Flashforth, I have a Github repository AVR_FF which has examples and the latest copy of the HAL.

Old Debugging help:

Old but helpful link on connecting UNO to ISP programmer

Snap Programming Issues

avrdude warning: avrdude: usbhid_open(): No device found

When using the SNAP as your programmer, you might see this warning, avrdude: usbhid_open(): No device found and find your programmer worked as expected. The error is described here and is not a significant problem. When looking for programmers, avrdude will rotate three PID’s and if it doesn’t find a device, it says so. One can either ignore it or fix the avrdude.conf file. To do so, find your avrdude.conf file and move the 0x2180 PID to the beginning so that it is found first.:

  id    = "snap_isp";
  desc  = "MPLAB(R) SNAP in ISP mode";
  type  = "jtagice3_isp";
  connection_type = usb;
  usbpid = 0x2180, 0x217F, 0x2181;
# old  usbpid = 0x217F, 0x2180, 0x2181;

Comments powered by Talkyard.