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.
Not enough information. Please provide I minimal but complete example (source-code, linker-script, makefile) to reproduce the issue.
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.
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; }
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
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
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.
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?
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
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.
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
Log in with Google account
No account? Register here.