EmbDev.net

Forum: ARM programming with GCC/GNU tools Bag in gcc?


von Dima B. (mrengineer)


Rate this post
useful
not useful
Hello All,

looks like there is bag in gcc compiler

I spent 3 days trying init LCD display. I wrote init procedure where
used
this
#define OFF  pPIO->PIO_CODR
#define ON  pPIO->PIO_SODR

and OFF  = LED_MASK; where
#define LED_MASK (LED1|DB0|DB1|DB2|DB3|A0|RW|E|DB7|DB6|DB5|DB4) is very
long. And it does not work until I canged LED_MASK to group of comands
like
OFF = DB0;
OFF = DB1; ... etc

Looks like there is an error if MASK is too big.

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Not enough information. Please provide I minimal but complete example
(source-code, linker-script, makefile) to reproduce the issue.

von Clifford S. (clifford)


Rate this post
useful
not useful
You mean a "bug" not a "bag", and I doubt it. Given the many millions of
working lines of GCC code that exist in the world, the maturity of the
compiler, and the simplicity of construct you have described, Occam's
Razor would suggest that the error was in your code, but since you never
posted it, we can't tell.

You must make sure that the PIO structure members are declared volatile,
otherwise an access may get optimized out.

Since you have posted before I know you are using a AT91SAM7S64, but you
should have mentioned that also; ARM just describes the processor core,
not the peripheral devices or memory architecture.

von Dima B. (mrengineer)


Rate this post
useful
not useful
Well Here is LCD.c



#include "AT91SAM7S64.h"
#include "board.h"

#define ShortDelay 4

extern  void delay(unsigned long ms);

char Text [20] = "OK";
//char Prev [20] = "";


void LCD_Init (void) {
  volatile AT91PS_PIO  pPIO = AT91C_BASE_PIOA;      // pointer to PIO
data structure
  pPIO->PIO_PER   = LED_MASK;              // PIO Enable Register -
allow PIO to control pins P0 - P3 and pin 19
  pPIO->PIO_OER   = LED_MASK;              // PIO Output Enable Register
- sets pins P0 - P3 to outputs
  OFF  = LED_MASK;                    // PIO Set Output Data Register -
turns off


  delay(15);

  OFF  = LED_MASK;

  int j = 0;
  for (j = 3; j != 0; j-- ) {
    ON = DB5;  ON = DB4;  ON = E;
    delay(100);
    OFF = E;  OFF = DB5;  OFF = DB4;
  }

  for (j = 2; j != 0; j-- ) {
    ON = DB5;  ON = DB4;  ON = DB3;  ON = E;
    delay(100);
    OFF = E;  OFF = DB5;  OFF = DB4;  OFF = DB3;
  }

  ON = DB0;  ON = E;
  delay(10);
  OFF = E;  OFF = DB0;


  ON = DB2;   ON = DB1;  ON = E;
  delay(150);
  OFF = E;   OFF = DB2;  OFF = DB1;

// МИГАЮЩИЙ КУРСОР
  //ON = DB0;
  ON = DB3;
  ON = DB2;
  OFF = DB1;
  ON = E;
  delay(100);
  OFF = E;
  //OFF = DB1;
  OFF = DB3;
  OFF = DB2;
  OFF = DB1;

}

void LCD_Print(char c) {
  volatile AT91PS_PIO  pPIO = AT91C_BASE_PIOA;

ON = A0;

if (c == 0) c=32;

if ((c & 1)   != 0)    ON = DB0;   else  OFF     = DB0;
if ((c & 2)   != 0)    ON = DB1;  else  OFF     = DB1;
if ((c & 4)   != 0)    ON = DB2;  else  OFF  = DB2;
if ((c & 8)   != 0)    ON = DB3;  else  OFF  = DB3;
if ((c & 16)  != 0)    ON = DB4;  else  OFF  = DB4;
if ((c & 32)  != 0)    ON = DB5;  else  OFF  = DB5;
if ((c & 64)  != 0)    ON = DB6;  else  OFF  = DB6;
if ((c & 128) != 0)    ON = DB7;  else  OFF  = DB7;

ON = E;
delay(ShortDelay);
OFF = E;
OFF = A0;
OFF = DB0;
OFF = DB1;
OFF = DB2;
OFF = DB3;
OFF = DB4;
OFF = DB5;
OFF = DB6;
OFF = DB7;
delay(ShortDelay);
}

void LCD_Clean (void) {
  volatile AT91PS_PIO  pPIO = AT91C_BASE_PIOA;

  ON = DB0;
  ON = E;
  delay(ShortDelay);
  OFF = E;
  OFF = DB0;
  delay(ShortDelay);
}

void LCD_GotoLeft (void) {
  volatile AT91PS_PIO  pPIO = AT91C_BASE_PIOA;

  ON = DB1;
  ON = E;
  delay(ShortDelay);
  OFF = E;
  OFF = DB0;
  delay(ShortDelay);
}

void LCD_Redraw (void) {



  LCD_Clean();

  int i = 0;

  for (i=0; i != 10; i++ ) {
    LCD_Print(Text[i]);
  }
  delay(ShortDelay);

  Skip:
  return;
}

von Dima B. (mrengineer)


Rate this post
useful
not useful
And here is board.h


#ifndef Board_h
#define Board_h

#include "AT91SAM7S64.h"
#define __inline inline

#define true  -1
#define false  0

//-----------------------------------------------
// SAM7Board Memories Definition
//-----------------------------------------------
// The AT91SAM7S2564 embeds a 64-Kbyte SRAM bank, and 256 K-Byte Flash

#define  INT_SRAM      0x00200000
#define  INT_SRAM_REMAP    0x00000000

#define  INT_FLASH      0x00000000
#define  INT_FLASH_REMAP  0x01000000

#define  FLASH_PAGE_NB    512
#define  FLASH_PAGE_SIZE  128

//------------------------
// Leds Definition
//------------------------
#define LED1      (1<<8)            // LED on pcb

#define DB0        (1<<0)            // LCD DB0 pin is connected to PA0
of MC
#define DB1        (1<<1)            // LCD DB1 pin
#define DB2        (1<<2)            // LCD DB2 pin
#define DB3        (1<<3)
#define A0        (1<<4)
#define RW        (1<<5)
#define E        (1<<6)
#define DB7        (1<<7)
#define DB6        (1<<9)
#define DB5        (1<<10)
#define DB4        (1<<11)

#define NB_LEB      12
#define LED_MASK    (LED1|DB0|DB1|DB2|DB3|A0|RW|E|DB7|DB6|DB5|DB4)

#define OFF  pPIO->PIO_CODR
#define ON  pPIO->PIO_SODR


//--------------
// Master Clock
//--------------
#define EXT_OC    18432000            // Exetrnal ocilator MAINCK
#define MCK      47923200            // MCK (PLLRC div by 2)
#define MCKKHz    (MCK/1000)               //

#endif   // Board_h

von Dima B. (mrengineer)


Rate this post
useful
not useful
This code is working good. If in LCD_Print() I change

OFF = E;
OFF = A0;
OFF = DB0;
OFF = DB1;
OFF = DB2;
OFF = DB3;
OFF = DB4;
OFF = DB5;
OFF = DB6;
OFF = DB7;

to

OFF = LED_MASK;

it will not work. LCD will show something strange.

And if I write

OFF = (DB0|DB1|DB2|DB3|A0|RW|E|DB7|DB6|DB5|DB4);

result will be the same

von Clifford S. (clifford)


Rate this post
useful
not useful
Dima Bulkin wrote:

> OFF = LED_MASK;
>
> it will not work. LCD will show something strange.
>
Ah! that is not the same thing as a compiler bug! Have you checked the
actual hardware outputs with a scope or logic analyzer? If the outputs
are cleared, then the code has by definition worked - you need to check
that before before you can blame the compiler.

This looks like a hardware timing issue, are you sure that clearing all
these inputs simultaneously is a valid input to the LCD hardware? Check
the timing diagrams or specifications.

von Clifford S. (clifford)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Ah! that is not the same thing as a compiler bug! Have you checked the
> actual hardware outputs with a scope or logic analyzer?

... or logic probe, or even a simple multimeter?

von Dima B. (mrengineer)


Rate this post
useful
not useful
Clifford Slocombe wrote:
> Clifford Slocombe wrote:
>> Ah! that is not the same thing as a compiler bug! Have you checked the
>> actual hardware outputs with a scope or logic analyzer?
>
> ... or logic probe, or even a simple multimeter?

I have only multimeter now and it shows all right... o_O
But when I used this LCD with PIC and PIC C I write code to off/on all
pins together and it was ok.

I understand nothing

von Clifford S. (clifford)


Rate this post
useful
not useful
Dima Bulkin wrote:
> I have only multimeter now and it shows all right... o_O
> But when I used this LCD with PIC and PIC C I write code to off/on all
> pins together and it was ok.
Possibilities: Board/wiring fault, slow edges due to capacitance, subtle
timing differences between lines due to wiring/interfacing, incorrect
voltage levels, transient voltage drop due to excessive current draw,
permanent voltage drop due to excessive current draw, incorrect line
pull-up or pull-down.

Either way, not a compiler fault, the output is correct as you coded it.

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Maybe just an problem with the handling of the enable signal for the
LCD-controller. You may want to read the lcd-controller's datasheet
again and look for the timing diagramms. Also check the level on which
"Enable" is active. Try to set all pins before toggeling the enable line
(so remove "E" from the mask, set your "OFF" with the remaining mask and
handle just E in an extra instruction.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.