]> git.sur5r.net Git - freertos/blob - Demo/PIC32MX_MPLAB/lcd.c
Update to V5.0.0.
[freertos] / Demo / PIC32MX_MPLAB / lcd.c
1 /*\r
2         FreeRTOS.org V5.0.0 - Copyright (C) 2003-2008 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section \r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26     ***************************************************************************\r
27     ***************************************************************************\r
28     *                                                                         *\r
29     * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
30     * and even write all or part of your application on your behalf.          *\r
31     * See http://www.OpenRTOS.com for details of the services we provide to   *\r
32     * expedite your project.                                                  *\r
33     *                                                                         *\r
34     ***************************************************************************\r
35     ***************************************************************************\r
36 \r
37         Please ensure to read the configuration and relevant port sections of the\r
38         online documentation.\r
39 \r
40         http://www.FreeRTOS.org - Documentation, latest information, license and \r
41         contact details.\r
42 \r
43         http://www.SafeRTOS.com - A version that is certified for use in safety \r
44         critical systems.\r
45 \r
46         http://www.OpenRTOS.com - Commercial support, development, porting, \r
47         licensing and training services.\r
48 */\r
49 \r
50 /* peripheral library include */\r
51 #include <plib.h>\r
52 \r
53 /* Scheduler includes. */\r
54 #include "FreeRTOS.h"\r
55 #include "task.h"\r
56 #include "queue.h"\r
57 \r
58 /* Demo includes. */\r
59 #include "lcd.h"\r
60 \r
61 /*\r
62  * The LCD is written to by more than one task so is controlled by this\r
63  * 'gatekeeper' task.  This is the only task that is actually permitted to\r
64  * access the LCD directly.  Other tasks wanting to display a message send\r
65  * the message to the gatekeeper.\r
66  */\r
67 static void vLCDTask( void *pvParameters );\r
68 \r
69 /*\r
70  * Setup the peripherals required to communicate with the LCD.\r
71  */\r
72 static void prvSetupLCD( void );\r
73 \r
74 /* \r
75  * Move to the first (0) or second (1) row of the LCD. \r
76  */\r
77 static void prvLCDGotoRow( unsigned portSHORT usRow );\r
78 \r
79 /* \r
80  * Write a string of text to the LCD. \r
81  */\r
82 static void prvLCDPutString( portCHAR *pcString );\r
83 \r
84 /* \r
85  * Clear the LCD. \r
86  */\r
87 static void prvLCDClear( void );\r
88 \r
89 /*-----------------------------------------------------------*/\r
90 \r
91 /* Brief delay to permit the LCD to catch up with commands. */\r
92 #define lcdVERY_SHORT_DELAY     ( 1 )\r
93 #define lcdSHORT_DELAY          ( 4 / portTICK_RATE_MS )\r
94 #define lcdLONG_DELAY           ( 15 / portTICK_RATE_MS )\r
95 \r
96 /* LCD specific definitions. */\r
97 #define LCD_CLEAR_DISPLAY_CMD                   0x01\r
98 #define LCD_CURSOR_HOME_CMD                             0x02\r
99 #define LCD_ENTRY_MODE_CMD                              0x04\r
100 #define LCD_ENTRY_MODE_INCREASE                 0x02\r
101 #define LCD_DISPLAY_CTRL_CMD                    0x08\r
102 #define LCD_DISPLAY_CTRL_DISPLAY_ON             0x04\r
103 #define LCD_FUNCTION_SET_CMD                    0x20\r
104 #define LCD_FUNCTION_SET_8_BITS                 0x10\r
105 #define LCD_FUNCTION_SET_2_LINES                0x08\r
106 #define LCD_FUNCTION_SET_LRG_FONT               0x04\r
107 #define LCD_NEW_LINE                                    0xC0\r
108 #define LCD_COMMAND_ADDRESS                             0x00\r
109 #define LCD_DATA_ADDRESS                                0x01\r
110 \r
111 /* The length of the queue used to send messages to the LCD gatekeeper task. */\r
112 #define lcdQUEUE_SIZE           3\r
113 \r
114 /*-----------------------------------------------------------*/\r
115 \r
116 /* The queue used to send messages to the LCD task. */\r
117 xQueueHandle xLCDQueue;\r
118 \r
119 /* LCD access functions. */\r
120 static void prvLCDCommand( portCHAR cCommand );\r
121 static void prvLCDData( portCHAR cChar );\r
122 \r
123 /*-----------------------------------------------------------*/\r
124 \r
125 xQueueHandle xStartLCDTask( void )\r
126 {\r
127         /* Create the queue used by the LCD task.  Messages for display on the LCD\r
128         are received via this queue. */\r
129         xLCDQueue = xQueueCreate( lcdQUEUE_SIZE, sizeof( xLCDMessage ));\r
130 \r
131         /* Start the task that will write to the LCD.  The LCD hardware is\r
132         initialised from within the task itself so delays can be used. */\r
133         xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );\r
134 \r
135         return xLCDQueue;\r
136 }\r
137 /*-----------------------------------------------------------*/\r
138 \r
139 static void prvLCDGotoRow( unsigned portSHORT usRow )\r
140 {\r
141         if(usRow == 0) \r
142         {\r
143                 prvLCDCommand( LCD_CURSOR_HOME_CMD );\r
144         } \r
145         else \r
146         {\r
147                 prvLCDCommand( LCD_NEW_LINE );\r
148         }\r
149 }\r
150 /*-----------------------------------------------------------*/\r
151 \r
152 static void prvLCDCommand( portCHAR cCommand ) \r
153 {\r
154         PMPSetAddress( LCD_COMMAND_ADDRESS );\r
155         PMPMasterWrite( cCommand );\r
156         vTaskDelay( lcdSHORT_DELAY );\r
157 }\r
158 /*-----------------------------------------------------------*/\r
159 \r
160 static void prvLCDData( portCHAR cChar )\r
161 {\r
162         PMPSetAddress( LCD_DATA_ADDRESS );\r
163         PMPMasterWrite( cChar );\r
164         vTaskDelay( lcdVERY_SHORT_DELAY );\r
165 }\r
166 /*-----------------------------------------------------------*/\r
167 \r
168 static void prvLCDPutString( portCHAR *pcString )\r
169 {\r
170         /* Write out each character with appropriate delay between each. */\r
171         while(*pcString)\r
172         {\r
173                 prvLCDData(*pcString);\r
174                 pcString++;\r
175                 vTaskDelay(lcdSHORT_DELAY);\r
176         }\r
177 }\r
178 /*-----------------------------------------------------------*/\r
179 \r
180 static void prvLCDClear(void)\r
181 {\r
182         prvLCDCommand(LCD_CLEAR_DISPLAY_CMD);\r
183 }\r
184 /*-----------------------------------------------------------*/\r
185 \r
186 static void prvSetupLCD(void)\r
187 {\r
188         /* Wait for proper power up. */\r
189         vTaskDelay( lcdLONG_DELAY );\r
190         \r
191         /* Open the PMP port */\r
192         mPMPOpen((PMP_ON | PMP_READ_WRITE_EN | PMP_CS2_CS1_EN |\r
193                           PMP_LATCH_POL_HI | PMP_CS2_POL_HI | PMP_CS1_POL_HI |\r
194                           PMP_WRITE_POL_HI | PMP_READ_POL_HI),\r
195                          (PMP_MODE_MASTER1 | PMP_WAIT_BEG_4 | PMP_WAIT_MID_15 |\r
196                           PMP_WAIT_END_4),\r
197                           PMP_PEN_0, 0);\r
198                          \r
199         /* Wait for the LCD to power up correctly. */\r
200         vTaskDelay( lcdLONG_DELAY );\r
201         vTaskDelay( lcdLONG_DELAY );\r
202         vTaskDelay( lcdLONG_DELAY );\r
203 \r
204         /* Set up the LCD function. */\r
205         prvLCDCommand( LCD_FUNCTION_SET_CMD | LCD_FUNCTION_SET_8_BITS | LCD_FUNCTION_SET_2_LINES | LCD_FUNCTION_SET_LRG_FONT );\r
206         \r
207         /* Turn the display on. */\r
208         prvLCDCommand( LCD_DISPLAY_CTRL_CMD | LCD_DISPLAY_CTRL_DISPLAY_ON );\r
209         \r
210         /* Clear the display. */\r
211         prvLCDCommand( LCD_CLEAR_DISPLAY_CMD );\r
212         vTaskDelay( lcdLONG_DELAY );    \r
213         \r
214         /* Increase the cursor. */\r
215         prvLCDCommand( LCD_ENTRY_MODE_CMD | LCD_ENTRY_MODE_INCREASE );\r
216         vTaskDelay( lcdLONG_DELAY );                    \r
217         vTaskDelay( lcdLONG_DELAY );                    \r
218         vTaskDelay( lcdLONG_DELAY );\r
219 }\r
220 /*-----------------------------------------------------------*/\r
221 \r
222 static void vLCDTask(void *pvParameters)\r
223 {\r
224 xLCDMessage xMessage;\r
225 unsigned portSHORT usRow = 0;\r
226 \r
227         /* Initialise the hardware.  This uses delays so must not be called prior\r
228         to the scheduler being started. */\r
229         prvSetupLCD();\r
230 \r
231         /* Welcome message. */\r
232         prvLCDPutString( "www.FreeRTOS.org" );\r
233 \r
234         for(;;)\r
235         {\r
236                 /* Wait for a message to arrive that requires displaying. */\r
237                 while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );\r
238 \r
239                 /* Clear the current display value. */\r
240                 prvLCDClear();\r
241 \r
242                 /* Switch rows each time so we can see that the display is still being\r
243                 updated. */\r
244                 prvLCDGotoRow( usRow & 0x01 );\r
245                 usRow++;\r
246                 prvLCDPutString( xMessage.pcMessage );\r
247 \r
248                 /* Delay the requested amount of time to ensure the text just written \r
249                 to the LCD is not overwritten. */\r
250                 vTaskDelay( xMessage.xMinDisplayTime );         \r
251         }\r
252 }\r
253 \r
254 \r
255 \r
256 \r