copied over all of the custom pcb stuff and switched connectors + added PWM headers to the power board
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4029 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/gyro_board/src/usb/CommonDemoTasks/GenQTest.c b/gyro_board/src/usb/CommonDemoTasks/GenQTest.c
new file mode 100644
index 0000000..1b486ba
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/GenQTest.c
@@ -0,0 +1,525 @@
+/*
+ FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+ ***************************************************************************
+ * *
+ * If you are: *
+ * *
+ * + New to FreeRTOS, *
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *
+ * + Looking for basic training, *
+ * + Wanting to improve your FreeRTOS skills and productivity *
+ * *
+ * then take a look at the FreeRTOS eBook *
+ * *
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ * A pdf reference manual is also available. Both are usually delivered *
+ * to your inbox within 20 minutes to two hours when purchased between 8am *
+ * and 8pm GMT (although please allow up to 24 hours in case of *
+ * exceptional circumstances). Thank you for your support! *
+ * *
+ ***************************************************************************
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
+ ***NOTE*** The exception to the GPL is included to allow you to distribute
+ a combined work that includes FreeRTOS without being obliged to provide the
+ source code for proprietary components outside of the FreeRTOS kernel.
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details. You should have received a copy of the GNU General Public
+ License and the FreeRTOS license exception along with FreeRTOS; if not it
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained
+ by writing to Richard Barry, contact details for whom are available on the
+ FreeRTOS WEB site.
+
+ 1 tab == 4 spaces!
+
+ http://www.FreeRTOS.org - Documentation, latest information, license and
+ contact details.
+
+ http://www.SafeRTOS.com - A version that is certified for use in safety
+ critical systems.
+
+ http://www.OpenRTOS.com - Commercial support, development, porting,
+ licensing and training services.
+*/
+
+
+/*
+ * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 -
+ * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and
+ * mutex behaviour.
+ *
+ * See the comments above the prvSendFrontAndBackTest() and
+ * prvLowPriorityMutexTask() prototypes below for more information.
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* Demo program include files. */
+#include "GenQTest.h"
+
+#define genqQUEUE_LENGTH ( 5 )
+#define genqNO_BLOCK ( 0 )
+
+#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY )
+#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
+#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack()
+ * macros by using both to fill a queue, then reading from the queue to
+ * check the resultant queue order is as expected. Queue data is also
+ * peeked.
+ */
+static void prvSendFrontAndBackTest(void *pvParameters);
+
+/*
+ * The following three tasks are used to demonstrate the mutex behaviour.
+ * Each task is given a different priority to demonstrate the priority
+ * inheritance mechanism.
+ *
+ * The low priority task obtains a mutex. After this a high priority task
+ * attempts to obtain the same mutex, causing its priority to be inherited
+ * by the low priority task. The task with the inherited high priority then
+ * resumes a medium priority task to ensure it is not blocked by the medium
+ * priority task while it holds the inherited high priority. Once the mutex
+ * is returned the task with the inherited priority returns to its original
+ * low priority, and is therefore immediately preempted by first the high
+ * priority task and then the medium prioroity task before it can continue.
+ */
+static void prvLowPriorityMutexTask(void *pvParameters);
+static void prvMediumPriorityMutexTask(void *pvParameters);
+static void prvHighPriorityMutexTask(void *pvParameters);
+
+/*-----------------------------------------------------------*/
+
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be
+detected in any of the tasks. */
+static portBASE_TYPE xErrorDetected = pdFALSE;
+
+/* Counters that are incremented on each cycle of a test. This is used to
+detect a stalled task - a test that is no longer running. */
+static volatile unsigned portLONG ulLoopCounter = 0;
+static volatile unsigned portLONG ulLoopCounter2 = 0;
+
+/* The variable that is guarded by the mutex in the mutex demo tasks. */
+static volatile unsigned portLONG ulGuardedVariable = 0;
+
+/* Handles used in the mutext test to suspend and resume the high and medium
+priority mutex test tasks. */
+static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;
+
+/*-----------------------------------------------------------*/
+
+void vStartGenericQueueTasks(unsigned portBASE_TYPE uxPriority)
+{
+ xQueueHandle xQueue;
+ xSemaphoreHandle xMutex;
+
+ /* Create the queue that we are going to use for the
+ prvSendFrontAndBackTest demo. */
+ xQueue = xQueueCreate(genqQUEUE_LENGTH, sizeof(unsigned portLONG));
+
+ /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
+ in use. The queue registry is provided as a means for kernel aware
+ debuggers to locate queues and has no purpose if a kernel aware debugger
+ is not being used. The call to vQueueAddToRegistry() will be removed
+ by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
+ defined to be less than 1. */
+ vQueueAddToRegistry(xQueue, (signed portCHAR *) "Gen_Queue_Test");
+
+ /* Create the demo task and pass it the queue just created. We are
+ passing the queue handle by value so it does not matter that it is
+ declared on the stack here. */
+ xTaskCreate(prvSendFrontAndBackTest, (signed portCHAR *)"GenQ", configMINIMAL_STACK_SIZE, (void *) xQueue, uxPriority, NULL);
+
+ /* Create the mutex used by the prvMutexTest task. */
+ xMutex = xSemaphoreCreateMutex();
+
+ /* vQueueAddToRegistry() adds the mutex to the registry, if one is
+ in use. The registry is provided as a means for kernel aware
+ debuggers to locate mutexes and has no purpose if a kernel aware debugger
+ is not being used. The call to vQueueAddToRegistry() will be removed
+ by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
+ defined to be less than 1. */
+ vQueueAddToRegistry((xQueueHandle) xMutex, (signed portCHAR *) "Gen_Queue_Mutex");
+
+ /* Create the mutex demo tasks and pass it the mutex just created. We are
+ passing the mutex handle by value so it does not matter that it is declared
+ on the stack here. */
+ xTaskCreate(prvLowPriorityMutexTask, (signed portCHAR *)"MuLow", configMINIMAL_STACK_SIZE, (void *) xMutex, genqMUTEX_LOW_PRIORITY, NULL);
+ xTaskCreate(prvMediumPriorityMutexTask, (signed portCHAR *)"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask);
+ xTaskCreate(prvHighPriorityMutexTask, (signed portCHAR *)"MuHigh", configMINIMAL_STACK_SIZE, (void *) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask);
+}
+/*-----------------------------------------------------------*/
+
+static void prvSendFrontAndBackTest(void *pvParameters)
+{
+ unsigned portLONG ulData, ulData2;
+ xQueueHandle xQueue;
+
+#ifdef USE_STDIO
+ void vPrintDisplayMessage(const portCHAR * const * ppcMessageToSend);
+
+ const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n";
+
+ /* Queue a message for printing to say the task has started. */
+ vPrintDisplayMessage(&pcTaskStartMsg);
+#endif
+
+ xQueue = (xQueueHandle) pvParameters;
+
+ for (;;) {
+ /* The queue is empty, so sending an item to the back of the queue
+ should have the same efect as sending it to the front of the queue.
+
+ First send to the front and check everything is as expected. */
+ xQueueSendToFront(xQueue, (void *) &ulLoopCounter, genqNO_BLOCK);
+
+ if (uxQueueMessagesWaiting(xQueue) != 1) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (xQueueReceive(xQueue, (void *) &ulData, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* The data we sent to the queue should equal the data we just received
+ from the queue. */
+ if (ulLoopCounter != ulData) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Then do the same, sending the data to the back, checking everything
+ is as expected. */
+ if (uxQueueMessagesWaiting(xQueue) != 0) {
+ xErrorDetected = pdTRUE;
+ }
+
+ xQueueSendToBack(xQueue, (void *) &ulLoopCounter, genqNO_BLOCK);
+
+ if (uxQueueMessagesWaiting(xQueue) != 1) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (xQueueReceive(xQueue, (void *) &ulData, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (uxQueueMessagesWaiting(xQueue) != 0) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* The data we sent to the queue should equal the data we just received
+ from the queue. */
+ if (ulLoopCounter != ulData) {
+ xErrorDetected = pdTRUE;
+ }
+
+#if configUSE_PREEMPTION == 0
+ taskYIELD();
+#endif
+
+
+
+ /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */
+ for (ulData = 2; ulData < 5; ulData++) {
+ xQueueSendToBack(xQueue, (void *) &ulData, genqNO_BLOCK);
+ }
+
+ /* Now the order in the queue should be 2, 3, 4, with 2 being the first
+ thing to be read out. Now add 1 then 0 to the front of the queue. */
+ if (uxQueueMessagesWaiting(xQueue) != 3) {
+ xErrorDetected = pdTRUE;
+ }
+ ulData = 1;
+ xQueueSendToFront(xQueue, (void *) &ulData, genqNO_BLOCK);
+ ulData = 0;
+ xQueueSendToFront(xQueue, (void *) &ulData, genqNO_BLOCK);
+
+ /* Now the queue should be full, and when we read the data out we
+ should receive 0, 1, 2, 3, 4. */
+ if (uxQueueMessagesWaiting(xQueue) != 5) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (xQueueSendToFront(xQueue, (void *) &ulData, genqNO_BLOCK) != errQUEUE_FULL) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (xQueueSendToBack(xQueue, (void *) &ulData, genqNO_BLOCK) != errQUEUE_FULL) {
+ xErrorDetected = pdTRUE;
+ }
+
+#if configUSE_PREEMPTION == 0
+ taskYIELD();
+#endif
+
+ /* Check the data we read out is in the expected order. */
+ for (ulData = 0; ulData < genqQUEUE_LENGTH; ulData++) {
+ /* Try peeking the data first. */
+ if (xQueuePeek(xQueue, &ulData2, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulData != ulData2) {
+ xErrorDetected = pdTRUE;
+ }
+
+
+ /* Now try receiving the data for real. The value should be the
+ same. Clobber the value first so we know we really received it. */
+ ulData2 = ~ulData2;
+ if (xQueueReceive(xQueue, &ulData2, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulData != ulData2) {
+ xErrorDetected = pdTRUE;
+ }
+ }
+
+ /* The queue should now be empty again. */
+ if (uxQueueMessagesWaiting(xQueue) != 0) {
+ xErrorDetected = pdTRUE;
+ }
+
+#if configUSE_PREEMPTION == 0
+ taskYIELD();
+#endif
+
+
+ /* Our queue is empty once more, add 10, 11 to the back. */
+ ulData = 10;
+ if (xQueueSend(xQueue, &ulData, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+ ulData = 11;
+ if (xQueueSend(xQueue, &ulData, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (uxQueueMessagesWaiting(xQueue) != 2) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the
+ front. */
+ for (ulData = 9; ulData >= 7; ulData--) {
+ if (xQueueSendToFront(xQueue, (void *) &ulData, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+ }
+
+ /* Now check that the queue is full, and that receiving data provides
+ the expected sequence of 7, 8, 9, 10, 11. */
+ if (uxQueueMessagesWaiting(xQueue) != 5) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (xQueueSendToFront(xQueue, (void *) &ulData, genqNO_BLOCK) != errQUEUE_FULL) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (xQueueSendToBack(xQueue, (void *) &ulData, genqNO_BLOCK) != errQUEUE_FULL) {
+ xErrorDetected = pdTRUE;
+ }
+
+#if configUSE_PREEMPTION == 0
+ taskYIELD();
+#endif
+
+ /* Check the data we read out is in the expected order. */
+ for (ulData = 7; ulData < (7 + genqQUEUE_LENGTH); ulData++) {
+ if (xQueueReceive(xQueue, &ulData2, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulData != ulData2) {
+ xErrorDetected = pdTRUE;
+ }
+ }
+
+ if (uxQueueMessagesWaiting(xQueue) != 0) {
+ xErrorDetected = pdTRUE;
+ }
+
+ ulLoopCounter++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvLowPriorityMutexTask(void *pvParameters)
+{
+ xSemaphoreHandle xMutex = (xSemaphoreHandle) pvParameters;
+
+#ifdef USE_STDIO
+ void vPrintDisplayMessage(const portCHAR * const * ppcMessageToSend);
+
+ const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n";
+
+ /* Queue a message for printing to say the task has started. */
+ vPrintDisplayMessage(&pcTaskStartMsg);
+#endif
+
+ for (;;) {
+ /* Take the mutex. It should be available now. */
+ if (xSemaphoreTake(xMutex, genqNO_BLOCK) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Set our guarded variable to a known start value. */
+ ulGuardedVariable = 0;
+
+ /* Our priority should be as per that assigned when the task was
+ created. */
+ if (uxTaskPriorityGet(NULL) != genqMUTEX_LOW_PRIORITY) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Now unsuspend the high priority task. This will attempt to take the
+ mutex, and block when it finds it cannot obtain it. */
+ vTaskResume(xHighPriorityMutexTask);
+
+ /* We should now have inherited the prioritoy of the high priority task,
+ as by now it will have attempted to get the mutex. */
+ if (uxTaskPriorityGet(NULL) != genqMUTEX_HIGH_PRIORITY) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* We can attempt to set our priority to the test priority - between the
+ idle priority and the medium/high test priorities, but our actual
+ prioroity should remain at the high priority. */
+ vTaskPrioritySet(NULL, genqMUTEX_TEST_PRIORITY);
+ if (uxTaskPriorityGet(NULL) != genqMUTEX_HIGH_PRIORITY) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Now unsuspend the medium priority task. This should not run as our
+ inherited priority is above that of the medium priority task. */
+ vTaskResume(xMediumPriorityMutexTask);
+
+ /* If the did run then it will have incremented our guarded variable. */
+ if (ulGuardedVariable != 0) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* When we give back the semaphore our priority should be disinherited
+ back to the priority to which we attempted to set ourselves. This means
+ that when the high priority task next blocks, the medium priority task
+ should execute and increment the guarded variable. When we next run
+ both the high and medium priority tasks will have been suspended again. */
+ if (xSemaphoreGive(xMutex) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Check that the guarded variable did indeed increment... */
+ if (ulGuardedVariable != 1) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* ... and that our priority has been disinherited to
+ genqMUTEX_TEST_PRIORITY. */
+ if (uxTaskPriorityGet(NULL) != genqMUTEX_TEST_PRIORITY) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Set our priority back to our original priority ready for the next
+ loop around this test. */
+ vTaskPrioritySet(NULL, genqMUTEX_LOW_PRIORITY);
+
+ /* Just to show we are still running. */
+ ulLoopCounter2++;
+
+#if configUSE_PREEMPTION == 0
+ taskYIELD();
+#endif
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvMediumPriorityMutexTask(void *pvParameters)
+{
+ (void) pvParameters;
+
+ for (;;) {
+ /* The medium priority task starts by suspending itself. The low
+ priority task will unsuspend this task when required. */
+ vTaskSuspend(NULL);
+
+ /* When this task unsuspends all it does is increment the guarded
+ variable, this is so the low priority task knows that it has
+ executed. */
+ ulGuardedVariable++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvHighPriorityMutexTask(void *pvParameters)
+{
+ xSemaphoreHandle xMutex = (xSemaphoreHandle) pvParameters;
+
+ for (;;) {
+ /* The high priority task starts by suspending itself. The low
+ priority task will unsuspend this task when required. */
+ vTaskSuspend(NULL);
+
+ /* When this task unsuspends all it does is attempt to obtain
+ the mutex. It should find the mutex is not available so a
+ block time is specified. */
+ if (xSemaphoreTake(xMutex, portMAX_DELAY) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* When we eventually obtain the mutex we just give it back then
+ return to suspend ready for the next test. */
+ if (xSemaphoreGive(xMutex) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreGenericQueueTasksStillRunning(void)
+{
+ static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;
+
+ /* If the demo task is still running then we expect the loopcounters to
+ have incremented since this function was last called. */
+ if (ulLastLoopCounter == ulLoopCounter) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulLastLoopCounter2 == ulLoopCounter2) {
+ xErrorDetected = pdTRUE;
+ }
+
+ ulLastLoopCounter = ulLoopCounter;
+ ulLastLoopCounter2 = ulLoopCounter2;
+
+ /* Errors detected in the task itself will have latched xErrorDetected
+ to true. */
+
+ return !xErrorDetected;
+}
+
+