Tero's blog

Random notes

Porting PN532 routines from AVR-Ada to GNAT ARM

Olimex STM32-E407 with PN532 breakout board

If you have followed my Arduino blog you know that I have written some time ago PN532 routines for AVR-Ada.

Now, to play with Ada_Drivers_Library, I decided to port my PN532 routines to ARM Cortex-M4 using STM32F4 board (STM32-E407) from Olimex.

The porting process was relatively smooth, as I already had separated SPI/I2C bus related communication from other logic. I mostly had to replace my AVR-Ada specific logging routines with ones for ARM/STM32.

The biggest problems I had with STM32-E407 board, which doesn't have its own board definition in Ada_Drivers_Library / embedded-runtimes repo.

With following tweaks to embedded-runtimes I got the board (and its UART/SPI peripherals) working:

diff --git a/bsps/stm32f4/bsp/s-bbbopa.ads b/bsps/stm32f4/bsp/s-bbbopa.ads
index 95c65e5..98668ea 100644
--- a/bsps/stm32f4/bsp/s-bbbopa.ads
+++ b/bsps/stm32f4/bsp/s-bbbopa.ads
@@ -37,12 +37,12 @@ package System.BB.Board_Parameters is
    -- Hardware clock --

-   Main_Clock_Frequency : constant := 168_000_000;
+   Main_Clock_Frequency : constant := 144_000_000;
    --  Optimal frequency of the system clock. Note that the STM32F411 can go
    --  up to 200 MHz, but all other STM32F40x and STM32F41x MCUs can only do
    --  168 MHz.

-   HSE_Clock_Frequency : constant := 8_000_000;
+   HSE_Clock_Frequency : constant := 12_000_000;
    --  Frequency of High Speed External clock.

    FLASH_Latency : constant := 5;
diff --git a/bsps/stm32f4/bsp/setup_pll.adb b/bsps/stm32f4/bsp/setup_pll.adb
index 59c0363..96e4aff 100644
--- a/bsps/stm32f4/bsp/setup_pll.adb
+++ b/bsps/stm32f4/bsp/setup_pll.adb
@@ -51,7 +51,7 @@ procedure Setup_Pll is
    LSI_Enabled     : constant Boolean := True;  -- use low-speed internal clock

    Activate_PLL       : constant Boolean := True;
-   Activate_Overdrive : constant Boolean := True;
+   Activate_Overdrive : constant Boolean := False;
    Activate_PLLI2S    : constant Boolean := False;

    pragma Compile_Time_Error (not (if Activate_PLL then HSE_Enabled),

Basically, I decreased the clock speed a little and corrected the HSE clock frequency (because the Olimex board uses 12MHz crystal).

In theory, STM32F407 on the Olimex board should be able to run at 168MHz, but for some reason the clock speed calculation algorithm used in embedded-runtimes worked only up to 144MHz.

Anyway, the code is now available under my Github account in my Ada_Drivers_Library fork.

There are some caveats though:

  • Reading NFC-enabled Yubikeys do not seem to work, although they work with AVR-Ada version
  • Likewise, there are some problems with NFC tag emulation

I suspect that they are some timing related errors as PN532 is sometimes quite sensitive to timings. In addition, in my AVR-Ada code I have used quite short timeout values for calls and they might be calculated incorrectly on ARM.

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