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