comp.lang.ada
 help / color / mirror / Atom feed
* Cleanest Ada way to do this?
@ 2014-06-22 16:51 Mike Silva
  2014-06-22 19:07 ` Simon Clubley
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Mike Silva @ 2014-06-22 16:51 UTC (permalink / raw)


I'd like some help on the cleanest, or most elegant, way to do this in Ada.  I'm writing to an LCD character display, in 4-bit mode, which requires writing an 8 bit character or command value as two 4 bit pieces.  The port (a memory address) being written to is 32 bits wide.  What I would like to be able to do is some form of this (not valid Ada, I know):

 Port32(4..7) := Some_Char(4..7);
 ..twiddle some other control bits..
 Port32(4..7) := Some_Char(0..3);
 ..twiddle some other control bits..

Any thoughts?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-22 16:51 Cleanest Ada way to do this? Mike Silva
@ 2014-06-22 19:07 ` Simon Clubley
  2014-06-22 21:20   ` Mike Silva
  2014-06-22 21:05 ` Shark8
  2014-06-23  9:02 ` rrr.eee.27
  2 siblings, 1 reply; 12+ messages in thread
From: Simon Clubley @ 2014-06-22 19:07 UTC (permalink / raw)


On 2014-06-22, Mike Silva <hungupharps@gmail.com> wrote:
> I'd like some help on the cleanest, or most elegant, way to do this in Ada. 
> I'm writing to an LCD character display, in 4-bit mode, which requires writing
> an 8 bit character or command value as two 4 bit pieces.  The port (a memory
> address) being written to is 32 bits wide.  What I would like to be able to do
> is some form of this (not valid Ada, I know):
>
>  Port32(4..7) := Some_Char(4..7);
>  ..twiddle some other control bits..
>  Port32(4..7) := Some_Char(0..3);
>  ..twiddle some other control bits..
>

Do the other bits in Port32 need to be preserved when (4..7) are written ?

Is it _required_ that Port32 is written in units of 32 bits ?
(The answer to that is probably yes, but I thought I would check).

There was some discussion of this class of problem a few weeks ago when
I was proposing syntax to allow the atomic update of multiple bitfields
at the same time without having to use an intermediate variables.

The conclusions from that were that if you need to preserve the other
bits in Port32(4..7) your only real option is to use a temporary
variable with a 32-bit record structure to match your bitfield
requirements (unless you want to get into using C style bitmasks.)

Pragma Atomic and/or Pragma Volatile may also need to be applied.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-22 16:51 Cleanest Ada way to do this? Mike Silva
  2014-06-22 19:07 ` Simon Clubley
@ 2014-06-22 21:05 ` Shark8
  2014-06-23  0:17   ` Simon Clubley
  2014-06-23  9:02 ` rrr.eee.27
  2 siblings, 1 reply; 12+ messages in thread
From: Shark8 @ 2014-06-22 21:05 UTC (permalink / raw)


On 22-Jun-14 10:51, Mike Silva wrote:
> I'd like some help on the cleanest, or most elegant, way to do this in Ada.
>  I'm writing to an LCD character display, in 4-bit mode, which requires writing
> an 8 bit character or command value as two 4 bit pieces.  The port (a memory
> address) being written to is 32 bits wide.  What I would like to be able to do
> is some form of this (not valid Ada, I know):
>
>   Port32(4..7) := Some_Char(4..7);
>   ..twiddle some other control bits..
>   Port32(4..7) := Some_Char(0..3);
>   ..twiddle some other control bits..
>
> Any thoughts?
>

Depends on the situation, I think; if there's a lot of them [ports] like 
say one for each 'character' you may be better off making a generic 
package to interface with it.

Package Parent is
   Type Segment is range 1..16 with Size => 4;
   Type LCD_Character is private;
   Type LCD_Handle is not null access LCD_Character;
Private
  Type Segment_Array is Array(Segment) of Boolean
     with Size => Segment'Last;
  Type LCD_Character is record
    Segments : Segment_Array;
  end record;
End Parent;

Generic
   Port_Address : in Address;
Package Parent.Port is
   Port : aliased LCD_Character with Volatile, Address => Port_Address;
End Parent.port;

With Parent.Port;
Package Display is
   Number_of_Segments : Constant Positive := 3;
   Type LCD_Array is Array(1..Number_of_Segments) of LCD_Handle;

   Display : constant LCD_Array;
Private
   Package Segment_1 is new Parent.Port( ######## );
   Package Segment_2 is new Parent.Port( ######## );
   Package Segment_3 is new Parent.Port( ######## );

   Display : constant LCD_Array:=
     ( 1 => Segment_1.Port, 2 => Segment_2.Port, 3 => Segment_3.Port );
End Display;

Or if it's a one-off type thing do it more directly:

LCD_Display : LCD_Character with Address => Port_Address;


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-22 19:07 ` Simon Clubley
@ 2014-06-22 21:20   ` Mike Silva
  0 siblings, 0 replies; 12+ messages in thread
From: Mike Silva @ 2014-06-22 21:20 UTC (permalink / raw)


On Sunday, June 22, 2014 12:07:32 PM UTC-7, Simon Clubley wrote:
> On 2014-06-22, Mike Silva  wrote:
> 
> > I'd like some help on the cleanest, or most elegant, way to do this in Ada. 
> 
> > I'm writing to an LCD character display, in 4-bit mode, which requires writing
> 
> > an 8 bit character or command value as two 4 bit pieces.  The port (a memory
> 
> > address) being written to is 32 bits wide.  What I would like to be able to do
> 
> > is some form of this (not valid Ada, I know):
> 
> >
> 
> >  Port32(4..7) := Some_Char(4..7);
> 
> >  ..twiddle some other control bits..
> 
> >  Port32(4..7) := Some_Char(0..3);
> 
> >  ..twiddle some other control bits..
> 
> >
> 
> 
> 
> Do the other bits in Port32 need to be preserved when (4..7) are written ?
> 
> 
> 
> Is it _required_ that Port32 is written in units of 32 bits ?
> 
> (The answer to that is probably yes, but I thought I would check).
> 
> 
> 
> There was some discussion of this class of problem a few weeks ago when
> 
> I was proposing syntax to allow the atomic update of multiple bitfields
> 
> at the same time without having to use an intermediate variables.
> 
> 
> 
> The conclusions from that were that if you need to preserve the other
> 
> bits in Port32(4..7) your only real option is to use a temporary
> 
> variable with a 32-bit record structure to match your bitfield
> 
> requirements (unless you want to get into using C style bitmasks.)

Yes, the other bits need to be preserved.  In C the code would look something like this

P32 = (P32 & ~0x00F0) | (c & 0xF0);
...twiddle some control bits
P32 = (P32 & ~0x00F0) | ((c << 4) & 0xF0);


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-22 21:05 ` Shark8
@ 2014-06-23  0:17   ` Simon Clubley
  2014-06-23  6:46     ` hungupharps
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Clubley @ 2014-06-23  0:17 UTC (permalink / raw)


On 2014-06-22, Shark8 <OneWingedShark@gmail.com> wrote:
> On 22-Jun-14 10:51, Mike Silva wrote:
>> I'd like some help on the cleanest, or most elegant, way to do this in Ada.
>>  I'm writing to an LCD character display, in 4-bit mode, which requires writing
>> an 8 bit character or command value as two 4 bit pieces.  The port (a memory
>> address) being written to is 32 bits wide.  What I would like to be able to do
>> is some form of this (not valid Ada, I know):
>>
>>   Port32(4..7) := Some_Char(4..7);
>>   ..twiddle some other control bits..
>>   Port32(4..7) := Some_Char(0..3);
>>   ..twiddle some other control bits..
>>
>> Any thoughts?
>>
>
> Depends on the situation, I think; if there's a lot of them [ports] like 
> say one for each 'character' you may be better off making a generic 
> package to interface with it.
>

There will probably only be one 32 bit port in use for the LCD and only
a small subset of the bits will probably be in use (at least for driving
the LCD if it's the type of LCD I think it is).

It looks like Mike is implementing the traditional character LCD driver.
Intermixed with the display data will probably be command data including
things like cursor addressing and there will probably be additional I/O
lines for things like Read/Write select and data/command mode.

However, to reduce the amount of I/O pins you need to wire up, you can
command the LCD module to switch from 8-bit mode to 4-bit mode so you
end up sending each command or data character as two nibbles and that
looks like what Mike has done here.

My first pass at a design for this would be a 32-bit record type with
the bitfields laid out to correspond with the actual wiring of the I/O
port, so he has separate bitfields for both the R/W and data/command
lines as well as a 4-bit wide field for the above data lines.

If Mike needs to modify more than one of the bitfields at the same
time, then he will have to use a temporary variable. However, I've
just looked at some C code from a few years ago which does the same
thing and in that code, I don't appear to need to do that.

However, Pragma Atomic (and/or Volatile) are probably required.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-23  0:17   ` Simon Clubley
@ 2014-06-23  6:46     ` hungupharps
  2014-06-23  7:32       ` Georg Bauhaus
  0 siblings, 1 reply; 12+ messages in thread
From: hungupharps @ 2014-06-23  6:46 UTC (permalink / raw)


On Sunday, June 22, 2014 5:17:49 PM UTC-7, Simon Clubley wrote:
> 
> There will probably only be one 32 bit port in use for the LCD and only
> 
> a small subset of the bits will probably be in use (at least for driving
> 
> the LCD if it's the type of LCD I think it is).
> 
> 
> 
> It looks like Mike is implementing the traditional character LCD driver.
> 
> Intermixed with the display data will probably be command data including
> 
> things like cursor addressing and there will probably be additional I/O
> 
> lines for things like Read/Write select and data/command mode.
> 
> 
> 
> However, to reduce the amount of I/O pins you need to wire up, you can
> 
> command the LCD module to switch from 8-bit mode to 4-bit mode so you
> 
> end up sending each command or data character as two nibbles and that
> 
> looks like what Mike has done here.
> 
> 
> 
> My first pass at a design for this would be a 32-bit record type with
> 
> the bitfields laid out to correspond with the actual wiring of the I/O
> 
> port, so he has separate bitfields for both the R/W and data/command
> 
> lines as well as a 4-bit wide field for the above data lines.

Yes, it's that type of LCD.  4 data lines, an E signal and a RS (register select) signal.  Hard-wire the R/W line to GND.

Ignoring the control signals (they will just be writes to separate atomic set or reset registers, to avoid a RMW cycle), what might this code look like?  I've got a bitfield representing the LCD data lines and I'm trying then to write bits from a Character into it.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-23  6:46     ` hungupharps
@ 2014-06-23  7:32       ` Georg Bauhaus
  2014-06-23 11:48         ` Simon Clubley
  0 siblings, 1 reply; 12+ messages in thread
From: Georg Bauhaus @ 2014-06-23  7:32 UTC (permalink / raw)


On 23/06/14 08:46, hungupharps@gmail.com wrote:
> I've got a bitfield representing the LCD data lines and I'm trying then to write bits from a Character into it.

If you know the size of the Character, 8 say, unchecked_conversion
seems possible, the target type being any 8-bit type that works,
e.g. a packed array of bits, or an Unsigned_8. The first offering
slices, the second providing for shifts and masks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-22 16:51 Cleanest Ada way to do this? Mike Silva
  2014-06-22 19:07 ` Simon Clubley
  2014-06-22 21:05 ` Shark8
@ 2014-06-23  9:02 ` rrr.eee.27
  2014-06-23 11:57   ` Simon Clubley
  2 siblings, 1 reply; 12+ messages in thread
From: rrr.eee.27 @ 2014-06-23  9:02 UTC (permalink / raw)


On Sunday, June 22, 2014 6:51:01 PM UTC+2, Mike Silva wrote:
> I'd like some help on the cleanest, or most elegant, way to do this in Ada. I'm writing to an LCD character display, in 4-bit mode, which requires writing an 8 bit character or command value as two 4 bit pieces. The port (a memory address) being written to is 32 bits wide. What I would like to be able to do is some form of this (not valid Ada, I know): Port32(4..7) := Some_Char(4..7); ..twiddle some other control bits.. Port32(4..7) := Some_Char(0..3); ..twiddle some other control bits.. Any thoughts?

You have to drive not only the four data lines but also some Enable or RegisterSelect lines (for the standard LCD controller HD44780). Those have to be written in parallel. the second nibble (other half of the byte) has to follow with specific timing. I recommend a look on lcd.ads, lcd.adb, and lcd-wiring.ads from AVR-Ada at http://sourceforge.net/p/avr-ada/code/ci/master/tree/avr/lcd/.

You can probably leave out the dependancy on AVR and AVR.Strings in lcd.ads as you are on a 32bit machine.

The actual mapping of the ports and port bits is in LCD.Wiring. Here you have to find your own solution based on your hardware.

HTH
    Rolf

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-23  7:32       ` Georg Bauhaus
@ 2014-06-23 11:48         ` Simon Clubley
  2014-06-23 15:40           ` G.B.
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Clubley @ 2014-06-23 11:48 UTC (permalink / raw)


On 2014-06-23, Georg Bauhaus <rm-host.bauhaus@maps.futureapps.de> wrote:
> On 23/06/14 08:46, hungupharps@gmail.com wrote:
>> I've got a bitfield representing the LCD data lines and I'm trying then to write bits from a Character into it.
>
> If you know the size of the Character, 8 say, unchecked_conversion
> seems possible, the target type being any 8-bit type that works,
> e.g. a packed array of bits, or an Unsigned_8. The first offering
> slices, the second providing for shifts and masks.
>

Wouldn't a better approach be to start with Character'Pos instead of a
Unchecked_Conversion ?

I'm genuinely curious. I'm wondering if there's something I am missing.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-23  9:02 ` rrr.eee.27
@ 2014-06-23 11:57   ` Simon Clubley
  2014-06-23 12:05     ` rrr.eee.27
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Clubley @ 2014-06-23 11:57 UTC (permalink / raw)


On 2014-06-23, rrr.eee.27@gmail.com <rrr.eee.27@gmail.com> wrote:
> On Sunday, June 22, 2014 6:51:01 PM UTC+2, Mike Silva wrote:
>> I'd like some help on the cleanest, or most elegant, way to do this in Ada. I'm writing to an LCD character display, in 4-bit mode, which requires writing an 8 bit character or command value as two 4 bit pieces. The port (a memory address) being written to is 32 bits wide. What I would like to be able to do is some form of this (not valid Ada, I know): Port32(4..7) := Some_Char(4..7); ..twiddle some other control bits.. Port32(4..7) := Some_Char(0..3); ..twiddle some other control bits.. Any thoughts?
>
> You have to drive not only the four data lines but also some Enable or
> RegisterSelect lines (for the standard LCD controller HD44780). Those have to
> be written in parallel. the second nibble (other half of the byte) has to
> follow with specific timing. I recommend a look on lcd.ads, lcd.adb, and
> lcd-wiring.ads from AVR-Ada at
> http://sourceforge.net/p/avr-ada/code/ci/master/tree/avr/lcd/.
>

Dammit. That's something I should have thought to go looking for as well.

I see they are also using Character'Pos for the conversion although they
are also using a more generic approach of treating each data I/O line in
isolation instead of as a related block of 4 contiguous lines.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-23 11:57   ` Simon Clubley
@ 2014-06-23 12:05     ` rrr.eee.27
  0 siblings, 0 replies; 12+ messages in thread
From: rrr.eee.27 @ 2014-06-23 12:05 UTC (permalink / raw)


On Monday, June 23, 2014 1:57:39 PM UTC+2, Simon Clubley wrote:
> I see they are also using Character'Pos for the conversion although they 
> are also using a more generic approach of treating each data I/O line in 
> isolation instead of as a related block of 4 contiguous lines. 
>   

AFAIR that was due to code size (four single bit assignments being shorter than a byte write!) and due to flexibility for wiring the data lines.

Rolf


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Cleanest Ada way to do this?
  2014-06-23 11:48         ` Simon Clubley
@ 2014-06-23 15:40           ` G.B.
  0 siblings, 0 replies; 12+ messages in thread
From: G.B. @ 2014-06-23 15:40 UTC (permalink / raw)


On 23.06.14 13:48, Simon Clubley wrote:
> On 2014-06-23, Georg Bauhaus <rm-host.bauhaus@maps.futureapps.de> wrote:
>> On 23/06/14 08:46, hungupharps@gmail.com wrote:
>>> I've got a bitfield representing the LCD data lines and I'm trying then to write bits from a Character into it.
>>
>> If you know the size of the Character, 8 say, unchecked_conversion
>> seems possible, the target type being any 8-bit type that works,
>> e.g. a packed array of bits, or an Unsigned_8. The first offering
>> slices, the second providing for shifts and masks.
>>
>
> Wouldn't a better approach be to start with Character'Pos instead of a
> Unchecked_Conversion ?

Yes, if it is sufficient to use shifts and masks. The instructions
generated seem identical, at least when using GNAT on Intel.



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-06-23 15:40 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-22 16:51 Cleanest Ada way to do this? Mike Silva
2014-06-22 19:07 ` Simon Clubley
2014-06-22 21:20   ` Mike Silva
2014-06-22 21:05 ` Shark8
2014-06-23  0:17   ` Simon Clubley
2014-06-23  6:46     ` hungupharps
2014-06-23  7:32       ` Georg Bauhaus
2014-06-23 11:48         ` Simon Clubley
2014-06-23 15:40           ` G.B.
2014-06-23  9:02 ` rrr.eee.27
2014-06-23 11:57   ` Simon Clubley
2014-06-23 12:05     ` rrr.eee.27

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