Code Monkey home page Code Monkey logo

ada_drivers_library's Introduction

Gitter chat CI status

1. Introduction

This repository contains drivers and sample projects to program micro-controllers with the Ada and SPARK languages. The library also provides some middleware services and drivers for external devices such as sensors. We intend this to be a location for both AdaCore and the community in general to contribute support for additional processors, platforms, and vendors.

2. Supported hardware

Ada_Drivers_Library provides support for various devices in the ARM Cortex-M and RISC-V architectures. Some devices are only partially supported. Go to the boards directory for a list of supported hardware.

Board list

Arch Board
ARM STM32F407_Discovery
ARM STM32F429_Discovery
ARM STM32F469_Discovery
ARM STM32F4XX_M
ARM STM32_F4VE
ARM STM32F746_Discovery
ARM STM32F769_Discovery
ARM STM32_H405
ARM NUCLEO_F446ZE
ARM Crazyflie
ARM Feather_STM32F405
ARM OpenMV2
ARM MicroBit
ARM NRF52_DK
RISC-V HiFive1
RISC-V HiFive1_rev_B
RISC-V Unleashed
Native

3. Getting started

To start using the Ada_Drivers_Library, please go to the examples directory where you will find instructions to run your first project.

4. License

All files are provided under a 3-clause Berkeley Software Distribution (BSD) license. As such, and within the conditions required by the license, the files are available both for proprietary ("commercial") and non-proprietary use.

For details, see the LICENSE file in the root directory.

5. Requirements

The software is written in Ada 2012 and uses, for example, preconditions, postconditions, and the high-level iterator form of for-loops.

In addition, a GNAT implementation-defined pragma is used extensively. This pragma makes it possible to avoid explicit temporary copies when assigning components of types representing hardware registers requiring full word or full half-word accesses. The pragma is named Volatile_Full_Access. Those persons wishing to submit additions to the library should see the GNAT Reference Manual for details.

Therefore, building with the sources requires a compiler supporting both Ada 2012 and the GNAT-defined pragma Volatile_Full_Access. For instance a recent GNAT Pro compiler or GNAT FSF 12 for ARM ELF or RISC-V ELF (Download here).

6. Roadmap

Here is a list of projects that we are either dreaming about or already working on. If you are interested by one of those, please contact us on the project's GitHub page.

  • ARM
  • STM32F4/7 USB drivers
  • Components
  • BlueNRG-MS (Bluetooth Low Energy Network Processor)
  • Services
  • Bluetooth Low Energy stack
  • USB stack

7. Project using the Ada_Drivers_Library

(Add yours to the list!)

ada_drivers_library's People

Contributors

astro-jerry avatar dkm avatar elbric0 avatar emareg avatar fabien-chouteau avatar feqzz avatar gingold-adacore avatar jbester avatar jeremygrosser avatar lambourg avatar mbdme26 avatar mbeckersys avatar mcneight avatar morbos avatar mosteo avatar nocko avatar pat-rogers avatar plestedr avatar pmderodat avatar quinot avatar reznikmm avatar rod-chapman avatar rree avatar simonjwright avatar stangassinger avatar trainman419 avatar vassilydev avatar victorlsogilis avatar wickedshell avatar wridder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ada_drivers_library's Issues

EthDemo constant restart

Hi,
I've got blink.adb running on a Nucleo STM32F429ZI board.

When I attempt to run Ethdemo.adb the program constantly resets.

It resets on line 160 of stm32-eth.adb
Rx_Descs (I) := (Rdes0 => (Own => 1, others => <>), Rdes1 => (Dic => 0, Rbs2 => 0, Rer => (if Last then 1 else 0), Rch => 1, Rbs => Rx_Buffer'Length, others => <>), Rdes2 => W (Rx_Buffs (I)'Address), Rdes3 => W (Rx_Descs (I + 1)'Address));

within the procedure Init_Rx_Desc (I : Rx_Desc_Range)

The Nucleo board uses a PHY LAN8742A-CZ-TR

F7 SPI clock

On the F7 and L4 the SPI clock trains length seems to be determined by the greater of this logic:

  1. The DS[3:0] field
  2. The size of the instr used to read/wr (ld/st, ldh/sth, ldb/stb)

A new L4/F7 field is data size DS[3:0] = 7 (=8bits (chip default btw)) but use a 32bit st instr to write the DR reg... you will get the maximal 16 clocks.

Of course, the svd file has volatile, size => 32. Perhaps you can now see where this is going...

Unless the volatile write is for a size 8 bit field, the SPI clock train will get widened to 16 despite DS's smaller setting.

On the F1 and F4 the CR1 bit11 DFF field dictates clock train size. The DFF field has been changed in the L4 and F7 to CRCL int the RM but remains DFF in the svd(!).

As a workaround, I funnel all 8bit read/writes to a asm peek poke funcs. Ugly... but works.

tnx

Hedley

STM32F42x needs UART 7, 8

ARM/STM32/devices/stm32f42x/stm32-device.ads should support UART7, UART8 (RM0090 Fig 27 shows they are on STM32F42xxx and STM32F43xxx).

Also the AFs ...

Post-conditions in GPIO are wrong

There's at least one post condition in the GPIO that is invalid:
overriding
procedure Set (This : in out GPIO_Point) with
Inline,
Post => Set (This);

Sometimes, setting a pin to a particular value will have no effect if the output is Open Drain, but is not erroneous either.

Trying to build STM32F411 Nucleo

Hello,
I'm trying to build a runtime for STM32F411RE Nucleo board.
One of the problems I face is that for example, stm32-timers.ads refers to TIM6_Base, TIM7_BASE, TIM12_Base, TIM13_Base and TIM14_Base which do not exist in the SVD file I got for STM32F411.
For stm32-usarts.ads from uart_stm32f4, the same kind of problem appears with USART1_Peripheral .
What is the right way to proceed and correct these problems?

Thanks for help

stm32f46_79x/stm32_svd-ethernet.ads: definitions for MAC addresses

I'm a bit confused by this. I'd be grateful for any pointers. The file stm32_svd-ethernet.ads defines the MAC address in two halves. For example:

MACA0HR at 64 range 0 .. 31;
MACA0LR at 68 range 0 .. 31;
MACA1HR at 72 range 0 .. 31;
MACA1LR at 76 range 0 .. 31;
MACA2HR at 80 range 0 .. 31;
MACA2LR at 84 range 0 .. 31;
MACA3HR at 88 range 0 .. 31;
MACA3LR at 92 range 0 .. 31;

So each is a 32 bit word.

They are later set as, for example:

MAC2AH : MACA2HR_MAC2AH_Field := 16#FFFF#;

The problem I've got is that a MAC address is of the form:

hh:hh:hh:ll:ll:ll

eg:

01:23:45:67:89:ab

In other words, it's made up of six bytes. The definition in the file is, of course, for four bytes, two sixteen bit words.

Shouldn't the correct form be, for example:

MAC0AH : MACA0HR_MAC0AH_Field := 48#FFFFFF#;
MAC0AL : MACA0LR_MAC0AL_Field := 48#FFFFFF#;

So that, for the above example, it'd be set as:

MAC0AH : MACA0HR_MAC0AH_Field := 48#012345#;
MAC0AL : MACA0LR_MAC0AL_Field := 48#6789ab#;

Example: tracks_display.adb incorrect definition

tracks_display.adb:37:04: "Track_Color" conflicts with declaration at line 36

The problem is:

Track_Color : constant Bitmap_Color := HAL.Bitmap.Light_Gray;

The package wants gray misspelt 'Grey'. Replacing line 36 with:

Track_Color : constant Bitmap_Color := HAL.Bitmap.Light_Grey;

Fixes the problem.

HAL.Filesystem: memory allocations

Hi,

In HAL.Filesystem, the FS_Driver.Open primitive creates a File_Handle_Ref, so I guess users are supposed to deallocate the handle when done with it (after calling Close, which have no access view). If this is indeed how file handles are supposed to be handled, what about providing in HAL.Filesystem a procedure to deallocate one? This would avoid for all users the pain of instantiating one. :-) Likewise for directory handles.

Ethernet & TCP/IP

Are there any plans on making use of the Ethernet port on the stm32f7 discovery board?

mpu9250 self test configuration

In components/src/motion/mpu9250/mpu9250.adb:193 there is

      MPU9250_Write_Byte_At_Register
        (Device, MPU9250_RA_GYRO_CONFIG, Shift_Left (1, FS));
[...]
      MPU9250_Write_Byte_At_Register
        (Device, MPU9250_RA_ACCEL_CONFIG, Shift_Left (1, FS));

which is equivalent to kriswiner’s code:928 and has, I believe, the same issue; in both cases it should be Shift_Left (FS, 3).

STM32 DMA Interrupts don’t allow priority control

As in the title: to mimic the Certyflie DMA setup I need control of the DMA transfer to the NRF51.

I tried modifying STM32.DMA.Interrupts to

   protected type DMA_Interrupt_Controller
     (Controller : not null access DMA_Controller;
      Stream     : DMA_Stream_Selector;
      ID         : Ada.Interrupts.Interrupt_ID;
      Priority   : System.Interrupt_Priority)
   is
      pragma Interrupt_Priority (Priority);
      ...

(well, to be honest, I tried providing a default for Priority, but that would mean providing defaults for all).

This then leads to a problem with STM32.Device: it declares DMA_Interrupt_Controllers, whose priority would be fixed (and probably not to the one I need!). And of course I can’t declare my own, because that would mean attempting to attach two handlers to the same interrupt.

I’d think we could achieve this by declaring subtypes and leaving it up to the user to declare instances as required, from the provided subtype if the defaults are OK.

   subtype DMA2_Stream6_Type is DMA_Interrupt_Controller
     (Controller => DMA_2'Access,
      Stream     => Stream_6,
      ID         => Ada.Interrupts.Names.DMA2_Stream6_Interrupt,
      Priority   => System.Interrupt_Priority'Last);

SVD error for F7

In the svd directory, the file stm32_svd-spi.ads does not have the correct bit layouts for some of the registers (CR1, CR2, SR) - they seem to be for the F4 chips. On the F7 these registers have changed.
Reference: page 1110 of RM0385 for STM32F75xxx and STM32F74xxx advanced ARM-based
32-bit MCUs

need svd source for CRC unit to have workaround

We lost the work-around for the compiler bug Q207-001 in stm32_svd-crc.ads, in which a register component has an extra "with Volatile" even though that is already specified at the record level. I had manually added that to the Ada file but I don't know how to specify that in the SVD input part.

Ethernet - DHCP - MAC address - stm32f7disco

Has anybody, ever, enabled the Ethernet card for DHCP, and set its MAC address, using Ada?

Is there, possibly, somewhere, something like the echo example shown here:

http://www.st.com/resource/en/user_manual/dm00103685.pdf

If so, would it be possible to look at the code?

I can see how to do this in C, it’s easy, and fairly well documented here:

http://stm32f4-discovery.net/2015/02/library-52-ethernet-peripheral-on-stm32f4xx/

I have managed to find documentation for the register acronyms here:

https://github.com/deiKruve/openPowerLink-Ada/blob/master/stm32f-definitions/workfiles/stm32f4-o7xx-eth.ads.nopp

Unfortunately, this makes it clear that the bit (and it is only one bit, in one register) that sets the card to DHCP, and the place to put the MAC address in the initialisation code, are not there.

Any suggestions very gratefully received!

STM32F4.GPIO.Set raises assertion failure

When running this test program on an STM32F405:

with Ada.Real_Time; use Ada.Real_Time;
with STM32F4;       use STM32F4;
with STM32F4.GPIO;  use STM32F4.GPIO;
with STM32F40xxx;   use STM32F40xxx;

procedure LEDTest is
   Period     : constant Time_Span := Milliseconds (200);  -- arbitrary
   Next_Start : Time := Clock;
begin
   Configure_IO(Port => GPIO_A, Pin => Pin_8, Config =>
      (Mode         => Mode_Out,
       Output_Type  => Push_Pull,
       Speed        => Speed_2MHz,
       Resistors    => Floating));

   Set(GPIO_A, Pin_8);

   loop
      Clear(GPIO_A, Pin_8);

      Next_Start := Next_Start + Period;
      delay until Next_Start;

      Set(GPIO_A, Pin_8);

      Next_Start := Next_Start + Period;
      delay until Next_Start;
   end loop;
end LEDTest;

I get an assertion failure.

If I place a breakpoint in the system assertion handler (ravenscar-sfp-stm32f4.build/common/s-assert.adb:42), I'm able to extract the assertion message:

(gdb) c
Continuing.

Breakpoint 8, system.assertions.raise_assert_failure (msg=...) at /beuvry.a/gnatmail/sandbox/gnat-7.4.0/arm-elf-linux/recompilablerts/src/bb-runtimes/obj/ravenscar-sfp-stm32f4.build/common/s-assert.adb:42
42  in /beuvry.a/gnatmail/sandbox/gnat-7.4.0/arm-elf-linux/recompilablerts/src/bb-runtimes/obj/ravenscar-sfp-stm32f4.build/common/s-assert.adb
(gdb) print Msg
$5 = "failed postcondition from stm32f4-gpio.ads:131"

It looks like that postcondition is checking that the corresponding bit is set in the input register, but I'm not sure if the state of the output register actually affects the state of the input register.

Thoughts?

examples/filesystem compiles but crashes when run

Hi Fabien

Do you have any instructions to go with the filesystem demo? I was able to build it for the stm32f407 and load it on the discovery board, but when I run the program it stops at line 84 in semihosting.adb, at the beginning of the assembler code in Generic_SH_Call. I get this...

Program received signal SIGTRAP, Trace/breakpoint trap.
0x08003176 in semihosting.generic_sh_call (r0=1, r1=536904472) at C:\users\bob\desktop\ada_drivers_library\ARM\cortex_m\src\semihosting.adb:84

I see there's a file called disk_8_partitions.img that comes with the code, do I need to do something with that file?

I get similar results using both the _sfp and _full builds

Thanks!
Bob

Implementing UART Streams

Hi,

is it reasonable to have a stream interface for the UARTs ? That would ease the use of the UARTs and serialization. On the other hand streams are only available with the full Ravenscar RTS and it looks like SFP doesn't support streams.
Are there any thoughts about this?

Fat Filesystem return no_filesystem even when reading the MBR

I have a hard time to make the sd card Mount_Drive function to work.

The sd card is reading Ok since the snippet code to read it's size and MBR does it correctly, i.e. this snippet prints the 2GB size of my sd card.

      STM32.Board.SDCard_Device.Initialize;

      if STM32.Board.SDCard_Device.Card_Present then
         AIP.IO.Put_Line ("SD card is present");

         SD_Card_Info := STM32.Board.SDCard_Device.Get_Card_Information;

         --  Dump general info about the SD-card
         Capacity := SD_Card_Info.Card_Capacity;

         for Unit of Units loop
            if Capacity < 1000 or else Unit = 'T' then
               Put (5, 70, "SDcard size:" & Capacity'Img & " " & Unit & "B");
               exit;
            end if;

            if Capacity mod 1000 >= 500 then
               Capacity := Capacity / 1000 + 1;
            else
               Capacity := Capacity / 1000;
            end if;
         end loop;
    end if;

Then I call

Status := Mount_Drive ("sdcard", STM32.Board.SDCard_Device'Access);

Inside the Mount_Drive, the function read

Status := Read (Device, MBR);

was returning OK but actually the MBR variable was all in 0's, so I did some debugging and determine that inside the function the assignment was not execute correctly, that is the line

MBR := Tmp; so I rewrite the function a little bit

   function Read
     (Controller  : HAL.Block_Drivers.Any_Block_Driver;
      MBR         : access Master_Boot_Record)
      return File_IO.Status_Code
   is
--        Tmp  : aliased Master_Boot_Record;
      Ptr  : constant Master_Boot_Record_Access := MBR.all'Unchecked_Access;
      Data : aliased HAL.UInt8_Array (1 .. 512) with Address => Ptr.all'Address;
--        Data : aliased HAL.UInt8_Array (1 .. 512) with Address => Tmp'Address;
   begin
      --  Let's read the MBR: located in the first block
      if not Controller.Read (0, Data) then
         return File_IO.Disk_Error;
      end if;

--        MBR := Tmp;  --  This was not working at all

      if MBR.Signature /= 16#AA55# then
         return File_IO.No_MBR_Found;
      end if;

      return File_IO.OK;
   end Read;

Notice that I am using an access for MBR, so the calling function change to

Status := Read (Device, MBR'Access);

after that I can read the MBR correctly and it pass the sanity checks

     if Valid (MBR, P)
       and then Get_Type (MBR, P) in 6 | 11 .. 12

but then in function function Mount_Drive, the call to

        Status := Convert (Open (Controller => Device,
                                 LBA        => LBA (MBR, P),
                                 FS         => FAT_FS.all));

is giving me no_filesystem, because inside it when it checks the Window for 55AA,

which it's done in Initialize_FS

  if FS.Window (510 .. 511) /= (16#55#, 16#AA#) then
     Status := No_Filesystem;
     return;
  end if;

it fails since WIndow is all 0's.

I guess the following call done prior to the Open call

FAT_FS := new FAT_Filesystem;

should have read or set that Window "data".

sd_card_mbr_ok

time facility and runtime dependencies for code in the "components" dirs

Background: We want all component abstractions (the code in the "components" subdirs) to work with all runtimes. The components often require the ability to export time value declarations and execute delay statements. The ZFP runtimes do not include package Ada.Real_Time and do not support delay statements, therefore the components code cannot use them.

We can avoid the use of type Time_Span by declaring the quantities as named numbers, with a comment (or subtype of Integer) indicating what units are intended. For example:

Min_Sample_Interval : constant := 10; -- milliseconds

or

subtype Milliseconds is Natural; -- or Positive
subtype Microseconds is Natural;
...

Min_Sample_Interval : constant Milliseconds := 10;

or even derive the types so that they cannot be mixed accidentally.

Not ideal -- after all, Ada.Real_Time is included in the language to make this sort of thing unnecessary -- but acceptable.

However, that does not address the issue of delay statements.

Currently we have HAL.Time as a replacement for Ada.Real_Time:

package HAL.Time is

  type Delays is limited interface;

  type Delays_Ref is access all Delays'Class;

  procedure Delay_Microseconds (This : in out Delays;
                                Us   : Integer) is abstract;

  procedure Delay_Milliseconds (This : in out Delays;
                                Ms   : Integer) is abstract;

  procedure Delay_Seconds      (This : in out Delays;
                                S    : Integer) is abstract;

end HAL.Time;

with the intention of there being some concrete subclass implementations that do use delay statements, when a ravenscar-* runtime is in use, and other implementations that do not, when using a ZFP runtime.

Given that interface, we are using the access-to-classwide type as a discriminant in the declarations of the component abstraction types in order to make the components independent of the runtimes. For example, the Time discriminant:

type STMPE811_Device
(Port : not null I2C_Port_Ref;
I2C_Addr : I2C_Address;
Time : not null HAL.Time.Delays_Ref) is`

The problems with that approach are:

  1. It makes the client (user) code responsible for what is otherwise strictly an implementation detail. This is a very serious flaw in terms of software engineering.

  2. It "pollutes" the API with something that has nothing to do with applying the component itself.

  3. It is a rather heavy approach.

My suggestion: make HAL.Time have concrete delay routines, with the selection of the body of the package controlled by the runtime selection, something like what we do now for the last chance handlers that can use an LCD when the board supports it. Then the components code could just call the routines directly, without the client code having to do anything in that regard.

Something like this:

package HAL.Time is

  procedure Delay_Microseconds (Count : Natural);

  procedure Delay_Milliseconds (Count : Natural);

  procedure Delay_Seconds (Count : Natural);

end HAL.Time;

although we would likely declare the subtypes or derived types

subtype Milliseconds is Natural;
subtype Microseconds is Natural;
...

in that package too.

Thoughts?

STM32L4xx

Before a wheel reinvention... anyone had a stab at Ada_Drivers_Library for the L4 series. Sifting through the ST F40x -> L4 porting docs, i2c for ex: (that statement below is no joke... the svd file is quite diff).

Register configuration is very different in STM32F405/415 line and STM32F407/417 line vs STM32L4 Series. Please refer to STM32L4 Series reference manuals for details.

My thought would be minimally to make a new drivers dir driversL4 or some such.

Its a bare minimum target. 128k flash, 64k sram. Prob sfp only.

I2C w/16bit mem addr

I see a punch through issue wrt successive .DR.DR writes for a 16bit mem addr.

In stm32-i2c.adb:621 adding this wait after the end case seems to clean up the issue. Should be benign for 8bit mem addr also. I have not looked at the other 16bit handlers but I assume they will also need this treatment. Certainly read needs it. My sensor is an ST VL6180X Range and ALS sensor. It uses 16bit addresses. On the logic analyzer I do see the address being stepped on by the following read command thereby culling the DR of the LSB for the parts mem addr.

  Wait_Flag (This, Tx_Data_Register_Empty, False, Timeout, Status);

  if Status /= HAL.I2C.Ok then
 return;
  end if;
  
  --  We now need to reset and send the slave address in read mode
  This.Periph.CR1.START := True;

  Wait_Flag (This, Start_Bit, False, Timeout, Status);

Seperation of register definitions and convenience functions

Hi,

the files in the 'drivers' directory contain both register definitions and convenience functions/procedures to access them. That's fine if these files are completely written by hand.
Considering automatic (at least partially automatic) generation of register definitions from CMSIS-SVD files, it could be beneficial to separate the definitions and the convenience functions / low level drivers.

Build stuck while compiling start_rom.S

I tried building "wolf" example for stm32f429 discovery with GPS obtained from gnat-gpl-2016-arm-elf-windows-bin.exe. My build gets stuck while compiling start_rom.S

Conflict with GPIO with SDRAM & serial port

I've just started playing with the stm32f29-disco board so the architecture is a bit new to me, I was planning to use one of the serial ports to transfer some bitmaps which could then be rendered on the display. I have the serial port demo working fine along with the "draw" example which I'm using as a starting point. However I've spotted that after initialising the display device, the serial port no longer works. I think this is down to a conflict with the PB6 GPIO - this is used as the Tx pin in the serial demo but also appears to be used in setting up the SDRAM.

Given that the serial demo code has the comment "arbitrary values" about the GPIO settings assigned to the UART, I'm guessing I can configure this to use a different pair however it's not clear to me which GPIOs are free for assignment or how to figure this out despite having downloaded an assortment of documents for this board.

initialization approach for STM32.Button

Currently there is a check within the Has_Been_Pressed function to see if the hardware has been configured via procedure Initialize. If not, the function calls Initialize. That has the advantage of not initializing unless needed, but doesn't seem worth the overhead on every function call, some of which might be time-critical.

If the user has the package in the closure of context clauses, surely they intend to use the package, and so initialization is required. Currently all the code in the repo does the initialize call explicitly.

We could have the package body executable part call Initialize. That would guarantee initialization, and would only be done once. We wouldn't need to export procedure Initialize in that case. However then we have to worry about access-before-elaboration issues, and for that reason I generally recommend people not do calls to other library packages during lib unit elaboration. An explicit initialization routine gives clients full control over the order of initialization.

In addition, having an exported initialization routine would allow the user to specify (with a new parameter) the interrupt rising or falling edge choice. Currently we hardcode it to rising edge.

If we require clients to call Initialize (ie, remove the check and the call from within the function), they might forget to do it. We could address that by having a precondition on the function that would make it clear that it is required, and check that it has in fact been initialized. The precondition check would only be enabled in debug mode when it wouldn't hurt performance, and then users who forget to call Initialize will see what they missed. Just seeing the precondition in the package spec is likely sufficient to indicate what they forgot, even without debugging.

IMO the explicit initialization procedure is the best approach, with the precondition on the function.

clean up the need for package Interfaces

With the way the HAL package declares some of the unsigned types, clients need both the HAL package and the Interfaces package because the HAL package alone doesn't make the operations available.
Specifically, the HAL package declares some types as subtypes of those in Interfaces. That makes the subtype name visible via HAL, but not the operations. There is no transitivity of visibility for the operations, in other words.

Currently the HAL package does this:

type Bit is mod 2**1
with Size => 1;
...
subtype UInt8 is Interfaces.Unsigned_8;
subtype Byte is Interfaces.Unsigned_8;
...
subtype UInt16 is Interfaces.Unsigned_16;
...
subtype UInt32 is Interfaces.Unsigned_32;
...
subtype UInt64 is Interfaces.Unsigned_64;

Instead of subtypes, we should derive them, thereby inheriting the operations too. That would make package HAL sufficient by itself. Thus, for those defined as subtypes of Interfaces.*, we would just do this:

...
type UInt8 is new Interfaces.Unsigned_8;
subtype Byte is UInt8;
...
type UInt16 is new Interfaces.Unsigned_16;
...
type UInt32 is new Interfaces.Unsigned_32;
...
type UInt64 is new Interfaces.Unsigned_64;

That will make the operators available for the new types, solely with package HAL, and thus clients will not need with/use-clauses for Interfaces in their code. It will also make the shift and rotate operations available.

1:79 (style) incorrect line terminator

I have cloned the Ada_Drivers_Library and the embedded-runtimes below that.

Trying the build the blinky_f4disco project I initially found that the two with'ed projects were out of place, I fixed that but now I'm getting the line terminator issue on most of the adb and ads files in the embedded-runtimes project. Wondering if I goofed something up when I did that.

I can't fix the the terminators, neither by editing the files by hand nor commanding git to append crlf to every line (I'm on a Win 10 machine).

Oddly enough, I opened a few of the cases in gps outside of their projects - opened the source code files directly - and they got through the syntax check that way. I even added a comment to make sure it really was the same file.

This issue seems to be halting compilation. There has to be a way to override that but I can't find it.

Toolchain works using the example that was bundled with the compiler, so its not that.

Gotta be some newbie issue that I'm overlooking, but its been days!

I'd like to commit the blinky_f4disco.gpr but I won't until I see it work all the way through.

Thanks in Advance!
Bob

Compile error

The latest change to file stm32f4.ads causes a compile error. The 'with pack' needs to be there!

Display drivers for '429-Discovery

Hi,

there are two different drivers for the display on the '429-Discovery board:

  • in 'components' (ILI9341 - serial mode)
  • in 'utils' (LTDC mode)

I think some hints in the file headers or in a readme file ('what do I find in this or that file') would be helpful.

BTW, the name of the directory 'utils' is somewhat misleading. I would expect some tools (e.g. a converter for character sets or something like that...) in a directory named 'utils'. The LCD related files are clearly drivers. I must admit that I haven't found a better directory name for the rest of the files yet.

AK8963 scalings should use individual components

In components/src/motion/ak8963/ak8963.adb, procedure Get_Heading, it says

     if Status = Ok then
        Mx := Mx * ((Float (Buffer (1)) - 128.0) / 256.0 + 1.0);
        My := My * ((Float (Buffer (1)) - 128.0) / 256.0 + 1.0);
        Mz := Mz * ((Float (Buffer (1)) - 128.0) / 256.0 + 1.0);
     end if;

The Y component should use Buffer (2), the Z component should use Buffer (3).

New To this

I have been working on and off adding features to the Ada_Drivers_Library for a while now on my own, but never committed. I am new to open source and have some questions about how how the copy right, credit is done, also about derivative works and how that all works. If I were to take the STM32 library written in c and port it to Ada. But not a straight over port most of the names are changed and the data structures are completely different but the code follows very similarly. Could I legally add it to the project? I have read the STM32 ULA and I am not sure if it is ok. It talks about derivative works...

I noticed that most of the work for this project is by AdaCore employees. When adding significant amounts of code to your project how does this work when it comes to credit, because at that point you didn't create the files. (I am new to open source). So many of the files say Copyright (C) AdaCore what would my files say?

My code hasn't been tested yet but I thought that I should get some of the questions answered and get connected. (I have a few thousand lines written already.)

Which bit type declarations should be used?

Hello, we are trying to port part of the Ada_Drivers_Library to EDU-CIAA-NXP board (For more information about board you can view to issues 16 and 17 from the embedded-runtimes repository). We started out with the GPIO drivers. We analyzed driver and device code and arrived at the conclusion that it would be necessary to manually modify the ada binding files that were created by svd2ada. The vendor's svd file is messy and it's very difficult to adapt driver and device code to the hardware structures created by svd2ada from this file.

Now, looking at the ada binding files we created from the svd file with svd2ada and comparing them to the binding files for the stm32f429 in both the bsp directory from the embedded-runtimes repository and the svd directory from the Ada_Drivers_Library repository we noticed:

  • That the binding files we created all use the bit types declared in the Interfaces.LPC4337 package as can be observed here.
  • The binding files for the stm32f429_disco bsp in the embedded-runtimes repository all use the bit types declared in the Interfaces.Bit_Types package as can be observed here.
  • The binding files for the stm32f429 in the Ada_Drivers_Library all use the bit types declared in the HAL package as can be observed here.

So our question is which one should we use in each case and why?

Regards.

SDMMC_Interrupt_Handler interrupt priority

In STM32.SDMMC_Interrupt, there is

   protected type SDMMC_Interrupt_Handler
     (Interrupt_ID : Ada.Interrupts.Interrupt_ID)
   is
      pragma Interrupt_Priority (250);

I found this because I was using a different RTS, with fewer priorities, but I think that either it should be in terms of System.Interrupt_Priority'Last, or left as a discriminant for the user to decide.

zero footprint library

I don't really know where else to put this or where to look for answers but, I have experimented with porting the stm32f4 runtime library (sfp) to an stm32f103 device. By changing various stack sizes I was able to fit it all in the 20KB of RAM. Considering even smaller controllers it seems reasonable to go with the ZFP runtime systems. But i was not able to find any resources on how to implement interrupts with a ZFP rts. Can anyone help me out tackling this or even better provide me sources for study?
Note i've created my ZFP rts from the bb-runtime sources from libreada

Example: b__balls_demo.adb linking error, liblto_plugin.so missing

I'm missing a configuration step somewhere.

The demo task b__balls_demo.adb complies, but, at link time gives this error:

arm-eabi-gnatbind balls_demo.ali
arm-eabi-gcc -c b__balls_demo.adb
arm-eabi-gcc fractals_demo.o -Wl,--defsym=__stack_size=32768 -Wl,--gc-sections -Wl,--print-memory-usage -o fractals_demo
arm-eabi-gcc: fatal error: -fuse-linker-plugin, but liblto_plugin.so not found

A fix for this is documented here:

https://www.lpcware.com/content/forum/libltopluginso-not-found

However, this doesn't work. It looks as if something is missing from config.gpr, pointing to the library.

I'm using the example file stm32f7disco_examples.gpr so my build line is:

gprbuild stm32f7disco_examples.gpr

I'm using:

Linux host 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:06:14 UTC 2016 i686 i686 i686 GNU/Linux

GPRBUILD GPL 2016 (20160515) (i686-pc-linux-gnu)

arm-eabi-gcc (GCC) 4.9.4 20160426 (for GNAT GPL 2016 20160515)

I have tried including the library specifically:

package Compiler is
case Build is
when "Production" =>
for Default_Switches ("Ada") use
("-g", "-O3", "-gnatp", "-gnatn", "-l/media/sf_Ada/arm-elf-linux/adagpl-2016/gnatgpl/gnat-gpl-2016-arm-elf-linux-bin/lib/bfd-plugins/liblto_plugin.so");

But this doesn't help.

Tasks

Hello. What is the point to use tasks on every driver demos?

Installation issue?

When I try to build the examples and open the project by double-clicking the gpr file, I get 'Could not locate exec gnatls'. Also the project is not loaded and I get the 'default' project instead.

Opening the gpr file from a running GPS does open a project and allows me to build it as well, but I cannot access the Ada runtime library from the help menu. I get empty files instead!

To me this is strange because I do not see this with the Certyflie project (cf_ada_spark.gpr).

I am using the crazyflie virtual machine (Ubuntu 14.0) and the Adacore gnat-gpl-2016-arm-elf-linux compiler. Since I have a STM32f429 discovery board, I tested examples like draw_stm32f429disco.gpr and blinky_f429disco.gpr
Note that from the terminal, the command 'arm-eabi-gnatls' does work.

Any help is appreciated :-)

Ethernet - Make with Ada

I wanted to ask some questions, and chat about the Ethernet driver, in particular - I'm soon going to be working on the 'Make with Ada' competition ( http://www.makewithada.org ), and I want to get my hands on as much of the relevant documentation as possible.

I've ordered the STM32F746G-DISCO kit ( 32F746GDISCOVERY - http://www.mouser.com/ds/2/389/32f746gdiscovery-953766.pdf ) with the STM32F746NGH6 microcontroller. So it will be the stm32f7_discovery that I'll be specifically interested in - but I'm hoping that that will mainly be for the display, which is less important to my project than the ethernet port. [I may be interested in the USB port too, but as a connection to a second Ethernet device]

So I've put my questions into the Wiki here - hoping that they can turn into answers that'll be useful documentation for anybody else.

I'm hoping I've not done the wrong thing - but I'd love some feedback or suggestions from anybody here.

If anybody here is interested in what I'm trying to do, my project is a subset of the larger project that I've started to describe at the top level here:

https://github.com/fustbariclation/Ada-Transport-Level-Security-TLS-module-

Adding support for STM32F303

Hi,
I'm interested in adding support for the STM32F303 line of microcontrollers. I would appreciate any guidance on where to start.

What I'm particularly confused about is the relation between Ada_Drivers_Library and AdaCore/embedded-runtimes. To support the line of MCUs, would both projects need to be updated?

Problems with SPARK_Mode

I see a lot of problems using SPARK GPL 2015. For example, this (concocted from stm32f4-adc.ads and stm32f42xxx.ads) occurs frequently (there are others).

with System.Storage_Elements;
use System;
use type System.Storage_Elements.Storage_Offset;

package Access_To_Volatile with Spark_Mode is

   type Analog_To_Digital_Converter is limited record
      Dummy : Integer;
   end record
   with Volatile;

   type Analog_Input_Channel is mod 19;

   type ADC_Point is record
      ADC     : access Analog_To_Digital_Converter;
      Channel : Analog_Input_Channel;
   end record;

   VBat_Channel : constant Analog_Input_Channel := 18;

   Peripheral_Base : constant Address := System'To_Address (16#4000_0000#);
   APB2_Peripheral_Base : constant Address := Peripheral_Base + 16#0001_0000#;
   ADC1_Base   : constant Address := APB2_Peripheral_Base + 16#2000#;

   ADC_1 : aliased Analog_To_Digital_Converter
     with Volatile, Address => ADC1_Base;
   VBat : constant ADC_Point :=
     (ADC_1'Access, Channel => VBat_Channel);

end Access_To_Volatile;

results in

$ gnatprove -P sparking.gpr
Phase 1 of 2: generation of Global contracts ...
access_to_volatile.ads:28:07: volatile object cannot appear in this context (SPARK RM 7.1.3(13))
gnatprove: error during generation of Global contracts

I see you have some Codepeer constructs in bodies; is it that you don’t use SPARK, or is it that the GPL 2015 version has problems in this area? (I note that the error message is wrong, there is no (13) in the SPARK RM released with GPL 2015!)

Short Feedback

Hi all, I want to share my first experiences with the library.
For my project I only use the Peripheral drivers and thus only included ./ARM and ./HAL.
So far I have used the following modules: GPIO, I2C, UART, SPI.

First of all, thank you for the great work the library works most of the time as expected!

However, I noticed some issues and/or have some suggestions for improvement.
Maybe some of these issues are already on your todo list or you have a special reason for it, but since there is no public list I will mention everything that came to my mind.

GPIO

  1. No in out paramters if it is not necessary
    In procedure Set (Point : in out GPIO_Point) from HAL-gpio.ads. If Point is in out then one has to declare a variable before calling the procedure and cannot use a constant value or return value.
  2. Are limitted types necessary for Peripheral descriptors?
    I would like to write a mapping function that maps from my own device ID type e.g. (Baro, IMU) to the corresponding SPI Peripheral. However when I try to return a constant Peripheral object such as STM32.Device.SPI_1 the compiler correctly complains that I cannot copy a limited type. It would be nice to have a type that identifies the peripheral without representing it by the actual address as the limited type does.
  3. Ambigious enum values
    I noticed that when I want to access a GPIO Port A for the Set function and type STM32.Device.GPIO, GPS suggests auto-completion for GPIO_PORT_A and GPIO_A and it is not easy to see the difference between them.

General Naming Conventions

The library will only be written once but used by many people who will read the source code and have to understand it. Thus a primary goal for naming should be readability and consistency. Even names become longer, they will be auto-completed by the IDE. I think the naming is quite good but I have some additional suggestions.

  1. Only common abbreviations:
    When I first saw CRC_Poly I though of CRC_Policy. Of course polynom makes much more sense but I would avoid abbreviations if they are not very very common or could be ambiguous. Depending on one's background different associations could come to mind.
  2. Types could have a postfix _Type
    I have seen this often in examples and use it myself. Advantages would be
    • fast identification of type identifiers
    • singleton naming for parameters: Configure : Configure_Type, no need to come up with a different name/abbreviation
    • developers might be already used to it
  3. Consistent parameter names
    I noticed that the I2C and SPI modules have different parameter names for the configure method. I2C.configure requires a Handle while SPI.configure requires a Port. It would be nice if the parameter names of equivalent subprograms are consistent.
  4. Consistent prefix
    Within SPI module almost all types start with the prefix SPI_, except for Internal_SPI_Port. Maybe it should be renamed to SPI_Internal_Port for consistency.
  5. No mixing of similar words such as send and transmit
    SPI has send and transmit as public subprograms and it is not easy to see which one to use. I2C has only transmit functions, so maybe it would be possible to remove the plain send procedure from the public part in the SPI module.
  6. Documentation of naming conventions
    Whatever the naming rules are, they should be documented somewhere (e.g. in the git wiki), so that new users can understand the reason behind the names and getting used to the library. This is beneficial
    1. for contributors to be able to follow the rules
    2. for users to understand code better/faster

USART

  1. Unified Bus procedures
    I really like the Configure(Port, Configuration) methods.
    Right now USART does not use a single configuration procedure like SPI/I2C do but has several. I think it would be more consistent if every Bus is configured with one configure procedure.

    Every Bus (SPI, I2C, UART) should have a transmit, receive and transfer/transceive method.The USART transmit procedure does not check the TXE flag and the receive method does not check RXNE or timeout as SPI/I2C do. Again I think it would be consistent if every transmit/receive procedure behaves the same.

  2. Clarify the unit of parameters
    In Set_Baud_Rate the parameter Baud_Rates is of type word. It is not clear what the unit of this type is. Maybe Baud_Rates should be renamed to Baud_Rate_In_Hz

  3. Required order of call
    I noticed that Set_Baud_Rate reads CR1.OVER8 so a user should call Set_Oversampling_Mode beforehand.
    It is not clear from the interface that Set_Baud_Rate reads this register.
    This issue could also be avoided by a single configuration call.

SPARK

I also want to use SPARK but the library is not in SPARK which I guess is not avoidable. However is it possible to shift the non SPARK parts in the body to be able to declare the spec with SPARK mode? Are there any plans or recommendation how to use the library in a SPARK project?

I hope this feedback is somehow useful for you. As I said it is just everything that came to my mind. I really like the library so far and it is very useful. So thank you for all the effort!

Kind regards,
Emanuel

Improve user documentation

Hello, is it possible to provide some documentation for the library? I tried to launch an SPI on stm32f4-discovery board, but I wasn't succeed. And I don't know, how the library should be used. I saw several examples, but they are not enough for a beginner in Ada to start using this library.

STM32F7 : Quad-SPI byte access to CCR

Hello,

First of all I am kind of new with Ada so if my issue is not a real issue but a miss-use of your SVD files, sorry for that.

I am trying to use the QUAD-SPI of my STM32F767 using your STM32F7 SVD files.

I currently use directly the "QUADSPI_Periph" object from the file Ada_Drivers_Library/arch/ARM/STM32/svd/stm32f7x9/stm32_svd-quadspi.ads.

From the STM32F7 Reference Manual, the Quad-SPI communication starts as soon as we wrote into the QuadSPI_CCR.INSTRUCTION register (which has a size of 8 bits).

For example, I am using your object like this :

STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.DDRM :=  ...   ;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.DHHC := ...   ;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.SIOO := ...   ;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.DMODE :=  ...   ;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.DCYC := ...   ;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.ADMODE :=  ...   ;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.IMODE := ..;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.FMODE := ... ;
STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.ABMODE := ...  ;

Once I setup my communication frame format, trigger the communication by writing into INSTRUCTION

STM32_SVD.QUADSPI.QUADSPI_Periph.CCR.INSTRUCTION :=  ... ;

The problem is that the CCR register is defined as a "Volatile_Full_Access" like this :

type CCR_Register is record
      --  Instruction
      INSTRUCTION    : CCR_INSTRUCTION_Field := 16#0#;
      --  Instruction mode
      IMODE          : CCR_IMODE_Field := 16#0#;
      --  Address mode
      ADMODE         : CCR_ADMODE_Field := 16#0#;
      --  Address size
      ADSIZE         : CCR_ADSIZE_Field := 16#0#;
      --  Alternate bytes mode
      ABMODE         : CCR_ABMODE_Field := 16#0#;
      --  Alternate bytes size
      ABSIZE         : CCR_ABSIZE_Field := 16#0#;
      --  Number of dummy cycles
      DCYC           : CCR_DCYC_Field := 16#0#;
      --  unspecified
      Reserved_23_23 : HAL.Bit := 16#0#;
      --  Data mode
      DMODE          : CCR_DMODE_Field := 16#0#;
      --  Functional mode
      FMODE          : CCR_FMODE_Field := 16#0#;
      --  Send instruction only once mode
      SIOO           : Boolean := False;
      --  unspecified
      Reserved_29_29 : HAL.Bit := 16#0#;
      --  DDR hold half cycle
      DHHC           : Boolean := False;
      --  Double data rate mode
      DDRM           : Boolean := False;
   end record
     with Volatile_Full_Access, Size => 32,
Bit_Order => 
System.Low_Order_First;

With this pragma, I suspect that my instructions above, when configuring the CCR modes independently, wrote several times inside CCR.INSTRUCTION and then, the Quad-SPI peripheral tries to start several communications.

I currently don't have a solution to propose (exepecting creating manually several pointers to the right locations... but I would prefer a way to fix the SVD descriptions, these descriptions are so helpful !)

So, let me know what do you think.

Best regards,
FG

Missing config.gpr file

Hi,

The serial-ports f429disco example (Ada_Drivers_Library/examples/serial_ports/serial_ports_f429disco.gpr) gpr file includes a file config.gpr which should be stored in the main library folder, but it's not there.
It seems to be removed in e3a3ceb.
Project doesn't compile. I'm not sure if this is an issue of the example gpr file or sth else.

Kind regards,
zdun8

Stm32f103

Is it possible to use ada with 103?
How can i get runtime for it?

stm32-eth.ads - design - expected calling sequences

Most of the internal buffer variables in stm32-eth.adb are hidden. So I've been wondering what the design intention has been for reading and writing from and to the ethernet card.

For example, in the demo, there is the line:

STM32.Eth.Wait_Packet;

When this completes, it means that a packet has arrived. It is in the buffer Last_Rx, but this is hidden.

If you wanted to get the buffer, what would be the correct method here? If the buffer was visible, then it could be:

STM32.Eth.Wait_Packet.Last_Rx;

But, obviously, that is not the expected method!

Similarly, you define:

Tx_Desc_Type

In STM32.Eth - but there is no procedure linked to it. What method would you be expecting the user to use to send a packet?

I know it's also possible to set it up to call a task on interrupt - if this is the preferred method, is the buffer(packet) passed to the task - or is it passed a pointer to the common buffer?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.