st7036_at91.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log: st7036_at91.c,v $
00036  * Revision 1.1  2007/02/15 16:09:07  haraldkipp
00037  * Tested with EA DOG-M LCDs.
00038  *
00039  */
00040 
00041 #include <cfg/arch.h>
00042 #include <cfg/arch/gpio.h>
00043 #include <cfg/lcd.h>
00044 
00045 #include <stdlib.h>
00046 #include <string.h>
00047 
00048 #include <sys/nutconfig.h>
00049 #include <dev/st7036.h>
00050 #include <dev/term.h>
00051 #include <sys/timer.h>
00052 
00053 #ifndef LCD_ROWS
00054 #define LCD_ROWS    2
00055 #endif
00056 
00057 #ifndef LCD_COLS
00058 #define LCD_COLS    16
00059 #endif
00060 
00061 #ifndef LCD_SHORT_DELAY
00062 #define LCD_SHORT_DELAY 100
00063 #endif
00064 
00065 #ifndef LCD_LONG_DELAY
00066 #define LCD_LONG_DELAY  1000
00067 #endif
00068 
00072 #if defined(AT91SAM7X_EK)
00073 
00074 #ifndef LCD_CS_PIO_ID
00075 #define LCD_CS_PIO_ID   PIOB_ID
00076 #endif
00077 #ifndef LCD_CS_BIT
00078 #define LCD_CS_BIT      24
00079 #endif
00080 
00081 #ifndef LCD_RS_PIO_ID
00082 #define LCD_RS_PIO_ID   PIOB_ID
00083 #endif
00084 #ifndef LCD_RS_BIT
00085 #define LCD_RS_BIT      23
00086 #endif
00087 
00088 #ifndef LCD_CLK_PIO_ID
00089 #define LCD_CLK_PIO_ID  PIOA_ID
00090 #endif
00091 #ifndef LCD_CLK_BIT
00092 #define LCD_CLK_BIT     18
00093 #endif
00094 
00095 #ifndef LCD_MOSI_PIO_ID
00096 #define LCD_MOSI_PIO_ID PIOA_ID
00097 #endif
00098 #ifndef LCD_MOSI_BIT
00099 #define LCD_MOSI_BIT    17
00100 #endif
00101 
00102 #elif defined(AT91SAM9260_EK)
00103 
00104 #ifndef LCD_CS_PIO_ID
00105 #define LCD_CS_PIO_ID   PIOB_ID
00106 #endif
00107 #ifndef LCD_CS_BIT
00108 #define LCD_CS_BIT      11
00109 #endif
00110 
00111 #ifndef LCD_RS_PIO_ID
00112 #define LCD_RS_PIO_ID   PIOB_ID
00113 #endif
00114 #ifndef LCD_RS_BIT
00115 #define LCD_RS_BIT      20
00116 #endif
00117 
00118 #ifndef LCD_CLK_PIO_ID
00119 #define LCD_CLK_PIO_ID  PIOB_ID
00120 #endif
00121 #ifndef LCD_CLK_BIT
00122 #define LCD_CLK_BIT     2
00123 #endif
00124 
00125 #ifndef LCD_MOSI_PIO_ID
00126 #define LCD_MOSI_PIO_ID PIOB_ID
00127 #endif
00128 #ifndef LCD_MOSI_BIT
00129 #define LCD_MOSI_BIT    1
00130 #endif
00131 
00132 #else
00133 
00134 #ifndef LCD_CS_PIO_ID
00135 #define LCD_CS_PIO_ID   PIO_ID
00136 #endif
00137 #ifndef LCD_CS_BIT
00138 #define LCD_CS_BIT      0
00139 #endif
00140 
00141 #ifndef LCD_RS_PIO_ID
00142 #define LCD_RS_PIO_ID   PIO_ID
00143 #endif
00144 #ifndef LCD_RS_BIT
00145 #define LCD_RS_BIT      3
00146 #endif
00147 
00148 #ifndef LCD_CLK_PIO_ID
00149 #define LCD_CLK_PIO_ID  PIO_ID
00150 #endif
00151 #ifndef LCD_CLK_BIT
00152 #define LCD_CLK_BIT     1
00153 #endif
00154 
00155 #ifndef LCD_MOSI_PIO_ID
00156 #define LCD_MOSI_PIO_ID PIO_ID
00157 #endif
00158 #ifndef LCD_MOSI_BIT
00159 #define LCD_MOSI_BIT    2
00160 #endif
00161 
00162 #endif
00163 
00164 #define LCD_CS      _BV(LCD_CS_BIT)
00165 #define LCD_RS      _BV(LCD_RS_BIT)
00166 #define LCD_CLK     _BV(LCD_CLK_BIT)
00167 #define LCD_MOSI    _BV(LCD_MOSI_BIT)
00168 
00169 
00170 #if LCD_CS_PIO_ID == PIOA_ID
00171 #define LCD_CS_SET() { outr(PIOA_PER, LCD_CS); outr(PIOA_SODR, LCD_CS); outr(PIOA_OER, LCD_CS); }
00172 #define LCD_CS_CLR() { outr(PIOA_PER, LCD_CS); outr(PIOA_CODR, LCD_CS); outr(PIOA_OER, LCD_CS); }
00173 #elif LCD_CS_PIO_ID == PIOB_ID
00174 #define LCD_CS_SET() { outr(PIOB_PER, LCD_CS); outr(PIOB_SODR, LCD_CS); outr(PIOB_OER, LCD_CS); }
00175 #define LCD_CS_CLR() { outr(PIOB_PER, LCD_CS); outr(PIOB_CODR, LCD_CS); outr(PIOB_OER, LCD_CS); }
00176 #elif LCD_CS_PIO_ID == PIOC_ID
00177 #define LCD_CS_SET() { outr(PIOC_PER, LCD_CS); outr(PIOC_SODR, LCD_CS); outr(PIOC_OER, LCD_CS); }
00178 #define LCD_CS_CLR() { outr(PIOC_PER, LCD_CS); outr(PIOC_CODR, LCD_CS); outr(PIOC_OER, LCD_CS); }
00179 #else
00180 #define LCD_CS_SET() { outr(PIO_PER, LCD_CS); outr(PIO_SODR, LCD_CS); outr(PIO_OER, LCD_CS); }
00181 #define LCD_CS_CLR() { outr(PIO_PER, LCD_CS); outr(PIO_CODR, LCD_CS); outr(PIO_OER, LCD_CS); }
00182 #endif
00183 
00184 #if LCD_RS_PIO_ID == PIOA_ID
00185 #define LCD_RS_SET() { outr(PIOA_PER, LCD_RS); outr(PIOA_SODR, LCD_RS); outr(PIOA_OER, LCD_RS); }
00186 #define LCD_RS_CLR() { outr(PIOA_PER, LCD_RS); outr(PIOA_CODR, LCD_RS); outr(PIOA_OER, LCD_RS); }
00187 #elif LCD_RS_PIO_ID == PIOB_ID
00188 #define LCD_RS_SET() { outr(PIOB_PER, LCD_RS); outr(PIOB_SODR, LCD_RS); outr(PIOB_OER, LCD_RS); }
00189 #define LCD_RS_CLR() { outr(PIOB_PER, LCD_RS); outr(PIOB_CODR, LCD_RS); outr(PIOB_OER, LCD_RS); }
00190 #elif LCD_RS_PIO_ID == PIOC_ID
00191 #define LCD_RS_SET() { outr(PIOC_PER, LCD_RS); outr(PIOC_SODR, LCD_RS); outr(PIOC_OER, LCD_RS); }
00192 #define LCD_RS_CLR() { outr(PIOC_PER, LCD_RS); outr(PIOC_CODR, LCD_RS); outr(PIOC_OER, LCD_RS); }
00193 #else
00194 #define LCD_RS_SET() { outr(PIO_PER, LCD_RS); outr(PIO_SODR, LCD_RS); outr(PIO_OER, LCD_RS); }
00195 #define LCD_RS_CLR() { outr(PIO_PER, LCD_RS); outr(PIO_CODR, LCD_RS); outr(PIO_OER, LCD_RS); }
00196 #endif
00197 
00198 #if LCD_CLK_PIO_ID == PIOA_ID
00199 #define LCD_CLK_SET() { outr(PIOA_PER, LCD_CLK); outr(PIOA_SODR, LCD_CLK); outr(PIOA_OER, LCD_CLK); }
00200 #define LCD_CLK_CLR() { outr(PIOA_PER, LCD_CLK); outr(PIOA_CODR, LCD_CLK); outr(PIOA_OER, LCD_CLK); }
00201 #elif LCD_CLK_PIO_ID == PIOB_ID
00202 #define LCD_CLK_SET() { outr(PIOB_PER, LCD_CLK); outr(PIOB_SODR, LCD_CLK); outr(PIOB_OER, LCD_CLK); }
00203 #define LCD_CLK_CLR() { outr(PIOB_PER, LCD_CLK); outr(PIOB_CODR, LCD_CLK); outr(PIOB_OER, LCD_CLK); }
00204 #elif LCD_CLK_PIO_ID == PIOC_ID
00205 #define LCD_CLK_SET() { outr(PIOC_PER, LCD_CLK); outr(PIOC_SODR, LCD_CLK); outr(PIOC_OER, LCD_CLK); }
00206 #define LCD_CLK_CLR() { outr(PIOC_PER, LCD_CLK); outr(PIOC_CODR, LCD_CLK); outr(PIOC_OER, LCD_CLK); }
00207 #else
00208 #define LCD_CLK_SET() { outr(PIO_PER, LCD_CLK); outr(PIO_SODR, LCD_CLK); outr(PIO_OER, LCD_CLK); }
00209 #define LCD_CLK_CLR() { outr(PIO_PER, LCD_CLK); outr(PIO_CODR, LCD_CLK); outr(PIO_OER, LCD_CLK); }
00210 #endif
00211 
00212 #if LCD_MOSI_PIO_ID == PIOA_ID
00213 #define LCD_MOSI_SET() { outr(PIOA_PER, LCD_MOSI); outr(PIOA_SODR, LCD_MOSI); outr(PIOA_OER, LCD_MOSI); }
00214 #define LCD_MOSI_CLR() { outr(PIOA_PER, LCD_MOSI); outr(PIOA_CODR, LCD_MOSI); outr(PIOA_OER, LCD_MOSI); }
00215 #elif LCD_MOSI_PIO_ID == PIOB_ID
00216 #define LCD_MOSI_SET() { outr(PIOB_PER, LCD_MOSI); outr(PIOB_SODR, LCD_MOSI); outr(PIOB_OER, LCD_MOSI); }
00217 #define LCD_MOSI_CLR() { outr(PIOB_PER, LCD_MOSI); outr(PIOB_CODR, LCD_MOSI); outr(PIOB_OER, LCD_MOSI); }
00218 #elif LCD_MOSI_PIO_ID == PIOC_ID
00219 #define LCD_MOSI_SET() { outr(PIOC_PER, LCD_MOSI); outr(PIOC_SODR, LCD_MOSI); outr(PIOC_OER, LCD_MOSI); }
00220 #define LCD_MOSI_CLR() { outr(PIOC_PER, LCD_MOSI); outr(PIOC_CODR, LCD_MOSI); outr(PIOC_OER, LCD_MOSI); }
00221 #else
00222 #define LCD_MOSI_SET() { outr(PIO_PER, LCD_MOSI); outr(PIO_SODR, LCD_MOSI); outr(PIO_OER, LCD_MOSI); }
00223 #define LCD_MOSI_CLR() { outr(PIO_PER, LCD_MOSI); outr(PIO_CODR, LCD_MOSI); outr(PIO_OER, LCD_MOSI); }
00224 #endif
00225 
00230 
00241 static void LcdDelay(u_int cycles)
00242 {
00243     while (cycles--) {
00244         _NOP(); _NOP(); _NOP(); _NOP();
00245         _NOP(); _NOP(); _NOP(); _NOP();
00246         _NOP(); _NOP(); _NOP(); _NOP();
00247         _NOP(); _NOP(); _NOP(); _NOP();
00248         _NOP(); _NOP(); _NOP(); _NOP();
00249         _NOP(); _NOP(); _NOP(); _NOP();
00250         _NOP(); _NOP(); _NOP(); _NOP();
00251         _NOP(); _NOP(); _NOP(); _NOP();
00252         _NOP(); _NOP(); _NOP(); _NOP();
00253         _NOP(); _NOP(); _NOP(); _NOP();
00254         _NOP(); _NOP(); _NOP(); _NOP();
00255         _NOP(); _NOP(); _NOP(); _NOP();
00256     }
00257 }
00258 
00259 #if 0
00260 static void INLINE LcdSetBits(u_int mask)
00261 {
00262     outr(LCD_PIO_SOD_REG, mask);
00263     outr(LCD_PIO_OE_REG, mask);
00264 }
00265 
00266 static void INLINE LcdClrBits(u_int mask)
00267 {
00268     outr(LCD_PIO_COD_REG, mask);
00269     outr(LCD_PIO_OE_REG, mask);
00270 }
00271 #endif
00272 
00273 static void LcdWaitReady(u_int delay)
00274 {
00275     while (delay--) {
00276         _NOP();
00277     }
00278 }
00279 
00285 static void LcdWriteByte(u_int data)
00286 {
00287     u_char msk = 0x80;
00288 
00289     while (msk) {
00290         LCD_CLK_CLR();
00291         if (data & msk) {
00292             LCD_MOSI_SET();
00293         } else {
00294             LCD_MOSI_CLR();
00295         }
00296         LCD_CLK_SET();
00297         msk >>= 1;
00298         LcdDelay(1);
00299     }
00300     LcdWaitReady(LCD_LONG_DELAY);
00301 }
00302 
00308 static void LcdWriteCmd(u_char cmd)
00309 {
00310     /* RS low selects instruction register. */
00311     LCD_CS_CLR();
00312     LcdDelay(LCD_SHORT_DELAY);
00313     LCD_RS_CLR();
00314     LcdDelay(LCD_SHORT_DELAY);
00315     LcdWriteByte(cmd);
00316     LcdDelay(LCD_SHORT_DELAY);
00317     LCD_RS_SET();
00318     LcdDelay(LCD_SHORT_DELAY);
00319     LCD_CS_SET();
00320     LcdDelay(LCD_SHORT_DELAY);
00321 }
00322 
00323 static void LcdWriteInstruction(u_char cmd, u_char xt)
00324 {
00325     LcdWriteCmd(cmd);
00326 }
00327 
00333 static void LcdWriteData(u_char data)
00334 {
00335     /* RS high selects data register. */
00336     LCD_CS_CLR();
00337     LcdDelay(LCD_SHORT_DELAY);
00338     LCD_RS_SET();
00339     LcdDelay(LCD_SHORT_DELAY);
00340     LcdWriteByte(data);
00341     LcdDelay(LCD_SHORT_DELAY);
00342     LCD_CS_SET();
00343     LcdDelay(LCD_SHORT_DELAY);
00344 }
00345 
00346 static void LcdSetCursor(u_char pos)
00347 {
00348     u_char offset[] = {
00349         0x00, 0x40, 0x10, 0x50
00350     };
00351 
00352     pos = offset[(pos / LCD_COLS) % LCD_ROWS] + pos % LCD_COLS;
00353     LcdWriteCmd(0x80 | pos);
00354 }
00355 
00356 static void LcdCursorHome(void)
00357 {
00358     LcdWriteCmd(0x02);
00359     LcdDelay(10 * LCD_LONG_DELAY);
00360 }
00361 
00362 static void LcdCursorLeft(void)
00363 {
00364     LcdWriteCmd(0x10);
00365 }
00366 
00367 static void LcdCursorRight(void)
00368 {
00369     LcdWriteCmd(0x14);
00370 }
00371 
00372 static void LcdClear(void)
00373 {
00374     LcdWriteCmd(0x01);
00375     LcdDelay(10 * LCD_LONG_DELAY);
00376 }
00377 
00378 static void LcdCursorMode(u_char on)
00379 {
00380     if (on) {
00381         LcdWriteCmd(0x0D);
00382     } else {
00383         LcdWriteCmd(0x0C);
00384     }
00385     LcdDelay(10 * LCD_LONG_DELAY);
00386 }
00387 
00388 static void LcdInit(NUTDEVICE * dev)
00389 {
00390 #if defined(PMC_PCER)
00391     outr(PMC_PCER, _BV(LCD_CS_PIO_ID) | _BV(LCD_RS_PIO_ID) | _BV(LCD_CLK_PIO_ID) | _BV(LCD_MOSI_PIO_ID));
00392 #endif
00393 
00394     /* Initialize GPIO lines. */
00395     LCD_CS_SET();
00396     LCD_RS_SET();
00397     LCD_CLK_SET();
00398     LCD_MOSI_SET();
00399 
00400     /* Initial delay. Actually only required after power on. */
00401     NutSleep(50);
00402 
00403     LCD_RS_CLR();
00404     LCD_CS_CLR();
00405 
00406     LcdWriteCmd(0x38);    /* Function set. */
00407     NutSleep(2);
00408     LcdWriteCmd(0x39);    /* Function set. */
00409     NutSleep(2);
00410     LcdWriteCmd(0x14);    /* Bias 1/5, 2 lines. */
00411     NutSleep(1);
00412     LcdWriteCmd(0x55);    /* Power/ICON/Contrast control. */
00413     NutSleep(1);
00414     LcdWriteCmd(0x6D);    /* Follower control. */
00415     NutSleep(1);
00416     LcdWriteCmd(0x78);    /* Booster on, Contrast set. */
00417     NutSleep(1);
00418     LcdWriteCmd(0x0F);    /* Display on. */
00419     NutSleep(1);
00420     LcdWriteCmd(0x01);    /* Clear display. */
00421     NutSleep(1);
00422     LcdWriteCmd(0x06);    /* Entry mode set. */
00423     NutSleep(1);
00424 
00425     LCD_CS_SET();
00426     LCD_RS_SET();
00427 
00428     /* Clear display. */
00429     LcdClear();
00430     /* Move cursor home. */
00431     LcdCursorHome();
00432 }
00433 
00437 static TERMDCB dcb_term = {
00438     LcdInit,                    
00439     LcdWriteData,               
00440     LcdWriteInstruction,        
00441     LcdClear,                   
00442     LcdSetCursor,               
00443     LcdCursorHome,              
00444     LcdCursorLeft,              
00445     LcdCursorRight,             
00446     LcdCursorMode,              
00447     0,                          
00448     0,                          
00449     LCD_ROWS,                   
00450     LCD_COLS,                   
00451     LCD_COLS,                   
00452     0,                          
00453     0,                          
00454     0                           
00455 };
00456 
00460 NUTDEVICE devSbiLcd = {
00461     0,                          
00462     {'s', 'b', 'i', 'l', 'c', 'd', 0, 0, 0},  
00463     IFTYP_STREAM,               
00464     0,                          
00465     0,                          
00466     0,                          
00467     &dcb_term,                  
00468     TermInit,                   
00469     TermIOCtl,                  
00470     0,
00471     TermWrite,
00472     TermOpen,
00473     TermClose,
00474     0
00475 };
00476 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/