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