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 }
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
Thank you for advice, Martin. I will choose that way.
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
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.
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...
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.