Code Reviews and Libraries

Code Review, is the act of collaborating with other programmers to check code for mistakes.

A library is a collection of code reused to develop software.

Disclaimer: I’m not a programmer, I’m a electronics technician/designer who stumbles and fumbles his way thru code. I enjoy the process of writing code but only when the end result is a working hardware solution.

Can Forth Code be Reviewed, are Libraries Useful ?

What follows are just a few of my thoughts on these matters, my opinion only, and I’m often wrong.

Every Forth Program is a Different Programming Language

Because Forth programs soon morph into the language of the problem they solve, technically every Forth program is a different programming language, unlike say Pascal or C where the language syntax is always the same from one program to the next.

Note

Would you ask a Haskell programmer to review your Perl code ?

Every Forth Implementation Targets a Specific MCU or MCU Family

Forth is as different as the hardware it runs on. Even in the same hardware family, say STM32xx, Mecrisp-Stellaris Forth may have different Kernel Words between models, depending on the hardware variations.

Examples

Set a BIT:-

Mecrisp-Stellaris for STM32Fxx

$48000800 constant PORTC_Base
PORTC_BASE $18 + constant PORTC_BSRR
4 constant Anode    \ PC4
1 Anode lshift PORTC_BSRR !   ( Anode high )

Flashforth for PIC:-

$ffc2 constant adcon0
%10 adcon0 mset \ Start conversion

Note

Would a Mecrisp-Stellaris user ask a Flashforth user to review their code ?

Most Forth Development Environments Are Different

Forth allows a programmer to design their own Development Environment.

Matthias Koch

Will write his memory mapped code something like this:-

$48000000 constant PORTA_Base
$48000400 constant PORTB_Base
$48000800 constant PORTC_Base
$48000C00 constant PORTD_Base
$48001400 constant PORTF_Base

PORTC_BASE $00 + constant PORTC_MODER    \ Reset 0 Port Mode Register - 00=Input  01=Output  10=Alternate  11=Analog
PORTC_BASE $04 + constant PORTC_OTYPER   \ Reset 0 Port Output type register - (0) Push/Pull vs. (1) Open Drain
PORTC_BASE $08 + constant PORTC_OSPEEDR  \ Reset 0 Output Speed Register - 00=2 MHz  01=25 MHz  10=50 MHz  11=100 MHz
PORTC_BASE $0C + constant PORTC_PUPDR    \ Reset 0 Pullup / Pulldown - 00=none  01=Pullup  10=Pulldown
PORTC_BASE $10 + constant PORTC_IDR      \ RO      Input Data Register
PORTC_BASE $14 + constant PORTC_ODR      \ Reset 0 Output Data Register
PORTC_BASE $18 + constant PORTC_BSRR     \ WO
PORTC_BASE $20 + constant PORTC_AFRL     \ Reset 0 Alternate function  low register
PORTC_BASE $24 + constant PORTC_AFRH     \ Reset 0 Alternate function high register
PORTC_BASE $28 + constant PORTC_BRR      \ Reset 0 Bit Reset Register

He will then use this memory mapping code like so :-

4 constant Anode    \ PC4
5 constant Cathode  \ PC5

%01 Anode   2* lshift
%01 Cathode 2* lshift or PORTC_MODER bis! \ Set anode and cathode as output

Note

“The above code may seem simple enough, but try using this method to set PC4 and PC5 to mode INPUT ? Be sure to test your code and make sure it works first.

The Author

My memory mapping code is different, because I parse it automatically from CMSIS-SVD :-

$48000000 constant GPIOA_MODER ( GPIO port mode register )
$48000004 constant GPIOA_OTYPER ( GPIO port output type register )
$48000008 constant GPIOA_OSPEEDR ( GPIO port output speed  register )
$4800000C constant GPIOA_PUPDR ( GPIO port pull-up/pull-down  register )
$48000010 constant GPIOA_IDR ( GPIO port input data register )
$48000014 constant GPIOA_ODR ( GPIO port output data register )
$48000018 constant GPIOA_BSRR ( GPIO port bit set/reset  register )
$4800001C constant GPIOA_LCKR ( GPIO port configuration lock  register )
$48000020 constant GPIOA_AFRL ( GPIO alternate function low  register )
$48000024 constant GPIOA_AFRH ( GPIO alternate function high  register )
$48000028 constant GPIOA_BRR ( Port bit reset register )

I also prefer to not have to consult the databook when manipulating Register Bitfields of more than ONE BIT, such as GPIOx_MODER which is TWO BITS wide, so I automatically generate Words to make it easy for me.

My thanks to Manfred Mahlow [manfredmahlow] for his bf! code.

: bf! ( bits bf-offs a-addr mask -- )
  swap >r over lshift >r lshift r@ and r> r@ bic! r> bis! ;

%00 constant INPUT
%01 constant OUTPUT
%10 constant ALT-FUNCT
%11 constant ANALOG

: GPIOA_MODER_MODER12 24 $48000000 %11 ;   ( PA12 mode )

OUTPUT GPIOA_MODER_MODER12 bf!     ( PA12 --> OUTOUT --> LED1 Anode )
1 GPIOA_ODR_ODR12 bf!              ( LED1 --> ON )

Note

Charles Moore, the inventor of forth said “ Don’t add extra code that your Forth program doesn’t need, add it later when you need it”.