PLANG

_images/plang-icon-red.png

PLANG ?

The name is an abbreviation of Peripheral Language.

Audience

Electronics people who use Mecrisp-Stellaris Forth under Unix to make real hardware devices using STM32 MCU’s.

Synopsis

PLANG :

  • encourages detailed source documentation for peripheral configurations, to assist knowledge sharing, code reuse and maintenance for hardware.

  • a SQlite database of PLANG Words is automatically created to easily find STM32 bitfields.

  • automatically parses your Forth source code and supplies the dependencies so you don’t need to do it manually.

  • encourages multiple file use without the need for buried include commands, so your files are still Mecrisp-Stellaris compatible without a special Linux only terminal or Python based uploader.

  • doesn’t need a terminal to develop a project, tho one is included. Most work is done from your favorite text editor.

Target MCU

The STM32F0xx is used for all PLANG examples here, tho PLANG will work for any STM32 for which there is a CMSIS-SVD XML file available.

Scope

This document will attempt to explain what PLANG does, later documents will explain how PLANG works in detail.

STM32 Peripheral Howto

  • Read the reference manual for an hour

  • Verify it doesn’t work as it should

  • Curse

  • Read the reference manual for 10 hours

  • Try everything

  • Accept the fact you still don’t understand what the hell is going on and try harder

  • Use Forth to explore a wide range of tests, verify the results with assertions

  • Finally understand what is required and wonder why the hell you didn’t get it the first time

  • ;-)

Usage

Anyone making a hardware device using the STM32 peripherals must have at least the following information:

  1. A CMSIS-SVD compliant peripheral register memory map file.

  2. A CMSIS-SVD compliant peripheral register bitfield list.

  3. The STM32F0x Technical Reference Manual to explain how to use and configure the peripherals.

  4. A clear concept of what the peripheral is expected to do.

PLANG removes items 1. and 2. from the list.

Everything in PLANG is coordinated by a Makefile which you configure initially to include the type of STM32 target MCU you’re using. Basically one edits their source and enters “Make” and everything is uploaded to the on chip Forth to be compiled. Errors in the code and logic are fixed and the process is repeated as required.

Configuring The Peripheral

This is why PLANG exists.

Let’s use the Quadrature Rotary Switch project source code as an example ?

After reading the Technical Reference Manual section for Timer 3, I discovered needed (amongst other things) to configure “TIM3 to encoder mode 1” so how is this done using PLANG ?

SMCR

_images/tim3_smcr.jpg

SMS

_images/sms.jpg
  1. Find the SMS bitfield for TIM3.

  2. Set TIM3_SMCR_SMS to %001.

We can use the PLANG database search facility like so:

Find the SMS bitfield for TIM3

SQlite is used for the database and a howto for CLI operations can be found here: https://sqlite.org/cli.html

Search #1

Lets search for the name ? This is entered on your Unix PC to start SQlite and load the database into it.

# sqlite3 bitfields.db

And then this:

.mode column
.width 15 15 15 4 2 2 50
SELECT * FROM 'TIM3'  WHERE name LIKE '%SMS%';

Output

TIM3_SMCR_SMS<     ( %3 --  x )                     rw  3   0   Slave mode selection

Search #2

Or we can search on the description field ?

SELECT * FROM 'TIM3'  WHERE description LIKE '%Slave%';

Output

TIM3_SMCR_SMS<     ( %3 --  x )                     rw  3   0   Slave mode selection

PLANG Database Syntax Table

Description

Meaning

Taken from CMSIS-SVD ?

TIM3_SMCR_SMS<

The PLANG Word name

TIM3_SMCR_SMS

The fully compliant CMSIS-SVD bitfield name

X

<

Appended indicator: TIM3_SMCR_SMS is expecting a input parameter

( %3 – x )

Stack comment: The input parameter is 3 bits wide, (0x000 to 0x111) a value “x” is output

rw

The TIM3_SMCR_SMS bitfield is read-write

X

3

The input parameter is 3 bits wide

X

0

The register offset is zero

X

Slave mode selection

Description field

X

Note

X means YES

Set TIM3_SMCR_SMS to %001

Having found the correct name we can paste that in the source code with %001 as the input parameter, and store the output to TIM3_SMCR like so:

%001 TIM3_SMCR_SMS<          \ %001: Encoder mode 1
TIM3_SMCR hbis!              \ save %001 to TIM3_SMCR

That’s all you need to enter, even tho TIM3_SMCR is a peripheral register and has a fixed memory address, PLANG will insert both that and the actual Word “TIM3_SMCR_SMS<” into a “includes” file as shown in the flowchart below.

includes.fs

These have been automatically inserted based on the results of the source by PLANG. You don’t have to insert them manually.

Note

only relevent text included, everything is available in the Quradature Rotary Switch example

\ ------------------------------------------------------------------------------ \
\ includes.fs
\ f0-quadrot-sw2.fs preprocessor generated dependencies
compiletoram
$40000408 constant TIM3_SMCR \ slave mode control register
: TIM3_SMCR_SMS<   ( %3 --  x )      ; \ rw","3","0","Slave mode selection

A Do Nothing Word ?

Does this Word really do nothing because the output parameter is just the input parameter ?

Note

The bit offset is zero, it’s not even shifted left.

I suppose if you consider documentation and maintennance unimportant, then the Word is indeed doing nothing.

Note

Out of the 26 Words inserted into the includes.fs file by PLANG at the end of the Quadrature Rotary Switch project, only 3 are do nothing words including this example.

Disassembled

The cost of this ‘do nothing’ Word is two bytes which is the return code present at the end any Word.

see TIM3_SMCR_SMS<
20000C06: 4770  bx lr
Bytes: 2  ok

Inlined

When TIM3_SMCR_SMS< is incorporated into the tim3-config Word the return code isn’t used again due to automatic inlining.

Disassembled

see tim3-config
20000E46: 2080  movs r0 #80
20000E48: 0500  lsls r0 r0 #14
20000E4A: 3080  adds r0 #80
20000E4C: 00C0  lsls r0 r0 #3
20000E4E: 8B03  ldrh r3 [ r0 #18 ]
20000E50: 2280  movs r2 #80
20000E52: 0052  lsls r2 r2 #1
20000E54: 3201  adds r2 #1
20000E56: 4313  orrs r3 r2
20000E58: 8303  strh r3 [ r0 #18 ]
20000E5A: 8C03  ldrh r3 [ r0 #20 ]
20000E5C: 2222  movs r2 #22
20000E5E: 4393  bics r3 r2
20000E60: 8403  strh r3 [ r0 #20 ]
20000E62: 8903  ldrh r3 [ r0 #8 ]
20000E64: 2201  movs r2 #1
20000E66: 4313  orrs r3 r2
20000E68: 8103  strh r3 [ r0 #8 ]
20000E6A: 2327  movs r3 #27
20000E6C: 62C3  str r3 [ r0 #2C ]
20000E6E: 6983  ldr r3 [ r0 #18 ]
20000E70: 22C0  movs r2 #C0
20000E72: 0192  lsls r2 r2 #6
20000E74: 3230  adds r2 #30
20000E76: 4313  orrs r3 r2
20000E78: 6183  str r3 [ r0 #18 ]
20000E7A: 8803  ldrh r3 [ r0 #0 ]
20000E7C: 2201  movs r2 #1
20000E7E: 4313  orrs r3 r2
20000E80: 8003  strh r3 [ r0 #0 ]
20000E82: 4770  bx lr
Bytes: 62  ok.

The Old Dichotomy

Is This Efficient ?

That depends on who you ask, after all 2 bytes are wasted for nothing but documentation and maintenance

A career programmer/Hacker who is not also a career electronics technician/engineer will probably say “no”, perhaps because they have embraced the Manifesto for Agile Software Development which states :-

“Working software over comprehensive documentation” ?

A career electronics person who programs enough to make his device work (like me) will say, “aha, so that’s how this peripheral is configured”. Everything is included, and although the contents of the includes.fs file isn’t shown in the source (on purpose) it’s still there in the project to be referred to as needed. A maintainer now has all the hardware configs displayed in the open, not buried inside magic numbers in write only code. The code re-user can now easily see what variables need changing to suit his application.

This dichotomy of viewpoint is nothing new. In the 1970’s when Chrysler developed the ‘Learn Burn Hemi Engine’ they encountered a major problem …

Within 6 months, the mechanical engineers and the electronics engineers were refusing to communicate because each team was convinced the other team wasn’t telling them the truth during project collaboration. The truth was that no one was lying.

Put simply, the two disciplines were so different that each team had no idea what the other team was talking about so a lot of what they heard sounded like b.s.

The Modern Age

In the 1990’s when a Microchip PIC had 1K of flash and 80 bytes of ram, there was nothing to spare. You had to use assembly or C, or if you were really fortunate a Tethered Forth.

In 2014 a STM32F051 with 64KB of flash and 8 KB of ram cost $0.56 USD ea, retail and can in my opinion easily afford a little inefficiency in the name of maintainable and reusable code.

Jump to a STM32F407 with 1MB flash and the question isn’t even relevant.

PLANG Flowchart

Briefly, PLANG intelligently processes the CMSIS-SVD file and then your Forth source so it may supply all the dependencies automatically, so you don’t have to do it.

Who here has not left blocks of memory mapped constants in their Fourth source simply because they were not used and then forgotten ?

_images/flowchart.png

Intelligent Processing ?

PLANG processes the CMSIS-SVD file based on the access mode, i.e. read-write,read-only or write-only and the bitfield bitwidth, i.e. only one bit or greater than one bit. Words are auto-created to best suit these factors.

PLANG Database

If you’d like to play with the SQlite3 database in the example above, it can be downloaded here:

https://sourceforge.net/projects/mecrisp-stellaris-folkdoc/files/STM32F103C8-plang-db.tar.gz is a tarball with the following contents:

.
├── README
├── STM32F103C8T6.memmap.fs
├── bitfields.db
└── mit-license.txt

Although I show a simple CLI SQL search method, there are a number of nice FLOSS GUI apps that can read and modify SQlite databases also. They will all work with this database.

How is the Database Created ?

As shown in the flowchart, PLANG (via SVD2FORTH-V6) creates the pattern files for Gemu which are used later in scanning the user Forth source before upload. A shell script then removes all SQlite3 unfriendly text to create the database. This way, because it all only uses the one source, when I change the (alpha level) PLANG language, all changes are faithfully updated in the database.

Peripherals Configured

Assuming the peripheral configs are all completed, your Forth program can now move to the higher level of a PDL.

This excerpt is taken from the Quadrature Rotary Switch project showing part of my PDL solution.

: test-switch   ( -- ) \ PB4 = BLUE. PB5 = GREEN.
   test-switch-config  \ Very slowly turn switch, watch the leds to see the contact and detent sequence.
   BEGIN
      PB4?             \ high = BLUE on
      PB5?             \ high = GREEN on
   key? UNTIL          \ Escape main loop if any keyboard key is pressed
;

Dependencies

PLANG depends upon SVD2FORTH-V6, Gemu, Sqlite3, Swdcom and a few other common Unix utilities such as Shell.

The End

For now as this project is still Alpha level really. Next will be a detailed page, with a working project and all files.

Terry @ 17 October 2021

See also

Bitfields

See also

PLANG Reader