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. #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. * \brief Write a single character on the LCD
  94. *
  95. * Writes a single character on the LCD on the current cursor position
  96. *
  97. * \param LcdChar character to write
  98. */
  99. /* ����������������������������������������������������������������������� */
  100. void LcdChar(char MyChar)
  101. {
  102. LcdWriteByte(WRITE_DATA, MyChar);
  103. }
  104. /* ����������������������������������������������������������������������� */
  105. /*!
  106. * \brief Low-level initialisation function of the LCD-controller
  107. *
  108. * Initialise the controller and send the User-Defined Characters to CG-RAM
  109. * settings: 4-bit interface, cursor invisible and NOT blinking
  110. * 1 line dislay, 10 dots high characters
  111. *
  112. */
  113. /* ����������������������������������������������������������������������� */
  114. void LcdLowLevelInit()
  115. {
  116. u_char i;
  117. NutDelay(140); // wait for more than 140 ms after Vdd rises to 2.7 V
  118. for (i=0; i<3; ++i)
  119. {
  120. LcdWriteNibble(WRITE_COMMAND, 0x33); // function set: 8-bit mode; necessary to guarantee that
  121. NutDelay(4); // SIR starts up always in 5x10 dot mode
  122. }
  123. LcdWriteNibble(WRITE_COMMAND, 0x22); // function set: 4-bit mode; necessary because KS0070 doesn't
  124. NutDelay(1); // accept combined 4-bit mode & 5x10 dot mode programming
  125. //LcdWriteByte(WRITE_COMMAND, 0x24); // function set: 4-bit mode, 5x10 dot mode, 1-line
  126. LcdWriteByte(WRITE_COMMAND, 0x28); // function set: 4-bit mode, 5x7 dot mode, 2-lines
  127. NutDelay(5);
  128. LcdWriteByte(WRITE_COMMAND, 0x0C); // display ON/OFF: display ON, cursor OFF, blink OFF
  129. NutDelay(5);
  130. LcdWriteByte(WRITE_COMMAND, 0x01); // display clear
  131. NutDelay(5);
  132. LcdWriteByte(WRITE_COMMAND, 0x06); // entry mode set: increment mode, entire shift OFF
  133. LcdWriteByte(WRITE_COMMAND, 0x80); // DD-RAM address counter (cursor pos) to '0'
  134. }
  135. /* ����������������������������������������������������������������������� */
  136. /*!
  137. * \brief Low-level routine to write a byte to LCD-controller
  138. *
  139. * Writes one byte to the LCD-controller (by calling LcdWriteNibble twice)
  140. * CtrlState determines if the byte is written to the instruction register
  141. * or to the data register.
  142. *
  143. * \param CtrlState destination: instruction or data
  144. * \param LcdByte byte to write
  145. *
  146. */
  147. /* ����������������������������������������������������������������������� */
  148. static void LcdWriteByte(u_char CtrlState, u_char LcdByte)
  149. {
  150. LcdWaitBusy(); // see if the controller is ready to receive next byte
  151. LcdWriteNibble(CtrlState, LcdByte & 0xF0);
  152. LcdWriteNibble(CtrlState, LcdByte << 4);
  153. }
  154. /* ����������������������������������������������������������������������� */
  155. /*!
  156. * \brief Low-level routine to write a nibble to LCD-controller
  157. *
  158. * Writes a nibble to the LCD-controller (interface is a 4-bit databus, so
  159. * only 4 databits can be send at once).
  160. * The nibble to write is in the upper 4 bits of LcdNibble
  161. *
  162. * \param CtrlState destination: instruction or data
  163. * \param LcdNibble nibble to write (upper 4 bits in this byte
  164. *
  165. */
  166. /* ����������������������������������������������������������������������� */
  167. static void LcdWriteNibble(u_char CtrlState, u_char LcdNibble)
  168. {
  169. outp((inp(LCD_DATA_DDR) & 0x0F) | 0xF0, LCD_DATA_DDR); // set data-port to output again
  170. outp((inp(LCD_DATA_PORT) & 0x0F) | (LcdNibble & 0xF0), LCD_DATA_PORT); // prepare databus with nibble to write
  171. if (CtrlState == WRITE_COMMAND)
  172. {
  173. cbi(LCD_RS_PORT, LCD_RS); // command: RS low
  174. }
  175. else
  176. {
  177. sbi(LCD_RS_PORT, LCD_RS); // data: RS high
  178. }
  179. sbi(LCD_EN_PORT, LCD_EN);
  180. asm("nop\n\tnop"); // small delay
  181. cbi(LCD_EN_PORT, LCD_EN);
  182. cbi(LCD_RS_PORT, LCD_RS);
  183. outp((inp(LCD_DATA_DDR) & 0x0F), LCD_DATA_DDR); // set upper 4-bits of data-port to input
  184. outp((inp(LCD_DATA_PORT) & 0x0F) | 0xF0, LCD_DATA_PORT); // enable pull-ups in data-port
  185. }
  186. /* ����������������������������������������������������������������������� */
  187. /*!
  188. * \brief Low-level routine to see if the controller is ready to receive
  189. *
  190. * This routine repeatetly reads the databus and checks if the highest bit (bit 7)
  191. * has become '0'. If a '0' is detected on bit 7 the function returns.
  192. *
  193. */
  194. /* ����������������������������������������������������������������������� */
  195. static void LcdWaitBusy()
  196. {
  197. u_char Busy = 1;
  198. u_char LcdStatus = 0;
  199. cbi (LCD_RS_PORT, LCD_RS); // select instruction register
  200. sbi (LCD_RW_PORT, LCD_RW); // we are going to read
  201. while (Busy)
  202. {
  203. sbi (LCD_EN_PORT, LCD_EN); // set 'enable' to catch 'Ready'
  204. asm("nop\n\tnop"); // small delay
  205. LcdStatus = inp(LCD_IN_PORT); // LcdStatus is used elsewhere in this module as well
  206. Busy = LcdStatus & 0x80; // break out of while-loop cause we are ready (b7='0')
  207. }
  208. cbi (LCD_EN_PORT, LCD_EN); // all ctrlpins low
  209. cbi (LCD_RS_PORT, LCD_RS);
  210. cbi (LCD_RW_PORT, LCD_RW); // we are going to write
  211. }
  212. //clears the Lcd screen
  213. void ClearLcd()
  214. {
  215. LcdWriteByte(WRITE_COMMAND, 0x01);
  216. }
  217. void LcdArrayLineOne(char *data, int size)
  218. {
  219. int i;
  220. LcdWriteByte(WRITE_COMMAND, 0x80);
  221. NutSleep(2);
  222. for(i = 0; i < size; i = i + 1){
  223. LcdChar(data[i]);
  224. }
  225. }
  226. void LcdArrayLineTwo(char *data, int size){
  227. int i;
  228. LcdWriteByte(WRITE_COMMAND, 0xC0);
  229. NutSleep(2);
  230. for(i = 0; i < size; i = i + 1){
  231. LcdChar(data[i]);
  232. }
  233. }
  234. /* ---------- end of module ------------------------------------------------ */
  235. /*@}*/