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