]> git.sur5r.net Git - freertos/blob - Demo/NEC_78K0R_IAR/LEDtoggle/LED.c
Continue 78K0R development.
[freertos] / Demo / NEC_78K0R_IAR / LEDtoggle / LED.c
1 /*\r
2         FreeRTOS.org V5.0.2 - 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 /**\r
51  * This is a simple LED toggle test for the 78K0R/Kx3 Target Board (QB-78K0RKG3-TB).\r
52  *\r
53  * Creates two task that control one LED each. \r
54  *\r
55  * The first task toggles a LED with a frequency of 1Hz by using the vTaskDelay \r
56  * function. So the task is yielded for 1 seconed after each LED switch.\r
57  *\r
58  * The second LED can be toggled by a switch within the second task.\r
59  * When the switch is pushed it is detected by an interrupt. When the interrupt\r
60  * occurs a flag is set in the ISR and sent to the second task by using a queue. \r
61  * Therefore the  xQueueSendFromISR() function is called from within the ISR to\r
62  * write the flag value to the queue. The task uses the xQueueReceive() function\r
63  * to read the flag value from the queue.\r
64  * If the flag value changed from the last task activation the LED is toggled.\r
65  * \r
66  * Also a check function is implemented to check if the task still run properly\r
67  */\r
68 \r
69 /* Scheduler include files. */\r
70 #include "FreeRTOS.h"\r
71 #include "task.h"\r
72 \r
73 /* Demo program include files. */\r
74 #include "LED.h"\r
75 #include "queue.h"\r
76 #include "print.h"\r
77 \r
78 #define LEDToggleSTACK_SIZE (( unsigned portSHORT ) configMINIMAL_STACK_SIZE)\r
79 #define LED_NUMBER_OF_TASKS   2 \r
80 \r
81 /* LED toggle wait time and check definitions */\r
82 #define LED1_Wait_Time  1000\r
83 #define LED2_Wait_Time  100\r
84 \r
85 /* Task function prototypes */\r
86 static void vLEDToggleTask1( void *pvParameters);\r
87 static void vLEDToggleTask2( void *pvParameters);\r
88 \r
89 /* Port Initialization for LED's and Switch */\r
90 static void prvLEDInit(void);\r
91 \r
92 /* Switch press counter */\r
93 static unsigned portSHORT usClick = 0;\r
94 \r
95 /* Queue used for LED02 toggle*/ \r
96 static xQueueHandle xLEDQueue;\r
97 \r
98 /*xQUEUE *xLEDQueue;*/ \r
99 \r
100 static volatile unsigned portSHORT usTask1Check = 0, usTask2Check = 0, usLEDQueue = 0;\r
101 \r
102 void vStartLEDToggleTasks( unsigned portBASE_TYPE uxPriority )\r
103 {\r
104 \r
105 const unsigned portBASE_TYPE uxQueueSize = 4;\r
106 \r
107         prvLEDInit();\r
108 \r
109         /* Create the queue used by the Switch ISR and the second task. */\r
110         xLEDQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) );\r
111         /* create 2 LED toggle Tasks */\r
112         xTaskCreate(vLEDToggleTask1, "LEDTog1", LEDToggleSTACK_SIZE, ( void * ) &(usTask1Check), uxPriority, NULL );\r
113         xTaskCreate(vLEDToggleTask2, "LEDTog2", LEDToggleSTACK_SIZE, ( void * ) &xLEDQueue, uxPriority, NULL );  \r
114 }\r
115 /*-----------------------------------------------------------*/\r
116 \r
117 static void vLEDToggleTask1( void *pvParameters)\r
118 {\r
119 static portCHAR pcLED1old;\r
120 portSHORT sError = pdFALSE;\r
121 volatile unsigned portSHORT *pusTaskCheckVariable;\r
122 const portCHAR * const pcTaskFailMsg = "ERROR: LED toggle failed.\r\n";\r
123   \r
124         pusTaskCheckVariable = ( unsigned portSHORT * ) pvParameters;  \r
125         for(;;)\r
126         {\r
127                 pcLED1old = LED01;\r
128                 \r
129                 vTaskDelay( LED1_Wait_Time );\r
130                 /* toggle the LED01 */\r
131                 LED01 = ~LED01;\r
132 \r
133                 if(pcLED1old == LED01)\r
134                 {\r
135                         /* an error has occured */\r
136                         vPrintDisplayMessage( &pcTaskFailMsg );\r
137                         sError = pdTRUE;\r
138                 }\r
139                 \r
140                 if(sError != pdTRUE)\r
141                 {\r
142                         /* If a LED toggle has been made, increment the check\r
143                         variable so we know this task is still running okay. */\r
144                         ( *pusTaskCheckVariable )++;\r
145                 }\r
146         }              \r
147\r
148 /*-----------------------------------------------------------*/\r
149 \r
150 static void vLEDToggleTask2( void *pvParameters)\r
151 {\r
152 unsigned portSHORT usData, usDataOld = 0;\r
153 xQueueHandle *pxQueue;\r
154  \r
155         pxQueue = ( xQueueHandle * ) pvParameters;\r
156         for(;;)\r
157         {\r
158                 if( xQueueReceive( *pxQueue, &usData, ( portTickType ) 0 ) == pdPASS )\r
159                 {\r
160                         if (usData != usDataOld)\r
161                         {\r
162                                 LED02 = ~LED02;\r
163                         }\r
164                         usDataOld = usData;\r
165                 }\r
166                 vTaskDelay( LED2_Wait_Time );\r
167                 /* increment check variable whenever the task gets active */\r
168                 usTask2Check++;\r
169         }              \r
170 }\r
171 \r
172 portBASE_TYPE xAreLEDToggleTaskStillRunning( void )\r
173 {\r
174 /* \r
175  * Keep a history of the check variables so we know if they have been incremented \r
176  * since the last call.\r
177  */\r
178 static unsigned portSHORT usLastTask1Check = 0;\r
179 static unsigned portSHORT usLastTask2Check = 0;\r
180 portBASE_TYPE xReturn = pdTRUE;\r
181 \r
182         /* Check the LED toggle tasks are still running by ensuring their check variables \r
183          * are still incrementing. \r
184          */\r
185         if(( usTask1Check == usLastTask1Check )||(usLastTask2Check == usTask2Check))\r
186         {\r
187                 /* The check has not incremented so an error exists. */\r
188                 xReturn = pdFALSE;\r
189         }\r
190 \r
191         usLastTask1Check = usTask1Check;\r
192         usLastTask2Check = usTask2Check;\r
193 \r
194         return xReturn;\r
195 }\r
196 /*-----------------------------------------------------------*/\r
197 \r
198 static void prvLEDInit(void)\r
199 {\r
200 /* LED Port Initialization */\r
201         /* set Port Register */\r
202         P7  = 0x80;\r
203         /* set Port Mode Register */\r
204         PM7 = 0x3F;  \r
205 \r
206 /* Switch Pin Initialization */        \r
207         /* enable pull-up resistor */ \r
208         PU12_bit.no0  = 1;               \r
209         /* INTP0 disable */\r
210         PMK0 = 1;                       \r
211         /* INTP0 IF clear */\r
212         PIF0 = 0;                       \r
213         EGN0_bit.no0  = 1;\r
214         /* INTP0 priority low */\r
215         PPR10 = 0;\r
216         PPR00 = 1;\r
217         /* enable ext. INTP0 interrupt */\r
218         PMK0  = 0; \r
219 }\r
220 /*-----------------------------------------------------------*/\r
221 \r
222 /* Switch ISR */\r
223 \r
224 #pragma vector=INTP0_vect\r
225 __interrupt void P0_isr (void)\r
226 {\r
227         /* Increment Switch pressed counter */\r
228         usClick++;\r
229         /* Use usClick to signalize a detected Interrupt for the vLEDToggleTask2\r
230          * to toggle the LED02.\r
231          */\r
232         xQueueSendFromISR( xLEDQueue, &usClick, pdFALSE );\r
233 }\r
234 /*-----------------------------------------------------------*/