Commit 983b1cec authored by jhugues's avatar jhugues
Browse files

* Update serial drivers to use ASN.1 configuration variables,

	 change driver to use same core/device as input and output



git-svn-id: https://tecsw.estec.esa.int/svn/taste/trunk/po-hi-ada@2522 129961e7-ef38-4bb5-a8f7-c9a525a55882
parent 756c8a71
with Interfaces;
pragma Style_Checks (Off);
With Interfaces;
with Ada.Unchecked_Conversion;
with Uart.Core;
with Uart.Core; use type UART.Core.UART_Device;
with Uart.HLInterface;
with Uart.Streams;
......@@ -13,8 +15,36 @@ with PolyORB_HI_Generated.Transport;
-- This package provides support for the GRUART device driver as
-- defined in the GRUART AADLv2 model.
with System; use System;
with POHICDRIVER_UART; use POHICDRIVER_UART;
package body PolyORB_HI_Drivers_GRUART is
type Serial_Conf_T_Acc is access all POHICDRIVER_UART.Serial_Conf_T;
function To_Serial_Conf_T_Acc is new Ada.Unchecked_Conversion
(System.Address, Serial_Conf_T_Acc);
To_GNAT_Baud_Rate : constant array (POHICDRIVER_UART.Baudrate_T) of
UART.HLInterface.Data_Rate :=
(B9600 => UART.HLInterface.B9600,
B19200 => UART.HLInterface.B19200,
B38400 => UART.HLInterface.B38400,
B57600 => UART.HLInterface.B57600,
B115200 => UART.HLInterface.B115200,
B230400 => UART.HLInterface.B115200);
-- XXX does not exist in GCC.4.4.4
To_GNAT_Parity_Check : constant array (POHICDRIVER_UART.Parity_T) of
UART.HLInterface.Parity_Check :=
(Even => UART.HLInterface.Even,
Odd => UART.HLInterface.Odd);
To_GNAT_Bits : constant array (7 .. 8) of
UART.HLInterface.Data_Bits :=
(7 => UART.HLInterface.B7,
8 => UART.HLInterface.B8);
pragma Suppress (Elaboration_Check, PolyORB_HI_Generated.Transport);
-- We do not want a pragma Elaborate_All to be implicitely
-- generated for Transport.
......@@ -25,15 +55,12 @@ package body PolyORB_HI_Drivers_GRUART is
use PolyORB_HI.Output;
type Node_Record is record
-- UART is a simple protocol, we use one port to send, another
-- to receive.
UART_Port_Send : Uart.HLInterface.Serial_Port;
UART_Device_Send : Uart.Core.UART_Device;
UART_Port_Receive : Uart.HLInterface.Serial_Port;
UART_Device_Receive : Uart.Core.UART_Device;
-- UART is a simple protocol, we use one port to send, assuming
-- it can be used in full duplex mode.
UART_Port : Uart.HLInterface.Serial_Port;
UART_Device : Uart.Core.UART_Device;
UART_Config : Serial_Conf_T;
end record;
Nodes : array (Node_Type) of Node_Record;
......@@ -57,6 +84,7 @@ package body PolyORB_HI_Drivers_GRUART is
procedure Initialize (Name_Table : PolyORB_HI.Utils.Naming_Table_Type) is
Success : Boolean;
Use_Asn1 : Boolean := False;
begin
Uart.HLInterface.Initialize (Success);
......@@ -67,28 +95,52 @@ package body PolyORB_HI_Drivers_GRUART is
end if;
for J in Name_Table'Range loop
Nodes (J).UART_Device_Send
:= Uart.Core.UART_Device'Value
(To_String (Name_Table (J).Location) (1 .. 1));
Nodes (J).UART_Device_Receive
:= Uart.Core.UART_Device'Value
(To_String (Name_Table (J).Location) (3 .. 3));
if Name_Table (J).Variable = System.Null_Address then
Nodes (J).UART_Device
:= Uart.Core.UART_Device'Value
(To_String (Name_Table (J).Location) (1 .. 1));
-- Note: we only consider the first half of the
-- configuration string.
else
Nodes (J).UART_Config := To_Serial_Conf_T_Acc
(Name_Table (J).Variable).all;
Use_Asn1 := True;
Put_Line (Normal, "Device: " & Nodes (J).UART_Config.devname);
-- Translate the device name into an UART_Device
if Nodes (J).UART_Config.Devname (1 .. 14) /= "/dev/apburasta" then
Put_Line ("invalid device name");
else
-- We assume the device name to be "/dev/apburastaX"
-- with X in 0 .. 2. We need to move X to the 1 .. 3
-- range.
Nodes (J).UART_Device
:= UART.Core.UART_Device
(Integer'Value (Nodes (J).UART_Config.Devname (15 .. 15)) + 1);
end if;
end if;
end loop;
Uart.HLInterface.Open (Port => Nodes (My_Node).UART_Port_Send,
Number => Nodes (My_Node).UART_Device_Send);
Uart.HLInterface.Open (Port => Nodes (My_Node).UART_Port_Receive,
Number => Nodes (My_Node).UART_Device_Receive);
Uart.HLInterface.Set (Port => Nodes (My_Node).UART_Port_Send,
Rate => Uart.HLInterface.B19200);
Uart.HLInterface.Set (Port => Nodes (My_Node).UART_Port_Receive,
Rate => Uart.HLInterface.B19200,
Block => True);
Uart.HLInterface.Open (Port => Nodes (My_Node).UART_Port,
Number => Nodes (My_Node).UART_Device);
if not Use_Asn1 then
Uart.HLInterface.Set (Port => Nodes (My_Node).UART_Port,
Rate => Uart.HLInterface.B19200,
Block => True);
else
UART.HLInterface.Set
(Port => Nodes (My_Node).UART_Port,
Rate => To_GNAT_Baud_Rate (Nodes (My_Node).UART_Config.Speed),
Parity => To_GNAT_Parity_Check (Nodes (My_Node).UART_Config.Parity),
Bits => To_GNAT_Bits (Integer (Nodes (My_Node).UART_Config.Bits)),
Block => True);
end if;
pragma Debug (Put_Line (Normal, "Initialization of UART subsystem"
& " is complete"));
end Initialize;
......@@ -110,13 +162,13 @@ package body PolyORB_HI_Drivers_GRUART is
Main_Loop : loop
Put_Line ("Using user-provided GRUART stack to receive");
Put_Line ("Waiting on UART #"
& Nodes (My_Node).UART_Device_Receive'Img);
& Nodes (My_Node).UART_Device'Img);
-- UART is a character-oriented protocol
-- 1/ Receive message length
Uart.HLInterface.Read (Nodes (My_Node).UART_Port_Receive, SEL, SEO);
Uart.HLInterface.Read (Nodes (My_Node).UART_Port, SEL, SEO);
Packet_Size := Uart.Streams.Stream_Element_Offset
(To_Length (To_PO_HI_Message_Length_Stream (SEL)));
......@@ -129,7 +181,7 @@ package body PolyORB_HI_Drivers_GRUART is
while Data_Received_Index <= Packet_Size + Message_Length_Size loop
-- We must loop to make sure we receive all data
Uart.HLInterface.Read (Nodes (My_Node).UART_Port_Receive,
Uart.HLInterface.Read (Nodes (My_Node).UART_Port,
SEA (Data_Received_Index .. SEO + 1),
SEO);
Data_Received_Index := 1 + SEO + 1;
......@@ -141,7 +193,7 @@ package body PolyORB_HI_Drivers_GRUART is
Put_Line
(Normal,
"UART #"
& Nodes (My_Node).UART_Device_Receive'Img
& Nodes (My_Node).UART_Device'Img
& " received"
& Uart.Streams.Stream_Element_Offset'Image (SEO)
& " bytes");
......@@ -183,10 +235,10 @@ package body PolyORB_HI_Drivers_GRUART is
begin
Put_Line ("Using user-provided UART stack to send");
Put_Line ("Sending through UART #"
& Nodes (Node).UART_Device_Send'Img
& Nodes (Node).UART_Device'Img
& Size'Img & " bytes");
Uart.HLInterface.Write (Port => Nodes (My_Node).UART_Port_Send,
Uart.HLInterface.Write (Port => Nodes (My_Node).UART_Port,
Buffer => Msg);
return Error_Kind'(Error_None);
......
......@@ -3,9 +3,6 @@ with PolyORB_HI_Generated.Deployment;
with PolyORB_HI.Streams;
with PolyORB_HI.Utils;
with POHICDRIVER_UART;
pragma Unreferenced (POHICDRIVER_UART);
package PolyORB_HI_Drivers_GRUART is
use PolyORB_HI.Errors;
......
with Ada.Exceptions;
With Ada.Exceptions;
with Ada.Streams;
with Ada.Unchecked_Conversion;
with Interfaces;
......@@ -13,8 +13,36 @@ with PolyORB_HI_Generated.Transport;
-- This package provides support for the Native_UART device driver as
-- defined in the Native_UART AADLv2 model.
with System; use System;
with POHICDRIVER_UART; use POHICDRIVER_UART;
package body PolyORB_HI_Drivers_Native_UART is
type Serial_Conf_T_Acc is access all POHICDRIVER_UART.Serial_Conf_T;
function To_Serial_Conf_T_Acc is new Ada.Unchecked_Conversion
(System.Address, Serial_Conf_T_Acc);
To_GNAT_Baud_Rate : constant array (POHICDRIVER_UART.Baudrate_T) of
GNAT.Serial_Communications.Data_Rate :=
(B9600 => GNAT.Serial_Communications.B9600,
B19200 => GNAT.Serial_Communications.B19200,
B38400 => GNAT.Serial_Communications.B38400,
B57600 => GNAT.Serial_Communications.B57600,
B115200 => GNAT.Serial_Communications.B115200,
B230400 => GNAT.Serial_Communications.B115200);
-- XXX does not exist in GCC.4.4.4
To_GNAT_Parity_Check : constant array (POHICDRIVER_UART.Parity_T) of
GNAT.Serial_Communications.Parity_Check :=
(Even => GNAT.Serial_Communications.Even,
Odd => GNAT.Serial_Communications.Odd);
To_GNAT_Bits : constant array (7 .. 8) of
GNAT.Serial_Communications.Data_Bits :=
(7 => GNAT.Serial_Communications.CS7,
8 => GNAT.Serial_Communications.CS8);
pragma Suppress (Elaboration_Check, PolyORB_HI_Generated.Transport);
-- We do not want a pragma Elaborate_All to be implicitely
-- generated for Transport.
......@@ -25,11 +53,11 @@ package body PolyORB_HI_Drivers_Native_UART is
use PolyORB_HI.Output;
type Node_Record is record
-- UART is a simple protocol, we use one port to send, another
-- to receive.
-- UART is a simple protocol, we use one port to send, assuming
-- it can be used in full duplex mode.
UART_Port_Send : GNAT.Serial_Communications.Serial_Port;
UART_Port_Receive : GNAT.Serial_Communications.Serial_Port;
UART_Port : GNAT.Serial_Communications.Serial_Port;
UART_Config : Serial_Conf_T; -- ASN.1 Configuration variable
end record;
Nodes : array (Node_Type) of Node_Record;
......@@ -52,126 +80,148 @@ package body PolyORB_HI_Drivers_Native_UART is
----------------
procedure Initialize (Name_Table : PolyORB_HI.Utils.Naming_Table_Type) is
Parity : GNAT.Serial_Communications.Parity_Check;
begin
for J in Name_Table'Range loop
-- The structure of the location information is
-- "serial DEVICE BAUDS DATA_BITS PARITY STOP_BIT"
declare
S : constant String := PolyORB_HI.Utils.To_String
(Name_Table (J).Location);
Device_First, Device_Last : Integer;
Bauds : GNAT.Serial_Communications.Data_Rate;
Bits : GNAT.Serial_Communications.Data_Bits;
Parity : GNAT.Serial_Communications.Parity_Check;
Stop_Bits : GNAT.Serial_Communications.Stop_Bits_Number;
First, Last : Integer;
begin
First := S'First;
-- First parse the prefix "serial"
if Name_Table (J).Variable = System.Null_Address then
-- The structure of the location information is
-- "serial DEVICE BAUDS DATA_BITS PARITY STOP_BIT"
Last := Parse_String (S, First, ' ');
declare
S : constant String := PolyORB_HI.Utils.To_String
(Name_Table (J).Location);
Device_First, Device_Last : Integer;
Bauds : GNAT.Serial_Communications.Data_Rate;
Bits : GNAT.Serial_Communications.Data_Bits;
Stop_Bits : GNAT.Serial_Communications.Stop_Bits_Number;
if S (First .. Last) /= "serial" then
raise Program_Error with "Invalid configuration";
end if;
First, Last : Integer;
-- Then, parse the device
First := Last + 2;
Last := Parse_String (S, First, ' ');
Device_First := First;
Device_Last := Last;
-- Then, parse the baud rate
First := Last + 2;
Last := Parse_String (S, First, ' ');
begin
Bauds := GNAT.Serial_Communications.Data_Rate'Value
('B' & S (First .. Last));
First := S'First;
-- First parse the prefix "serial"
Last := Parse_String (S, First, ' ');
if S (First .. Last) /= "serial" then
raise Program_Error with "Invalid configuration";
end if;
-- Then, parse the device
First := Last + 2;
Last := Parse_String (S, First, ' ');
Device_First := First;
Device_Last := Last;
-- Then, parse the baud rate
First := Last + 2;
Last := Parse_String (S, First, ' ');
begin
Bauds := GNAT.Serial_Communications.Data_Rate'Value
('B' & S (First .. Last));
exception
when others =>
Put_Line (Normal, "Wrong baud rate: " & S (First .. Last));
raise;
end;
-- Then, parse the data bits
First := Last + 2;
Last := Parse_String (S, First, ' ');
-- Note: on GNAT GPL 2008 and before, Data_Bits define
-- the B8 and B7 enumerators; on GNAT GPL 2009 and after,
-- Data_Bits define the CS8 and CS7 enumerators.
if S (First) = '8' then
Bits := GNAT.Serial_Communications.CS8;
elsif S (First) = '7' then
Bits := GNAT.Serial_Communications.CS7;
else
raise Program_Error with "Wrong bits: " & S (First);
end if;
-- Then, parse the parity
First := Last + 2;
Last := Parse_String (S, First, ' ');
if S (First) = 'N' then
Parity := GNAT.Serial_Communications.None;
elsif S (First) = 'E' then
Parity := GNAT.Serial_Communications.Even;
elsif S (First) = 'O' then
Parity := GNAT.Serial_Communications.Odd;
else
raise Program_Error with "Wrong parity: " & S (First);
end if;
-- Finally, parse the stop_bits
First := Last + 2;
Last := Parse_String (S, First, ' ');
if S (First) = '1' then
Stop_Bits := GNAT.Serial_Communications.One;
elsif S (First) = '2' then
Stop_Bits := GNAT.Serial_Communications.Two;
else
raise Program_Error with "Wrong stop bits: " & S (First);
end if;
GNAT.Serial_Communications.Open
(Port => Nodes (My_Node).UART_Port,
Name => GNAT.Serial_Communications.Port_Name
(S (Device_First .. Device_Last)));
GNAT.Serial_Communications.Set
(Port => Nodes (My_Node).UART_Port,
Rate => Bauds,
Bits => Bits,
Stop_Bits => Stop_Bits,
Parity => Parity,
Block => True);
exception
when others =>
Put_Line (Normal, "Wrong baud rate: " & S (First .. Last));
raise;
Put_Line (Normal, "Initialization of UART subsystem dead");
end;
else
-- We got an ASN.1 configuration variable, use it
-- directly.
-- Then, parse the data bits
First := Last + 2;
Last := Parse_String (S, First, ' ');
-- Note: on GNAT GPL 2008 and before, Data_Bits define
-- the B8 and B7 enumerators; on GNAT GPL 2009 and after,
-- Data_Bits define the CS8 and CS7 enumerators.
if S (First) = '8' then
Bits := GNAT.Serial_Communications.CS8;
elsif S (First) = '7' then
Bits := GNAT.Serial_Communications.CS7;
else
raise Program_Error with "Wrong bits: " & S (First);
end if;
-- Then, parse the parity
First := Last + 2;
Last := Parse_String (S, First, ' ');
if S (First) = 'N' then
Parity := GNAT.Serial_Communications.None;
elsif S (First) = 'E' then
Parity := GNAT.Serial_Communications.Even;
elsif S (First) = 'O' then
Parity := GNAT.Serial_Communications.Odd;
else
raise Program_Error with "Wrong parity: " & S (First);
end if;
-- Finally, parse the stop_bits
First := Last + 2;
Last := Parse_String (S, First, ' ');
Nodes (J).UART_Config := To_Serial_Conf_T_Acc
(Name_Table (J).Variable).all;
if S (First) = '1' then
Stop_Bits := GNAT.Serial_Communications.One;
elsif S (First) = '2' then
Stop_Bits := GNAT.Serial_Communications.Two;
else
raise Program_Error with "Wrong stop bits: " & S (First);
end if;
Put_Line (Normal, "Device: " & Nodes (J).UART_Config.devname);
Put_Line (Normal, "Speed: " & Nodes (J).UART_Config.speed'Img);
Put_Line (Normal, "Parity: " & Nodes (J).UART_Config.parity'Img);
Put_Line (Normal, "Bits: " & Nodes (J).UART_Config.bits'Img);
Put_Line (Normal, "Use Parity bits: "
& Nodes (J).UART_Config.use_paritybit'Img);
GNAT.Serial_Communications.Open
(Port => Nodes (My_Node).UART_Port_Send,
(Port => Nodes (My_Node).UART_Port,
Name => GNAT.Serial_Communications.Port_Name
(S (Device_First .. Device_Last)));
GNAT.Serial_Communications.Set
(Port => Nodes (My_Node).UART_Port_Send,
Rate => Bauds,
Bits => Bits,
Stop_Bits => Stop_Bits,
Parity => Parity,
Block => True);
(Nodes (J).UART_Config.devname));
-- XXX should correct the rest
GNAT.Serial_Communications.Open
(Port => Nodes (My_Node).UART_Port_Receive,
Name => "/dev/ttyUSB0");
if Nodes (J).UART_Config.Use_Paritybit then
Parity := To_GNAT_Parity_Check (Nodes (J).UART_Config.Parity);
else
Parity := GNAT.Serial_Communications.None;
end if;
GNAT.Serial_Communications.Set
(Port => Nodes (My_Node).UART_Port_Receive,
Parity => GNAT.Serial_Communications.Even,
Rate => GNAT.Serial_Communications.B19200,
Block => True);
exception
when others =>
Put_Line (Normal, "Initialization of UART subsystem dead");
end;
(Port => Nodes (My_Node).UART_Port,
Rate => To_GNAT_Baud_Rate (Nodes (J).UART_Config.Speed),
Parity => Parity,
Bits => To_GNAT_Bits (Integer (Nodes (J).UART_Config.Bits)),
Block => True);
end if;
end loop;
Put_Line (Normal, "Initialization of UART subsystem is complete");
......@@ -199,7 +249,7 @@ package body PolyORB_HI_Drivers_Native_UART is
-- 1/ Receive message length
GNAT.Serial_Communications.Read
(Nodes (My_Node).UART_Port_Receive, SEL, SEO);
(Nodes (My_Node).UART_Port, SEL, SEO);
Packet_Size := Ada.Streams.Stream_Element_Offset
(To_Length (To_PO_HI_Message_Length_Stream (SEL)));
......@@ -213,7 +263,7 @@ package body PolyORB_HI_Drivers_Native_UART is
-- We must loop to make sure we receive all data
GNAT.Serial_Communications.Read
(Nodes (My_Node).UART_Port_Receive,
(Nodes (My_Node).UART_Port,
SEA (Data_Received_Index .. SEO + 1),
SEO);
Data_Received_Index := 1 + SEO + 1;
......@@ -275,7 +325,7 @@ package body PolyORB_HI_Drivers_Native_UART is
& Size'Img & " bytes");
GNAT.Serial_Communications.Write
(Port => Nodes (My_Node).UART_Port_Send,
(Port => Nodes (My_Node).UART_Port,
Buffer => Msg);
return Error_Kind'(Error_None);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment