[En-Nut-Discussion] new to nutos usage (should be: LCD driver ...)

Ulrich Prinz uprinz2 at netscape.net
Fri Jun 25 22:59:10 CEST 2010


Hi!

As I said before, I didn't check with AVR as I don't have one running.
If you checked, and there is no driver for the AVR available, then you 
can simply take mine for reference and adopt it for AVR.

But making everything configurable like implementation of the AT91 
version is a bit of work and may not be easy for one who never did 
anything with Nut/OS before.

On the other hand it's one of the easy drivers so it is the right point 
to start your first driver for Nut/OS.

If you have any question, just feel welcomed to ask any time.

Best regards, Ulrich

Am 25.06.2010 10:45, schrieb Paolo Simoncelli:
>
>
> Hi all,
>
> Ulrich, thank you very much for your reply,
> In my previous message i was actually referring to the impossibility
> to change LCD wiring configuration via NutOS configurator,
> now it seems that the problem is that there's no HD44780 driver
> for AVR architecture,( am i right ? ) and just writing one will
> solve all the issues.
>
> ;-) In this case be prepared to some help request ...
>
> Ciao!
> Paolo
>
>
>
>
>> ------------------------------
>>
>> Message: 2
>> Date: Tue, 22 Jun 2010 18:45:59 +0200
>> From: Ulrich Prinz<uprinz2 at netscape.net>
>> Subject: Re: [En-Nut-Discussion] new to nutos usage
>> To: "Ethernut User Chat (English)"<en-nut-discussion at egnite.de>
>> Message-ID:<4C20E8C7.4030003 at netscape.net>
>> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>>
>> Hi!
>>
>> I wrote / reorganized the latest code for a character lcd on an at91
>> board like en3.x or EIR.
>> The driver is almost valid for any kind of CPU bus as I don't have any
>> AVR driven ethernut device, I cannot test. That's the reason why I kept
>> it in arch/arm/dev instead moving it to /dev.
>>
>> So if you take this driver as an example the porting should not be very
>> difficult.
>>
>> Best regards, Ulrich
>>
>> Am 21.06.2010 12:57, schrieb Paolo Simoncelli:
>>> Hi all,
>>>
>>> sorry zvonko, but i have had no good luck with LCD displays
>>> and ethernut, here is my experience:
>>>
>>>
>>> At first i haven't been able to make Jose's code work,
>>>
>>> it's using the builtin driver: (quite old post ...)
>>> http://lists.egnite.de/pipermail/en-nut-discussion/2007-March/007990.html
>>>
>>> maybe there's an open bug for that:
>>> http://sourceforge.net/tracker/?func=detail&aid=2995417&group_id=34079&atid=410687
>>> (BTW i will be glad to contribute for a fix ;-) )
>>>
>>> Next i went to the code reported on "Ethernut application note 001"
>>> but it did not even compiled at first (some editing needed,
>>> maybe it refers to old NutOS/Ethernut versions) anyway no luck at all :-(
>>>
>>> So, based on appnote001 sw&   hw wiring, i wrote my own code,
>>> here follows a basic example, i have left the appnote001 comments
>>> plus some spaghetti programming examples ;-)
>>> sorry for the long post hope it will help ! ciao !
>>>
>>>
>>>
>>>
>>> //  -- LCD ------------------------------------------------------------
>>>
>>>
>>> /*
>>> Instruction               Code                            Description
>>>                            D7  D6  D5  D4  D3  D2  D1  D0
>>> Clear display           0   0   0   0   0   0   0   1   Clears display and returns cursor to the home position (address 0).     1.64mS
>>> Cursor home               0   0   0   0   0   0   1   *     Returns cursor to home position (address 0). Also returns display being
>>> shifted to the original position. DDRAM contents remains unchanged.     1.64mS
>>> Entry mode set          0   0   0   0   0   1   I/D S   Sets cursor move direction (I/D), specifies to shift the display (S).
>>> These operations are performed during data read/write.  40uS
>>> Display On/Off control  0   0   0   0   1   D   C   B   Sets On/Off of all display (D), cursor On/Off (C) and blink of cursor
>>> position character (B).     40uS
>>> Cursor/display shift      0   0   0   1   S/C R/L *   *     Sets cursor-move or display-shift (S/C), shift direction (R/L). DDRAM
>>> contents remains unchanged.     40uS
>>> Function set              0   0   1   DL  N   F   *   *     Sets interface data length (DL), number of display line (N) and character
>>> font(F).    40uS
>>> Set CGRAM address       0   1   CGRAM address           Sets the CGRAM address. CGRAM data is sent and received after this
>>> setting.    40uS
>>> Set DDRAM address       1   DDRAM address               Sets the DDRAM address. DDRAM data is sent and received after this
>>> setting.    40uS
>>>
>>> Read busy-flag and address counter  0   1   BF  CGRAM / DDRAM address   Reads Busy-flag (BF) indicating internal operation is being
>>> performed and reads CGRAM or DDRAM address counter contents (depending on previous instruction).    0uS
>>> Write to CGRAM or DDRAM     1   0   write data  Writes data to CGRAM or DDRAM.  40uS
>>> Read from CGRAM or DDRAM    1   1   read data   Reads data from CGRAM or DDRAM.     40uS
>>> Remarks:
>>>
>>> */
>>>
>>>
>>> // HD44780 Commandset
>>>
>>> //  01h     Clear display
>>> #define LCD_CLR             0      // DB0: clear display
>>>
>>> //  02h or 03h  Return cursor home
>>> #define LCD_HOME            1      // DB1: return to home position
>>>
>>> //  04h 05h 06h 07h Entry mode set
>>> #define LCD_ENTRY_MODE      2      // DB2: set entry mode
>>> #define LCD_ENTRY_INC       1      //   DB1: increment
>>> #define LCD_ENTRY_SHIFT     0      //   DB2: shift
>>>
>>> //  08h 09h 0Ah 0Bh   0Ch 0Dh 0Eh 0Fh  Display/Cursor ON OFF
>>> #define LCD_ON_CTRL         3      // DB3: turn lcd/cursor on
>>> #define LCD_ON_DISPLAY      2      //   DB2: turn display on
>>> #define LCD_ON_CURSOR       1      //   DB1: turn cursor on
>>> #define LCD_ON_BLINK        0      //   DB0: blinking cursor
>>>
>>> #define LCD_MOVE            4      // DB4: move cursor/display
>>> #define LCD_MOVE_DISP       3      //   DB3: move display (0->   move cursor)
>>> #define LCD_MOVE_RIGHT      2      //   DB2: move right (0->   left)
>>>
>>> #define LCD_FUNCTION        5      // DB5: function set
>>> #define LCD_FUNCTION_8BIT   4      //   DB4: set 8BIT mode (0->4BIT mode)
>>> #define LCD_FUNCTION_2LINES 3      //   DB3: two lines (0->one line)
>>> #define LCD_FUNCTION_RE     2      //   DB2: KS0073 Controller: Extended Register
>>> #define LCD_FUNCTION_10DOTS 2      //   DB2: 5x10 font (0->5x7 font)
>>> #define LCD_FUNCTION_DS     1      //   DB1: DisplayShift / DotScroll
>>> #define LCD_FUNCTION_REV    0      //   DB0: Reverse Display
>>>
>>> #define LCD_EXT             3      // DB3: Extended Register Set
>>> #define LCD_EXT_FONT        2      //   DB2: Fontwidth: 5 / 6 Pixel
>>> #define LCD_EXT_INVCURS     1      //   DB1: Normal / Inverted Cursor
>>> #define LCD_EXT_4LINES      0      //   DB0: 1/2 Lines (normal) or 4Lines
>>>
>>> #define LCD_CGRAM           6      // DB6: set CG RAM address
>>>
>>> #define LCD_DDRAM           7      // DB7: set DD RAM address
>>> // reading:
>>> #define LCD_BUSY            7      // DB7: LCD is busy
>>>
>>>
>>>
>>> //  Initializing the LCD
>>> //  Some definitions first. As we find in the schematic, the LCD data port is connected to
>>> //  the upper 4 bits of port D.
>>>
>>> #define LCD_DATA_DDR DDRD
>>> #define LCD_DATA_PORT PORTD
>>>
>>> //  The two control lines are connected to bits 2 and 3 of port E.
>>>
>>> #define LCD_CTRL_DDR DDRE
>>> #define LCD_CTRL_PORT PORTE
>>> #define LCD_CTRL_E PE3
>>> #define LCD_CTRL_RS PE2
>>> #define LCD_CTRL_RW PE4
>>>
>>> //  The LCD backlight is controlled by bit 6 on port B. (no backlight for now ...)
>>>
>>> // #define LCD_LIGHT_DDR DDRB
>>> // #define LCD_LIGHT_PORT PORTB
>>> // #define LCD_LIGHT_BIT PB6
>>>
>>> //  Various delays
>>>
>>> #define LCD_PWRON_DELAY 10
>>> #define LCD_INIT_DELAY 4
>>> #define LCD_LONG_DELAY 2
>>> #define LCD_SHORT_DELAY 1
>>>
>>>
>>>
>>> //  Controlling the LCD
>>> //  The initialization routine already uses other subroutines to send data bytes and
>>> //  instructions to the LCD controller. Remember, that we drive the LCD in 4 bit mode. A
>>> //  special routine named LcdSendNibble will send the upper four bits of a character
>>> //  variable to the LCD data port. It sets the data lines and toggles the enable line.
>>>
>>> static inline void LcdSendNibble(u_char nib)
>>> {
>>>        outp((inp(LCD_DATA_PORT)&   0x0F) | (nib&   0xF0), LCD_DATA_PORT);
>>>        sbi(LCD_CTRL_PORT, LCD_CTRL_E);
>>>        asm volatile("nop\n\tnop");
>>>        cbi(LCD_CTRL_PORT, LCD_CTRL_E);
>>> }
>>>
>>>
>>>
>>> //  Another routine called LcdSendByte sends a complete byte to the LCD controller by
>>> //  calling LcdSendNibble twice.
>>>
>>> static inline void LcdSendByte(u_char ch, u_char xt)
>>> {
>>>        LcdSendNibble(ch&   0xF0);
>>>        LcdSendNibble(ch<<   4);
>>>        NutDelay(xt);
>>> }
>>>
>>>
>>>
>>> //  Finally two additional routines are provided to either send an instruction or a data byte.
>>> //  Note, that only instructions need a specific delay time.
>>>
>>> static void LcdWriteCmd(u_char cmd, u_char xt)
>>> {
>>>        cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
>>>        LcdSendByte(cmd, xt);
>>> }
>>>
>>> void LcdWriteChar(u_char ch)
>>> {
>>>        sbi(LCD_CTRL_PORT, LCD_CTRL_RS);
>>>        LcdSendByte(ch,LCD_SHORT_DELAY);
>>> }
>>>
>>>
>>> void LcdWriteS(char *ch)
>>> {
>>> int i;
>>> char c;
>>>
>>>        i=0;
>>>        while((c=ch[i++])>0){
>>>            LcdWriteChar(c);
>>>        }
>>> }
>>>
>>>
>>> //  One of the most often used instructions to be send to the display is the clear
>>> //  command, which blanks the display. A special routine LcdClear will do this.
>>>
>>> void LcdClear(void)
>>> {
>>>        LcdWriteCmd(LCD_HOME,LCD_LONG_DELAY);
>>> }
>>>
>>>
>>> //  The initialization routine uses another command routine named LcdSwitch, which
>>> //  switches on and off certain mode bits in the LCD controller.
>>>
>>> void LcdSwitch(u_char on, u_char off)
>>> {
>>> //      switch_control |= on&   LCD_SWITCH_ALL;
>>> //      switch_control&= ~(off&   LCD_SWITCH_ALL);
>>> //      LcdWriteCmd(switch_control, LCD_SHORT_DELAY);
>>> }
>>>
>>>
>>> //  When calling LcdWriteChar instead of LcdWriteCmd, the characters of the specified
>>> //  codes are displayed and the cursor is automatically advanced to the next character
>>> //  position. In addition to the normal 7 bit ASCII character set the controller can display
>>> //  many other characters. It is even possible to define up to 8 custom characters, which
>>> //  however isn't explained in this application note.
>>>
>>>
>>>
>>> //  The LCD controller doesn't support cursor positioning on a specific column or row, but
>>> //  requires a memory address. This is not a big deal on 2 line displays, but address
>>> //  locations for the third and the second row depend on the number of columns being
>>> //  displayed. On 4 line displays with 16 columns each, the values are:
>>>
>>> //  #define LCD_ROW2_START 0x10
>>> //  #define LCD_ROW3_START 0x50
>>> #define LCD_ROW2_START 0x14
>>> #define LCD_ROW3_START 0x54
>>>
>>>
>>> //  Another routine called LcdSetCursor may be used to place the cursor to a specific
>>> //  position.
>>>
>>> void LcdSetCursor(u_char row, u_char col)
>>> {
>>> u_char row_start[] = { 0x00, 0x40, LCD_ROW2_START, LCD_ROW3_START };
>>>
>>>        LcdWriteCmd(0x80 | row_start[row&   0x03] | col, LCD_SHORT_DELAY);
>>> }
>>>
>>>
>>>
>>> //   routine called LcdSetCursor may be used to place the cursor to a specific
>>> //  position.
>>>
>>> void LcdWriteAt(u_char row, u_char col, char *ch)
>>> {
>>>        LcdSetCursor(row,col);
>>>        LcdWriteS(ch);
>>> }
>>>
>>>
>>>
>>> // A single routine is used to initialize all I/O lines and setup the LCD. Most notable is the
>>> //  for loop somewhere in the middle of the routine. When the LCD is powered up, the
>>> //  LCD controller will start in 8 bit mode. Switching it into 4 bit mode requires a specific
>>> //  command sequence. The loop will send three nibbles of value 3, two of value 2 and
>>> //  finally of value 8.
>>>
>>> void LcdInit(void)
>>> {
>>> u_char i;
>>>
>>>
>>> /*
>>> * Set LCD read write low.
>>> */
>>>        cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
>>>        sbi(LCD_CTRL_DDR, LCD_CTRL_RW);
>>>
>>> /*
>>> * Set LCD register select low.
>>> */
>>>        cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
>>>        sbi(LCD_CTRL_DDR, LCD_CTRL_RS);
>>>
>>> /*
>>> * Set LCD enable low.
>>> */
>>>        cbi(LCD_CTRL_PORT, LCD_CTRL_E);
>>>        sbi(LCD_CTRL_DDR, LCD_CTRL_E);
>>>
>>> /*
>>> * Set direction register of LCD data port.
>>> */
>>>        sbi(LCD_DATA_DDR, 4);
>>>        sbi(LCD_DATA_DDR, 5);
>>>        sbi(LCD_DATA_DDR, 6);
>>>        sbi(LCD_DATA_DDR, 7);
>>>
>>> /*
>>> * Initialize for 4-bit operation.
>>> */
>>>        NutDelay(LCD_PWRON_DELAY);
>>>        for(i = 0;i<3; i++){
>>>            LcdSendNibble(0x30);
>>>            NutDelay(LCD_INIT_DELAY);
>>>        }
>>>
>>>        LcdSendNibble(0x20);
>>>        NutDelay(LCD_SHORT_DELAY);
>>>
>>> /*
>>> * 4-bit mode, 2/4 lines, 5x7 matrix.
>>> */
>>>        LcdWriteCmd(0x28,LCD_SHORT_DELAY);
>>>
>>> /*
>>> * Switch display, cursor and cursor blinking off.
>>> */
>>> //      LcdSwitch(0, LCD_SWITCH_ALL);
>>>
>>> /*
>>> * Clear display.
>>> */
>>>        LcdClear();
>>>
>>> /*
>>> * Increment cursor when writing.
>>> */
>>>        LcdWriteCmd((1<<LCD_ENTRY_MODE|1<<LCD_ENTRY_INC|0<<LCD_ENTRY_SHIFT),LCD_SHORT_DELAY);
>>>
>>> /*
>>> * Set cursor appearance
>>> */
>>>        LcdWriteCmd((1<<LCD_ON_CTRL|1<<LCD_ON_DISPLAY|1<<LCD_ON_CURSOR|1<<LCD_ON_BLINK),LCD_SHORT_DELAY);
>>>
>>>
>>> /*
>>> * Lit LED and switch display on.
>>> */
>>> //    sbi(LCD_LIGHT_DDR, LCD_LIGHT_BIT);
>>> //    sbi(LCD_LIGHT_PORT, LCD_LIGHT_BIT);
>>> //    LcdSwitch(LCD_SWITCH_DISPLAY, 0);
>>>
>>> }
>>>
>>>
>>> //  -- END LCD --------------------------------------------------------
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>    --
>>>    Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP autenticato? GRATIS solo con Email.it http://www.email.it/f
>>>
>>>    Sponsor:
>>>    Sardegna - Stintino Club Hotel CALA ROSA, 4 stelle. Situato in parco di 4  ettari, dotato dei migliori servizi. dal 24/7 al 31/7 SETTE giorni TUTTO COMPRESO Euro 690
>>>    Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=10590&d=21-6
>>> _______________________________________________
>>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>>
>>
>> ------------------------------
>>
>> _______________________________________________
>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>>
>>
>> End of En-Nut-Discussion Digest, Vol 80, Issue 15
>> *************************************************
>>
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion



More information about the En-Nut-Discussion mailing list