Skip to content

Commit

Permalink
Merge pull request #1165 from gusthoff/content/ada_idioms/review/edit…
Browse files Browse the repository at this point in the history
…orial/code_examples/20241227

Editorial change: restricting code examples to 80-column limit
  • Loading branch information
gusthoff authored Jan 5, 2025
2 parents 1bae604 + 9c7e007 commit d399ae5
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,12 @@ Here is the client view of the ADT for the interrupt-driven implementation:
-- Serial_IO.Device.

overriding
procedure Put (This : in out Serial_Port; Data : HAL.UInt8) with Inline;
procedure Put (This : in out Serial_Port; Data : HAL.UInt8)
with Inline;

overriding
procedure Get (This : in out Serial_Port; Data : out HAL.UInt8) with Inline;
procedure Get (This : in out Serial_Port; Data : out HAL.UInt8)
with Inline;

private
...
Expand Down Expand Up @@ -770,14 +772,16 @@ Next, the interrupt-driven extension.
-- declared here, as operations inherited from Serial_IO.Device

overriding
procedure Put (This : in out Serial_Port; Data : HAL.UInt8) with Inline;
procedure Put (This : in out Serial_Port; Data : HAL.UInt8)
with Inline;
-- Non-blocking, ie the caller can return before the Data goes out,
-- but does block until the underlying UART is not doing any other
-- transmitting. Does no polling. Will not interfere with any other I/O
-- on the same device.

overriding
procedure Get (This : in out Serial_Port; Data : out HAL.UInt8) with Inline;
procedure Get (This : in out Serial_Port; Data : out HAL.UInt8)
with Inline;
-- Blocks the caller until a character is available! Does no polling.
-- Will not interfere with any other I/O on the same device.

Expand Down Expand Up @@ -877,7 +881,8 @@ And the package body:
Get (Serial_IO.Device (Port.all), Incoming);

Await_Reception_Complete : loop
exit when not Port.Transceiver.Status (Read_Data_Register_Not_Empty);
exit when not
Port.Transceiver.Status (Read_Data_Register_Not_Empty);
end loop Await_Reception_Complete;
Port.Transceiver.Disable_Interrupts (Received_Data_Not_Empty);
Port.Transceiver.Clear_Status (Read_Data_Register_Not_Empty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,8 +529,10 @@ various PID gain parameters, that are not shown.
task body Servo is
Next_Release : Time;
Target_Angle : Float;
Current_Angle : Float := 0.0; -- zero for call to Steering_Computer.Enable
Steering_Power : Float := 0.0; -- zero for call to Steering_Computer.Enable
Current_Angle : Float := 0.0;
-- zero for call to Steering_Computer.Enable
Steering_Power : Float := 0.0;
-- zero for call to Steering_Computer.Enable
Motor_Power : NXT.Motors.Power_Level;
Rotation_Direction : NXT.Motors.Directions;
Steering_Offset : Float;
Expand All @@ -545,16 +547,20 @@ various PID gain parameters, that are not shown.
begin
Global_Initialization.Critical_Instant.Wait (Epoch => Next_Release);
Initialize_Steering_Mechanism (Steering_Offset);
Steering_Computer.Enable (Process_Variable => Current_Angle, Control_Variable => Steering_Power);
Steering_Computer.Enable (Process_Variable => Current_Angle,
Control_Variable => Steering_Power);
loop
Current_Angle := Current_Motor_Angle (Steering_Motor) - Steering_Offset;
Current_Angle := Current_Motor_Angle (Steering_Motor) -
Steering_Offset;
Target_Angle := Float (Remote_Control.Requested_Steering_Angle);
Limit (Target_Angle, -Steering_Offset, +Steering_Offset);
Steering_Computer.Compute_Output
(Process_Variable => Current_Angle,
Setpoint => Target_Angle,
Control_Variable => Steering_Power);
Convert_To_Motor_Values (Steering_Power, Motor_Power, Rotation_Direction);
Convert_To_Motor_Values (Steering_Power,
Motor_Power,
Rotation_Direction);
Steering_Motor.Engage (Rotation_Direction, Motor_Power);

Next_Release := Next_Release + Period;
Expand Down Expand Up @@ -601,7 +607,8 @@ representing the current instance object, thus any object of the type.

package Bounded_Stacks is

subtype Element is Integer; -- arbitrary substitute for generic formal type
subtype Element is Integer;
-- arbitrary substitute for generic formal type

type Stack (Capacity : Positive) is limited private with
Default_Initial_Condition => Empty (Stack);
Expand Down Expand Up @@ -849,8 +856,10 @@ the idiom solution.
-- counter, i.e., RDTSC, which returns a 64-bit count of the number of
-- system clock cycles since power-up.

function Sample (This : not null access Cycle_Counter) return Cycle_Count is
(Read_TimeStamp_Counter); -- The formal parameter This is not referenced
function Sample (This : not null access Cycle_Counter)
return Cycle_Count is
(Read_TimeStamp_Counter);
-- The formal parameter This is not referenced

end Timestamp;

Expand Down Expand Up @@ -979,12 +988,17 @@ additional primitives for working with samples.
function Counter return not null Timestamp_Sampler_Reference with Inline;
-- returns an access value designating the single instance

procedure Take_First_Sample (This : not null access Timestamp_Sampler) with Inline;
procedure Take_Second_Sample (This : not null access Timestamp_Sampler) with Inline;
procedure Take_First_Sample (This : not null access Timestamp_Sampler)
with Inline;
procedure Take_Second_Sample (This : not null access Timestamp_Sampler)
with Inline;

function First_Sample (This : not null access Timestamp_Sampler) return Cycle_Count;
function Second_Sample (This : not null access Timestamp_Sampler) return Cycle_Count;
function Elapsed (This : not null access Timestamp_Sampler) return Cycle_Count;
function First_Sample (This : not null access Timestamp_Sampler)
return Cycle_Count;
function Second_Sample (This : not null access Timestamp_Sampler)
return Cycle_Count;
function Elapsed (This : not null access Timestamp_Sampler)
return Cycle_Count;

private

Expand Down Expand Up @@ -1033,21 +1047,24 @@ additional primitives for working with samples.
-- First_Sample --
------------------

function First_Sample (This : not null access Timestamp_Sampler) return Cycle_Count is
function First_Sample (This : not null access Timestamp_Sampler)
return Cycle_Count is
(This.First);

-------------------
-- Second_Sample --
-------------------

function Second_Sample (This : not null access Timestamp_Sampler) return Cycle_Count is
function Second_Sample (This : not null access Timestamp_Sampler)
return Cycle_Count is
(This.Second);

-------------
-- Elapsed --
-------------

function Elapsed (This : not null access Timestamp_Sampler) return Cycle_Count is
function Elapsed (This : not null access Timestamp_Sampler)
return Cycle_Count is
(This.Second - This.First + 1);

end Timestamp.Sampling;
Expand Down Expand Up @@ -1103,7 +1120,9 @@ removing it:

.. code-block:: ada

function Sample (This : not null access Cycle_Counter'Class) return Cycle_Count with Inline;
function Sample (This : not null access Cycle_Counter'Class)
return Cycle_Count
with Inline;

In the version above, the formal parameter type is now (anonymous) access to
:ada:`Cycle_Counter'Class`, i.e., class-wide, so in this version :ada:`Sample`
Expand Down Expand Up @@ -1142,7 +1161,8 @@ frequency.

procedure Demo_Sampling_Cycle_Counter is

Delay_Interval : constant Duration := 1.0; -- arbitrary, change if desired
Delay_Interval : constant Duration := 1.0;
-- arbitrary, change if desired
Elapsed_Time : Duration;

GHz : constant := 1_000_000_000;
Expand All @@ -1154,7 +1174,8 @@ frequency.

use type Timestamp.Cycle_Count; -- for "<"
begin
Put_Line ("Using" & Machine_Cycles_Per_Second'Image & " Hertz for system clock");
Put_Line ("Using" & Machine_Cycles_Per_Second'Image
& " Hertz for system clock");

Put_Line ("Delaying for" & Delay_Interval'Image & " second(s) ...");

Expand Down
48 changes: 34 additions & 14 deletions content/courses/ada-idioms/chapters/interrupt_handling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -198,18 +198,30 @@ them so that we can focus on the interrupt handler itself.
procedure DMA_IRQ_Handler is
use STM32.Board; -- for the audio DMA
begin
if Status (Audio_DMA, Audio_DMA_Out_Stream, DMA.Half_Transfer_Complete_Indicated) then
if Status (Audio_DMA,
Audio_DMA_Out_Stream,
DMA.Half_Transfer_Complete_Indicated)
then
-- The middle of the double-buffer array has been reached by the
-- DMA transfer, therefore the "upper half buffer" is empty.
Fill_Logical_Buffer (Outgoing_PCM_Samples, Starting_Index => Upper_Buffer_Start);
Clear_Status (Audio_DMA, Audio_DMA_Out_Stream, DMA.Half_Transfer_Complete_Indicated);
Fill_Logical_Buffer (Outgoing_PCM_Samples,
Starting_Index => Upper_Buffer_Start);
Clear_Status (Audio_DMA,
Audio_DMA_Out_Stream,
DMA.Half_Transfer_Complete_Indicated);
end if;

if Status (Audio_DMA, Audio_DMA_Out_Stream, DMA.Transfer_Complete_Indicated) then
if Status (Audio_DMA,
Audio_DMA_Out_Stream,
DMA.Transfer_Complete_Indicated)
then
-- The bottom of the double-buffer array has been reached by the
-- DMA transfer, therefore the "lower half buffer" is empty.
Fill_Logical_Buffer (Outgoing_PCM_Samples, Starting_Index => Lower_Buffer_Start);
Clear_Status (Audio_DMA, Audio_DMA_Out_Stream, DMA.Transfer_Complete_Indicated);
Fill_Logical_Buffer (Outgoing_PCM_Samples,
Starting_Index => Lower_Buffer_Start);
Clear_Status (Audio_DMA,
Audio_DMA_Out_Stream,
DMA.Transfer_Complete_Indicated);
end if;
end DMA_IRQ_Handler;

Expand Down Expand Up @@ -335,10 +347,12 @@ task notification, here is the full interrupt handler PO type declaration
type Serial_Port ... is new Serial_IO.Device with private;

overriding
procedure Put (This : in out Serial_Port; Data : HAL.UInt8) with Inline;
procedure Put (This : in out Serial_Port; Data : HAL.UInt8)
with Inline;

overriding
procedure Get (This : in out Serial_Port; Data : out HAL.UInt8) with Inline;
procedure Get (This : in out Serial_Port; Data : out HAL.UInt8)
with Inline;

private

Expand Down Expand Up @@ -433,9 +447,11 @@ ready for them, via the entry barriers controlled by the interrupt handler.
if Port.Transceiver.Status (Read_Data_Register_Not_Empty) and then
Port.Transceiver.Interrupt_Enabled (Received_Data_Not_Empty)
then -- handle reception
Get (Serial_IO.Device (Port.all), Incoming); -- call the Serial_IO.Device version!
Get (Serial_IO.Device (Port.all), Incoming);
-- call the Serial_IO.Device version!
Await_Reception_Complete : loop
exit when not Port.Transceiver.Status (Read_Data_Register_Not_Empty);
exit when not
Port.Transceiver.Status (Read_Data_Register_Not_Empty);
end loop Await_Reception_Complete;
Port.Transceiver.Disable_Interrupts (Received_Data_Not_Empty);
Port.Transceiver.Clear_Status (Read_Data_Register_Not_Empty);
Expand All @@ -446,7 +462,8 @@ ready for them, via the entry barriers controlled by the interrupt handler.
if Port.Transceiver.Status (Transmission_Complete_Indicated) and then
Port.Transceiver.Interrupt_Enabled (Transmission_Complete)
then -- handle transmission
Put (Serial_IO.Device (Port.all), Outgoing); -- call the Serial_IO.Device version!
Put (Serial_IO.Device (Port.all), Outgoing);
-- call the Serial_IO.Device version!
Port.Transceiver.Disable_Interrupts (Transmission_Complete);
Port.Transceiver.Clear_Status (Transmission_Complete_Indicated);
Transmission_Pending := False;
Expand Down Expand Up @@ -725,7 +742,8 @@ procedure. The routine for transmitting is similar.
.. code-block:: ada

procedure Handle_Reception is
Received_Char : constant Character := Character'Val (Current_Input (Device.Transceiver.all));
Received_Char : constant Character :=
Character'Val (Current_Input (Device.Transceiver.all));
begin
if Received_Char /= Incoming_Msg.Terminator then
Incoming_Msg.Append (Received_Char);
Expand All @@ -735,9 +753,11 @@ procedure. The routine for transmitting is similar.
then -- reception complete
loop
-- wait for device to clear the status
exit when not Status (Device.Transceiver.all, Read_Data_Register_Not_Empty);
exit when not Status (Device.Transceiver.all,
Read_Data_Register_Not_Empty);
end loop;
Disable_Interrupts (Device.Transceiver.all, Source => Received_Data_Not_Empty);
Disable_Interrupts (Device.Transceiver.all,
Source => Received_Data_Not_Empty);
Incoming_Msg.Signal_Reception_Complete;
Incoming_Msg := null;
end if;
Expand Down
9 changes: 6 additions & 3 deletions content/courses/ada-idioms/chapters/type_punning.rst
Original file line number Diff line number Diff line change
Expand Up @@ -273,21 +273,24 @@ sensitivity, returning all three in the mode-out record parameter.
This.Loc_IO_Read (Buffer (5), OUT_Z_H);

Get_X : declare
Raw : Acceleration renames As_Acceleration_Pointer (Buffer (0)'Address).all;
Raw : Acceleration renames
As_Acceleration_Pointer (Buffer (0)'Address).all;
begin
Scaled := Float (Raw) * This.Sensitivity;
Axes.X := Acceleration (Scaled);
end Get_X;

Get_Y : declare
Raw : Acceleration renames As_Acceleration_Pointer (Buffer (2)'Address).all;
Raw : Acceleration renames
As_Acceleration_Pointer (Buffer (2)'Address).all;
begin
Scaled := Float (Raw) * This.Sensitivity;
Axes.Y := Acceleration (Scaled);
end Get_Y;

Get_Z : declare
Raw : Acceleration renames As_Acceleration_Pointer (Buffer (4)'Address).all;
Raw : Acceleration renames
As_Acceleration_Pointer (Buffer (4)'Address).all;
begin
Scaled := Float (Raw) * This.Sensitivity;
Axes.Z := Acceleration (Scaled);
Expand Down

0 comments on commit d399ae5

Please sign in to comment.