display.c 8.6 KB

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