OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [MB96350_Softune_Dice_Kit/] [DiceTask.c] - Blame information for rev 851

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 584 jeremybenn
/*
2
    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
3
 
4
    ***************************************************************************
5
    *                                                                         *
6
    * If you are:                                                             *
7
    *                                                                         *
8
    *    + New to FreeRTOS,                                                   *
9
    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
10
    *    + Looking for basic training,                                        *
11
    *    + Wanting to improve your FreeRTOS skills and productivity           *
12
    *                                                                         *
13
    * then take a look at the FreeRTOS books - available as PDF or paperback  *
14
    *                                                                         *
15
    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
16
    *                  http://www.FreeRTOS.org/Documentation                  *
17
    *                                                                         *
18
    * A pdf reference manual is also available.  Both are usually delivered   *
19
    * to your inbox within 20 minutes to two hours when purchased between 8am *
20
    * and 8pm GMT (although please allow up to 24 hours in case of            *
21
    * exceptional circumstances).  Thank you for your support!                *
22
    *                                                                         *
23
    ***************************************************************************
24
 
25
    This file is part of the FreeRTOS distribution.
26
 
27
    FreeRTOS is free software; you can redistribute it and/or modify it under
28
    the terms of the GNU General Public License (version 2) as published by the
29
    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
30
    ***NOTE*** The exception to the GPL is included to allow you to distribute
31
    a combined work that includes FreeRTOS without being obliged to provide the
32
    source code for proprietary components outside of the FreeRTOS kernel.
33
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
34
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
36
    more details. You should have received a copy of the GNU General Public
37
    License and the FreeRTOS license exception along with FreeRTOS; if not it
38
    can be viewed here: http://www.freertos.org/a00114.html and also obtained
39
    by writing to Richard Barry, contact details for whom are available on the
40
    FreeRTOS WEB site.
41
 
42
    1 tab == 4 spaces!
43
 
44
    http://www.FreeRTOS.org - Documentation, latest information, license and
45
    contact details.
46
 
47
    http://www.SafeRTOS.com - A version that is certified for use in safety
48
    critical systems.
49
 
50
    http://www.OpenRTOS.com - Commercial support, development, porting,
51
    licensing and training services.
52
*/
53
 
54
 
55
/*
56
 * Defines the 'dice' tasks as described at the top of main.c
57
 */
58
 
59
 
60
/* Kernel includes. */
61
#include "FreeRTOS.h"
62
#include "task.h"
63
#include "semphr.h"
64
 
65
/* Delays used within the dice functionality.  All delays are defined in milliseconds. */
66
#define diceDELAY_BETWEEN_RANDOM_NUMBERS_ms             ( 20 / portTICK_RATE_MS )
67
#define diceSHAKE_TIME                                                  ( ( 2000 / portTICK_RATE_MS ) / diceDELAY_BETWEEN_RANDOM_NUMBERS_ms )
68
#define diceSHORT_PAUSE_BEFORE_SHAKE                    ( 250 / portTICK_RATE_MS )
69
#define diceDELAY_WHILE_DISPLAYING_RESULT               ( 5000 / portTICK_RATE_MS )
70
 
71
/* Macro to access the display ports. */
72
#define dice7SEG_Value( x )             ( *( pucDisplayOutput[ x ] ) )
73
 
74
/* Checks the semaphore use to communicate button push events.  A block time
75
can be specified - this is the time to wait for a button push to occur should
76
one have not already occurred. */
77
#define prvButtonHit( ucIndex, xTicksToWait ) xSemaphoreTake( xSemaphores[ ucIndex ], xTicksToWait )
78
 
79
/* Defines the outputs required for each digit on the display. */
80
static const char cDisplaySegments[ 2 ][ 11 ] =
81
{
82
        { 0x48, 0xeb, 0x8c, 0x89, 0x2b, 0x19, 0x18, 0xcb, 0x08, 0x09, 0xf7 }, /* Left display. */
83
        { 0xa0, 0xf3, 0xc4, 0xc1, 0x93, 0x89, 0x88, 0xe3, 0x80, 0x81, 0x7f }  /* Right display. */
84
};
85
 
86
/* The semaphores used to communicate button push events between the button
87
input interrupt handlers and the dice tasks.  Two dice tasks are created so two
88
semaphores are required. */
89
static xSemaphoreHandle xSemaphores[ 2 ] = { 0 };
90
 
91
/* Defines the ports used to write to the display.  This variable is defined in
92
partest.c, which contains the LED set/clear/toggle functions. */
93
extern volatile unsigned char *pucDisplayOutput[ 2 ];
94
 
95
/*-----------------------------------------------------------*/
96
 
97
/*
98
 * Defines the 'dice' tasks as described at the top of main.c
99
 */
100
void vDiceTask( void *pvParameters )
101
{
102
unsigned char ucDiceValue, ucIndex;
103
unsigned long ulDiceRunTime;
104
extern void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks );
105
 
106
 
107
 
108
        /* Two instances of this task are created so the task parameter is used
109
        to pass in a constant that indicates whether this task is controlling
110
        the left side or right side display.  The constant is used as an index
111
        into the arrays defined at file scope within this file. */
112
        ucIndex = ( unsigned char ) pvParameters;
113
 
114
        /* A binary semaphore is used to signal button push events.  Create the
115
        semaphore before it is used. */
116
        vSemaphoreCreateBinary( xSemaphores[ ucIndex ] );
117
 
118
        /* Make sure the semaphore starts in the wanted state - no button pushes
119
        pending. This call will just clear any button pushes that are latched.
120
        Passing in 0 as the block time means the call will not wait for any further
121
        button pushes but instead return immediately. */
122
        prvButtonHit( ucIndex, 0 );
123
 
124
        /* Seed the random number generator. */
125
        srand( ( unsigned char ) diceSHAKE_TIME );
126
 
127
 
128
 
129
 
130
        /* Start the task proper.  A loop will be performed each time a button is
131
        pushed.  The task will remain in the blocked state (sleeping) until a
132
        button is pushed. */
133
        for( ;; )
134
        {
135
                /* Wait for a button push.  This task will enter the Blocked state
136
                (will not run again) until after a button has been pushed. */
137
                prvButtonHit( ucIndex, portMAX_DELAY );
138
 
139
                /* The next line will only execute after a button has been pushed -
140
                initialise the variable used to control the time the dice is shaken
141
                for. */
142
                ulDiceRunTime = diceSHAKE_TIME;
143
 
144
                /* Suspend the flash tasks so this task has exclusive access to the
145
                display. */
146
                vSuspendFlashTasks( ucIndex, pdTRUE );
147
 
148
                /* Clear the display and pause for a short time, before starting to
149
                shake. */
150
                *pucDisplayOutput[ ucIndex ] = 0xff;
151
                vTaskDelay( diceSHORT_PAUSE_BEFORE_SHAKE );
152
 
153
                /* Keep generating and displaying random numbers until the shake time
154
                expires. */
155
                while( ulDiceRunTime > 0 )
156
                {
157
                        ulDiceRunTime--;
158
 
159
                        /* Generate and display a random number. */
160
                        ucDiceValue = rand() % 6 + 1;
161
                        dice7SEG_Value( ucIndex ) = ( dice7SEG_Value( ucIndex ) | 0xf7 ) & cDisplaySegments[ ucIndex ][ ucDiceValue ];
162
 
163
                        /* Block/sleep for a very short time before generating the next
164
                        random number. */
165
                        vTaskDelay( diceDELAY_BETWEEN_RANDOM_NUMBERS_ms );
166
                }
167
 
168
 
169
 
170
                /* Clear any button pushes that are pending because a button bounced, or
171
                was pressed while the dice were shaking.  Again a block time of zero is
172
                used so the function does not wait for any pushes but instead returns
173
                immediately. */
174
                prvButtonHit( ucIndex, 0 );
175
 
176
                /* Delay for a short while to display the dice shake result.  Use a queue
177
                peek here instead of a vTaskDelay() allows the delay to be interrupted by
178
                a button push.  If a button is pressed xQueuePeek() will return but the
179
                button push will remain pending to be read again at the top of this for
180
                loop.  It is safe to uses a queue function on a semaphore handle as
181
                semaphores are implemented as macros that uses queues, so the two are
182
                basically the same thing. */
183
                xQueuePeek( xSemaphores[ ucIndex ], NULL, diceDELAY_WHILE_DISPLAYING_RESULT );
184
 
185
                /* Clear the display then resume the tasks or co-routines that were using
186
                the segments of the display. */
187
                *pucDisplayOutput[ ucIndex ] = 0xff;
188
                vSuspendFlashTasks( ucIndex, pdFALSE );
189
        }
190
}
191
/*-----------------------------------------------------------*/
192
 
193
/* Handler for the SW2 button push interrupt. */
194
__interrupt void vExternalInt8Handler( void )
195
{
196
short sHigherPriorityTaskWoken = pdFALSE;
197
 
198
        /* Reset the interrupt. */
199
        EIRR1_ER8 = 0;
200
 
201
        /* Check the semaphore has been created before attempting to use it. */
202
        if( xSemaphores[ configLEFT_DISPLAY ] != NULL )
203
        {
204
                /* Send a message via the semaphore to the dice task that controls the
205
                left side display.  This will unblock the task if it is blocked waiting
206
                for a button push. */
207
                xSemaphoreGiveFromISR( xSemaphores[ configLEFT_DISPLAY ], &sHigherPriorityTaskWoken );
208
        }
209
 
210
        /* If sending the semaphore unblocked a task, and the unblocked task has a
211
        priority that is higher than the currently running task, then force a context
212
        switch. */
213
        if( sHigherPriorityTaskWoken != pdFALSE )
214
        {
215
                portYIELD_FROM_ISR();
216
        }
217
}
218
/*-----------------------------------------------------------*/
219
 
220
/* As per vExternalInt8Handler(), but for SW3 and the right side display. */
221
__interrupt void vExternalInt9Handler( void )
222
{
223
short sHigherPriorityTaskWoken = pdFALSE;
224
 
225
        /* Reset the interrupt. */
226
        EIRR1_ER9 = 0;
227
 
228
        if( xSemaphores[ configRIGHT_DISPLAY ] != NULL )
229
        {
230
                xSemaphoreGiveFromISR( xSemaphores[ configRIGHT_DISPLAY ], &sHigherPriorityTaskWoken );
231
        }
232
 
233
        if( sHigherPriorityTaskWoken != pdFALSE )
234
        {
235
                portYIELD_FROM_ISR();
236
        }
237
}
238
 
239
 
240
 
241
 
242
 
243
 
244
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.