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;
next 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