display.c 10 KB

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