From 93cae0e6ce53d133d2dbc9767e24f39a12841e92 Mon Sep 17 00:00:00 2001 From: Mason Ticehurst Date: Fri, 8 Mar 2024 20:42:38 -0500 Subject: [PATCH] More user-button interrupt handler testing --- eRINA_STM32F7/src/rina/board.adb | 73 +++++++++++++++++++++++++++++--- eRINA_STM32F7/src/rina/board.ads | 27 ++++++++++-- 2 files changed, 91 insertions(+), 9 deletions(-) diff --git a/eRINA_STM32F7/src/rina/board.adb b/eRINA_STM32F7/src/rina/board.adb index 0376d16..0143555 100644 --- a/eRINA_STM32F7/src/rina/board.adb +++ b/eRINA_STM32F7/src/rina/board.adb @@ -1,11 +1,74 @@ with Debug; +with STM32.Board; use STM32.Board; +with STM32.Device; use STM32.Device; +with STM32.GPIO; use STM32.GPIO; +with STM32.EXTI; use STM32.EXTI; package body Board is + + Button_High : Boolean := True; + + Debounce_Time : constant Time_Span := Milliseconds (250); + + EXTI_Line : constant External_Line_Number := + User_Button_Point.Interrupt_Line_Number; + + Initialization_Complete : Boolean := False; + protected body Button_Handler is - procedure Pressed is + procedure Interrupt is + begin + Clear_External_Interrupt (EXTI_Line); + Debug.Print (Debug.Info, "Button pressed!"); + if (Button_High and then User_Button_Point.Set) + or else (not Button_High and then not User_Button_Point.Set) + then + if Clock - Start_Time > Debounce_Time then + Pressed := True; + end if; + end if; + end Interrupt; + + function Current_State return Boolean is + begin + return Pressed; + end Current_State; + + procedure Clear_State is begin - STM32.Board.All_LEDs_On; - Debug.Print(Debug.Info, "Button pressed!"); - end Pressed; + if Pressed then + Start_Time := Clock; + Pressed := False; + end if; + end Clear_State; end Button_Handler; -end Board; \ No newline at end of file + + procedure Initialize (Use_Rising_Edge : Boolean := True) is + Edge : constant External_Triggers := + (if Use_Rising_Edge then Interrupt_Rising_Edge + else Interrupt_Falling_Edge); + begin + Enable_Clock (User_Button_Point); + + User_Button_Point.Configure_IO + ((Mode => Mode_In, + Resistors => (if Use_Rising_Edge then Pull_Down else Pull_Up))); + + -- Connect the button's pin to the External Interrupt Handler + User_Button_Point.Configure_Trigger (Edge, 0); + + Button_High := Use_Rising_Edge; + Initialization_Complete := True; + end Initialize; + + function Has_Been_Pressed return Boolean is + State : Boolean; + begin + State := Button_Handler.Current_State; + Button_Handler.Clear_State; + + return State; + end Has_Been_Pressed; + + function Initialized return Boolean is (Initialization_Complete); +end Board; diff --git a/eRINA_STM32F7/src/rina/board.ads b/eRINA_STM32F7/src/rina/board.ads index e69d1ef..d186d6d 100644 --- a/eRINA_STM32F7/src/rina/board.ads +++ b/eRINA_STM32F7/src/rina/board.ads @@ -1,9 +1,28 @@ with STM32; with STM32.Board; +with Ada.Real_Time; use Ada.Real_Time; package Board is - protected type Button_Handler is - procedure Pressed; - pragma Attach_Handler (Pressed, STM32.Board.User_Button_Interrupt); + + procedure Initialize (Use_Rising_Edge : Boolean := True) with + Pre => not Initialized, Post => Initialized; + + function Has_Been_Pressed return Boolean with + Pre => Initialized; + -- Returns whether the user button has been pressed since the last time + -- this subprogram was called. + + function Initialized return Boolean; + + protected Button_Handler is + pragma Interrupt_Priority; + function Current_State return Boolean; + procedure Clear_State; + private + procedure Interrupt; + pragma Attach_Handler (Interrupt, STM32.Board.User_Button_Interrupt); + + Pressed : Boolean := False; + Start_Time : Time := Clock; end Button_Handler; -end Board; \ No newline at end of file +end Board;