pico_examples_2.0.0_cd57c29a/multicore/src/led_control.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
--
--  Copyright (C) 2022 Jeremy Grosser <jeremy@synack.me>
--
--  SPDX-License-Identifier: BSD-3-Clause
--
with System.Storage_Elements; use System.Storage_Elements;
with RP2040_SVD.PPB;
with RP.Multicore.FIFO;
with RP.Multicore;
with RP.Device;
with RP.Timer;
with RP.Clock;
with RP.GPIO;
with Pico;
with HAL;

package body LED_Control is

   procedure Initialize is
   begin
      RP.Clock.Initialize (Pico.XOSC_Frequency);
      Pico.LED.Configure (RP.GPIO.Output);
   end Initialize;

   procedure Start is
      --  By default, both cores have a 4 KB stack in the non-striped address space
      --  Core 0's stack is in SCRATCH_Y, SRAM4_BASE 0x20040000
      --  Core 1's stack is in SCRATCH_X, SRAM5_BASE 0x20041000
      --  See the linker script, memmap_default.ld, for more information
      --
      --  Both cores can access the entire address space, so this is just
      --  convention, not a requirement. Put the stack wherever you want.
      VTOR : constant System.Address := To_Address (Integer_Address (RP2040_SVD.PPB.PPB_Periph.VTOR.TBLOFF));
      Stack_One_Top : HAL.UInt32
         with Import, External_Name => "__StackOneTop";
   begin
      RP.Multicore.Launch_Core1
         (Trap_Vector   => VTOR,                  --  Use the same vector table as Core 0
          Stack_Pointer => Stack_One_Top'Address, --  Initial stack pointer (SP)
          Entry_Point   => Run_Core1'Address);    --  Initial program counter (PC)
      Run_Core0;
   end Start;

   procedure Run_Core0 is
      use RP.Timer;
      T : Time := Clock;
   begin
      RP.Device.Timer.Enable;
      loop
         T := T + Milliseconds (1_000);
         RP.Device.Timer.Delay_Until (T);
         RP.Multicore.FIFO.Push_Blocking (3);
      end loop;
   end Run_Core0;

   procedure Run_Core1 is
      N : Natural with Volatile;
   begin
      loop
         Pico.LED.Toggle;
         N := Natural (RP.Multicore.FIFO.Pop_Blocking);
      end loop;
   end Run_Core1;

end LED_Control;