comp.lang.ada
 help / color / mirror / Atom feed
From: Alexander Van Hecke <alexke@hotmail.com>
Subject: question about COM2
Date: 2000/01/06
Date: 2000-01-06T16:19:20+00:00	[thread overview]
Message-ID: <3874C02F.53CE5769@hotmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1321 bytes --]

hi all,

I have a question about a program I am writing in Ada.  The program
should do the following (I know, it's not much :-)) : you type a number
(INTEGER) on computer 1, this computer sends the number to computer 2
via nullmodem connected to COM2, you type a number on computer 2, and
send this number back to computer 1.  both computers do some
calculations with these numbers and then give some output.  I have been
trying to write a device driver for the serial port communication, but
I'm stuck.  I don't know what the Interrupt_ID is for serial
communication : in the function Attach_Handler you must pass your
interrupt handler routine and the interrupt ID.  I don't know what this
is for serial communication, and when I look on the internet, I only
find examples in C (interrupt ID for serial port is 0xC or 0xB or
something like that : it doesn't work in Ada).  The ultimate goal is to
write a package that contains two routines : Send_Number(..) and
Get_Number(...).  The numbers that must be sent should be several (> 2)
bytes, so they should probably be split.  Allthough I know my way around
with C, I have no previous experience with Ada.  Does anybody know the
solution to this problem?  I will attach my code as it is right now.
Any comments / suggestions are very welcome!

Thanks in advance,
alex



[-- Attachment #2: Serial_Device_Driver.ada --]
[-- Type: text/plain, Size: 6159 bytes --]

-- dit is de Serial_Device_Driver package
-- let op : we werken met COM2!
-- dwz : TX en RX buffer op 2F8H
-- divisor latch register op 2F8H en 2F9H
-- line control register op 2FBH
-- line status register op 2FDH

package Serial_Device_Driver is
	type 2bits is range 0..3;
	procedure Get_Number(getal : out INTEGER);
	procedure Send_Number(getal : in INTEGER);

private : 
	for 2bits'Size use 2;	-- er mogen slechts 2 bits voor gebruikt worden;

end Serial_Device_Driver;

with Ada.Interrupts.Names, System, System.Storage_Elements;
use Ada.Interrupts.Names, System, System.Storage_Elements;

package body Serial_Device_Driver is
	Bits_In_Word : constant := 16;
	Bits_In_Byte : constant := 8;
	Word : constant := 2;
	type Flag in (Down, Set);

	type Line_Control_Register is
	record
		DL_access : Flag;					-- divisor latch access bit
		break_control : Flag;			-- set break control
		stick_parity : Flag;			-- stick parity
		even_parity : Flag;				-- even parity select
		parity_enable : Flag;			-- parity enable
		stop_bits : Flag;					-- stop bits
		word_length : 2bits;			-- word length : zet op 11
	end record;

-- nu specifieren we de layout

	for Line_Control_Register use
	record
		DL_acces 			at 0*Word range 7..7;
		break_control at 0*Word range 6..6;
		stick_parity 	at 0*Word range 5..5;
		even_parity		at 0*Word range 4..4;
		parity_enable at 0*Word range 3..3;
		stop_bits			at 0*Word range 2..2;
		word_length		at 0*Word range 0..1;
	end record;

	for Line_Control_Register'Size use Bits_In_Byte;		-- het register is 8 bits
	for Line_Control_Register'Alignment use Word;
	for Line_Control_Register'Bit_order us Low_Order_First;	-- LSB = 0;


	type Line_Status_Register is
	record
		TSR_empty : Flag;					-- Trans-shift-register empty
		THR_empty : Flag;					-- Trans-hold-register empty
		Break_Int : Flag;					-- Break interrupt indicator
		Framing_err : Flag;				-- Framing error indicator
		Par_err : Flag;						-- Parity error indicator
		Overrun_err : Flag;				-- Overrun error indicator
		rec_data_ready : Flag;		-- Receiver data ready
	end record;

-- nu specifieren we de layout

	for Line_Status_Register use
	record
		TSR_empty 			at 0*Word range 6..6;
		THR_empty				at 0*Word range 5..5;
		Break_Int				at 0*Word range 4..4;
		Framing_err			at 0*Word range 3..3;
		Par_err					at 0*Word range 2..2;
		Overrun_err			at 0*Word range 1..1;
		rec_data_ready	at 0*Word range 0..0;
	end record;

	for Line_Status_Register'Size use Bits_In_Byte;		-- het register is 8 bits
	for Line_Status_Register'Alignment use Word;
	for Line_Status_Register'Bit_order us Low_Order_First;	-- LSB = 0;

-- als bit 7 van het line control register 1 is, dan zijn de adressen 3F8H en 3F9H voor
-- het divisor latch register
-- als bit 7 van het line control register 0 is, dan zijn de adressen 3F8H en 3F9H voor
-- het verzenden en ontvangen van data
-- we moeten dus eerst op allebei de computers bit 7 van het line control register op
-- 1 zetten, zodat we de baudsnelheid kunnen selecteren;
-- als dit gedaan is, zetten we bit 7 van het line control register op 0, zodat we
-- de adressen 3F8H en 3F9H kunnen gebruiken als dataregister.

	type Divisor_Latch_Register is
	record
		baud_rate : INTEGER;
	end record;

-- specifieren van de layout

	for Divisor_Latch_Register use
	record
		baud_rate at 0*Word range 0..15;
	end record;


	for Divisor_Latch_Register'Size use Bits_In_Word;		-- het register is 16 bits
	for Divisor_Latch_Register'Alignment use Word;
	for Divisor_Latch_Register'Bit_order us Low_Order_First;	-- LSB = 0;

	type Data_Register is INTEGER;		-- alle mogelijke getallen kunnen voorkomen in het data register
	for Data_Register'Size use Bits_In_Word;

	Contr_Reg_Addr: constant Address := To_Address(16#2FB#);
	Stat_Reg_Addr : constant Address := To_Address(16#2FD#);
	Latch_Reg_Addr : constant Address := To_Address(16#2F8#);
	Data_Reg_Addr : constant Address := To_Address(16#2F8#);
	Serial_Priority : constant Interrupt_Priority := 63;

	Control_Reg : aliased Line_Control_Register;
	for Control_Reg'Address use Contr_Reg_Addr;

	Status_Reg : aliased Line_Status_Register;
	for Status_Reg'Address use Stat_Reg_Addr;

	Latch_Reg : aliased Divisor_Latch_Register;
	for Latch_Reg'Address use Latch_Reg_Addr;

	Data_Reg : aliased Data_Register;
	for Data_Reg'Address use Data_Reg_Addr; 


-- nu de interrupt interface nog schrijven

	protected type Interrupt_Interface(Int_Id : Interrupt_Id;
		Cr : access Line_Control_Register;
		Sr : access Line_Status_Register;
		Lr : access Divisor_Latch_Register;
		Dr : access Data_Register) is
		
		entry Read(getal : out INTEGER);		-- het uitlezen van een getal
		entry Write(getal : in INTEGER); 		-- het schrijven van een getal
private :	
		entry Done(getal : out INTEGER);
		procedure Handler;
		pragma Attach_Handler(Handler, Int_Id)
		pragma Interrupt_Priority(Serial_Priority)
		Interrupt_Occurred : Boolean := False;
		Next_Request : Boolean := True;
	end Interrupt_Interface;

	Serial_Interface : Interrupt_Interface(Names.Serial, Control_Reg'Address, 
											Status_Reg'Address, Latch_Reg'Address, Data_Reg'Address);

	protected body Interrupt_Interface is

		entry Read(getal : out INTEGER) when Next_Request is
			Shadow_Register : Control_Register;
		begin
			-- shadow register invullen
			-- en copieren naar controle register
			-- data lezen

			Interrupt_Occurred := False;
			Next_Request := False;
			requeue Done;
		end Read;

		entry Write(getal : in INTEGER) when not Next_Request is
			Shadow_Register : ???
		begin
			???
		end Write;

		procedure Handler is
		begin
			Interrupt_Occurred := True;
		end Handler;

		entry Done(getal : out INTEGER) when Interrupt_Occurred is
		begin
			Next_Request := True;
			-- uitlezen van de data in het getal;
			-- checken op errors?
		end Done;

	end Interrupt_Interface;

	procedure Get_Number(getal : out INTEGER) is
	begin
		Serial_Interface.Read(getal);
	end Get_Number;

	procedure Send_Number(getal : in INTEGER) is
	begin
		-- opsplitsen van getal in afzonderlijke groepjes van 2 bytes!
		-- in het datareg kunnen maar 16 bits tegelijk
    Serial_Interface.Write(getal);
	end Send_Number;
end Serial_Device_Driver;

             reply	other threads:[~2000-01-06  0:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-01-06  0:00 Alexander Van Hecke [this message]
2000-01-07  0:00 ` question about COM2 Ed Falis
2000-01-07  0:00 ` Ed Falis
2000-01-07  0:00 ` more information on OS and compiler Alexander Van Hecke
2000-01-11  0:00   ` Alfred Hilscher
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox