display.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* ========================================================================
  2. * [PROJECT] SIR100
  3. * [MODULE] Display
  4. * [TITLE] display source file
  5. * [FILE] display.c
  6. * [VSN] 1.0
  7. * [CREATED] 26092003
  8. * [LASTCHNGD] 06102006
  9. * [COPYRIGHT] Copyright (C) STREAMIT BV
  10. * [PURPOSE] contains all interface- and low-level routines to
  11. * control the LCD and write characters or strings (menu-items)
  12. * ======================================================================== */
  13. #define LOG_MODULE LOG_DISPLAY_MODULE
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <sys/types.h>
  17. #include <sys/timer.h>
  18. #include <sys/event.h>
  19. #include <sys/thread.h>
  20. #include <sys/heap.h>
  21. #include "system.h"
  22. #include "portio.h"
  23. #include "display.h"
  24. #include "log.h"
  25. #include <time.h>
  26. /*-------------------------------------------------------------------------*/
  27. /* local defines */
  28. /*-------------------------------------------------------------------------*/
  29. /*-------------------------------------------------------------------------*/
  30. /* local variable definitions */
  31. /*-------------------------------------------------------------------------*/
  32. /*-------------------------------------------------------------------------*/
  33. /* local routines (prototyping) */
  34. /*-------------------------------------------------------------------------*/
  35. static void LcdWriteByte(u_char, u_char);
  36. static void LcdWriteNibble(u_char, u_char);
  37. static void LcdWaitBusy(void);
  38. int timerLCD(u_char Mode){
  39. time_t Start;
  40. if(Mode == startLCD)
  41. {
  42. time_t diff = time(0) - Start;
  43. return diff;
  44. }
  45. else if(Mode == stopLCD)
  46. {
  47. Start = time(0);
  48. }
  49. }
  50. /*!
  51. * \addtogroup Display
  52. */
  53. /*@{*/
  54. /*-------------------------------------------------------------------------*/
  55. /* start of code */
  56. /*-------------------------------------------------------------------------*/
  57. /* ����������������������������������������������������������������������� */
  58. /*!
  59. * \brief control backlight
  60. */
  61. /* ����������������������������������������������������������������������� */
  62. void LcdBackLight(u_char Mode)
  63. {
  64. if (Mode==LCD_BACKLIGHT_ON)
  65. {
  66. sbi(LCD_BL_PORT, LCD_BL_BIT); // Turn on backlight
  67. }
  68. if (Mode==LCD_BACKLIGHT_OFF)
  69. {
  70. cbi(LCD_BL_PORT, LCD_BL_BIT); // Turn off backlight
  71. }
  72. }
  73. /* ����������������������������������������������������������������������� */
  74. /*
  75. * Lcdbacklight knipperen
  76. */
  77. void LcdBacklightKnipperen(u_char Mode)
  78. {
  79. time_t Start;
  80. time_t Stop;
  81. if (Mode==startLCD)
  82. {
  83. sbi(LCD_BL_PORT, LCD_BL_BIT); // Turn on backlight
  84. timer(Start);
  85. }
  86. if (Mode==stopLCD)
  87. {
  88. cbi(LCD_BL_PORT, LCD_BL_BIT); // Turn off backlight
  89. timer(Stop);
  90. }
  91. }
  92. /*
  93. /* ����������������������������������������������������������������������� */
  94. /*!
  95. * \brief Write a single character on the LCD
  96. *
  97. * Writes a single character on the LCD on the current cursor position
  98. *
  99. * \param LcdChar character to write
  100. */
  101. /* ����������������������������������������������������������������������� */
  102. void LcdChar(char MyChar)
  103. {
  104. LcdWriteByte(WRITE_DATA, MyChar);
  105. }
  106. /* ����������������������������������������������������������������������� */
  107. /*!
  108. * \brief Low-level initialisation function of the LCD-controller
  109. *
  110. * Initialise the controller and send the User-Defined Characters to CG-RAM
  111. * settings: 4-bit interface, cursor invisible and NOT blinking
  112. * 1 line dislay, 10 dots high characters
  113. *
  114. */
  115. /* ����������������������������������������������������������������������� */
  116. void LcdLowLevelInit()
  117. {
  118. u_char i;
  119. NutDelay(140); // wait for more than 140 ms after Vdd rises to 2.7 V
  120. for (i=0; i<3; ++i)
  121. {
  122. LcdWriteNibble(WRITE_COMMAND, 0x33); // function set: 8-bit mode; necessary to guarantee that
  123. NutDelay(4); // SIR starts up always in 5x10 dot mode
  124. }
  125. LcdWriteNibble(WRITE_COMMAND, 0x22); // function set: 4-bit mode; necessary because KS0070 doesn't
  126. NutDelay(1); // accept combined 4-bit mode & 5x10 dot mode programming
  127. //LcdWriteByte(WRITE_COMMAND, 0x24); // function set: 4-bit mode, 5x10 dot mode, 1-line
  128. LcdWriteByte(WRITE_COMMAND, 0x28); // function set: 4-bit mode, 5x7 dot mode, 2-lines
  129. NutDelay(5);
  130. LcdWriteByte(WRITE_COMMAND, 0x0C); // display ON/OFF: display ON, cursor OFF, blink OFF
  131. NutDelay(5);
  132. LcdWriteByte(WRITE_COMMAND, 0x01); // display clear
  133. NutDelay(5);
  134. LcdWriteByte(WRITE_COMMAND, 0x06); // entry mode set: increment mode, entire shift OFF
  135. LcdWriteByte(WRITE_COMMAND, 0x80); // DD-RAM address counter (cursor pos) to '0'
  136. }
  137. /* ����������������������������������������������������������������������� */
  138. /*!
  139. * \brief Low-level routine to write a byte to LCD-controller
  140. *
  141. * Writes one byte to the LCD-controller (by calling LcdWriteNibble twice)
  142. * CtrlState determines if the byte is written to the instruction register
  143. * or to the data register.
  144. *
  145. * \param CtrlState destination: instruction or data
  146. * \param LcdByte byte to write
  147. *
  148. */
  149. /* ����������������������������������������������������������������������� */
  150. static void LcdWriteByte(u_char CtrlState, u_char LcdByte)
  151. {
  152. LcdWaitBusy(); // see if the controller is ready to receive next byte
  153. LcdWriteNibble(CtrlState, LcdByte & 0xF0);
  154. LcdWriteNibble(CtrlState, LcdByte << 4);
  155. }
  156. /* ����������������������������������������������������������������������� */
  157. /*!
  158. * \brief Low-level routine to write a nibble to LCD-controller
  159. *
  160. * Writes a nibble to the LCD-controller (interface is a 4-bit databus, so
  161. * only 4 databits can be send at once).
  162. * The nibble to write is in the upper 4 bits of LcdNibble
  163. *
  164. * \param CtrlState destination: instruction or data
  165. * \param LcdNibble nibble to write (upper 4 bits in this byte
  166. *
  167. */
  168. /* ����������������������������������������������������������������������� */
  169. static void LcdWriteNibble(u_char CtrlState, u_char LcdNibble)
  170. {
  171. outp((inp(LCD_DATA_DDR) & 0x0F) | 0xF0, LCD_DATA_DDR); // set data-port to output again
  172. outp((inp(LCD_DATA_PORT) & 0x0F) | (LcdNibble & 0xF0), LCD_DATA_PORT); // prepare databus with nibble to write
  173. if (CtrlState == WRITE_COMMAND)
  174. {
  175. cbi(LCD_RS_PORT, LCD_RS); // command: RS low
  176. }
  177. else
  178. {
  179. sbi(LCD_RS_PORT, LCD_RS); // data: RS high
  180. }
  181. sbi(LCD_EN_PORT, LCD_EN);
  182. asm("nop\n\tnop"); // small delay
  183. cbi(LCD_EN_PORT, LCD_EN);
  184. cbi(LCD_RS_PORT, LCD_RS);
  185. outp((inp(LCD_DATA_DDR) & 0x0F), LCD_DATA_DDR); // set upper 4-bits of data-port to input
  186. outp((inp(LCD_DATA_PORT) & 0x0F) | 0xF0, LCD_DATA_PORT); // enable pull-ups in data-port
  187. }
  188. /* ����������������������������������������������������������������������� */
  189. /*!
  190. * \brief Low-level routine to see if the controller is ready to receive
  191. *
  192. * This routine repeatetly reads the databus and checks if the highest bit (bit 7)
  193. * has become '0'. If a '0' is detected on bit 7 the function returns.
  194. *
  195. */
  196. /* ����������������������������������������������������������������������� */
  197. static void LcdWaitBusy()
  198. {
  199. u_char Busy = 1;
  200. u_char LcdStatus = 0;
  201. cbi (LCD_RS_PORT, LCD_RS); // select instruction register
  202. sbi (LCD_RW_PORT, LCD_RW); // we are going to read
  203. while (Busy)
  204. {
  205. sbi (LCD_EN_PORT, LCD_EN); // set 'enable' to catch 'Ready'
  206. asm("nop\n\tnop"); // small delay
  207. LcdStatus = inp(LCD_IN_PORT); // LcdStatus is used elsewhere in this module as well
  208. Busy = LcdStatus & 0x80; // break out of while-loop cause we are ready (b7='0')
  209. }
  210. cbi (LCD_EN_PORT, LCD_EN); // all ctrlpins low
  211. cbi (LCD_RS_PORT, LCD_RS);
  212. cbi (LCD_RW_PORT, LCD_RW); // we are going to write
  213. }
  214. //clears the Lcd screen
  215. void ClearLcd()
  216. {
  217. LcdWriteByte(WRITE_COMMAND, 0x01);
  218. }
  219. void LcdArrayLineOne(char *data, int size)
  220. {
  221. int i;
  222. LcdWriteByte(WRITE_COMMAND, 0x80);
  223. NutSleep(2);
  224. for(i = 0; i < size; i = i + 1){
  225. LcdChar(data[i]);
  226. }
  227. }
  228. void LcdArrayLineTwo(char *data, int size){
  229. int i;
  230. LcdWriteByte(WRITE_COMMAND, 0xC0);
  231. NutSleep(2);
  232. for(i = 0; i < size; i = i + 1){
  233. LcdChar(data[i]);
  234. }
  235. }
  236. /* ---------- end of module ------------------------------------------------ */
  237. /*@}*/