.. index:: plang, svd2forth,plang reader .. _plang: PLANG ===== .. image:: projects/plang/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 :ref:`CMSIS-SVD` compliant peripheral register memory map file. 2. A :ref:`CMSIS-SVD` compliant peripheral register :ref:`bitfield` list. 3. The STM32F0x :download:`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 :ref:`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 ^^^^ .. image:: projects/plang/tim3_smcr.jpg SMS ^^^ .. image:: projects/plang/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 :ref:`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 :ref:`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 :ref:`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 :ref:`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 ? .. image:: projects/plang/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 :ref:`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 .. seealso:: :ref:`Bitfields` .. seealso:: :ref:`Plang for STM32F103C8` .. seealso:: :ref:`PLANG Reader`