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