summaryrefslogtreecommitdiff
path: root/boards/dk-tm4c129x/freertos_demo/spider_task.c
diff options
context:
space:
mode:
authorYuval Adam <yuv.adm@gmail.com>2014-06-29 12:34:32 +0300
committerYuval Adam <yuv.adm@gmail.com>2014-06-29 12:34:32 +0300
commitc3e4c9a25c2910d2d66d52215b3406b13d5b23d5 (patch)
treeadded370d1e356901f8579f076e3263fb0464db7 /boards/dk-tm4c129x/freertos_demo/spider_task.c
parent990090a4cc9070837d31e66b58d40f0c3d038741 (diff)
Add more board models
Diffstat (limited to 'boards/dk-tm4c129x/freertos_demo/spider_task.c')
-rw-r--r--boards/dk-tm4c129x/freertos_demo/spider_task.c855
1 files changed, 855 insertions, 0 deletions
diff --git a/boards/dk-tm4c129x/freertos_demo/spider_task.c b/boards/dk-tm4c129x/freertos_demo/spider_task.c
new file mode 100644
index 0000000..2f530c0
--- /dev/null
+++ b/boards/dk-tm4c129x/freertos_demo/spider_task.c
@@ -0,0 +1,855 @@
+//*****************************************************************************
+//
+// spider_task.c - Tasks to animate a set of spiders on the LCD, one task per
+// spider.
+//
+// Copyright (c) 2009-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the DK-TM4C129X Firmware Package.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "inc/hw_ints.h"
+#include "inc/hw_types.h"
+#include "driverlib/interrupt.h"
+#include "grlib/grlib.h"
+#include "grlib/widget.h"
+#include "drivers/touch.h"
+#include "display_task.h"
+#include "idle_task.h"
+#include "images.h"
+#include "priorities.h"
+#include "random.h"
+#include "freertos_demo.h"
+#include "spider_task.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+//*****************************************************************************
+//
+// The stack size for the spider control task.
+//
+//*****************************************************************************
+# define STACKSIZE_CONTROLTASK 128
+
+//*****************************************************************************
+//
+// The stack sizes for the spider tasks.
+//
+//*****************************************************************************
+# define STACKSIZE_SPIDERTASK 128
+
+//*****************************************************************************
+//
+// The following define the screen area in which the spiders are allowed to
+// roam
+//
+//*****************************************************************************
+#define AREA_X 8
+#define AREA_Y 24
+#define AREA_WIDTH 303
+#define AREA_HEIGHT (231 - 24 - 20)
+
+//*****************************************************************************
+//
+// The size of the spider images.
+//
+//*****************************************************************************
+#define SPIDER_WIDTH 24
+#define SPIDER_HEIGHT 24
+
+//*****************************************************************************
+//
+// The following define the extents of the centroid of the spiders.
+//
+//*****************************************************************************
+#define SPIDER_MIN_X (AREA_X + (SPIDER_WIDTH / 2))
+#define SPIDER_MAX_X (AREA_X + AREA_WIDTH - (SPIDER_WIDTH / 2))
+#define SPIDER_MIN_Y (AREA_Y + (SPIDER_HEIGHT / 2))
+#define SPIDER_MAX_Y (AREA_Y + AREA_HEIGHT - (SPIDER_HEIGHT / 2))
+
+//*****************************************************************************
+//
+// The item size, queue size, and memory size for the spider control message
+// queue.
+//
+//*****************************************************************************
+#define CONTROL_ITEM_SIZE sizeof(unsigned long)
+#define CONTROL_QUEUE_SIZE 10
+
+//*****************************************************************************
+//
+// The queue that holds messages sent to the spider control task.
+//
+//*****************************************************************************
+static xQueueHandle g_pControlQueue;
+
+//*****************************************************************************
+//
+// The amount the spider moves horizontally for each direction of movement.
+//
+// For this and all subsequent arrays that are indexed by direction of
+// movement, the indices are as follows:
+//
+// 0 => right
+// 1 => right and down
+// 2 => down
+// 3 => left and down
+// 4 => left
+// 5 => left and up
+// 6 => up
+// 7 => right and up
+//
+//*****************************************************************************
+static const int32_t g_pi32SpiderStepX[8] =
+{
+ 1, 1, 0, -1, -1, -1, 0, 1
+};
+
+//*****************************************************************************
+//
+// The amount the spider moves vertically for each direction of movement.
+//
+//*****************************************************************************
+static const int32_t g_pi32SpiderStepY[8] =
+{
+ 0, 1, 1, 1, 0, -1, -1, -1
+};
+
+//*****************************************************************************
+//
+// The animation images for the spider, two per direction of movement. In
+// other words, entries 0 and 1 correspond to direction 0 (right), entries 2
+// and 3 correspond to direction 1 (right and down), etc.
+//
+//*****************************************************************************
+static const uint8_t *g_ppui8SpiderImage[16] =
+{
+ g_pui8SpiderR1Image,
+ g_pui8SpiderR2Image,
+ g_pui8SpiderDR1Image,
+ g_pui8SpiderDR2Image,
+ g_pui8SpiderD1Image,
+ g_pui8SpiderD2Image,
+ g_pui8SpiderDL1Image,
+ g_pui8SpiderDL2Image,
+ g_pui8SpiderL1Image,
+ g_pui8SpiderL2Image,
+ g_pui8SpiderUL1Image,
+ g_pui8SpiderUL2Image,
+ g_pui8SpiderU1Image,
+ g_pui8SpiderU2Image,
+ g_pui8SpiderUR1Image,
+ g_pui8SpiderUR2Image
+};
+
+//*****************************************************************************
+//
+// The number of ticks to delay a spider task based on the direction of
+// movement. This array has only two entries; the first corresponding to
+// horizontal and vertical movement, and the second corresponding to diagonal
+// movement. By having the second entry be 1.4 times the first, the spiders
+// are updated slower when moving along the diagonal to compensate for the
+// fact that each step is further (since it is moving one step in both the
+// horizontal and vertical).
+//
+//*****************************************************************************
+uint32_t g_pui32SpiderDelay[2];
+
+//*****************************************************************************
+//
+// The horizontal position of the spiders.
+//
+//*****************************************************************************
+static int32_t g_pi32SpiderX[MAX_SPIDERS];
+
+//*****************************************************************************
+//
+// The vertical position of the spiders.
+//
+//*****************************************************************************
+static int32_t g_pi32SpiderY[MAX_SPIDERS];
+
+//*****************************************************************************
+//
+// A bitmap that indicates which spiders are alive (which corresponds to a
+// running task for that spider).
+//
+//*****************************************************************************
+static uint32_t g_ui32SpiderAlive;
+
+//*****************************************************************************
+//
+// A bitmap that indicates which spiders have been killed (by touching them).
+//
+//*****************************************************************************
+static uint32_t g_ui32SpiderDead;
+xTaskHandle g_sSpiderTask; // FIXME
+//*****************************************************************************
+//
+// Determines if a given point collides with one of the spiders. The spider
+// specified is ignored when doing collision detection in order to prevent a
+// false collision with itself (when checking to see if it is safe to move the
+// spider).
+//
+//*****************************************************************************
+static int32_t
+SpiderCollide(int32_t i32Spider, int32_t i32X, int32_t i32Y)
+{
+ int32_t i32Idx, i32DX, i32DY;
+
+ //
+ // Loop through all the spiders.
+ //
+ for(i32Idx = 0; i32Idx < MAX_SPIDERS; i32Idx++)
+ {
+ //
+ // Skip this spider if it is not alive or is the spider that should be
+ // ignored.
+ //
+ if((HWREGBITW(&g_ui32SpiderAlive, i32Idx) == 0) ||
+ (i32Idx == i32Spider))
+ {
+ continue;
+ }
+
+ //
+ // Compute the horizontal and vertical difference between this spider's
+ // position and the point in question.
+ //
+ i32DX = ((g_pi32SpiderX[i32Idx] > i32X) ?
+ (g_pi32SpiderX[i32Idx] - i32X) :
+ (i32X - g_pi32SpiderX[i32Idx]));
+ i32DY = ((g_pi32SpiderY[i32Idx] > i32Y) ?
+ (g_pi32SpiderY[i32Idx] - i32Y) :
+ (i32Y - g_pi32SpiderY[i32Idx]));
+
+ //
+ // Return this spider index if the point in question collides with it.
+ //
+ if((i32DX < SPIDER_WIDTH) && (i32DY < SPIDER_HEIGHT))
+ {
+ return(i32Idx);
+ }
+ }
+
+ //
+ // No collision was detected.
+ //
+ return(-1);
+}
+
+//*****************************************************************************
+//
+// This task manages the scurrying about of a spider.
+//
+//*****************************************************************************
+static void
+SpiderTask(void *pvParameters)
+{
+ uint32_t ui32Dir, ui32Image, ui32Temp;
+ int32_t i32X, i32Y, i32Spider;
+
+ //
+ // Get the spider number from the parameter.
+ //
+ i32Spider = (long)pvParameters;
+
+ //
+ // Add the current tick count to the random entropy pool.
+ //
+ RandomAddEntropy(xTaskGetTickCount());
+
+ //
+ // Reseed the random number generator.
+ //
+ RandomSeed();
+
+ //
+ // Indicate that this spider is alive.
+ //
+ HWREGBITW(&g_ui32SpiderAlive, i32Spider) = 1;
+
+ //
+ // Indicate that this spider is not dead yet.
+ //
+ HWREGBITW(&g_ui32SpiderDead, i32Spider) = 0;
+
+ //
+ // Get a local copy of the spider's starting position.
+ //
+ i32X = g_pi32SpiderX[i32Spider];
+ i32Y = g_pi32SpiderY[i32Spider];
+
+ //
+ // Choose a random starting direction for the spider.
+ //
+ ui32Dir = RandomNumber() >> 29;
+
+ //
+ // Start by displaying the first of the two spider animation images.
+ //
+ ui32Image = 0;
+
+ //
+ // Loop forever.
+ //
+ while(1)
+ {
+ //
+ // See if this spider has been killed.
+ //
+ if(HWREGBITW(&g_ui32SpiderDead, i32Spider) == 1)
+ {
+ //
+ // Wait for 2 seconds.
+ //
+ vTaskDelay((1000 / portTICK_RATE_MS) * 2);
+
+ //
+ // Clear the spider from the display.
+ //
+ DisplayImage(i32X - (SPIDER_WIDTH / 2), i32Y - (SPIDER_HEIGHT / 2),
+ g_pui8SpiderBlankImage);
+
+ //
+ // Indicate that this spider is not alive.
+ //
+ HWREGBITW(&g_ui32SpiderAlive, i32Spider) = 0;
+
+ //
+ // Delete the current task. This should never return.
+ //
+ vTaskDelete(NULL);
+
+ //
+ // In case it does return, loop forever.
+ //
+ while(1)
+ {
+ }
+ }
+
+ //
+ // Enter a critical section while the next move for the spider is
+ // determined. Having more than one spider trying to move at a time
+ // (via preemption) would make the collision detection check fail.
+ //
+ taskENTER_CRITICAL();
+
+ //
+ // Move the spider.
+ //
+ i32X += g_pi32SpiderStepX[ui32Dir];
+ i32Y += g_pi32SpiderStepY[ui32Dir];
+
+ //
+ // See if the spider has cross the boundary of its area, if it has
+ // collided with another spider, or if random chance says that the
+ // spider should turn despite not having collided with anything.
+ //
+ if((i32X < SPIDER_MIN_X) || (i32X > SPIDER_MAX_X) ||
+ (i32Y < SPIDER_MIN_Y) || (i32Y > SPIDER_MAX_Y) ||
+ (SpiderCollide(i32Spider, i32X, i32Y) != -1) ||
+ (RandomNumber() < 0x08000000))
+ {
+ //
+ // Undo the previous movement of the spider.
+ //
+ i32X -= g_pi32SpiderStepX[ui32Dir];
+ i32Y -= g_pi32SpiderStepY[ui32Dir];
+
+ //
+ // Get a random number to determine the turn to be made.
+ //
+ ui32Temp = RandomNumber();
+
+ //
+ // Determine how to turn the spider based on the random number.
+ // Half the time the spider turns to the left and half the time it
+ // turns to the right. Of each half, it turns a quarter of a turn
+ // 12.5% of the time and an eighth of a turn 87.5% of the time.
+ //
+ if(ui32Temp < 0x10000000)
+ {
+ ui32Dir = (ui32Dir + 2) & 7;
+ }
+ else if(ui32Temp < 0x80000000)
+ {
+ ui32Dir = (ui32Dir + 1) & 7;
+ }
+ else if(ui32Temp < 0xf0000000)
+ {
+ ui32Dir = (ui32Dir - 1) & 7;
+ }
+ else
+ {
+ ui32Dir = (ui32Dir - 2) & 7;
+ }
+ }
+
+ //
+ // Update the position of the spider.
+ //
+ g_pi32SpiderX[i32Spider] = i32X;
+ g_pi32SpiderY[i32Spider] = i32Y;
+
+ //
+ // Exit the critical section now that the spider has been moved.
+ //
+ taskEXIT_CRITICAL();
+
+ //
+ // Have the display task draw the spider at the new position. Since
+ // there is a one pixel empty border around all the images, and the
+ // position of the spider is incremented by only one pixel, this also
+ // erases any traces of the spider in its previous position.
+ //
+ DisplayImage(i32X - (SPIDER_WIDTH / 2), i32Y - (SPIDER_HEIGHT / 2),
+ g_ppui8SpiderImage[(ui32Dir * 2) + ui32Image]);
+
+ //
+ // Toggle the spider animation index.
+ //
+ ui32Image ^= 1;
+
+ //
+ // Delay this task for an amount of time based on the direction the
+ // spider is moving.
+ //
+ vTaskDelay(g_pui32SpiderDelay[ui32Dir & 1]);
+
+ //
+ // Add the new tick count to the random entropy pool.
+ //
+ RandomAddEntropy(xTaskGetTickCount());
+
+ //
+ // Reseed the random number generator.
+ //
+ RandomSeed();
+ }
+}
+
+//*****************************************************************************
+//
+// Creates a spider task.
+//
+//*****************************************************************************
+static uint32_t
+CreateSpider(int32_t i32X, int32_t i32Y)
+{
+ uint32_t ui32Spider;
+
+ //
+ // Search to see if there is a spider task available.
+ //
+ for(ui32Spider = 0; ui32Spider < MAX_SPIDERS; ui32Spider++)
+ {
+ if(HWREGBITW(&g_ui32SpiderAlive, ui32Spider) == 0)
+ {
+ break;
+ }
+ }
+
+ //
+ // Return a failure if no spider tasks are available (in other words, the
+ // maximum number of spiders are already alive).
+ //
+ if(ui32Spider == MAX_SPIDERS)
+ {
+ return(1);
+ }
+
+ //
+ // Adjust the starting horizontal position to make sure it is inside the
+ // allowable area for the spiders.
+ //
+ if(i32X < SPIDER_MIN_X)
+ {
+ i32X = SPIDER_MIN_X;
+ }
+ else if(i32X > SPIDER_MAX_X)
+ {
+ i32X = SPIDER_MAX_X;
+ }
+
+ //
+ // Adjust the starting vertical position to make sure it is inside the
+ // allowable area for the spiders.
+ //
+ if(i32Y < SPIDER_MIN_Y)
+ {
+ i32Y = SPIDER_MIN_Y;
+ }
+ else if(i32Y > SPIDER_MAX_Y)
+ {
+ i32Y = SPIDER_MAX_Y;
+ }
+
+ //
+ // Save the starting position for this spider.
+ //
+ g_pi32SpiderX[ui32Spider] = i32X;
+ g_pi32SpiderY[ui32Spider] = i32Y;
+
+ //
+ // Create a task to animate this spider.
+ //
+ if(xTaskCreate(SpiderTask, (signed portCHAR *)"Spider",
+ STACKSIZE_SPIDERTASK, (void *)ui32Spider,
+ tskIDLE_PRIORITY + PRIORITY_SPIDER_TASK, NULL) != pdTRUE)
+ {
+ return(1);
+ }
+
+ //
+ // Success.
+ //
+ return(0);
+}
+
+//*****************************************************************************
+//
+// The callback function for messages from the touch screen driver.
+//
+//*****************************************************************************
+static int32_t
+ControlTouchCallback(uint32_t ui32Message, int32_t i32X, int32_t i32Y)
+{
+ portBASE_TYPE bTaskWaken;
+
+ //
+ // Ignore all messages other than pointer down messages.
+ //
+ if(ui32Message != WIDGET_MSG_PTR_DOWN)
+ {
+ return(0);
+ }
+
+ //
+ // Pack the position into a message to send to the spider control task.
+ //
+ ui32Message = ((i32X & 65535) << 16) | (i32Y & 65535);
+
+ //
+ // Send the position message to the spider control task.
+ //
+ xQueueSendFromISR(g_pControlQueue, &ui32Message, &bTaskWaken);
+
+ //
+ // Perform a task yield if necessary.
+ //
+#if defined(__Check_Later)
+ taskYIELD_FROM_ISR(bTaskWaken);
+#endif
+
+ //
+ // This message has been handled.
+ //
+ return(0);
+}
+
+//*****************************************************************************
+//
+// Determines if a given touch screen point collides with one of the spiders.
+//
+//*****************************************************************************
+static int32_t
+SpiderTouchCollide(int32_t i32X, int32_t i32Y)
+{
+ int32_t i32Idx, i32DX, i32DY, i32Best, i32Dist;
+
+ //
+ // Until a collision is found, there is no best spider choice.
+ //
+ i32Best = -1;
+ i32Dist = 1000000;
+
+ //
+ // Loop through all the spiders.
+ //
+ for(i32Idx = 0; i32Idx < MAX_SPIDERS; i32Idx++)
+ {
+ //
+ // Skip this spider if it is not alive.
+ //
+ if((HWREGBITW(&g_ui32SpiderAlive, i32Idx) == 0) ||
+ (HWREGBITW(&g_ui32SpiderDead, i32Idx) == 1))
+ {
+ continue;
+ }
+
+ //
+ // Compute the horizontal and vertical difference between this spider's
+ // position and the point in question.
+ //
+ i32DX = ((g_pi32SpiderX[i32Idx] > i32X) ?
+ (g_pi32SpiderX[i32Idx] - i32X) :
+ (i32X - g_pi32SpiderX[i32Idx]));
+ i32DY = ((g_pi32SpiderY[i32Idx] > i32Y) ?
+ (g_pi32SpiderY[i32Idx] - i32Y) :
+ (i32Y - g_pi32SpiderY[i32Idx]));
+
+ //
+ // See if the point in question collides with this spider.
+ //
+ if((i32DX < (SPIDER_WIDTH + 4)) && (i32DY < (SPIDER_HEIGHT + 4)))
+ {
+ //
+ // Compute distance (squared) between this point and the spider.
+ //
+ i32DX = (i32DX * i32DX) + (i32DY * i32DY);
+
+ //
+ // See if this spider is closer to the point in question than any
+ // other spider encountered.
+ //
+ if(i32DX < i32Dist)
+ {
+ //
+ // Save this spider as the new best choice.
+ //
+ i32Best = i32Idx;
+ i32Dist = i32DX;
+ }
+ }
+ }
+
+ //
+ // Return the best choice, if one was found.
+ //
+ if(i32Best != -1)
+ {
+ return(i32Best);
+ }
+
+ //
+ // Loop through all the spiders. This time, the spiders that are dead but
+ // not cleared from the screen are not ignored.
+ //
+ for(i32Idx = 0; i32Idx < MAX_SPIDERS; i32Idx++)
+ {
+ //
+ // Skip this spider if it is not alive.
+ //
+ if(HWREGBITW(&g_ui32SpiderAlive, i32Idx) == 0)
+ {
+ continue;
+ }
+
+ //
+ // Compute the horizontal and vertical difference between this spider's
+ // position and the point in question.
+ //
+ i32DX = ((g_pi32SpiderX[i32Idx] > i32X) ?
+ (g_pi32SpiderX[i32Idx] - i32X) :
+ (i32X - g_pi32SpiderX[i32Idx]));
+ i32DY = ((g_pi32SpiderY[i32Idx] > i32Y) ?
+ (g_pi32SpiderY[i32Idx] - i32Y) :
+ (i32Y - g_pi32SpiderY[i32Idx]));
+
+ //
+ // See if the point in question collides with this spider.
+ //
+ if((i32DX < (SPIDER_WIDTH + 4)) && (i32DY < (SPIDER_HEIGHT + 4)))
+ {
+ //
+ // Compute distance (squared) between this point and the spider.
+ //
+ i32DX = (i32DX * i32DX) + (i32DY * i32DY);
+
+ //
+ // See if this spider is closer to the point in question than any
+ // other spider encountered.
+ //
+ if(i32DX < i32Dist)
+ {
+ //
+ // Save this spider as the new best choice.
+ //
+ i32Best = i32Idx;
+ i32Dist = i32DX;
+ }
+ }
+ }
+
+ //
+ // Return the best choice, if one was found.
+ //
+ return(i32Best);
+}
+
+//*****************************************************************************
+//
+// This task provides overall control of the spiders, spawning and killing them
+// in response to presses on the touch screen.
+//
+//*****************************************************************************
+static void
+ControlTask(void *pvParameters)
+{
+ uint32_t ui32Message;
+ int32_t i32X, i32Y, i32Spider;
+
+ //
+ // Initialize the touch screen driver and register a callback function.
+ //
+ TouchScreenInit(g_ui32SysClock);
+ TouchScreenCallbackSet(ControlTouchCallback);
+
+ //
+ // Lower the priority of the touch screen interrupt handler. This is
+ // required so that the interrupt handler can safely call the interrupt-
+ // safe FreeRTOS functions (specifically to send messages to the queue).
+ //
+ IntPrioritySet(INT_ADC0SS3, 0xc0);
+
+ //
+ // Loop forever.
+ //
+ while(1)
+ {
+ //
+ // Read the next message from the queue.
+ //
+ if(xQueueReceive(g_pControlQueue, &ui32Message, portMAX_DELAY) ==
+ pdPASS)
+ {
+ //
+ // Extract the position of the screen touch from the message.
+ //
+ i32X = ui32Message >> 16;
+ i32Y = ui32Message & 65535;
+
+ //
+ // Ignore this screen touch if it is not inside the spider area.
+ //
+ if((i32X >= AREA_X) && (i32X < (AREA_X + AREA_WIDTH)) &&
+ (i32Y >= AREA_Y) && (i32Y < (AREA_Y + AREA_HEIGHT)))
+ {
+ //
+ // See if this position collides with any of the spiders.
+ //
+ i32Spider = SpiderTouchCollide(i32X, i32Y);
+ if(i32Spider == -1)
+ {
+ //
+ // There is no collision, so create a new spider (if
+ // possible) at this position.
+ //
+ CreateSpider(i32X, i32Y);
+ }
+ else
+ {
+ //
+ // There is a collision, so kill this spider.
+ //
+ HWREGBITW(&g_ui32SpiderDead, i32Spider) = 1;
+ }
+ }
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// Sets the speed of the spiders by specifying the number of milliseconds
+// between updates to the spider's position.
+//
+//*****************************************************************************
+void
+SpiderSpeedSet(uint32_t ui32Speed)
+{
+ //
+ // Convert the update rate from milliseconds to ticks. The second entry
+ // of the array is 1.4 times the first so that updates when moving along
+ // the diagonal, which are longer steps, are done less frequently by a
+ // proportional amount.
+ //
+ g_pui32SpiderDelay[0] = (ui32Speed * (1000 / portTICK_RATE_MS)) / 1000;
+ g_pui32SpiderDelay[1] = (ui32Speed * 14 * (1000 / portTICK_RATE_MS)) /
+ 10000;
+}
+
+//*****************************************************************************
+//
+// Initializes the spider tasks.
+//
+//*****************************************************************************
+uint32_t
+SpiderTaskInit(void)
+{
+ uint32_t ui32Idx;
+
+ //
+ // Set the initial speed of the spiders.
+ //
+ SpiderSpeedSet(10);
+
+ //
+ // Create a queue for sending messages to the spider control task.
+ //
+ g_pControlQueue = xQueueCreate(CONTROL_QUEUE_SIZE, CONTROL_QUEUE_SIZE);
+ if(g_pControlQueue == NULL)
+ {
+ return(1);
+ }
+
+ //
+ // Create the spider control task.
+ //
+ if(xTaskCreate(ControlTask, (signed portCHAR *)"ControlTask",
+ STACKSIZE_CONTROLTASK, NULL,
+ tskIDLE_PRIORITY + PRIORITY_CONTROL_TASK, &g_sSpiderTask) != pdTRUE)
+ {// FIXME
+ return(1);
+ }
+
+ //
+ // Create eight spiders initially.
+ //
+ for(ui32Idx = 0; ui32Idx < 8; ui32Idx++)
+ {
+ //
+ // Create a spider that is centered vertically and equally spaced
+ // horizontally across the display.
+ //
+ if(CreateSpider((ui32Idx * (AREA_WIDTH / 8)) + (AREA_WIDTH / 16),
+ (AREA_HEIGHT / 2) + AREA_Y) == 1)
+ {
+ return(1);
+ }
+
+ //
+ // Provide an early indication that this spider is alive. The task is
+ // not running yet (since this function is called before the scheduler
+ // has been started) so this variable is not set by the task (yet).
+ // Manually setting it allows the remaining initial spiders to be
+ // created properly.
+ //
+ HWREGBITW(&g_ui32SpiderAlive, ui32Idx) = 1;
+ }
+
+ //
+ // Success.
+ //
+ return(0);
+}