]> git.sur5r.net Git - freertos/blob - Demo/MB96350_Softune_Dice_Kit/SegmentToggleTasks.c
Tidy up and prepare for release.
[freertos] / Demo / MB96350_Softune_Dice_Kit / SegmentToggleTasks.c
1 /*\r
2         FreeRTOS.org V5.1.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     *                                                                         *\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  * Defines the tasks and co-routines used to toggle the segments of the two\r
52  * seven segment displays, as described at the top of main.c\r
53  */\r
54 \r
55 \r
56 #include <stdlib.h>\r
57 \r
58 /* Scheduler include files. */\r
59 #include "FreeRTOS.h"\r
60 #include "task.h"\r
61 #include "croutine.h"\r
62 \r
63 /* Demo program include files. */\r
64 #include "partest.h"\r
65 \r
66 /*-----------------------------------------------------------*/\r
67 \r
68 /* One task per segment of the left side display. */\r
69 #define ledNUM_OF_LED_TASKS     ( 7 )\r
70 \r
71 /* Each task toggles at a frequency that is a multiple of 333ms. */\r
72 #define ledFLASH_RATE_BASE      ( ( portTickType ) 333 )\r
73 \r
74 /* One co-routine per segment of the right hand display. */\r
75 #define ledNUM_OF_LED_CO_ROUTINES       7\r
76 \r
77 /* All co-routines run at the same priority. */\r
78 #define ledCO_ROUTINE_PRIORITY          0\r
79 \r
80 /*-----------------------------------------------------------*/\r
81 \r
82 /* The task that is created 7 times. */\r
83 static void vLEDFlashTask( void *pvParameters );\r
84 \r
85 /* The co-routine that is created 7 times. */\r
86 static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex );\r
87 \r
88 /* This task is created once, but itself creates 7 co-routines. */\r
89 static void vLEDCoRoutineControlTask( void *pvParameters );\r
90 \r
91 /* Handles to each of the 7 tasks.  Used so the tasks can be suspended\r
92 and resumed. */\r
93 static xTaskHandle xFlashTaskHandles[ ledNUM_OF_LED_TASKS ] = { 0 };\r
94 \r
95 /* Handle to the task in which the co-routines run.  Used so the\r
96 co-routines can be suspended and resumed. */\r
97 static xTaskHandle xCoroutineTask;\r
98 \r
99 /*-----------------------------------------------------------*/\r
100 \r
101 /**\r
102  * Creates the tasks and co-routines used to toggle the segments of the two\r
103  * seven segment displays, as described at the top of main.c\r
104  */\r
105 void vCreateFlashTasksAndCoRoutines( void )\r
106 {\r
107 signed short sLEDTask;\r
108 \r
109         /* Create the tasks that flash segments on the first LED. */\r
110         for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask )\r
111         {\r
112                 /* Spawn the task. */\r
113                 xTaskCreate( vLEDFlashTask, ( signed char * ) "LEDt", configMINIMAL_STACK_SIZE, ( void * ) sLEDTask, ( tskIDLE_PRIORITY + 1 ), &( xFlashTaskHandles[ sLEDTask ] ) );\r
114         }\r
115 \r
116         /* Create the task in which the co-routines run.  The co-routines themselves\r
117         are created within the task. */\r
118         xTaskCreate( vLEDCoRoutineControlTask, ( signed char * ) "LEDc", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xCoroutineTask );\r
119 }\r
120 /*-----------------------------------------------------------*/\r
121 \r
122 void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks )\r
123 {\r
124 short sLEDTask;\r
125 \r
126         if( ucIndex == configLEFT_DISPLAY )\r
127         {\r
128                 /* Suspend or resume the tasks that are toggling the segments of the\r
129                 left side display. */\r
130                 for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask )\r
131                 {\r
132                         if( xFlashTaskHandles[ sLEDTask ] != NULL )\r
133                         {\r
134                                 if( sSuspendTasks == pdTRUE )\r
135                                 {\r
136                                         vTaskSuspend( xFlashTaskHandles[ sLEDTask ] );\r
137                                 }\r
138                                 else\r
139                                 {\r
140                                         vTaskResume( xFlashTaskHandles[ sLEDTask ] );\r
141                                 }\r
142                         }\r
143                 }\r
144         }\r
145         else\r
146         {\r
147                 /* Suspend or resume the task in which the co-routines are running.  The\r
148                 co-routines toggle the segments of the right side display. */\r
149                 if( sSuspendTasks == pdTRUE )\r
150                 {\r
151                         vTaskSuspend( xCoroutineTask );\r
152                 }\r
153                 else\r
154                 {\r
155                         vTaskResume( xCoroutineTask );\r
156                 }\r
157         }\r
158 }\r
159 /*-----------------------------------------------------------*/\r
160 \r
161 static void vLEDFlashTask( void * pvParameters )\r
162 {\r
163 portTickType xFlashRate, xLastFlashTime;\r
164 unsigned short usLED;\r
165 \r
166         /* The LED to flash is passed in as the task parameter. */\r
167         usLED = ( unsigned short ) pvParameters;\r
168 \r
169         /* Calculate the rate at which this task is going to toggle its LED. */\r
170         xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) usLED );\r
171         xFlashRate /= portTICK_RATE_MS;\r
172 \r
173         /* We will turn the LED on and off again in the delay period, so each\r
174         delay is only half the total period. */\r
175         xFlashRate /= ( portTickType ) 2;\r
176 \r
177         /* We need to initialise xLastFlashTime prior to the first call to \r
178         vTaskDelayUntil(). */\r
179         xLastFlashTime = xTaskGetTickCount();\r
180 \r
181         for(;;)\r
182         {\r
183                 /* Delay for half the flash period then turn the LED on. */\r
184                 vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
185                 vParTestToggleLED( usLED );\r
186 \r
187                 /* Delay for half the flash period then turn the LED off. */\r
188                 vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
189                 vParTestToggleLED( usLED );\r
190         }\r
191 }\r
192 /*-----------------------------------------------------------*/\r
193 \r
194 static void vLEDCoRoutineControlTask( void *pvParameters )\r
195 {\r
196 unsigned short usCoroutine;\r
197 \r
198         ( void ) pvParameters;\r
199 \r
200         /* Create the co-routines - one of each segment of the right side display. */\r
201         for( usCoroutine = 0; usCoroutine < ledNUM_OF_LED_CO_ROUTINES; usCoroutine++ )\r
202         {\r
203                 xCoRoutineCreate( prvFixedDelayCoRoutine, ledCO_ROUTINE_PRIORITY, usCoroutine );\r
204         }\r
205 \r
206         /* This task has nothing else to do except scheduler the co-routines it just\r
207         created. */\r
208         for( ;; )\r
209         {\r
210                 vCoRoutineSchedule();\r
211         }\r
212 }\r
213 /*-----------------------------------------------------------*/\r
214 \r
215 static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex )\r
216 {\r
217 /* The usIndex parameter of the co-routine function is used as an index into\r
218 the xFlashRates array to obtain the delay period to use. */\r
219 static const portTickType xFlashRates[ ledNUM_OF_LED_CO_ROUTINES ] = { 150 / portTICK_RATE_MS,\r
220                                                                                                                                 300 / portTICK_RATE_MS,\r
221                                                                                                                                 450 / portTICK_RATE_MS,\r
222                                                                                                                                 600 / portTICK_RATE_MS,\r
223                                                                                                                                 750 / portTICK_RATE_MS,\r
224                                                                                                                                 900 / portTICK_RATE_MS,\r
225                                                                                                                                 1050 / portTICK_RATE_MS };\r
226 \r
227         /* Co-routines MUST start with a call to crSTART. */\r
228         crSTART( xHandle );\r
229 \r
230         for( ;; )\r
231         {\r
232                 /* Toggle the LED.  An offset of 8 is used to skip over the segments of\r
233                 the left side display which use the low numbers. */\r
234                 vParTestToggleLED( usIndex + 8 );\r
235 \r
236                 /* Delay until it is time to toggle the segment that this co-routine is\r
237                 controlling again. */\r
238                 crDELAY( xHandle, xFlashRates[ usIndex ] );\r
239         }\r
240 \r
241         /* Co-routines MUST end with a call to crEND. */\r
242         crEND();\r
243 }\r
244 /*-----------------------------------------------------------*/\r
245 \r
246 \r