Tero's blog

Random notes

Running Ada 2012 on Olimex STM32-E407 (ARM Cortex-M4 / STM32F4)

Almost two years after I got my first ARM Cortex-Mx device, I finally found time to build Ada ARM Cortex-M cross-compiler using FSF GCC/GNAT. But, instead of Atmel SAM3, I used STM32F4 processor found from Olimex STM32-E407 board.

Relevant code pieces are sprinkled into three repositories at Bitbucket:

First repository, embedded-arm-gnat-build, contains the build scripts for GNAT (arm-none-eabi target; the script for binutils is missing, you need to install it manually).

The second repository (embedded-arm-gnat-rts) has simple runtime for GNAT. It is almost direct copy of Lucretia's TAMP RTS. The runtime does not have install script, so after building it you need to install the runtime manually.

The third one (gnat-arm-app-skeleton) contains the actual application. I loaned the startup files from mbed project, in case you wonder why there are so many C and assembler files. They could be optimized to two simple assembler files, but I haven't got that far.

The most interesting parts of the app are here:

-- blink.adb, Ada 2012 code
with Interfaces;
with STM32F4;

procedure Blink is
   use type Interfaces.Unsigned_32;

   procedure My_Delay is

      -- Mark X volatile so that GNAT does not optimize
      -- the loop. Notice the new Ada 2012 aspect syntax.
      X : Interfaces.Unsigned_32 := 0 with Volatile;
   begin
      loop
         exit when X = 1000_000;
         X := X + 1;
      end loop;
   end My_Delay;

begin
   STM32F4.RCC_ENABLE := STM32F4.RCC_ENABLE
     or STM32F4.GPIOC_ENABLE_BIT or STM32F4.GPIOD_ENABLE_BIT;

   --                            13 c  b a  9 8  7         3
   STM32F4.GPIOC_MODE  := 2#0000_0101_0101_0000_0000_0000_0000_0000#;
   STM32F4.GPIOC_TYPE  := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- push-pull
   STM32F4.GPIOC_SPEED := 2#0000_1100_0000_0000_0000_0000_0000_0000#; -- fast
   STM32F4.GPIOC_PUPD  := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- no pull

   STM32F4.GPIOD_MODE  := 2#0000_0101_0101_0000_0000_0000_0000_0000#;
   STM32F4.GPIOD_TYPE  := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- push-pull
   STM32F4.GPIOD_SPEED := 2#0000_1100_0000_0000_0000_0000_0000_0000#; -- fast
   STM32F4.GPIOD_PUPD  := 2#0000_0000_0000_0000_0000_0000_0000_0000#; -- no pull

   STM32F4.GPIOC_BSRR  := 2#0111_1000_0000_0000_0000_0000_0000_0000#;
   STM32F4.GPIOD_BSRR  := 2#0000_0000_0000_0000_0011_1100_0000_0000#;
   loop
      STM32F4.GPIOC_BSRR := 2#0111_1000_0000_0000_0000_0000_0000_0000#;
      STM32F4.GPIOD_BSRR := 2#0111_1000_0000_0000_0000_0000_0000_0000#;
      My_Delay;
      STM32F4.GPIOC_BSRR := 2#0000_0000_0000_0000_0111_1000_0000_0000#;
      STM32F4.GPIOD_BSRR := 2#0000_0000_0000_0000_0111_1000_0000_0000#;
      My_Delay;
   end loop;
end Blink;

The program blinks various leds at port C and port D.

On Olimex STM32-E407, which I used for testing, the status led is at port C13. If you use the same board, you should see the led blinking.

Olimex STM32-E407

Note: My build scripts, GNAT runtime for ARM Cortex-Mx, and other Ada code are still very rough. I just wanted to try is it possible to use FSF GNAT for ARM Cortex-Mx development. As my time permits, I will continue to improve things, but it will take some time.


Copyright © 2011 Tero Koskinen - Theme Skeleton; Blogging engine Pelican; Powered by Python