Structure for pins in GCC to address them like LCD.DB0=0

OP #1174102
Hello! Please, help me.

I use Eclipse + gcc + JTAG to programm AT91SAM7S64. I get universal code
to use with my LCD with controller (hereunder). The lines like LCD.E=0;
Delay(>20ms); should be modified correctly and structure LCD with pins
sould be declared. I would like to understand how to use constructions
like LCD.E=1. Currently I use mask in my code:
In board.h define pins of LCD ----------------
#define DB0  (1<<0)      // DB0 pin of LCD
#define DB1  (1<<1)      // DB1 pin of LCD
#define DB2  (1<<2)      // DB2 pin of LCD
#define DB3  (1<<3)      // DB3 pin of LCD
#define A0   (1<<4)      // A0  pin of LCD
#define RDRW (1<<5)      // Read/Write pin
#define E    (1<<6)      // E pin
#define DB7  (1<<7)      // DB7
#define DB6  (1<<9)      // DB6
#define DB5  (1<<10)      // DB5
#define DB4  (1<<11)      // DB4


#define MY_MASK  (DB0|DB1|DB2|DB3|A0|RDRW|E|DB7|DB6|DB5|DB4)
--------------------------------------------
And in main.c I write to init LCD something like  this:

/// Swith off all pins
pPIO->PIO_CODR = E; //OFF
pPIO->PIO_CODR = A0; //OFF
pPIO->PIO_CODR = RDRW; //OFF
pPIO->PIO_CODR = DB7; //OFF
pPIO->PIO_CODR = DB6; //OFF
pPIO->PIO_CODR = DB5; //OFF
pPIO->PIO_CODR = DB4; //OFF
pPIO->PIO_CODR = DB3; //OFF
pPIO->PIO_CODR = DB2; //OFF
pPIO->PIO_CODR = DB1; //OFF
pPIO->PIO_CODR = DB0; //OFF

// Step 1
wait(150);

pPIO->PIO_CODR = E; //OFF
wait(10);
pPIO->PIO_CODR = A0; //OFF
pPIO->PIO_SODR = DB5; //ON
pPIO->PIO_SODR = DB4; //ON
pPIO->PIO_SODR = E; //ON

// Step 3
wait(100);

pPIO->PIO_CODR = E; //OFF
wait(10);
pPIO->PIO_SODR = DB5; //ON
......
----------------------------------------------

In PIC C I can make something like this

LCD={E==portA.1,A0==PortA.5, RDRW==portA.4, DB7==portA.7, ....,
DB0==portB4};

And use LCD.E=0; or LCD.1=0; in code. Or write LCD = 0x0040; without
pPIO->PIO_CODR etc.

How can I bild some structure with links to set of pins in gcc? And how
can I work with it without commands like "pPIO->" using just "=" and
HEX, DEC or binary numbers? I would like to use downloaded code
hereunder:



UNIVERSAL CODE FOR LCD: --------------------


#define  MT10S1    //Type of LCD

#define  Len1  8  //Symbols in first line of LCD
#define  Len2  2  //Symbols in second line of LCD
#define  Len3  0  //In 3th
#define  Len4  0  //In 4th
const char Text1[Len1]={  'M','E','L','T',' ','1','0','S'    };
const char Text2[Len2]={  '1',24          };


void main(void) {
int i;

  LCDinit();
  WriteCmd(0x80);    //Set cursor in start of first line
#if Len1>0
  for(i=0;i<Len1;i++) { WriteData(Text1[i]); }
#endif

#if Len3>0
  for(i=0;i<Len3;i++) { WriteData(Text3[i]); }
#endif
  WriteCmd(0x80+0x40);  //Set in start of second line
#if Len2>0
  for(i=0;i<Len2;i++) { WriteData(Text2[i]); }
#endif
#if Len4>0
  for(i=0;i<Len4;i++) { WriteData(Text4[i]); }
#endif
}

void LCDinit(void) {
  LCD.E=0; Delay(>20ms);
//Set data pins for exit if needed
  LCD.RW=0; LCD.A0=0; LCD.D=0x30;  //8 bit interface setup
  Delay(>40ns);    //Pause
  LCD.E=1; Delay(>230ns);  //Время предустановки данных попало сюда
(tDSW)
  LCD.E=0; Delay(>40us);  //Пауза между командами
  LCD.E=1; Delay(>230ns);  //Минимально допустимая длительность сигнала
E=1
  LCD.E=0; Delay(>40us);  //Пауза между командами
  LCD.E=1; Delay(>230ns);
  LCD.E=0; Delay(>270ns);  //Минимально допустимый интервал между
сигналами E=1
//Здесь индикатор входит в рабочий режим с установленным типом
интерфейса и можно подавать команды как обычно
  WriteCmd(0x3A);    //Настройка правильного режима ЖКИ
  WriteCmd(0x0C);    //Включение индикатора, курсор выключен
  WriteCmd(0x01);    //LCD CLEAR
  WriteCmd(0x06);    //Установка режима ввода данных: сдвигать курсор
вправо
}

void WriteCmd(byte b) { WriteByte(b,0); }

void WriteData(byte b) { WriteByte(b,1); }

void WriteByte(byte b, bit cd) {
//Сначала проверим готовность индикатора
//При необходимости настроить здесь шину данных на ввод
  LCD.RW=1; LCD.A0=0;  //Чтение флага занятости
  Delay(>40ns);    //Это время предустановки адреса (tAS)
  LCD.E=1; Delay(>230ns);  //Это минимально допустимая длительность
сигнала E=1 (информация на шину данных индикатором будет выдана раньше,
не более чем через 120нс)
  while(LCD.D.7==1);  //Ждать сброса флага занятости
  LCD.E=0; Delay(>270ns);  //Минимально допустимый интервал между
сигналами E=1
//При необходимости настроить здесь шину данных на вывод
  LCD.RW=0; LCD.A0=cd; LCD.D=b;
  Delay(>40ns);    //Это время предустановки адреса (tAS)
  LCD.E=1; Delay(>230ns);  //Время предустановки данных попало сюда
(tDSW)
  LCD.E=0; Delay(>270ns);  //Минимально допустимый интервал между
сигналами E=1
}
Moderator
Dima Bulkin wrote:
> I would like to understand how to use constructions
> like LCD.E=1.

Theoretically this is possible with bitfields which are mapped to the
hardware-address of a register. But AFAIK gcc does not create "correct"
32-bit read/writes and may "optimize" to 8-bit which will throw an
exception. This issue has been mentioned in this forum before (several
month ago). There is a patch for this in the gcc bugzilla but it did not
work for me. I have asked the author of the patch and he admitted that
it is not correct. Have to add: I tested sometime in May or June so
maybe this is already fixed.

Also for GPIO the Target has to allow some kind of direct write to a
register (not just CLR/SET "Flip-Flop"-access). Most newer
ARM-controllers provide this. Better try to modify the downloaded code
and use some macros or inline-functions which can be easily modified for
different targets (hardware abstraction layer i.e. LCD_RW_LOW,
LCD_RW_HIGH etc.) so you do not need any specific compiler feature or
non-standard-extension (i.e. IAR ICCARM has an extension for this kind
of access). The "hal" will save you a lot of time later when you reuse
your components for another compiler/target.

Martin Thomas
Hi there

Martin Thomas wrote:
> Theoretically this is possible with bitfields which are mapped to the
> hardware-address of a register. But AFAIK gcc does not create "correct"
> 32-bit read/writes and may "optimize" to 8-bit which will throw an
> exception. This issue has been mentioned in this forum before (several
> month ago). There is a patch for this in the gcc bugzilla but it did not
> work for me.

I've run into this exact same problem, trying to configure my
peripherals via structures, containing bitfields. I'm running a ST
STR912, under GCC 4.3.1, Newlib, OpenOCD and Eclipse, options:
--target=arm-elf --with-cpu=arm966e-s

I've seen in the GCC compiler options page
(http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/ARM-Options.html#ARM-Options
and
http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/MCore-Options.html#MCore-Options)
that the MCore architecture has an option: -mwide-bitfields, that forces
the access to the bitfield address as an int. I think a similar options
should solve the problem for ARMs.

ARM has a similar compiler option, but I think that this applies to the
structure as a whole, and not individual members of the structure:
"
-mstructure-size-boundary=n
The size of all structures and unions will be rounded up to a multiple
of the number of bits set by this option...
"


Could you perhaps provide me with the bugzilla entry, so that I could
follow it up with the GCC authors?

BTW - could you see with newer GCCs if it was resolved?

Regards,
Frikkie Thirion
Martin Thomas wrote:
> Frikkie Thirion wrote:
>> Could you perhaps provide me with the bugzilla entry, so that I could
>> follow it up with the GCC authors?
> Please see the old thread: http://en.mikrocontroller.net/topic/81611#new
>
>> BTW - could you see with newer GCCs if it was resolved?
> Sorry, I don't know. I will try again once I have gcc 4.3.1 installed.

Thank you for the reply.
I've tested the bitfield accesses on the HiTex (www.hitex.com)
instruction set simulator: HiTOP 5 (with GCC 4.1.1), which is quite
good. I could see in the disassebled view in the debugger that the
assembler used to implement my C code is using "ldrb" and "strb", which
are byte accesses when I manipulate bitfield structures.

If I access the memory location with a 32-bit pointer, I could see in
the disassebled that "ldr" and "str" is used.

Maybe I should rethink my register accesses to move away from bitfields
all together - what a pitty...

Reply

A question of your own? This thread is over 19 years old. Ask it in a thread of its own – more people read along there, and it gets answered more often and sooner.

Start a new thread

A fix, an addition or feedback on this thread? Then reply here.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.