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