]> git.sur5r.net Git - freertos/blob - Demo/PIC24_MPLAB/lcd.c
Update to V5.0.0.
[freertos] / Demo / PIC24_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 /* Scheduler includes. */\r
51 #include "FreeRTOS.h"\r
52 #include "task.h"\r
53 #include "queue.h"\r
54 \r
55 /* Demo includes. */\r
56 #include "lcd.h"\r
57 \r
58 /*\r
59  * The LCD is written to by more than one task so is controlled by this\r
60  * 'gatekeeper' task.  This is the only task that is actually permitted to\r
61  * access the LCD directly.  Other tasks wanting to display a message send\r
62  * the message to the gatekeeper.\r
63  */\r
64 static void vLCDTask( void *pvParameters );\r
65 \r
66 /*\r
67  * Setup the peripherals required to communicate with the LCD.\r
68  */\r
69 static void prvSetupLCD( void );\r
70 \r
71 /* \r
72  * Move to the first (0) or second (1) row of the LCD. \r
73  */\r
74 static void prvLCDGotoRow( unsigned portSHORT usRow );\r
75 \r
76 /* \r
77  * Write a string of text to the LCD. \r
78  */\r
79 static void prvLCDPutString( portCHAR *pcString );\r
80 \r
81 /* \r
82  * Clear the LCD. \r
83  */\r
84 static void prvLCDClear( void );\r
85 \r
86 /*-----------------------------------------------------------*/\r
87 \r
88 /* Brief delay to permit the LCD to catch up with commands. */\r
89 #define lcdSHORT_DELAY          3\r
90 \r
91 /* SFR that seems to be missing from the standard header files. */\r
92 #define PMAEN                           *( ( unsigned short * ) 0x60c )\r
93 \r
94 /* LCD commands. */\r
95 #define lcdDEFAULT_FUNCTION     0x3c\r
96 #define lcdDISPLAY_CONTROL      0x0c\r
97 #define lcdCLEAR_DISPLAY        0x01\r
98 #define lcdENTRY_MODE           0x06\r
99 \r
100 /* The length of the queue used to send messages to the LCD gatekeeper task. */\r
101 #define lcdQUEUE_SIZE           3\r
102 /*-----------------------------------------------------------*/\r
103 \r
104 /* The queue used to send messages to the LCD task. */\r
105 xQueueHandle xLCDQueue;\r
106 \r
107 \r
108 /*-----------------------------------------------------------*/\r
109 \r
110 xQueueHandle xStartLCDTask( void )\r
111 {\r
112         /* Create the queue used by the LCD task.  Messages for display on the LCD\r
113         are received via this queue. */\r
114         xLCDQueue = xQueueCreate( lcdQUEUE_SIZE, sizeof( xLCDMessage ) );\r
115 \r
116         /* Start the task that will write to the LCD.  The LCD hardware is\r
117         initialised from within the task itself so delays can be used. */\r
118         xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );\r
119 \r
120         return xLCDQueue;\r
121 }\r
122 /*-----------------------------------------------------------*/\r
123 \r
124 static void prvLCDGotoRow( unsigned portSHORT usRow )\r
125 {\r
126         if( usRow == 0 )\r
127         {\r
128                 PMADDR = 0x0000;\r
129                 PMDIN1 = 0x02;\r
130         }\r
131         else\r
132         {\r
133                 PMADDR = 0x0000;\r
134                 PMDIN1 = 0xc0;\r
135         }\r
136 \r
137         vTaskDelay( lcdSHORT_DELAY );\r
138 }\r
139 /*-----------------------------------------------------------*/\r
140 \r
141 static void prvLCDPutString( portCHAR *pcString )\r
142 {\r
143         /* Write out each character with appropriate delay between each. */\r
144         while( *pcString )\r
145         {\r
146                 PMADDR = 0x0001;\r
147                 PMDIN1 = *pcString;\r
148                 pcString++;\r
149                 vTaskDelay( lcdSHORT_DELAY );\r
150         }\r
151 }\r
152 /*-----------------------------------------------------------*/\r
153 \r
154 static void prvLCDClear( void )\r
155 {\r
156         /* Clear the display. */\r
157         PMADDR = 0x0000;\r
158         PMDIN1 = lcdCLEAR_DISPLAY;\r
159         vTaskDelay( lcdSHORT_DELAY );   \r
160 }\r
161 /*-----------------------------------------------------------*/\r
162 \r
163 static void prvSetupLCD( void )\r
164 {\r
165         /* Setup the PMP. */\r
166         PMCON = 0x83BF;\r
167         PMMODE = 0x3FF;\r
168         PMAEN = 1;\r
169         PMADDR = 0x0000;\r
170         vTaskDelay( lcdSHORT_DELAY );\r
171 \r
172         /* Set the default function. */\r
173         PMDIN1 = lcdDEFAULT_FUNCTION;\r
174         vTaskDelay( lcdSHORT_DELAY );\r
175 \r
176         /* Set the display control. */\r
177         PMDIN1 = lcdDISPLAY_CONTROL;\r
178         vTaskDelay( lcdSHORT_DELAY );\r
179 \r
180         /* Clear the display. */\r
181         PMDIN1 = lcdCLEAR_DISPLAY;\r
182         vTaskDelay( lcdSHORT_DELAY );\r
183 \r
184         /* Set the entry mode. */\r
185         PMDIN1 = lcdENTRY_MODE;\r
186         vTaskDelay( lcdSHORT_DELAY );\r
187 }\r
188 /*-----------------------------------------------------------*/\r
189 \r
190 static void vLCDTask( void *pvParameters )\r
191 {\r
192 xLCDMessage xMessage;\r
193 unsigned portSHORT usRow = 0;\r
194 \r
195         /* Initialise the hardware.  This uses delays so must not be called prior\r
196         to the scheduler being started. */\r
197         prvSetupLCD();\r
198 \r
199         /* Welcome message. */\r
200         prvLCDPutString( "www.FreeRTOS.org" );\r
201 \r
202         for( ;; )\r
203         {\r
204                 /* Wait for a message to arrive that requires displaying. */\r
205                 while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );\r
206 \r
207                 /* Clear the current display value. */\r
208                 prvLCDClear();\r
209 \r
210                 /* Switch rows each time so we can see that the display is still being\r
211                 updated. */\r
212                 prvLCDGotoRow( usRow & 0x01 );\r
213                 usRow++;\r
214                 prvLCDPutString( xMessage.pcMessage );\r
215 \r
216                 /* Delay the requested amount of time to ensure the text just written \r
217                 to the LCD is not overwritten. */\r
218                 vTaskDelay( xMessage.xMinDisplayTime );         \r
219         }\r
220 }\r
221 \r
222 \r
223 \r
224 \r