display.c 7.7 KB

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