]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/PIC24_MPLAB/lcd.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / PIC24_MPLAB / lcd.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /* Scheduler includes. */\r
30 #include "FreeRTOS.h"\r
31 #include "task.h"\r
32 #include "queue.h"\r
33 \r
34 /* Demo includes. */\r
35 #include "lcd.h"\r
36 \r
37 /*\r
38  * The LCD is written to by more than one task so is controlled by this\r
39  * 'gatekeeper' task.  This is the only task that is actually permitted to\r
40  * access the LCD directly.  Other tasks wanting to display a message send\r
41  * the message to the gatekeeper.\r
42  */\r
43 static void vLCDTask( void *pvParameters );\r
44 \r
45 /*\r
46  * Setup the peripherals required to communicate with the LCD.\r
47  */\r
48 static void prvSetupLCD( void );\r
49 \r
50 /* \r
51  * Move to the first (0) or second (1) row of the LCD. \r
52  */\r
53 static void prvLCDGotoRow( unsigned short usRow );\r
54 \r
55 /* \r
56  * Write a string of text to the LCD. \r
57  */\r
58 static void prvLCDPutString( char *pcString );\r
59 \r
60 /* \r
61  * Clear the LCD. \r
62  */\r
63 static void prvLCDClear( void );\r
64 \r
65 /*-----------------------------------------------------------*/\r
66 \r
67 /* Brief delay to permit the LCD to catch up with commands. */\r
68 #define lcdSHORT_DELAY          3\r
69 \r
70 /* SFR that seems to be missing from the standard header files. */\r
71 #define PMAEN                           *( ( unsigned short * ) 0x60c )\r
72 \r
73 /* LCD commands. */\r
74 #define lcdDEFAULT_FUNCTION     0x3c\r
75 #define lcdDISPLAY_CONTROL      0x0c\r
76 #define lcdCLEAR_DISPLAY        0x01\r
77 #define lcdENTRY_MODE           0x06\r
78 \r
79 /* The length of the queue used to send messages to the LCD gatekeeper task. */\r
80 #define lcdQUEUE_SIZE           3\r
81 /*-----------------------------------------------------------*/\r
82 \r
83 /* The queue used to send messages to the LCD task. */\r
84 QueueHandle_t xLCDQueue;\r
85 \r
86 \r
87 /*-----------------------------------------------------------*/\r
88 \r
89 QueueHandle_t xStartLCDTask( void )\r
90 {\r
91         /* Create the queue used by the LCD task.  Messages for display on the LCD\r
92         are received via this queue. */\r
93         xLCDQueue = xQueueCreate( lcdQUEUE_SIZE, sizeof( xLCDMessage ) );\r
94 \r
95         /* Start the task that will write to the LCD.  The LCD hardware is\r
96         initialised from within the task itself so delays can be used. */\r
97         xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );\r
98 \r
99         return xLCDQueue;\r
100 }\r
101 /*-----------------------------------------------------------*/\r
102 \r
103 static void prvLCDGotoRow( unsigned short usRow )\r
104 {\r
105         if( usRow == 0 )\r
106         {\r
107                 PMADDR = 0x0000;\r
108                 PMDIN1 = 0x02;\r
109         }\r
110         else\r
111         {\r
112                 PMADDR = 0x0000;\r
113                 PMDIN1 = 0xc0;\r
114         }\r
115 \r
116         vTaskDelay( lcdSHORT_DELAY );\r
117 }\r
118 /*-----------------------------------------------------------*/\r
119 \r
120 static void prvLCDPutString( char *pcString )\r
121 {\r
122         /* Write out each character with appropriate delay between each. */\r
123         while( *pcString )\r
124         {\r
125                 PMADDR = 0x0001;\r
126                 PMDIN1 = *pcString;\r
127                 pcString++;\r
128                 vTaskDelay( lcdSHORT_DELAY );\r
129         }\r
130 }\r
131 /*-----------------------------------------------------------*/\r
132 \r
133 static void prvLCDClear( void )\r
134 {\r
135         /* Clear the display. */\r
136         PMADDR = 0x0000;\r
137         PMDIN1 = lcdCLEAR_DISPLAY;\r
138         vTaskDelay( lcdSHORT_DELAY );   \r
139 }\r
140 /*-----------------------------------------------------------*/\r
141 \r
142 static void prvSetupLCD( void )\r
143 {\r
144         /* Setup the PMP. */\r
145         PMCON = 0x83BF;\r
146         PMMODE = 0x3FF;\r
147         PMAEN = 1;\r
148         PMADDR = 0x0000;\r
149         vTaskDelay( lcdSHORT_DELAY );\r
150 \r
151         /* Set the default function. */\r
152         PMDIN1 = lcdDEFAULT_FUNCTION;\r
153         vTaskDelay( lcdSHORT_DELAY );\r
154 \r
155         /* Set the display control. */\r
156         PMDIN1 = lcdDISPLAY_CONTROL;\r
157         vTaskDelay( lcdSHORT_DELAY );\r
158 \r
159         /* Clear the display. */\r
160         PMDIN1 = lcdCLEAR_DISPLAY;\r
161         vTaskDelay( lcdSHORT_DELAY );\r
162 \r
163         /* Set the entry mode. */\r
164         PMDIN1 = lcdENTRY_MODE;\r
165         vTaskDelay( lcdSHORT_DELAY );\r
166 }\r
167 /*-----------------------------------------------------------*/\r
168 \r
169 static void vLCDTask( void *pvParameters )\r
170 {\r
171 xLCDMessage xMessage;\r
172 unsigned short usRow = 0;\r
173 \r
174         /* Remove compiler warnigns. */\r
175         ( void ) pvParameters;\r
176 \r
177         /* Initialise the hardware.  This uses delays so must not be called prior\r
178         to the scheduler being started. */\r
179         prvSetupLCD();\r
180 \r
181         /* Welcome message. */\r
182         prvLCDPutString( "www.FreeRTOS.org" );\r
183 \r
184         for( ;; )\r
185         {\r
186                 /* Wait for a message to arrive that requires displaying. */\r
187                 while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );\r
188 \r
189                 /* Clear the current display value. */\r
190                 prvLCDClear();\r
191 \r
192                 /* Switch rows each time so we can see that the display is still being\r
193                 updated. */\r
194                 prvLCDGotoRow( usRow & 0x01 );\r
195                 usRow++;\r
196                 prvLCDPutString( xMessage.pcMessage );\r
197 \r
198                 /* Delay the requested amount of time to ensure the text just written \r
199                 to the LCD is not overwritten. */\r
200                 vTaskDelay( xMessage.xMinDisplayTime );         \r
201         }\r
202 }\r
203 \r
204 \r
205 \r
206 \r