hmc5883_1.0.0_acd90287/examples/hmc5883_put/main.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
--  SPDX-FileCopyrightText: 2024 Max Reznik <reznikmm@gmail.com>
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
----------------------------------------------------------------

with Ada.Real_Time;
with Ada.Text_IO;

with Ravenscar_Time;

with STM32.Board;
with STM32.Device;
with STM32.Setup;

with HAL.I2C;

with HMC5883.Sensor;

procedure Main is
   use type Ada.Real_Time.Time;

   package HMC5883_I2C is new HMC5883.Sensor
     (I2C_Port => STM32.Device.I2C_1'Access);

   Ok     : Boolean := False;
   Vector : array (1 .. 16) of HMC5883.Magnetic_Field_Vector;
   Prev   : Ada.Real_Time.Time;
begin
   STM32.Board.Initialize_LEDs;
   STM32.Setup.Setup_I2C_Master
     (Port        => STM32.Device.I2C_1,
      SDA         => STM32.Device.PB9,
      SCL         => STM32.Device.PB8,
      SDA_AF      => STM32.Device.GPIO_AF_I2C1_4,
      SCL_AF      => STM32.Device.GPIO_AF_I2C1_4,
      Clock_Speed => 400_000);

   declare
      Status : HAL.I2C.I2C_Status;
   begin
      --  Workaround for STM32 I2C driver bug
      STM32.Device.I2C_1.Master_Transmit
        (Addr    => 16#3C#,
         Data    => (1 => 16#0A#),  --  Chip ID for HMC5883L
         Status  => Status);
   end;

   --  Look for HMC5883L chip
   if not HMC5883_I2C.Check_Chip_Id then
      Ada.Text_IO.Put_Line ("HMC5883L not found.");
      raise Program_Error;
   end if;

   --  Set HMC5883L up
   HMC5883_I2C.Configure
     ((Average => 1,     --  no average
       ODR     => 15.0,  --  doesn't matter in single measurement mode
       Gain    => 1090,  --  default gain
       Bias    => HMC5883.None),
      Ok);
   pragma Assert (Ok);

   loop
      Prev := Ada.Real_Time.Clock;
      STM32.Board.Toggle (STM32.Board.D1_LED);

      for J in Vector'Range loop

         --  trigger single measurement
         HMC5883_I2C.Set_Mode (HMC5883.Single_Measurement, Ok);
         pragma Assert (Ok);

         Ravenscar_Time.Delays.Delay_Milliseconds (1000/150);  --  150 Hz

         --  Read scaled values from the sensor
         HMC5883_I2C.Read_Measurement (Vector (J), Ok);
         pragma Assert (Ok);
      end loop;

      --  Printing...
      declare
         Now  : constant Ada.Real_Time.Time := Ada.Real_Time.Clock;
         Diff : constant Duration := Ada.Real_Time.To_Duration (Now - Prev);
      begin
         Ada.Text_IO.New_Line;
         Ada.Text_IO.New_Line;
         Ada.Text_IO.Put_Line ("Time=" & Diff'Image & "/16");

         for Value of Vector loop
            declare
               X : constant String :=
                 (if Value.X.Is_Overflow then "Overflow"
                  else Value.X.Value'Image);

               Y : constant String :=
                 (if Value.Y.Is_Overflow then "Overflow"
                  else Value.Y.Value'Image);

               Z : constant String :=
                 (if Value.Z.Is_Overflow then "Overflow"
                  else Value.Z.Value'Image);
            begin
               Ada.Text_IO.Put_Line ("X=" & X & " Y=" & Y & " Z=" & Z);
            end;
         end loop;

         Ada.Text_IO.Put_Line ("Sleeping 2s...");
         Ravenscar_Time.Delays.Delay_Seconds (2);
      end;
   end loop;
end Main;