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.2  2007/10/04 20:01:50  olereinhardt
00037  * Support for SAM7S256 added
00038  *
00039  * Revision 1.1  2007/02/15 16:09:07  haraldkipp
00040  * Tested with EA DOG-M LCDs.
00041  *
00042  */
00043 
00044 #include <cfg/arch.h>
00045 #include <cfg/arch/gpio.h>
00046 #include <cfg/lcd.h>
00047 
00048 #include <stdlib.h>
00049 #include <string.h>
00050 
00051 #include <sys/nutconfig.h>
00052 #include <dev/st7036.h>
00053 #include <dev/term.h>
00054 #include <sys/timer.h>
00055 
00056 #ifndef LCD_ROWS
00057 #define LCD_ROWS    2
00058 #endif
00059 
00060 #ifndef LCD_COLS
00061 #define LCD_COLS    16
00062 #endif
00063 
00064 #ifndef LCD_SHORT_DELAY
00065 #define LCD_SHORT_DELAY 100
00066 #endif
00067 
00068 #ifndef LCD_LONG_DELAY
00069 #define LCD_LONG_DELAY  1000
00070 #endif
00071 
00075 #if defined(AT91SAM7X_EK)
00076 
00077 #ifndef LCD_CS_PIO_ID
00078 #define LCD_CS_PIO_ID   PIOB_ID
00079 #endif
00080 #ifndef LCD_CS_BIT
00081 #define LCD_CS_BIT      24
00082 #endif
00083 
00084 #ifndef LCD_RS_PIO_ID
00085 #define LCD_RS_PIO_ID   PIOB_ID
00086 #endif
00087 #ifndef LCD_RS_BIT
00088 #define LCD_RS_BIT      23
00089 #endif
00090 
00091 #ifndef LCD_CLK_PIO_ID
00092 #define LCD_CLK_PIO_ID  PIOA_ID
00093 #endif
00094 #ifndef LCD_CLK_BIT
00095 #define LCD_CLK_BIT     18
00096 #endif
00097 
00098 #ifndef LCD_MOSI_PIO_ID
00099 #define LCD_MOSI_PIO_ID PIOA_ID
00100 #endif
00101 #ifndef LCD_MOSI_BIT
00102 #define LCD_MOSI_BIT    17
00103 #endif
00104 
00105 #elif defined(AT91SAM7S)
00106 
00107 #ifndef LCD_CS_PIO_ID
00108 #define LCD_CS_PIO_ID   PIOA_ID
00109 #endif
00110 #ifndef LCD_CS_BIT
00111 #define LCD_CS_BIT      28
00112 #endif
00113 
00114 #ifndef LCD_RS_PIO_ID
00115 #define LCD_RS_PIO_ID   PIOA_ID
00116 #endif
00117 #ifndef LCD_RS_BIT
00118 #define LCD_RS_BIT      26
00119 #endif
00120 
00121 #ifndef LCD_CLK_PIO_ID
00122 #define LCD_CLK_PIO_ID  PIOA_ID
00123 #endif
00124 #ifndef LCD_CLK_BIT
00125 #define LCD_CLK_BIT     14
00126 #endif
00127 
00128 #ifndef LCD_MOSI_PIO_ID
00129 #define LCD_MOSI_PIO_ID PIOA_ID
00130 #endif
00131 #ifndef LCD_MOSI_BIT
00132 #define LCD_MOSI_BIT    13
00133 #endif
00134 
00135 #elif defined(AT91SAM9260_EK)
00136 
00137 #ifndef LCD_CS_PIO_ID
00138 #define LCD_CS_PIO_ID   PIOB_ID
00139 #endif
00140 #ifndef LCD_CS_BIT
00141 #define LCD_CS_BIT      11
00142 #endif
00143 
00144 #ifndef LCD_RS_PIO_ID
00145 #define LCD_RS_PIO_ID   PIOB_ID
00146 #endif
00147 #ifndef LCD_RS_BIT
00148 #define LCD_RS_BIT      20
00149 #endif
00150 
00151 #ifndef LCD_CLK_PIO_ID
00152 #define LCD_CLK_PIO_ID  PIOB_ID
00153 #endif
00154 #ifndef LCD_CLK_BIT
00155 #define LCD_CLK_BIT     2
00156 #endif
00157 
00158 #ifndef LCD_MOSI_PIO_ID
00159 #define LCD_MOSI_PIO_ID PIOB_ID
00160 #endif
00161 #ifndef LCD_MOSI_BIT
00162 #define LCD_MOSI_BIT    1
00163 #endif
00164 
00165 #else
00166 
00167 #ifndef LCD_CS_PIO_ID
00168 #define LCD_CS_PIO_ID   PIO_ID
00169 #endif
00170 #ifndef LCD_CS_BIT
00171 #define LCD_CS_BIT      0
00172 #endif
00173 
00174 #ifndef LCD_RS_PIO_ID
00175 #define LCD_RS_PIO_ID   PIO_ID
00176 #endif
00177 #ifndef LCD_RS_BIT
00178 #define LCD_RS_BIT      3
00179 #endif
00180 
00181 #ifndef LCD_CLK_PIO_ID
00182 #define LCD_CLK_PIO_ID  PIO_ID
00183 #endif
00184 #ifndef LCD_CLK_BIT
00185 #define LCD_CLK_BIT     1
00186 #endif
00187 
00188 #ifndef LCD_MOSI_PIO_ID
00189 #define LCD_MOSI_PIO_ID PIO_ID
00190 #endif
00191 #ifndef LCD_MOSI_BIT
00192 #define LCD_MOSI_BIT    2
00193 #endif
00194 
00195 #endif
00196 
00197 #define LCD_CS      _BV(LCD_CS_BIT)
00198 #define LCD_RS      _BV(LCD_RS_BIT)
00199 #define LCD_CLK     _BV(LCD_CLK_BIT)
00200 #define LCD_MOSI    _BV(LCD_MOSI_BIT)
00201 
00202 
00203 #if LCD_CS_PIO_ID == PIOA_ID
00204 #define LCD_CS_SET() { outr(PIOA_PER, LCD_CS); outr(PIOA_SODR, LCD_CS); outr(PIOA_OER, LCD_CS); }
00205 #define LCD_CS_CLR() { outr(PIOA_PER, LCD_CS); outr(PIOA_CODR, LCD_CS); outr(PIOA_OER, LCD_CS); }
00206 #elif LCD_CS_PIO_ID == PIOB_ID
00207 #define LCD_CS_SET() { outr(PIOB_PER, LCD_CS); outr(PIOB_SODR, LCD_CS); outr(PIOB_OER, LCD_CS); }
00208 #define LCD_CS_CLR() { outr(PIOB_PER, LCD_CS); outr(PIOB_CODR, LCD_CS); outr(PIOB_OER, LCD_CS); }
00209 #elif LCD_CS_PIO_ID == PIOC_ID
00210 #define LCD_CS_SET() { outr(PIOC_PER, LCD_CS); outr(PIOC_SODR, LCD_CS); outr(PIOC_OER, LCD_CS); }
00211 #define LCD_CS_CLR() { outr(PIOC_PER, LCD_CS); outr(PIOC_CODR, LCD_CS); outr(PIOC_OER, LCD_CS); }
00212 #else
00213 #define LCD_CS_SET() { outr(PIO_PER, LCD_CS); outr(PIO_SODR, LCD_CS); outr(PIO_OER, LCD_CS); }
00214 #define LCD_CS_CLR() { outr(PIO_PER, LCD_CS); outr(PIO_CODR, LCD_CS); outr(PIO_OER, LCD_CS); }
00215 #endif
00216 
00217 #if LCD_RS_PIO_ID == PIOA_ID
00218 #define LCD_RS_SET() { outr(PIOA_PER, LCD_RS); outr(PIOA_SODR, LCD_RS); outr(PIOA_OER, LCD_RS); }
00219 #define LCD_RS_CLR() { outr(PIOA_PER, LCD_RS); outr(PIOA_CODR, LCD_RS); outr(PIOA_OER, LCD_RS); }
00220 #elif LCD_RS_PIO_ID == PIOB_ID
00221 #define LCD_RS_SET() { outr(PIOB_PER, LCD_RS); outr(PIOB_SODR, LCD_RS); outr(PIOB_OER, LCD_RS); }
00222 #define LCD_RS_CLR() { outr(PIOB_PER, LCD_RS); outr(PIOB_CODR, LCD_RS); outr(PIOB_OER, LCD_RS); }
00223 #elif LCD_RS_PIO_ID == PIOC_ID
00224 #define LCD_RS_SET() { outr(PIOC_PER, LCD_RS); outr(PIOC_SODR, LCD_RS); outr(PIOC_OER, LCD_RS); }
00225 #define LCD_RS_CLR() { outr(PIOC_PER, LCD_RS); outr(PIOC_CODR, LCD_RS); outr(PIOC_OER, LCD_RS); }
00226 #else
00227 #define LCD_RS_SET() { outr(PIO_PER, LCD_RS); outr(PIO_SODR, LCD_RS); outr(PIO_OER, LCD_RS); }
00228 #define LCD_RS_CLR() { outr(PIO_PER, LCD_RS); outr(PIO_CODR, LCD_RS); outr(PIO_OER, LCD_RS); }
00229 #endif
00230 
00231 #if LCD_CLK_PIO_ID == PIOA_ID
00232 #define LCD_CLK_SET() { outr(PIOA_PER, LCD_CLK); outr(PIOA_SODR, LCD_CLK); outr(PIOA_OER, LCD_CLK); }
00233 #define LCD_CLK_CLR() { outr(PIOA_PER, LCD_CLK); outr(PIOA_CODR, LCD_CLK); outr(PIOA_OER, LCD_CLK); }
00234 #elif LCD_CLK_PIO_ID == PIOB_ID
00235 #define LCD_CLK_SET() { outr(PIOB_PER, LCD_CLK); outr(PIOB_SODR, LCD_CLK); outr(PIOB_OER, LCD_CLK); }
00236 #define LCD_CLK_CLR() { outr(PIOB_PER, LCD_CLK); outr(PIOB_CODR, LCD_CLK); outr(PIOB_OER, LCD_CLK); }
00237 #elif LCD_CLK_PIO_ID == PIOC_ID
00238 #define LCD_CLK_SET() { outr(PIOC_PER, LCD_CLK); outr(PIOC_SODR, LCD_CLK); outr(PIOC_OER, LCD_CLK); }
00239 #define LCD_CLK_CLR() { outr(PIOC_PER, LCD_CLK); outr(PIOC_CODR, LCD_CLK); outr(PIOC_OER, LCD_CLK); }
00240 #else
00241 #define LCD_CLK_SET() { outr(PIO_PER, LCD_CLK); outr(PIO_SODR, LCD_CLK); outr(PIO_OER, LCD_CLK); }
00242 #define LCD_CLK_CLR() { outr(PIO_PER, LCD_CLK); outr(PIO_CODR, LCD_CLK); outr(PIO_OER, LCD_CLK); }
00243 #endif
00244 
00245 #if LCD_MOSI_PIO_ID == PIOA_ID
00246 #define LCD_MOSI_SET() { outr(PIOA_PER, LCD_MOSI); outr(PIOA_SODR, LCD_MOSI); outr(PIOA_OER, LCD_MOSI); }
00247 #define LCD_MOSI_CLR() { outr(PIOA_PER, LCD_MOSI); outr(PIOA_CODR, LCD_MOSI); outr(PIOA_OER, LCD_MOSI); }
00248 #elif LCD_MOSI_PIO_ID == PIOB_ID
00249 #define LCD_MOSI_SET() { outr(PIOB_PER, LCD_MOSI); outr(PIOB_SODR, LCD_MOSI); outr(PIOB_OER, LCD_MOSI); }
00250 #define LCD_MOSI_CLR() { outr(PIOB_PER, LCD_MOSI); outr(PIOB_CODR, LCD_MOSI); outr(PIOB_OER, LCD_MOSI); }
00251 #elif LCD_MOSI_PIO_ID == PIOC_ID
00252 #define LCD_MOSI_SET() { outr(PIOC_PER, LCD_MOSI); outr(PIOC_SODR, LCD_MOSI); outr(PIOC_OER, LCD_MOSI); }
00253 #define LCD_MOSI_CLR() { outr(PIOC_PER, LCD_MOSI); outr(PIOC_CODR, LCD_MOSI); outr(PIOC_OER, LCD_MOSI); }
00254 #else
00255 #define LCD_MOSI_SET() { outr(PIO_PER, LCD_MOSI); outr(PIO_SODR, LCD_MOSI); outr(PIO_OER, LCD_MOSI); }
00256 #define LCD_MOSI_CLR() { outr(PIO_PER, LCD_MOSI); outr(PIO_CODR, LCD_MOSI); outr(PIO_OER, LCD_MOSI); }
00257 #endif
00258 
00263 
00274 static void LcdDelay(u_int cycles)
00275 {
00276     while (cycles--) {
00277         _NOP(); _NOP(); _NOP(); _NOP();
00278         _NOP(); _NOP(); _NOP(); _NOP();
00279         _NOP(); _NOP(); _NOP(); _NOP();
00280         _NOP(); _NOP(); _NOP(); _NOP();
00281         _NOP(); _NOP(); _NOP(); _NOP();
00282         _NOP(); _NOP(); _NOP(); _NOP();
00283         _NOP(); _NOP(); _NOP(); _NOP();
00284         _NOP(); _NOP(); _NOP(); _NOP();
00285         _NOP(); _NOP(); _NOP(); _NOP();
00286         _NOP(); _NOP(); _NOP(); _NOP();
00287         _NOP(); _NOP(); _NOP(); _NOP();
00288         _NOP(); _NOP(); _NOP(); _NOP();
00289     }
00290 }
00291 
00292 #if 0
00293 static void INLINE LcdSetBits(u_int mask)
00294 {
00295     outr(LCD_PIO_SOD_REG, mask);
00296     outr(LCD_PIO_OE_REG, mask);
00297 }
00298 
00299 static void INLINE LcdClrBits(u_int mask)
00300 {
00301     outr(LCD_PIO_COD_REG, mask);
00302     outr(LCD_PIO_OE_REG, mask);
00303 }
00304 #endif
00305 
00306 static void LcdWaitReady(u_int delay)
00307 {
00308     while (delay--) {
00309         _NOP();
00310     }
00311 }
00312 
00318 static void LcdWriteByte(u_int data)
00319 {
00320     u_char msk = 0x80;
00321 
00322     while (msk) {
00323         LCD_CLK_CLR();
00324         if (data & msk) {
00325             LCD_MOSI_SET();
00326         } else {
00327             LCD_MOSI_CLR();
00328         }
00329         LCD_CLK_SET();
00330         msk >>= 1;
00331         LcdDelay(1);
00332     }
00333     LcdWaitReady(LCD_LONG_DELAY);
00334 }
00335 
00341 static void LcdWriteCmd(u_char cmd)
00342 {
00343     /* RS low selects instruction register. */
00344     LCD_CS_CLR();
00345     LcdDelay(LCD_SHORT_DELAY);
00346     LCD_RS_CLR();
00347     LcdDelay(LCD_SHORT_DELAY);
00348     LcdWriteByte(cmd);
00349     LcdDelay(LCD_SHORT_DELAY);
00350     LCD_RS_SET();
00351     LcdDelay(LCD_SHORT_DELAY);
00352     LCD_CS_SET();
00353     LcdDelay(LCD_SHORT_DELAY);
00354 }
00355 
00356 static void LcdWriteInstruction(u_char cmd, u_char xt)
00357 {
00358     LcdWriteCmd(cmd);
00359 }
00360 
00366 static void LcdWriteData(u_char data)
00367 {
00368     /* RS high selects data register. */
00369     LCD_CS_CLR();
00370     LcdDelay(LCD_SHORT_DELAY);
00371     LCD_RS_SET();
00372     LcdDelay(LCD_SHORT_DELAY);
00373     LcdWriteByte(data);
00374     LcdDelay(LCD_SHORT_DELAY);
00375     LCD_CS_SET();
00376     LcdDelay(LCD_SHORT_DELAY);
00377 }
00378 
00379 static void LcdSetCursor(u_char pos)
00380 {
00381     u_char offset[] = {
00382         0x00, 0x40, 0x10, 0x50
00383     };
00384 
00385     pos = offset[(pos / LCD_COLS) % LCD_ROWS] + pos % LCD_COLS;
00386     LcdWriteCmd(0x80 | pos);
00387 }
00388 
00389 static void LcdCursorHome(void)
00390 {
00391     LcdWriteCmd(0x02);
00392     LcdDelay(10 * LCD_LONG_DELAY);
00393 }
00394 
00395 static void LcdCursorLeft(void)
00396 {
00397     LcdWriteCmd(0x10);
00398 }
00399 
00400 static void LcdCursorRight(void)
00401 {
00402     LcdWriteCmd(0x14);
00403 }
00404 
00405 static void LcdClear(void)
00406 {
00407     LcdWriteCmd(0x01);
00408     LcdDelay(10 * LCD_LONG_DELAY);
00409 }
00410 
00411 static void LcdCursorMode(u_char on)
00412 {
00413     if (on) {
00414         LcdWriteCmd(0x0D);
00415     } else {
00416         LcdWriteCmd(0x0C);
00417     }
00418     LcdDelay(10 * LCD_LONG_DELAY);
00419 }
00420 
00421 static void LcdInit(NUTDEVICE * dev)
00422 {
00423 #if defined(PMC_PCER)
00424     outr(PMC_PCER, _BV(LCD_CS_PIO_ID) | _BV(LCD_RS_PIO_ID) | _BV(LCD_CLK_PIO_ID) | _BV(LCD_MOSI_PIO_ID));
00425 #endif
00426 
00427     /* Initialize GPIO lines. */
00428     LCD_CS_SET();
00429     LCD_RS_SET();
00430     LCD_CLK_SET();
00431     LCD_MOSI_SET();
00432 
00433     /* Initial delay. Actually only required after power on. */
00434     NutSleep(50);
00435 
00436     LCD_RS_CLR();
00437     LCD_CS_CLR();
00438 
00439     LcdWriteCmd(0x38);    /* Function set. */
00440     NutSleep(2);
00441     LcdWriteCmd(0x39);    /* Function set. */
00442     NutSleep(2);
00443     LcdWriteCmd(0x14);    /* Bias 1/5, 2 lines. */
00444     NutSleep(1);
00445     LcdWriteCmd(0x55);    /* Power/ICON/Contrast control. */
00446     NutSleep(1);
00447     LcdWriteCmd(0x6D);    /* Follower control. */
00448     NutSleep(1);
00449     LcdWriteCmd(0x78);    /* Booster on, Contrast set. */
00450     NutSleep(1);
00451     LcdWriteCmd(0x0F);    /* Display on. */
00452     NutSleep(1);
00453     LcdWriteCmd(0x01);    /* Clear display. */
00454     NutSleep(1);
00455     LcdWriteCmd(0x06);    /* Entry mode set. */
00456     NutSleep(1);
00457 
00458     LCD_CS_SET();
00459     LCD_RS_SET();
00460 
00461     /* Clear display. */
00462     LcdClear();
00463     /* Move cursor home. */
00464     LcdCursorHome();
00465 }
00466 
00470 static TERMDCB dcb_term = {
00471     LcdInit,                    
00472     LcdWriteData,               
00473     LcdWriteInstruction,        
00474     LcdClear,                   
00475     LcdSetCursor,               
00476     LcdCursorHome,              
00477     LcdCursorLeft,              
00478     LcdCursorRight,             
00479     LcdCursorMode,              
00480     0,                          
00481     0,                          
00482     LCD_ROWS,                   
00483     LCD_COLS,                   
00484     LCD_COLS,                   
00485     0,                          
00486     0,                          
00487     0                           
00488 };
00489 
00493 NUTDEVICE devSbiLcd = {
00494     0,                          
00495     {'s', 'b', 'i', 'l', 'c', 'd', 0, 0, 0},  
00496     IFTYP_STREAM,               
00497     0,                          
00498     0,                          
00499     0,                          
00500     &dcb_term,                  
00501     TermInit,                   
00502     TermIOCtl,                  
00503     0,
00504     TermWrite,
00505     TermOpen,
00506     TermClose,
00507     0
00508 };
00509 

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