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/CAN.c b/gyro_board/src/usb/CAN.c
new file mode 100644
index 0000000..74e0a62
--- /dev/null
+++ b/gyro_board/src/usb/CAN.c
@@ -0,0 +1,283 @@
+/* Standard includes. */
+#include "stdio.h"
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "task.h"
+
+/* Demo app includes. */
+#include "flash.h"
+#include "partest.h"
+#include "analog.h"
+#include "spi.h"
+#include "LPCUSB/usbapi.h"
+#include "CAN.h"
+
+static xQueueHandle CAN_tx_queue = NULL, CAN_rx_queue = NULL;
+
+/** Send a CAN message. The message is stored by copy.
+ *
+ * \returns Zero on success, and one on failure to queue the message.
+ */
+int CAN_send(can_message *message) {
+ uint32_t sr = CAN1->SR;
+ // Queue the message up in a queue!
+ if (sr & 0x00040404) {
+ uint32_t IFx = (message->RTR << 30) +
+ (message->length << 16) +
+ (message->priority);
+
+ uint32_t data0 = message->wdata[0];
+ uint32_t data1 = message->wdata[1];
+
+ if(sr & 0x00000004){
+ CAN1->TFI1 = IFx;
+ CAN1->TID1 = message->id;
+ CAN1->TDA1 = data0;
+ CAN1->TDB1 = data1;
+ CAN1->CMR = 0x00000021;
+ printf("Writing 1\n");
+ return 0;
+ } else if(sr & 0x00000400) {
+ CAN1->TFI2 = IFx;
+ CAN1->TID2 = message->id;
+ CAN1->TDA2 = data0;
+ CAN1->TDB2 = data1;
+ CAN1->CMR = 0x00000041;
+ return 0;
+ } else if(sr & 0x00040000) {
+ CAN1->TFI3 = IFx;
+ CAN1->TID3 = message->id;
+ CAN1->TDA3 = data0;
+ CAN1->TDB3 = data1;
+ CAN1->CMR = 0x00000081;
+ return 0;
+ }
+ return 1;
+ }
+ return xQueueSend(CAN_tx_queue, message, 0) != pdPASS;
+}
+
+/**
+ * Get a CAN message, blocking if one isn't available.
+ * This is useful for a read/dispatch thread.
+ *
+ * \returns 0 on Success, and nonzero on failure
+ */
+int CAN_get(can_message *message) {
+ // Blocking read the queue.
+ if (xQueueReceive(CAN_rx_queue, message, portMAX_DELAY) == pdFALSE) {
+ return 1;
+ } else {
+ return message->error;
+ }
+}
+
+void CAN_IRQHandler(void) {
+ uint32_t interrupts = CAN1->ICR;
+ long lHigherPriorityTaskWoken = pdFALSE;
+ can_message message;
+ // CAN1->CMR contains all the action items, like initiating a send et all.
+ // On a bus error interrupt, set an error semaphore so the handler can set the LED, or set it ourselfs.
+ printf("CAN interrupt\n");
+
+ if (interrupts & 0x1) {
+ // Recieved a packet.
+ uint32_t rfs = CAN1->RFS;
+
+ message.RTR = (rfs & 0x40000000) >> 30;
+ message.length = (rfs & 0x000f0000) >> 16;
+ message.id = CAN1->RID & 0x000007ff;
+
+ message.wdata[0] = CAN1->RDA;
+ message.wdata[1] = CAN1->RDB;
+
+ // Release the registers
+ CAN1->CMR = 0x00000004;
+
+ message.error = 0;
+
+ xQueueSendFromISR(CAN_rx_queue, &message, &lHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+ return;
+ }
+
+ if (interrupts & 0x602) {
+ // TX buffers are no longer empty (now empty??)
+ if (xQueueReceiveFromISR(CAN_tx_queue, &message, &lHigherPriorityTaskWoken)) {
+ uint32_t IFx = (message.RTR << 30) +
+ (message.length << 16) +
+ (message.priority);
+ uint32_t data0 = message.wdata[0];
+ uint32_t data1 = message.wdata[1];
+
+ // Message was in the queue, and will now be sent.
+ if (interrupts & 0x2) {
+ // TX buffer 1 is no longer empty
+ CAN1->TFI1 = IFx;
+ CAN1->TID1 = message.id;
+ CAN1->TDA1 = data0;
+ CAN1->TDB1 = data1;
+ CAN1->CMR = 0x00000021;
+ } else if (interrupts & 0x200) {
+ // TX buffer 2 is no longer empty
+ CAN1->TFI2 = IFx;
+ CAN1->TID2 = message.id;
+ CAN1->TDA2 = data0;
+ CAN1->TDB2 = data1;
+ CAN1->CMR = 0x00000041;
+ } else if (interrupts & 0x400) {
+ // TX buffer 3 is no longer empty
+ CAN1->TFI3 = IFx;
+ CAN1->TID3 = message.id;
+ CAN1->TDA3 = data0;
+ CAN1->TDB3 = data1;
+ CAN1->CMR = 0x00000081;
+ }
+ }
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+ return;
+ }
+
+ if (interrupts & 0x4) {
+ // Error Warning interrupt
+ message.error = 0x01;
+ if (CAN1->GSR & 0x00000040) {
+ // Reached the limit.
+ message.error = 0x01;
+ } else if (CAN1->GSR & 0x00000080) {
+ // No longer allowed to send.
+ message.error = 0x20;
+ } else {
+ message.error = 0x20;
+ }
+ xQueueSendFromISR(CAN_rx_queue, &message, &lHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+ return;
+ }
+
+ if (interrupts & 0x8) {
+ // Data overrun
+ CAN1->CMR = 0x00000008;
+ message.error = 0x02;
+ xQueueSendFromISR(CAN_rx_queue, &message, &lHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+ return;
+ }
+
+ if (interrupts & 0x20) {
+ // Error Passive Interrupt
+ message.error = 0x04;
+ xQueueSendFromISR(CAN_rx_queue, &message, &lHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+ return;
+ }
+
+ if (interrupts & 0x80) {
+ // Bus Error Interrupt
+ message.error = 0x08;
+ xQueueSendFromISR(CAN_rx_queue, &message, &lHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+ return;
+ }
+ message.error = 0x10;
+ xQueueSendFromISR(CAN_rx_queue, &message, &lHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+extern int VCOM_getchar(void);
+
+static portTASK_FUNCTION(vCAN1Write, pvParameters) {
+ can_message message;
+ message.RTR = 0;
+ message.id = 12;
+ message.priority = 1;
+ message.length = 4;
+
+ // Enable the pins.
+ PINCON->PINSEL3 = (PINCON->PINSEL3 & 0xffc3cf3f) | 0x00141040;
+
+ portTickType xLastFlashTime;
+ xLastFlashTime = xTaskGetTickCount();
+
+ for (;;) {
+ printf("hello\n");
+
+ int c = VCOM_getchar();
+ while (c != -1) {
+ printf("hello\n");
+ int j = c;
+ printf("Sending data 0x%x\n", j);
+ message.data[0] = j++;
+ message.data[1] = j++;
+ message.data[2] = j++;
+ message.data[3] = j;
+ CAN_send(&message);
+ c = VCOM_getchar();
+ }
+
+ vTaskDelayUntil(&xLastFlashTime, 500);
+ }
+}
+static portTASK_FUNCTION(vCAN1, pvParameters) {
+ portTickType xLastFlashTime;
+
+ CAN_rx_queue = xQueueCreate(20, sizeof(can_message));
+ CAN_tx_queue = xQueueCreate(5, sizeof(char));
+
+ if ((CAN_rx_queue == NULL) || (CAN_tx_queue == NULL)) {
+ /* Not enough heap available to create the buffer queues, can't do
+ * anything so just delete ourselves.
+ */
+ vTaskDelete(NULL);
+ }
+
+ // Enable CAN
+ SC->PCONP |= PCONP_PCCAN1;
+
+ PINCON->PINSEL0 = (PINCON->PINSEL0 & 0xfffffff0) | 0x00000005;
+ PINCON->PINMODE0 = (PINCON->PINMODE0 & 0xfffffffc) | 0x00000001;
+
+ // Enable RX, TX, overrun, Bus Error,
+ // Error Passive/Active, and Error Warning Interupts.
+ NVIC_SetPriority(CAN_IRQn, configCAN_INTERRUPT_PRIORITY);
+ NVIC_EnableIRQ(CAN_IRQn);
+
+ CAN1->IER = 0x000006af;
+
+ // Priority depends on the TX priority register
+ CAN1->MOD = 0x00000008;
+
+ CAN1->CMR = 0x00000004;
+
+ CANAF->AFMR = 0x00000002;
+
+ // CAN clocks. (Defaults look fine)
+
+ /* We need to initialise xLastFlashTime prior to the first call to
+ vTaskDelayUntil(). */
+ xLastFlashTime = xTaskGetTickCount();
+
+ can_message message;
+
+ xTaskCreate(vCAN1Write, (signed char *) "CAN1wx", configMINIMAL_STACK_SIZE + 100, NULL, tskIDLE_PRIORITY + 4, NULL);
+
+ for (;;) {
+ /* Delay for half the flash period then turn the LED on. */
+ if (CAN_get(&message)) {
+ printf("Message error 0x%x\n", message.error);
+ } else {
+ printf("Got a message with a length of %d\n", message.length);
+ printf("data[0] = 0x%x\n", message.data[0]);
+ printf("data[1] = 0x%x\n", message.data[1]);
+ printf("data[2] = 0x%x\n", message.data[2]);
+ printf("data[3] = 0x%x\n", message.data[3]);
+ }
+ }
+}
+
+
+void initCAN(void){
+ xTaskCreate(vCAN1, (signed char *) "CAN1rx", configMINIMAL_STACK_SIZE + 400, NULL, tskIDLE_PRIORITY + 1, NULL);
+}
diff --git a/gyro_board/src/usb/CAN.h b/gyro_board/src/usb/CAN.h
new file mode 100644
index 0000000..1ef39d5
--- /dev/null
+++ b/gyro_board/src/usb/CAN.h
@@ -0,0 +1,19 @@
+#ifndef _CAN_H_
+#define _CAN_H_
+
+typedef struct _can_message {
+ unsigned RTR:1;
+ unsigned error:7;
+ uint16_t id;
+ uint8_t priority;
+ uint8_t length;
+ union {
+ uint8_t data[8];
+ uint32_t wdata[2];
+ };
+} can_message;
+
+int CAN_get(can_message *message);
+void initCAN(void);
+
+#endif
diff --git a/gyro_board/src/usb/CommonDemoTasks/BlockQ.c b/gyro_board/src/usb/CommonDemoTasks/BlockQ.c
new file mode 100644
index 0000000..e05af05
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/BlockQ.c
@@ -0,0 +1,293 @@
+/*
+ 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.
+*/
+
+/*
+ * Creates six tasks that operate on three queues as follows:
+ *
+ * The first two tasks send and receive an incrementing number to/from a queue.
+ * One task acts as a producer and the other as the consumer. The consumer is a
+ * higher priority than the producer and is set to block on queue reads. The queue
+ * only has space for one item - as soon as the producer posts a message on the
+ * queue the consumer will unblock, pre-empt the producer, and remove the item.
+ *
+ * The second two tasks work the other way around. Again the queue used only has
+ * enough space for one item. This time the consumer has a lower priority than the
+ * producer. The producer will try to post on the queue blocking when the queue is
+ * full. When the consumer wakes it will remove the item from the queue, causing
+ * the producer to unblock, pre-empt the consumer, and immediately re-fill the
+ * queue.
+ *
+ * The last two tasks use the same queue producer and consumer functions. This time the queue has
+ * enough space for lots of items and the tasks operate at the same priority. The
+ * producer will execute, placing items into the queue. The consumer will start
+ * executing when either the queue becomes full (causing the producer to block) or
+ * a context switch occurs (tasks of the same priority will time slice).
+ *
+ */
+
+/*
+
+Changes from V4.1.1
+
+ + The second set of tasks were created the wrong way around. This has been
+ corrected.
+*/
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Demo program include files. */
+#include "BlockQ.h"
+
+#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE
+#define blckqNUM_TASK_SETS ( 3 )
+
+/* Structure used to pass parameters to the blocking queue tasks. */
+typedef struct BLOCKING_QUEUE_PARAMETERS {
+ xQueueHandle xQueue; /*< The queue to be used by the task. */
+ portTickType xBlockTime; /*< The block time to use on queue reads/writes. */
+ volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */
+} xBlockingQueueParameters;
+
+/* Task function that creates an incrementing number and posts it on a queue. */
+static portTASK_FUNCTION_PROTO(vBlockingQueueProducer, pvParameters);
+
+/* Task function that removes the incrementing number from a queue and checks that
+it is the expected number. */
+static portTASK_FUNCTION_PROTO(vBlockingQueueConsumer, pvParameters);
+
+/* Variables which are incremented each time an item is removed from a queue, and
+found to be the expected value.
+These are used to check that the tasks are still running. */
+static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = {(unsigned short) 0, (unsigned short) 0, (unsigned short) 0 };
+
+/* Variable which are incremented each time an item is posted on a queue. These
+are used to check that the tasks are still running. */
+static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = {(unsigned short) 0, (unsigned short) 0, (unsigned short) 0 };
+
+/*-----------------------------------------------------------*/
+
+void vStartBlockingQueueTasks(unsigned portBASE_TYPE uxPriority)
+{
+ xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;
+ xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
+ xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
+ const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5;
+ const portTickType xBlockTime = (portTickType) 1000 / portTICK_RATE_MS;
+ const portTickType xDontBlock = (portTickType) 0;
+
+ /* Create the first two tasks as described at the top of the file. */
+
+ /* First create the structure used to pass parameters to the consumer tasks. */
+ pxQueueParameters1 = (xBlockingQueueParameters *) pvPortMalloc(sizeof(xBlockingQueueParameters));
+
+ /* Create the queue used by the first two tasks to pass the incrementing number.
+ Pass a pointer to the queue in the parameter structure. */
+ pxQueueParameters1->xQueue = xQueueCreate(uxQueueSize1, (unsigned portBASE_TYPE) sizeof(unsigned short));
+
+ /* The consumer is created first so gets a block time as described above. */
+ pxQueueParameters1->xBlockTime = xBlockTime;
+
+ /* Pass in the variable that this task is going to increment so we can check it
+ is still running. */
+ pxQueueParameters1->psCheckVariable = &(sBlockingConsumerCount[ 0 ]);
+
+ /* Create the structure used to pass parameters to the producer task. */
+ pxQueueParameters2 = (xBlockingQueueParameters *) pvPortMalloc(sizeof(xBlockingQueueParameters));
+
+ /* Pass the queue to this task also, using the parameter structure. */
+ pxQueueParameters2->xQueue = pxQueueParameters1->xQueue;
+
+ /* The producer is not going to block - as soon as it posts the consumer will
+ wake and remove the item so the producer should always have room to post. */
+ pxQueueParameters2->xBlockTime = xDontBlock;
+
+ /* Pass in the variable that this task is going to increment so we can check
+ it is still running. */
+ pxQueueParameters2->psCheckVariable = &(sBlockingProducerCount[ 0 ]);
+
+
+ /* Note the producer has a lower priority than the consumer when the tasks are
+ spawned. */
+ xTaskCreate(vBlockingQueueConsumer, (signed char *) "QConsB1", blckqSTACK_SIZE, (void *) pxQueueParameters1, uxPriority, NULL);
+ xTaskCreate(vBlockingQueueProducer, (signed char *) "QProdB2", blckqSTACK_SIZE, (void *) pxQueueParameters2, tskIDLE_PRIORITY, NULL);
+
+
+
+ /* Create the second two tasks as described at the top of the file. This uses
+ the same mechanism but reverses the task priorities. */
+
+ pxQueueParameters3 = (xBlockingQueueParameters *) pvPortMalloc(sizeof(xBlockingQueueParameters));
+ pxQueueParameters3->xQueue = xQueueCreate(uxQueueSize1, (unsigned portBASE_TYPE) sizeof(unsigned short));
+ pxQueueParameters3->xBlockTime = xDontBlock;
+ pxQueueParameters3->psCheckVariable = &(sBlockingProducerCount[ 1 ]);
+
+ pxQueueParameters4 = (xBlockingQueueParameters *) pvPortMalloc(sizeof(xBlockingQueueParameters));
+ pxQueueParameters4->xQueue = pxQueueParameters3->xQueue;
+ pxQueueParameters4->xBlockTime = xBlockTime;
+ pxQueueParameters4->psCheckVariable = &(sBlockingConsumerCount[ 1 ]);
+
+ xTaskCreate(vBlockingQueueConsumer, (signed char *) "QProdB3", blckqSTACK_SIZE, (void *) pxQueueParameters3, tskIDLE_PRIORITY, NULL);
+ xTaskCreate(vBlockingQueueProducer, (signed char *) "QConsB4", blckqSTACK_SIZE, (void *) pxQueueParameters4, uxPriority, NULL);
+
+
+
+ /* Create the last two tasks as described above. The mechanism is again just
+ the same. This time both parameter structures are given a block time. */
+ pxQueueParameters5 = (xBlockingQueueParameters *) pvPortMalloc(sizeof(xBlockingQueueParameters));
+ pxQueueParameters5->xQueue = xQueueCreate(uxQueueSize5, (unsigned portBASE_TYPE) sizeof(unsigned short));
+ pxQueueParameters5->xBlockTime = xBlockTime;
+ pxQueueParameters5->psCheckVariable = &(sBlockingProducerCount[ 2 ]);
+
+ pxQueueParameters6 = (xBlockingQueueParameters *) pvPortMalloc(sizeof(xBlockingQueueParameters));
+ pxQueueParameters6->xQueue = pxQueueParameters5->xQueue;
+ pxQueueParameters6->xBlockTime = xBlockTime;
+ pxQueueParameters6->psCheckVariable = &(sBlockingConsumerCount[ 2 ]);
+
+ xTaskCreate(vBlockingQueueProducer, (signed char *) "QProdB5", blckqSTACK_SIZE, (void *) pxQueueParameters5, tskIDLE_PRIORITY, NULL);
+ xTaskCreate(vBlockingQueueConsumer, (signed char *) "QConsB6", blckqSTACK_SIZE, (void *) pxQueueParameters6, tskIDLE_PRIORITY, NULL);
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION(vBlockingQueueProducer, pvParameters)
+{
+ unsigned short usValue = 0;
+ xBlockingQueueParameters *pxQueueParameters;
+ short sErrorEverOccurred = pdFALSE;
+
+ pxQueueParameters = (xBlockingQueueParameters *) pvParameters;
+
+ for (;;) {
+ if (xQueueSend(pxQueueParameters->xQueue, (void *) &usValue, pxQueueParameters->xBlockTime) != pdPASS) {
+ sErrorEverOccurred = pdTRUE;
+ } else {
+ /* We have successfully posted a message, so increment the variable
+ used to check we are still running. */
+ if (sErrorEverOccurred == pdFALSE) {
+ (*pxQueueParameters->psCheckVariable)++;
+ }
+
+ /* Increment the variable we are going to post next time round. The
+ consumer will expect the numbers to follow in numerical order. */
+ ++usValue;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION(vBlockingQueueConsumer, pvParameters)
+{
+ unsigned short usData, usExpectedValue = 0;
+ xBlockingQueueParameters *pxQueueParameters;
+ short sErrorEverOccurred = pdFALSE;
+
+ pxQueueParameters = (xBlockingQueueParameters *) pvParameters;
+
+ for (;;) {
+ if (xQueueReceive(pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime) == pdPASS) {
+ if (usData != usExpectedValue) {
+ /* Catch-up. */
+ usExpectedValue = usData;
+
+ sErrorEverOccurred = pdTRUE;
+ } else {
+ /* We have successfully received a message, so increment the
+ variable used to check we are still running. */
+ if (sErrorEverOccurred == pdFALSE) {
+ (*pxQueueParameters->psCheckVariable)++;
+ }
+
+ /* Increment the value we expect to remove from the queue next time
+ round. */
+ ++usExpectedValue;
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreBlockingQueuesStillRunning(void)
+{
+ static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = {(unsigned short) 0, (unsigned short) 0, (unsigned short) 0 };
+ static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = {(unsigned short) 0, (unsigned short) 0, (unsigned short) 0 };
+ portBASE_TYPE xReturn = pdPASS, xTasks;
+
+ /* Not too worried about mutual exclusion on these variables as they are 16
+ bits and we are only reading them. We also only care to see if they have
+ changed or not.
+
+ Loop through each check variable to and return pdFALSE if any are found not
+ to have changed since the last call. */
+
+ for (xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++) {
+ if (sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ]) {
+ xReturn = pdFALSE;
+ }
+ sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ];
+
+
+ if (sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ]) {
+ xReturn = pdFALSE;
+ }
+ sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ];
+ }
+
+ return xReturn;
+}
+
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;
+}
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/PollQ.c b/gyro_board/src/usb/CommonDemoTasks/PollQ.c
new file mode 100644
index 0000000..5428693
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/PollQ.c
@@ -0,0 +1,230 @@
+/*
+ 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.
+*/
+
+/*
+ * This version of PollQ. c is for use on systems that have limited stack
+ * space and no display facilities. The complete version can be found in
+ * the Demo/Common/Full directory.
+ *
+ * Creates two tasks that communicate over a single queue. One task acts as a
+ * producer, the other a consumer.
+ *
+ * The producer loops for three iteration, posting an incrementing number onto the
+ * queue each cycle. It then delays for a fixed period before doing exactly the
+ * same again.
+ *
+ * The consumer loops emptying the queue. Each item removed from the queue is
+ * checked to ensure it contains the expected value. When the queue is empty it
+ * blocks for a fixed period, then does the same again.
+ *
+ * All queue access is performed without blocking. The consumer completely empties
+ * the queue each time it runs so the producer should never find the queue full.
+ *
+ * An error is flagged if the consumer obtains an unexpected value or the producer
+ * find the queue is full.
+ */
+
+/*
+Changes from V2.0.0
+
+ + Delay periods are now specified using variables and constants of
+ portTickType rather than unsigned long.
+*/
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Demo program include files. */
+#include "PollQ.h"
+
+#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE
+#define pollqQUEUE_SIZE ( 10 )
+#define pollqPRODUCER_DELAY ( ( portTickType ) 200 / portTICK_RATE_MS )
+#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( portTickType ) ( 20 / portTICK_RATE_MS ) )
+#define pollqNO_DELAY ( ( portTickType ) 0 )
+#define pollqVALUES_TO_PRODUCE ( ( signed portBASE_TYPE ) 3 )
+#define pollqINITIAL_VALUE ( ( signed portBASE_TYPE ) 0 )
+
+/* The task that posts the incrementing number onto the queue. */
+static portTASK_FUNCTION_PROTO(vPolledQueueProducer, pvParameters);
+
+/* The task that empties the queue. */
+static portTASK_FUNCTION_PROTO(vPolledQueueConsumer, pvParameters);
+
+/* Variables that are used to check that the tasks are still running with no
+errors. */
+static volatile signed portBASE_TYPE xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE;
+
+/*-----------------------------------------------------------*/
+
+void vStartPolledQueueTasks(unsigned portBASE_TYPE uxPriority)
+{
+ static xQueueHandle xPolledQueue;
+
+ /* Create the queue used by the producer and consumer. */
+ xPolledQueue = xQueueCreate(pollqQUEUE_SIZE, (unsigned portBASE_TYPE) sizeof(unsigned short));
+
+ /* 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(xPolledQueue, (signed char *) "Poll_Test_Queue");
+
+ /* Spawn the producer and consumer. */
+ xTaskCreate(vPolledQueueConsumer, (signed char *) "QConsNB", pollqSTACK_SIZE, (void *) &xPolledQueue, uxPriority, (xTaskHandle *) NULL);
+ xTaskCreate(vPolledQueueProducer, (signed char *) "QProdNB", pollqSTACK_SIZE, (void *) &xPolledQueue, uxPriority, (xTaskHandle *) NULL);
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION(vPolledQueueProducer, pvParameters)
+{
+ unsigned short usValue = (unsigned short) 0;
+ signed portBASE_TYPE xError = pdFALSE, xLoop;
+
+ for (;;) {
+ for (xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++) {
+ /* Send an incrementing number on the queue without blocking. */
+ if (xQueueSend(*((xQueueHandle *) pvParameters), (void *) &usValue, pollqNO_DELAY) != pdPASS) {
+ /* We should never find the queue full so if we get here there
+ has been an error. */
+ xError = pdTRUE;
+ } else {
+ if (xError == pdFALSE) {
+ /* If an error has ever been recorded we stop incrementing the
+ check variable. */
+ portENTER_CRITICAL();
+ xPollingProducerCount++;
+ portEXIT_CRITICAL();
+ }
+
+ /* Update the value we are going to post next time around. */
+ usValue++;
+ }
+ }
+
+ /* Wait before we start posting again to ensure the consumer runs and
+ empties the queue. */
+ vTaskDelay(pollqPRODUCER_DELAY);
+ }
+} /*lint !e818 Function prototype must conform to API. */
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION(vPolledQueueConsumer, pvParameters)
+{
+ unsigned short usData, usExpectedValue = (unsigned short) 0;
+ signed portBASE_TYPE xError = pdFALSE;
+
+ for (;;) {
+ /* Loop until the queue is empty. */
+ while (uxQueueMessagesWaiting(*((xQueueHandle *) pvParameters))) {
+ if (xQueueReceive(*((xQueueHandle *) pvParameters), &usData, pollqNO_DELAY) == pdPASS) {
+ if (usData != usExpectedValue) {
+ /* This is not what we expected to receive so an error has
+ occurred. */
+ xError = pdTRUE;
+
+ /* Catch-up to the value we received so our next expected
+ value should again be correct. */
+ usExpectedValue = usData;
+ } else {
+ if (xError == pdFALSE) {
+ /* Only increment the check variable if no errors have
+ occurred. */
+ portENTER_CRITICAL();
+ xPollingConsumerCount++;
+ portEXIT_CRITICAL();
+ }
+ }
+
+ /* Next time round we would expect the number to be one higher. */
+ usExpectedValue++;
+ }
+ }
+
+ /* Now the queue is empty we block, allowing the producer to place more
+ items in the queue. */
+ vTaskDelay(pollqCONSUMER_DELAY);
+ }
+} /*lint !e818 Function prototype must conform to API. */
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running with no errors. */
+portBASE_TYPE xArePollingQueuesStillRunning(void)
+{
+ portBASE_TYPE xReturn;
+
+ /* Check both the consumer and producer poll count to check they have both
+ been changed since out last trip round. We do not need a critical section
+ around the check variables as this is called from a higher priority than
+ the other tasks that access the same variables. */
+ if ((xPollingConsumerCount == pollqINITIAL_VALUE) ||
+ (xPollingProducerCount == pollqINITIAL_VALUE)
+ ) {
+ xReturn = pdFALSE;
+ } else {
+ xReturn = pdTRUE;
+ }
+
+ /* Set the check variables back down so we know if they have been
+ incremented the next time around. */
+ xPollingConsumerCount = pollqINITIAL_VALUE;
+ xPollingProducerCount = pollqINITIAL_VALUE;
+
+ return xReturn;
+}
diff --git a/gyro_board/src/usb/CommonDemoTasks/QPeek.c b/gyro_board/src/usb/CommonDemoTasks/QPeek.c
new file mode 100644
index 0000000..6aa2f78
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/QPeek.c
@@ -0,0 +1,416 @@
+/*
+ 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 behaviour when data is peeked from a queue when there are
+ * multiple tasks blocked on the queue.
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* Demo program include files. */
+#include "QPeek.h"
+
+#define qpeekQUEUE_LENGTH ( 5 )
+#define qpeekNO_BLOCK ( 0 )
+#define qpeekSHORT_DELAY ( 10 )
+
+#define qpeekLOW_PRIORITY ( tskIDLE_PRIORITY + 0 )
+#define qpeekMEDIUM_PRIORITY ( tskIDLE_PRIORITY + 1 )
+#define qpeekHIGH_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define qpeekHIGHEST_PRIORITY ( tskIDLE_PRIORITY + 3 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * The following three tasks are used to demonstrate the peeking behaviour.
+ * Each task is given a different priority to demonstrate the order in which
+ * tasks are woken as data is peeked from a queue.
+ */
+static void prvLowPriorityPeekTask(void *pvParameters);
+static void prvMediumPriorityPeekTask(void *pvParameters);
+static void prvHighPriorityPeekTask(void *pvParameters);
+static void prvHighestPriorityPeekTask(void *pvParameters);
+
+/*-----------------------------------------------------------*/
+
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be
+detected in any of the tasks. */
+static volatile portBASE_TYPE xErrorDetected = pdFALSE;
+
+/* Counter that is 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;
+
+/* Handles to the test tasks. */
+xTaskHandle xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask;
+/*-----------------------------------------------------------*/
+
+void vStartQueuePeekTasks(void)
+{
+ xQueueHandle xQueue;
+
+ /* Create the queue that we are going to use for the test/demo. */
+ xQueue = xQueueCreate(qpeekQUEUE_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 *) "QPeek_Test_Queue");
+
+ /* Create the demo tasks 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(prvLowPriorityPeekTask, (signed portCHAR *)"PeekL", configMINIMAL_STACK_SIZE, (void *) xQueue, qpeekLOW_PRIORITY, NULL);
+ xTaskCreate(prvMediumPriorityPeekTask, (signed portCHAR *)"PeekM", configMINIMAL_STACK_SIZE, (void *) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask);
+ xTaskCreate(prvHighPriorityPeekTask, (signed portCHAR *)"PeekH1", configMINIMAL_STACK_SIZE, (void *) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask);
+ xTaskCreate(prvHighestPriorityPeekTask, (signed portCHAR *)"PeekH2", configMINIMAL_STACK_SIZE, (void *) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask);
+}
+/*-----------------------------------------------------------*/
+
+static void prvHighestPriorityPeekTask(void *pvParameters)
+{
+ xQueueHandle xQueue = (xQueueHandle) pvParameters;
+ unsigned portLONG ulValue;
+
+#ifdef USE_STDIO
+ {
+ void vPrintDisplayMessage(const portCHAR * const * ppcMessageToSend);
+
+ const portCHAR * const pcTaskStartMsg = "Queue peek test started.\r\n";
+
+ /* Queue a message for printing to say the task has started. */
+ vPrintDisplayMessage(&pcTaskStartMsg);
+ }
+#endif
+
+ for (;;) {
+ /* Try peeking from the queue. The queue should be empty so we will
+ block, allowing the high priority task to execute. */
+ if (xQueuePeek(xQueue, &ulValue, portMAX_DELAY) != pdPASS) {
+ /* We expected to have received something by the time we unblock. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* When we reach here the high and medium priority tasks should still
+ be blocked on the queue. We unblocked because the low priority task
+ wrote a value to the queue, which we should have peeked. Peeking the
+ data (rather than receiving it) will leave the data on the queue, so
+ the high priority task should then have also been unblocked, but not
+ yet executed. */
+ if (ulValue != 0x11223344) {
+ /* We did not receive the expected value. */
+ xErrorDetected = pdTRUE;
+ }
+
+ if (uxQueueMessagesWaiting(xQueue) != 1) {
+ /* The message should have been left on the queue. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Now we are going to actually receive the data, so when the high
+ priority task runs it will find the queue empty and return to the
+ blocked state. */
+ ulValue = 0;
+ if (xQueueReceive(xQueue, &ulValue, qpeekNO_BLOCK) != pdPASS) {
+ /* We expected to receive the value. */
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulValue != 0x11223344) {
+ /* We did not receive the expected value - which should have been
+ the same value as was peeked. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Now we will block again as the queue is once more empty. The low
+ priority task can then execute again. */
+ if (xQueuePeek(xQueue, &ulValue, portMAX_DELAY) != pdPASS) {
+ /* We expected to have received something by the time we unblock. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* When we get here the low priority task should have again written to the
+ queue. */
+ if (ulValue != 0x01234567) {
+ /* We did not receive the expected value. */
+ xErrorDetected = pdTRUE;
+ }
+
+ if (uxQueueMessagesWaiting(xQueue) != 1) {
+ /* The message should have been left on the queue. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* We only peeked the data, so suspending ourselves now should enable
+ the high priority task to also peek the data. The high priority task
+ will have been unblocked when we peeked the data as we left the data
+ in the queue. */
+ vTaskSuspend(NULL);
+
+
+
+ /* This time we are going to do the same as the above test, but the
+ high priority task is going to receive the data, rather than peek it.
+ This means that the medium priority task should never peek the value. */
+ if (xQueuePeek(xQueue, &ulValue, portMAX_DELAY) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulValue != 0xaabbaabb) {
+ xErrorDetected = pdTRUE;
+ }
+
+ vTaskSuspend(NULL);
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvHighPriorityPeekTask(void *pvParameters)
+{
+ xQueueHandle xQueue = (xQueueHandle) pvParameters;
+ unsigned portLONG ulValue;
+
+ for (;;) {
+ /* Try peeking from the queue. The queue should be empty so we will
+ block, allowing the medium priority task to execute. Both the high
+ and highest priority tasks will then be blocked on the queue. */
+ if (xQueuePeek(xQueue, &ulValue, portMAX_DELAY) != pdPASS) {
+ /* We expected to have received something by the time we unblock. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* When we get here the highest priority task should have peeked the data
+ (unblocking this task) then suspended (allowing this task to also peek
+ the data). */
+ if (ulValue != 0x01234567) {
+ /* We did not receive the expected value. */
+ xErrorDetected = pdTRUE;
+ }
+
+ if (uxQueueMessagesWaiting(xQueue) != 1) {
+ /* The message should have been left on the queue. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* We only peeked the data, so suspending ourselves now should enable
+ the medium priority task to also peek the data. The medium priority task
+ will have been unblocked when we peeked the data as we left the data
+ in the queue. */
+ vTaskSuspend(NULL);
+
+
+ /* This time we are going actually receive the value, so the medium
+ priority task will never peek the data - we removed it from the queue. */
+ if (xQueueReceive(xQueue, &ulValue, portMAX_DELAY) != pdPASS) {
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulValue != 0xaabbaabb) {
+ xErrorDetected = pdTRUE;
+ }
+
+ vTaskSuspend(NULL);
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvMediumPriorityPeekTask(void *pvParameters)
+{
+ xQueueHandle xQueue = (xQueueHandle) pvParameters;
+ unsigned portLONG ulValue;
+
+ for (;;) {
+ /* Try peeking from the queue. The queue should be empty so we will
+ block, allowing the low priority task to execute. The highest, high
+ and medium priority tasks will then all be blocked on the queue. */
+ if (xQueuePeek(xQueue, &ulValue, portMAX_DELAY) != pdPASS) {
+ /* We expected to have received something by the time we unblock. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* When we get here the high priority task should have peeked the data
+ (unblocking this task) then suspended (allowing this task to also peek
+ the data). */
+ if (ulValue != 0x01234567) {
+ /* We did not receive the expected value. */
+ xErrorDetected = pdTRUE;
+ }
+
+ if (uxQueueMessagesWaiting(xQueue) != 1) {
+ /* The message should have been left on the queue. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Just so we know the test is still running. */
+ ulLoopCounter++;
+
+ /* Now we can suspend ourselves so the low priority task can execute
+ again. */
+ vTaskSuspend(NULL);
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvLowPriorityPeekTask(void *pvParameters)
+{
+ xQueueHandle xQueue = (xQueueHandle) pvParameters;
+ unsigned portLONG ulValue;
+
+ for (;;) {
+ /* Write some data to the queue. This should unblock the highest
+ priority task that is waiting to peek data from the queue. */
+ ulValue = 0x11223344;
+ if (xQueueSendToBack(xQueue, &ulValue, qpeekNO_BLOCK) != pdPASS) {
+ /* We were expecting the queue to be empty so we should not of
+ had a problem writing to the queue. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* By the time we get here the data should have been removed from
+ the queue. */
+ if (uxQueueMessagesWaiting(xQueue) != 0) {
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Write another value to the queue, again waking the highest priority
+ task that is blocked on the queue. */
+ ulValue = 0x01234567;
+ if (xQueueSendToBack(xQueue, &ulValue, qpeekNO_BLOCK) != pdPASS) {
+ /* We were expecting the queue to be empty so we should not of
+ had a problem writing to the queue. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* All the other tasks should now have successfully peeked the data.
+ The data is still in the queue so we should be able to receive it. */
+ ulValue = 0;
+ if (xQueueReceive(xQueue, &ulValue, qpeekNO_BLOCK) != pdPASS) {
+ /* We expected to receive the data. */
+ xErrorDetected = pdTRUE;
+ }
+
+ if (ulValue != 0x01234567) {
+ /* We did not receive the expected value. */
+ }
+
+ /* Lets just delay a while as this is an intensive test as we don't
+ want to starve other tests of processing time. */
+ vTaskDelay(qpeekSHORT_DELAY);
+
+ /* Unsuspend the other tasks so we can repeat the test - this time
+ however not all the other tasks will peek the data as the high
+ priority task is actually going to remove it from the queue. Send
+ to front is used just to be different. As the queue is empty it
+ makes no difference to the result. */
+ vTaskResume(xMediumPriorityTask);
+ vTaskResume(xHighPriorityTask);
+ vTaskResume(xHighestPriorityTask);
+
+ ulValue = 0xaabbaabb;
+ if (xQueueSendToFront(xQueue, &ulValue, qpeekNO_BLOCK) != pdPASS) {
+ /* We were expecting the queue to be empty so we should not of
+ had a problem writing to the queue. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* This time we should find that the queue is empty. The high priority
+ task actually removed the data rather than just peeking it. */
+ if (xQueuePeek(xQueue, &ulValue, qpeekNO_BLOCK) != errQUEUE_EMPTY) {
+ /* We expected to receive the data. */
+ xErrorDetected = pdTRUE;
+ }
+
+ /* Unsuspend the highest and high priority tasks so we can go back
+ and repeat the whole thing. The medium priority task should not be
+ suspended as it was not able to peek the data in this last case. */
+ vTaskResume(xHighPriorityTask);
+ vTaskResume(xHighestPriorityTask);
+
+ /* Lets just delay a while as this is an intensive test as we don't
+ want to starve other tests of processing time. */
+ vTaskDelay(qpeekSHORT_DELAY);
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreQueuePeekTasksStillRunning(void)
+{
+ static unsigned portLONG ulLastLoopCounter = 0;
+
+ /* If the demo task is still running then we expect the loopcounter to
+ have incremented since this function was last called. */
+ if (ulLastLoopCounter == ulLoopCounter) {
+ xErrorDetected = pdTRUE;
+ }
+
+ ulLastLoopCounter = ulLoopCounter;
+
+ /* Errors detected in the task itself will have latched xErrorDetected
+ to true. */
+
+ return !xErrorDetected;
+}
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/blocktim.c b/gyro_board/src/usb/CommonDemoTasks/blocktim.c
new file mode 100644
index 0000000..0174cee
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/blocktim.c
@@ -0,0 +1,456 @@
+/*
+ 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.
+*/
+
+/*
+ * This file contains some test scenarios that ensure tasks do not exit queue
+ * send or receive functions prematurely. A description of the tests is
+ * included within the code.
+ */
+
+/* Kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Demo includes. */
+#include "blocktim.h"
+
+/* Task priorities. Allow these to be overridden. */
+#ifndef bktPRIMARY_PRIORITY
+#define bktPRIMARY_PRIORITY ( 3 )
+#endif
+
+#ifndef bktSECONDARY_PRIORITY
+#define bktSECONDARY_PRIORITY ( 2 )
+#endif
+
+/* Task behaviour. */
+#define bktQUEUE_LENGTH ( 5 )
+#define bktSHORT_WAIT ( ( ( portTickType ) 20 ) / portTICK_RATE_MS )
+#define bktPRIMARY_BLOCK_TIME ( 10 )
+#define bktALLOWABLE_MARGIN ( 15 )
+#define bktTIME_TO_BLOCK ( 175 )
+#define bktDONT_BLOCK ( ( portTickType ) 0 )
+#define bktRUN_INDICATOR ( ( unsigned portBASE_TYPE ) 0x55 )
+
+/* The queue on which the tasks block. */
+static xQueueHandle xTestQueue;
+
+/* Handle to the secondary task is required by the primary task for calls
+to vTaskSuspend/Resume(). */
+static xTaskHandle xSecondary;
+
+/* Used to ensure that tasks are still executing without error. */
+static volatile portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0;
+static volatile portBASE_TYPE xErrorOccurred = pdFALSE;
+
+/* Provides a simple mechanism for the primary task to know when the
+secondary task has executed. */
+static volatile unsigned portBASE_TYPE xRunIndicator;
+
+/* The two test tasks. Their behaviour is commented within the files. */
+static void vPrimaryBlockTimeTestTask(void *pvParameters);
+static void vSecondaryBlockTimeTestTask(void *pvParameters);
+
+/*-----------------------------------------------------------*/
+
+void vCreateBlockTimeTasks(void)
+{
+ /* Create the queue on which the two tasks block. */
+ xTestQueue = xQueueCreate(bktQUEUE_LENGTH, sizeof(portBASE_TYPE));
+
+ /* 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(xTestQueue, (signed char *) "Block_Time_Queue");
+
+ /* Create the two test tasks. */
+ xTaskCreate(vPrimaryBlockTimeTestTask, (signed char *)"BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL);
+ xTaskCreate(vSecondaryBlockTimeTestTask, (signed char *)"BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary);
+}
+/*-----------------------------------------------------------*/
+
+static void vPrimaryBlockTimeTestTask(void *pvParameters)
+{
+ portBASE_TYPE xItem, xData;
+ portTickType xTimeWhenBlocking;
+ portTickType xTimeToBlock, xBlockedTime;
+
+ (void) pvParameters;
+
+ for (;;) {
+ /*********************************************************************
+ Test 1
+
+ Simple block time wakeup test on queue receives. */
+ for (xItem = 0; xItem < bktQUEUE_LENGTH; xItem++) {
+ /* The queue is empty. Attempt to read from the queue using a block
+ time. When we wake, ensure the delta in time is as expected. */
+ xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;
+
+ xTimeWhenBlocking = xTaskGetTickCount();
+
+ /* We should unblock after xTimeToBlock having not received
+ anything on the queue. */
+ if (xQueueReceive(xTestQueue, &xData, xTimeToBlock) != errQUEUE_EMPTY) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* How long were we blocked for? */
+ xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+ if (xBlockedTime < xTimeToBlock) {
+ /* Should not have blocked for less than we requested. */
+ xErrorOccurred = pdTRUE;
+ }
+
+ if (xBlockedTime > (xTimeToBlock + bktALLOWABLE_MARGIN)) {
+ /* Should not have blocked for longer than we requested,
+ although we would not necessarily run as soon as we were
+ unblocked so a margin is allowed. */
+ xErrorOccurred = pdTRUE;
+ }
+ }
+
+ /*********************************************************************
+ Test 2
+
+ Simple block time wakeup test on queue sends.
+
+ First fill the queue. It should be empty so all sends should pass. */
+ for (xItem = 0; xItem < bktQUEUE_LENGTH; xItem++) {
+ if (xQueueSend(xTestQueue, &xItem, bktDONT_BLOCK) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+#if configUSE_PREEMPTION == 0
+ taskYIELD();
+#endif
+ }
+
+ for (xItem = 0; xItem < bktQUEUE_LENGTH; xItem++) {
+ /* The queue is full. Attempt to write to the queue using a block
+ time. When we wake, ensure the delta in time is as expected. */
+ xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;
+
+ xTimeWhenBlocking = xTaskGetTickCount();
+
+ /* We should unblock after xTimeToBlock having not received
+ anything on the queue. */
+ if (xQueueSend(xTestQueue, &xItem, xTimeToBlock) != errQUEUE_FULL) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* How long were we blocked for? */
+ xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+ if (xBlockedTime < xTimeToBlock) {
+ /* Should not have blocked for less than we requested. */
+ xErrorOccurred = pdTRUE;
+ }
+
+ if (xBlockedTime > (xTimeToBlock + bktALLOWABLE_MARGIN)) {
+ /* Should not have blocked for longer than we requested,
+ although we would not necessarily run as soon as we were
+ unblocked so a margin is allowed. */
+ xErrorOccurred = pdTRUE;
+ }
+ }
+
+ /*********************************************************************
+ Test 3
+
+ Wake the other task, it will block attempting to post to the queue.
+ When we read from the queue the other task will wake, but before it
+ can run we will post to the queue again. When the other task runs it
+ will find the queue still full, even though it was woken. It should
+ recognise that its block time has not expired and return to block for
+ the remains of its block time.
+
+ Wake the other task so it blocks attempting to post to the already
+ full queue. */
+ xRunIndicator = 0;
+ vTaskResume(xSecondary);
+
+ /* We need to wait a little to ensure the other task executes. */
+ while (xRunIndicator != bktRUN_INDICATOR) {
+ /* The other task has not yet executed. */
+ vTaskDelay(bktSHORT_WAIT);
+ }
+ /* Make sure the other task is blocked on the queue. */
+ vTaskDelay(bktSHORT_WAIT);
+ xRunIndicator = 0;
+
+ for (xItem = 0; xItem < bktQUEUE_LENGTH; xItem++) {
+ /* Now when we make space on the queue the other task should wake
+ but not execute as this task has higher priority. */
+ if (xQueueReceive(xTestQueue, &xData, bktDONT_BLOCK) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Now fill the queue again before the other task gets a chance to
+ execute. If the other task had executed we would find the queue
+ full ourselves, and the other task have set xRunIndicator. */
+ if (xQueueSend(xTestQueue, &xItem, bktDONT_BLOCK) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ if (xRunIndicator == bktRUN_INDICATOR) {
+ /* The other task should not have executed. */
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Raise the priority of the other task so it executes and blocks
+ on the queue again. */
+ vTaskPrioritySet(xSecondary, bktPRIMARY_PRIORITY + 2);
+
+ /* The other task should now have re-blocked without exiting the
+ queue function. */
+ if (xRunIndicator == bktRUN_INDICATOR) {
+ /* The other task should not have executed outside of the
+ queue function. */
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Set the priority back down. */
+ vTaskPrioritySet(xSecondary, bktSECONDARY_PRIORITY);
+ }
+
+ /* Let the other task timeout. When it unblockes it will check that it
+ unblocked at the correct time, then suspend itself. */
+ while (xRunIndicator != bktRUN_INDICATOR) {
+ vTaskDelay(bktSHORT_WAIT);
+ }
+ vTaskDelay(bktSHORT_WAIT);
+ xRunIndicator = 0;
+
+
+ /*********************************************************************
+ Test 4
+
+ As per test 3 - but with the send and receive the other way around.
+ The other task blocks attempting to read from the queue.
+
+ Empty the queue. We should find that it is full. */
+ for (xItem = 0; xItem < bktQUEUE_LENGTH; xItem++) {
+ if (xQueueReceive(xTestQueue, &xData, bktDONT_BLOCK) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+ }
+
+ /* Wake the other task so it blocks attempting to read from the
+ already empty queue. */
+ vTaskResume(xSecondary);
+
+ /* We need to wait a little to ensure the other task executes. */
+ while (xRunIndicator != bktRUN_INDICATOR) {
+ vTaskDelay(bktSHORT_WAIT);
+ }
+ vTaskDelay(bktSHORT_WAIT);
+ xRunIndicator = 0;
+
+ for (xItem = 0; xItem < bktQUEUE_LENGTH; xItem++) {
+ /* Now when we place an item on the queue the other task should
+ wake but not execute as this task has higher priority. */
+ if (xQueueSend(xTestQueue, &xItem, bktDONT_BLOCK) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Now empty the queue again before the other task gets a chance to
+ execute. If the other task had executed we would find the queue
+ empty ourselves, and the other task would be suspended. */
+ if (xQueueReceive(xTestQueue, &xData, bktDONT_BLOCK) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ if (xRunIndicator == bktRUN_INDICATOR) {
+ /* The other task should not have executed. */
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Raise the priority of the other task so it executes and blocks
+ on the queue again. */
+ vTaskPrioritySet(xSecondary, bktPRIMARY_PRIORITY + 2);
+
+ /* The other task should now have re-blocked without exiting the
+ queue function. */
+ if (xRunIndicator == bktRUN_INDICATOR) {
+ /* The other task should not have executed outside of the
+ queue function. */
+ xErrorOccurred = pdTRUE;
+ }
+ vTaskPrioritySet(xSecondary, bktSECONDARY_PRIORITY);
+ }
+
+ /* Let the other task timeout. When it unblockes it will check that it
+ unblocked at the correct time, then suspend itself. */
+ while (xRunIndicator != bktRUN_INDICATOR) {
+ vTaskDelay(bktSHORT_WAIT);
+ }
+ vTaskDelay(bktSHORT_WAIT);
+
+ xPrimaryCycles++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void vSecondaryBlockTimeTestTask(void *pvParameters)
+{
+ portTickType xTimeWhenBlocking, xBlockedTime;
+ portBASE_TYPE xData;
+
+ (void) pvParameters;
+
+ for (;;) {
+ /*********************************************************************
+ Test 1 and 2
+
+ This task does does not participate in these tests. */
+ vTaskSuspend(NULL);
+
+ /*********************************************************************
+ Test 3
+
+ The first thing we do is attempt to read from the queue. It should be
+ full so we block. Note the time before we block so we can check the
+ wake time is as per that expected. */
+ xTimeWhenBlocking = xTaskGetTickCount();
+
+ /* We should unblock after bktTIME_TO_BLOCK having not sent
+ anything to the queue. */
+ xData = 0;
+ xRunIndicator = bktRUN_INDICATOR;
+ if (xQueueSend(xTestQueue, &xData, bktTIME_TO_BLOCK) != errQUEUE_FULL) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* How long were we inside the send function? */
+ xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+ /* We should not have blocked for less time than bktTIME_TO_BLOCK. */
+ if (xBlockedTime < bktTIME_TO_BLOCK) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* We should of not blocked for much longer than bktALLOWABLE_MARGIN
+ either. A margin is permitted as we would not necessarily run as
+ soon as we unblocked. */
+ if (xBlockedTime > (bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN)) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Suspend ready for test 3. */
+ xRunIndicator = bktRUN_INDICATOR;
+ vTaskSuspend(NULL);
+
+ /*********************************************************************
+ Test 4
+
+ As per test three, but with the send and receive reversed. */
+ xTimeWhenBlocking = xTaskGetTickCount();
+
+ /* We should unblock after bktTIME_TO_BLOCK having not received
+ anything on the queue. */
+ xRunIndicator = bktRUN_INDICATOR;
+ if (xQueueReceive(xTestQueue, &xData, bktTIME_TO_BLOCK) != errQUEUE_EMPTY) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
+
+ /* We should not have blocked for less time than bktTIME_TO_BLOCK. */
+ if (xBlockedTime < bktTIME_TO_BLOCK) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* We should of not blocked for much longer than bktALLOWABLE_MARGIN
+ either. A margin is permitted as we would not necessarily run as soon
+ as we unblocked. */
+ if (xBlockedTime > (bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN)) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ xRunIndicator = bktRUN_INDICATOR;
+
+ xSecondaryCycles++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xAreBlockTimeTestTasksStillRunning(void)
+{
+ static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;
+ portBASE_TYPE xReturn = pdPASS;
+
+ /* Have both tasks performed at least one cycle since this function was
+ last called? */
+ if (xPrimaryCycles == xLastPrimaryCycleCount) {
+ xReturn = pdFAIL;
+ }
+
+ if (xSecondaryCycles == xLastSecondaryCycleCount) {
+ xReturn = pdFAIL;
+ }
+
+ if (xErrorOccurred == pdTRUE) {
+ xReturn = pdFAIL;
+ }
+
+ xLastSecondaryCycleCount = xSecondaryCycles;
+ xLastPrimaryCycleCount = xPrimaryCycles;
+
+ return xReturn;
+}
diff --git a/gyro_board/src/usb/CommonDemoTasks/flash.c b/gyro_board/src/usb/CommonDemoTasks/flash.c
new file mode 100644
index 0000000..fadc899
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/flash.c
@@ -0,0 +1,146 @@
+/*
+ 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.
+*/
+
+/**
+ * This version of flash .c is for use on systems that have limited stack space
+ * and no display facilities. The complete version can be found in the
+ * Demo/Common/Full directory.
+ *
+ * Three tasks are created, each of which flash an LED at a different rate. The first
+ * LED flashes every 200ms, the second every 400ms, the third every 600ms.
+ *
+ * The LED flash tasks provide instant visual feedback. They show that the scheduler
+ * is still operational.
+ *
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Demo program include files. */
+#include "partest.h"
+#include "flash.h"
+
+#define ledSTACK_SIZE configMINIMAL_STACK_SIZE
+#define ledNUMBER_OF_LEDS ( 3 )
+#define ledFLASH_RATE_BASE ( ( portTickType ) 333 )
+
+/* Variable used by the created tasks to calculate the LED number to use, and
+the rate at which they should flash the LED. */
+static volatile unsigned portBASE_TYPE uxFlashTaskNumber = 0;
+
+/* The task that is created three times. */
+static portTASK_FUNCTION_PROTO(vLEDFlashTask, pvParameters);
+
+/*-----------------------------------------------------------*/
+
+// To continually print out the serial output, run the following command.
+// while true; do [ `ls /dev/ttyACM* 2>/dev/null` ] && ls /dev/ttyACM* | python -c "import sys; x = sys.stdin.readline()[:-1].split(' ')[0]; sys.stderr.write('Connecting to %s\n' % (x,)); print x" | xargs cat || sleep 0.25; done
+
+void vStartLEDFlashTasks(unsigned portBASE_TYPE uxPriority)
+{
+ signed portBASE_TYPE xLEDTask;
+
+ /* Create the three tasks. */
+ for (xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask) {
+ /* Spawn the task. */
+ xTaskCreate(vLEDFlashTask, (signed char *) "LEDx", ledSTACK_SIZE, NULL, uxPriority, (xTaskHandle *) NULL);
+ }
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION(vLEDFlashTask, pvParameters)
+{
+ portTickType xFlashRate, xLastFlashTime;
+ unsigned portBASE_TYPE uxLED;
+
+ /* The parameters are not used. */
+ (void) pvParameters;
+
+ /* Calculate the LED and flash rate. */
+ portENTER_CRITICAL();
+ {
+ /* See which of the eight LED's we should use. */
+ uxLED = uxFlashTaskNumber;
+
+ /* Update so the next task uses the next LED. */
+ uxFlashTaskNumber++;
+ }
+ portEXIT_CRITICAL();
+
+ xFlashRate = ledFLASH_RATE_BASE + (ledFLASH_RATE_BASE * (portTickType) uxLED);
+ xFlashRate /= portTICK_RATE_MS;
+
+ /* We will turn the LED on and off again in the delay period, so each
+ delay is only half the total period. */
+ xFlashRate /= (portTickType) 2;
+
+ /* We need to initialise xLastFlashTime prior to the first call to
+ vTaskDelayUntil(). */
+ xLastFlashTime = xTaskGetTickCount();
+
+ for (;;) {
+ /* Delay for half the flash period then turn the LED on. */
+ vTaskDelayUntil(&xLastFlashTime, xFlashRate);
+ vParTestToggleLED(uxLED);
+
+ /* Delay for half the flash period then turn the LED off. */
+ vTaskDelayUntil(&xLastFlashTime, xFlashRate);
+ vParTestToggleLED(uxLED);
+ }
+} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/AltBlckQ.h b/gyro_board/src/usb/CommonDemoTasks/include/AltBlckQ.h
new file mode 100644
index 0000000..dad37ba
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/AltBlckQ.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef ALT_BLOCK_Q_H
+#define ALT_BLOCK_Q_H
+
+void vStartAltBlockingQueueTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreAltBlockingQueuesStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/AltBlock.h b/gyro_board/src/usb/CommonDemoTasks/include/AltBlock.h
new file mode 100644
index 0000000..caa0516
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/AltBlock.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef FAST_BLOCK_TIME_TEST_H
+#define FAST_BLOCK_TIME_TEST_H
+
+void vCreateAltBlockTimeTasks(void);
+portBASE_TYPE xAreAltBlockTimeTestTasksStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/AltPollQ.h b/gyro_board/src/usb/CommonDemoTasks/include/AltPollQ.h
new file mode 100644
index 0000000..66ac04e
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/AltPollQ.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef ALT_POLLED_Q_H
+#define ALT_POLLED_Q_H
+
+void vStartAltPolledQueueTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreAltPollingQueuesStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/AltQTest.h b/gyro_board/src/usb/CommonDemoTasks/include/AltQTest.h
new file mode 100644
index 0000000..b8cc24d
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/AltQTest.h
@@ -0,0 +1,63 @@
+/*
+ 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.
+*/
+
+#ifndef FAST_GEN_Q_TEST_H
+#define FAST_GEN_Q_TEST_H
+
+void vStartAltGenericQueueTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreAltGenericQueueTasksStillRunning(void);
+
+#endif /* GEN_Q_TEST_H */
+
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/BlockQ.h b/gyro_board/src/usb/CommonDemoTasks/include/BlockQ.h
new file mode 100644
index 0000000..30ea0e1
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/BlockQ.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef BLOCK_Q_H
+#define BLOCK_Q_H
+
+void vStartBlockingQueueTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreBlockingQueuesStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/GenQTest.h b/gyro_board/src/usb/CommonDemoTasks/include/GenQTest.h
new file mode 100644
index 0000000..32a2718
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/GenQTest.h
@@ -0,0 +1,63 @@
+/*
+ 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.
+*/
+
+#ifndef GEN_Q_TEST_H
+#define GEN_Q_TEST_H
+
+void vStartGenericQueueTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreGenericQueueTasksStillRunning(void);
+
+#endif /* GEN_Q_TEST_H */
+
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/IntQueue.h b/gyro_board/src/usb/CommonDemoTasks/include/IntQueue.h
new file mode 100644
index 0000000..514e458
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/IntQueue.h
@@ -0,0 +1,68 @@
+/*
+ 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.
+*/
+
+#ifndef QUEUE_ACCESS_TEST
+#define QUEUE_ACCESS_TEST
+
+void vStartInterruptQueueTasks(void);
+portBASE_TYPE xAreIntQueueTasksStillRunning(void);
+portBASE_TYPE xFirstTimerHandler(void);
+portBASE_TYPE xSecondTimerHandler(void);
+
+#endif /* QUEUE_ACCESS_TEST */
+
+
+
+
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/PollQ.h b/gyro_board/src/usb/CommonDemoTasks/include/PollQ.h
new file mode 100644
index 0000000..096b820
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/PollQ.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef POLLED_Q_H
+#define POLLED_Q_H
+
+void vStartPolledQueueTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xArePollingQueuesStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/QPeek.h b/gyro_board/src/usb/CommonDemoTasks/include/QPeek.h
new file mode 100644
index 0000000..2666ebd
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/QPeek.h
@@ -0,0 +1,63 @@
+/*
+ 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.
+*/
+
+#ifndef Q_PEEK_TEST_H
+#define Q_PEEK_TEST_H
+
+void vStartQueuePeekTasks(void);
+portBASE_TYPE xAreQueuePeekTasksStillRunning(void);
+
+#endif /* Q_PEEK_TEST_H */
+
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/blocktim.h b/gyro_board/src/usb/CommonDemoTasks/include/blocktim.h
new file mode 100644
index 0000000..72fac90
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/blocktim.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef BLOCK_TIME_TEST_H
+#define BLOCK_TIME_TEST_H
+
+void vCreateBlockTimeTasks(void);
+portBASE_TYPE xAreBlockTimeTestTasksStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/comtest.h b/gyro_board/src/usb/CommonDemoTasks/include/comtest.h
new file mode 100644
index 0000000..df974e2
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/comtest.h
@@ -0,0 +1,63 @@
+/*
+ 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.
+*/
+
+#ifndef COMTEST_H
+#define COMTEST_H
+
+void vAltStartComTestTasks(unsigned portBASE_TYPE uxPriority, unsigned long ulBaudRate, unsigned portBASE_TYPE uxLED);
+void vStartComTestTasks(unsigned portBASE_TYPE uxPriority, eCOMPort ePort, eBaud eBaudRate);
+portBASE_TYPE xAreComTestTasksStillRunning(void);
+void vComTestUnsuspendTask(void);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/comtest2.h b/gyro_board/src/usb/CommonDemoTasks/include/comtest2.h
new file mode 100644
index 0000000..18beab0
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/comtest2.h
@@ -0,0 +1,61 @@
+/*
+ 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.
+*/
+
+#ifndef COMTEST_H
+#define COMTEST_H
+
+void vAltStartComTestTasks(unsigned portBASE_TYPE uxPriority, unsigned long ulBaudRate, unsigned portBASE_TYPE uxLED);
+portBASE_TYPE xAreComTestTasksStillRunning(void);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/countsem.h b/gyro_board/src/usb/CommonDemoTasks/include/countsem.h
new file mode 100644
index 0000000..d08db7b
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/countsem.h
@@ -0,0 +1,61 @@
+/*
+ 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.
+*/
+
+#ifndef COUNT_SEMAPHORE_TEST_H
+#define COUNT_SEMAPHORE_TEST_H
+
+void vStartCountingSemaphoreTasks(void);
+portBASE_TYPE xAreCountingSemaphoreTasksStillRunning(void);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/crflash.h b/gyro_board/src/usb/CommonDemoTasks/include/crflash.h
new file mode 100644
index 0000000..6a5f715
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/crflash.h
@@ -0,0 +1,73 @@
+/*
+ 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.
+*/
+
+#ifndef CRFLASH_LED_H
+#define CRFLASH_LED_H
+
+/*
+ * Create the co-routines used to flash the LED's at different rates.
+ *
+ * @param uxPriority The number of 'fixed delay' co-routines to create. This
+ * also effects the number of LED's that will be utilised. For example,
+ * passing in 3 will cause LED's 0 to 2 to be utilised.
+ */
+void vStartFlashCoRoutines(unsigned portBASE_TYPE uxPriority);
+
+/*
+ * Return pdPASS or pdFAIL depending on whether an error has been detected
+ * or not.
+ */
+portBASE_TYPE xAreFlashCoRoutinesStillRunning(void);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/crhook.h b/gyro_board/src/usb/CommonDemoTasks/include/crhook.h
new file mode 100644
index 0000000..370677f
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/crhook.h
@@ -0,0 +1,69 @@
+/*
+ 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.
+*/
+
+#ifndef CRHOOK_H
+#define CRHOOK_H
+
+/*
+ * Create the co-routines used to communicate wit the tick hook.
+ */
+void vStartHookCoRoutines(void);
+
+/*
+ * Return pdPASS or pdFAIL depending on whether an error has been detected
+ * or not.
+ */
+portBASE_TYPE xAreHookCoRoutinesStillRunning(void);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/death.h b/gyro_board/src/usb/CommonDemoTasks/include/death.h
new file mode 100644
index 0000000..155f4f1
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/death.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef SUICIDE_TASK_H
+#define SUICIDE_TASK_H
+
+void vCreateSuicidalTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xIsCreateTaskStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/dynamic.h b/gyro_board/src/usb/CommonDemoTasks/include/dynamic.h
new file mode 100644
index 0000000..b2bf281
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/dynamic.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef DYNAMIC_MANIPULATION_H
+#define DYNAMIC_MANIPULATION_H
+
+void vStartDynamicPriorityTasks(void);
+portBASE_TYPE xAreDynamicPriorityTasksStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/fileIO.h b/gyro_board/src/usb/CommonDemoTasks/include/fileIO.h
new file mode 100644
index 0000000..9f3c7e0
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/fileIO.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef FILE_IO_H
+#define FILE_OI_H
+
+void vDisplayMessage(const char * const pcMessageToPrint);
+void vWriteMessageToDisk(const char * const pcMessage);
+void vWriteBufferToDisk(const char * const pcBuffer, unsigned long ulBufferLength);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/flash.h b/gyro_board/src/usb/CommonDemoTasks/include/flash.h
new file mode 100644
index 0000000..008df24
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/flash.h
@@ -0,0 +1,60 @@
+/*
+ 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.
+*/
+
+#ifndef FLASH_LED_H
+#define FLASH_LED_H
+
+void vStartLEDFlashTasks(unsigned portBASE_TYPE uxPriority);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/flop.h b/gyro_board/src/usb/CommonDemoTasks/include/flop.h
new file mode 100644
index 0000000..2e5fb79
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/flop.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef FLOP_TASKS_H
+#define FLOP_TASKS_H
+
+void vStartMathTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreMathsTaskStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/integer.h b/gyro_board/src/usb/CommonDemoTasks/include/integer.h
new file mode 100644
index 0000000..0bdf620
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/integer.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef INTEGER_TASKS_H
+#define INTEGER_TASKS_H
+
+void vStartIntegerMathTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreIntegerMathsTaskStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/mevents.h b/gyro_board/src/usb/CommonDemoTasks/include/mevents.h
new file mode 100644
index 0000000..5452d4b
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/mevents.h
@@ -0,0 +1,62 @@
+/*
+ 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.
+*/
+
+#ifndef EVENTS_TEST_H
+#define EVENTS_TEST_H
+
+void vStartMultiEventTasks(void);
+portBASE_TYPE xAreMultiEventTasksStillRunning(void);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/partest.h b/gyro_board/src/usb/CommonDemoTasks/include/partest.h
new file mode 100644
index 0000000..4318351
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/partest.h
@@ -0,0 +1,64 @@
+/*
+ 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.
+*/
+
+#ifndef PARTEST_H
+#define PARTEST_H
+
+#define partstDEFAULT_PORT_ADDRESS ( ( unsigned short ) 0x378 )
+
+void vParTestInitialise(void);
+void vParTestSetLED(unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue);
+void vParTestToggleLED(unsigned portBASE_TYPE uxLED);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/print.h b/gyro_board/src/usb/CommonDemoTasks/include/print.h
new file mode 100644
index 0000000..f0242bd
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/print.h
@@ -0,0 +1,63 @@
+/*
+ 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.
+*/
+
+#ifndef PRINT_H
+#define PRINT_H
+
+void vPrintInitialise(void);
+void vPrintDisplayMessage(const char * const * pcMessageToSend);
+const char *pcPrintGetNextMessage(portTickType xPrintRate);
+
+#endif
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/recmutex.h b/gyro_board/src/usb/CommonDemoTasks/include/recmutex.h
new file mode 100644
index 0000000..856d6f8
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/recmutex.h
@@ -0,0 +1,61 @@
+/*
+ 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.
+*/
+
+#ifndef RECURSIVE_MUTEX_TEST_H
+#define RECURSIVE_MUTEX_TEST_H
+
+void vStartRecursiveMutexTasks(void);
+portBASE_TYPE xAreRecursiveMutexTasksStillRunning(void);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/semtest.h b/gyro_board/src/usb/CommonDemoTasks/include/semtest.h
new file mode 100644
index 0000000..04d5369
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/semtest.h
@@ -0,0 +1,61 @@
+/*
+ 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.
+*/
+
+#ifndef SEMAPHORE_TEST_H
+#define SEMAPHORE_TEST_H
+
+void vStartSemaphoreTasks(unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xAreSemaphoreTasksStillRunning(void);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/include/serial.h b/gyro_board/src/usb/CommonDemoTasks/include/serial.h
new file mode 100644
index 0000000..dcc76ea
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/include/serial.h
@@ -0,0 +1,119 @@
+/*
+ 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.
+*/
+
+#ifndef SERIAL_COMMS_H
+#define SERIAL_COMMS_H
+
+typedef void * xComPortHandle;
+
+typedef enum {
+ serCOM1,
+ serCOM2,
+ serCOM3,
+ serCOM4,
+ serCOM5,
+ serCOM6,
+ serCOM7,
+ serCOM8
+} eCOMPort;
+
+typedef enum {
+ serNO_PARITY,
+ serODD_PARITY,
+ serEVEN_PARITY,
+ serMARK_PARITY,
+ serSPACE_PARITY
+} eParity;
+
+typedef enum {
+ serSTOP_1,
+ serSTOP_2
+} eStopBits;
+
+typedef enum {
+ serBITS_5,
+ serBITS_6,
+ serBITS_7,
+ serBITS_8
+} eDataBits;
+
+typedef enum {
+ ser50,
+ ser75,
+ ser110,
+ ser134,
+ ser150,
+ ser200,
+ ser300,
+ ser600,
+ ser1200,
+ ser1800,
+ ser2400,
+ ser4800,
+ ser9600,
+ ser19200,
+ ser38400,
+ ser57600,
+ ser115200
+} eBaud;
+
+xComPortHandle xSerialPortInitMinimal(unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength);
+xComPortHandle xSerialPortInit(eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength);
+void vSerialPutString(xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength);
+signed portBASE_TYPE xSerialGetChar(xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime);
+signed portBASE_TYPE xSerialPutChar(xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime);
+portBASE_TYPE xSerialWaitForSemaphore(xComPortHandle xPort);
+void vSerialClose(xComPortHandle xPort);
+
+#endif
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/integer.c b/gyro_board/src/usb/CommonDemoTasks/integer.c
new file mode 100644
index 0000000..4e2db69
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/integer.c
@@ -0,0 +1,206 @@
+/*
+ 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.
+*/
+
+/*
+ * This version of integer. c is for use on systems that have limited stack
+ * space and no display facilities. The complete version can be found in
+ * the Demo/Common/Full directory.
+ *
+ * As with the full version, the tasks created in this file are a good test
+ * of the scheduler context switch mechanism. The processor has to access
+ * 32bit variables in two or four chunks (depending on the processor). The low
+ * priority of these tasks means there is a high probability that a context
+ * switch will occur mid calculation. See flop. c documentation for
+ * more information.
+ *
+ */
+
+/*
+Changes from V1.2.1
+
+ + The constants used in the calculations are larger to ensure the
+ optimiser does not truncate them to 16 bits.
+
+Changes from V1.2.3
+
+ + uxTaskCheck is now just used as a boolean. Instead of incrementing
+ the variable each cycle of the task, the variable is simply set to
+ true. sAreIntegerMathsTaskStillRunning() sets it back to false and
+ expects it to have been set back to true by the time it is called
+ again.
+ + A division has been included in the calculation.
+*/
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Demo program include files. */
+#include "integer.h"
+
+/* The constants used in the calculation. */
+#define intgCONST1 ( ( long ) 123 )
+#define intgCONST2 ( ( long ) 234567 )
+#define intgCONST3 ( ( long ) -3 )
+#define intgCONST4 ( ( long ) 7 )
+#define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 )
+
+#define intgSTACK_SIZE configMINIMAL_STACK_SIZE
+
+/* As this is the minimal version, we will only create one task. */
+#define intgNUMBER_OF_TASKS ( 1 )
+
+/* The task function. Repeatedly performs a 32 bit calculation, checking the
+result against the expected result. If the result is incorrect then the
+context switch must have caused some corruption. */
+static portTASK_FUNCTION_PROTO(vCompeteingIntMathTask, pvParameters);
+
+/* Variables that are set to true within the calculation task to indicate
+that the task is still executing. The check task sets the variable back to
+false, flagging an error if the variable is still false the next time it
+is called. */
+static volatile signed portBASE_TYPE xTaskCheck[ intgNUMBER_OF_TASKS ] = {(signed portBASE_TYPE) pdFALSE };
+
+/*-----------------------------------------------------------*/
+
+void vStartIntegerMathTasks(unsigned portBASE_TYPE uxPriority)
+{
+ short sTask;
+
+ for (sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++) {
+ xTaskCreate(vCompeteingIntMathTask, (signed char *) "IntMath", intgSTACK_SIZE, (void *) &(xTaskCheck[ sTask ]), uxPriority, (xTaskHandle *) NULL);
+ }
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION(vCompeteingIntMathTask, pvParameters)
+{
+ /* These variables are all effectively set to constants so they are volatile to
+ ensure the compiler does not just get rid of them. */
+ volatile long lValue;
+ short sError = pdFALSE;
+ volatile signed portBASE_TYPE *pxTaskHasExecuted;
+
+ /* Set a pointer to the variable we are going to set to true each
+ iteration. This is also a good test of the parameter passing mechanism
+ within each port. */
+ pxTaskHasExecuted = (volatile signed portBASE_TYPE *) pvParameters;
+
+ /* Keep performing a calculation and checking the result against a constant. */
+ for (;;) {
+ /* Perform the calculation. This will store partial value in
+ registers, resulting in a good test of the context switch mechanism. */
+ lValue = intgCONST1;
+ lValue += intgCONST2;
+
+ /* Yield in case cooperative scheduling is being used. */
+#if configUSE_PREEMPTION == 0
+ {
+ taskYIELD();
+ }
+#endif
+
+ /* Finish off the calculation. */
+ lValue *= intgCONST3;
+ lValue /= intgCONST4;
+
+ /* If the calculation is found to be incorrect we stop setting the
+ TaskHasExecuted variable so the check task can see an error has
+ occurred. */
+ if (lValue != intgEXPECTED_ANSWER) { /*lint !e774 volatile used to prevent this being optimised out. */
+ sError = pdTRUE;
+ }
+
+ if (sError == pdFALSE) {
+ /* We have not encountered any errors, so set the flag that show
+ we are still executing. This will be periodically cleared by
+ the check task. */
+ portENTER_CRITICAL();
+ *pxTaskHasExecuted = pdTRUE;
+ portEXIT_CRITICAL();
+ }
+
+ /* Yield in case cooperative scheduling is being used. */
+#if configUSE_PREEMPTION == 0
+ {
+ taskYIELD();
+ }
+#endif
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreIntegerMathsTaskStillRunning(void)
+{
+ portBASE_TYPE xReturn = pdTRUE;
+ short sTask;
+
+ /* Check the maths tasks are still running by ensuring their check variables
+ are still being set to true. */
+ for (sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++) {
+ if (xTaskCheck[ sTask ] == pdFALSE) {
+ /* The check has not incremented so an error exists. */
+ xReturn = pdFALSE;
+ }
+
+ /* Reset the check variable so we can tell if it has been set by
+ the next time around. */
+ xTaskCheck[ sTask ] = pdFALSE;
+ }
+
+ return xReturn;
+}
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/recmutex.c b/gyro_board/src/usb/CommonDemoTasks/recmutex.c
new file mode 100644
index 0000000..9d163d8
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/recmutex.c
@@ -0,0 +1,334 @@
+/*
+ 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.
+*/
+
+/*
+ The tasks defined on this page demonstrate the use of recursive mutexes.
+
+ For recursive mutex functionality the created mutex should be created using
+ xSemaphoreCreateRecursiveMutex(), then be manipulated
+ using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API
+ functions.
+
+ This demo creates three tasks all of which access the same recursive mutex:
+
+ prvRecursiveMutexControllingTask() has the highest priority so executes
+ first and grabs the mutex. It then performs some recursive accesses -
+ between each of which it sleeps for a short period to let the lower
+ priority tasks execute. When it has completed its demo functionality
+ it gives the mutex back before suspending itself.
+
+ prvRecursiveMutexBlockingTask() attempts to access the mutex by performing
+ a blocking 'take'. The blocking task has a lower priority than the
+ controlling task so by the time it executes the mutex has already been
+ taken by the controlling task, causing the blocking task to block. It
+ does not unblock until the controlling task has given the mutex back,
+ and it does not actually run until the controlling task has suspended
+ itself (due to the relative priorities). When it eventually does obtain
+ the mutex all it does is give the mutex back prior to also suspending
+ itself. At this point both the controlling task and the blocking task are
+ suspended.
+
+ prvRecursiveMutexPollingTask() runs at the idle priority. It spins round
+ a tight loop attempting to obtain the mutex with a non-blocking call. As
+ the lowest priority task it will not successfully obtain the mutex until
+ both the controlling and blocking tasks are suspended. Once it eventually
+ does obtain the mutex it first unsuspends both the controlling task and
+ blocking task prior to giving the mutex back - resulting in the polling
+ task temporarily inheriting the controlling tasks priority.
+*/
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* Demo app include files. */
+#include "recmutex.h"
+
+/* Priorities assigned to the three tasks. */
+#define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
+#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 )
+
+/* The recursive call depth. */
+#define recmuMAX_COUNT ( 10 )
+
+/* Misc. */
+#define recmuSHORT_DELAY ( 20 / portTICK_RATE_MS )
+#define recmuNO_DELAY ( ( portTickType ) 0 )
+#define recmuTWO_TICK_DELAY ( ( portTickType ) 2 )
+
+/* The three tasks as described at the top of this file. */
+static void prvRecursiveMutexControllingTask(void *pvParameters);
+static void prvRecursiveMutexBlockingTask(void *pvParameters);
+static void prvRecursiveMutexPollingTask(void *pvParameters);
+
+/* The mutex used by the demo. */
+static xSemaphoreHandle xMutex;
+
+/* Variables used to detect and latch errors. */
+static volatile portBASE_TYPE xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE;
+static volatile unsigned portBASE_TYPE uxControllingCycles = 0, uxBlockingCycles, uxPollingCycles = 0;
+
+/* Handles of the two higher priority tasks, required so they can be resumed
+(unsuspended). */
+static xTaskHandle xControllingTaskHandle, xBlockingTaskHandle;
+
+/*-----------------------------------------------------------*/
+
+void vStartRecursiveMutexTasks(void)
+{
+ /* Just creates the mutex and the three tasks. */
+
+ xMutex = xSemaphoreCreateRecursiveMutex();
+
+ /* 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 mutex 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 *) "Recursive_Mutex");
+
+
+ if (xMutex != NULL) {
+ xTaskCreate(prvRecursiveMutexControllingTask, (signed portCHAR *) "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle);
+ xTaskCreate(prvRecursiveMutexBlockingTask, (signed portCHAR *) "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle);
+ xTaskCreate(prvRecursiveMutexPollingTask, (signed portCHAR *) "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL);
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRecursiveMutexControllingTask(void *pvParameters)
+{
+ unsigned portBASE_TYPE ux;
+
+ /* Just to remove compiler warning. */
+ (void) pvParameters;
+
+ for (;;) {
+ /* Should not be able to 'give' the mutex, as we have not yet 'taken'
+ it. */
+ if (xSemaphoreGiveRecursive(xMutex) == pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ for (ux = 0; ux < recmuMAX_COUNT; ux++) {
+ /* We should now be able to take the mutex as many times as
+ we like. A one tick delay is used so the polling task will
+ inherit our priority on all but the first cycle of this task.
+ If we did not block attempting to receive the mutex then no
+ priority inheritance would occur. */
+ if (xSemaphoreTakeRecursive(xMutex, recmuTWO_TICK_DELAY) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Ensure the other task attempting to access the mutex (and the
+ other demo tasks) are able to execute. */
+ vTaskDelay(recmuSHORT_DELAY);
+ }
+
+ /* For each time we took the mutex, give it back. */
+ for (ux = 0; ux < recmuMAX_COUNT; ux++) {
+ /* Ensure the other task attempting to access the mutex (and the
+ other demo tasks) are able to execute. */
+ vTaskDelay(recmuSHORT_DELAY);
+
+ /* We should now be able to give the mutex as many times as we
+ took it. */
+ if (xSemaphoreGiveRecursive(xMutex) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+ }
+
+ /* Having given it back the same number of times as it was taken, we
+ should no longer be the mutex owner, so the next give sh ould fail. */
+ if (xSemaphoreGiveRecursive(xMutex) == pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Keep count of the number of cycles this task has performed so a
+ stall can be detected. */
+ uxControllingCycles++;
+
+ /* Suspend ourselves to the blocking task can execute. */
+ xControllingIsSuspended = pdTRUE;
+ vTaskSuspend(NULL);
+ xControllingIsSuspended = pdFALSE;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRecursiveMutexBlockingTask(void *pvParameters)
+{
+ /* Just to remove compiler warning. */
+ (void) pvParameters;
+
+ for (;;) {
+ /* Attempt to obtain the mutex. We should block until the
+ controlling task has given up the mutex, and not actually execute
+ past this call until the controlling task is suspended. */
+ if (xSemaphoreTakeRecursive(xMutex, portMAX_DELAY) == pdPASS) {
+ if (xControllingIsSuspended != pdTRUE) {
+ /* Did not expect to execute until the controlling task was
+ suspended. */
+ xErrorOccurred = pdTRUE;
+ } else {
+ /* Give the mutex back before suspending ourselves to allow
+ the polling task to obtain the mutex. */
+ if (xSemaphoreGiveRecursive(xMutex) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ xBlockingIsSuspended = pdTRUE;
+ vTaskSuspend(NULL);
+ xBlockingIsSuspended = pdFALSE;
+ }
+ } else {
+ /* We should not leave the xSemaphoreTakeRecursive() function
+ until the mutex was obtained. */
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* The controlling and blocking tasks should be in lock step. */
+ if (uxControllingCycles != (uxBlockingCycles + 1)) {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Keep count of the number of cycles this task has performed so a
+ stall can be detected. */
+ uxBlockingCycles++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRecursiveMutexPollingTask(void *pvParameters)
+{
+ /* Just to remove compiler warning. */
+ (void) pvParameters;
+
+ for (;;) {
+ /* Keep attempting to obtain the mutex. We should only obtain it when
+ the blocking task has suspended itself. */
+ if (xSemaphoreTakeRecursive(xMutex, recmuNO_DELAY) == pdPASS) {
+ /* Is the blocking task suspended? */
+ if (xBlockingIsSuspended != pdTRUE) {
+ xErrorOccurred = pdTRUE;
+ } else {
+ /* Keep count of the number of cycles this task has performed so
+ a stall can be detected. */
+ uxPollingCycles++;
+
+ /* We can resume the other tasks here even though they have a
+ higher priority than the polling task. When they execute they
+ will attempt to obtain the mutex but fail because the polling
+ task is still the mutex holder. The polling task (this task)
+ will then inherit the higher priority. */
+ vTaskResume(xBlockingTaskHandle);
+ vTaskResume(xControllingTaskHandle);
+
+ /* Release the mutex, disinheriting the higher priority again. */
+ if (xSemaphoreGiveRecursive(xMutex) != pdPASS) {
+ xErrorOccurred = pdTRUE;
+ }
+ }
+ }
+
+#if configUSE_PREEMPTION == 0
+ {
+ taskYIELD();
+ }
+#endif
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreRecursiveMutexTasksStillRunning(void)
+{
+ portBASE_TYPE xReturn;
+ static unsigned portBASE_TYPE uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0;
+
+ /* Is the controlling task still cycling? */
+ if (uxLastControllingCycles == uxControllingCycles) {
+ xErrorOccurred = pdTRUE;
+ } else {
+ uxLastControllingCycles = uxControllingCycles;
+ }
+
+ /* Is the blocking task still cycling? */
+ if (uxLastBlockingCycles == uxBlockingCycles) {
+ xErrorOccurred = pdTRUE;
+ } else {
+ uxLastBlockingCycles = uxBlockingCycles;
+ }
+
+ /* Is the polling task still cycling? */
+ if (uxLastPollingCycles == uxPollingCycles) {
+ xErrorOccurred = pdTRUE;
+ } else {
+ uxLastPollingCycles = uxPollingCycles;
+ }
+
+ if (xErrorOccurred == pdTRUE) {
+ xReturn = pdFAIL;
+ } else {
+ xReturn = pdTRUE;
+ }
+
+ return xReturn;
+}
+
+
+
+
diff --git a/gyro_board/src/usb/CommonDemoTasks/semtest.c b/gyro_board/src/usb/CommonDemoTasks/semtest.c
new file mode 100644
index 0000000..055ed11
--- /dev/null
+++ b/gyro_board/src/usb/CommonDemoTasks/semtest.c
@@ -0,0 +1,263 @@
+/*
+ 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.
+*/
+
+/*
+ * Creates two sets of two tasks. The tasks within a set share a variable, access
+ * to which is guarded by a semaphore.
+ *
+ * Each task starts by attempting to obtain the semaphore. On obtaining a
+ * semaphore a task checks to ensure that the guarded variable has an expected
+ * value. It then clears the variable to zero before counting it back up to the
+ * expected value in increments of 1. After each increment the variable is checked
+ * to ensure it contains the value to which it was just set. When the starting
+ * value is again reached the task releases the semaphore giving the other task in
+ * the set a chance to do exactly the same thing. The starting value is high
+ * enough to ensure that a tick is likely to occur during the incrementing loop.
+ *
+ * An error is flagged if at any time during the process a shared variable is
+ * found to have a value other than that expected. Such an occurrence would
+ * suggest an error in the mutual exclusion mechanism by which access to the
+ * variable is restricted.
+ *
+ * The first set of two tasks poll their semaphore. The second set use blocking
+ * calls.
+ *
+ */
+
+
+#include <stdlib.h>
+
+/* Scheduler include files. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* Demo app include files. */
+#include "semtest.h"
+
+/* The value to which the shared variables are counted. */
+#define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xfff )
+#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xff )
+
+#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE
+
+#define semtstNUM_TASKS ( 4 )
+
+#define semtstDELAY_FACTOR ( ( portTickType ) 10 )
+
+/* The task function as described at the top of the file. */
+static portTASK_FUNCTION_PROTO(prvSemaphoreTest, pvParameters);
+
+/* Structure used to pass parameters to each task. */
+typedef struct SEMAPHORE_PARAMETERS {
+ xSemaphoreHandle xSemaphore;
+ volatile unsigned long *pulSharedVariable;
+ portTickType xBlockTime;
+} xSemaphoreParameters;
+
+/* Variables used to check that all the tasks are still running without errors. */
+static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 };
+static volatile short sNextCheckVariable = 0;
+
+/*-----------------------------------------------------------*/
+
+void vStartSemaphoreTasks(unsigned portBASE_TYPE uxPriority)
+{
+ xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters;
+ const portTickType xBlockTime = (portTickType) 100;
+
+ /* Create the structure used to pass parameters to the first two tasks. */
+ pxFirstSemaphoreParameters = (xSemaphoreParameters *) pvPortMalloc(sizeof(xSemaphoreParameters));
+
+ if (pxFirstSemaphoreParameters != NULL) {
+ /* Create the semaphore used by the first two tasks. */
+ vSemaphoreCreateBinary(pxFirstSemaphoreParameters->xSemaphore);
+
+ if (pxFirstSemaphoreParameters->xSemaphore != NULL) {
+ /* Create the variable which is to be shared by the first two tasks. */
+ pxFirstSemaphoreParameters->pulSharedVariable = (unsigned long *) pvPortMalloc(sizeof(unsigned long));
+
+ /* Initialise the share variable to the value the tasks expect. */
+ *(pxFirstSemaphoreParameters->pulSharedVariable) = semtstNON_BLOCKING_EXPECTED_VALUE;
+
+ /* The first two tasks do not block on semaphore calls. */
+ pxFirstSemaphoreParameters->xBlockTime = (portTickType) 0;
+
+ /* Spawn the first two tasks. As they poll they operate at the idle priority. */
+ xTaskCreate(prvSemaphoreTest, (signed char *) "PolSEM1", semtstSTACK_SIZE, (void *) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, (xTaskHandle *) NULL);
+ xTaskCreate(prvSemaphoreTest, (signed char *) "PolSEM2", semtstSTACK_SIZE, (void *) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, (xTaskHandle *) NULL);
+ }
+ }
+
+ /* Do exactly the same to create the second set of tasks, only this time
+ provide a block time for the semaphore calls. */
+ pxSecondSemaphoreParameters = (xSemaphoreParameters *) pvPortMalloc(sizeof(xSemaphoreParameters));
+ if (pxSecondSemaphoreParameters != NULL) {
+ vSemaphoreCreateBinary(pxSecondSemaphoreParameters->xSemaphore);
+
+ if (pxSecondSemaphoreParameters->xSemaphore != NULL) {
+ pxSecondSemaphoreParameters->pulSharedVariable = (unsigned long *) pvPortMalloc(sizeof(unsigned long));
+ *(pxSecondSemaphoreParameters->pulSharedVariable) = semtstBLOCKING_EXPECTED_VALUE;
+ pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_RATE_MS;
+
+ xTaskCreate(prvSemaphoreTest, (signed char *) "BlkSEM1", semtstSTACK_SIZE, (void *) pxSecondSemaphoreParameters, uxPriority, (xTaskHandle *) NULL);
+ xTaskCreate(prvSemaphoreTest, (signed char *) "BlkSEM2", semtstSTACK_SIZE, (void *) pxSecondSemaphoreParameters, uxPriority, (xTaskHandle *) NULL);
+ }
+ }
+
+ /* vQueueAddToRegistry() adds the semaphore to the registry, if one is
+ in use. The registry is provided as a means for kernel aware
+ debuggers to locate semaphores 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) pxFirstSemaphoreParameters->xSemaphore, (signed char *) "Counting_Sem_1");
+ vQueueAddToRegistry((xQueueHandle) pxSecondSemaphoreParameters->xSemaphore, (signed char *) "Counting_Sem_2");
+}
+/*-----------------------------------------------------------*/
+
+static portTASK_FUNCTION(prvSemaphoreTest, pvParameters)
+{
+ xSemaphoreParameters *pxParameters;
+ volatile unsigned long *pulSharedVariable, ulExpectedValue;
+ unsigned long ulCounter;
+ short sError = pdFALSE, sCheckVariableToUse;
+
+ /* See which check variable to use. sNextCheckVariable is not semaphore
+ protected! */
+ portENTER_CRITICAL();
+ sCheckVariableToUse = sNextCheckVariable;
+ sNextCheckVariable++;
+ portEXIT_CRITICAL();
+
+ /* A structure is passed in as the parameter. This contains the shared
+ variable being guarded. */
+ pxParameters = (xSemaphoreParameters *) pvParameters;
+ pulSharedVariable = pxParameters->pulSharedVariable;
+
+ /* If we are blocking we use a much higher count to ensure loads of context
+ switches occur during the count. */
+ if (pxParameters->xBlockTime > (portTickType) 0) {
+ ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;
+ } else {
+ ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;
+ }
+
+ for (;;) {
+ /* Try to obtain the semaphore. */
+ if (xSemaphoreTake(pxParameters->xSemaphore, pxParameters->xBlockTime) == pdPASS) {
+ /* We have the semaphore and so expect any other tasks using the
+ shared variable to have left it in the state we expect to find
+ it. */
+ if (*pulSharedVariable != ulExpectedValue) {
+ sError = pdTRUE;
+ }
+
+ /* Clear the variable, then count it back up to the expected value
+ before releasing the semaphore. Would expect a context switch or
+ two during this time. */
+ for (ulCounter = (unsigned long) 0; ulCounter <= ulExpectedValue; ulCounter++) {
+ *pulSharedVariable = ulCounter;
+ if (*pulSharedVariable != ulCounter) {
+ sError = pdTRUE;
+ }
+ }
+
+ /* Release the semaphore, and if no errors have occurred increment the check
+ variable. */
+ if (xSemaphoreGive(pxParameters->xSemaphore) == pdFALSE) {
+ sError = pdTRUE;
+ }
+
+ if (sError == pdFALSE) {
+ if (sCheckVariableToUse < semtstNUM_TASKS) {
+ (sCheckVariables[ sCheckVariableToUse ])++;
+ }
+ }
+
+ /* If we have a block time then we are running at a priority higher
+ than the idle priority. This task takes a long time to complete
+ a cycle (deliberately so to test the guarding) so will be starving
+ out lower priority tasks. Block for some time to allow give lower
+ priority tasks some processor time. */
+ vTaskDelay(pxParameters->xBlockTime * semtstDELAY_FACTOR);
+ } else {
+ if (pxParameters->xBlockTime == (portTickType) 0) {
+ /* We have not got the semaphore yet, so no point using the
+ processor. We are not blocking when attempting to obtain the
+ semaphore. */
+ taskYIELD();
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* This is called to check that all the created tasks are still running. */
+portBASE_TYPE xAreSemaphoreTasksStillRunning(void)
+{
+ static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 };
+ portBASE_TYPE xTask, xReturn = pdTRUE;
+
+ for (xTask = 0; xTask < semtstNUM_TASKS; xTask++) {
+ if (sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ]) {
+ xReturn = pdFALSE;
+ }
+
+ sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ];
+ }
+
+ return xReturn;
+}
+
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/FreeRTOS.h b/gyro_board/src/usb/FreeRTOS/include/FreeRTOS.h
new file mode 100644
index 0000000..afbd505
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/FreeRTOS.h
@@ -0,0 +1,420 @@
+/*
+ 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.
+*/
+
+#ifndef INC_FREERTOS_H
+#define INC_FREERTOS_H
+
+
+/*
+ * Include the generic headers required for the FreeRTOS port being used.
+ */
+#include <stddef.h>
+
+/* Basic FreeRTOS definitions. */
+#include "projdefs.h"
+
+/* Application specific configuration options. */
+#include "FreeRTOSConfig.h"
+
+/* Definitions specific to the port being used. */
+#include "portable.h"
+
+
+/* Defines the prototype to which the application task hook function must
+conform. */
+typedef portBASE_TYPE(*pdTASK_HOOK_CODE)(void *);
+
+
+
+
+
+/*
+ * Check all the required application specific macros have been defined.
+ * These macros are application specific and (as downloaded) are defined
+ * within FreeRTOSConfig.h.
+ */
+
+#ifndef configUSE_PREEMPTION
+#error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_IDLE_HOOK
+#error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_TICK_HOOK
+#error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_CO_ROUTINES
+#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskPrioritySet
+#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_uxTaskPriorityGet
+#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelete
+#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskCleanUpResources
+#error Missing definition: INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskSuspend
+#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelayUntil
+#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelay
+#error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_16_BIT_TICKS
+#error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_APPLICATION_TASK_TAG
+#define configUSE_APPLICATION_TASK_TAG 0
+#endif
+
+#ifndef INCLUDE_uxTaskGetStackHighWaterMark
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#endif
+
+#ifndef configUSE_RECURSIVE_MUTEXES
+#define configUSE_RECURSIVE_MUTEXES 0
+#endif
+
+#ifndef configUSE_MUTEXES
+#define configUSE_MUTEXES 0
+#endif
+
+#ifndef configUSE_COUNTING_SEMAPHORES
+#define configUSE_COUNTING_SEMAPHORES 0
+#endif
+
+#ifndef configUSE_ALTERNATIVE_API
+#define configUSE_ALTERNATIVE_API 0
+#endif
+
+#ifndef portCRITICAL_NESTING_IN_TCB
+#define portCRITICAL_NESTING_IN_TCB 0
+#endif
+
+#ifndef configMAX_TASK_NAME_LEN
+#define configMAX_TASK_NAME_LEN 16
+#endif
+
+#ifndef configIDLE_SHOULD_YIELD
+#define configIDLE_SHOULD_YIELD 1
+#endif
+
+#if configMAX_TASK_NAME_LEN < 1
+#undef configMAX_TASK_NAME_LEN
+#define configMAX_TASK_NAME_LEN 1
+#endif
+
+#ifndef INCLUDE_xTaskResumeFromISR
+#define INCLUDE_xTaskResumeFromISR 1
+#endif
+
+#ifndef INCLUDE_xTaskGetSchedulerState
+#define INCLUDE_xTaskGetSchedulerState 0
+#endif
+
+#if ( configUSE_MUTEXES == 1 )
+/* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism
+within the mutex implementation so must be available if mutexes are used. */
+#undef INCLUDE_xTaskGetCurrentTaskHandle
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#else
+#ifndef INCLUDE_xTaskGetCurrentTaskHandle
+#define INCLUDE_xTaskGetCurrentTaskHandle 0
+#endif
+#endif
+
+
+#ifndef portSET_INTERRUPT_MASK_FROM_ISR
+#define portSET_INTERRUPT_MASK_FROM_ISR() 0
+#endif
+
+#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
+#endif
+
+
+#ifndef configQUEUE_REGISTRY_SIZE
+#define configQUEUE_REGISTRY_SIZE 0
+#endif
+
+#if configQUEUE_REGISTRY_SIZE < 1
+#define configQUEUE_REGISTRY_SIZE 0
+#define vQueueAddToRegistry( xQueue, pcName )
+#define vQueueUnregisterQueue( xQueue )
+#endif
+
+
+/* Remove any unused trace macros. */
+#ifndef traceSTART
+/* Used to perform any necessary initialisation - for example, open a file
+into which trace is to be written. */
+#define traceSTART()
+#endif
+
+#ifndef traceEND
+/* Use to close a trace, for example close a file into which trace has been
+written. */
+#define traceEND()
+#endif
+
+#ifndef traceTASK_SWITCHED_IN
+/* Called after a task has been selected to run. pxCurrentTCB holds a pointer
+to the task control block of the selected task. */
+#define traceTASK_SWITCHED_IN()
+#endif
+
+#ifndef traceTASK_SWITCHED_OUT
+/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
+to the task control block of the task being switched out. */
+#define traceTASK_SWITCHED_OUT()
+#endif
+
+#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
+/* Task is about to block because it cannot read from a
+queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
+upon which the read was attempted. pxCurrentTCB points to the TCB of the
+task that attempted the read. */
+#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
+#endif
+
+#ifndef traceBLOCKING_ON_QUEUE_SEND
+/* Task is about to block because it cannot write to a
+queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
+upon which the write was attempted. pxCurrentTCB points to the TCB of the
+task that attempted the write. */
+#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
+#endif
+
+#ifndef configCHECK_FOR_STACK_OVERFLOW
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#endif
+
+/* The following event macros are embedded in the kernel API calls. */
+
+#ifndef traceQUEUE_CREATE
+#define traceQUEUE_CREATE( pxNewQueue )
+#endif
+
+#ifndef traceQUEUE_CREATE_FAILED
+#define traceQUEUE_CREATE_FAILED()
+#endif
+
+#ifndef traceCREATE_MUTEX
+#define traceCREATE_MUTEX( pxNewQueue )
+#endif
+
+#ifndef traceCREATE_MUTEX_FAILED
+#define traceCREATE_MUTEX_FAILED()
+#endif
+
+#ifndef traceGIVE_MUTEX_RECURSIVE
+#define traceGIVE_MUTEX_RECURSIVE( pxMutex )
+#endif
+
+#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
+#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
+#endif
+
+#ifndef traceTAKE_MUTEX_RECURSIVE
+#define traceTAKE_MUTEX_RECURSIVE( pxMutex )
+#endif
+
+#ifndef traceCREATE_COUNTING_SEMAPHORE
+#define traceCREATE_COUNTING_SEMAPHORE()
+#endif
+
+#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
+#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
+#endif
+
+#ifndef traceQUEUE_SEND
+#define traceQUEUE_SEND( pxQueue )
+#endif
+
+#ifndef traceQUEUE_SEND_FAILED
+#define traceQUEUE_SEND_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE
+#define traceQUEUE_RECEIVE( pxQueue )
+#endif
+
+#ifndef traceQUEUE_PEEK
+#define traceQUEUE_PEEK( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE_FAILED
+#define traceQUEUE_RECEIVE_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_SEND_FROM_ISR
+#define traceQUEUE_SEND_FROM_ISR( pxQueue )
+#endif
+
+#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
+#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE_FROM_ISR
+#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
+#endif
+
+#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
+#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
+#endif
+
+#ifndef traceQUEUE_DELETE
+#define traceQUEUE_DELETE( pxQueue )
+#endif
+
+#ifndef traceTASK_CREATE
+#define traceTASK_CREATE( pxNewTCB )
+#endif
+
+#ifndef traceTASK_CREATE_FAILED
+#define traceTASK_CREATE_FAILED( pxNewTCB )
+#endif
+
+#ifndef traceTASK_DELETE
+#define traceTASK_DELETE( pxTaskToDelete )
+#endif
+
+#ifndef traceTASK_DELAY_UNTIL
+#define traceTASK_DELAY_UNTIL()
+#endif
+
+#ifndef traceTASK_DELAY
+#define traceTASK_DELAY()
+#endif
+
+#ifndef traceTASK_PRIORITY_SET
+#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
+#endif
+
+#ifndef traceTASK_SUSPEND
+#define traceTASK_SUSPEND( pxTaskToSuspend )
+#endif
+
+#ifndef traceTASK_RESUME
+#define traceTASK_RESUME( pxTaskToResume )
+#endif
+
+#ifndef traceTASK_RESUME_FROM_ISR
+#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
+#endif
+
+#ifndef traceTASK_INCREMENT_TICK
+#define traceTASK_INCREMENT_TICK( xTickCount )
+#endif
+
+#ifndef configGENERATE_RUN_TIME_STATS
+#define configGENERATE_RUN_TIME_STATS 0
+#endif
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
+#error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.
+#endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */
+
+#ifndef portGET_RUN_TIME_COUNTER_VALUE
+#error If configGENERATE_RUN_TIME_STATS is defined then portGET_RUN_TIME_COUNTER_VALUE must also be defined. portGET_RUN_TIME_COUNTER_VALUE should evaluate to the counter value of the timer/counter peripheral used as the run time counter time base.
+#endif /* portGET_RUN_TIME_COUNTER_VALUE */
+
+#endif /* configGENERATE_RUN_TIME_STATS */
+
+#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
+#endif
+
+#ifndef configUSE_MALLOC_FAILED_HOOK
+#define configUSE_MALLOC_FAILED_HOOK 0
+#endif
+
+#ifndef portPRIVILEGE_BIT
+#define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )
+#endif
+
+#ifndef portYIELD_WITHIN_API
+#define portYIELD_WITHIN_API portYIELD
+#endif
+
+#ifndef pvPortMallocAligned
+#define pvPortMallocAligned( x, puxStackBuffer ) ( ( puxStackBuffer == NULL ) ? ( pvPortMalloc( x ) ) : ( puxStackBuffer ) )
+#endif
+
+#ifndef vPortFreeAligned
+#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
+#endif
+
+#endif /* INC_FREERTOS_H */
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/StackMacros.h b/gyro_board/src/usb/FreeRTOS/include/StackMacros.h
new file mode 100644
index 0000000..67d4c09
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/StackMacros.h
@@ -0,0 +1,173 @@
+/*
+ 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.
+*/
+
+#ifndef STACK_MACROS_H
+#define STACK_MACROS_H
+
+/*
+ * Call the stack overflow hook function if the stack of the task being swapped
+ * out is currently overflowed, or looks like it might have overflowed in the
+ * past.
+ *
+ * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
+ * the current stack state only - comparing the current top of stack value to
+ * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
+ * will also cause the last few stack bytes to be checked to ensure the value
+ * to which the bytes were set when the task was created have not been
+ * overwritten. Note this second test does not guarantee that an overflowed
+ * stack will always be recognised.
+ */
+
+/*-----------------------------------------------------------*/
+
+#if( configCHECK_FOR_STACK_OVERFLOW == 0 )
+
+/* FreeRTOSConfig.h is not set to check for stack overflows. */
+#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()
+#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
+
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */
+/*-----------------------------------------------------------*/
+
+#if( configCHECK_FOR_STACK_OVERFLOW == 1 )
+
+/* FreeRTOSConfig.h is only set to use the first method of
+overflow checking. */
+#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )
+
+/* Only the current stack state is to be checked. */
+#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
+ { \
+ extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
+ \
+ /* Is the currently saved stack pointer within the stack limit? */ \
+ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
+ { \
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
+ } \
+ }
+
+#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )
+
+/* Only the current stack state is to be checked. */
+#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
+ { \
+ extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
+ \
+ /* Is the currently saved stack pointer within the stack limit? */ \
+ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
+ { \
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
+ } \
+ }
+
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
+
+#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
+ { \
+ extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
+ static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
+ \
+ \
+ /* Has the extremity of the task stack ever been written over? */ \
+ if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
+ { \
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
+ } \
+ }
+
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
+/*-----------------------------------------------------------*/
+
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
+
+#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
+ { \
+ extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ); \
+ char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
+ static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
+ \
+ \
+ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
+ \
+ /* Has the extremity of the task stack ever been written over? */ \
+ if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
+ { \
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
+ } \
+ }
+
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
+/*-----------------------------------------------------------*/
+
+#endif /* STACK_MACROS_H */
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/croutine.h b/gyro_board/src/usb/FreeRTOS/include/croutine.h
new file mode 100644
index 0000000..bcedb26
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/croutine.h
@@ -0,0 +1,749 @@
+/*
+ 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.
+*/
+
+#ifndef INC_FREERTOS_H
+#error "#include FreeRTOS.h" must appear in source files before "#include croutine.h"
+#endif
+
+
+
+
+#ifndef CO_ROUTINE_H
+#define CO_ROUTINE_H
+
+#include "list.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /* Used to hide the implementation of the co-routine control block. The
+ control block structure however has to be included in the header due to
+ the macro implementation of the co-routine functionality. */
+ typedef void * xCoRoutineHandle;
+
+ /* Defines the prototype to which co-routine functions must conform. */
+ typedef void (*crCOROUTINE_CODE)(xCoRoutineHandle, unsigned portBASE_TYPE);
+
+ typedef struct corCoRoutineControlBlock {
+ crCOROUTINE_CODE pxCoRoutineFunction;
+ xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
+ xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */
+ unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
+ unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
+ unsigned short uxState; /*< Used internally by the co-routine implementation. */
+ } corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
+
+ /**
+ * croutine. h
+ *<pre>
+ portBASE_TYPE xCoRoutineCreate(
+ crCOROUTINE_CODE pxCoRoutineCode,
+ unsigned portBASE_TYPE uxPriority,
+ unsigned portBASE_TYPE uxIndex
+ );</pre>
+ *
+ * Create a new co-routine and add it to the list of co-routines that are
+ * ready to run.
+ *
+ * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
+ * functions require special syntax - see the co-routine section of the WEB
+ * documentation for more information.
+ *
+ * @param uxPriority The priority with respect to other co-routines at which
+ * the co-routine will run.
+ *
+ * @param uxIndex Used to distinguish between different co-routines that
+ * execute the same function. See the example below and the co-routine section
+ * of the WEB documentation for further information.
+ *
+ * @return pdPASS if the co-routine was successfully created and added to a ready
+ * list, otherwise an error code defined with ProjDefs.h.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // This co-routine just delays for a fixed period, then toggles
+ // an LED. Two co-routines are created using this function, so
+ // the uxIndex parameter is used to tell the co-routine which
+ // LED to flash and how long to delay. This assumes xQueue has
+ // already been created.
+ vParTestToggleLED( cLedToFlash[ uxIndex ] );
+ crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+ // Create two co-routines at priority 0. The first is given index 0
+ // so (from the code above) toggles LED 5 every 200 ticks. The second
+ // is given index 1 so toggles LED 6 every 400 ticks.
+ for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+ {
+ xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+ }
+ }
+ </pre>
+ * \defgroup xCoRoutineCreate xCoRoutineCreate
+ * \ingroup Tasks
+ */
+ signed portBASE_TYPE xCoRoutineCreate(crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex);
+
+
+ /**
+ * croutine. h
+ *<pre>
+ void vCoRoutineSchedule( void );</pre>
+ *
+ * Run a co-routine.
+ *
+ * vCoRoutineSchedule() executes the highest priority co-routine that is able
+ * to run. The co-routine will execute until it either blocks, yields or is
+ * preempted by a task. Co-routines execute cooperatively so one
+ * co-routine cannot be preempted by another, but can be preempted by a task.
+ *
+ * If an application comprises of both tasks and co-routines then
+ * vCoRoutineSchedule should be called from the idle task (in an idle task
+ * hook).
+ *
+ * Example usage:
+ <pre>
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+ vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+ for( ;; )
+ {
+ vCoRoutineSchedule();
+ }
+ }
+ </pre>
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule
+ * \ingroup Tasks
+ */
+ void vCoRoutineSchedule(void);
+
+ /**
+ * croutine. h
+ * <pre>
+ crSTART( xCoRoutineHandle xHandle );</pre>
+ *
+ * This macro MUST always be called at the start of a co-routine function.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Co-routine functionality goes here.
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }</pre>
+ * \defgroup crSTART crSTART
+ * \ingroup Tasks
+ */
+#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
+
+ /**
+ * croutine. h
+ * <pre>
+ crEND();</pre>
+ *
+ * This macro MUST always be called at the end of a co-routine function.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Co-routine functionality goes here.
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }</pre>
+ * \defgroup crSTART crSTART
+ * \ingroup Tasks
+ */
+#define crEND() }
+
+ /*
+ * These macros are intended for internal use by the co-routine implementation
+ * only. The macros should not be used directly by application writers.
+ */
+#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
+#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
+
+ /**
+ * croutine. h
+ *<pre>
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
+ *
+ * Delay a co-routine for a fixed period of time.
+ *
+ * crDELAY can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function. This is because
+ * co-routines do not maintain their own stack.
+ *
+ * @param xHandle The handle of the co-routine to delay. This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should delay
+ * for. The actual amount of time this equates to is defined by
+ * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
+ * can be used to convert ticks to milliseconds.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Delay for 200ms.
+ crDELAY( xHandle, xDelayTime );
+
+ // Do something here.
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }</pre>
+ * \defgroup crDELAY crDELAY
+ * \ingroup Tasks
+ */
+#define crDELAY( xHandle, xTicksToDelay ) \
+ if( xTicksToDelay > 0 ) \
+ { \
+ vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \
+ } \
+ crSET_STATE0( xHandle );
+
+ /**
+ * <pre>
+ crQUEUE_SEND(
+ xCoRoutineHandle xHandle,
+ xQueueHandle pxQueue,
+ void *pvItemToQueue,
+ portTickType xTicksToWait,
+ portBASE_TYPE *pxResult
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
+ *
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
+ * xQueueSend() and xQueueReceive() can only be used from tasks.
+ *
+ * crQUEUE_SEND can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function. This is because
+ * co-routines do not maintain their own stack.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xHandle The handle of the calling co-routine. This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param pxQueue The handle of the queue on which the data will be posted.
+ * The handle is obtained as the return value when the queue is created using
+ * the xQueueCreate() API function.
+ *
+ * @param pvItemToQueue A pointer to the data being posted onto the queue.
+ * The number of bytes of each queued item is specified when the queue is
+ * created. This number of bytes is copied from pvItemToQueue into the queue
+ * itself.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should block
+ * to wait for space to become available on the queue, should space not be
+ * available immediately. The actual amount of time this equates to is defined
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
+ * below).
+ *
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
+ * data was successfully posted onto the queue, otherwise it will be set to an
+ * error defined within ProjDefs.h.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xNumberToPost = 0;
+ static portBASE_TYPE xResult;
+
+ // Co-routines must begin with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // This assumes the queue has already been created.
+ crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+ if( xResult != pdPASS )
+ {
+ // The message was not posted!
+ }
+
+ // Increment the number to be posted onto the queue.
+ xNumberToPost++;
+
+ // Delay for 100 ticks.
+ crDELAY( xHandle, 100 );
+ }
+
+ // Co-routines must end with a call to crEND().
+ crEND();
+ }</pre>
+ * \defgroup crQUEUE_SEND crQUEUE_SEND
+ * \ingroup Tasks
+ */
+#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
+{ \
+ *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \
+ if( *pxResult == errQUEUE_BLOCKED ) \
+ { \
+ crSET_STATE0( xHandle ); \
+ *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \
+ } \
+ if( *pxResult == errQUEUE_YIELD ) \
+ { \
+ crSET_STATE1( xHandle ); \
+ *pxResult = pdPASS; \
+ } \
+}
+
+ /**
+ * croutine. h
+ * <pre>
+ crQUEUE_RECEIVE(
+ xCoRoutineHandle xHandle,
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait,
+ portBASE_TYPE *pxResult
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
+ *
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
+ * xQueueSend() and xQueueReceive() can only be used from tasks.
+ *
+ * crQUEUE_RECEIVE can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function. This is because
+ * co-routines do not maintain their own stack.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xHandle The handle of the calling co-routine. This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param pxQueue The handle of the queue from which the data will be received.
+ * The handle is obtained as the return value when the queue is created using
+ * the xQueueCreate() API function.
+ *
+ * @param pvBuffer The buffer into which the received item is to be copied.
+ * The number of bytes of each queued item is specified when the queue is
+ * created. This number of bytes is copied into pvBuffer.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should block
+ * to wait for data to become available from the queue, should data not be
+ * available immediately. The actual amount of time this equates to is defined
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
+ * crQUEUE_SEND example).
+ *
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
+ * data was successfully retrieved from the queue, otherwise it will be set to
+ * an error code as defined within ProjDefs.h.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine receives the number of an LED to flash from a queue. It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xResult;
+ static unsigned portBASE_TYPE uxLEDToFlash;
+
+ // All co-routines must start with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Wait for data to become available on the queue.
+ crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+ if( xResult == pdPASS )
+ {
+ // We received the LED to flash - flash it!
+ vParTestToggleLED( uxLEDToFlash );
+ }
+ }
+
+ crEND();
+ }</pre>
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
+ * \ingroup Tasks
+ */
+#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
+{ \
+ *pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \
+ if( *pxResult == errQUEUE_BLOCKED ) \
+ { \
+ crSET_STATE0( xHandle ); \
+ *pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \
+ } \
+ if( *pxResult == errQUEUE_YIELD ) \
+ { \
+ crSET_STATE1( xHandle ); \
+ *pxResult = pdPASS; \
+ } \
+}
+
+ /**
+ * croutine. h
+ * <pre>
+ crQUEUE_SEND_FROM_ISR(
+ xQueueHandle pxQueue,
+ void *pvItemToQueue,
+ portBASE_TYPE xCoRoutinePreviouslyWoken
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
+ * functions used by tasks.
+ *
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and
+ * ISR.
+ *
+ * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
+ * that is being used from within a co-routine.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
+ * the same queue multiple times from a single interrupt. The first call
+ * should always pass in pdFALSE. Subsequent calls should pass in
+ * the value returned from the previous call.
+ *
+ * @return pdTRUE if a co-routine was woken by posting onto the queue. This is
+ * used by the ISR to determine if a context switch may be required following
+ * the ISR.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ char cRxedChar;
+ portBASE_TYPE xResult;
+
+ // All co-routines must start with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Wait for data to become available on the queue. This assumes the
+ // queue xCommsRxQueue has already been created!
+ crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+ // Was a character received?
+ if( xResult == pdPASS )
+ {
+ // Process the character here.
+ }
+ }
+
+ // All co-routines must end with a call to crEND().
+ crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+ // We loop around reading characters until there are none left in the UART.
+ while( UART_RX_REG_NOT_EMPTY() )
+ {
+ // Obtain the character from the UART.
+ cRxedChar = UART_RX_REG;
+
+ // Post the character onto a queue. xCRWokenByPost will be pdFALSE
+ // the first time around the loop. If the post causes a co-routine
+ // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+ // In this manner we can ensure that if more than one co-routine is
+ // blocked on the queue only one is woken by this ISR no matter how
+ // many characters are posted to the queue.
+ xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+ }
+ }</pre>
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
+ * \ingroup Tasks
+ */
+#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
+
+
+ /**
+ * croutine. h
+ * <pre>
+ crQUEUE_SEND_FROM_ISR(
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portBASE_TYPE * pxCoRoutineWoken
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
+ * functions used by tasks.
+ *
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and
+ * ISR.
+ *
+ * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
+ * from a queue that is being used from within a co-routine (a co-routine
+ * posted to the queue).
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvBuffer A pointer to a buffer into which the received item will be
+ * placed. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from the queue into
+ * pvBuffer.
+ *
+ * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
+ * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
+ * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
+ * *pxCoRoutineWoken will remain unchanged.
+ *
+ * @return pdTRUE an item was successfully received from the queue, otherwise
+ * pdFALSE.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period. The character is incremented each time.
+ static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ portBASE_TYPE xResult;
+
+ // All co-routines must start with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Send the next character to the queue.
+ crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+ if( xResult == pdPASS )
+ {
+ // The character was successfully posted to the queue.
+ }
+ else
+ {
+ // Could not post the character to the queue.
+ }
+
+ // Enable the UART Tx interrupt to cause an interrupt in this
+ // hypothetical UART. The interrupt will obtain the character
+ // from the queue and send it.
+ ENABLE_RX_INTERRUPT();
+
+ // Increment to the next character then block for a fixed period.
+ // cCharToTx will maintain its value across the delay as it is
+ // declared static.
+ cCharToTx++;
+ if( cCharToTx > 'x' )
+ {
+ cCharToTx = 'a';
+ }
+ crDELAY( 100 );
+ }
+
+ // All co-routines must end with a call to crEND().
+ crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+ while( UART_TX_REG_EMPTY() )
+ {
+ // Are there any characters in the queue waiting to be sent?
+ // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+ // is woken by the post - ensuring that only a single co-routine is
+ // woken no matter how many times we go around this loop.
+ if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+ {
+ SEND_CHARACTER( cCharToTx );
+ }
+ }
+ }</pre>
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
+ * \ingroup Tasks
+ */
+#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
+
+ /*
+ * This function is intended for internal use by the co-routine macros only.
+ * The macro nature of the co-routine implementation requires that the
+ * prototype appears here. The function should not be used by application
+ * writers.
+ *
+ * Removes the current co-routine from its ready list and places it in the
+ * appropriate delayed list.
+ */
+ void vCoRoutineAddToDelayedList(portTickType xTicksToDelay, xList *pxEventList);
+
+ /*
+ * This function is intended for internal use by the queue implementation only.
+ * The function should not be used by application writers.
+ *
+ * Removes the highest priority co-routine from the event list and places it in
+ * the pending ready list.
+ */
+ signed portBASE_TYPE xCoRoutineRemoveFromEventList(const xList *pxEventList);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CO_ROUTINE_H */
diff --git a/gyro_board/src/usb/FreeRTOS/include/list.h b/gyro_board/src/usb/FreeRTOS/include/list.h
new file mode 100644
index 0000000..5299ec9
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/list.h
@@ -0,0 +1,303 @@
+/*
+ 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.
+*/
+
+/*
+ * This is the list implementation used by the scheduler. While it is tailored
+ * heavily for the schedulers needs, it is also available for use by
+ * application code.
+ *
+ * xLists can only store pointers to xListItems. Each xListItem contains a
+ * numeric value (xItemValue). Most of the time the lists are sorted in
+ * descending item value order.
+ *
+ * Lists are created already containing one list item. The value of this
+ * item is the maximum possible that can be stored, it is therefore always at
+ * the end of the list and acts as a marker. The list member pxHead always
+ * points to this marker - even though it is at the tail of the list. This
+ * is because the tail contains a wrap back pointer to the true head of
+ * the list.
+ *
+ * In addition to it's value, each list item contains a pointer to the next
+ * item in the list (pxNext), a pointer to the list it is in (pxContainer)
+ * and a pointer to back to the object that contains it. These later two
+ * pointers are included for efficiency of list manipulation. There is
+ * effectively a two way link between the object containing the list item and
+ * the list item itself.
+ *
+ *
+ * \page ListIntroduction List Implementation
+ * \ingroup FreeRTOSIntro
+ */
+
+/*
+ Changes from V4.3.1
+
+ + Included local const within listGET_OWNER_OF_NEXT_ENTRY() to assist
+ compiler with optimisation. Thanks B.R.
+*/
+
+#ifndef LIST_H
+#define LIST_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ /*
+ * Definition of the only type of object that a list can contain.
+ */
+ struct xLIST_ITEM {
+ portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
+ volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
+ volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
+ void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
+ void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
+ };
+ typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
+
+ struct xMINI_LIST_ITEM {
+ portTickType xItemValue;
+ volatile struct xLIST_ITEM *pxNext;
+ volatile struct xLIST_ITEM *pxPrevious;
+ };
+ typedef struct xMINI_LIST_ITEM xMiniListItem;
+
+ /*
+ * Definition of the type of queue used by the scheduler.
+ */
+ typedef struct xLIST {
+ volatile unsigned portBASE_TYPE uxNumberOfItems;
+ volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
+ volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
+ } xList;
+
+ /*
+ * Access macro to set the owner of a list item. The owner of a list item
+ * is the object (usually a TCB) that contains the list item.
+ *
+ * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner
+
+ /*
+ * Access macro to set the value of the list item. In most cases the value is
+ * used to sort the list in descending order.
+ *
+ * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue
+
+ /*
+ * Access macro the retrieve the value of the list item. The value can
+ * represent anything - for example a the priority of a task, or the time at
+ * which a task should be unblocked.
+ *
+ * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
+
+ /*
+ * Access macro to determine if a list contains any items. The macro will
+ * only have the value true if the list is empty.
+ *
+ * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
+ * \ingroup LinkedList
+ */
+#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
+
+ /*
+ * Access macro to return the number of items in the list.
+ */
+#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
+
+ /*
+ * Access function to obtain the owner of the next entry in a list.
+ *
+ * The list member pxIndex is used to walk through a list. Calling
+ * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
+ * and returns that entries pxOwner parameter. Using multiple calls to this
+ * function it is therefore possible to move through every item contained in
+ * a list.
+ *
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item. In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxList The list from which the next item owner is to be returned.
+ *
+ * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
+{ \
+xList * const pxConstList = pxList; \
+ /* Increment the index to the next item and return the item, ensuring */ \
+ /* we don't return the marker used at the end of the list. */ \
+ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
+ if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \
+ { \
+ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
+ } \
+ pxTCB = ( pxConstList )->pxIndex->pvOwner; \
+}
+
+
+ /*
+ * Access function to obtain the owner of the first entry in a list. Lists
+ * are normally sorted in ascending item value order.
+ *
+ * This function returns the pxOwner member of the first item in the list.
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item. In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxList The list from which the owner of the head item is to be
+ * returned.
+ *
+ * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )
+
+ /*
+ * Check to see if a list item is within a list. The list item maintains a
+ * "container" pointer that points to the list it is in. All this macro does
+ * is check to see if the container and the list match.
+ *
+ * @param pxList The list we want to know if the list item is within.
+ * @param pxListItem The list item we want to know if is in the list.
+ * @return pdTRUE is the list item is in the list, otherwise pdFALSE.
+ * pointer against
+ */
+#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )
+
+ /*
+ * Must be called before a list is used! This initialises all the members
+ * of the list structure and inserts the xListEnd item into the list as a
+ * marker to the back of the list.
+ *
+ * @param pxList Pointer to the list being initialised.
+ *
+ * \page vListInitialise vListInitialise
+ * \ingroup LinkedList
+ */
+ void vListInitialise(xList *pxList);
+
+ /*
+ * Must be called before a list item is used. This sets the list container to
+ * null so the item does not think that it is already contained in a list.
+ *
+ * @param pxItem Pointer to the list item being initialised.
+ *
+ * \page vListInitialiseItem vListInitialiseItem
+ * \ingroup LinkedList
+ */
+ void vListInitialiseItem(xListItem *pxItem);
+
+ /*
+ * Insert a list item into a list. The item will be inserted into the list in
+ * a position determined by its item value (descending item value order).
+ *
+ * @param pxList The list into which the item is to be inserted.
+ *
+ * @param pxNewListItem The item to that is to be placed in the list.
+ *
+ * \page vListInsert vListInsert
+ * \ingroup LinkedList
+ */
+ void vListInsert(xList *pxList, xListItem *pxNewListItem);
+
+ /*
+ * Insert a list item into a list. The item will be inserted in a position
+ * such that it will be the last item within the list returned by multiple
+ * calls to listGET_OWNER_OF_NEXT_ENTRY.
+ *
+ * The list member pvIndex is used to walk through a list. Calling
+ * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
+ * Placing an item in a list using vListInsertEnd effectively places the item
+ * in the list position pointed to by pvIndex. This means that every other
+ * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
+ * the pvIndex parameter again points to the item being inserted.
+ *
+ * @param pxList The list into which the item is to be inserted.
+ *
+ * @param pxNewListItem The list item to be inserted into the list.
+ *
+ * \page vListInsertEnd vListInsertEnd
+ * \ingroup LinkedList
+ */
+ void vListInsertEnd(xList *pxList, xListItem *pxNewListItem);
+
+ /*
+ * Remove an item from a list. The list item has a pointer to the list that
+ * it is in, so only the list item need be passed into the function.
+ *
+ * @param vListRemove The item to be removed. The item will remove itself from
+ * the list pointed to by it's pxContainer parameter.
+ *
+ * \page vListRemove vListRemove
+ * \ingroup LinkedList
+ */
+ void vListRemove(xListItem *pxItemToRemove);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/mpu_wrappers.h b/gyro_board/src/usb/FreeRTOS/include/mpu_wrappers.h
new file mode 100644
index 0000000..ad8ce2d
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/mpu_wrappers.h
@@ -0,0 +1,135 @@
+/*
+ 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.
+*/
+
+#ifndef MPU_WRAPPERS_H
+#define MPU_WRAPPERS_H
+
+/* This file redefines API functions to be called through a wrapper macro, but
+only for ports that are using the MPU. */
+#ifdef portUSING_MPU_WRAPPERS
+
+/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
+included from queue.c or task.c to prevent it from having an effect within
+those files. */
+#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#define xTaskGenericCreate MPU_xTaskGenericCreate
+#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
+#define vTaskDelete MPU_vTaskDelete
+#define vTaskDelayUntil MPU_vTaskDelayUntil
+#define vTaskDelay MPU_vTaskDelay
+#define uxTaskPriorityGet MPU_uxTaskPriorityGet
+#define vTaskPrioritySet MPU_vTaskPrioritySet
+#define vTaskSuspend MPU_vTaskSuspend
+#define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended
+#define vTaskResume MPU_vTaskResume
+#define vTaskSuspendAll MPU_vTaskSuspendAll
+#define xTaskResumeAll MPU_xTaskResumeAll
+#define xTaskGetTickCount MPU_xTaskGetTickCount
+#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
+#define vTaskList MPU_vTaskList
+#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
+#define vTaskStartTrace MPU_vTaskStartTrace
+#define ulTaskEndTrace MPU_ulTaskEndTrace
+#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
+#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
+#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
+#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
+#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
+#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
+
+#define xQueueCreate MPU_xQueueCreate
+#define xQueueCreateMutex MPU_xQueueCreateMutex
+#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
+#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
+#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
+#define xQueueGenericSend MPU_xQueueGenericSend
+#define xQueueAltGenericSend MPU_xQueueAltGenericSend
+#define xQueueAltGenericReceive MPU_xQueueAltGenericReceive
+#define xQueueGenericReceive MPU_xQueueGenericReceive
+#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
+#define vQueueDelete MPU_vQueueDelete
+
+#define pvPortMalloc MPU_pvPortMalloc
+#define vPortFree MPU_vPortFree
+#define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize
+#define vPortInitialiseBlocks MPU_vPortInitialiseBlocks
+
+#if configQUEUE_REGISTRY_SIZE > 0
+#define vQueueAddToRegistry MPU_vQueueAddToRegistry
+#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
+#endif
+
+/* Remove the privileged function macro. */
+#define PRIVILEGED_FUNCTION
+
+#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
+
+/* Ensure API functions go in the privileged execution section. */
+#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
+#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
+//#define PRIVILEGED_DATA
+
+#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
+
+#else /* portUSING_MPU_WRAPPERS */
+
+#define PRIVILEGED_FUNCTION
+#define PRIVILEGED_DATA
+#define portUSING_MPU_WRAPPERS 0
+
+#endif /* portUSING_MPU_WRAPPERS */
+
+
+#endif /* MPU_WRAPPERS_H */
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/portable.h b/gyro_board/src/usb/FreeRTOS/include/portable.h
new file mode 100644
index 0000000..385be74
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/portable.h
@@ -0,0 +1,391 @@
+/*
+ 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.
+*/
+
+/*-----------------------------------------------------------
+ * Portable layer API. Each function must be defined for each port.
+ *----------------------------------------------------------*/
+
+#ifndef PORTABLE_H
+#define PORTABLE_H
+
+/* Include the macro file relevant to the port being used. */
+
+#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
+#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
+typedef void (__interrupt __far *pxISR)();
+#endif
+
+#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
+#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
+typedef void (__interrupt __far *pxISR)();
+#endif
+
+#ifdef GCC_MEGA_AVR
+#include "../portable/GCC/ATMega323/portmacro.h"
+#endif
+
+#ifdef IAR_MEGA_AVR
+#include "../portable/IAR/ATMega323/portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC24_PORT
+#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
+#endif
+
+#ifdef MPLAB_DSPIC_PORT
+#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC18F_PORT
+#include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC32MX_PORT
+#include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"
+#endif
+
+#ifdef _FEDPICC
+#include "libFreeRTOS/Include/portmacro.h"
+#endif
+
+#ifdef SDCC_CYGNAL
+#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
+#endif
+
+#ifdef GCC_ARM7
+#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
+#endif
+
+#ifdef GCC_ARM7_ECLIPSE
+#include "portmacro.h"
+#endif
+
+#ifdef ROWLEY_LPC23xx
+#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
+#endif
+
+#ifdef IAR_MSP430
+#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
+#endif
+
+#ifdef GCC_MSP430
+#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
+#endif
+
+#ifdef ROWLEY_MSP430
+#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
+#endif
+
+#ifdef ARM7_LPC21xx_KEIL_RVDS
+#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
+#endif
+
+#ifdef SAM7_GCC
+#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
+#endif
+
+#ifdef SAM7_IAR
+#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
+#endif
+
+#ifdef SAM9XE_IAR
+#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
+#endif
+
+#ifdef LPC2000_IAR
+#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
+#endif
+
+#ifdef STR71X_IAR
+#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
+#endif
+
+#ifdef STR75X_IAR
+#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
+#endif
+
+#ifdef STR75X_GCC
+#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
+#endif
+
+#ifdef STR91X_IAR
+#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
+#endif
+
+#ifdef GCC_H8S
+#include "../../Source/portable/GCC/H8S2329/portmacro.h"
+#endif
+
+#ifdef GCC_AT91FR40008
+#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
+#endif
+
+#ifdef RVDS_ARMCM3_LM3S102
+#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef GCC_ARMCM3_LM3S102
+#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef GCC_ARMCM3
+#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef IAR_ARM_CM3
+#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef IAR_ARMCM3_LM
+#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef HCS12_CODE_WARRIOR
+#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
+#endif
+
+#ifdef MICROBLAZE_GCC
+#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
+#endif
+
+#ifdef TERN_EE
+#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
+#endif
+
+#ifdef GCC_HCS12
+#include "../../Source/portable/GCC/HCS12/portmacro.h"
+#endif
+
+#ifdef GCC_MCF5235
+#include "../../Source/portable/GCC/MCF5235/portmacro.h"
+#endif
+
+#ifdef COLDFIRE_V2_GCC
+#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
+#endif
+
+#ifdef COLDFIRE_V2_CODEWARRIOR
+#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
+#endif
+
+#ifdef GCC_PPC405
+#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
+#endif
+
+#ifdef GCC_PPC440
+#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
+#endif
+
+#ifdef _16FX_SOFTUNE
+#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
+#endif
+
+#ifdef BCC_INDUSTRIAL_PC_PORT
+/* A short file name has to be used in place of the normal
+FreeRTOSConfig.h when using the Borland compiler. */
+#include "frconfig.h"
+#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
+typedef void (__interrupt __far *pxISR)();
+#endif
+
+#ifdef BCC_FLASH_LITE_186_PORT
+/* A short file name has to be used in place of the normal
+FreeRTOSConfig.h when using the Borland compiler. */
+#include "frconfig.h"
+#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
+typedef void (__interrupt __far *pxISR)();
+#endif
+
+#ifdef __GNUC__
+#ifdef __AVR32_AVR32A__
+#include "portmacro.h"
+#endif
+#endif
+
+#ifdef __ICCAVR32__
+#ifdef __CORE__
+#if __CORE__ == __AVR32A__
+#include "portmacro.h"
+#endif
+#endif
+#endif
+
+#ifdef __91467D
+#include "portmacro.h"
+#endif
+
+#ifdef __96340
+#include "portmacro.h"
+#endif
+
+
+#ifdef __IAR_V850ES_Fx3__
+#include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Jx3__
+#include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Jx3_L__
+#include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Jx2__
+#include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_V850ES_Hx2__
+#include "../../Source/portable/IAR/V850ES/portmacro.h"
+#endif
+
+#ifdef __IAR_78K0R_Kx3__
+#include "../../Source/portable/IAR/78K0R/portmacro.h"
+#endif
+
+#ifdef __IAR_78K0R_Kx3L__
+#include "../../Source/portable/IAR/78K0R/portmacro.h"
+#endif
+
+/* Catch all to ensure portmacro.h is included in the build. Newer demos
+have the path as part of the project options, rather than as relative from
+the project location. If portENTER_CRITICAL() has not been defined then
+portmacro.h has not yet been included - as every portmacro.h provides a
+portENTER_CRITICAL() definition. Check the demo application for your demo
+to find the path to the correct portmacro.h file. */
+#ifndef portENTER_CRITICAL
+#include "portmacro.h"
+#endif
+
+#if portBYTE_ALIGNMENT == 8
+#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
+#endif
+
+#if portBYTE_ALIGNMENT == 4
+#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
+#endif
+
+#if portBYTE_ALIGNMENT == 2
+#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
+#endif
+
+#if portBYTE_ALIGNMENT == 1
+#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
+#endif
+
+#ifndef portBYTE_ALIGNMENT_MASK
+#error "Invalid portBYTE_ALIGNMENT definition"
+#endif
+
+#ifndef portNUM_CONFIGURABLE_REGIONS
+#define portNUM_CONFIGURABLE_REGIONS 1
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "mpu_wrappers.h"
+
+ /*
+ * Setup the stack of a new task so it is ready to be placed under the
+ * scheduler control. The registers have to be placed on the stack in
+ * the order that the port expects to find them.
+ *
+ */
+#if( portUSING_MPU_WRAPPERS == 1 )
+ portSTACK_TYPE *pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged) PRIVILEGED_FUNCTION;
+#else
+ portSTACK_TYPE *pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters);
+#endif
+
+ /*
+ * Map to the memory management routines required for the port.
+ */
+ void *pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION;
+ void vPortFree(void *pv) PRIVILEGED_FUNCTION;
+ void vPortInitialiseBlocks(void) PRIVILEGED_FUNCTION;
+ size_t xPortGetFreeHeapSize(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * Setup the hardware ready for the scheduler to take control. This generally
+ * sets up a tick interrupt and sets timers for the correct tick frequency.
+ */
+ portBASE_TYPE xPortStartScheduler(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
+ * the hardware is left in its original condition after the scheduler stops
+ * executing.
+ */
+ void vPortEndScheduler(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * The structures and methods of manipulating the MPU are contained within the
+ * port layer.
+ *
+ * Fills the xMPUSettings structure with the memory region information
+ * contained in xRegions.
+ */
+#if( portUSING_MPU_WRAPPERS == 1 )
+ struct xMEMORY_REGION;
+ void vPortStoreTaskMPUSettings(xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth) PRIVILEGED_FUNCTION;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PORTABLE_H */
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/projdefs.h b/gyro_board/src/usb/FreeRTOS/include/projdefs.h
new file mode 100644
index 0000000..543992d
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/projdefs.h
@@ -0,0 +1,77 @@
+/*
+ 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.
+*/
+
+#ifndef PROJDEFS_H
+#define PROJDEFS_H
+
+/* Defines the prototype to which task functions must conform. */
+typedef void (*pdTASK_CODE)(void *);
+
+#define pdTRUE ( 1 )
+#define pdFALSE ( 0 )
+
+#define pdPASS ( 1 )
+#define pdFAIL ( 0 )
+#define errQUEUE_EMPTY ( 0 )
+#define errQUEUE_FULL ( 0 )
+
+/* Error definitions. */
+#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
+#define errNO_TASK_TO_RUN ( -2 )
+#define errQUEUE_BLOCKED ( -4 )
+#define errQUEUE_YIELD ( -5 )
+
+#endif /* PROJDEFS_H */
+
+
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/queue.h b/gyro_board/src/usb/FreeRTOS/include/queue.h
new file mode 100644
index 0000000..8d5dcba
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/queue.h
@@ -0,0 +1,1262 @@
+/*
+ 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.
+*/
+
+#ifndef INC_FREERTOS_H
+#error "#include FreeRTOS.h" must appear in source files before "#include queue.h"
+#endif
+
+
+
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "mpu_wrappers.h"
+
+
+ typedef void * xQueueHandle;
+
+
+ /* For internal use only. */
+#define queueSEND_TO_BACK ( 0 )
+#define queueSEND_TO_FRONT ( 1 )
+
+
+ /**
+ * queue. h
+ * <pre>
+ xQueueHandle xQueueCreate(
+ unsigned portBASE_TYPE uxQueueLength,
+ unsigned portBASE_TYPE uxItemSize
+ );
+ * </pre>
+ *
+ * Creates a new queue instance. This allocates the storage required by the
+ * new queue and returns a handle for the queue.
+ *
+ * @param uxQueueLength The maximum number of items that the queue can contain.
+ *
+ * @param uxItemSize The number of bytes each item in the queue will require.
+ * Items are queued by copy, not by reference, so this is the number of bytes
+ * that will be copied for each posted item. Each item on the queue must be
+ * the same size.
+ *
+ * @return If the queue is successfully create then a handle to the newly
+ * created queue is returned. If the queue cannot be created then 0 is
+ * returned.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+
+ // Create a queue capable of containing 10 unsigned long values.
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+ if( xQueue1 == 0 )
+ {
+ // Queue was not created and must not be used.
+ }
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue2 == 0 )
+ {
+ // Queue was not created and must not be used.
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueCreate xQueueCreate
+ * \ingroup QueueManagement
+ */
+ xQueueHandle xQueueCreate(unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize);
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToToFront(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ );
+ * </pre>
+ *
+ * This is a macro that calls xQueueGenericSend().
+ *
+ * Post an item to the front of a queue. The item is queued by copy, not by
+ * reference. This function must not be called from an interrupt service
+ * routine. See xQueueSendFromISR () for an alternative which may be used
+ * in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the
+ * queue is full. The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 unsigned long values.
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an unsigned long. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToBack(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ );
+ * </pre>
+ *
+ * This is a macro that calls xQueueGenericSend().
+ *
+ * Post an item to the back of a queue. The item is queued by copy, not by
+ * reference. This function must not be called from an interrupt service
+ * routine. See xQueueSendFromISR () for an alternative which may be used
+ * in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the queue
+ * is full. The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 unsigned long values.
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an unsigned long. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSend(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ );
+ * </pre>
+ *
+ * This is a macro that calls xQueueGenericSend(). It is included for
+ * backward compatibility with versions of FreeRTOS.org that did not
+ * include the xQueueSendToFront() and xQueueSendToBack() macros. It is
+ * equivalent to xQueueSendToBack().
+ *
+ * Post an item on a queue. The item is queued by copy, not by reference.
+ * This function must not be called from an interrupt service routine.
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the
+ * queue is full. The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 unsigned long values.
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an unsigned long. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueGenericSend(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ portBASE_TYPE xCopyPosition
+ );
+ * </pre>
+ *
+ * It is preferred that the macros xQueueSend(), xQueueSendToFront() and
+ * xQueueSendToBack() are used in place of calling this function directly.
+ *
+ * Post an item on a queue. The item is queued by copy, not by reference.
+ * This function must not be called from an interrupt service routine.
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the
+ * queue is full. The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item
+ * at the front of the queue (for high priority messages).
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 unsigned long values.
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an unsigned long. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+ signed portBASE_TYPE xQueueGenericSend(xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition);
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueuePeek(
+ xQueueHandle xQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait
+ );</pre>
+ *
+ * This is a macro that calls the xQueueGenericReceive() function.
+ *
+ * Receive an item from a queue without removing the item from the queue.
+ * The item is received by copy so a buffer of adequate size must be
+ * provided. The number of bytes copied into the buffer was defined when
+ * the queue was created.
+ *
+ * Successfully received items remain on the queue so will be returned again
+ * by the next call, or a call to xQueueReceive().
+ *
+ * This macro must not be used in an interrupt service routine.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call. The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue
+ * is empty.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+ // ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+ if( xQueue != 0 )
+ {
+ // Peek a message on the created queue. Block for 10 ticks if a
+ // message is not immediately available.
+ if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+ {
+ // pcRxedMessage now points to the struct AMessage variable posted
+ // by vATask, but the item still remains on the queue.
+ }
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueReceive(
+ xQueueHandle xQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait
+ );</pre>
+ *
+ * This is a macro that calls the xQueueGenericReceive() function.
+ *
+ * Receive an item from a queue. The item is received by copy so a buffer of
+ * adequate size must be provided. The number of bytes copied into the buffer
+ * was defined when the queue was created.
+ *
+ * Successfully received items are removed from the queue.
+ *
+ * This function must not be used in an interrupt service routine. See
+ * xQueueReceiveFromISR for an alternative that can.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call. xQueueReceive() will return immediately if xTicksToWait
+ * is zero and the queue is empty. The time is defined in tick periods so the
+ * constant portTICK_RATE_MS should be used to convert to real time if this is
+ * required.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+ // ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+ if( xQueue != 0 )
+ {
+ // Receive a message on the created queue. Block for 10 ticks if a
+ // message is not immediately available.
+ if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+ {
+ // pcRxedMessage now points to the struct AMessage variable posted
+ // by vATask.
+ }
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
+
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueGenericReceive(
+ xQueueHandle xQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait
+ portBASE_TYPE xJustPeek
+ );</pre>
+ *
+ * It is preferred that the macro xQueueReceive() be used rather than calling
+ * this function directly.
+ *
+ * Receive an item from a queue. The item is received by copy so a buffer of
+ * adequate size must be provided. The number of bytes copied into the buffer
+ * was defined when the queue was created.
+ *
+ * This function must not be used in an interrupt service routine. See
+ * xQueueReceiveFromISR for an alternative that can.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call. The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ * xQueueGenericReceive() will return immediately if the queue is empty and
+ * xTicksToWait is 0.
+ *
+ * @param xJustPeek When set to true, the item received from the queue is not
+ * actually removed from the queue - meaning a subsequent call to
+ * xQueueReceive() will return the same item. When set to false, the item
+ * being received from the queue is also removed from the queue.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+ // ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+ if( xQueue != 0 )
+ {
+ // Receive a message on the created queue. Block for 10 ticks if a
+ // message is not immediately available.
+ if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+ {
+ // pcRxedMessage now points to the struct AMessage variable posted
+ // by vATask.
+ }
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+ signed portBASE_TYPE xQueueGenericReceive(xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek);
+
+ /**
+ * queue. h
+ * <pre>unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );</pre>
+ *
+ * Return the number of messages stored in a queue.
+ *
+ * @param xQueue A handle to the queue being queried.
+ *
+ * @return The number of messages available in the queue.
+ *
+ * \page uxQueueMessagesWaiting uxQueueMessagesWaiting
+ * \ingroup QueueManagement
+ */
+ unsigned portBASE_TYPE uxQueueMessagesWaiting(const xQueueHandle xQueue);
+
+ /**
+ * queue. h
+ * <pre>void vQueueDelete( xQueueHandle xQueue );</pre>
+ *
+ * Delete a queue - freeing all the memory allocated for storing of items
+ * placed on the queue.
+ *
+ * @param xQueue A handle to the queue to be deleted.
+ *
+ * \page vQueueDelete vQueueDelete
+ * \ingroup QueueManagement
+ */
+ void vQueueDelete(xQueueHandle xQueue);
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToFrontFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken
+ );
+ </pre>
+ *
+ * This is a macro that calls xQueueGenericSendFromISR().
+ *
+ * Post an item to the front of a queue. It is safe to use this macro from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+ <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPrioritTaskWoken;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWoken = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post the byte.
+ xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary.
+ if( xHigherPriorityTaskWoken )
+ {
+ taskYIELD ();
+ }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_FRONT )
+
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendToBackFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken
+ );
+ </pre>
+ *
+ * This is a macro that calls xQueueGenericSendFromISR().
+ *
+ * Post an item to the back of a queue. It is safe to use this macro from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+ <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWoken = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post the byte.
+ xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary.
+ if( xHigherPriorityTaskWoken )
+ {
+ taskYIELD ();
+ }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken
+ );
+ </pre>
+ *
+ * This is a macro that calls xQueueGenericSendFromISR(). It is included
+ * for backward compatibility with versions of FreeRTOS.org that did not
+ * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR()
+ * macros.
+ *
+ * Post an item to the back of a queue. It is safe to use this function from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueSendFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+ <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWoken = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post the byte.
+ xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary.
+ if( xHigherPriorityTaskWoken )
+ {
+ // Actual macro used here is port specific.
+ taskYIELD_FROM_ISR ();
+ }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueGenericSendFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken,
+ portBASE_TYPE xCopyPosition
+ );
+ </pre>
+ *
+ * It is preferred that the macros xQueueSendFromISR(),
+ * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place
+ * of calling this function directly.
+ *
+ * Post an item on a queue. It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item
+ * at the front of the queue (for high priority messages).
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+ <pre>
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWokenByPost;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWokenByPost = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post each byte.
+ xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary. Note that the
+ // name of the yield function required is port specific.
+ if( xHigherPriorityTaskWokenByPost )
+ {
+ taskYIELD_YIELD_FROM_ISR();
+ }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+ signed portBASE_TYPE xQueueGenericSendFromISR(xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition);
+
+ /**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueReceiveFromISR(
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portBASE_TYPE *pxTaskWoken
+ );
+ * </pre>
+ *
+ * Receive an item from a queue. It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param pxTaskWoken A task may be blocked waiting for space to become
+ * available on the queue. If xQueueReceiveFromISR causes such a task to
+ * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will
+ * remain unchanged.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+ <pre>
+
+ xQueueHandle xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const portTickType xBlockTime = ( portTickType )0xff;
+
+ // Create a queue capable of containing 10 characters.
+ xQueue = xQueueCreate( 10, sizeof( char ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Post some characters that will be used within an ISR. If the queue
+ // is full then this task will block for xBlockTime ticks.
+ cValueToPost = 'a';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ cValueToPost = 'b';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+
+ // ... keep posting characters ... this task may block when the queue
+ // becomes full.
+
+ cValueToPost = 'c';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ portBASE_TYPE xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+ while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+ {
+ // A character was received. Output the character now.
+ vOutputCharacter( cRxedChar );
+
+ // If removing the character from the queue woke the task that was
+ // posting onto the queue cTaskWokenByReceive will have been set to
+ // pdTRUE. No matter how many times this loop iterates only one
+ // task will be woken.
+ }
+
+ if( cTaskWokenByPost != ( char ) pdFALSE;
+ {
+ taskYIELD ();
+ }
+ }
+ </pre>
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR
+ * \ingroup QueueManagement
+ */
+ signed portBASE_TYPE xQueueReceiveFromISR(xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken);
+
+ /*
+ * Utilities to query queue that are safe to use from an ISR. These utilities
+ * should be used only from witin an ISR, or within a critical section.
+ */
+ signed portBASE_TYPE xQueueIsQueueEmptyFromISR(const xQueueHandle pxQueue);
+ signed portBASE_TYPE xQueueIsQueueFullFromISR(const xQueueHandle pxQueue);
+ unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR(const xQueueHandle pxQueue);
+
+
+ /*
+ * xQueueAltGenericSend() is an alternative version of xQueueGenericSend().
+ * Likewise xQueueAltGenericReceive() is an alternative version of
+ * xQueueGenericReceive().
+ *
+ * The source code that implements the alternative (Alt) API is much
+ * simpler because it executes everything from within a critical section.
+ * This is the approach taken by many other RTOSes, but FreeRTOS.org has the
+ * preferred fully featured API too. The fully featured API has more
+ * complex code that takes longer to execute, but makes much less use of
+ * critical sections. Therefore the alternative API sacrifices interrupt
+ * responsiveness to gain execution speed, whereas the fully featured API
+ * sacrifices execution speed to ensure better interrupt responsiveness.
+ */
+ signed portBASE_TYPE xQueueAltGenericSend(xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition);
+ signed portBASE_TYPE xQueueAltGenericReceive(xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking);
+#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
+#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
+#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
+
+ /*
+ * The functions defined above are for passing data to and from tasks. The
+ * functions below are the equivalents for passing data to and from
+ * co-routines.
+ *
+ * These functions are called from the co-routine macro implementation and
+ * should not be called directly from application code. Instead use the macro
+ * wrappers defined within croutine.h.
+ */
+ signed portBASE_TYPE xQueueCRSendFromISR(xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken);
+ signed portBASE_TYPE xQueueCRReceiveFromISR(xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken);
+ signed portBASE_TYPE xQueueCRSend(xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait);
+ signed portBASE_TYPE xQueueCRReceive(xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait);
+
+ /*
+ * For internal use only. Use xSemaphoreCreateMutex() or
+ * xSemaphoreCreateCounting() instead of calling these functions directly.
+ */
+ xQueueHandle xQueueCreateMutex(void);
+ xQueueHandle xQueueCreateCountingSemaphore(unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount);
+
+ /*
+ * For internal use only. Use xSemaphoreTakeMutexRecursive() or
+ * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
+ */
+ portBASE_TYPE xQueueTakeMutexRecursive(xQueueHandle xMutex, portTickType xBlockTime);
+ portBASE_TYPE xQueueGiveMutexRecursive(xQueueHandle xMutex);
+
+ /*
+ * The registry is provided as a means for kernel aware debuggers to
+ * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add
+ * a queue, semaphore or mutex handle to the registry if you want the handle
+ * to be available to a kernel aware debugger. If you are not using a kernel
+ * aware debugger then this function can be ignored.
+ *
+ * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the
+ * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0
+ * within FreeRTOSConfig.h for the registry to be available. Its value
+ * does not effect the number of queues, semaphores and mutexes that can be
+ * created - just the number that the registry can hold.
+ *
+ * @param xQueue The handle of the queue being added to the registry. This
+ * is the handle returned by a call to xQueueCreate(). Semaphore and mutex
+ * handles can also be passed in here.
+ *
+ * @param pcName The name to be associated with the handle. This is the
+ * name that the kernel aware debugger will display.
+ */
+#if configQUEUE_REGISTRY_SIZE > 0
+ void vQueueAddToRegistry(xQueueHandle xQueue, signed char *pcName);
+#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QUEUE_H */
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/semphr.h b/gyro_board/src/usb/FreeRTOS/include/semphr.h
new file mode 100644
index 0000000..b941518
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/semphr.h
@@ -0,0 +1,711 @@
+/*
+ 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.
+*/
+
+#ifndef INC_FREERTOS_H
+#error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
+#endif
+
+#ifndef SEMAPHORE_H
+#define SEMAPHORE_H
+
+#include "queue.h"
+
+typedef xQueueHandle xSemaphoreHandle;
+
+#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1 )
+#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0 )
+#define semGIVE_BLOCK_TIME ( ( portTickType ) 0 )
+
+
+/**
+ * semphr. h
+ * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
+ *
+ * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
+ * The queue length is 1 as this is a binary semaphore. The data size is 0
+ * as we don't want to actually store any data - we just want to know if the
+ * queue is empty or full.
+ *
+ * This type of semaphore can be used for pure synchronisation between tasks or
+ * between an interrupt and a task. The semaphore need not be given back once
+ * obtained, so one task/interrupt can continuously 'give' the semaphore while
+ * another continuously 'takes' the semaphore. For this reason this type of
+ * semaphore does not use a priority inheritance mechanism. For an alternative
+ * that does use priority inheritance see xSemaphoreCreateMutex().
+ *
+ * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+ // This is a macro so pass the variable in directly.
+ vSemaphoreCreateBinary( xSemaphore );
+
+ if( xSemaphore != NULL )
+ {
+ // The semaphore was created successfully.
+ // The semaphore can now be used.
+ }
+ }
+ </pre>
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
+ * \ingroup Semaphores
+ */
+#define vSemaphoreCreateBinary( xSemaphore ) { \
+ xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
+ if( xSemaphore != NULL ) \
+ { \
+ xSemaphoreGive( xSemaphore ); \
+ } \
+ }
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreTake(
+ * xSemaphoreHandle xSemaphore,
+ * portTickType xBlockTime
+ * )</pre>
+ *
+ * <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
+ * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * xSemaphoreCreateCounting().
+ *
+ * @param xSemaphore A handle to the semaphore being taken - obtained when
+ * the semaphore was created.
+ *
+ * @param xBlockTime The time in ticks to wait for the semaphore to become
+ * available. The macro portTICK_RATE_MS can be used to convert this to a
+ * real time. A block time of zero can be used to poll the semaphore. A block
+ * time of portMAX_DELAY can be used to block indefinitely (provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
+ *
+ * @return pdTRUE if the semaphore was obtained. pdFALSE
+ * if xBlockTime expired without the semaphore becoming available.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+ // Create the semaphore to guard a shared resource.
+ vSemaphoreCreateBinary( xSemaphore );
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+ // ... Do other things.
+
+ if( xSemaphore != NULL )
+ {
+ // See if we can obtain the semaphore. If the semaphore is not available
+ // wait 10 ticks to see if it becomes free.
+ if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+ {
+ // We were able to obtain the semaphore and can now access the
+ // shared resource.
+
+ // ...
+
+ // We have finished accessing the shared resource. Release the
+ // semaphore.
+ xSemaphoreGive( xSemaphore );
+ }
+ else
+ {
+ // We could not obtain the semaphore and can therefore not access
+ // the shared resource safely.
+ }
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreTake xSemaphoreTake
+ * \ingroup Semaphores
+ */
+#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
+
+/**
+ * semphr. h
+ * xSemaphoreTakeRecursive(
+ * xSemaphoreHandle xMutex,
+ * portTickType xBlockTime
+ * )
+ *
+ * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
+ * The mutex must have previously been created using a call to
+ * xSemaphoreCreateRecursiveMutex();
+ *
+ * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
+ * macro to be available.
+ *
+ * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
+ *
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
+ * doesn't become available again until the owner has called
+ * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will
+ * not be available to any other task until it has also 'given' the mutex back
+ * exactly five times.
+ *
+ * @param xMutex A handle to the mutex being obtained. This is the
+ * handle returned by xSemaphoreCreateRecursiveMutex();
+ *
+ * @param xBlockTime The time in ticks to wait for the semaphore to become
+ * available. The macro portTICK_RATE_MS can be used to convert this to a
+ * real time. A block time of zero can be used to poll the semaphore. If
+ * the task already owns the semaphore then xSemaphoreTakeRecursive() will
+ * return immediately no matter what the value of xBlockTime.
+ *
+ * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
+ * expired without the semaphore becoming available.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+ // Create the mutex to guard a shared resource.
+ xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+ // ... Do other things.
+
+ if( xMutex != NULL )
+ {
+ // See if we can obtain the mutex. If the mutex is not available
+ // wait 10 ticks to see if it becomes free.
+ if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+ {
+ // We were able to obtain the mutex and can now access the
+ // shared resource.
+
+ // ...
+ // For some reason due to the nature of the code further calls to
+ // xSemaphoreTakeRecursive() are made on the same mutex. In real
+ // code these would not be just sequential calls as this would make
+ // no sense. Instead the calls are likely to be buried inside
+ // a more complex call structure.
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+ // The mutex has now been 'taken' three times, so will not be
+ // available to another task until it has also been given back
+ // three times. Again it is unlikely that real code would have
+ // these calls sequentially, but instead buried in a more complex
+ // call structure. This is just for illustrative purposes.
+ xSemaphoreGiveRecursive( xMutex );
+ xSemaphoreGiveRecursive( xMutex );
+ xSemaphoreGiveRecursive( xMutex );
+
+ // Now the mutex can be taken by other tasks.
+ }
+ else
+ {
+ // We could not obtain the mutex and can therefore not access
+ // the shared resource safely.
+ }
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime )
+
+
+/*
+ * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
+ *
+ * The source code that implements the alternative (Alt) API is much
+ * simpler because it executes everything from within a critical section.
+ * This is the approach taken by many other RTOSes, but FreeRTOS.org has the
+ * preferred fully featured API too. The fully featured API has more
+ * complex code that takes longer to execute, but makes much less use of
+ * critical sections. Therefore the alternative API sacrifices interrupt
+ * responsiveness to gain execution speed, whereas the fully featured API
+ * sacrifices execution speed to ensure better interrupt responsiveness.
+ */
+#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
+ *
+ * <i>Macro</i> to release a semaphore. The semaphore must have previously been
+ * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
+ * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
+ *
+ * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
+ * an alternative which can be used from an ISR.
+ *
+ * This macro must also not be used on semaphores created using
+ * xSemaphoreCreateRecursiveMutex().
+ *
+ * @param xSemaphore A handle to the semaphore being released. This is the
+ * handle returned when the semaphore was created.
+ *
+ * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
+ * Semaphores are implemented using queues. An error can occur if there is
+ * no space on the queue to post a message - indicating that the
+ * semaphore was not first obtained correctly.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+ // Create the semaphore to guard a shared resource.
+ vSemaphoreCreateBinary( xSemaphore );
+
+ if( xSemaphore != NULL )
+ {
+ if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+ {
+ // We would expect this call to fail because we cannot give
+ // a semaphore without first "taking" it!
+ }
+
+ // Obtain the semaphore - don't block if the semaphore is not
+ // immediately available.
+ if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
+ {
+ // We now have the semaphore and can access the shared resource.
+
+ // ...
+
+ // We have finished accessing the shared resource so can free the
+ // semaphore.
+ if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+ {
+ // We would not expect this call to fail because we must have
+ // obtained the semaphore to get here.
+ }
+ }
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreGive xSemaphoreGive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
+ *
+ * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
+ * The mutex must have previously been created using a call to
+ * xSemaphoreCreateRecursiveMutex();
+ *
+ * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
+ * macro to be available.
+ *
+ * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
+ *
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
+ * doesn't become available again until the owner has called
+ * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will
+ * not be available to any other task until it has also 'given' the mutex back
+ * exactly five times.
+ *
+ * @param xMutex A handle to the mutex being released, or 'given'. This is the
+ * handle returned by xSemaphoreCreateMutex();
+ *
+ * @return pdTRUE if the semaphore was given.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+ // Create the mutex to guard a shared resource.
+ xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+ // ... Do other things.
+
+ if( xMutex != NULL )
+ {
+ // See if we can obtain the mutex. If the mutex is not available
+ // wait 10 ticks to see if it becomes free.
+ if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
+ {
+ // We were able to obtain the mutex and can now access the
+ // shared resource.
+
+ // ...
+ // For some reason due to the nature of the code further calls to
+ // xSemaphoreTakeRecursive() are made on the same mutex. In real
+ // code these would not be just sequential calls as this would make
+ // no sense. Instead the calls are likely to be buried inside
+ // a more complex call structure.
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+ // The mutex has now been 'taken' three times, so will not be
+ // available to another task until it has also been given back
+ // three times. Again it is unlikely that real code would have
+ // these calls sequentially, it would be more likely that the calls
+ // to xSemaphoreGiveRecursive() would be called as a call stack
+ // unwound. This is just for demonstrative purposes.
+ xSemaphoreGiveRecursive( xMutex );
+ xSemaphoreGiveRecursive( xMutex );
+ xSemaphoreGiveRecursive( xMutex );
+
+ // Now the mutex can be taken by other tasks.
+ }
+ else
+ {
+ // We could not obtain the mutex and can therefore not access
+ // the shared resource safely.
+ }
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex )
+
+/*
+ * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
+ *
+ * The source code that implements the alternative (Alt) API is much
+ * simpler because it executes everything from within a critical section.
+ * This is the approach taken by many other RTOSes, but FreeRTOS.org has the
+ * preferred fully featured API too. The fully featured API has more
+ * complex code that takes longer to execute, but makes much less use of
+ * critical sections. Therefore the alternative API sacrifices interrupt
+ * responsiveness to gain execution speed, whereas the fully featured API
+ * sacrifices execution speed to ensure better interrupt responsiveness.
+ */
+#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * <pre>
+ xSemaphoreGiveFromISR(
+ xSemaphoreHandle xSemaphore,
+ signed portBASE_TYPE *pxHigherPriorityTaskWoken
+ )</pre>
+ *
+ * <i>Macro</i> to release a semaphore. The semaphore must have previously been
+ * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
+ *
+ * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
+ * must not be used with this macro.
+ *
+ * This macro can be used from an ISR.
+ *
+ * @param xSemaphore A handle to the semaphore being released. This is the
+ * handle returned when the semaphore was created.
+ *
+ * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+ <pre>
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT 10
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // We want this task to run every 10 ticks of a timer. The semaphore
+ // was created before this task was started.
+
+ // Block waiting for the semaphore to become available.
+ if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+ {
+ // It is time to execute.
+
+ // ...
+
+ // We have finished our task. Return to the top of the loop where
+ // we will block on the semaphore until it is time to execute
+ // again. Note when using the semaphore for synchronisation with an
+ // ISR in this manner there is no need to 'give' the semaphore back.
+ }
+ }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static unsigned char ucLocalTickCount = 0;
+ static signed portBASE_TYPE xHigherPriorityTaskWoken;
+
+ // A timer tick has occurred.
+
+ // ... Do other time functions.
+
+ // Is it time for vATask () to run?
+ xHigherPriorityTaskWoken = pdFALSE;
+ ucLocalTickCount++;
+ if( ucLocalTickCount >= TICKS_TO_WAIT )
+ {
+ // Unblock the task by releasing the semaphore.
+ xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+ // Reset the count so we release the semaphore again in 10 ticks time.
+ ucLocalTickCount = 0;
+ }
+
+ if( xHigherPriorityTaskWoken != pdFALSE )
+ {
+ // We can force a context switch here. Context switching from an
+ // ISR uses port specific syntax. Check the demo task for your port
+ // to find the syntax required.
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
+ *
+ * <i>Macro</i> that implements a mutex semaphore by using the existing queue
+ * mechanism.
+ *
+ * Mutexes created using this macro can be accessed using the xSemaphoreTake()
+ * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
+ * xSemaphoreGiveRecursive() macros should not be used.
+ *
+ * This type of semaphore uses a priority inheritance mechanism so a task
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
+ * semaphore it is no longer required.
+ *
+ * Mutex type semaphores cannot be used from within interrupt service routines.
+ *
+ * See vSemaphoreCreateBinary() for an alternative implementation that can be
+ * used for pure synchronisation (where one task or interrupt always 'gives' the
+ * semaphore and another always 'takes' the semaphore) and from within interrupt
+ * service routines.
+ *
+ * @return xSemaphore Handle to the created mutex semaphore. Should be of type
+ * xSemaphoreHandle.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+ // This is a macro so pass the variable in directly.
+ xSemaphore = xSemaphoreCreateMutex();
+
+ if( xSemaphore != NULL )
+ {
+ // The semaphore was created successfully.
+ // The semaphore can now be used.
+ }
+ }
+ </pre>
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateMutex() xQueueCreateMutex()
+
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
+ *
+ * <i>Macro</i> that implements a recursive mutex by using the existing queue
+ * mechanism.
+ *
+ * Mutexes created using this macro can be accessed using the
+ * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
+ * xSemaphoreTake() and xSemaphoreGive() macros should not be used.
+ *
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
+ * doesn't become available again until the owner has called
+ * xSemaphoreGiveRecursive() for each successful 'take' request. For example,
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will
+ * not be available to any other task until it has also 'given' the mutex back
+ * exactly five times.
+ *
+ * This type of semaphore uses a priority inheritance mechanism so a task
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
+ * semaphore it is no longer required.
+ *
+ * Mutex type semaphores cannot be used from within interrupt service routines.
+ *
+ * See vSemaphoreCreateBinary() for an alternative implementation that can be
+ * used for pure synchronisation (where one task or interrupt always 'gives' the
+ * semaphore and another always 'takes' the semaphore) and from within interrupt
+ * service routines.
+ *
+ * @return xSemaphore Handle to the created mutex semaphore. Should be of type
+ * xSemaphoreHandle.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+ // This is a macro so pass the variable in directly.
+ xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+ if( xSemaphore != NULL )
+ {
+ // The semaphore was created successfully.
+ // The semaphore can now be used.
+ }
+ }
+ </pre>
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
+ *
+ * <i>Macro</i> that creates a counting semaphore by using the existing
+ * queue mechanism.
+ *
+ * Counting semaphores are typically used for two things:
+ *
+ * 1) Counting events.
+ *
+ * In this usage scenario an event handler will 'give' a semaphore each time
+ * an event occurs (incrementing the semaphore count value), and a handler
+ * task will 'take' a semaphore each time it processes an event
+ * (decrementing the semaphore count value). The count value is therefore
+ * the difference between the number of events that have occurred and the
+ * number that have been processed. In this case it is desirable for the
+ * initial count value to be zero.
+ *
+ * 2) Resource management.
+ *
+ * In this usage scenario the count value indicates the number of resources
+ * available. To obtain control of a resource a task must first obtain a
+ * semaphore - decrementing the semaphore count value. When the count value
+ * reaches zero there are no free resources. When a task finishes with the
+ * resource it 'gives' the semaphore back - incrementing the semaphore count
+ * value. In this case it is desirable for the initial count value to be
+ * equal to the maximum count value, indicating that all resources are free.
+ *
+ * @param uxMaxCount The maximum count value that can be reached. When the
+ * semaphore reaches this value it can no longer be 'given'.
+ *
+ * @param uxInitialCount The count value assigned to the semaphore when it is
+ * created.
+ *
+ * @return Handle to the created semaphore. Null if the semaphore could not be
+ * created.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+ // The max value to which the semaphore can count should be 10, and the
+ // initial value assigned to the count should be 0.
+ xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+ if( xSemaphore != NULL )
+ {
+ // The semaphore was created successfully.
+ // The semaphore can now be used.
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
+
+
+#endif /* SEMAPHORE_H */
+
+
diff --git a/gyro_board/src/usb/FreeRTOS/include/task.h b/gyro_board/src/usb/FreeRTOS/include/task.h
new file mode 100644
index 0000000..a8d8a62
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/include/task.h
@@ -0,0 +1,1261 @@
+/*
+ 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.
+*/
+
+
+#ifndef INC_FREERTOS_H
+#error "#include FreeRTOS.h" must appear in source files before "#include task.h"
+#endif
+
+
+
+#ifndef TASK_H
+#define TASK_H
+
+#include "portable.h"
+#include "list.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /*-----------------------------------------------------------
+ * MACROS AND DEFINITIONS
+ *----------------------------------------------------------*/
+
+#define tskKERNEL_VERSION_NUMBER "V6.0.4"
+
+ /**
+ * task. h
+ *
+ * Type by which tasks are referenced. For example, a call to xTaskCreate
+ * returns (via a pointer parameter) an xTaskHandle variable that can then
+ * be used as a parameter to vTaskDelete to delete the task.
+ *
+ * \page xTaskHandle xTaskHandle
+ * \ingroup Tasks
+ */
+ typedef void * xTaskHandle;
+
+ /*
+ * Used internally only.
+ */
+ typedef struct xTIME_OUT {
+ portBASE_TYPE xOverflowCount;
+ portTickType xTimeOnEntering;
+ } xTimeOutType;
+
+ /*
+ * Defines the memory ranges allocated to the task when an MPU is used.
+ */
+ typedef struct xMEMORY_REGION {
+ void *pvBaseAddress;
+ unsigned long ulLengthInBytes;
+ unsigned long ulParameters;
+ } xMemoryRegion;
+
+ /*
+ * Parameters required to create an MPU protected task.
+ */
+ typedef struct xTASK_PARAMTERS {
+ pdTASK_CODE pvTaskCode;
+ const signed char * const pcName;
+ unsigned short usStackDepth;
+ void *pvParameters;
+ unsigned portBASE_TYPE uxPriority;
+ portSTACK_TYPE *puxStackBuffer;
+ xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ];
+ } xTaskParameters;
+
+ /*
+ * Defines the priority used by the idle task. This must not be modified.
+ *
+ * \ingroup TaskUtils
+ */
+#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 )
+
+ /**
+ * task. h
+ *
+ * Macro for forcing a context switch.
+ *
+ * \page taskYIELD taskYIELD
+ * \ingroup SchedulerControl
+ */
+#define taskYIELD() portYIELD()
+
+ /**
+ * task. h
+ *
+ * Macro to mark the start of a critical code region. Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \page taskENTER_CRITICAL taskENTER_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskENTER_CRITICAL() portENTER_CRITICAL()
+
+ /**
+ * task. h
+ *
+ * Macro to mark the end of a critical code region. Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \page taskEXIT_CRITICAL taskEXIT_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
+
+ /**
+ * task. h
+ *
+ * Macro to disable all maskable interrupts.
+ *
+ * \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()
+
+ /**
+ * task. h
+ *
+ * Macro to enable microcontroller interrupts.
+ *
+ * \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
+
+ /* Definitions returned by xTaskGetSchedulerState(). */
+#define taskSCHEDULER_NOT_STARTED 0
+#define taskSCHEDULER_RUNNING 1
+#define taskSCHEDULER_SUSPENDED 2
+
+ /*-----------------------------------------------------------
+ * TASK CREATION API
+ *----------------------------------------------------------*/
+
+ /**
+ * task. h
+ *<pre>
+ portBASE_TYPE xTaskCreate(
+ pdTASK_CODE pvTaskCode,
+ const char * const pcName,
+ unsigned short usStackDepth,
+ void *pvParameters,
+ unsigned portBASE_TYPE uxPriority,
+ xTaskHandle *pvCreatedTask
+ );</pre>
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ *
+ * xTaskCreate() can only be used to create a task that has unrestricted
+ * access to the entire microcontroller memory map. Systems that include MPU
+ * support can alternatively create an MPU constrained task using
+ * xTaskCreateRestricted().
+ *
+ * @param pvTaskCode Pointer to the task entry function. Tasks
+ * must be implemented to never return (i.e. continuous loop).
+ *
+ * @param pcName A descriptive name for the task. This is mainly used to
+ * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default
+ * is 16.
+ *
+ * @param usStackDepth The size of the task stack specified as the number of
+ * variables the stack can hold - not the number of bytes. For example, if
+ * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes
+ * will be allocated for stack storage.
+ *
+ * @param pvParameters Pointer that will be used as the parameter for the task
+ * being created.
+ *
+ * @param uxPriority The priority at which the task should run. Systems that
+ * include MPU support can optionally create tasks in a privileged (system)
+ * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For
+ * example, to create a privileged task at priority 2 the uxPriority parameter
+ * should be set to ( 2 | portPRIVILEGE_BIT ).
+ *
+ * @param pvCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file errors. h
+ *
+ * Example usage:
+ <pre>
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+ }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+ // Create the task, storing the handle. Note that the passed parameter ucParameterToPass
+ // must exist for the lifetime of the task, so in this case is declared static. If it was just an
+ // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+ // the new task attempts to access it.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+
+ // Use the handle to delete the task.
+ vTaskDelete( xHandle );
+ }
+ </pre>
+ * \defgroup xTaskCreate xTaskCreate
+ * \ingroup Tasks
+ */
+#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )
+
+ /**
+ * task. h
+ *<pre>
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );</pre>
+ *
+ * xTaskCreateRestricted() should only be used in systems that include an MPU
+ * implementation.
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ * The function parameters define the memory regions and associated access
+ * permissions allocated to the task.
+ *
+ * @param pxTaskDefinition Pointer to a structure that contains a member
+ * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
+ * documentation) plus an optional stack buffer and the memory region
+ * definitions.
+ *
+ * @param pxCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file errors. h
+ *
+ * Example usage:
+ <pre>
+ // Create an xTaskParameters structure that defines the task to be created.
+ static const xTaskParameters xCheckTaskParameters =
+ {
+ vATask, // pvTaskCode - the function that implements the task.
+ "ATask", // pcName - just a text name for the task to assist debugging.
+ 100, // usStackDepth - the stack size DEFINED IN WORDS.
+ NULL, // pvParameters - passed into the task function as the function parameters.
+ ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+ cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+ // xRegions - Allocate up to three separate memory regions for access by
+ // the task, with appropriate access permissions. Different processors have
+ // different memory alignment requirements - refer to the FreeRTOS documentation
+ // for full information.
+ {
+ // Base address Length Parameters
+ { cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
+ { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
+ { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
+ }
+ };
+
+ int main( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task from the const structure defined above. The task handle
+ // is requested (the second parameter is not NULL) but in this case just for
+ // demonstration purposes as its not actually used.
+ xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+ // Start the scheduler.
+ vTaskStartScheduler();
+
+ // Will only get here if there was insufficient memory to create the idle
+ // task.
+ for( ;; );
+ }
+ </pre>
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted
+ * \ingroup Tasks
+ */
+#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) )
+
+ /**
+ * task. h
+ *<pre>
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );</pre>
+ *
+ * Memory regions are assigned to a restricted task when the task is created by
+ * a call to xTaskCreateRestricted(). These regions can be redefined using
+ * vTaskAllocateMPURegions().
+ *
+ * @param xTask The handle of the task being updated.
+ *
+ * @param xRegions A pointer to an xMemoryRegion structure that contains the
+ * new memory region definitions.
+ *
+ * Example usage:
+ <pre>
+ // Define an array of xMemoryRegion structures that configures an MPU region
+ // allowing read/write access for 1024 bytes starting at the beginning of the
+ // ucOneKByte array. The other two of the maximum 3 definable regions are
+ // unused so set to zero.
+ static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+ {
+ // Base address Length Parameters
+ { ucOneKByte, 1024, portMPU_REGION_READ_WRITE },
+ { 0, 0, 0 },
+ { 0, 0, 0 }
+ };
+
+ void vATask( void *pvParameters )
+ {
+ // This task was created such that it has access to certain regions of
+ // memory as defined by the MPU configuration. At some point it is
+ // desired that these MPU regions are replaced with that defined in the
+ // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions()
+ // for this purpose. NULL is used as the task handle to indicate that this
+ // function should modify the MPU regions of the calling task.
+ vTaskAllocateMPURegions( NULL, xAltRegions );
+
+ // Now the task can continue its function, but from this point on can only
+ // access its stack and the ucOneKByte array (unless any other statically
+ // defined or shared regions have been declared elsewhere).
+ }
+ </pre>
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted
+ * \ingroup Tasks
+ */
+ void vTaskAllocateMPURegions(xTaskHandle xTask, const xMemoryRegion * const pxRegions) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void vTaskDelete( xTaskHandle pxTask );</pre>
+ *
+ * INCLUDE_vTaskDelete must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Remove a task from the RTOS real time kernels management. The task being
+ * deleted will be removed from all ready, blocked, suspended and event lists.
+ *
+ * NOTE: The idle task is responsible for freeing the kernel allocated
+ * memory from tasks that have been deleted. It is therefore important that
+ * the idle task is not starved of microcontroller processing time if your
+ * application makes any calls to vTaskDelete (). Memory allocated by the
+ * task code is not automatically freed, and should be freed before the task
+ * is deleted.
+ *
+ * See the demo application file death.c for sample code that utilises
+ * vTaskDelete ().
+ *
+ * @param pxTask The handle of the task to be deleted. Passing NULL will
+ * cause the calling task to be deleted.
+ *
+ * Example usage:
+ <pre>
+ void vOtherFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create the task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // Use the handle to delete the task.
+ vTaskDelete( xHandle );
+ }
+ </pre>
+ * \defgroup vTaskDelete vTaskDelete
+ * \ingroup Tasks
+ */
+ void vTaskDelete(xTaskHandle pxTask) PRIVILEGED_FUNCTION;
+
+
+ /*-----------------------------------------------------------
+ * TASK CONTROL API
+ *----------------------------------------------------------*/
+
+ /**
+ * task. h
+ * <pre>void vTaskDelay( portTickType xTicksToDelay );</pre>
+ *
+ * Delay a task for a given number of ticks. The actual time that the
+ * task remains blocked depends on the tick rate. The constant
+ * portTICK_RATE_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * INCLUDE_vTaskDelay must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ *
+ * vTaskDelay() specifies a time at which the task wishes to unblock relative to
+ * the time at which vTaskDelay() is called. For example, specifying a block
+ * period of 100 ticks will cause the task to unblock 100 ticks after
+ * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method
+ * of controlling the frequency of a cyclical task as the path taken through the
+ * code, as well as other task and interrupt activity, will effect the frequency
+ * at which vTaskDelay() gets called and therefore the time at which the task
+ * next executes. See vTaskDelayUntil() for an alternative API function designed
+ * to facilitate fixed frequency execution. It does this by specifying an
+ * absolute time (rather than a relative time) at which the calling task should
+ * unblock.
+ *
+ * @param xTicksToDelay The amount of time, in tick periods, that
+ * the calling task should block.
+ *
+ * Example usage:
+
+ void vTaskFunction( void * pvParameters )
+ {
+ void vTaskFunction( void * pvParameters )
+ {
+ // Block for 500ms.
+ const portTickType xDelay = 500 / portTICK_RATE_MS;
+
+ for( ;; )
+ {
+ // Simply toggle the LED every 500ms, blocking between each toggle.
+ vToggleLED();
+ vTaskDelay( xDelay );
+ }
+ }
+
+ * \defgroup vTaskDelay vTaskDelay
+ * \ingroup TaskCtrl
+ */
+ void vTaskDelay(portTickType xTicksToDelay) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );</pre>
+ *
+ * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Delay a task until a specified time. This function can be used by cyclical
+ * tasks to ensure a constant execution frequency.
+ *
+ * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will
+ * cause a task to block for the specified number of ticks from the time vTaskDelay () is
+ * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed
+ * execution frequency as the time between a task starting to execute and that task
+ * calling vTaskDelay () may not be fixed [the task may take a different path though the
+ * code between calls, or may get interrupted or preempted a different number of times
+ * each time it executes].
+ *
+ * Whereas vTaskDelay () specifies a wake time relative to the time at which the function
+ * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to
+ * unblock.
+ *
+ * The constant portTICK_RATE_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the
+ * task was last unblocked. The variable must be initialised with the current time
+ * prior to its first use (see the example below). Following this the variable is
+ * automatically updated within vTaskDelayUntil ().
+ *
+ * @param xTimeIncrement The cycle time period. The task will be unblocked at
+ * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the
+ * same xTimeIncrement parameter value will cause the task to execute with
+ * a fixed interface period.
+ *
+ * Example usage:
+ <pre>
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ portTickType xLastWakeTime;
+ const portTickType xFrequency = 10;
+
+ // Initialise the xLastWakeTime variable with the current time.
+ xLastWakeTime = xTaskGetTickCount ();
+ for( ;; )
+ {
+ // Wait for the next cycle.
+ vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+ // Perform action here.
+ }
+ }
+ </pre>
+ * \defgroup vTaskDelayUntil vTaskDelayUntil
+ * \ingroup TaskCtrl
+ */
+ void vTaskDelayUntil(portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );</pre>
+ *
+ * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Obtain the priority of any task.
+ *
+ * @param pxTask Handle of the task to be queried. Passing a NULL
+ * handle results in the priority of the calling task being returned.
+ *
+ * @return The priority of pxTask.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to obtain the priority of the created task.
+ // It was created with tskIDLE_PRIORITY, but may have changed
+ // it itself.
+ if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+ {
+ // The task has changed it's priority.
+ }
+
+ // ...
+
+ // Is our priority higher than the created task?
+ if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+ {
+ // Our priority (obtained using NULL handle) is higher.
+ }
+ }
+ </pre>
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet
+ * \ingroup TaskCtrl
+ */
+ unsigned portBASE_TYPE uxTaskPriorityGet(xTaskHandle pxTask) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );</pre>
+ *
+ * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Set the priority of any task.
+ *
+ * A context switch will occur before the function returns if the priority
+ * being set is higher than the currently executing task.
+ *
+ * @param pxTask Handle to the task for which the priority is being set.
+ * Passing a NULL handle results in the priority of the calling task being set.
+ *
+ * @param uxNewPriority The priority to which the task will be set.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to raise the priority of the created task.
+ vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+ // ...
+
+ // Use a NULL handle to raise our priority to the same value.
+ vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+ </pre>
+ * \defgroup vTaskPrioritySet vTaskPrioritySet
+ * \ingroup TaskCtrl
+ */
+ void vTaskPrioritySet(xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void vTaskSuspend( xTaskHandle pxTaskToSuspend );</pre>
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Suspend any task. When suspended a task will never get any microcontroller
+ * processing time, no matter what its priority.
+ *
+ * Calls to vTaskSuspend are not accumulative -
+ * i.e. calling vTaskSuspend () twice on the same task still only requires one
+ * call to vTaskResume () to ready the suspended task.
+ *
+ * @param pxTaskToSuspend Handle to the task being suspended. Passing a NULL
+ * handle will cause the calling task to be suspended.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to suspend the created task.
+ vTaskSuspend( xHandle );
+
+ // ...
+
+ // The created task will not run during this period, unless
+ // another task calls vTaskResume( xHandle ).
+
+ //...
+
+
+ // Suspend ourselves.
+ vTaskSuspend( NULL );
+
+ // We cannot get here unless another task calls vTaskResume
+ // with our handle as the parameter.
+ }
+ </pre>
+ * \defgroup vTaskSuspend vTaskSuspend
+ * \ingroup TaskCtrl
+ */
+ void vTaskSuspend(xTaskHandle pxTaskToSuspend) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void vTaskResume( xTaskHandle pxTaskToResume );</pre>
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Resumes a suspended task.
+ *
+ * A task that has been suspended by one of more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * vTaskResume ().
+ *
+ * @param pxTaskToResume Handle to the task being readied.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to suspend the created task.
+ vTaskSuspend( xHandle );
+
+ // ...
+
+ // The created task will not run during this period, unless
+ // another task calls vTaskResume( xHandle ).
+
+ //...
+
+
+ // Resume the suspended task ourselves.
+ vTaskResume( xHandle );
+
+ // The created task will once again get microcontroller processing
+ // time in accordance with it priority within the system.
+ }
+ </pre>
+ * \defgroup vTaskResume vTaskResume
+ * \ingroup TaskCtrl
+ */
+ void vTaskResume(xTaskHandle pxTaskToResume) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void xTaskResumeFromISR( xTaskHandle pxTaskToResume );</pre>
+ *
+ * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be
+ * available. See the configuration section for more information.
+ *
+ * An implementation of vTaskResume() that can be called from within an ISR.
+ *
+ * A task that has been suspended by one of more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * xTaskResumeFromISR ().
+ *
+ * @param pxTaskToResume Handle to the task being readied.
+ *
+ * \defgroup vTaskResumeFromISR vTaskResumeFromISR
+ * \ingroup TaskCtrl
+ */
+ portBASE_TYPE xTaskResumeFromISR(xTaskHandle pxTaskToResume) PRIVILEGED_FUNCTION;
+
+ /*-----------------------------------------------------------
+ * SCHEDULER CONTROL
+ *----------------------------------------------------------*/
+
+ /**
+ * task. h
+ * <pre>void vTaskStartScheduler( void );</pre>
+ *
+ * Starts the real time kernel tick processing. After calling the kernel
+ * has control over which tasks are executed and when. This function
+ * does not return until an executing task calls vTaskEndScheduler ().
+ *
+ * At least one task should be created via a call to xTaskCreate ()
+ * before calling vTaskStartScheduler (). The idle task is created
+ * automatically when the first application task is created.
+ *
+ * See the demo application file main.c for an example of creating
+ * tasks and starting the kernel.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ // Create at least one task before starting the kernel.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+ // Start the real time kernel with preemption.
+ vTaskStartScheduler ();
+
+ // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+ </pre>
+ *
+ * \defgroup vTaskStartScheduler vTaskStartScheduler
+ * \ingroup SchedulerControl
+ */
+ void vTaskStartScheduler(void) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void vTaskEndScheduler( void );</pre>
+ *
+ * Stops the real time kernel tick. All created tasks will be automatically
+ * deleted and multitasking (either preemptive or cooperative) will
+ * stop. Execution then resumes from the point where vTaskStartScheduler ()
+ * was called, as if vTaskStartScheduler () had just returned.
+ *
+ * See the demo application file main. c in the demo/PC directory for an
+ * example that uses vTaskEndScheduler ().
+ *
+ * vTaskEndScheduler () requires an exit function to be defined within the
+ * portable layer (see vPortEndScheduler () in port. c for the PC port). This
+ * performs hardware specific operations such as stopping the kernel tick.
+ *
+ * vTaskEndScheduler () will cause all of the resources allocated by the
+ * kernel to be freed - but will not free resources allocated by application
+ * tasks.
+ *
+ * Example usage:
+ <pre>
+ void vTaskCode( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // At some point we want to end the real time kernel processing
+ // so call ...
+ vTaskEndScheduler ();
+ }
+ }
+
+ void vAFunction( void )
+ {
+ // Create at least one task before starting the kernel.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+ // Start the real time kernel with preemption.
+ vTaskStartScheduler ();
+
+ // Will only get here when the vTaskCode () task has called
+ // vTaskEndScheduler (). When we get here we are back to single task
+ // execution.
+ }
+ </pre>
+ *
+ * \defgroup vTaskEndScheduler vTaskEndScheduler
+ * \ingroup SchedulerControl
+ */
+ void vTaskEndScheduler(void) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>void vTaskSuspendAll( void );</pre>
+ *
+ * Suspends all real time kernel activity while keeping interrupts (including the
+ * kernel tick) enabled.
+ *
+ * After calling vTaskSuspendAll () the calling task will continue to execute
+ * without risk of being swapped out until a call to xTaskResumeAll () has been
+ * made.
+ *
+ * API functions that have the potential to cause a context switch (for example,
+ * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler
+ * is suspended.
+ *
+ * Example usage:
+ <pre>
+ void vTask1( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // ...
+
+ // At some point the task wants to perform a long operation during
+ // which it does not want to get swapped out. It cannot use
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+ // operation may cause interrupts to be missed - including the
+ // ticks.
+
+ // Prevent the real time kernel swapping out the task.
+ vTaskSuspendAll ();
+
+ // Perform the operation here. There is no need to use critical
+ // sections as we have all the microcontroller processing time.
+ // During this time interrupts will still operate and the kernel
+ // tick count will be maintained.
+
+ // ...
+
+ // The operation is complete. Restart the kernel.
+ xTaskResumeAll ();
+ }
+ }
+ </pre>
+ * \defgroup vTaskSuspendAll vTaskSuspendAll
+ * \ingroup SchedulerControl
+ */
+ void vTaskSuspendAll(void) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>char xTaskResumeAll( void );</pre>
+ *
+ * Resumes real time kernel activity following a call to vTaskSuspendAll ().
+ * After a call to vTaskSuspendAll () the kernel will take control of which
+ * task is executing at any time.
+ *
+ * @return If resuming the scheduler caused a context switch then pdTRUE is
+ * returned, otherwise pdFALSE is returned.
+ *
+ * Example usage:
+ <pre>
+ void vTask1( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // ...
+
+ // At some point the task wants to perform a long operation during
+ // which it does not want to get swapped out. It cannot use
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+ // operation may cause interrupts to be missed - including the
+ // ticks.
+
+ // Prevent the real time kernel swapping out the task.
+ vTaskSuspendAll ();
+
+ // Perform the operation here. There is no need to use critical
+ // sections as we have all the microcontroller processing time.
+ // During this time interrupts will still operate and the real
+ // time kernel tick count will be maintained.
+
+ // ...
+
+ // The operation is complete. Restart the kernel. We want to force
+ // a context switch - but there is no point if resuming the scheduler
+ // caused a context switch already.
+ if( !xTaskResumeAll () )
+ {
+ taskYIELD ();
+ }
+ }
+ }
+ </pre>
+ * \defgroup xTaskResumeAll xTaskResumeAll
+ * \ingroup SchedulerControl
+ */
+ signed portBASE_TYPE xTaskResumeAll(void) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <pre>signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );</pre>
+ *
+ * Utility task that simply returns pdTRUE if the task referenced by xTask is
+ * currently in the Suspended state, or pdFALSE if the task referenced by xTask
+ * is in any other state.
+ *
+ */
+ signed portBASE_TYPE xTaskIsTaskSuspended(xTaskHandle xTask) PRIVILEGED_FUNCTION;
+
+ /*-----------------------------------------------------------
+ * TASK UTILITIES
+ *----------------------------------------------------------*/
+
+ /**
+ * task. h
+ * <PRE>volatile portTickType xTaskGetTickCount( void );</PRE>
+ *
+ * @return The count of ticks since vTaskStartScheduler was called.
+ *
+ * \page xTaskGetTickCount xTaskGetTickCount
+ * \ingroup TaskUtils
+ */
+ portTickType xTaskGetTickCount(void) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <PRE>unsigned short uxTaskGetNumberOfTasks( void );</PRE>
+ *
+ * @return The number of tasks that the real time kernel is currently managing.
+ * This includes all ready, blocked and suspended tasks. A task that
+ * has been deleted but not yet freed by the idle task will also be
+ * included in the count.
+ *
+ * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks
+ * \ingroup TaskUtils
+ */
+ unsigned portBASE_TYPE uxTaskGetNumberOfTasks(void) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <PRE>void vTaskList( char *pcWriteBuffer );</PRE>
+ *
+ * configUSE_TRACE_FACILITY must be defined as 1 for this function to be
+ * available. See the configuration section for more information.
+ *
+ * NOTE: This function will disable interrupts for its duration. It is
+ * not intended for normal application runtime use but as a debug aid.
+ *
+ * Lists all the current tasks, along with their current state and stack
+ * usage high water mark.
+ *
+ * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
+ * suspended ('S').
+ *
+ * @param pcWriteBuffer A buffer into which the above mentioned details
+ * will be written, in ascii form. This buffer is assumed to be large
+ * enough to contain the generated report. Approximately 40 bytes per
+ * task should be sufficient.
+ *
+ * \page vTaskList vTaskList
+ * \ingroup TaskUtils
+ */
+ void vTaskList(signed char *pcWriteBuffer) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <PRE>void vTaskGetRunTimeStats( char *pcWriteBuffer );</PRE>
+ *
+ * configGENERATE_RUN_TIME_STATS must be defined as 1 for this function
+ * to be available. The application must also then provide definitions
+ * for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and
+ * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter
+ * and return the timers current count value respectively. The counter
+ * should be at least 10 times the frequency of the tick count.
+ *
+ * NOTE: This function will disable interrupts for its duration. It is
+ * not intended for normal application runtime use but as a debug aid.
+ *
+ * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
+ * accumulated execution time being stored for each task. The resolution
+ * of the accumulated time value depends on the frequency of the timer
+ * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
+ * Calling vTaskGetRunTimeStats() writes the total execution time of each
+ * task into a buffer, both as an absolute count value and as a percentage
+ * of the total system execution time.
+ *
+ * @param pcWriteBuffer A buffer into which the execution times will be
+ * written, in ascii form. This buffer is assumed to be large enough to
+ * contain the generated report. Approximately 40 bytes per task should
+ * be sufficient.
+ *
+ * \page vTaskGetRunTimeStats vTaskGetRunTimeStats
+ * \ingroup TaskUtils
+ */
+ void vTaskGetRunTimeStats(signed char *pcWriteBuffer) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <PRE>void vTaskStartTrace( char * pcBuffer, unsigned portBASE_TYPE uxBufferSize );</PRE>
+ *
+ * Starts a real time kernel activity trace. The trace logs the identity of
+ * which task is running when.
+ *
+ * The trace file is stored in binary format. A separate DOS utility called
+ * convtrce.exe is used to convert this into a tab delimited text file which
+ * can be viewed and plotted in a spread sheet.
+ *
+ * @param pcBuffer The buffer into which the trace will be written.
+ *
+ * @param ulBufferSize The size of pcBuffer in bytes. The trace will continue
+ * until either the buffer in full, or ulTaskEndTrace () is called.
+ *
+ * \page vTaskStartTrace vTaskStartTrace
+ * \ingroup TaskUtils
+ */
+ void vTaskStartTrace(signed char * pcBuffer, unsigned long ulBufferSize) PRIVILEGED_FUNCTION;
+
+ /**
+ * task. h
+ * <PRE>unsigned long ulTaskEndTrace( void );</PRE>
+ *
+ * Stops a kernel activity trace. See vTaskStartTrace ().
+ *
+ * @return The number of bytes that have been written into the trace buffer.
+ *
+ * \page usTaskEndTrace usTaskEndTrace
+ * \ingroup TaskUtils
+ */
+ unsigned long ulTaskEndTrace(void) PRIVILEGED_FUNCTION;
+
+ /**
+ * task.h
+ * <PRE>unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );</PRE>
+ *
+ * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for
+ * this function to be available.
+ *
+ * Returns the high water mark of the stack associated with xTask. That is,
+ * the minimum free stack space there has been (in bytes) since the task
+ * started. The smaller the returned number the closer the task has come
+ * to overflowing its stack.
+ *
+ * @param xTask Handle of the task associated with the stack to be checked.
+ * Set xTask to NULL to check the stack of the calling task.
+ *
+ * @return The smallest amount of free stack space there has been (in bytes)
+ * since the task referenced by xTask was created.
+ */
+ unsigned portBASE_TYPE uxTaskGetStackHighWaterMark(xTaskHandle xTask) PRIVILEGED_FUNCTION;
+
+ /**
+ * task.h
+ * <pre>void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>
+ *
+ * Sets pxHookFunction to be the task hook function used by the task xTask.
+ * Passing xTask as NULL has the effect of setting the calling tasks hook
+ * function.
+ */
+ void vTaskSetApplicationTaskTag(xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction) PRIVILEGED_FUNCTION;
+
+ /**
+ * task.h
+ * <pre>void xTaskGetApplicationTaskTag( xTaskHandle xTask );</pre>
+ *
+ * Returns the pxHookFunction value assigned to the task xTask.
+ */
+ pdTASK_HOOK_CODE xTaskGetApplicationTaskTag(xTaskHandle xTask) PRIVILEGED_FUNCTION;
+
+ /**
+ * task.h
+ * <pre>portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>
+ *
+ * Calls the hook function associated with xTask. Passing xTask as NULL has
+ * the effect of calling the Running tasks (the calling task) hook function.
+ *
+ * pvParameter is passed to the hook function for the task to interpret as it
+ * wants.
+ */
+ portBASE_TYPE xTaskCallApplicationTaskHook(xTaskHandle xTask, void *pvParameter) PRIVILEGED_FUNCTION;
+
+
+ /*-----------------------------------------------------------
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
+ *----------------------------------------------------------*/
+
+ /*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Called from the real time kernel tick (either preemptive or cooperative),
+ * this increments the tick count and checks if any tasks that are blocked
+ * for a finite period required removing from a blocked list and placing on
+ * a ready list.
+ */
+ void vTaskIncrementTick(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes the calling task from the ready list and places it both
+ * on the list of tasks waiting for a particular event, and the
+ * list of delayed tasks. The task will be removed from both lists
+ * and replaced on the ready list should either the event occur (and
+ * there be no higher priority tasks waiting on the same event) or
+ * the delay period expires.
+ *
+ * @param pxEventList The list containing tasks that are blocked waiting
+ * for the event to occur.
+ *
+ * @param xTicksToWait The maximum amount of time that the task should wait
+ * for the event to occur. This is specified in kernel ticks,the constant
+ * portTICK_RATE_MS can be used to convert kernel ticks into a real time
+ * period.
+ */
+ void vTaskPlaceOnEventList(const xList * const pxEventList, portTickType xTicksToWait) PRIVILEGED_FUNCTION;
+
+ /*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes a task from both the specified event list and the list of blocked
+ * tasks, and places it on a ready queue.
+ *
+ * xTaskRemoveFromEventList () will be called if either an event occurs to
+ * unblock a task, or the block timeout period expires.
+ *
+ * @return pdTRUE if the task being removed has a higher priority than the task
+ * making the call, otherwise pdFALSE.
+ */
+ signed portBASE_TYPE xTaskRemoveFromEventList(const xList * const pxEventList) PRIVILEGED_FUNCTION;
+
+ /*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * INCLUDE_vTaskCleanUpResources and INCLUDE_vTaskSuspend must be defined as 1
+ * for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Empties the ready and delayed queues of task control blocks, freeing the
+ * memory allocated for the task control block and task stacks as it goes.
+ */
+ void vTaskCleanUpResources(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Sets the pointer to the current TCB to the TCB of the highest priority task
+ * that is ready to run.
+ */
+ void vTaskSwitchContext(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * Return the handle of the calling task.
+ */
+ xTaskHandle xTaskGetCurrentTaskHandle(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * Capture the current time status for future reference.
+ */
+ void vTaskSetTimeOutState(xTimeOutType * const pxTimeOut) PRIVILEGED_FUNCTION;
+
+ /*
+ * Compare the time status now with that previously captured to see if the
+ * timeout has expired.
+ */
+ portBASE_TYPE xTaskCheckForTimeOut(xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait) PRIVILEGED_FUNCTION;
+
+ /*
+ * Shortcut used by the queue implementation to prevent unnecessary call to
+ * taskYIELD();
+ */
+ void vTaskMissedYield(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * Returns the scheduler state as taskSCHEDULER_RUNNING,
+ * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.
+ */
+ portBASE_TYPE xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION;
+
+ /*
+ * Raises the priority of the mutex holder to that of the calling task should
+ * the mutex holder have a priority less than the calling task.
+ */
+ void vTaskPriorityInherit(xTaskHandle * const pxMutexHolder) PRIVILEGED_FUNCTION;
+
+ /*
+ * Set the priority of a task back to its proper priority in the case that it
+ * inherited a higher priority while it was holding a semaphore.
+ */
+ void vTaskPriorityDisinherit(xTaskHandle * const pxMutexHolder) PRIVILEGED_FUNCTION;
+
+ /*
+ * Generic version of the task creation function which is in turn called by the
+ * xTaskCreate() and xTaskCreateRestricted() macros.
+ */
+ signed portBASE_TYPE xTaskGenericCreate(pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions) PRIVILEGED_FUNCTION;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* TASK_H */
+
+
+
diff --git a/gyro_board/src/usb/FreeRTOS/list.c b/gyro_board/src/usb/FreeRTOS/list.c
new file mode 100644
index 0000000..0b88791
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/list.c
@@ -0,0 +1,186 @@
+/*
+ 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.
+*/
+
+
+#include <stdlib.h>
+#include "FreeRTOS.h"
+#include "list.h"
+
+/*-----------------------------------------------------------
+ * PUBLIC LIST API documented in list.h
+ *----------------------------------------------------------*/
+
+void vListInitialise(xList *pxList)
+{
+ /* The list structure contains a list item which is used to mark the
+ end of the list. To initialise the list the list end is inserted
+ as the only list entry. */
+ pxList->pxIndex = (xListItem *) & (pxList->xListEnd);
+
+ /* The list end value is the highest possible value in the list to
+ ensure it remains at the end of the list. */
+ pxList->xListEnd.xItemValue = portMAX_DELAY;
+
+ /* The list end next and previous pointers point to itself so we know
+ when the list is empty. */
+ pxList->xListEnd.pxNext = (xListItem *) & (pxList->xListEnd);
+ pxList->xListEnd.pxPrevious = (xListItem *) & (pxList->xListEnd);
+
+ pxList->uxNumberOfItems = 0;
+}
+/*-----------------------------------------------------------*/
+
+void vListInitialiseItem(xListItem *pxItem)
+{
+ /* Make sure the list item is not recorded as being on a list. */
+ pxItem->pvContainer = NULL;
+}
+/*-----------------------------------------------------------*/
+
+void vListInsertEnd(xList *pxList, xListItem *pxNewListItem)
+{
+ volatile xListItem * pxIndex;
+
+ /* Insert a new list item into pxList, but rather than sort the list,
+ makes the new list item the last item to be removed by a call to
+ pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by
+ the pxIndex member. */
+ pxIndex = pxList->pxIndex;
+
+ pxNewListItem->pxNext = pxIndex->pxNext;
+ pxNewListItem->pxPrevious = pxList->pxIndex;
+ pxIndex->pxNext->pxPrevious = (volatile xListItem *) pxNewListItem;
+ pxIndex->pxNext = (volatile xListItem *) pxNewListItem;
+ pxList->pxIndex = (volatile xListItem *) pxNewListItem;
+
+ /* Remember which list the item is in. */
+ pxNewListItem->pvContainer = (void *) pxList;
+
+ (pxList->uxNumberOfItems)++;
+}
+/*-----------------------------------------------------------*/
+
+void vListInsert(xList *pxList, xListItem *pxNewListItem)
+{
+ volatile xListItem *pxIterator;
+ portTickType xValueOfInsertion;
+
+ /* Insert the new list item into the list, sorted in ulListItem order. */
+ xValueOfInsertion = pxNewListItem->xItemValue;
+
+ /* If the list already contains a list item with the same item value then
+ the new list item should be placed after it. This ensures that TCB's which
+ are stored in ready lists (all of which have the same ulListItem value)
+ get an equal share of the CPU. However, if the xItemValue is the same as
+ the back marker the iteration loop below will not end. This means we need
+ to guard against this by checking the value first and modifying the
+ algorithm slightly if necessary. */
+ if (xValueOfInsertion == portMAX_DELAY) {
+ pxIterator = pxList->xListEnd.pxPrevious;
+ } else {
+ /* *** NOTE ***********************************************************
+ If you find your application is crashing here then likely causes are:
+ 1) Stack overflow -
+ see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
+ 2) Incorrect interrupt priority assignment, especially on Cortex M3
+ parts where numerically high priority values denote low actual
+ interrupt priories, which can seem counter intuitive. See
+ configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
+ 3) Calling an API function from within a critical section or when
+ the scheduler is suspended.
+ 4) Using a queue or semaphore before it has been initialised or
+ before the scheduler has been started (are interrupts firing
+ before vTaskStartScheduler() has been called?).
+ See http://www.freertos.org/FAQHelp.html for more tips.
+ **********************************************************************/
+
+ for (pxIterator = (xListItem *) & (pxList->xListEnd); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext) {
+ /* There is nothing to do here, we are just iterating to the
+ wanted insertion position. */
+ }
+ }
+
+ pxNewListItem->pxNext = pxIterator->pxNext;
+ pxNewListItem->pxNext->pxPrevious = (volatile xListItem *) pxNewListItem;
+ pxNewListItem->pxPrevious = pxIterator;
+ pxIterator->pxNext = (volatile xListItem *) pxNewListItem;
+
+ /* Remember which list the item is in. This allows fast removal of the
+ item later. */
+ pxNewListItem->pvContainer = (void *) pxList;
+
+ (pxList->uxNumberOfItems)++;
+}
+/*-----------------------------------------------------------*/
+
+void vListRemove(xListItem *pxItemToRemove)
+{
+ xList * pxList;
+
+ pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
+ pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
+
+ /* The list item knows which list it is in. Obtain the list from the list
+ item. */
+ pxList = (xList *) pxItemToRemove->pvContainer;
+
+ /* Make sure the index is left pointing to a valid item. */
+ if (pxList->pxIndex == pxItemToRemove) {
+ pxList->pxIndex = pxItemToRemove->pxPrevious;
+ }
+
+ pxItemToRemove->pvContainer = NULL;
+ (pxList->uxNumberOfItems)--;
+}
+/*-----------------------------------------------------------*/
+
diff --git a/gyro_board/src/usb/FreeRTOS/portable/GCC/ARM_CM3/port.c b/gyro_board/src/usb/FreeRTOS/portable/GCC/ARM_CM3/port.c
new file mode 100644
index 0000000..fb55c72
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/portable/GCC/ARM_CM3/port.c
@@ -0,0 +1,280 @@
+/*
+ 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.
+*/
+
+/*-----------------------------------------------------------
+ * Implementation of functions defined in portable.h for the ARM CM3 port.
+ *----------------------------------------------------------*/
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
+defined. The value should also ensure backward compatibility.
+FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
+#ifndef configKERNEL_INTERRUPT_PRIORITY
+#define configKERNEL_INTERRUPT_PRIORITY 255
+#endif
+
+/* Constants required to manipulate the NVIC. */
+#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )
+#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )
+#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
+#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )
+#define portNVIC_SYSTICK_CLK 0x00000004
+#define portNVIC_SYSTICK_INT 0x00000002
+#define portNVIC_SYSTICK_ENABLE 0x00000001
+#define portNVIC_PENDSVSET 0x10000000
+#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16 )
+#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
+
+/* Constants required to set up the initial stack. */
+#define portINITIAL_XPSR ( 0x01000000 )
+
+/* The priority used by the kernel is assigned to a variable to make access
+from inline assembler easier. */
+const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
+
+/* Each task maintains its own interrupt status in the critical nesting
+variable. */
+static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
+
+/*
+ * Setup the timer to generate the tick interrupts.
+ */
+static void prvSetupTimerInterrupt(void);
+
+/*
+ * Exception handlers.
+ */
+void xPortPendSVHandler(void) __attribute__((naked));
+void xPortSysTickHandler(void);
+void vPortSVCHandler(void) __attribute__((naked));
+
+/*
+ * Start first task is a separate function so it can be tested in isolation.
+ */
+void vPortStartFirstTask(void) __attribute__((naked));
+
+/*-----------------------------------------------------------*/
+
+/*
+ * See header file for description.
+ */
+portSTACK_TYPE *pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters)
+{
+ /* Simulate the stack frame as it would be created by a context switch
+ interrupt. */
+ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
+ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) pxCode; /* PC */
+ pxTopOfStack--;
+ *pxTopOfStack = 0; /* LR */
+ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
+ *pxTopOfStack = (portSTACK_TYPE) pvParameters; /* R0 */
+ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
+
+ return pxTopOfStack;
+}
+/*-----------------------------------------------------------*/
+
+void vPortSVCHandler(void)
+{
+ __asm volatile(
+ " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
+ " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
+ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
+ " ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
+ " msr psp, r0 \n" /* Restore the task stack pointer. */
+ " mov r0, #0 \n"
+ " msr basepri, r0 \n"
+ " orr r14, #0xd \n"
+ " bx r14 \n"
+ " \n"
+ " .align 2 \n"
+ "pxCurrentTCBConst2: .word pxCurrentTCB \n"
+ );
+}
+/*-----------------------------------------------------------*/
+
+void vPortStartFirstTask(void)
+{
+ __asm volatile(
+ " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
+ " ldr r0, [r0] \n"
+ " ldr r0, [r0] \n"
+ " msr msp, r0 \n" /* Set the msp back to the start of the stack. */
+ " svc 0 \n" /* System call to start first task. */
+ );
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * See header file for description.
+ */
+portBASE_TYPE xPortStartScheduler(void)
+{
+ /* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
+ *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
+ *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
+
+ /* Start the timer that generates the tick ISR. Interrupts are disabled
+ here already. */
+ prvSetupTimerInterrupt();
+
+ /* Initialise the critical nesting count ready for the first task. */
+ uxCriticalNesting = 0;
+
+ /* Start the first task. */
+ vPortStartFirstTask();
+
+ /* Should not get here! */
+ return 0;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEndScheduler(void)
+{
+ /* It is unlikely that the CM3 port will require this function as there
+ is nothing to return to. */
+}
+/*-----------------------------------------------------------*/
+
+void vPortYieldFromISR(void)
+{
+ /* Set a PendSV to request a context switch. */
+ *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEnterCritical(void)
+{
+ portDISABLE_INTERRUPTS();
+ uxCriticalNesting++;
+}
+/*-----------------------------------------------------------*/
+
+void vPortExitCritical(void)
+{
+ uxCriticalNesting--;
+ if (uxCriticalNesting == 0) {
+ portENABLE_INTERRUPTS();
+ }
+}
+/*-----------------------------------------------------------*/
+
+void xPortPendSVHandler(void)
+{
+ /* This is a naked function. */
+
+ __asm volatile
+ (
+ " mrs r0, psp \n"
+ " \n"
+ " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
+ " ldr r2, [r3] \n"
+ " \n"
+ " stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */
+ " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
+ " \n"
+ " stmdb sp!, {r3, r14} \n"
+ " mov r0, %0 \n"
+ " msr basepri, r0 \n"
+ " bl vTaskSwitchContext \n"
+ " mov r0, #0 \n"
+ " msr basepri, r0 \n"
+ " ldmia sp!, {r3, r14} \n"
+ " \n" /* Restore the context, including the critical nesting count. */
+ " ldr r1, [r3] \n"
+ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
+ " ldmia r0!, {r4-r11} \n" /* Pop the registers. */
+ " msr psp, r0 \n"
+ " bx r14 \n"
+ " \n"
+ " .align 2 \n"
+ "pxCurrentTCBConst: .word pxCurrentTCB \n"
+ ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
+ );
+}
+/*-----------------------------------------------------------*/
+
+void xPortSysTickHandler(void)
+{
+ unsigned long ulDummy;
+
+ /* If using preemption, also force a context switch. */
+#if configUSE_PREEMPTION == 1
+ *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
+#endif
+
+ ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
+ {
+ vTaskIncrementTick();
+ }
+ portCLEAR_INTERRUPT_MASK_FROM_ISR(ulDummy);
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Setup the systick timer to generate the tick interrupts at the required
+ * frequency.
+ */
+void prvSetupTimerInterrupt(void)
+{
+ /* Configure SysTick to interrupt at the requested rate. */
+ *(portNVIC_SYSTICK_LOAD) = (configCPU_CLOCK_HZ / configTICK_RATE_HZ) - 1UL;
+ *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
+}
+/*-----------------------------------------------------------*/
+
diff --git a/gyro_board/src/usb/FreeRTOS/portable/GCC/ARM_CM3/portmacro.h b/gyro_board/src/usb/FreeRTOS/portable/GCC/ARM_CM3/portmacro.h
new file mode 100644
index 0000000..35c57ac
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/portable/GCC/ARM_CM3/portmacro.h
@@ -0,0 +1,157 @@
+/*
+ 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.
+*/
+
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /*-----------------------------------------------------------
+ * Port specific definitions.
+ *
+ * The settings in this file configure FreeRTOS correctly for the
+ * given hardware and compiler.
+ *
+ * These settings should not be altered.
+ *-----------------------------------------------------------
+ */
+
+ /* Type definitions. */
+#define portCHAR char
+#define portFLOAT float
+#define portDOUBLE double
+#define portLONG long
+#define portSHORT short
+#define portSTACK_TYPE unsigned portLONG
+#define portBASE_TYPE long
+
+#if( configUSE_16_BIT_TICKS == 1 )
+ typedef unsigned portSHORT portTickType;
+#define portMAX_DELAY ( portTickType ) 0xffff
+#else
+ typedef unsigned portLONG portTickType;
+#define portMAX_DELAY ( portTickType ) 0xffffffff
+#endif
+ /*-----------------------------------------------------------*/
+
+ /* Architecture specifics. */
+#define portSTACK_GROWTH ( -1 )
+#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
+#define portBYTE_ALIGNMENT 8
+ /*-----------------------------------------------------------*/
+
+
+ /* Scheduler utilities. */
+ extern void vPortYieldFromISR(void);
+
+#define portYIELD() vPortYieldFromISR()
+
+#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
+ /*-----------------------------------------------------------*/
+
+
+ /* Critical section management. */
+
+ /*
+ * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other
+ * registers. r0 is clobbered.
+ */
+#define portSET_INTERRUPT_MASK() \
+ __asm volatile \
+ ( \
+ " mov r0, %0 \n" \
+ " msr basepri, r0 \n" \
+ ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0" \
+ )
+
+ /*
+ * Set basepri back to 0 without effective other registers.
+ * r0 is clobbered.
+ */
+#define portCLEAR_INTERRUPT_MASK() \
+ __asm volatile \
+ ( \
+ " mov r0, #0 \n" \
+ " msr basepri, r0 \n" \
+ :::"r0" \
+ )
+
+#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
+
+
+ extern void vPortEnterCritical(void);
+ extern void vPortExitCritical(void);
+
+#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
+#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
+#define portENTER_CRITICAL() vPortEnterCritical()
+#define portEXIT_CRITICAL() vPortExitCritical()
+ /*-----------------------------------------------------------*/
+
+ /* Task function macros as described on the FreeRTOS.org WEB site. */
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
+
+#define portNOP()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PORTMACRO_H */
+
diff --git a/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_1.c b/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_1.c
new file mode 100644
index 0000000..5ccda33
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_1.c
@@ -0,0 +1,152 @@
+/*
+ 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.
+*/
+
+
+/*
+ * The simplest possible implementation of pvPortMalloc(). Note that this
+ * implementation does NOT allow allocated memory to be freed again.
+ *
+ * See heap_2.c and heap_3.c for alternative implementations, and the memory
+ * management pages of http://www.FreeRTOS.org for more information.
+ */
+#include <stdlib.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers. That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+/* Allocate the memory for the heap. The struct is used to force byte
+alignment without using any non-portable code. */
+static union xRTOS_HEAP
+{
+ #if portBYTE_ALIGNMENT == 8
+ volatile portDOUBLE dDummy;
+ #else
+ volatile unsigned long ulDummy;
+ #endif
+ unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
+} xHeap;
+
+static size_t xNextFreeByte = ( size_t ) 0;
+/*-----------------------------------------------------------*/
+
+void *pvPortMalloc( size_t xWantedSize )
+{
+void *pvReturn = NULL;
+
+ /* Ensure that blocks are always aligned to the required number of bytes. */
+ #if portBYTE_ALIGNMENT != 1
+ if( xWantedSize & portBYTE_ALIGNMENT_MASK )
+ {
+ /* Byte alignment required. */
+ xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
+ }
+ #endif
+
+ vTaskSuspendAll();
+ {
+ /* Check there is enough room left for the allocation. */
+ if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) &&
+ ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
+ {
+ /* Return the next free byte then increment the index past this
+ block. */
+ pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] );
+ xNextFreeByte += xWantedSize;
+ }
+ }
+ xTaskResumeAll();
+
+ #if( configUSE_MALLOC_FAILED_HOOK == 1 )
+ {
+ if( pvReturn == NULL )
+ {
+ extern void vApplicationMallocFailedHook( void );
+ vApplicationMallocFailedHook();
+ }
+ }
+ #endif
+
+ return pvReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vPortFree( void *pv )
+{
+ /* Memory cannot be freed using this scheme. See heap_2.c and heap_3.c
+ for alternative implementations, and the memory management pages of
+ http://www.FreeRTOS.org for more information. */
+ ( void ) pv;
+}
+/*-----------------------------------------------------------*/
+
+void vPortInitialiseBlocks( void )
+{
+ /* Only required when static memory is not cleared. */
+ xNextFreeByte = ( size_t ) 0;
+}
+/*-----------------------------------------------------------*/
+
+size_t xPortGetFreeHeapSize( void )
+{
+ return ( configTOTAL_HEAP_SIZE - xNextFreeByte );
+}
+
+
+
diff --git a/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_2.c b/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_2.c
new file mode 100644
index 0000000..77e13b8
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_2.c
@@ -0,0 +1,278 @@
+/*
+ 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.
+*/
+
+/*
+ * A sample implementation of pvPortMalloc() and vPortFree() that permits
+ * allocated blocks to be freed, but does not combine adjacent free blocks
+ * into a single larger block.
+ *
+ * See heap_1.c and heap_3.c for alternative implementations, and the memory
+ * management pages of http://www.FreeRTOS.org for more information.
+ */
+#include <stdlib.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers. That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+/* Allocate the memory for the heap. The struct is used to force byte
+alignment without using any non-portable code. */
+static union xRTOS_HEAP
+{
+ #if portBYTE_ALIGNMENT == 8
+ volatile portDOUBLE dDummy;
+ #else
+ volatile unsigned long ulDummy;
+ #endif
+ unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
+} xHeap;
+
+/* Define the linked list structure. This is used to link free blocks in order
+of their size. */
+typedef struct A_BLOCK_LINK
+{
+ struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
+ size_t xBlockSize; /*<< The size of the free block. */
+} xBlockLink;
+
+
+static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );
+#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
+
+/* Create a couple of list links to mark the start and end of the list. */
+static xBlockLink xStart, xEnd;
+
+/* Keeps track of the number of free bytes remaining, but says nothing about
+fragmentation. */
+static size_t xFreeBytesRemaining = configTOTAL_HEAP_SIZE;
+
+/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
+
+/*
+ * Insert a block into the list of free blocks - which is ordered by size of
+ * the block. Small blocks at the start of the list and large blocks at the end
+ * of the list.
+ */
+#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \
+{ \
+xBlockLink *pxIterator; \
+size_t xBlockSize; \
+ \
+ xBlockSize = pxBlockToInsert->xBlockSize; \
+ \
+ /* Iterate through the list until a block is found that has a larger size */ \
+ /* than the block we are inserting. */ \
+ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
+ { \
+ /* There is nothing to do here - just iterate to the correct position. */ \
+ } \
+ \
+ /* Update the list to include the block being inserted in the correct */ \
+ /* position. */ \
+ pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \
+ pxIterator->pxNextFreeBlock = pxBlockToInsert; \
+}
+/*-----------------------------------------------------------*/
+
+#define prvHeapInit() \
+{ \
+xBlockLink *pxFirstFreeBlock; \
+ \
+ /* xStart is used to hold a pointer to the first item in the list of free */ \
+ /* blocks. The void cast is used to prevent compiler warnings. */ \
+ xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; \
+ xStart.xBlockSize = ( size_t ) 0; \
+ \
+ /* xEnd is used to mark the end of the list of free blocks. */ \
+ xEnd.xBlockSize = configTOTAL_HEAP_SIZE; \
+ xEnd.pxNextFreeBlock = NULL; \
+ \
+ /* To start with there is a single free block that is sized to take up the \
+ entire heap space. */ \
+ pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \
+ pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \
+ pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \
+}
+/*-----------------------------------------------------------*/
+
+void *pvPortMalloc( size_t xWantedSize )
+{
+xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
+static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE;
+void *pvReturn = NULL;
+
+ vTaskSuspendAll();
+ {
+ /* If this is the first call to malloc then the heap will require
+ initialisation to setup the list of free blocks. */
+ if( xHeapHasBeenInitialised == pdFALSE )
+ {
+ prvHeapInit();
+ xHeapHasBeenInitialised = pdTRUE;
+ }
+
+ /* The wanted size is increased so it can contain a xBlockLink
+ structure in addition to the requested amount of bytes. */
+ if( xWantedSize > 0 )
+ {
+ xWantedSize += heapSTRUCT_SIZE;
+
+ /* Ensure that blocks are always aligned to the required number of bytes. */
+ if( xWantedSize & portBYTE_ALIGNMENT_MASK )
+ {
+ /* Byte alignment required. */
+ xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
+ }
+ }
+
+ if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) )
+ {
+ /* Blocks are stored in byte order - traverse the list from the start
+ (smallest) block until one of adequate size is found. */
+ pxPreviousBlock = &xStart;
+ pxBlock = xStart.pxNextFreeBlock;
+ while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) )
+ {
+ pxPreviousBlock = pxBlock;
+ pxBlock = pxBlock->pxNextFreeBlock;
+ }
+
+ /* If we found the end marker then a block of adequate size was not found. */
+ if( pxBlock != &xEnd )
+ {
+ /* Return the memory space - jumping over the xBlockLink structure
+ at its start. */
+ pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
+
+ /* This block is being returned for use so must be taken our of the
+ list of free blocks. */
+ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
+
+ /* If the block is larger than required it can be split into two. */
+ if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
+ {
+ /* This block is to be split into two. Create a new block
+ following the number of bytes requested. The void cast is
+ used to prevent byte alignment warnings from the compiler. */
+ pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize );
+
+ /* Calculate the sizes of two blocks split from the single
+ block. */
+ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
+ pxBlock->xBlockSize = xWantedSize;
+
+ /* Insert the new block into the list of free blocks. */
+ prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
+ }
+
+ xFreeBytesRemaining -= xWantedSize;
+ }
+ }
+ }
+ xTaskResumeAll();
+
+ #if( configUSE_MALLOC_FAILED_HOOK == 1 )
+ {
+ if( pvReturn == NULL )
+ {
+ extern void vApplicationMallocFailedHook( void );
+ vApplicationMallocFailedHook();
+ }
+ }
+ #endif
+
+ return pvReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vPortFree( void *pv )
+{
+unsigned char *puc = ( unsigned char * ) pv;
+xBlockLink *pxLink;
+
+ if( pv )
+ {
+ /* The memory being freed will have an xBlockLink structure immediately
+ before it. */
+ puc -= heapSTRUCT_SIZE;
+
+ /* This casting is to keep the compiler from issuing warnings. */
+ pxLink = ( void * ) puc;
+
+ vTaskSuspendAll();
+ {
+ /* Add this block to the list of free blocks. */
+ prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) );
+ xFreeBytesRemaining += pxLink->xBlockSize;
+ }
+ xTaskResumeAll();
+ }
+}
+/*-----------------------------------------------------------*/
+
+size_t xPortGetFreeHeapSize( void )
+{
+ return xFreeBytesRemaining;
+}
+/*-----------------------------------------------------------*/
+
+void vPortInitialiseBlocks( void )
+{
+ /* This just exists to keep the linker quiet. */
+}
diff --git a/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_3.c b/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_3.c
new file mode 100644
index 0000000..643f750
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/portable/MemMang/heap_3.c
@@ -0,0 +1,117 @@
+/*
+ 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.
+*/
+
+
+/*
+ * Implementation of pvPortMalloc() and vPortFree() that relies on the
+ * compilers own malloc() and free() implementations.
+ *
+ * This file can only be used if the linker is configured to to generate
+ * a heap memory area.
+ *
+ * See heap_2.c and heap_1.c for alternative implementations, and the memory
+ * management pages of http://www.FreeRTOS.org for more information.
+ */
+
+#include <stdlib.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers. That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+/*-----------------------------------------------------------*/
+
+void *pvPortMalloc( size_t xWantedSize )
+{
+void *pvReturn;
+
+ vTaskSuspendAll();
+ {
+ pvReturn = malloc( xWantedSize );
+ }
+ xTaskResumeAll();
+
+ #if( configUSE_MALLOC_FAILED_HOOK == 1 )
+ {
+ if( pvReturn == NULL )
+ {
+ extern void vApplicationMallocFailedHook( void );
+ vApplicationMallocFailedHook();
+ }
+ }
+ #endif
+
+ return pvReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vPortFree( void *pv )
+{
+ if( pv )
+ {
+ vTaskSuspendAll();
+ {
+ free( pv );
+ }
+ xTaskResumeAll();
+ }
+}
+
+
+
diff --git a/gyro_board/src/usb/FreeRTOS/queue.c b/gyro_board/src/usb/FreeRTOS/queue.c
new file mode 100644
index 0000000..acd6119
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/queue.c
@@ -0,0 +1,1302 @@
+/*
+ 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.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers. That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "croutine.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+/*-----------------------------------------------------------
+ * PUBLIC LIST API documented in list.h
+ *----------------------------------------------------------*/
+
+/* Constants used with the cRxLock and cTxLock structure members. */
+#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
+#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )
+
+#define queueERRONEOUS_UNBLOCK ( -1 )
+
+/* For internal use only. */
+#define queueSEND_TO_BACK ( 0 )
+#define queueSEND_TO_FRONT ( 1 )
+
+/* Effectively make a union out of the xQUEUE structure. */
+#define pxMutexHolder pcTail
+#define uxQueueType pcHead
+#define uxRecursiveCallCount pcReadFrom
+#define queueQUEUE_IS_MUTEX NULL
+
+/* Semaphores do not actually store or copy data, so have an items size of
+zero. */
+#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )
+#define queueDONT_BLOCK ( ( portTickType ) 0 )
+#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 )
+
+/*
+ * Definition of the queue used by the scheduler.
+ * Items are queued by copy, not reference.
+ */
+typedef struct QueueDefinition {
+ signed char *pcHead; /*< Points to the beginning of the queue storage area. */
+ signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
+
+ signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
+ signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
+
+ xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
+ xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
+
+ volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
+ unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
+ unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */
+
+ signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
+ signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
+
+} xQUEUE;
+/*-----------------------------------------------------------*/
+
+/*
+ * Inside this file xQueueHandle is a pointer to a xQUEUE structure.
+ * To keep the definition private the API header file defines it as a
+ * pointer to void.
+ */
+typedef xQUEUE * xQueueHandle;
+
+/*
+ * Prototypes for public functions are included here so we don't have to
+ * include the API header file (as it defines xQueueHandle differently). These
+ * functions are documented in the API header file.
+ */
+xQueueHandle xQueueCreate(unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueGenericSend(xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition) PRIVILEGED_FUNCTION;
+unsigned portBASE_TYPE uxQueueMessagesWaiting(const xQueueHandle pxQueue) PRIVILEGED_FUNCTION;
+void vQueueDelete(xQueueHandle xQueue) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueGenericSendFromISR(xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueGenericReceive(xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueReceiveFromISR(xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken) PRIVILEGED_FUNCTION;
+xQueueHandle xQueueCreateMutex(void) PRIVILEGED_FUNCTION;
+xQueueHandle xQueueCreateCountingSemaphore(unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount) PRIVILEGED_FUNCTION;
+portBASE_TYPE xQueueTakeMutexRecursive(xQueueHandle xMutex, portTickType xBlockTime) PRIVILEGED_FUNCTION;
+portBASE_TYPE xQueueGiveMutexRecursive(xQueueHandle xMutex) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueAltGenericSend(xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueAltGenericReceive(xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR(const xQueueHandle pxQueue) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueIsQueueFullFromISR(const xQueueHandle pxQueue) PRIVILEGED_FUNCTION;
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR(const xQueueHandle pxQueue) PRIVILEGED_FUNCTION;
+
+/*
+ * Co-routine queue functions differ from task queue functions. Co-routines are
+ * an optional component.
+ */
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRSendFromISR(xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueCRReceiveFromISR(xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueCRSend(xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait) PRIVILEGED_FUNCTION;
+signed portBASE_TYPE xQueueCRReceive(xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait) PRIVILEGED_FUNCTION;
+#endif
+
+/*
+ * The queue registry is just a means for kernel aware debuggers to locate
+ * queue structures. It has no other purpose so is an optional component.
+ */
+#if configQUEUE_REGISTRY_SIZE > 0
+
+/* The type stored within the queue registry array. This allows a name
+to be assigned to each queue making kernel aware debugging a little
+more user friendly. */
+typedef struct QUEUE_REGISTRY_ITEM {
+ signed char *pcQueueName;
+ xQueueHandle xHandle;
+} xQueueRegistryItem;
+
+/* The queue registry is simply an array of xQueueRegistryItem structures.
+The pcQueueName member of a structure being NULL is indicative of the
+array position being vacant. */
+xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
+
+/* Removes a queue from the registry by simply setting the pcQueueName
+member to NULL. */
+static void vQueueUnregisterQueue(xQueueHandle xQueue) PRIVILEGED_FUNCTION;
+void vQueueAddToRegistry(xQueueHandle xQueue, signed char *pcQueueName) PRIVILEGED_FUNCTION;
+#endif
+
+/*
+ * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
+ * prevent an ISR from adding or removing items to the queue, but does prevent
+ * an ISR from removing tasks from the queue event lists. If an ISR finds a
+ * queue is locked it will instead increment the appropriate queue lock count
+ * to indicate that a task may require unblocking. When the queue in unlocked
+ * these lock counts are inspected, and the appropriate action taken.
+ */
+static void prvUnlockQueue(xQueueHandle pxQueue) PRIVILEGED_FUNCTION;
+
+/*
+ * Uses a critical section to determine if there is any data in a queue.
+ *
+ * @return pdTRUE if the queue contains no items, otherwise pdFALSE.
+ */
+static signed portBASE_TYPE prvIsQueueEmpty(const xQueueHandle pxQueue) PRIVILEGED_FUNCTION;
+
+/*
+ * Uses a critical section to determine if there is any space in a queue.
+ *
+ * @return pdTRUE if there is no space, otherwise pdFALSE;
+ */
+static signed portBASE_TYPE prvIsQueueFull(const xQueueHandle pxQueue) PRIVILEGED_FUNCTION;
+
+/*
+ * Copies an item into the queue, either at the front of the queue or the
+ * back of the queue.
+ */
+static void prvCopyDataToQueue(xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition) PRIVILEGED_FUNCTION;
+
+/*
+ * Copies an item out of a queue.
+ */
+static void prvCopyDataFromQueue(xQUEUE * const pxQueue, const void *pvBuffer) PRIVILEGED_FUNCTION;
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro to mark a queue as locked. Locking a queue prevents an ISR from
+ * accessing the queue event lists.
+ */
+#define prvLockQueue( pxQueue ) \
+{ \
+ taskENTER_CRITICAL(); \
+ { \
+ if( pxQueue->xRxLock == queueUNLOCKED ) \
+ { \
+ pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \
+ } \
+ if( pxQueue->xTxLock == queueUNLOCKED ) \
+ { \
+ pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \
+ } \
+ } \
+ taskEXIT_CRITICAL(); \
+}
+/*-----------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------
+ * PUBLIC QUEUE MANAGEMENT API documented in queue.h
+ *----------------------------------------------------------*/
+
+xQueueHandle xQueueCreate(unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize)
+{
+ xQUEUE *pxNewQueue;
+ size_t xQueueSizeInBytes;
+
+ /* Allocate the new queue structure. */
+ if (uxQueueLength > (unsigned portBASE_TYPE) 0) {
+ pxNewQueue = (xQUEUE *) pvPortMalloc(sizeof(xQUEUE));
+ if (pxNewQueue != NULL) {
+ /* Create the list of pointers to queue items. The queue is one byte
+ longer than asked for to make wrap checking easier/faster. */
+ xQueueSizeInBytes = (size_t)(uxQueueLength * uxItemSize) + (size_t) 1;
+
+ pxNewQueue->pcHead = (signed char *) pvPortMalloc(xQueueSizeInBytes);
+ if (pxNewQueue->pcHead != NULL) {
+ /* Initialise the queue members as described above where the
+ queue type is defined. */
+ pxNewQueue->pcTail = pxNewQueue->pcHead + (uxQueueLength * uxItemSize);
+ pxNewQueue->uxMessagesWaiting = 0;
+ pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
+ pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ((uxQueueLength - 1) * uxItemSize);
+ pxNewQueue->uxLength = uxQueueLength;
+ pxNewQueue->uxItemSize = uxItemSize;
+ pxNewQueue->xRxLock = queueUNLOCKED;
+ pxNewQueue->xTxLock = queueUNLOCKED;
+
+ /* Likewise ensure the event queues start with the correct state. */
+ vListInitialise(&(pxNewQueue->xTasksWaitingToSend));
+ vListInitialise(&(pxNewQueue->xTasksWaitingToReceive));
+
+ traceQUEUE_CREATE(pxNewQueue);
+ return pxNewQueue;
+ } else {
+ traceQUEUE_CREATE_FAILED();
+ vPortFree(pxNewQueue);
+ }
+ }
+ }
+
+ /* Will only reach here if we could not allocate enough memory or no memory
+ was required. */
+ return NULL;
+}
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_MUTEXES == 1 )
+
+xQueueHandle xQueueCreateMutex(void)
+{
+ xQUEUE *pxNewQueue;
+
+ /* Allocate the new queue structure. */
+ pxNewQueue = (xQUEUE *) pvPortMalloc(sizeof(xQUEUE));
+ if (pxNewQueue != NULL) {
+ /* Information required for priority inheritance. */
+ pxNewQueue->pxMutexHolder = NULL;
+ pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
+
+ /* Queues used as a mutex no data is actually copied into or out
+ of the queue. */
+ pxNewQueue->pcWriteTo = NULL;
+ pxNewQueue->pcReadFrom = NULL;
+
+ /* Each mutex has a length of 1 (like a binary semaphore) and
+ an item size of 0 as nothing is actually copied into or out
+ of the mutex. */
+ pxNewQueue->uxMessagesWaiting = 0;
+ pxNewQueue->uxLength = 1;
+ pxNewQueue->uxItemSize = 0;
+ pxNewQueue->xRxLock = queueUNLOCKED;
+ pxNewQueue->xTxLock = queueUNLOCKED;
+
+ /* Ensure the event queues start with the correct state. */
+ vListInitialise(&(pxNewQueue->xTasksWaitingToSend));
+ vListInitialise(&(pxNewQueue->xTasksWaitingToReceive));
+
+ /* Start with the semaphore in the expected state. */
+ xQueueGenericSend(pxNewQueue, NULL, 0, queueSEND_TO_BACK);
+
+ traceCREATE_MUTEX(pxNewQueue);
+ } else {
+ traceCREATE_MUTEX_FAILED();
+ }
+
+ return pxNewQueue;
+}
+
+#endif /* configUSE_MUTEXES */
+/*-----------------------------------------------------------*/
+
+#if configUSE_RECURSIVE_MUTEXES == 1
+
+portBASE_TYPE xQueueGiveMutexRecursive(xQueueHandle pxMutex)
+{
+ portBASE_TYPE xReturn;
+
+ /* If this is the task that holds the mutex then pxMutexHolder will not
+ change outside of this task. If this task does not hold the mutex then
+ pxMutexHolder can never coincidentally equal the tasks handle, and as
+ this is the only condition we are interested in it does not matter if
+ pxMutexHolder is accessed simultaneously by another task. Therefore no
+ mutual exclusion is required to test the pxMutexHolder variable. */
+ if (pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle()) {
+ traceGIVE_MUTEX_RECURSIVE(pxMutex);
+
+ /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to
+ the task handle, therefore no underflow check is required. Also,
+ uxRecursiveCallCount is only modified by the mutex holder, and as
+ there can only be one, no mutual exclusion is required to modify the
+ uxRecursiveCallCount member. */
+ (pxMutex->uxRecursiveCallCount)--;
+
+ /* Have we unwound the call count? */
+ if (pxMutex->uxRecursiveCallCount == 0) {
+ /* Return the mutex. This will automatically unblock any other
+ task that might be waiting to access the mutex. */
+ xQueueGenericSend(pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK);
+ }
+
+ xReturn = pdPASS;
+ } else {
+ /* We cannot give the mutex because we are not the holder. */
+ xReturn = pdFAIL;
+
+ traceGIVE_MUTEX_RECURSIVE_FAILED(pxMutex);
+ }
+
+ return xReturn;
+}
+
+#endif /* configUSE_RECURSIVE_MUTEXES */
+/*-----------------------------------------------------------*/
+
+#if configUSE_RECURSIVE_MUTEXES == 1
+
+portBASE_TYPE xQueueTakeMutexRecursive(xQueueHandle pxMutex, portTickType xBlockTime)
+{
+ portBASE_TYPE xReturn;
+
+ /* Comments regarding mutual exclusion as per those within
+ xQueueGiveMutexRecursive(). */
+
+ traceTAKE_MUTEX_RECURSIVE(pxMutex);
+
+ if (pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle()) {
+ (pxMutex->uxRecursiveCallCount)++;
+ xReturn = pdPASS;
+ } else {
+ xReturn = xQueueGenericReceive(pxMutex, NULL, xBlockTime, pdFALSE);
+
+ /* pdPASS will only be returned if we successfully obtained the mutex,
+ we may have blocked to reach here. */
+ if (xReturn == pdPASS) {
+ (pxMutex->uxRecursiveCallCount)++;
+ }
+ }
+
+ return xReturn;
+}
+
+#endif /* configUSE_RECURSIVE_MUTEXES */
+/*-----------------------------------------------------------*/
+
+#if configUSE_COUNTING_SEMAPHORES == 1
+
+xQueueHandle xQueueCreateCountingSemaphore(unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount)
+{
+ xQueueHandle pxHandle;
+
+ pxHandle = xQueueCreate((unsigned portBASE_TYPE) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH);
+
+ if (pxHandle != NULL) {
+ pxHandle->uxMessagesWaiting = uxInitialCount;
+
+ traceCREATE_COUNTING_SEMAPHORE();
+ } else {
+ traceCREATE_COUNTING_SEMAPHORE_FAILED();
+ }
+
+ return pxHandle;
+}
+
+#endif /* configUSE_COUNTING_SEMAPHORES */
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueGenericSend(xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition)
+{
+ signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+ xTimeOutType xTimeOut;
+
+ /* This function relaxes the coding standard somewhat to allow return
+ statements within the function itself. This is done in the interest
+ of execution time efficiency. */
+ for (;;) {
+ taskENTER_CRITICAL();
+ {
+ /* Is there room on the queue now? To be running we must be
+ the highest priority task wanting to access the queue. */
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) {
+ traceQUEUE_SEND(pxQueue);
+ prvCopyDataToQueue(pxQueue, pvItemToQueue, xCopyPosition);
+
+ /* If there was a task waiting for data to arrive on the
+ queue then unblock it now. */
+ if (listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive)) == pdFALSE) {
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) == pdTRUE) {
+ /* The unblocked task has a priority higher than
+ our own so yield immediately. Yes it is ok to do
+ this from within the critical section - the kernel
+ takes care of that. */
+ portYIELD_WITHIN_API();
+ }
+ }
+
+ taskEXIT_CRITICAL();
+
+ /* Return to the original privilege level before exiting the
+ function. */
+ return pdPASS;
+ } else {
+ if (xTicksToWait == (portTickType) 0) {
+ /* The queue was full and no block time is specified (or
+ the block time has expired) so leave now. */
+ taskEXIT_CRITICAL();
+
+ /* Return to the original privilege level before exiting
+ the function. */
+ traceQUEUE_SEND_FAILED(pxQueue);
+ return errQUEUE_FULL;
+ } else if (xEntryTimeSet == pdFALSE) {
+ /* The queue was full and a block time was specified so
+ configure the timeout structure. */
+ vTaskSetTimeOutState(&xTimeOut);
+ xEntryTimeSet = pdTRUE;
+ }
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ /* Interrupts and other tasks can send to and receive from the queue
+ now the critical section has been exited. */
+
+ vTaskSuspendAll();
+ prvLockQueue(pxQueue);
+
+ /* Update the timeout state to see if it has expired yet. */
+ if (xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE) {
+ if (prvIsQueueFull(pxQueue)) {
+ traceBLOCKING_ON_QUEUE_SEND(pxQueue);
+ vTaskPlaceOnEventList(&(pxQueue->xTasksWaitingToSend), xTicksToWait);
+
+ /* Unlocking the queue means queue events can effect the
+ event list. It is possible that interrupts occurring now
+ remove this task from the event list again - but as the
+ scheduler is suspended the task will go onto the pending
+ ready last instead of the actual ready list. */
+ prvUnlockQueue(pxQueue);
+
+ /* Resuming the scheduler will move tasks from the pending
+ ready list into the ready list - so it is feasible that this
+ task is already in a ready list before it yields - in which
+ case the yield will not cause a context switch unless there
+ is also a higher priority task in the pending ready list. */
+ if (!xTaskResumeAll()) {
+ portYIELD_WITHIN_API();
+ }
+ } else {
+ /* Try again. */
+ prvUnlockQueue(pxQueue);
+ (void) xTaskResumeAll();
+ }
+ } else {
+ /* The timeout has expired. */
+ prvUnlockQueue(pxQueue);
+ (void) xTaskResumeAll();
+
+ /* Return to the original privilege level before exiting the
+ function. */
+ traceQUEUE_SEND_FAILED(pxQueue);
+ return errQUEUE_FULL;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+#if configUSE_ALTERNATIVE_API == 1
+
+signed portBASE_TYPE xQueueAltGenericSend(xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition)
+{
+ signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+ xTimeOutType xTimeOut;
+
+ for (;;) {
+ taskENTER_CRITICAL();
+ {
+ /* Is there room on the queue now? To be running we must be
+ the highest priority task wanting to access the queue. */
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) {
+ traceQUEUE_SEND(pxQueue);
+ prvCopyDataToQueue(pxQueue, pvItemToQueue, xCopyPosition);
+
+ /* If there was a task waiting for data to arrive on the
+ queue then unblock it now. */
+ if (listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive)) == pdFALSE) {
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) == pdTRUE) {
+ /* The unblocked task has a priority higher than
+ our own so yield immediately. */
+ portYIELD_WITHIN_API();
+ }
+ }
+
+ taskEXIT_CRITICAL();
+ return pdPASS;
+ } else {
+ if (xTicksToWait == (portTickType) 0) {
+ taskEXIT_CRITICAL();
+ return errQUEUE_FULL;
+ } else if (xEntryTimeSet == pdFALSE) {
+ vTaskSetTimeOutState(&xTimeOut);
+ xEntryTimeSet = pdTRUE;
+ }
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ taskENTER_CRITICAL();
+ {
+ if (xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE) {
+ if (prvIsQueueFull(pxQueue)) {
+ traceBLOCKING_ON_QUEUE_SEND(pxQueue);
+ vTaskPlaceOnEventList(&(pxQueue->xTasksWaitingToSend), xTicksToWait);
+ portYIELD_WITHIN_API();
+ }
+ } else {
+ taskEXIT_CRITICAL();
+ traceQUEUE_SEND_FAILED(pxQueue);
+ return errQUEUE_FULL;
+ }
+ }
+ taskEXIT_CRITICAL();
+ }
+}
+
+#endif /* configUSE_ALTERNATIVE_API */
+/*-----------------------------------------------------------*/
+
+#if configUSE_ALTERNATIVE_API == 1
+
+signed portBASE_TYPE xQueueAltGenericReceive(xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking)
+{
+ signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+ xTimeOutType xTimeOut;
+ signed char *pcOriginalReadPosition;
+
+ for (;;) {
+ taskENTER_CRITICAL();
+ {
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) {
+ /* Remember our read position in case we are just peeking. */
+ pcOriginalReadPosition = pxQueue->pcReadFrom;
+
+ prvCopyDataFromQueue(pxQueue, pvBuffer);
+
+ if (xJustPeeking == pdFALSE) {
+ traceQUEUE_RECEIVE(pxQueue);
+
+ /* We are actually removing data. */
+ --(pxQueue->uxMessagesWaiting);
+
+#if ( configUSE_MUTEXES == 1 )
+ {
+ if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) {
+ /* Record the information required to implement
+ priority inheritance should it become necessary. */
+ pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
+ }
+ }
+#endif
+
+ if (listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToSend)) == pdFALSE) {
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToSend)) == pdTRUE) {
+ portYIELD_WITHIN_API();
+ }
+ }
+ } else {
+ traceQUEUE_PEEK(pxQueue);
+
+ /* We are not removing the data, so reset our read
+ pointer. */
+ pxQueue->pcReadFrom = pcOriginalReadPosition;
+
+ /* The data is being left in the queue, so see if there are
+ any other tasks waiting for the data. */
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive))) {
+ /* Tasks that are removed from the event list will get added to
+ the pending ready list as the scheduler is still suspended. */
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) {
+ /* The task waiting has a higher priority than this task. */
+ portYIELD_WITHIN_API();
+ }
+ }
+
+ }
+
+ taskEXIT_CRITICAL();
+ return pdPASS;
+ } else {
+ if (xTicksToWait == (portTickType) 0) {
+ taskEXIT_CRITICAL();
+ traceQUEUE_RECEIVE_FAILED(pxQueue);
+ return errQUEUE_EMPTY;
+ } else if (xEntryTimeSet == pdFALSE) {
+ vTaskSetTimeOutState(&xTimeOut);
+ xEntryTimeSet = pdTRUE;
+ }
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ taskENTER_CRITICAL();
+ {
+ if (xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE) {
+ if (prvIsQueueEmpty(pxQueue)) {
+ traceBLOCKING_ON_QUEUE_RECEIVE(pxQueue);
+
+#if ( configUSE_MUTEXES == 1 )
+ {
+ if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) {
+ portENTER_CRITICAL();
+ vTaskPriorityInherit((void *) pxQueue->pxMutexHolder);
+ portEXIT_CRITICAL();
+ }
+ }
+#endif
+
+ vTaskPlaceOnEventList(&(pxQueue->xTasksWaitingToReceive), xTicksToWait);
+ portYIELD_WITHIN_API();
+ }
+ } else {
+ taskEXIT_CRITICAL();
+ traceQUEUE_RECEIVE_FAILED(pxQueue);
+ return errQUEUE_EMPTY;
+ }
+ }
+ taskEXIT_CRITICAL();
+ }
+}
+
+
+#endif /* configUSE_ALTERNATIVE_API */
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueGenericSendFromISR(xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition)
+{
+ signed portBASE_TYPE xReturn;
+ unsigned portBASE_TYPE uxSavedInterruptStatus;
+
+ /* Similar to xQueueGenericSend, except we don't block if there is no room
+ in the queue. Also we don't directly wake a task that was blocked on a
+ queue read, instead we return a flag to say whether a context switch is
+ required or not (i.e. has a task with a higher priority than us been woken
+ by this post). */
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
+ {
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) {
+ traceQUEUE_SEND_FROM_ISR(pxQueue);
+
+ prvCopyDataToQueue(pxQueue, pvItemToQueue, xCopyPosition);
+
+ /* If the queue is locked we do not alter the event list. This will
+ be done when the queue is unlocked later. */
+ if (pxQueue->xTxLock == queueUNLOCKED) {
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive))) {
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) {
+ /* The task waiting has a higher priority so record that a
+ context switch is required. */
+ *pxHigherPriorityTaskWoken = pdTRUE;
+ }
+ }
+ } else {
+ /* Increment the lock count so the task that unlocks the queue
+ knows that data was posted while it was locked. */
+ ++(pxQueue->xTxLock);
+ }
+
+ xReturn = pdPASS;
+ } else {
+ traceQUEUE_SEND_FROM_ISR_FAILED(pxQueue);
+ xReturn = errQUEUE_FULL;
+ }
+ }
+ portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueGenericReceive(xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking)
+{
+ signed portBASE_TYPE xEntryTimeSet = pdFALSE;
+ xTimeOutType xTimeOut;
+ signed char *pcOriginalReadPosition;
+
+ /* This function relaxes the coding standard somewhat to allow return
+ statements within the function itself. This is done in the interest
+ of execution time efficiency. */
+
+ for (;;) {
+ taskENTER_CRITICAL();
+ {
+ /* Is there data in the queue now? To be running we must be
+ the highest priority task wanting to access the queue. */
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) {
+ /* Remember our read position in case we are just peeking. */
+ pcOriginalReadPosition = pxQueue->pcReadFrom;
+
+ prvCopyDataFromQueue(pxQueue, pvBuffer);
+
+ if (xJustPeeking == pdFALSE) {
+ traceQUEUE_RECEIVE(pxQueue);
+
+ /* We are actually removing data. */
+ --(pxQueue->uxMessagesWaiting);
+
+#if ( configUSE_MUTEXES == 1 )
+ {
+ if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) {
+ /* Record the information required to implement
+ priority inheritance should it become necessary. */
+ pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
+ }
+ }
+#endif
+
+ if (listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToSend)) == pdFALSE) {
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToSend)) == pdTRUE) {
+ portYIELD_WITHIN_API();
+ }
+ }
+ } else {
+ traceQUEUE_PEEK(pxQueue);
+
+ /* We are not removing the data, so reset our read
+ pointer. */
+ pxQueue->pcReadFrom = pcOriginalReadPosition;
+
+ /* The data is being left in the queue, so see if there are
+ any other tasks waiting for the data. */
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive))) {
+ /* Tasks that are removed from the event list will get added to
+ the pending ready list as the scheduler is still suspended. */
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) {
+ /* The task waiting has a higher priority than this task. */
+ portYIELD_WITHIN_API();
+ }
+ }
+
+ }
+
+ taskEXIT_CRITICAL();
+ return pdPASS;
+ } else {
+ if (xTicksToWait == (portTickType) 0) {
+ /* The queue was empty and no block time is specified (or
+ the block time has expired) so leave now. */
+ taskEXIT_CRITICAL();
+ traceQUEUE_RECEIVE_FAILED(pxQueue);
+ return errQUEUE_EMPTY;
+ } else if (xEntryTimeSet == pdFALSE) {
+ /* The queue was empty and a block time was specified so
+ configure the timeout structure. */
+ vTaskSetTimeOutState(&xTimeOut);
+ xEntryTimeSet = pdTRUE;
+ }
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ /* Interrupts and other tasks can send to and receive from the queue
+ now the critical section has been exited. */
+
+ vTaskSuspendAll();
+ prvLockQueue(pxQueue);
+
+ /* Update the timeout state to see if it has expired yet. */
+ if (xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE) {
+ if (prvIsQueueEmpty(pxQueue)) {
+ traceBLOCKING_ON_QUEUE_RECEIVE(pxQueue);
+
+#if ( configUSE_MUTEXES == 1 )
+ {
+ if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) {
+ portENTER_CRITICAL();
+ {
+ vTaskPriorityInherit((void *) pxQueue->pxMutexHolder);
+ }
+ portEXIT_CRITICAL();
+ }
+ }
+#endif
+
+ vTaskPlaceOnEventList(&(pxQueue->xTasksWaitingToReceive), xTicksToWait);
+ prvUnlockQueue(pxQueue);
+ if (!xTaskResumeAll()) {
+ portYIELD_WITHIN_API();
+ }
+ } else {
+ /* Try again. */
+ prvUnlockQueue(pxQueue);
+ (void) xTaskResumeAll();
+ }
+ } else {
+ prvUnlockQueue(pxQueue);
+ (void) xTaskResumeAll();
+ traceQUEUE_RECEIVE_FAILED(pxQueue);
+ return errQUEUE_EMPTY;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueReceiveFromISR(xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken)
+{
+ signed portBASE_TYPE xReturn;
+ unsigned portBASE_TYPE uxSavedInterruptStatus;
+
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
+ {
+ /* We cannot block from an ISR, so check there is data available. */
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) {
+ traceQUEUE_RECEIVE_FROM_ISR(pxQueue);
+
+ prvCopyDataFromQueue(pxQueue, pvBuffer);
+ --(pxQueue->uxMessagesWaiting);
+
+ /* If the queue is locked we will not modify the event list. Instead
+ we update the lock count so the task that unlocks the queue will know
+ that an ISR has removed data while the queue was locked. */
+ if (pxQueue->xRxLock == queueUNLOCKED) {
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToSend))) {
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToSend)) != pdFALSE) {
+ /* The task waiting has a higher priority than us so
+ force a context switch. */
+ *pxTaskWoken = pdTRUE;
+ }
+ }
+ } else {
+ /* Increment the lock count so the task that unlocks the queue
+ knows that data was removed while it was locked. */
+ ++(pxQueue->xRxLock);
+ }
+
+ xReturn = pdPASS;
+ } else {
+ xReturn = pdFAIL;
+ traceQUEUE_RECEIVE_FROM_ISR_FAILED(pxQueue);
+ }
+ }
+ portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxQueueMessagesWaiting(const xQueueHandle pxQueue)
+{
+ unsigned portBASE_TYPE uxReturn;
+
+ taskENTER_CRITICAL();
+ uxReturn = pxQueue->uxMessagesWaiting;
+ taskEXIT_CRITICAL();
+
+ return uxReturn;
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR(const xQueueHandle pxQueue)
+{
+ unsigned portBASE_TYPE uxReturn;
+
+ uxReturn = pxQueue->uxMessagesWaiting;
+
+ return uxReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vQueueDelete(xQueueHandle pxQueue)
+{
+ traceQUEUE_DELETE(pxQueue);
+ vQueueUnregisterQueue(pxQueue);
+ vPortFree(pxQueue->pcHead);
+ vPortFree(pxQueue);
+}
+/*-----------------------------------------------------------*/
+
+static void prvCopyDataToQueue(xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition)
+{
+ if (pxQueue->uxItemSize == (unsigned portBASE_TYPE) 0) {
+#if ( configUSE_MUTEXES == 1 )
+ {
+ if (pxQueue->uxQueueType == queueQUEUE_IS_MUTEX) {
+ /* The mutex is no longer being held. */
+ vTaskPriorityDisinherit((void *) pxQueue->pxMutexHolder);
+ pxQueue->pxMutexHolder = NULL;
+ }
+ }
+#endif
+ } else if (xPosition == queueSEND_TO_BACK) {
+ memcpy((void *) pxQueue->pcWriteTo, pvItemToQueue, (unsigned) pxQueue->uxItemSize);
+ pxQueue->pcWriteTo += pxQueue->uxItemSize;
+ if (pxQueue->pcWriteTo >= pxQueue->pcTail) {
+ pxQueue->pcWriteTo = pxQueue->pcHead;
+ }
+ } else {
+ memcpy((void *) pxQueue->pcReadFrom, pvItemToQueue, (unsigned) pxQueue->uxItemSize);
+ pxQueue->pcReadFrom -= pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom < pxQueue->pcHead) {
+ pxQueue->pcReadFrom = (pxQueue->pcTail - pxQueue->uxItemSize);
+ }
+ }
+
+ ++(pxQueue->uxMessagesWaiting);
+}
+/*-----------------------------------------------------------*/
+
+static void prvCopyDataFromQueue(xQUEUE * const pxQueue, const void *pvBuffer)
+{
+ if (pxQueue->uxQueueType != queueQUEUE_IS_MUTEX) {
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom >= pxQueue->pcTail) {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ memcpy((void *) pvBuffer, (void *) pxQueue->pcReadFrom, (unsigned) pxQueue->uxItemSize);
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvUnlockQueue(xQueueHandle pxQueue)
+{
+ /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
+
+ /* The lock counts contains the number of extra data items placed or
+ removed from the queue while the queue was locked. When a queue is
+ locked items can be added or removed, but the event lists cannot be
+ updated. */
+ taskENTER_CRITICAL();
+ {
+ /* See if data was added to the queue while it was locked. */
+ while (pxQueue->xTxLock > queueLOCKED_UNMODIFIED) {
+ /* Data was posted while the queue was locked. Are any tasks
+ blocked waiting for data to become available? */
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive))) {
+ /* Tasks that are removed from the event list will get added to
+ the pending ready list as the scheduler is still suspended. */
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) {
+ /* The task waiting has a higher priority so record that a
+ context switch is required. */
+ vTaskMissedYield();
+ }
+
+ --(pxQueue->xTxLock);
+ } else {
+ break;
+ }
+ }
+
+ pxQueue->xTxLock = queueUNLOCKED;
+ }
+ taskEXIT_CRITICAL();
+
+ /* Do the same for the Rx lock. */
+ taskENTER_CRITICAL();
+ {
+ while (pxQueue->xRxLock > queueLOCKED_UNMODIFIED) {
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToSend))) {
+ if (xTaskRemoveFromEventList(&(pxQueue->xTasksWaitingToSend)) != pdFALSE) {
+ vTaskMissedYield();
+ }
+
+ --(pxQueue->xRxLock);
+ } else {
+ break;
+ }
+ }
+
+ pxQueue->xRxLock = queueUNLOCKED;
+ }
+ taskEXIT_CRITICAL();
+}
+/*-----------------------------------------------------------*/
+
+static signed portBASE_TYPE prvIsQueueEmpty(const xQueueHandle pxQueue)
+{
+ signed portBASE_TYPE xReturn;
+
+ taskENTER_CRITICAL();
+ xReturn = (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0);
+ taskEXIT_CRITICAL();
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR(const xQueueHandle pxQueue)
+{
+ signed portBASE_TYPE xReturn;
+
+ xReturn = (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0);
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static signed portBASE_TYPE prvIsQueueFull(const xQueueHandle pxQueue)
+{
+ signed portBASE_TYPE xReturn;
+
+ taskENTER_CRITICAL();
+ xReturn = (pxQueue->uxMessagesWaiting == pxQueue->uxLength);
+ taskEXIT_CRITICAL();
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xQueueIsQueueFullFromISR(const xQueueHandle pxQueue)
+{
+ signed portBASE_TYPE xReturn;
+
+ xReturn = (pxQueue->uxMessagesWaiting == pxQueue->uxLength);
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRSend(xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait)
+{
+ signed portBASE_TYPE xReturn;
+
+ /* If the queue is already full we may have to block. A critical section
+ is required to prevent an interrupt removing something from the queue
+ between the check to see if the queue is full and blocking on the queue. */
+ portDISABLE_INTERRUPTS();
+ {
+ if (prvIsQueueFull(pxQueue)) {
+ /* The queue is full - do we want to block or just leave without
+ posting? */
+ if (xTicksToWait > (portTickType) 0) {
+ /* As this is called from a coroutine we cannot block directly, but
+ return indicating that we need to block. */
+ vCoRoutineAddToDelayedList(xTicksToWait, &(pxQueue->xTasksWaitingToSend));
+ portENABLE_INTERRUPTS();
+ return errQUEUE_BLOCKED;
+ } else {
+ portENABLE_INTERRUPTS();
+ return errQUEUE_FULL;
+ }
+ }
+ }
+ portENABLE_INTERRUPTS();
+
+ portNOP();
+
+ portDISABLE_INTERRUPTS();
+ {
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) {
+ /* There is room in the queue, copy the data into the queue. */
+ prvCopyDataToQueue(pxQueue, pvItemToQueue, queueSEND_TO_BACK);
+ xReturn = pdPASS;
+
+ /* Were any co-routines waiting for data to become available? */
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive))) {
+ /* In this instance the co-routine could be placed directly
+ into the ready list as we are within a critical section.
+ Instead the same pending ready list mechanism is used as if
+ the event were caused from within an interrupt. */
+ if (xCoRoutineRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) {
+ /* The co-routine waiting has a higher priority so record
+ that a yield might be appropriate. */
+ xReturn = errQUEUE_YIELD;
+ }
+ }
+ } else {
+ xReturn = errQUEUE_FULL;
+ }
+ }
+ portENABLE_INTERRUPTS();
+
+ return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRReceive(xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait)
+{
+ signed portBASE_TYPE xReturn;
+
+ /* If the queue is already empty we may have to block. A critical section
+ is required to prevent an interrupt adding something to the queue
+ between the check to see if the queue is empty and blocking on the queue. */
+ portDISABLE_INTERRUPTS();
+ {
+ if (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0) {
+ /* There are no messages in the queue, do we want to block or just
+ leave with nothing? */
+ if (xTicksToWait > (portTickType) 0) {
+ /* As this is a co-routine we cannot block directly, but return
+ indicating that we need to block. */
+ vCoRoutineAddToDelayedList(xTicksToWait, &(pxQueue->xTasksWaitingToReceive));
+ portENABLE_INTERRUPTS();
+ return errQUEUE_BLOCKED;
+ } else {
+ portENABLE_INTERRUPTS();
+ return errQUEUE_FULL;
+ }
+ }
+ }
+ portENABLE_INTERRUPTS();
+
+ portNOP();
+
+ portDISABLE_INTERRUPTS();
+ {
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) {
+ /* Data is available from the queue. */
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom >= pxQueue->pcTail) {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --(pxQueue->uxMessagesWaiting);
+ memcpy((void *) pvBuffer, (void *) pxQueue->pcReadFrom, (unsigned) pxQueue->uxItemSize);
+
+ xReturn = pdPASS;
+
+ /* Were any co-routines waiting for space to become available? */
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToSend))) {
+ /* In this instance the co-routine could be placed directly
+ into the ready list as we are within a critical section.
+ Instead the same pending ready list mechanism is used as if
+ the event were caused from within an interrupt. */
+ if (xCoRoutineRemoveFromEventList(&(pxQueue->xTasksWaitingToSend)) != pdFALSE) {
+ xReturn = errQUEUE_YIELD;
+ }
+ }
+ } else {
+ xReturn = pdFAIL;
+ }
+ }
+ portENABLE_INTERRUPTS();
+
+ return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRSendFromISR(xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken)
+{
+ /* Cannot block within an ISR so if there is no space on the queue then
+ exit without doing anything. */
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength) {
+ prvCopyDataToQueue(pxQueue, pvItemToQueue, queueSEND_TO_BACK);
+
+ /* We only want to wake one co-routine per ISR, so check that a
+ co-routine has not already been woken. */
+ if (!xCoRoutinePreviouslyWoken) {
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToReceive))) {
+ if (xCoRoutineRemoveFromEventList(&(pxQueue->xTasksWaitingToReceive)) != pdFALSE) {
+ return pdTRUE;
+ }
+ }
+ }
+ }
+
+ return xCoRoutinePreviouslyWoken;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRReceiveFromISR(xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken)
+{
+ signed portBASE_TYPE xReturn;
+
+ /* We cannot block from an ISR, so check there is data available. If
+ not then just leave without doing anything. */
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0) {
+ /* Copy the data from the queue. */
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom >= pxQueue->pcTail) {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --(pxQueue->uxMessagesWaiting);
+ memcpy((void *) pvBuffer, (void *) pxQueue->pcReadFrom, (unsigned) pxQueue->uxItemSize);
+
+ if (!(*pxCoRoutineWoken)) {
+ if (!listLIST_IS_EMPTY(&(pxQueue->xTasksWaitingToSend))) {
+ if (xCoRoutineRemoveFromEventList(&(pxQueue->xTasksWaitingToSend)) != pdFALSE) {
+ *pxCoRoutineWoken = pdTRUE;
+ }
+ }
+ }
+
+ xReturn = pdPASS;
+ } else {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+#if configQUEUE_REGISTRY_SIZE > 0
+
+void vQueueAddToRegistry(xQueueHandle xQueue, signed char *pcQueueName)
+{
+ unsigned portBASE_TYPE ux;
+
+ /* See if there is an empty space in the registry. A NULL name denotes
+ a free slot. */
+ for (ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++) {
+ if (xQueueRegistry[ ux ].pcQueueName == NULL) {
+ /* Store the information on this queue. */
+ xQueueRegistry[ ux ].pcQueueName = pcQueueName;
+ xQueueRegistry[ ux ].xHandle = xQueue;
+ break;
+ }
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if configQUEUE_REGISTRY_SIZE > 0
+
+static void vQueueUnregisterQueue(xQueueHandle xQueue)
+{
+ unsigned portBASE_TYPE ux;
+
+ /* See if the handle of the queue being unregistered in actually in the
+ registry. */
+ for (ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++) {
+ if (xQueueRegistry[ ux ].xHandle == xQueue) {
+ /* Set the name to NULL to show that this slot if free again. */
+ xQueueRegistry[ ux ].pcQueueName = NULL;
+ break;
+ }
+ }
+
+}
+
+#endif
+
diff --git a/gyro_board/src/usb/FreeRTOS/tasks.c b/gyro_board/src/usb/FreeRTOS/tasks.c
new file mode 100644
index 0000000..22587a4
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOS/tasks.c
@@ -0,0 +1,2150 @@
+/*
+ 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.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
+all the API functions to use the MPU wrappers. That should only be done when
+task.h is included from an application file. */
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "StackMacros.h"
+
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
+
+/*
+ * Macro to define the amount of stack available to the idle task.
+ */
+#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE
+
+/*
+ * Task control block. A task control block (TCB) is allocated to each task,
+ * and stores the context of the task.
+ */
+typedef struct tskTaskControlBlock {
+ volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */
+
+#if ( portUSING_MPU_WRAPPERS == 1 )
+ xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */
+#endif
+
+ xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */
+ xListItem xEventListItem; /*< List item used to place the TCB in event lists. */
+ unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */
+ portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */
+ signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */
+
+#if ( portSTACK_GROWTH > 0 )
+ portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */
+#endif
+
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )
+ unsigned portBASE_TYPE uxCriticalNesting;
+#endif
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+ unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */
+#endif
+
+#if ( configUSE_MUTEXES == 1 )
+ unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
+#endif
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+ pdTASK_HOOK_CODE pxTaskTag;
+#endif
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+ unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */
+#endif
+
+} tskTCB;
+
+
+/*
+ * Some kernel aware debuggers require data to be viewed to be global, rather
+ * than file scope.
+ */
+#ifdef portREMOVE_STATIC_QUALIFIER
+#define static
+#endif
+
+/*lint -e956 */
+PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;
+
+/* Lists for ready and blocked tasks. --------------------*/
+
+PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */
+PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */
+PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
+PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */
+PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
+PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */
+
+#if ( INCLUDE_vTaskDelete == 1 )
+
+PRIVILEGED_DATA static volatile xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = (unsigned portBASE_TYPE) 0;
+
+#endif
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */
+
+#endif
+
+/* File private variables. --------------------------------*/
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = (unsigned portBASE_TYPE) 0;
+PRIVILEGED_DATA static volatile portTickType xTickCount = (portTickType) 0;
+PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
+PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = (unsigned portBASE_TYPE) pdFALSE;
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = (unsigned portBASE_TYPE) 0;
+PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = (portBASE_TYPE) pdFALSE;
+PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = (portBASE_TYPE) 0;
+PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = (unsigned portBASE_TYPE) 0;
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+PRIVILEGED_DATA static char pcStatsString[ 50 ] ;
+PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
+static void prvGenerateRunTimeStatsForTasksInList(const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime) PRIVILEGED_FUNCTION;
+
+#endif
+
+/* Debugging and trace facilities private variables and macros. ------------*/
+
+/*
+ * The value used to fill the stack of a task when the task is created. This
+ * is used purely for checking the high water mark for tasks.
+ */
+#define tskSTACK_FILL_BYTE ( 0xa5 )
+
+/*
+ * Macros used by vListTask to indicate which state a task is in.
+ */
+#define tskBLOCKED_CHAR ( ( signed char ) 'B' )
+#define tskREADY_CHAR ( ( signed char ) 'R' )
+#define tskDELETED_CHAR ( ( signed char ) 'D' )
+#define tskSUSPENDED_CHAR ( ( signed char ) 'S' )
+
+/*
+ * Macros and private variables used by the trace facility.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+#define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) )
+PRIVILEGED_DATA static volatile signed char * volatile pcTraceBuffer;
+PRIVILEGED_DATA static signed char *pcTraceBufferStart;
+PRIVILEGED_DATA static signed char *pcTraceBufferEnd;
+PRIVILEGED_DATA static signed portBASE_TYPE xTracing = pdFALSE;
+static unsigned portBASE_TYPE uxPreviousTask = 255;
+PRIVILEGED_DATA static char pcStatusString[ 50 ];
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro that writes a trace of scheduler activity to a buffer. This trace
+ * shows which task is running when and is very useful as a debugging tool.
+ * As this macro is called each context switch it is a good idea to undefine
+ * it if not using the facility.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+#define vWriteTraceToBuffer() \
+ { \
+ if( xTracing ) \
+ { \
+ if( uxPreviousTask != pxCurrentTCB->uxTCBNumber ) \
+ { \
+ if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \
+ { \
+ uxPreviousTask = pxCurrentTCB->uxTCBNumber; \
+ *( unsigned long * ) pcTraceBuffer = ( unsigned long ) xTickCount; \
+ pcTraceBuffer += sizeof( unsigned long ); \
+ *( unsigned long * ) pcTraceBuffer = ( unsigned long ) uxPreviousTask; \
+ pcTraceBuffer += sizeof( unsigned long ); \
+ } \
+ else \
+ { \
+ xTracing = pdFALSE; \
+ } \
+ } \
+ } \
+ }
+
+#else
+
+#define vWriteTraceToBuffer()
+
+#endif
+/*-----------------------------------------------------------*/
+
+/*
+ * Place the task represented by pxTCB into the appropriate ready queue for
+ * the task. It is inserted at the end of the list. One quirk of this is
+ * that if the task being inserted is at the same priority as the currently
+ * executing task, then it will only be rescheduled after the currently
+ * executing task has been rescheduled.
+ */
+#define prvAddTaskToReadyQueue( pxTCB ) \
+{ \
+ if( pxTCB->uxPriority > uxTopReadyPriority ) \
+ { \
+ uxTopReadyPriority = pxTCB->uxPriority; \
+ } \
+ vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro that looks at the list of tasks that are currently delayed to see if
+ * any require waking.
+ *
+ * Tasks are stored in the queue in the order of their wake time - meaning
+ * once one tasks has been found whose timer has not expired we need not look
+ * any further down the list.
+ */
+#define prvCheckDelayedTasks() \
+{ \
+register tskTCB *pxTCB; \
+ \
+ while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \
+ { \
+ if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \
+ { \
+ break; \
+ } \
+ vListRemove( &( pxTCB->xGenericListItem ) ); \
+ /* Is the task waiting on an event also? */ \
+ if( pxTCB->xEventListItem.pvContainer ) \
+ { \
+ vListRemove( &( pxTCB->xEventListItem ) ); \
+ } \
+ prvAddTaskToReadyQueue( pxTCB ); \
+ } \
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Several functions take an xTaskHandle parameter that can optionally be NULL,
+ * where NULL is used to indicate that the handle of the currently executing
+ * task should be used in place of the parameter. This macro simply checks to
+ * see if the parameter is NULL and returns a pointer to the appropriate TCB.
+ */
+#define prvGetTCBFromHandle( pxHandle ) ( ( pxHandle == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) pxHandle )
+
+
+/* File private functions. --------------------------------*/
+
+/*
+ * Utility to ready a TCB for a given task. Mainly just copies the parameters
+ * into the TCB structure.
+ */
+static void prvInitialiseTCBVariables(tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth) PRIVILEGED_FUNCTION;
+
+/*
+ * Utility to ready all the lists used by the scheduler. This is called
+ * automatically upon the creation of the first task.
+ */
+static void prvInitialiseTaskLists(void) PRIVILEGED_FUNCTION;
+
+/*
+ * The idle task, which as all tasks is implemented as a never ending loop.
+ * The idle task is automatically created and added to the ready lists upon
+ * creation of the first user task.
+ *
+ * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific
+ * language extensions. The equivalent prototype for this function is:
+ *
+ * void prvIdleTask( void *pvParameters );
+ *
+ */
+static portTASK_FUNCTION_PROTO(prvIdleTask, pvParameters);
+
+/*
+ * Utility to free all memory allocated by the scheduler to hold a TCB,
+ * including the stack pointed to by the TCB.
+ *
+ * This does not free memory allocated by the task itself (i.e. memory
+ * allocated by calls to pvPortMalloc from within the tasks application code).
+ */
+#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
+
+static void prvDeleteTCB(tskTCB *pxTCB) PRIVILEGED_FUNCTION;
+
+#endif
+
+/*
+ * Used only by the idle task. This checks to see if anything has been placed
+ * in the list of tasks waiting to be deleted. If so the task is cleaned up
+ * and its TCB deleted.
+ */
+static void prvCheckTasksWaitingTermination(void) PRIVILEGED_FUNCTION;
+
+/*
+ * Allocates memory from the heap for a TCB and associated stack. Checks the
+ * allocation was successful.
+ */
+static tskTCB *prvAllocateTCBAndStack(unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer) PRIVILEGED_FUNCTION;
+
+/*
+ * Called from vTaskList. vListTasks details all the tasks currently under
+ * control of the scheduler. The tasks may be in one of a number of lists.
+ * prvListTaskWithinSingleList accepts a list and details the tasks from
+ * within just that list.
+ *
+ * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
+ * NORMAL APPLICATION CODE.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+static void prvListTaskWithinSingleList(const signed char *pcWriteBuffer, xList *pxList, signed char cStatus) PRIVILEGED_FUNCTION;
+
+#endif
+
+/*
+ * When a task is created, the stack of the task is filled with a known value.
+ * This function determines the 'high water mark' of the task stack by
+ * determining how much of the stack remains at the original preset value.
+ */
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
+
+static unsigned short usTaskCheckFreeStackSpace(const unsigned char * pucStackByte) PRIVILEGED_FUNCTION;
+
+#endif
+
+
+/*lint +e956 */
+
+
+
+/*-----------------------------------------------------------
+ * TASK CREATION API documented in task.h
+ *----------------------------------------------------------*/
+
+signed portBASE_TYPE xTaskGenericCreate(pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions)
+{
+ signed portBASE_TYPE xReturn;
+ tskTCB * pxNewTCB;
+
+ /* Allocate the memory required by the TCB and stack for the new task,
+ checking that the allocation was successful. */
+ pxNewTCB = prvAllocateTCBAndStack(usStackDepth, puxStackBuffer);
+
+ if (pxNewTCB != NULL) {
+ portSTACK_TYPE *pxTopOfStack;
+
+#if( portUSING_MPU_WRAPPERS == 1 )
+ /* Should the task be created in privileged mode? */
+ portBASE_TYPE xRunPrivileged;
+ if ((uxPriority & portPRIVILEGE_BIT) != 0x00) {
+ xRunPrivileged = pdTRUE;
+ } else {
+ xRunPrivileged = pdFALSE;
+ }
+ uxPriority &= ~portPRIVILEGE_BIT;
+#endif /* portUSING_MPU_WRAPPERS == 1 */
+
+ /* Calculate the top of stack address. This depends on whether the
+ stack grows from high memory to low (as per the 80x86) or visa versa.
+ portSTACK_GROWTH is used to make the result positive or negative as
+ required by the port. */
+#if( portSTACK_GROWTH < 0 )
+ {
+ pxTopOfStack = pxNewTCB->pxStack + (usStackDepth - 1);
+ pxTopOfStack = (portSTACK_TYPE *)(((unsigned long) pxTopOfStack) & ((unsigned long) ~portBYTE_ALIGNMENT_MASK));
+ }
+#else
+ {
+ pxTopOfStack = pxNewTCB->pxStack;
+
+ /* If we want to use stack checking on architectures that use
+ a positive stack growth direction then we also need to store the
+ other extreme of the stack space. */
+ pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + (usStackDepth - 1);
+ }
+#endif
+
+ /* Setup the newly allocated TCB with the initial state of the task. */
+ prvInitialiseTCBVariables(pxNewTCB, pcName, uxPriority, xRegions, usStackDepth);
+
+ /* Initialize the TCB stack to look as if the task was already running,
+ but had been interrupted by the scheduler. The return address is set
+ to the start of the task function. Once the stack has been initialised
+ the top of stack variable is updated. */
+#if( portUSING_MPU_WRAPPERS == 1 )
+ {
+ pxNewTCB->pxTopOfStack = pxPortInitialiseStack(pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged);
+ }
+#else
+ {
+ pxNewTCB->pxTopOfStack = pxPortInitialiseStack(pxTopOfStack, pxTaskCode, pvParameters);
+ }
+#endif
+
+ /* We are going to manipulate the task queues to add this task to a
+ ready list, so must make sure no interrupts occur. */
+ portENTER_CRITICAL();
+ {
+ uxCurrentNumberOfTasks++;
+ if (uxCurrentNumberOfTasks == (unsigned portBASE_TYPE) 1) {
+ /* As this is the first task it must also be the current task. */
+ pxCurrentTCB = pxNewTCB;
+
+ /* This is the first task to be created so do the preliminary
+ initialisation required. We will not recover if this call
+ fails, but we will report the failure. */
+ prvInitialiseTaskLists();
+ } else {
+ /* If the scheduler is not already running, make this task the
+ current task if it is the highest priority task to be created
+ so far. */
+ if (xSchedulerRunning == pdFALSE) {
+ if (pxCurrentTCB->uxPriority <= uxPriority) {
+ pxCurrentTCB = pxNewTCB;
+ }
+ }
+ }
+
+ /* Remember the top priority to make context switching faster. Use
+ the priority in pxNewTCB as this has been capped to a valid value. */
+ if (pxNewTCB->uxPriority > uxTopUsedPriority) {
+ uxTopUsedPriority = pxNewTCB->uxPriority;
+ }
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+ {
+ /* Add a counter into the TCB for tracing only. */
+ pxNewTCB->uxTCBNumber = uxTaskNumber;
+ }
+#endif
+ uxTaskNumber++;
+
+ prvAddTaskToReadyQueue(pxNewTCB);
+
+ xReturn = pdPASS;
+ traceTASK_CREATE(pxNewTCB);
+ }
+ portEXIT_CRITICAL();
+ } else {
+ xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
+ traceTASK_CREATE_FAILED(pxNewTCB);
+ }
+
+ if (xReturn == pdPASS) {
+ if ((void *) pxCreatedTask != NULL) {
+ /* Pass the TCB out - in an anonymous way. The calling function/
+ task can use this as a handle to delete the task later if
+ required.*/
+ *pxCreatedTask = (xTaskHandle) pxNewTCB;
+ }
+
+ if (xSchedulerRunning != pdFALSE) {
+ /* If the created task is of a higher priority than the current task
+ then it should run now. */
+ if (pxCurrentTCB->uxPriority < uxPriority) {
+ portYIELD_WITHIN_API();
+ }
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelete == 1 )
+
+void vTaskDelete(xTaskHandle pxTaskToDelete)
+{
+ tskTCB *pxTCB;
+
+ portENTER_CRITICAL();
+ {
+ /* Ensure a yield is performed if the current task is being
+ deleted. */
+ if (pxTaskToDelete == pxCurrentTCB) {
+ pxTaskToDelete = NULL;
+ }
+
+ /* If null is passed in here then we are deleting ourselves. */
+ pxTCB = prvGetTCBFromHandle(pxTaskToDelete);
+
+ /* Remove task from the ready list and place in the termination list.
+ This will stop the task from be scheduled. The idle task will check
+ the termination list and free up any memory allocated by the
+ scheduler for the TCB and stack. */
+ vListRemove(&(pxTCB->xGenericListItem));
+
+ /* Is the task waiting on an event also? */
+ if (pxTCB->xEventListItem.pvContainer) {
+ vListRemove(&(pxTCB->xEventListItem));
+ }
+
+ vListInsertEnd((xList *) &xTasksWaitingTermination, &(pxTCB->xGenericListItem));
+
+ /* Increment the ucTasksDeleted variable so the idle task knows
+ there is a task that has been deleted and that it should therefore
+ check the xTasksWaitingTermination list. */
+ ++uxTasksDeleted;
+
+ /* Increment the uxTaskNumberVariable also so kernel aware debuggers
+ can detect that the task lists need re-generating. */
+ uxTaskNumber++;
+
+ traceTASK_DELETE(pxTCB);
+ }
+ portEXIT_CRITICAL();
+
+ /* Force a reschedule if we have just deleted the current task. */
+ if (xSchedulerRunning != pdFALSE) {
+ if ((void *) pxTaskToDelete == NULL) {
+ portYIELD_WITHIN_API();
+ }
+ }
+}
+
+#endif
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * TASK CONTROL API documented in task.h
+ *----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelayUntil == 1 )
+
+void vTaskDelayUntil(portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement)
+{
+ portTickType xTimeToWake;
+ portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;
+
+ vTaskSuspendAll();
+ {
+ /* Generate the tick time at which the task wants to wake. */
+ xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
+
+ if (xTickCount < *pxPreviousWakeTime) {
+ /* The tick count has overflowed since this function was
+ lasted called. In this case the only time we should ever
+ actually delay is if the wake time has also overflowed,
+ and the wake time is greater than the tick time. When this
+ is the case it is as if neither time had overflowed. */
+ if ((xTimeToWake < *pxPreviousWakeTime) && (xTimeToWake > xTickCount)) {
+ xShouldDelay = pdTRUE;
+ }
+ } else {
+ /* The tick time has not overflowed. In this case we will
+ delay if either the wake time has overflowed, and/or the
+ tick time is less than the wake time. */
+ if ((xTimeToWake < *pxPreviousWakeTime) || (xTimeToWake > xTickCount)) {
+ xShouldDelay = pdTRUE;
+ }
+ }
+
+ /* Update the wake time ready for the next call. */
+ *pxPreviousWakeTime = xTimeToWake;
+
+ if (xShouldDelay) {
+ traceTASK_DELAY_UNTIL();
+
+ /* We must remove ourselves from the ready list before adding
+ ourselves to the blocked list as the same list item is used for
+ both lists. */
+ vListRemove((xListItem *) &(pxCurrentTCB->xGenericListItem));
+
+ /* The list item will be inserted in wake time order. */
+ listSET_LIST_ITEM_VALUE(&(pxCurrentTCB->xGenericListItem), xTimeToWake);
+
+ if (xTimeToWake < xTickCount) {
+ /* Wake time has overflowed. Place this item in the
+ overflow list. */
+ vListInsert((xList *) pxOverflowDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ } else {
+ /* The wake time has not overflowed, so we can use the
+ current block list. */
+ vListInsert((xList *) pxDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ }
+ }
+ }
+ xAlreadyYielded = xTaskResumeAll();
+
+ /* Force a reschedule if xTaskResumeAll has not already done so, we may
+ have put ourselves to sleep. */
+ if (!xAlreadyYielded) {
+ portYIELD_WITHIN_API();
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelay == 1 )
+
+void vTaskDelay(portTickType xTicksToDelay)
+{
+ portTickType xTimeToWake;
+ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
+
+ /* A delay time of zero just forces a reschedule. */
+ if (xTicksToDelay > (portTickType) 0) {
+ vTaskSuspendAll();
+ {
+ traceTASK_DELAY();
+
+ /* A task that is removed from the event list while the
+ scheduler is suspended will not get placed in the ready
+ list or removed from the blocked list until the scheduler
+ is resumed.
+
+ This task cannot be in an event list as it is the currently
+ executing task. */
+
+ /* Calculate the time to wake - this may overflow but this is
+ not a problem. */
+ xTimeToWake = xTickCount + xTicksToDelay;
+
+ /* We must remove ourselves from the ready list before adding
+ ourselves to the blocked list as the same list item is used for
+ both lists. */
+ vListRemove((xListItem *) &(pxCurrentTCB->xGenericListItem));
+
+ /* The list item will be inserted in wake time order. */
+ listSET_LIST_ITEM_VALUE(&(pxCurrentTCB->xGenericListItem), xTimeToWake);
+
+ if (xTimeToWake < xTickCount) {
+ /* Wake time has overflowed. Place this item in the
+ overflow list. */
+ vListInsert((xList *) pxOverflowDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ } else {
+ /* The wake time has not overflowed, so we can use the
+ current block list. */
+ vListInsert((xList *) pxDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ }
+ }
+ xAlreadyYielded = xTaskResumeAll();
+ }
+
+ /* Force a reschedule if xTaskResumeAll has not already done so, we may
+ have put ourselves to sleep. */
+ if (!xAlreadyYielded) {
+ portYIELD_WITHIN_API();
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_uxTaskPriorityGet == 1 )
+
+unsigned portBASE_TYPE uxTaskPriorityGet(xTaskHandle pxTask)
+{
+ tskTCB *pxTCB;
+ unsigned portBASE_TYPE uxReturn;
+
+ portENTER_CRITICAL();
+ {
+ /* If null is passed in here then we are changing the
+ priority of the calling function. */
+ pxTCB = prvGetTCBFromHandle(pxTask);
+ uxReturn = pxTCB->uxPriority;
+ }
+ portEXIT_CRITICAL();
+
+ return uxReturn;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskPrioritySet == 1 )
+
+void vTaskPrioritySet(xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority)
+{
+ tskTCB *pxTCB;
+ unsigned portBASE_TYPE uxCurrentPriority, xYieldRequired = pdFALSE;
+
+ /* Ensure the new priority is valid. */
+ if (uxNewPriority >= configMAX_PRIORITIES) {
+ uxNewPriority = configMAX_PRIORITIES - 1;
+ }
+
+ portENTER_CRITICAL();
+ {
+ if (pxTask == pxCurrentTCB) {
+ pxTask = NULL;
+ }
+
+ /* If null is passed in here then we are changing the
+ priority of the calling function. */
+ pxTCB = prvGetTCBFromHandle(pxTask);
+
+ traceTASK_PRIORITY_SET(pxTask, uxNewPriority);
+
+#if ( configUSE_MUTEXES == 1 )
+ {
+ uxCurrentPriority = pxTCB->uxBasePriority;
+ }
+#else
+ {
+ uxCurrentPriority = pxTCB->uxPriority;
+ }
+#endif
+
+ if (uxCurrentPriority != uxNewPriority) {
+ /* The priority change may have readied a task of higher
+ priority than the calling task. */
+ if (uxNewPriority > uxCurrentPriority) {
+ if (pxTask != NULL) {
+ /* The priority of another task is being raised. If we
+ were raising the priority of the currently running task
+ there would be no need to switch as it must have already
+ been the highest priority task. */
+ xYieldRequired = pdTRUE;
+ }
+ } else if (pxTask == NULL) {
+ /* Setting our own priority down means there may now be another
+ task of higher priority that is ready to execute. */
+ xYieldRequired = pdTRUE;
+ }
+
+
+
+#if ( configUSE_MUTEXES == 1 )
+ {
+ /* Only change the priority being used if the task is not
+ currently using an inherited priority. */
+ if (pxTCB->uxBasePriority == pxTCB->uxPriority) {
+ pxTCB->uxPriority = uxNewPriority;
+ }
+
+ /* The base priority gets set whatever. */
+ pxTCB->uxBasePriority = uxNewPriority;
+ }
+#else
+ {
+ pxTCB->uxPriority = uxNewPriority;
+ }
+#endif
+
+ listSET_LIST_ITEM_VALUE(&(pxTCB->xEventListItem), (configMAX_PRIORITIES - (portTickType) uxNewPriority));
+
+ /* If the task is in the blocked or suspended list we need do
+ nothing more than change it's priority variable. However, if
+ the task is in a ready list it needs to be removed and placed
+ in the queue appropriate to its new priority. */
+ if (listIS_CONTAINED_WITHIN(&(pxReadyTasksLists[ uxCurrentPriority ]), &(pxTCB->xGenericListItem))) {
+ /* The task is currently in its ready list - remove before adding
+ it to it's new ready list. As we are in a critical section we
+ can do this even if the scheduler is suspended. */
+ vListRemove(&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue(pxTCB);
+ }
+
+ if (xYieldRequired == pdTRUE) {
+ portYIELD_WITHIN_API();
+ }
+ }
+ }
+ portEXIT_CRITICAL();
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+void vTaskSuspend(xTaskHandle pxTaskToSuspend)
+{
+ tskTCB *pxTCB;
+
+ portENTER_CRITICAL();
+ {
+ /* Ensure a yield is performed if the current task is being
+ suspended. */
+ if (pxTaskToSuspend == pxCurrentTCB) {
+ pxTaskToSuspend = NULL;
+ }
+
+ /* If null is passed in here then we are suspending ourselves. */
+ pxTCB = prvGetTCBFromHandle(pxTaskToSuspend);
+
+ traceTASK_SUSPEND(pxTCB);
+
+ /* Remove task from the ready/delayed list and place in the suspended list. */
+ vListRemove(&(pxTCB->xGenericListItem));
+
+ /* Is the task waiting on an event also? */
+ if (pxTCB->xEventListItem.pvContainer) {
+ vListRemove(&(pxTCB->xEventListItem));
+ }
+
+ vListInsertEnd((xList *) &xSuspendedTaskList, &(pxTCB->xGenericListItem));
+ }
+ portEXIT_CRITICAL();
+
+ /* We may have just suspended the current task. */
+ if ((void *) pxTaskToSuspend == NULL) {
+ portYIELD_WITHIN_API();
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+signed portBASE_TYPE xTaskIsTaskSuspended(xTaskHandle xTask)
+{
+ portBASE_TYPE xReturn = pdFALSE;
+ const tskTCB * const pxTCB = (tskTCB *) xTask;
+
+ /* Is the task we are attempting to resume actually in the
+ suspended list? */
+ if (listIS_CONTAINED_WITHIN(&xSuspendedTaskList, &(pxTCB->xGenericListItem)) != pdFALSE) {
+ /* Has the task already been resumed from within an ISR? */
+ if (listIS_CONTAINED_WITHIN(&xPendingReadyList, &(pxTCB->xEventListItem)) != pdTRUE) {
+ /* Is it in the suspended list because it is in the
+ Suspended state? It is possible to be in the suspended
+ list because it is blocked on a task with no timeout
+ specified. */
+ if (listIS_CONTAINED_WITHIN(NULL, &(pxTCB->xEventListItem)) == pdTRUE) {
+ xReturn = pdTRUE;
+ }
+ }
+ }
+
+ return xReturn;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+void vTaskResume(xTaskHandle pxTaskToResume)
+{
+ tskTCB *pxTCB;
+
+ /* Remove the task from whichever list it is currently in, and place
+ it in the ready list. */
+ pxTCB = (tskTCB *) pxTaskToResume;
+
+ /* The parameter cannot be NULL as it is impossible to resume the
+ currently executing task. */
+ if ((pxTCB != NULL) && (pxTCB != pxCurrentTCB)) {
+ portENTER_CRITICAL();
+ {
+ if (xTaskIsTaskSuspended(pxTCB) == pdTRUE) {
+ traceTASK_RESUME(pxTCB);
+
+ /* As we are in a critical section we can access the ready
+ lists even if the scheduler is suspended. */
+ vListRemove(&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue(pxTCB);
+
+ /* We may have just resumed a higher priority task. */
+ if (pxTCB->uxPriority >= pxCurrentTCB->uxPriority) {
+ /* This yield may not cause the task just resumed to run, but
+ will leave the lists in the correct state for the next yield. */
+ portYIELD_WITHIN_API();
+ }
+ }
+ }
+ portEXIT_CRITICAL();
+ }
+}
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
+
+portBASE_TYPE xTaskResumeFromISR(xTaskHandle pxTaskToResume)
+{
+ portBASE_TYPE xYieldRequired = pdFALSE;
+ tskTCB *pxTCB;
+
+ pxTCB = (tskTCB *) pxTaskToResume;
+
+ if (xTaskIsTaskSuspended(pxTCB) == pdTRUE) {
+ traceTASK_RESUME_FROM_ISR(pxTCB);
+
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) {
+ xYieldRequired = (pxTCB->uxPriority >= pxCurrentTCB->uxPriority);
+ vListRemove(&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue(pxTCB);
+ } else {
+ /* We cannot access the delayed or ready lists, so will hold this
+ task pending until the scheduler is resumed, at which point a
+ yield will be performed if necessary. */
+ vListInsertEnd((xList *) &(xPendingReadyList), &(pxTCB->xEventListItem));
+ }
+ }
+
+ return xYieldRequired;
+}
+
+#endif
+
+
+
+
+/*-----------------------------------------------------------
+ * PUBLIC SCHEDULER CONTROL documented in task.h
+ *----------------------------------------------------------*/
+
+
+void vTaskStartScheduler(void)
+{
+ portBASE_TYPE xReturn;
+
+ /* Add the idle task at the lowest priority. */
+ xReturn = xTaskCreate(prvIdleTask, (signed char *) "IDLE", tskIDLE_STACK_SIZE, (void *) NULL, (tskIDLE_PRIORITY | portPRIVILEGE_BIT), (xTaskHandle *) NULL);
+
+ if (xReturn == pdPASS) {
+ /* Interrupts are turned off here, to ensure a tick does not occur
+ before or during the call to xPortStartScheduler(). The stacks of
+ the created tasks contain a status word with interrupts switched on
+ so interrupts will automatically get re-enabled when the first task
+ starts to run.
+
+ STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE
+ DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */
+ portDISABLE_INTERRUPTS();
+
+ xSchedulerRunning = pdTRUE;
+ xTickCount = (portTickType) 0;
+
+ /* If configGENERATE_RUN_TIME_STATS is defined then the following
+ macro must be defined to configure the timer/counter used to generate
+ the run time counter time base. */
+ portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
+
+ /* Setting up the timer tick is hardware specific and thus in the
+ portable interface. */
+ if (xPortStartScheduler()) {
+ /* Should not reach here as if the scheduler is running the
+ function will not return. */
+ } else {
+ /* Should only reach here if a task calls xTaskEndScheduler(). */
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+void vTaskEndScheduler(void)
+{
+ /* Stop the scheduler interrupts and call the portable scheduler end
+ routine so the original ISRs can be restored if necessary. The port
+ layer must ensure interrupts enable bit is left in the correct state. */
+ portDISABLE_INTERRUPTS();
+ xSchedulerRunning = pdFALSE;
+ vPortEndScheduler();
+}
+/*----------------------------------------------------------*/
+
+void vTaskSuspendAll(void)
+{
+ /* A critical section is not required as the variable is of type
+ portBASE_TYPE. */
+ ++uxSchedulerSuspended;
+}
+/*----------------------------------------------------------*/
+
+signed portBASE_TYPE xTaskResumeAll(void)
+{
+ register tskTCB *pxTCB;
+ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
+
+ /* It is possible that an ISR caused a task to be removed from an event
+ list while the scheduler was suspended. If this was the case then the
+ removed task will have been added to the xPendingReadyList. Once the
+ scheduler has been resumed it is safe to move all the pending ready
+ tasks from this list into their appropriate ready list. */
+ portENTER_CRITICAL();
+ {
+ --uxSchedulerSuspended;
+
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) {
+ if (uxCurrentNumberOfTasks > (unsigned portBASE_TYPE) 0) {
+ portBASE_TYPE xYieldRequired = pdFALSE;
+
+ /* Move any readied tasks from the pending list into the
+ appropriate ready list. */
+ while ((pxTCB = (tskTCB *) listGET_OWNER_OF_HEAD_ENTRY(((xList *) & xPendingReadyList))) != NULL) {
+ vListRemove(&(pxTCB->xEventListItem));
+ vListRemove(&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue(pxTCB);
+
+ /* If we have moved a task that has a priority higher than
+ the current task then we should yield. */
+ if (pxTCB->uxPriority >= pxCurrentTCB->uxPriority) {
+ xYieldRequired = pdTRUE;
+ }
+ }
+
+ /* If any ticks occurred while the scheduler was suspended then
+ they should be processed now. This ensures the tick count does not
+ slip, and that any delayed tasks are resumed at the correct time. */
+ if (uxMissedTicks > (unsigned portBASE_TYPE) 0) {
+ while (uxMissedTicks > (unsigned portBASE_TYPE) 0) {
+ vTaskIncrementTick();
+ --uxMissedTicks;
+ }
+
+ /* As we have processed some ticks it is appropriate to yield
+ to ensure the highest priority task that is ready to run is
+ the task actually running. */
+#if configUSE_PREEMPTION == 1
+ {
+ xYieldRequired = pdTRUE;
+ }
+#endif
+ }
+
+ if ((xYieldRequired == pdTRUE) || (xMissedYield == pdTRUE)) {
+ xAlreadyYielded = pdTRUE;
+ xMissedYield = pdFALSE;
+ portYIELD_WITHIN_API();
+ }
+ }
+ }
+ }
+ portEXIT_CRITICAL();
+
+ return xAlreadyYielded;
+}
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * PUBLIC TASK UTILITIES documented in task.h
+ *----------------------------------------------------------*/
+
+
+
+portTickType xTaskGetTickCount(void)
+{
+ portTickType xTicks;
+
+ /* Critical section required if running on a 16 bit processor. */
+ portENTER_CRITICAL();
+ {
+ xTicks = xTickCount;
+ }
+ portEXIT_CRITICAL();
+
+ return xTicks;
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxTaskGetNumberOfTasks(void)
+{
+ /* A critical section is not required because the variables are of type
+ portBASE_TYPE. */
+ return uxCurrentNumberOfTasks;
+}
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+void vTaskList(signed char *pcWriteBuffer)
+{
+ unsigned portBASE_TYPE uxQueue;
+
+ /* This is a VERY costly function that should be used for debug only.
+ It leaves interrupts disabled for a LONG time. */
+
+ vTaskSuspendAll();
+ {
+ /* Run through all the lists that could potentially contain a TCB and
+ report the task name, state and stack high water mark. */
+
+ pcWriteBuffer[ 0 ] = (signed char) 0x00;
+ strcat((char *) pcWriteBuffer, (const char *) "\r\n");
+
+ uxQueue = uxTopUsedPriority + 1;
+
+ do {
+ uxQueue--;
+
+ if (!listLIST_IS_EMPTY(&(pxReadyTasksLists[ uxQueue ]))) {
+ prvListTaskWithinSingleList(pcWriteBuffer, (xList *) &(pxReadyTasksLists[ uxQueue ]), tskREADY_CHAR);
+ }
+ } while (uxQueue > (unsigned short) tskIDLE_PRIORITY);
+
+ if (!listLIST_IS_EMPTY(pxDelayedTaskList)) {
+ prvListTaskWithinSingleList(pcWriteBuffer, (xList *) pxDelayedTaskList, tskBLOCKED_CHAR);
+ }
+
+ if (!listLIST_IS_EMPTY(pxOverflowDelayedTaskList)) {
+ prvListTaskWithinSingleList(pcWriteBuffer, (xList *) pxOverflowDelayedTaskList, tskBLOCKED_CHAR);
+ }
+
+#if( INCLUDE_vTaskDelete == 1 )
+ {
+ if (!listLIST_IS_EMPTY(&xTasksWaitingTermination)) {
+ prvListTaskWithinSingleList(pcWriteBuffer, (xList *) &xTasksWaitingTermination, tskDELETED_CHAR);
+ }
+ }
+#endif
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+ {
+ if (!listLIST_IS_EMPTY(&xSuspendedTaskList)) {
+ prvListTaskWithinSingleList(pcWriteBuffer, (xList *) &xSuspendedTaskList, tskSUSPENDED_CHAR);
+ }
+ }
+#endif
+ }
+ xTaskResumeAll();
+}
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+void vTaskGetRunTimeStats(signed char *pcWriteBuffer)
+{
+ unsigned portBASE_TYPE uxQueue;
+ unsigned long ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
+
+ /* This is a VERY costly function that should be used for debug only.
+ It leaves interrupts disabled for a LONG time. */
+
+ vTaskSuspendAll();
+ {
+ /* Run through all the lists that could potentially contain a TCB,
+ generating a table of run timer percentages in the provided
+ buffer. */
+
+ pcWriteBuffer[ 0 ] = (signed char) 0x00;
+ strcat((char *) pcWriteBuffer, (const char *) "\r\n");
+
+ uxQueue = uxTopUsedPriority + 1;
+
+ do {
+ uxQueue--;
+
+ if (!listLIST_IS_EMPTY(&(pxReadyTasksLists[ uxQueue ]))) {
+ prvGenerateRunTimeStatsForTasksInList(pcWriteBuffer, (xList *) &(pxReadyTasksLists[ uxQueue ]), ulTotalRunTime);
+ }
+ } while (uxQueue > (unsigned short) tskIDLE_PRIORITY);
+
+ if (!listLIST_IS_EMPTY(pxDelayedTaskList)) {
+ prvGenerateRunTimeStatsForTasksInList(pcWriteBuffer, (xList *) pxDelayedTaskList, ulTotalRunTime);
+ }
+
+ if (!listLIST_IS_EMPTY(pxOverflowDelayedTaskList)) {
+ prvGenerateRunTimeStatsForTasksInList(pcWriteBuffer, (xList *) pxOverflowDelayedTaskList, ulTotalRunTime);
+ }
+
+#if ( INCLUDE_vTaskDelete == 1 )
+ {
+ if (!listLIST_IS_EMPTY(&xTasksWaitingTermination)) {
+ prvGenerateRunTimeStatsForTasksInList(pcWriteBuffer, (xList *) &xTasksWaitingTermination, ulTotalRunTime);
+ }
+ }
+#endif
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+ {
+ if (!listLIST_IS_EMPTY(&xSuspendedTaskList)) {
+ prvGenerateRunTimeStatsForTasksInList(pcWriteBuffer, (xList *) &xSuspendedTaskList, ulTotalRunTime);
+ }
+ }
+#endif
+ }
+ xTaskResumeAll();
+}
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+void vTaskStartTrace(signed char * pcBuffer, unsigned long ulBufferSize)
+{
+ portENTER_CRITICAL();
+ {
+ pcTraceBuffer = (signed char *)pcBuffer;
+ pcTraceBufferStart = pcBuffer;
+ pcTraceBufferEnd = pcBuffer + (ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE);
+ xTracing = pdTRUE;
+ }
+ portEXIT_CRITICAL();
+}
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+unsigned long ulTaskEndTrace(void)
+{
+ unsigned long ulBufferLength;
+
+ portENTER_CRITICAL();
+ xTracing = pdFALSE;
+ portEXIT_CRITICAL();
+
+ ulBufferLength = (unsigned long)(pcTraceBuffer - pcTraceBufferStart);
+
+ return ulBufferLength;
+}
+
+#endif
+
+
+
+/*-----------------------------------------------------------
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
+ * documented in task.h
+ *----------------------------------------------------------*/
+
+
+void vTaskIncrementTick(void)
+{
+ /* Called by the portable layer each time a tick interrupt occurs.
+ Increments the tick then checks to see if the new tick value will cause any
+ tasks to be unblocked. */
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) {
+ ++xTickCount;
+ if (xTickCount == (portTickType) 0) {
+ xList *pxTemp;
+
+ /* Tick count has overflowed so we need to swap the delay lists.
+ If there are any items in pxDelayedTaskList here then there is
+ an error! */
+ pxTemp = pxDelayedTaskList;
+ pxDelayedTaskList = pxOverflowDelayedTaskList;
+ pxOverflowDelayedTaskList = pxTemp;
+ xNumOfOverflows++;
+ }
+
+ /* See if this tick has made a timeout expire. */
+ prvCheckDelayedTasks();
+ } else {
+ ++uxMissedTicks;
+
+ /* The tick hook gets called at regular intervals, even if the
+ scheduler is locked. */
+#if ( configUSE_TICK_HOOK == 1 )
+ {
+ extern void vApplicationTickHook(void);
+
+ vApplicationTickHook();
+ }
+#endif
+ }
+
+#if ( configUSE_TICK_HOOK == 1 )
+ {
+ extern void vApplicationTickHook(void);
+
+ /* Guard against the tick hook being called when the missed tick
+ count is being unwound (when the scheduler is being unlocked. */
+ if (uxMissedTicks == 0) {
+ vApplicationTickHook();
+ }
+ }
+#endif
+
+ traceTASK_INCREMENT_TICK(xTickCount);
+}
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_vTaskCleanUpResources == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
+
+void vTaskCleanUpResources(void)
+{
+ unsigned short usQueue;
+ volatile tskTCB *pxTCB;
+
+ usQueue = (unsigned short) uxTopUsedPriority + (unsigned short) 1;
+
+ /* Remove any TCB's from the ready queues. */
+ do {
+ usQueue--;
+
+ while (!listLIST_IS_EMPTY(&(pxReadyTasksLists[ usQueue ]))) {
+ listGET_OWNER_OF_NEXT_ENTRY(pxTCB, &(pxReadyTasksLists[ usQueue ]));
+ vListRemove((xListItem *) &(pxTCB->xGenericListItem));
+
+ prvDeleteTCB((tskTCB *) pxTCB);
+ }
+ } while (usQueue > (unsigned short) tskIDLE_PRIORITY);
+
+ /* Remove any TCB's from the delayed queue. */
+ while (!listLIST_IS_EMPTY(&xDelayedTaskList1)) {
+ listGET_OWNER_OF_NEXT_ENTRY(pxTCB, &xDelayedTaskList1);
+ vListRemove((xListItem *) &(pxTCB->xGenericListItem));
+
+ prvDeleteTCB((tskTCB *) pxTCB);
+ }
+
+ /* Remove any TCB's from the overflow delayed queue. */
+ while (!listLIST_IS_EMPTY(&xDelayedTaskList2)) {
+ listGET_OWNER_OF_NEXT_ENTRY(pxTCB, &xDelayedTaskList2);
+ vListRemove((xListItem *) &(pxTCB->xGenericListItem));
+
+ prvDeleteTCB((tskTCB *) pxTCB);
+ }
+
+ while (!listLIST_IS_EMPTY(&xSuspendedTaskList)) {
+ listGET_OWNER_OF_NEXT_ENTRY(pxTCB, &xSuspendedTaskList);
+ vListRemove((xListItem *) &(pxTCB->xGenericListItem));
+
+ prvDeleteTCB((tskTCB *) pxTCB);
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+
+void vTaskSetApplicationTaskTag(xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue)
+{
+ tskTCB *xTCB;
+
+ /* If xTask is NULL then we are setting our own task hook. */
+ if (xTask == NULL) {
+ xTCB = (tskTCB *) pxCurrentTCB;
+ } else {
+ xTCB = (tskTCB *) xTask;
+ }
+
+ /* Save the hook function in the TCB. A critical section is required as
+ the value can be accessed from an interrupt. */
+ portENTER_CRITICAL();
+ xTCB->pxTaskTag = pxTagValue;
+ portEXIT_CRITICAL();
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+
+pdTASK_HOOK_CODE xTaskGetApplicationTaskTag(xTaskHandle xTask)
+{
+ tskTCB *xTCB;
+ pdTASK_HOOK_CODE xReturn;
+
+ /* If xTask is NULL then we are setting our own task hook. */
+ if (xTask == NULL) {
+ xTCB = (tskTCB *) pxCurrentTCB;
+ } else {
+ xTCB = (tskTCB *) xTask;
+ }
+
+ /* Save the hook function in the TCB. A critical section is required as
+ the value can be accessed from an interrupt. */
+ portENTER_CRITICAL();
+ xReturn = xTCB->pxTaskTag;
+ portEXIT_CRITICAL();
+
+ return xReturn;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+
+portBASE_TYPE xTaskCallApplicationTaskHook(xTaskHandle xTask, void *pvParameter)
+{
+ tskTCB *xTCB;
+ portBASE_TYPE xReturn;
+
+ /* If xTask is NULL then we are calling our own task hook. */
+ if (xTask == NULL) {
+ xTCB = (tskTCB *) pxCurrentTCB;
+ } else {
+ xTCB = (tskTCB *) xTask;
+ }
+
+ if (xTCB->pxTaskTag != NULL) {
+ xReturn = xTCB->pxTaskTag(pvParameter);
+ } else {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+void vTaskSwitchContext(void)
+{
+ if (uxSchedulerSuspended != (unsigned portBASE_TYPE) pdFALSE) {
+ /* The scheduler is currently suspended - do not allow a context
+ switch. */
+ xMissedYield = pdTRUE;
+ return;
+ }
+
+ traceTASK_SWITCHED_OUT();
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+ {
+ unsigned long ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();
+
+ /* Add the amount of time the task has been running to the accumulated
+ time so far. The time the task started running was stored in
+ ulTaskSwitchedInTime. Note that there is no overflow protection here
+ so count values are only valid until the timer overflows. Generally
+ this will be about 1 hour assuming a 1uS timer increment. */
+ pxCurrentTCB->ulRunTimeCounter += (ulTempCounter - ulTaskSwitchedInTime);
+ ulTaskSwitchedInTime = ulTempCounter;
+ }
+#endif
+
+ taskFIRST_CHECK_FOR_STACK_OVERFLOW();
+ taskSECOND_CHECK_FOR_STACK_OVERFLOW();
+
+ /* Find the highest priority queue that contains ready tasks. */
+ while (listLIST_IS_EMPTY(&(pxReadyTasksLists[ uxTopReadyPriority ]))) {
+ --uxTopReadyPriority;
+ }
+
+ /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the
+ same priority get an equal share of the processor time. */
+ listGET_OWNER_OF_NEXT_ENTRY(pxCurrentTCB, &(pxReadyTasksLists[ uxTopReadyPriority ]));
+
+ traceTASK_SWITCHED_IN();
+ vWriteTraceToBuffer();
+}
+/*-----------------------------------------------------------*/
+
+void vTaskPlaceOnEventList(const xList * const pxEventList, portTickType xTicksToWait)
+{
+ portTickType xTimeToWake;
+
+ /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
+ SCHEDULER SUSPENDED. */
+
+ /* Place the event list item of the TCB in the appropriate event list.
+ This is placed in the list in priority order so the highest priority task
+ is the first to be woken by the event. */
+ vListInsert((xList *) pxEventList, (xListItem *) &(pxCurrentTCB->xEventListItem));
+
+ /* We must remove ourselves from the ready list before adding ourselves
+ to the blocked list as the same list item is used for both lists. We have
+ exclusive access to the ready lists as the scheduler is locked. */
+ vListRemove((xListItem *) &(pxCurrentTCB->xGenericListItem));
+
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+ {
+ if (xTicksToWait == portMAX_DELAY) {
+ /* Add ourselves to the suspended task list instead of a delayed task
+ list to ensure we are not woken by a timing event. We will block
+ indefinitely. */
+ vListInsertEnd((xList *) &xSuspendedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ } else {
+ /* Calculate the time at which the task should be woken if the event does
+ not occur. This may overflow but this doesn't matter. */
+ xTimeToWake = xTickCount + xTicksToWait;
+
+ listSET_LIST_ITEM_VALUE(&(pxCurrentTCB->xGenericListItem), xTimeToWake);
+
+ if (xTimeToWake < xTickCount) {
+ /* Wake time has overflowed. Place this item in the overflow list. */
+ vListInsert((xList *) pxOverflowDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ } else {
+ /* The wake time has not overflowed, so we can use the current block list. */
+ vListInsert((xList *) pxDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ }
+ }
+ }
+#else
+ {
+ /* Calculate the time at which the task should be woken if the event does
+ not occur. This may overflow but this doesn't matter. */
+ xTimeToWake = xTickCount + xTicksToWait;
+
+ listSET_LIST_ITEM_VALUE(&(pxCurrentTCB->xGenericListItem), xTimeToWake);
+
+ if (xTimeToWake < xTickCount) {
+ /* Wake time has overflowed. Place this item in the overflow list. */
+ vListInsert((xList *) pxOverflowDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ } else {
+ /* The wake time has not overflowed, so we can use the current block list. */
+ vListInsert((xList *) pxDelayedTaskList, (xListItem *) &(pxCurrentTCB->xGenericListItem));
+ }
+ }
+#endif
+}
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE xTaskRemoveFromEventList(const xList * const pxEventList)
+{
+ tskTCB *pxUnblockedTCB;
+ portBASE_TYPE xReturn;
+
+ /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
+ SCHEDULER SUSPENDED. It can also be called from within an ISR. */
+
+ /* The event list is sorted in priority order, so we can remove the
+ first in the list, remove the TCB from the delayed list, and add
+ it to the ready list.
+
+ If an event is for a queue that is locked then this function will never
+ get called - the lock count on the queue will get modified instead. This
+ means we can always expect exclusive access to the event list here. */
+ pxUnblockedTCB = (tskTCB *) listGET_OWNER_OF_HEAD_ENTRY(pxEventList);
+ vListRemove(&(pxUnblockedTCB->xEventListItem));
+
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) {
+ vListRemove(&(pxUnblockedTCB->xGenericListItem));
+ prvAddTaskToReadyQueue(pxUnblockedTCB);
+ } else {
+ /* We cannot access the delayed or ready lists, so will hold this
+ task pending until the scheduler is resumed. */
+ vListInsertEnd((xList *) &(xPendingReadyList), &(pxUnblockedTCB->xEventListItem));
+ }
+
+ if (pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority) {
+ /* Return true if the task removed from the event list has
+ a higher priority than the calling task. This allows
+ the calling task to know if it should force a context
+ switch now. */
+ xReturn = pdTRUE;
+ } else {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vTaskSetTimeOutState(xTimeOutType * const pxTimeOut)
+{
+ pxTimeOut->xOverflowCount = xNumOfOverflows;
+ pxTimeOut->xTimeOnEntering = xTickCount;
+}
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE xTaskCheckForTimeOut(xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait)
+{
+ portBASE_TYPE xReturn;
+
+ portENTER_CRITICAL();
+ {
+#if ( INCLUDE_vTaskSuspend == 1 )
+ /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
+ the maximum block time then the task should block indefinitely, and
+ therefore never time out. */
+ if (*pxTicksToWait == portMAX_DELAY) {
+ xReturn = pdFALSE;
+ } else /* We are not blocking indefinitely, perform the checks below. */
+#endif
+
+ if ((xNumOfOverflows != pxTimeOut->xOverflowCount) && ((portTickType) xTickCount >= (portTickType) pxTimeOut->xTimeOnEntering)) {
+ /* The tick count is greater than the time at which vTaskSetTimeout()
+ was called, but has also overflowed since vTaskSetTimeOut() was called.
+ It must have wrapped all the way around and gone past us again. This
+ passed since vTaskSetTimeout() was called. */
+ xReturn = pdTRUE;
+ } else if (((portTickType)((portTickType) xTickCount - (portTickType) pxTimeOut->xTimeOnEntering)) < (portTickType) *pxTicksToWait) {
+ /* Not a genuine timeout. Adjust parameters for time remaining. */
+ *pxTicksToWait -= ((portTickType) xTickCount - (portTickType) pxTimeOut->xTimeOnEntering);
+ vTaskSetTimeOutState(pxTimeOut);
+ xReturn = pdFALSE;
+ } else {
+ xReturn = pdTRUE;
+ }
+ }
+ portEXIT_CRITICAL();
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vTaskMissedYield(void)
+{
+ xMissedYield = pdTRUE;
+}
+
+/*
+ * -----------------------------------------------------------
+ * The Idle task.
+ * ----------------------------------------------------------
+ *
+ * The portTASK_FUNCTION() macro is used to allow port/compiler specific
+ * language extensions. The equivalent prototype for this function is:
+ *
+ * void prvIdleTask( void *pvParameters );
+ *
+ */
+static portTASK_FUNCTION(prvIdleTask, pvParameters)
+{
+ /* Stop warnings. */
+ (void) pvParameters;
+
+ for (;;) {
+ /* See if any tasks have been deleted. */
+ prvCheckTasksWaitingTermination();
+
+#if ( configUSE_PREEMPTION == 0 )
+ {
+ /* If we are not using preemption we keep forcing a task switch to
+ see if any other task has become available. If we are using
+ preemption we don't need to do this as any task becoming available
+ will automatically get the processor anyway. */
+ taskYIELD();
+ }
+#endif
+
+#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
+ {
+ /* When using preemption tasks of equal priority will be
+ timesliced. If a task that is sharing the idle priority is ready
+ to run then the idle task should yield before the end of the
+ timeslice.
+
+ A critical region is not required here as we are just reading from
+ the list, and an occasional incorrect value will not matter. If
+ the ready list at the idle priority contains more than one task
+ then a task other than the idle task is ready to execute. */
+ if (listCURRENT_LIST_LENGTH(&(pxReadyTasksLists[ tskIDLE_PRIORITY ])) > (unsigned portBASE_TYPE) 1) {
+ taskYIELD();
+ }
+ }
+#endif
+
+#if ( configUSE_IDLE_HOOK == 1 )
+ {
+ extern void vApplicationIdleHook(void);
+
+ /* Call the user defined function from within the idle task. This
+ allows the application designer to add background functionality
+ without the overhead of a separate task.
+ NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
+ CALL A FUNCTION THAT MIGHT BLOCK. */
+ vApplicationIdleHook();
+ }
+#endif
+ }
+} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */
+
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * File private functions documented at the top of the file.
+ *----------------------------------------------------------*/
+
+
+
+static void prvInitialiseTCBVariables(tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth)
+{
+ /* Store the function name in the TCB. */
+#if configMAX_TASK_NAME_LEN > 1
+ {
+ /* Don't bring strncpy into the build unnecessarily. */
+ strncpy((char *) pxTCB->pcTaskName, (const char *) pcName, (unsigned short) configMAX_TASK_NAME_LEN);
+ }
+#endif
+ pxTCB->pcTaskName[(unsigned short) configMAX_TASK_NAME_LEN - (unsigned short) 1 ] = '\0';
+
+ /* This is used as an array index so must ensure it's not too large. First
+ remove the privilege bit if one is present. */
+ if (uxPriority >= configMAX_PRIORITIES) {
+ uxPriority = configMAX_PRIORITIES - 1;
+ }
+
+ pxTCB->uxPriority = uxPriority;
+#if ( configUSE_MUTEXES == 1 )
+ {
+ pxTCB->uxBasePriority = uxPriority;
+ }
+#endif
+
+ vListInitialiseItem(&(pxTCB->xGenericListItem));
+ vListInitialiseItem(&(pxTCB->xEventListItem));
+
+ /* Set the pxTCB as a link back from the xListItem. This is so we can get
+ back to the containing TCB from a generic item in a list. */
+ listSET_LIST_ITEM_OWNER(&(pxTCB->xGenericListItem), pxTCB);
+
+ /* Event lists are always in priority order. */
+ listSET_LIST_ITEM_VALUE(&(pxTCB->xEventListItem), configMAX_PRIORITIES - (portTickType) uxPriority);
+ listSET_LIST_ITEM_OWNER(&(pxTCB->xEventListItem), pxTCB);
+
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )
+ {
+ pxTCB->uxCriticalNesting = (unsigned portBASE_TYPE) 0;
+ }
+#endif
+
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )
+ {
+ pxTCB->pxTaskTag = NULL;
+ }
+#endif
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+ {
+ pxTCB->ulRunTimeCounter = 0UL;
+ }
+#endif
+
+#if ( portUSING_MPU_WRAPPERS == 1 )
+ {
+ vPortStoreTaskMPUSettings(&(pxTCB->xMPUSettings), xRegions, pxTCB->pxStack, usStackDepth);
+ }
+#else
+ {
+ (void) xRegions;
+ (void) usStackDepth;
+ }
+#endif
+}
+/*-----------------------------------------------------------*/
+
+#if ( portUSING_MPU_WRAPPERS == 1 )
+
+void vTaskAllocateMPURegions(xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions)
+{
+ tskTCB *pxTCB;
+
+ if (xTaskToModify == pxCurrentTCB) {
+ xTaskToModify = NULL;
+ }
+
+ /* If null is passed in here then we are deleting ourselves. */
+ pxTCB = prvGetTCBFromHandle(xTaskToModify);
+
+ vPortStoreTaskMPUSettings(&(pxTCB->xMPUSettings), xRegions, NULL, 0);
+}
+/*-----------------------------------------------------------*/
+#endif
+
+static void prvInitialiseTaskLists(void)
+{
+ unsigned portBASE_TYPE uxPriority;
+
+ for (uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++) {
+ vListInitialise((xList *) &(pxReadyTasksLists[ uxPriority ]));
+ }
+
+ vListInitialise((xList *) &xDelayedTaskList1);
+ vListInitialise((xList *) &xDelayedTaskList2);
+ vListInitialise((xList *) &xPendingReadyList);
+
+#if ( INCLUDE_vTaskDelete == 1 )
+ {
+ vListInitialise((xList *) &xTasksWaitingTermination);
+ }
+#endif
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+ {
+ vListInitialise((xList *) &xSuspendedTaskList);
+ }
+#endif
+
+ /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
+ using list2. */
+ pxDelayedTaskList = &xDelayedTaskList1;
+ pxOverflowDelayedTaskList = &xDelayedTaskList2;
+}
+/*-----------------------------------------------------------*/
+
+static void prvCheckTasksWaitingTermination(void)
+{
+#if ( INCLUDE_vTaskDelete == 1 )
+ {
+ portBASE_TYPE xListIsEmpty;
+
+ /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
+ too often in the idle task. */
+ if (uxTasksDeleted > (unsigned portBASE_TYPE) 0) {
+ vTaskSuspendAll();
+ xListIsEmpty = listLIST_IS_EMPTY(&xTasksWaitingTermination);
+ xTaskResumeAll();
+
+ if (!xListIsEmpty) {
+ tskTCB *pxTCB;
+
+ portENTER_CRITICAL();
+ {
+ pxTCB = (tskTCB *) listGET_OWNER_OF_HEAD_ENTRY(((xList *) & xTasksWaitingTermination));
+ vListRemove(&(pxTCB->xGenericListItem));
+ --uxCurrentNumberOfTasks;
+ --uxTasksDeleted;
+ }
+ portEXIT_CRITICAL();
+
+ prvDeleteTCB(pxTCB);
+ }
+ }
+ }
+#endif
+}
+/*-----------------------------------------------------------*/
+
+static tskTCB *prvAllocateTCBAndStack(unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer)
+{
+ tskTCB *pxNewTCB;
+
+ /* Allocate space for the TCB. Where the memory comes from depends on
+ the implementation of the port malloc function. */
+ pxNewTCB = (tskTCB *) pvPortMalloc(sizeof(tskTCB));
+
+ if (pxNewTCB != NULL) {
+ /* Allocate space for the stack used by the task being created.
+ The base of the stack memory stored in the TCB so the task can
+ be deleted later if required. */
+ pxNewTCB->pxStack = (portSTACK_TYPE *) pvPortMallocAligned((((size_t)usStackDepth) * sizeof(portSTACK_TYPE)), puxStackBuffer);
+
+ if (pxNewTCB->pxStack == NULL) {
+ /* Could not allocate the stack. Delete the allocated TCB. */
+ vPortFree(pxNewTCB);
+ pxNewTCB = NULL;
+ } else {
+ /* Just to help debugging. */
+ memset(pxNewTCB->pxStack, tskSTACK_FILL_BYTE, usStackDepth * sizeof(portSTACK_TYPE));
+ }
+ }
+
+ return pxNewTCB;
+}
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+static void prvListTaskWithinSingleList(const signed char *pcWriteBuffer, xList *pxList, signed char cStatus)
+{
+ volatile tskTCB *pxNextTCB, *pxFirstTCB;
+ unsigned short usStackRemaining;
+
+ /* Write the details of all the TCB's in pxList into the buffer. */
+ listGET_OWNER_OF_NEXT_ENTRY(pxFirstTCB, pxList);
+ do {
+ listGET_OWNER_OF_NEXT_ENTRY(pxNextTCB, pxList);
+#if ( portSTACK_GROWTH > 0 )
+ {
+ usStackRemaining = usTaskCheckFreeStackSpace((unsigned char *) pxNextTCB->pxEndOfStack);
+ }
+#else
+ {
+ usStackRemaining = usTaskCheckFreeStackSpace((unsigned char *) pxNextTCB->pxStack);
+ }
+#endif
+
+ sprintf(pcStatusString, (char *) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, (unsigned int) pxNextTCB->uxPriority, usStackRemaining, (unsigned int) pxNextTCB->uxTCBNumber);
+ strcat((char *) pcWriteBuffer, (char *) pcStatusString);
+
+ } while (pxNextTCB != pxFirstTCB);
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configGENERATE_RUN_TIME_STATS == 1 )
+
+static void prvGenerateRunTimeStatsForTasksInList(const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime)
+{
+ volatile tskTCB *pxNextTCB, *pxFirstTCB;
+ unsigned long ulStatsAsPercentage;
+
+ /* Write the run time stats of all the TCB's in pxList into the buffer. */
+ listGET_OWNER_OF_NEXT_ENTRY(pxFirstTCB, pxList);
+ do {
+ /* Get next TCB in from the list. */
+ listGET_OWNER_OF_NEXT_ENTRY(pxNextTCB, pxList);
+
+ /* Divide by zero check. */
+ if (ulTotalRunTime > 0UL) {
+ /* Has the task run at all? */
+ if (pxNextTCB->ulRunTimeCounter == 0) {
+ /* The task has used no CPU time at all. */
+ sprintf(pcStatsString, (char *) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName);
+ } else {
+ /* What percentage of the total run time as the task used?
+ This will always be rounded down to the nearest integer. */
+ ulStatsAsPercentage = (100UL * pxNextTCB->ulRunTimeCounter) / ulTotalRunTime;
+
+ if (ulStatsAsPercentage > 0UL) {
+ sprintf(pcStatsString, (char *) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, (unsigned int) pxNextTCB->ulRunTimeCounter, (unsigned int) ulStatsAsPercentage);
+ } else {
+ /* If the percentage is zero here then the task has
+ consumed less than 1% of the total run time. */
+ sprintf(pcStatsString, (char *) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, (unsigned int) pxNextTCB->ulRunTimeCounter);
+ }
+ }
+
+ strcat((char *) pcWriteBuffer, (char *) pcStatsString);
+ }
+
+ } while (pxNextTCB != pxFirstTCB);
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
+
+static unsigned short usTaskCheckFreeStackSpace(const unsigned char * pucStackByte)
+{
+ register unsigned short usCount = 0;
+
+ while (*pucStackByte == tskSTACK_FILL_BYTE) {
+ pucStackByte -= portSTACK_GROWTH;
+ usCount++;
+ }
+
+ usCount /= sizeof(portSTACK_TYPE);
+
+ return usCount;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
+
+unsigned portBASE_TYPE uxTaskGetStackHighWaterMark(xTaskHandle xTask)
+{
+ tskTCB *pxTCB;
+ unsigned char *pcEndOfStack;
+ unsigned portBASE_TYPE uxReturn;
+
+ pxTCB = prvGetTCBFromHandle(xTask);
+
+#if portSTACK_GROWTH < 0
+ {
+ pcEndOfStack = (unsigned char *) pxTCB->pxStack;
+ }
+#else
+ {
+ pcEndOfStack = (unsigned char *) pxTCB->pxEndOfStack;
+ }
+#endif
+
+ uxReturn = (unsigned portBASE_TYPE) usTaskCheckFreeStackSpace(pcEndOfStack);
+
+ return uxReturn;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
+
+static void prvDeleteTCB(tskTCB *pxTCB)
+{
+ /* Free up the memory allocated by the scheduler for the task. It is up to
+ the task to free any memory allocated at the application level. */
+ vPortFreeAligned(pxTCB->pxStack);
+ vPortFree(pxTCB);
+}
+
+#endif
+
+
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 )
+
+xTaskHandle xTaskGetCurrentTaskHandle(void)
+{
+ xTaskHandle xReturn;
+
+ /* A critical section is not required as this is not called from
+ an interrupt and the current TCB will always be the same for any
+ individual execution thread. */
+ xReturn = pxCurrentTCB;
+
+ return xReturn;
+}
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_xTaskGetSchedulerState == 1 )
+
+portBASE_TYPE xTaskGetSchedulerState(void)
+{
+ portBASE_TYPE xReturn;
+
+ if (xSchedulerRunning == pdFALSE) {
+ xReturn = taskSCHEDULER_NOT_STARTED;
+ } else {
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) {
+ xReturn = taskSCHEDULER_RUNNING;
+ } else {
+ xReturn = taskSCHEDULER_SUSPENDED;
+ }
+ }
+
+ return xReturn;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_MUTEXES == 1 )
+
+void vTaskPriorityInherit(xTaskHandle * const pxMutexHolder)
+{
+ tskTCB * const pxTCB = (tskTCB *) pxMutexHolder;
+
+ if (pxTCB->uxPriority < pxCurrentTCB->uxPriority) {
+ /* Adjust the mutex holder state to account for its new priority. */
+ listSET_LIST_ITEM_VALUE(&(pxTCB->xEventListItem), configMAX_PRIORITIES - (portTickType) pxCurrentTCB->uxPriority);
+
+ /* If the task being modified is in the ready state it will need to
+ be moved in to a new list. */
+ if (listIS_CONTAINED_WITHIN(&(pxReadyTasksLists[ pxTCB->uxPriority ]), &(pxTCB->xGenericListItem))) {
+ vListRemove(&(pxTCB->xGenericListItem));
+
+ /* Inherit the priority before being moved into the new list. */
+ pxTCB->uxPriority = pxCurrentTCB->uxPriority;
+ prvAddTaskToReadyQueue(pxTCB);
+ } else {
+ /* Just inherit the priority. */
+ pxTCB->uxPriority = pxCurrentTCB->uxPriority;
+ }
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_MUTEXES == 1 )
+
+void vTaskPriorityDisinherit(xTaskHandle * const pxMutexHolder)
+{
+ tskTCB * const pxTCB = (tskTCB *) pxMutexHolder;
+
+ if (pxMutexHolder != NULL) {
+ if (pxTCB->uxPriority != pxTCB->uxBasePriority) {
+ /* We must be the running task to be able to give the mutex back.
+ Remove ourselves from the ready list we currently appear in. */
+ vListRemove(&(pxTCB->xGenericListItem));
+
+ /* Disinherit the priority before adding ourselves into the new
+ ready list. */
+ pxTCB->uxPriority = pxTCB->uxBasePriority;
+ listSET_LIST_ITEM_VALUE(&(pxTCB->xEventListItem), configMAX_PRIORITIES - (portTickType) pxTCB->uxPriority);
+ prvAddTaskToReadyQueue(pxTCB);
+ }
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )
+
+void vTaskEnterCritical(void)
+{
+ portDISABLE_INTERRUPTS();
+
+ if (xSchedulerRunning != pdFALSE) {
+ pxCurrentTCB->uxCriticalNesting++;
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )
+
+void vTaskExitCritical(void)
+{
+ if (xSchedulerRunning != pdFALSE) {
+ if (pxCurrentTCB->uxCriticalNesting > 0) {
+ pxCurrentTCB->uxCriticalNesting--;
+
+ if (pxCurrentTCB->uxCriticalNesting == 0) {
+ portENABLE_INTERRUPTS();
+ }
+ }
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+
+
+
diff --git a/gyro_board/src/usb/FreeRTOSConfig.h b/gyro_board/src/usb/FreeRTOSConfig.h
new file mode 100644
index 0000000..5a46dad
--- /dev/null
+++ b/gyro_board/src/usb/FreeRTOSConfig.h
@@ -0,0 +1,159 @@
+/*
+ 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.
+*/
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include "LPC17xx.h"
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *----------------------------------------------------------*/
+
+#define configUSE_PREEMPTION 1
+#define configUSE_IDLE_HOOK 0
+#define configMAX_PRIORITIES ((unsigned portBASE_TYPE) 5)
+#define configUSE_TICK_HOOK 1
+#define configCPU_CLOCK_HZ ((unsigned long) 100000000)
+#define configTICK_RATE_HZ ((portTickType ) 1000)
+#define configMINIMAL_STACK_SIZE ((unsigned short) 80)
+#define configTOTAL_HEAP_SIZE ((size_t) (19 * 1024))
+#define configMAX_TASK_NAME_LEN (12)
+#define configUSE_TRACE_FACILITY 1
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 0
+#define configUSE_CO_ROUTINES 0
+#define configUSE_MUTEXES 1
+
+#define configMAX_CO_ROUTINE_PRIORITIES (2)
+
+#define configUSE_COUNTING_SEMAPHORES 0
+#define configUSE_ALTERNATIVE_API 0
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configQUEUE_REGISTRY_SIZE 10
+#define configGENERATE_RUN_TIME_STATS 1
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 0
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+
+/*-----------------------------------------------------------
+ * Ethernet configuration.
+ *-----------------------------------------------------------*/
+
+/* MAC address configuration. */
+#define configMAC_ADDR0 0x00
+#define configMAC_ADDR1 0x12
+#define configMAC_ADDR2 0x13
+#define configMAC_ADDR3 0x10
+#define configMAC_ADDR4 0x15
+#define configMAC_ADDR5 0x11
+
+/* IP address configuration. */
+#define configIP_ADDR0 192
+#define configIP_ADDR1 168
+#define configIP_ADDR2 0
+#define configIP_ADDR3 201
+
+/* Netmask configuration. */
+#define configNET_MASK0 255
+#define configNET_MASK1 255
+#define configNET_MASK2 255
+#define configNET_MASK3 0
+
+/* Use the system definition, if there is one */
+#ifdef __NVIC_PRIO_BITS
+#define configPRIO_BITS __NVIC_PRIO_BITS
+#else
+#define configPRIO_BITS 5 /* 32 priority levels */
+#endif
+
+/* The lowest priority. */
+#define configKERNEL_INTERRUPT_PRIORITY (31 << (8 - configPRIO_BITS))
+/* Priority 5, or 160 as only the top three bits are implemented. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY (5 << (8 - configPRIO_BITS))
+
+/* Priorities passed to NVIC_SetPriority() do not require shifting as the
+function does the shifting itself. Note these priorities need to be equal to
+or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY - therefore the numeric
+value needs to be equal to or greater than 5 (on the Cortex M3 the lower the
+numeric value the higher the interrupt priority). */
+#define configEMAC_INTERRUPT_PRIORITY 5
+#define configCAN_INTERRUPT_PRIORITY 5
+#define configUSB_INTERRUPT_PRIORITY 6
+
+
+
+/*-----------------------------------------------------------
+ * Macros required to setup the timer for the run time stats.
+ *-----------------------------------------------------------*/
+extern void vConfigureTimerForRunTimeStats(void);
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
+#define portGET_RUN_TIME_COUNTER_VALUE() TIM0->TC
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/gyro_board/src/usb/LPC17xx.h b/gyro_board/src/usb/LPC17xx.h
new file mode 100644
index 0000000..1743027
--- /dev/null
+++ b/gyro_board/src/usb/LPC17xx.h
@@ -0,0 +1,1052 @@
+#ifndef __LPC17xx_H
+#define __LPC17xx_H
+
+/* System Control Block (SCB) includes:
+ Flash Accelerator Module, Clocking and Power Control, External Interrupts,
+ Reset, System Control and Status
+*/
+#define SCB_BASE_ADDR 0x400FC000
+
+#define PCONP_PCTIM0 0x00000002
+#define PCONP_PCTIM1 0x00000004
+#define PCONP_PCUART0 0x00000008
+#define PCONP_PCUART1 0x00000010
+#define PCONP_PCPWM1 0x00000040
+#define PCONP_PCI2C0 0x00000080
+#define PCONP_PCSPI 0x00000100
+#define PCONP_PCRTC 0x00000200
+#define PCONP_PCSSP1 0x00000400
+#define PCONP_PCAD 0x00001000
+#define PCONP_PCCAN1 0x00002000
+#define PCONP_PCCAN2 0x00004000
+#define PCONP_PCGPIO 0x00008000
+#define PCONP_PCRIT 0x00010000
+#define PCONP_PCMCPWM 0x00020000
+#define PCONP_PCQEI 0x00040000
+#define PCONP_PCI2C1 0x00080000
+#define PCONP_PCSSP0 0x00200000
+#define PCONP_PCTIM2 0x00400000
+#define PCONP_PCTIM3 0x00800000
+#define PCONP_PCUART2 0x01000000
+#define PCONP_PCUART3 0x02000000
+#define PCONP_PCI2C2 0x04000000
+#define PCONP_PCI2S 0x08000000
+#define PCONP_PCGPDMA 0x20000000
+#define PCONP_PCENET 0x40000000
+#define PCONP_PCUSB 0x80000000
+
+#define PLLCON_PLLE 0x00000001
+#define PLLCON_PLLC 0x00000002
+#define PLLCON_MASK 0x00000003
+
+#define PLLCFG_MUL1 0x00000000
+#define PLLCFG_MUL2 0x00000001
+#define PLLCFG_MUL3 0x00000002
+#define PLLCFG_MUL4 0x00000003
+#define PLLCFG_MUL5 0x00000004
+#define PLLCFG_MUL6 0x00000005
+#define PLLCFG_MUL7 0x00000006
+#define PLLCFG_MUL8 0x00000007
+#define PLLCFG_MUL9 0x00000008
+#define PLLCFG_MUL10 0x00000009
+#define PLLCFG_MUL11 0x0000000A
+#define PLLCFG_MUL12 0x0000000B
+#define PLLCFG_MUL13 0x0000000C
+#define PLLCFG_MUL14 0x0000000D
+#define PLLCFG_MUL15 0x0000000E
+#define PLLCFG_MUL16 0x0000000F
+#define PLLCFG_MUL17 0x00000010
+#define PLLCFG_MUL18 0x00000011
+#define PLLCFG_MUL19 0x00000012
+#define PLLCFG_MUL20 0x00000013
+#define PLLCFG_MUL21 0x00000014
+#define PLLCFG_MUL22 0x00000015
+#define PLLCFG_MUL23 0x00000016
+#define PLLCFG_MUL24 0x00000017
+#define PLLCFG_MUL25 0x00000018
+#define PLLCFG_MUL26 0x00000019
+#define PLLCFG_MUL27 0x0000001A
+#define PLLCFG_MUL28 0x0000001B
+#define PLLCFG_MUL29 0x0000001C
+#define PLLCFG_MUL30 0x0000001D
+#define PLLCFG_MUL31 0x0000001E
+#define PLLCFG_MUL32 0x0000001F
+#define PLLCFG_MUL33 0x00000020
+#define PLLCFG_MUL34 0x00000021
+#define PLLCFG_MUL35 0x00000022
+#define PLLCFG_MUL36 0x00000023
+
+#define PLLCFG_DIV1 0x00000000
+#define PLLCFG_DIV2 0x00010000
+#define PLLCFG_DIV3 0x00020000
+#define PLLCFG_DIV4 0x00030000
+#define PLLCFG_DIV5 0x00040000
+#define PLLCFG_DIV6 0x00050000
+#define PLLCFG_DIV7 0x00060000
+#define PLLCFG_DIV8 0x00070000
+#define PLLCFG_DIV9 0x00080000
+#define PLLCFG_DIV10 0x00090000
+#define PLLCFG_MASK 0x00FF7FFF
+
+#define PLLSTAT_MSEL_MASK 0x00007FFF
+#define PLLSTAT_NSEL_MASK 0x00FF0000
+
+#define PLLSTAT_PLLE (1 << 24)
+#define PLLSTAT_PLLC (1 << 25)
+#define PLLSTAT_PLOCK (1 << 26)
+
+#define PLLFEED_FEED1 0x000000AA
+#define PLLFEED_FEED2 0x00000055
+
+#define NVIC_IRQ_WDT 0u // IRQ0, exception number 16
+#define NVIC_IRQ_TIMER0 1u // IRQ1, exception number 17
+#define NVIC_IRQ_TIMER1 2u // IRQ2, exception number 18
+#define NVIC_IRQ_TIMER2 3u // IRQ3, exception number 19
+#define NVIC_IRQ_TIMER3 4u // IRQ4, exception number 20
+#define NVIC_IRQ_UART0 5u // IRQ5, exception number 21
+#define NVIC_IRQ_UART1 6u // IRQ6, exception number 22
+#define NVIC_IRQ_UART2 7u // IRQ7, exception number 23
+#define NVIC_IRQ_UART3 8u // IRQ8, exception number 24
+#define NVIC_IRQ_PWM1 9u // IRQ9, exception number 25
+#define NVIC_IRQ_I2C0 10u // IRQ10, exception number 26
+#define NVIC_IRQ_I2C1 11u // IRQ11, exception number 27
+#define NVIC_IRQ_I2C2 12u // IRQ12, exception number 28
+#define NVIC_IRQ_SPI 13u // IRQ13, exception number 29
+#define NVIC_IRQ_SSP0 14u // IRQ14, exception number 30
+#define NVIC_IRQ_SSP1 15u // IRQ15, exception number 31
+#define NVIC_IRQ_PLL0 16u // IRQ16, exception number 32
+#define NVIC_IRQ_RTC 17u // IRQ17, exception number 33
+#define NVIC_IRQ_EINT0 18u // IRQ18, exception number 34
+#define NVIC_IRQ_EINT1 19u // IRQ19, exception number 35
+#define NVIC_IRQ_EINT2 20u // IRQ20, exception number 36
+#define NVIC_IRQ_EINT3 21u // IRQ21, exception number 37
+#define NVIC_IRQ_ADC 22u // IRQ22, exception number 38
+#define NVIC_IRQ_BOD 23u // IRQ23, exception number 39
+#define NVIC_IRQ_USB 24u // IRQ24, exception number 40
+#define NVIC_IRQ_CAN 25u // IRQ25, exception number 41
+#define NVIC_IRQ_GPDMA 26u // IRQ26, exception number 42
+#define NVIC_IRQ_I2S 27u // IRQ27, exception number 43
+#define NVIC_IRQ_ETHERNET 28u // IRQ28, exception number 44
+#define NVIC_IRQ_RIT 29u // IRQ29, exception number 45
+#define NVIC_IRQ_MCPWM 30u // IRQ30, exception number 46
+#define NVIC_IRQ_QE 31u // IRQ31, exception number 47
+#define NVIC_IRQ_PLL1 32u // IRQ32, exception number 48
+#define NVIC_IRQ_USB_ACT 33u // IRQ33, exception number 49
+#define NVIC_IRQ_CAN_ACT 34u // IRQ34, exception number 50
+
+
+#endif // __LPC17xx_H
+
+
+#ifndef CMSIS_17xx_H
+#define CMSIS_17xx_H
+
+/******************************************************************************
+ * @file: LPC17xx.h
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File for
+ * NXP LPC17xx Device Series
+ * @version: V1.1
+ * @date: 14th May 2009
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2008 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". 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.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#ifndef __LPC17xx_H__
+#define __LPC17xx_H__
+
+/*
+ * ==========================================================================
+ * ---------- Interrupt Number Definition -----------------------------------
+ * ==========================================================================
+ */
+
+typedef enum IRQn {
+ /****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
+ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
+ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
+
+ /****** LPC17xx Specific Interrupt Numbers *******************************************************/
+ WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */
+ TIMER0_IRQn = 1, /*!< Timer0 Interrupt */
+ TIMER1_IRQn = 2, /*!< Timer1 Interrupt */
+ TIMER2_IRQn = 3, /*!< Timer2 Interrupt */
+ TIMER3_IRQn = 4, /*!< Timer3 Interrupt */
+ UART0_IRQn = 5, /*!< UART0 Interrupt */
+ UART1_IRQn = 6, /*!< UART1 Interrupt */
+ UART2_IRQn = 7, /*!< UART2 Interrupt */
+ UART3_IRQn = 8, /*!< UART3 Interrupt */
+ PWM1_IRQn = 9, /*!< PWM1 Interrupt */
+ I2C0_IRQn = 10, /*!< I2C0 Interrupt */
+ I2C1_IRQn = 11, /*!< I2C1 Interrupt */
+ I2C2_IRQn = 12, /*!< I2C2 Interrupt */
+ SPI_IRQn = 13, /*!< SPI Interrupt */
+ SSP0_IRQn = 14, /*!< SSP0 Interrupt */
+ SSP1_IRQn = 15, /*!< SSP1 Interrupt */
+ PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */
+ RTC_IRQn = 17, /*!< Real Time Clock Interrupt */
+ EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */
+ EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */
+ EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */
+ EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */
+ ADC_IRQn = 22, /*!< A/D Converter Interrupt */
+ BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */
+ USB_IRQn = 24, /*!< USB Interrupt */
+ CAN_IRQn = 25, /*!< CAN Interrupt */
+ DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */
+ I2S_IRQn = 27, /*!< I2S Interrupt */
+ ENET_IRQn = 28, /*!< Ethernet Interrupt */
+ RIT_IRQn = 29, /*!< Repetitive Interrupt Timer Interrupt */
+ MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */
+ QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */
+ PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */
+} IRQn_Type;
+
+
+/*
+ * ==========================================================================
+ * ----------- Processor and Core Peripheral Section ------------------------
+ * ==========================================================================
+ */
+
+/* Configuration of the Cortex-M3 Processor and Core Peripherals */
+#define __MPU_PRESENT 1 /*!< MPU present or not */
+#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+
+
+//#include "..\core_cm3.h" /* Cortex-M3 processor and core peripherals */
+#include "core_cm3.h"
+#include "system_LPC17xx.h" /* System Header */
+
+
+
+/**
+ * Initialize the system clock
+ *
+ * @param none
+ * @return none
+ *
+ * @brief Setup the microcontroller system.
+ * Initialize the System and update the SystemFrequency variable.
+ */
+extern void SystemInit(void);
+
+
+/******************************************************************************/
+/* Device Specific Peripheral registers structures */
+/******************************************************************************/
+
+/*------------- System Control (SC) ------------------------------------------*/
+typedef struct {
+ __IO uint32_t FLASHCFG; /* Flash Accelerator Module */
+ uint32_t RESERVED0[31];
+ __IO uint32_t PLL0CON; /* Clocking and Power Control */
+ __IO uint32_t PLL0CFG;
+ __I uint32_t PLL0STAT;
+ __O uint32_t PLL0FEED;
+ uint32_t RESERVED1[4];
+ __IO uint32_t PLL1CON;
+ __IO uint32_t PLL1CFG;
+ __I uint32_t PLL1STAT;
+ __O uint32_t PLL1FEED;
+ uint32_t RESERVED2[4];
+ __IO uint32_t PCON;
+ __IO uint32_t PCONP;
+ uint32_t RESERVED3[15];
+ __IO uint32_t CCLKCFG;
+ __IO uint32_t USBCLKCFG;
+ __IO uint32_t CLKSRCSEL;
+ uint32_t RESERVED4[12];
+ __IO uint32_t EXTINT; /* External Interrupts */
+ uint32_t RESERVED5;
+ __IO uint32_t EXTMODE;
+ __IO uint32_t EXTPOLAR;
+ uint32_t RESERVED6[12];
+ __IO uint32_t RSID; /* Reset */
+ uint32_t RESERVED7[7];
+ __IO uint32_t SCS; /* Syscon Miscellaneous Registers */
+ __IO uint32_t IRCTRIM; /* Clock Dividers */
+ __IO uint32_t PCLKSEL0;
+ __IO uint32_t PCLKSEL1;
+ uint32_t RESERVED8[4];
+ __IO uint32_t USBIntSt; /* USB Device/OTG Interrupt Register */
+ uint32_t RESERVED9;
+ __IO uint32_t CLKOUTCFG; /* Clock Output Configuration */
+} SC_TypeDef;
+
+/*------------- Pin Connect Block (PINCON) -----------------------------------*/
+typedef struct {
+ __IO uint32_t PINSEL0;
+ __IO uint32_t PINSEL1;
+ __IO uint32_t PINSEL2;
+ __IO uint32_t PINSEL3;
+ __IO uint32_t PINSEL4;
+ __IO uint32_t PINSEL5;
+ __IO uint32_t PINSEL6;
+ __IO uint32_t PINSEL7;
+ __IO uint32_t PINSEL8;
+ __IO uint32_t PINSEL9;
+ __IO uint32_t PINSEL10;
+ uint32_t RESERVED0[5];
+ __IO uint32_t PINMODE0;
+ __IO uint32_t PINMODE1;
+ __IO uint32_t PINMODE2;
+ __IO uint32_t PINMODE3;
+ __IO uint32_t PINMODE4;
+ __IO uint32_t PINMODE5;
+ __IO uint32_t PINMODE6;
+ __IO uint32_t PINMODE7;
+ __IO uint32_t PINMODE8;
+ __IO uint32_t PINMODE9;
+ __IO uint32_t PINMODE_OD0;
+ __IO uint32_t PINMODE_OD1;
+ __IO uint32_t PINMODE_OD2;
+ __IO uint32_t PINMODE_OD3;
+ __IO uint32_t PINMODE_OD4;
+} PINCON_TypeDef;
+
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/
+typedef struct {
+ __IO uint32_t FIODIR;
+ uint32_t RESERVED0[3];
+ __IO uint32_t FIOMASK;
+ __IO uint32_t FIOPIN;
+ __IO uint32_t FIOSET;
+ __O uint32_t FIOCLR;
+} GPIO_TypeDef;
+
+typedef struct {
+ __I uint32_t IntStatus;
+ __I uint32_t IO0IntStatR;
+ __I uint32_t IO0IntStatF;
+ __O uint32_t IO0IntClr;
+ __IO uint32_t IO0IntEnR;
+ __IO uint32_t IO0IntEnF;
+ uint32_t RESERVED0[3];
+ __I uint32_t IO2IntStatR;
+ __I uint32_t IO2IntStatF;
+ __O uint32_t IO2IntClr;
+ __IO uint32_t IO2IntEnR;
+ __IO uint32_t IO2IntEnF;
+} GPIOINT_TypeDef;
+
+/*------------- Timer (TIM) --------------------------------------------------*/
+typedef struct {
+ __IO uint32_t IR;
+ __IO uint32_t TCR;
+ __IO uint32_t TC;
+ __IO uint32_t PR;
+ __IO uint32_t PC;
+ __IO uint32_t MCR;
+ __IO uint32_t MR0;
+ __IO uint32_t MR1;
+ __IO uint32_t MR2;
+ __IO uint32_t MR3;
+ __IO uint32_t CCR;
+ __I uint32_t CR0;
+ __I uint32_t CR1;
+ uint32_t RESERVED0[2];
+ __IO uint32_t EMR;
+ uint32_t RESERVED1[24];
+ __IO uint32_t CTCR;
+} TIM_TypeDef;
+
+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/
+typedef struct {
+ __IO uint32_t IR;
+ __IO uint32_t TCR;
+ __IO uint32_t TC;
+ __IO uint32_t PR;
+ __IO uint32_t PC;
+ __IO uint32_t MCR;
+ __IO uint32_t MR0;
+ __IO uint32_t MR1;
+ __IO uint32_t MR2;
+ __IO uint32_t MR3;
+ __IO uint32_t CCR;
+ __I uint32_t CR0;
+ __I uint32_t CR1;
+ __I uint32_t CR2;
+ __I uint32_t CR3;
+ __IO uint32_t MR4;
+ __IO uint32_t MR5;
+ __IO uint32_t MR6;
+ __IO uint32_t PCR;
+ __IO uint32_t LER;
+ uint32_t RESERVED0[7];
+ __IO uint32_t CTCR;
+} PWM_TypeDef;
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+typedef struct {
+ union {
+ __I uint8_t RBR;
+ __O uint8_t THR;
+ __IO uint8_t DLL;
+ uint32_t RESERVED0;
+ };
+ union {
+ __IO uint8_t DLM;
+ __IO uint32_t IER;
+ };
+ union {
+ __I uint32_t IIR;
+ __O uint8_t FCR;
+ };
+ __IO uint8_t LCR;
+ uint8_t RESERVED1[7];
+ __IO uint8_t LSR;
+ uint8_t RESERVED2[7];
+ __IO uint8_t SCR;
+ uint8_t RESERVED3[3];
+ __IO uint32_t ACR;
+ __IO uint8_t ICR;
+ uint8_t RESERVED4[3];
+ __IO uint8_t FDR;
+ uint8_t RESERVED5[7];
+ __IO uint8_t TER;
+ uint8_t RESERVED6[27];
+ __IO uint8_t RS485CTRL;
+ uint8_t RESERVED7[3];
+ __IO uint8_t ADRMATCH;
+} UART_TypeDef;
+
+typedef struct {
+ union {
+ __I uint8_t RBR;
+ __O uint8_t THR;
+ __IO uint8_t DLL;
+ uint32_t RESERVED0;
+ };
+ union {
+ __IO uint8_t DLM;
+ __IO uint32_t IER;
+ };
+ union {
+ __I uint32_t IIR;
+ __O uint8_t FCR;
+ };
+ __IO uint8_t LCR;
+ uint8_t RESERVED1[3];
+ __IO uint8_t MCR;
+ uint8_t RESERVED2[3];
+ __IO uint8_t LSR;
+ uint8_t RESERVED3[3];
+ __IO uint8_t MSR;
+ uint8_t RESERVED4[3];
+ __IO uint8_t SCR;
+ uint8_t RESERVED5[3];
+ __IO uint32_t ACR;
+ uint32_t RESERVED6;
+ __IO uint32_t FDR;
+ uint32_t RESERVED7;
+ __IO uint8_t TER;
+ uint8_t RESERVED8[27];
+ __IO uint8_t RS485CTRL;
+ uint8_t RESERVED9[3];
+ __IO uint8_t ADRMATCH;
+ uint8_t RESERVED10[3];
+ __IO uint8_t RS485DLY;
+} UART1_TypeDef;
+
+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/
+typedef struct {
+ __IO uint32_t SPCR;
+ __I uint32_t SPSR;
+ __IO uint32_t SPDR;
+ __IO uint32_t SPCCR;
+ uint32_t RESERVED0[3];
+ __IO uint32_t SPINT;
+} SPI_TypeDef;
+
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/
+typedef struct {
+ __IO uint32_t CR0;
+ __IO uint32_t CR1;
+ __IO uint32_t DR;
+ __I uint32_t SR;
+ __IO uint32_t CPSR;
+ __IO uint32_t IMSC;
+ __IO uint32_t RIS;
+ __IO uint32_t MIS;
+ __IO uint32_t ICR;
+ __IO uint32_t DMACR;
+} SSP_TypeDef;
+
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
+typedef struct {
+ __IO uint32_t I2CONSET;
+ __I uint32_t I2STAT;
+ __IO uint32_t I2DAT;
+ __IO uint32_t I2ADR0;
+ __IO uint32_t I2SCLH;
+ __IO uint32_t I2SCLL;
+ __O uint32_t I2CONCLR;
+ __IO uint32_t MMCTRL;
+ __IO uint32_t I2ADR1;
+ __IO uint32_t I2ADR2;
+ __IO uint32_t I2ADR3;
+ __I uint32_t I2DATA_BUFFER;
+ __IO uint32_t I2MASK0;
+ __IO uint32_t I2MASK1;
+ __IO uint32_t I2MASK2;
+ __IO uint32_t I2MASK3;
+} I2C_TypeDef;
+
+/*------------- Inter IC Sound (I2S) -----------------------------------------*/
+typedef struct {
+ __IO uint32_t I2SDAO;
+ __IO uint32_t I2SDAI;
+ __O uint32_t I2STXFIFO;
+ __I uint32_t I2SRXFIFO;
+ __I uint32_t I2SSTATE;
+ __IO uint32_t I2SDMA1;
+ __IO uint32_t I2SDMA2;
+ __IO uint32_t I2SIRQ;
+ __IO uint32_t I2STXRATE;
+ __IO uint32_t I2SRXRATE;
+ __IO uint32_t I2STXBITRATE;
+ __IO uint32_t I2SRXBITRATE;
+ __IO uint32_t I2STXMODE;
+ __IO uint32_t I2SRXMODE;
+} I2S_TypeDef;
+
+/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/
+typedef struct {
+ __IO uint32_t RICOMPVAL;
+ __IO uint32_t RIMASK;
+ __IO uint8_t RICTRL;
+ uint8_t RESERVED0[3];
+ __IO uint32_t RICOUNTER;
+} RIT_TypeDef;
+
+/*------------- Real-Time Clock (RTC) ----------------------------------------*/
+typedef struct {
+ __IO uint8_t ILR;
+ uint8_t RESERVED0[3];
+ __IO uint8_t CCR;
+ uint8_t RESERVED1[3];
+ __IO uint8_t CIIR;
+ uint8_t RESERVED2[3];
+ __IO uint8_t AMR;
+ uint8_t RESERVED3[3];
+ __I uint32_t CTIME0;
+ __I uint32_t CTIME1;
+ __I uint32_t CTIME2;
+ __IO uint8_t SEC;
+ uint8_t RESERVED4[3];
+ __IO uint8_t MIN;
+ uint8_t RESERVED5[3];
+ __IO uint8_t HOUR;
+ uint8_t RESERVED6[3];
+ __IO uint8_t DOM;
+ uint8_t RESERVED7[3];
+ __IO uint8_t DOW;
+ uint8_t RESERVED8[3];
+ __IO uint16_t DOY;
+ uint16_t RESERVED9;
+ __IO uint8_t MONTH;
+ uint8_t RESERVED10[3];
+ __IO uint16_t YEAR;
+ uint16_t RESERVED11;
+ __IO uint32_t CALIBRATION;
+ __IO uint32_t GPREG0;
+ __IO uint32_t GPREG1;
+ __IO uint32_t GPREG2;
+ __IO uint32_t GPREG3;
+ __IO uint32_t GPREG4;
+ __IO uint8_t WAKEUPDIS;
+ uint8_t RESERVED12[3];
+ __IO uint8_t PWRCTRL;
+ uint8_t RESERVED13[3];
+ __IO uint8_t ALSEC;
+ uint8_t RESERVED14[3];
+ __IO uint8_t ALMIN;
+ uint8_t RESERVED15[3];
+ __IO uint8_t ALHOUR;
+ uint8_t RESERVED16[3];
+ __IO uint8_t ALDOM;
+ uint8_t RESERVED17[3];
+ __IO uint8_t ALDOW;
+ uint8_t RESERVED18[3];
+ __IO uint16_t ALDOY;
+ uint16_t RESERVED19;
+ __IO uint8_t ALMON;
+ uint8_t RESERVED20[3];
+ __IO uint16_t ALYEAR;
+ uint16_t RESERVED21;
+} RTC_TypeDef;
+
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/
+typedef struct {
+ __IO uint8_t WDMOD;
+ uint8_t RESERVED0[3];
+ __IO uint32_t WDTC;
+ __O uint8_t WDFEED;
+ uint8_t RESERVED1[3];
+ __I uint32_t WDTV;
+ __IO uint32_t WDCLKSEL;
+} WDT_TypeDef;
+
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
+typedef struct {
+ __IO uint32_t ADCR;
+ __IO uint32_t ADGDR;
+ uint32_t RESERVED0;
+ __IO uint32_t ADINTEN;
+ __I uint32_t ADDR0;
+ __I uint32_t ADDR1;
+ __I uint32_t ADDR2;
+ __I uint32_t ADDR3;
+ __I uint32_t ADDR4;
+ __I uint32_t ADDR5;
+ __I uint32_t ADDR6;
+ __I uint32_t ADDR7;
+ __I uint32_t ADSTAT;
+ __IO uint32_t ADTRM;
+} ADC_TypeDef;
+
+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/
+typedef struct {
+ __IO uint32_t DACR;
+ __IO uint32_t DACCTRL;
+ __IO uint16_t DACCNTVAL;
+} DAC_TypeDef;
+
+/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/
+typedef struct {
+ __I uint32_t MCCON;
+ __O uint32_t MCCON_SET;
+ __O uint32_t MCCON_CLR;
+ __I uint32_t MCCAPCON;
+ __O uint32_t MCCAPCON_SET;
+ __O uint32_t MCCAPCON_CLR;
+ __IO uint32_t MCTC0;
+ __IO uint32_t MCTC1;
+ __IO uint32_t MCTC2;
+ __IO uint32_t MCLIM0;
+ __IO uint32_t MCLIM1;
+ __IO uint32_t MCLIM2;
+ __IO uint32_t MCMAT0;
+ __IO uint32_t MCMAT1;
+ __IO uint32_t MCMAT2;
+ __IO uint32_t MCDEADTIME;
+ __IO uint32_t MCCP;
+ __IO uint32_t MCCR0;
+ __IO uint32_t MCCR1;
+ __IO uint32_t MCCR2;
+ __I uint32_t MCINTEN;
+ __O uint32_t MCINTEN_SET;
+ __O uint32_t MCINTEN_CLR;
+ __I uint32_t MCCNTCON;
+ __O uint32_t MCCNTCON_SET;
+ __O uint32_t MCCNTCON_CLR;
+ __I uint32_t MCINTFLAG;
+ __O uint32_t MCINTFLAG_SET;
+ __O uint32_t MCINTFLAG_CLR;
+ __O uint32_t MCCAP_CLR;
+} MCPWM_TypeDef;
+
+/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/
+typedef struct {
+ __O uint32_t QEICON;
+ __I uint32_t QEISTAT;
+ __IO uint32_t QEICONF;
+ __I uint32_t QEIPOS;
+ __IO uint32_t QEIMAXPOS;
+ __IO uint32_t CMPOS0;
+ __IO uint32_t CMPOS1;
+ __IO uint32_t CMPOS2;
+ __I uint32_t INXCNT;
+ __IO uint32_t INXCMP;
+ __IO uint32_t QEILOAD;
+ __I uint32_t QEITIME;
+ __I uint32_t QEIVEL;
+ __I uint32_t QEICAP;
+ __IO uint32_t VELCOMP;
+ __IO uint32_t FILTER;
+ uint32_t RESERVED0[998];
+ __O uint32_t QEIIEC;
+ __O uint32_t QEIIES;
+ __I uint32_t QEIINTSTAT;
+ __I uint32_t QEIIE;
+ __O uint32_t QEICLR;
+ __O uint32_t QEISET;
+} QEI_TypeDef;
+
+/*------------- Controller Area Network (CAN) --------------------------------*/
+typedef struct {
+ __IO uint32_t mask[512]; /* ID Masks */
+} CANAF_RAM_TypeDef;
+
+typedef struct { /* Acceptance Filter Registers */
+ __IO uint32_t AFMR;
+ __IO uint32_t SFF_sa;
+ __IO uint32_t SFF_GRP_sa;
+ __IO uint32_t EFF_sa;
+ __IO uint32_t EFF_GRP_sa;
+ __IO uint32_t ENDofTable;
+ __I uint32_t LUTerrAd;
+ __I uint32_t LUTerr;
+} CANAF_TypeDef;
+
+typedef struct { /* Central Registers */
+ __I uint32_t CANTxSR;
+ __I uint32_t CANRxSR;
+ __I uint32_t CANMSR;
+} CANCR_TypeDef;
+
+typedef struct { /* Controller Registers */
+ __IO uint32_t MOD;
+ __O uint32_t CMR;
+ __IO uint32_t GSR;
+ __I uint32_t ICR;
+ __IO uint32_t IER;
+ __IO uint32_t BTR;
+ __IO uint32_t EWL;
+ __I uint32_t SR;
+ __IO uint32_t RFS;
+ __IO uint32_t RID;
+ __IO uint32_t RDA;
+ __IO uint32_t RDB;
+ __IO uint32_t TFI1;
+ __IO uint32_t TID1;
+ __IO uint32_t TDA1;
+ __IO uint32_t TDB1;
+ __IO uint32_t TFI2;
+ __IO uint32_t TID2;
+ __IO uint32_t TDA2;
+ __IO uint32_t TDB2;
+ __IO uint32_t TFI3;
+ __IO uint32_t TID3;
+ __IO uint32_t TDA3;
+ __IO uint32_t TDB3;
+} CAN_TypeDef;
+
+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/
+typedef struct { /* Common Registers */
+ __I uint32_t DMACIntStat;
+ __I uint32_t DMACIntTCStat;
+ __O uint32_t DMACIntTCClear;
+ __I uint32_t DMACIntErrStat;
+ __O uint32_t DMACIntErrClr;
+ __I uint32_t DMACRawIntTCStat;
+ __I uint32_t DMACRawIntErrStat;
+ __I uint32_t DMACEnbldChns;
+ __IO uint32_t DMACSoftBReq;
+ __IO uint32_t DMACSoftSReq;
+ __IO uint32_t DMACSoftLBReq;
+ __IO uint32_t DMACSoftLSReq;
+ __IO uint32_t DMACConfig;
+ __IO uint32_t DMACSync;
+} GPDMA_TypeDef;
+
+typedef struct { /* Channel Registers */
+ __IO uint32_t DMACCSrcAddr;
+ __IO uint32_t DMACCDestAddr;
+ __IO uint32_t DMACCLLI;
+ __IO uint32_t DMACCControl;
+ __IO uint32_t DMACCConfig;
+} GPDMACH_TypeDef;
+
+/*------------- Universal Serial Bus (USB) -----------------------------------*/
+typedef struct {
+ __I uint32_t HcRevision; /* USB Host Registers */
+ __IO uint32_t HcControl;
+ __IO uint32_t HcCommandStatus;
+ __IO uint32_t HcInterruptStatus;
+ __IO uint32_t HcInterruptEnable;
+ __IO uint32_t HcInterruptDisable;
+ __IO uint32_t HcHCCA;
+ __I uint32_t HcPeriodCurrentED;
+ __IO uint32_t HcControlHeadED;
+ __IO uint32_t HcControlCurrentED;
+ __IO uint32_t HcBulkHeadED;
+ __IO uint32_t HcBulkCurrentED;
+ __I uint32_t HcDoneHead;
+ __IO uint32_t HcFmInterval;
+ __I uint32_t HcFmRemaining;
+ __I uint32_t HcFmNumber;
+ __IO uint32_t HcPeriodicStart;
+ __IO uint32_t HcLSTreshold;
+ __IO uint32_t HcRhDescriptorA;
+ __IO uint32_t HcRhDescriptorB;
+ __IO uint32_t HcRhStatus;
+ __IO uint32_t HcRhPortStatus1;
+ __IO uint32_t HcRhPortStatus2;
+ uint32_t RESERVED0[40];
+ __I uint32_t Module_ID;
+
+ __I uint32_t OTGIntSt; /* USB On-The-Go Registers */
+ __IO uint32_t OTGIntEn;
+ __O uint32_t OTGIntSet;
+ __O uint32_t OTGIntClr;
+ __IO uint32_t OTGStCtrl;
+ __IO uint32_t OTGTmr;
+ uint32_t RESERVED1[58];
+
+ __I uint32_t USBDevIntSt; /* USB Device Interrupt Registers */
+ __IO uint32_t USBDevIntEn;
+ __O uint32_t USBDevIntClr;
+ __O uint32_t USBDevIntSet;
+
+ __O uint32_t USBCmdCode; /* USB Device SIE Command Registers */
+ __I uint32_t USBCmdData;
+
+ __I uint32_t USBRxData; /* USB Device Transfer Registers */
+ __O uint32_t USBTxData;
+ __I uint32_t USBRxPLen;
+ __O uint32_t USBTxPLen;
+ __IO uint32_t USBCtrl;
+ __O uint32_t USBDevIntPri;
+
+ __I uint32_t USBEpIntSt; /* USB Device Endpoint Interrupt Regs */
+ __IO uint32_t USBEpIntEn;
+ __O uint32_t USBEpIntClr;
+ __O uint32_t USBEpIntSet;
+ __O uint32_t USBEpIntPri;
+
+ __IO uint32_t USBReEp; /* USB Device Endpoint Realization Reg*/
+ __O uint32_t USBEpInd;
+ __IO uint32_t USBMaxPSize;
+
+ __I uint32_t USBDMARSt; /* USB Device DMA Registers */
+ __O uint32_t USBDMARClr;
+ __O uint32_t USBDMARSet;
+ uint32_t RESERVED2[9];
+ __IO uint32_t USBUDCAH;
+ __I uint32_t USBEpDMASt;
+ __O uint32_t USBEpDMAEn;
+ __O uint32_t USBEpDMADis;
+ __I uint32_t USBDMAIntSt;
+ __IO uint32_t USBDMAIntEn;
+ uint32_t RESERVED3[2];
+ __I uint32_t USBEoTIntSt;
+ __O uint32_t USBEoTIntClr;
+ __O uint32_t USBEoTIntSet;
+ __I uint32_t USBNDDRIntSt;
+ __O uint32_t USBNDDRIntClr;
+ __O uint32_t USBNDDRIntSet;
+ __I uint32_t USBSysErrIntSt;
+ __O uint32_t USBSysErrIntClr;
+ __O uint32_t USBSysErrIntSet;
+ uint32_t RESERVED4[15];
+
+ __I uint32_t I2C_RX; /* USB OTG I2C Registers */
+ __O uint32_t I2C_WO;
+ __I uint32_t I2C_STS;
+ __IO uint32_t I2C_CTL;
+ __IO uint32_t I2C_CLKHI;
+ __O uint32_t I2C_CLKLO;
+ uint32_t RESERVED5[823];
+
+ union {
+ __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */
+ __IO uint32_t OTGClkCtrl;
+ } ;
+ union {
+ __I uint32_t USBClkSt;
+ __I uint32_t OTGClkSt;
+ };
+} USB_TypeDef;
+
+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/
+typedef struct {
+ __IO uint32_t MAC1; /* MAC Registers */
+ __IO uint32_t MAC2;
+ __IO uint32_t IPGT;
+ __IO uint32_t IPGR;
+ __IO uint32_t CLRT;
+ __IO uint32_t MAXF;
+ __IO uint32_t SUPP;
+ __IO uint32_t TEST;
+ __IO uint32_t MCFG;
+ __IO uint32_t MCMD;
+ __IO uint32_t MADR;
+ __O uint32_t MWTD;
+ __I uint32_t MRDD;
+ __I uint32_t MIND;
+ uint32_t RESERVED0[2];
+ __IO uint32_t SA0;
+ __IO uint32_t SA1;
+ __IO uint32_t SA2;
+ uint32_t RESERVED1[45];
+ __IO uint32_t Command; /* Control Registers */
+ __I uint32_t Status;
+ __IO uint32_t RxDescriptor;
+ __IO uint32_t RxStatus;
+ __IO uint32_t RxDescriptorNumber;
+ __I uint32_t RxProduceIndex;
+ __IO uint32_t RxConsumeIndex;
+ __IO uint32_t TxDescriptor;
+ __IO uint32_t TxStatus;
+ __IO uint32_t TxDescriptorNumber;
+ __IO uint32_t TxProduceIndex;
+ __I uint32_t TxConsumeIndex;
+ uint32_t RESERVED2[10];
+ __I uint32_t TSV0;
+ __I uint32_t TSV1;
+ __I uint32_t RSV;
+ uint32_t RESERVED3[3];
+ __IO uint32_t FlowControlCounter;
+ __I uint32_t FlowControlStatus;
+ uint32_t RESERVED4[34];
+ __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */
+ __IO uint32_t RxFilterWoLStatus;
+ __IO uint32_t RxFilterWoLClear;
+ uint32_t RESERVED5;
+ __IO uint32_t HashFilterL;
+ __IO uint32_t HashFilterH;
+ uint32_t RESERVED6[882];
+ __I uint32_t IntStatus; /* Module Control Registers */
+ __IO uint32_t IntEnable;
+ __O uint32_t IntClear;
+ __O uint32_t IntSet;
+ uint32_t RESERVED7;
+ __IO uint32_t PowerDown;
+ uint32_t RESERVED8;
+ __IO uint32_t Module_ID;
+} EMAC_TypeDef;
+
+/******************************************************************************/
+/* Peripheral memory map */
+/******************************************************************************/
+/* Base addresses */
+#define FLASH_BASE (0x00000000UL)
+#define RAM_BASE (0x10000000UL)
+#define GPIO_BASE (0x2009C000UL)
+#define APB0_BASE (0x40000000UL)
+#define APB1_BASE (0x40080000UL)
+#define AHB_BASE (0x50000000UL)
+#define CM3_BASE (0xE0000000UL)
+
+/* APB0 peripherals */
+#define WDT_BASE (APB0_BASE + 0x00000)
+#define TIM0_BASE (APB0_BASE + 0x04000)
+#define TIM1_BASE (APB0_BASE + 0x08000)
+#define UART0_BASE (APB0_BASE + 0x0C000)
+#define UART1_BASE (APB0_BASE + 0x10000)
+#define PWM1_BASE (APB0_BASE + 0x18000)
+#define I2C0_BASE (APB0_BASE + 0x1C000)
+#define SPI_BASE (APB0_BASE + 0x20000)
+#define RTC_BASE (APB0_BASE + 0x24000)
+#define GPIOINT_BASE (APB0_BASE + 0x28080)
+#define PINCON_BASE (APB0_BASE + 0x2C000)
+#define SSP1_BASE (APB0_BASE + 0x30000)
+#define ADC_BASE (APB0_BASE + 0x34000)
+#define CANAF_RAM_BASE (APB0_BASE + 0x38000)
+#define CANAF_BASE (APB0_BASE + 0x3C000)
+#define CANCR_BASE (APB0_BASE + 0x40000)
+#define CAN1_BASE (APB0_BASE + 0x44000)
+#define CAN2_BASE (APB0_BASE + 0x48000)
+#define I2C1_BASE (APB0_BASE + 0x5C000)
+
+/* APB1 peripherals */
+#define SSP0_BASE (APB1_BASE + 0x08000)
+#define DAC_BASE (APB1_BASE + 0x0C000)
+#define TIM2_BASE (APB1_BASE + 0x10000)
+#define TIM3_BASE (APB1_BASE + 0x14000)
+#define UART2_BASE (APB1_BASE + 0x18000)
+#define UART3_BASE (APB1_BASE + 0x1C000)
+#define I2C2_BASE (APB1_BASE + 0x20000)
+#define I2S_BASE (APB1_BASE + 0x28000)
+#define RIT_BASE (APB1_BASE + 0x30000)
+#define MCPWM_BASE (APB1_BASE + 0x38000)
+#define QEI_BASE (APB1_BASE + 0x3C000)
+#define SC_BASE (APB1_BASE + 0x7C000)
+
+/* AHB peripherals */
+#define EMAC_BASE (AHB_BASE + 0x00000)
+#define GPDMA_BASE (AHB_BASE + 0x04000)
+#define GPDMACH0_BASE (AHB_BASE + 0x04100)
+#define GPDMACH1_BASE (AHB_BASE + 0x04120)
+#define GPDMACH2_BASE (AHB_BASE + 0x04140)
+#define GPDMACH3_BASE (AHB_BASE + 0x04160)
+#define GPDMACH4_BASE (AHB_BASE + 0x04180)
+#define GPDMACH5_BASE (AHB_BASE + 0x041A0)
+#define GPDMACH6_BASE (AHB_BASE + 0x041C0)
+#define GPDMACH7_BASE (AHB_BASE + 0x041E0)
+#define USB_BASE (AHB_BASE + 0x0C000)
+
+/* GPIOs */
+#define GPIO0_BASE (GPIO_BASE + 0x00000)
+#define GPIO1_BASE (GPIO_BASE + 0x00020)
+#define GPIO2_BASE (GPIO_BASE + 0x00040)
+#define GPIO3_BASE (GPIO_BASE + 0x00060)
+#define GPIO4_BASE (GPIO_BASE + 0x00080)
+
+
+/******************************************************************************/
+/* Peripheral declaration */
+/******************************************************************************/
+#define SC (( SC_TypeDef *) SC_BASE)
+#define GPIO0 (( GPIO_TypeDef *) GPIO0_BASE)
+#define GPIO1 (( GPIO_TypeDef *) GPIO1_BASE)
+#define GPIO2 (( GPIO_TypeDef *) GPIO2_BASE)
+#define GPIO3 (( GPIO_TypeDef *) GPIO3_BASE)
+#define GPIO4 (( GPIO_TypeDef *) GPIO4_BASE)
+#define WDT (( WDT_TypeDef *) WDT_BASE)
+#define TIM0 (( TIM_TypeDef *) TIM0_BASE)
+#define TIM1 (( TIM_TypeDef *) TIM1_BASE)
+#define TIM2 (( TIM_TypeDef *) TIM2_BASE)
+#define TIM3 (( TIM_TypeDef *) TIM3_BASE)
+#define RIT (( RIT_TypeDef *) RIT_BASE)
+#define UART0 (( UART_TypeDef *) UART0_BASE)
+#define UART1 (( UART1_TypeDef *) UART1_BASE)
+#define UART2 (( UART_TypeDef *) UART2_BASE)
+#define UART3 (( UART_TypeDef *) UART3_BASE)
+#define PWM1 (( PWM_TypeDef *) PWM1_BASE)
+#define I2C0 (( I2C_TypeDef *) I2C0_BASE)
+#define I2C1 (( I2C_TypeDef *) I2C1_BASE)
+#define I2C2 (( I2C_TypeDef *) I2C2_BASE)
+#define I2S (( I2S_TypeDef *) I2S_BASE)
+#define SPI (( SPI_TypeDef *) SPI_BASE)
+#define RTC (( RTC_TypeDef *) RTC_BASE)
+#define GPIOINT (( GPIOINT_TypeDef *) GPIOINT_BASE)
+#define PINCON (( PINCON_TypeDef *) PINCON_BASE)
+#define SSP0 (( SSP_TypeDef *) SSP0_BASE)
+#define SSP1 (( SSP_TypeDef *) SSP1_BASE)
+#define ADC (( ADC_TypeDef *) ADC_BASE)
+#define DAC (( DAC_TypeDef *) DAC_BASE)
+#define CANAF_RAM ((CANAF_RAM_TypeDef *) CANAF_RAM_BASE)
+#define CANAF (( CANAF_TypeDef *) CANAF_BASE)
+#define CANCR (( CANCR_TypeDef *) CANCR_BASE)
+#define CAN1 (( CAN_TypeDef *) CAN1_BASE)
+#define CAN2 (( CAN_TypeDef *) CAN2_BASE)
+#define MCPWM (( MCPWM_TypeDef *) MCPWM_BASE)
+#define QEI (( QEI_TypeDef *) QEI_BASE)
+#define EMAC (( EMAC_TypeDef *) EMAC_BASE)
+#define GPDMA (( GPDMA_TypeDef *) GPDMA_BASE)
+#define GPDMACH0 (( GPDMACH_TypeDef *) GPDMACH0_BASE)
+#define GPDMACH1 (( GPDMACH_TypeDef *) GPDMACH1_BASE)
+#define GPDMACH2 (( GPDMACH_TypeDef *) GPDMACH2_BASE)
+#define GPDMACH3 (( GPDMACH_TypeDef *) GPDMACH3_BASE)
+#define GPDMACH4 (( GPDMACH_TypeDef *) GPDMACH4_BASE)
+#define GPDMACH5 (( GPDMACH_TypeDef *) GPDMACH5_BASE)
+#define GPDMACH6 (( GPDMACH_TypeDef *) GPDMACH6_BASE)
+#define GPDMACH7 (( GPDMACH_TypeDef *) GPDMACH7_BASE)
+#define USB (( USB_TypeDef *) USB_BASE)
+
+#endif // __LPC17xx_H__
+
+
+#endif
diff --git a/gyro_board/src/usb/LPCUSB/USB_CDC.c b/gyro_board/src/usb/LPCUSB/USB_CDC.c
new file mode 100644
index 0000000..47d28db
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/USB_CDC.c
@@ -0,0 +1,454 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ Minimal implementation of a USB serial port, using the CDC class.
+ This example application simply echoes everything it receives right back
+ to the host.
+
+ Windows:
+ Extract the usbser.sys file from .cab file in C:\WINDOWS\Driver Cache\i386
+ and store it somewhere (C:\temp is a good place) along with the usbser.inf
+ file. Then plug in the LPC176x and direct windows to the usbser driver.
+ Windows then creates an extra COMx port that you can open in a terminal
+ program, like hyperterminal. [Note for FreeRTOS users - the required .inf
+ file is included in the project directory.]
+
+ Linux:
+ The device should be recognised automatically by the cdc_acm driver,
+ which creates a /dev/ttyACMx device file that acts just like a regular
+ serial port.
+
+*/
+
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "usbapi.h"
+#include "usbdebug.h"
+#include "usbstruct.h"
+
+#include "LPC17xx.h"
+
+#define usbMAX_SEND_BLOCK ( 20 / portTICK_RATE_MS )
+#define usbRXBUFFER_LEN ( 80 )
+#define usbTXBUFFER_LEN ( 600 )
+
+#define INCREMENT_ECHO_BY 0
+#define BAUD_RATE 115200
+
+#define INT_IN_EP 0x81
+#define BULK_OUT_EP 0x05
+#define BULK_IN_EP 0x82
+
+#define MAX_PACKET_SIZE 64
+
+#define LE_WORD(x) ((x)&0xFF),((x)>>8)
+
+// CDC definitions
+#define CS_INTERFACE 0x24
+#define CS_ENDPOINT 0x25
+
+#define SET_LINE_CODING 0x20
+#define GET_LINE_CODING 0x21
+#define SET_CONTROL_LINE_STATE 0x22
+
+// data structure for GET_LINE_CODING / SET_LINE_CODING class requests
+typedef struct {
+ unsigned long dwDTERate;
+ unsigned char bCharFormat;
+ unsigned char bParityType;
+ unsigned char bDataBits;
+} TLineCoding;
+
+static TLineCoding LineCoding = {115200, 0, 0, 8};
+static unsigned char abBulkBuf[64];
+static unsigned char abClassReqData[8];
+
+static xQueueHandle xRxedChars = NULL, xCharsForTx = NULL;
+
+// forward declaration of interrupt handler
+void USBIntHandler(void);
+
+static const unsigned char abDescriptors[] = {
+
+// device descriptor
+ 0x12,
+ DESC_DEVICE,
+ LE_WORD(0x0101), // bcdUSB
+ 0x02, // bDeviceClass
+ 0x00, // bDeviceSubClass
+ 0x00, // bDeviceProtocol
+ MAX_PACKET_SIZE0, // bMaxPacketSize
+ LE_WORD(0xFFFF), // idVendor
+ LE_WORD(0x0005), // idProduct
+ LE_WORD(0x0100), // bcdDevice
+ 0x01, // iManufacturer
+ 0x02, // iProduct
+ 0x03, // iSerialNumber
+ 0x01, // bNumConfigurations
+
+// configuration descriptor
+ 0x09,
+ DESC_CONFIGURATION,
+ LE_WORD(67), // wTotalLength
+ 0x02, // bNumInterfaces
+ 0x01, // bConfigurationValue
+ 0x00, // iConfiguration
+ 0xC0, // bmAttributes
+ 0x32, // bMaxPower
+// control class interface
+ 0x09,
+ DESC_INTERFACE,
+ 0x00, // bInterfaceNumber
+ 0x00, // bAlternateSetting
+ 0x01, // bNumEndPoints
+ 0x02, // bInterfaceClass
+ 0x02, // bInterfaceSubClass
+ 0x01, // bInterfaceProtocol, linux requires value of 1 for the cdc_acm module
+ 0x00, // iInterface
+// header functional descriptor
+ 0x05,
+ CS_INTERFACE,
+ 0x00,
+ LE_WORD(0x0110),
+// call management functional descriptor
+ 0x05,
+ CS_INTERFACE,
+ 0x01,
+ 0x01, // bmCapabilities = device handles call management
+ 0x01, // bDataInterface
+// ACM functional descriptor
+ 0x04,
+ CS_INTERFACE,
+ 0x02,
+ 0x02, // bmCapabilities
+// union functional descriptor
+ 0x05,
+ CS_INTERFACE,
+ 0x06,
+ 0x00, // bMasterInterface
+ 0x01, // bSlaveInterface0
+// notification EP
+ 0x07,
+ DESC_ENDPOINT,
+ INT_IN_EP, // bEndpointAddress
+ 0x03, // bmAttributes = intr
+ LE_WORD(8), // wMaxPacketSize
+ 0x0A, // bInterval
+// data class interface descriptor
+ 0x09,
+ DESC_INTERFACE,
+ 0x01, // bInterfaceNumber
+ 0x00, // bAlternateSetting
+ 0x02, // bNumEndPoints
+ 0x0A, // bInterfaceClass = data
+ 0x00, // bInterfaceSubClass
+ 0x00, // bInterfaceProtocol
+ 0x00, // iInterface
+// data EP OUT
+ 0x07,
+ DESC_ENDPOINT,
+ BULK_OUT_EP, // bEndpointAddress
+ 0x02, // bmAttributes = bulk
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
+ 0x00, // bInterval
+// data EP in
+ 0x07,
+ DESC_ENDPOINT,
+ BULK_IN_EP, // bEndpointAddress
+ 0x02, // bmAttributes = bulk
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
+ 0x00, // bInterval
+
+ // string descriptors
+ 0x04,
+ DESC_STRING,
+ LE_WORD(0x0409),
+
+ 0x0E,
+ DESC_STRING,
+ 'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,
+
+ 0x14,
+ DESC_STRING,
+ 'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0,
+
+ 0x12,
+ DESC_STRING,
+ 'A', 0, 'B', 0, 'S', 0, 'M', 0, 'o', 0, 't', 0, 'o', 0, 'r', 0,
+
+// terminating zero
+ 0
+};
+
+
+/**
+ Local function to handle incoming bulk data
+
+ @param [in] bEP
+ @param [in] bEPStatus
+ */
+static void BulkOut(unsigned char bEP, unsigned char bEPStatus)
+{
+ int i, iLen;
+ long lHigherPriorityTaskWoken = pdFALSE;
+
+ (void) bEPStatus;
+
+ // get data from USB into intermediate buffer
+ iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));
+ for (i = 0; i < iLen; i++) {
+ // put into queue
+ xQueueSendFromISR(xRxedChars, &(abBulkBuf[ i ]), &lHigherPriorityTaskWoken);
+ }
+
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+
+/**
+ Local function to handle outgoing bulk data
+
+ @param [in] bEP
+ @param [in] bEPStatus
+ */
+static void BulkIn(unsigned char bEP, unsigned char bEPStatus)
+{
+ int i, iLen;
+ long lHigherPriorityTaskWoken = pdFALSE;
+
+ (void) bEPStatus;
+
+ if (uxQueueMessagesWaitingFromISR(xCharsForTx) == 0) {
+ // no more data, disable further NAK interrupts until next USB frame
+ USBHwNakIntEnable(0);
+ return;
+ }
+
+ // get bytes from transmit FIFO into intermediate buffer
+ for (i = 0; i < MAX_PACKET_SIZE; i++) {
+ if (xQueueReceiveFromISR(xCharsForTx, (&abBulkBuf[i]), &lHigherPriorityTaskWoken) != pdPASS) {
+ break;
+ }
+ }
+ iLen = i;
+
+ // send over USB
+ if (iLen > 0) {
+ USBHwEPWrite(bEP, abBulkBuf, iLen);
+ }
+
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+
+/**
+ Local function to handle the USB-CDC class requests
+
+ @param [in] pSetup
+ @param [out] piLen
+ @param [out] ppbData
+ */
+static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ switch (pSetup->bRequest) {
+
+ // set line coding
+ case SET_LINE_CODING:
+ DBG("SET_LINE_CODING\n");
+ memcpy((unsigned char *)&LineCoding, *ppbData, 7);
+ *piLen = 7;
+ DBG("dwDTERate=%u, bCharFormat=%u, bParityType=%u, bDataBits=%u\n",
+ LineCoding.dwDTERate,
+ LineCoding.bCharFormat,
+ LineCoding.bParityType,
+ LineCoding.bDataBits);
+ break;
+
+ // get line coding
+ case GET_LINE_CODING:
+ DBG("GET_LINE_CODING\n");
+ *ppbData = (unsigned char *) & LineCoding;
+ *piLen = 7;
+ break;
+
+ // set control line state
+ case SET_CONTROL_LINE_STATE:
+ // bit0 = DTR, bit = RTS
+ DBG("SET_CONTROL_LINE_STATE %X\n", pSetup->wValue);
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ Writes one character to VCOM port
+
+ @param [in] c character to write
+ @returns character written, or EOF if character could not be written
+ */
+int VCOM_putchar(int c)
+{
+ char cc = (char) c;
+
+ if (xQueueSend(xCharsForTx, &cc, usbMAX_SEND_BLOCK) == pdPASS) {
+ return c;
+ } else {
+ return EOF;
+ }
+}
+
+
+/**
+ Reads one character from VCOM port
+
+ @returns character read, or EOF if character could not be read
+ */
+int VCOM_getchar(void)
+{
+ unsigned char c;
+
+ /* Block the task until a character is available. */
+ xQueueReceive(xRxedChars, &c, portMAX_DELAY);
+ return c;
+}
+
+
+/**
+ Interrupt handler
+
+ Simply calls the USB ISR
+ */
+void USB_IRQHandler(void)
+{
+ USBHwISR();
+}
+
+
+static void USBFrameHandler(unsigned short wFrame)
+{
+ (void) wFrame;
+
+ if (uxQueueMessagesWaitingFromISR(xCharsForTx) > 0) {
+ // data available, enable NAK interrupt on bulk in
+ USBHwNakIntEnable(INACK_BI);
+ }
+}
+
+unsigned long CPUcpsie(void)
+{
+ unsigned long ulRet;
+
+ //
+ // Read PRIMASK and enable interrupts.
+ //
+ __asm(" mrs %0, PRIMASK\n"
+ " cpsie i\n"
+ " bx lr\n"
+ : "=r"(ulRet));
+
+ //
+ // The return is handled in the inline assembly, but the compiler will
+ // still complain if there is not an explicit return here (despite the fact
+ // that this does not result in any code being produced because of the
+ // naked attribute).
+ //
+ return(ulRet);
+}
+
+void vUSBTask(void *pvParameters)
+{
+ //int c;
+ portTickType xLastFlashTime;
+
+ /* Just to prevent compiler warnings about the unused parameter. */
+ (void) pvParameters;
+ DBG("Initialising USB stack\n");
+
+ xRxedChars = xQueueCreate(usbRXBUFFER_LEN, sizeof(char));
+ xCharsForTx = xQueueCreate(usbTXBUFFER_LEN, sizeof(char));
+
+ if ((xRxedChars == NULL) || (xCharsForTx == NULL)) {
+ /* Not enough heap available to create the buffer queues, can't do
+ anything so just delete ourselves. */
+ vTaskDelete(NULL);
+ }
+
+
+ // initialise stack
+ USBInit();
+
+ // register descriptors
+ USBRegisterDescriptors(abDescriptors);
+
+ // register class request handler
+ USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abClassReqData);
+
+ // register endpoint handlers
+ USBHwRegisterEPIntHandler(INT_IN_EP, NULL);
+ USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn);
+ USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut);
+
+ // register frame handler
+ USBHwRegisterFrameHandler(USBFrameHandler);
+
+ // enable bulk-in interrupts on NAKs
+ USBHwNakIntEnable(INACK_BI);
+
+ DBG("Starting USB communication\n");
+
+ NVIC_SetPriority(USB_IRQn, configUSB_INTERRUPT_PRIORITY);
+ NVIC_EnableIRQ(USB_IRQn);
+
+ // connect to bus
+
+ DBG("Connecting to USB bus\n");
+ USBHwConnect(TRUE);
+
+ xLastFlashTime = xTaskGetTickCount();
+
+ // echo any character received (do USB stuff in interrupt)
+ for (;;) {
+ // c = VCOM_getchar();
+ // if (c != EOF) {
+ // // Echo character back with INCREMENT_ECHO_BY offset, so for example if
+ // // INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back.
+ // VCOM_putchar(c + INCREMENT_ECHO_BY);
+ // }
+ vTaskDelayUntil(&xLastFlashTime, 1000 / portTICK_RATE_MS);
+ }
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/USB_SENSOR_STREAM.c b/gyro_board/src/usb/LPCUSB/USB_SENSOR_STREAM.c
new file mode 100644
index 0000000..af1eede
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/USB_SENSOR_STREAM.c
@@ -0,0 +1,355 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "usbapi.h"
+#include "usbdebug.h"
+#include "usbstruct.h"
+
+#include "LPC17xx.h"
+
+#define usbMAX_SEND_BLOCK ( 20 / portTICK_RATE_MS )
+#define usbRXBUFFER_LEN ( 80 )
+#define usbTXBUFFER_LEN ( 600 )
+
+#define INT_IN_EP 0x81 //read manual for picking these...
+#define INT_OUT_EP 0x04
+#define BULK_IN_EP 0x82
+#define BULK_OUT_EP 0x05
+
+#define MAX_PACKET_SIZE 64
+
+#define LE_WORD(x) ((x)&0xFF),((x)>>8)
+
+static xQueueHandle xRxedChars = NULL, xCharsForTx = NULL;
+
+static const unsigned char abDescriptors[] = {
+
+// device descriptor
+ 0x12,
+ DESC_DEVICE,
+ LE_WORD(0x0101), // bcdUSB
+ 0xFF, // bDeviceClass
+ 0x00, // bDeviceSubClass
+ 0x00, // bDeviceProtocol
+ MAX_PACKET_SIZE0, // bMaxPacketSize
+ LE_WORD(0x1424), // idVendor
+ LE_WORD(0xd243), // idProduct
+ LE_WORD(0x0153), // bcdDevice
+ 0x03, // iManufacturer
+ 0x36, // iProduct
+ 0x33, // iSerialNumber
+ 0x01, // bNumConfigurations
+
+// configuration descriptor
+ 0x09,
+ DESC_CONFIGURATION,
+ LE_WORD(67), // wTotalLength
+ 0x01, // bNumInterfaces
+ 0x01, // bConfigurationValue
+ 0x00, // iConfiguration
+ 0xC0, // bmAttributes
+ 0x32, // bMaxPower
+// data class interface descriptor
+ 0x09,
+ DESC_INTERFACE,
+ 0x00, // bInterfaceNumber
+ 0x00, // bAlternateSetting
+ 0x04, // bNumEndPoints
+ 0x0A, // bInterfaceClass = data
+ 0x00, // bInterfaceSubClass
+ 0x00, // bInterfaceProtocol
+ 0x00, // iInterface
+// debug EP OUT
+ 0x07,
+ DESC_ENDPOINT,
+ BULK_OUT_EP, // bEndpointAddress
+ 0x02, // bmAttributes = bulk
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
+ 0x00, // bInterval
+// debug EP in
+ 0x07,
+ DESC_ENDPOINT,
+ BULK_IN_EP, // bEndpointAddress
+ 0x02, // bmAttributes = bulk
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
+ 0x00, // bInterval
+// data EP OUT
+ 0x07,
+ DESC_ENDPOINT,
+ INT_OUT_EP, // bEndpointAddress
+ 0x03, // bmAttributes = intr
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
+ 0x01, // bInterval
+// data EP in
+ 0x07,
+ DESC_ENDPOINT,
+ INT_IN_EP, // bEndpointAddress
+ 0x03, // bmAttributes = intr
+ LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize
+ 0x01, // bInterval
+
+ // string descriptors
+ 0x04,
+ DESC_STRING,
+ LE_WORD(0x0409),
+
+ 0x0E,
+ DESC_STRING,
+ 'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,
+
+ 0x14,
+ DESC_STRING,
+ 'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0,
+
+ 0x12,
+ DESC_STRING,
+ 'A', 0, 'B', 0, 'S', 0, 'M', 0, 'o', 0, 't', 0, 'o', 0, 'r', 0,
+
+// terminating zero
+ 0
+};
+
+
+/**
+ * Local function to handle incoming bulk data
+ *
+ * @param [in] bEP
+ * @param [in] bEPStatus
+ */
+static void DebugOut(unsigned char bEP, unsigned char bEPStatus) {
+ int i, iLen;
+ long lHigherPriorityTaskWoken = pdFALSE;
+ unsigned char abBulkBuf[64];
+
+ (void) bEPStatus;
+
+ // get data from USB into intermediate buffer
+ iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));
+ for (i = 0; i < iLen; i++) {
+ // put into queue
+ xQueueSendFromISR(xRxedChars, &(abBulkBuf[ i ]), &lHigherPriorityTaskWoken);
+ }
+
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+
+/**
+ * Local function to handle outgoing bulk data
+ *
+ * @param [in] bEP
+ * @param [in] bEPStatus
+ */
+static void DebugIn(unsigned char bEP, unsigned char bEPStatus) {
+ int i, iLen;
+ long lHigherPriorityTaskWoken = pdFALSE;
+ unsigned char abBulkBuf[64];
+
+ (void) bEPStatus;
+
+ if (uxQueueMessagesWaitingFromISR(xCharsForTx) == 0) {
+ // no more data, disable further NAK interrupts until next USB frame
+ USBHwNakIntEnable(INACK_II);
+ return;
+ }
+
+ // get bytes from transmit FIFO into intermediate buffer
+ for (i = 0; i < MAX_PACKET_SIZE; i++) {
+ if (xQueueReceiveFromISR(xCharsForTx, (&abBulkBuf[i]),
+ &lHigherPriorityTaskWoken) != pdPASS) {
+ break;
+ }
+ }
+ iLen = i;
+
+ // send over USB
+ if (iLen > 0) {
+ USBHwEPWrite(bEP, abBulkBuf, iLen);
+ }
+
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+extern int64_t gyro_angle;
+static unsigned char abDataBuf[64];
+int VCOM_putcharFromISR(int c, long *woken);
+static void DataOut(unsigned char bEP, unsigned char bEPStatus) {
+ int iLen;
+ long lHigherPriorityTaskWoken = pdFALSE;
+ char *a = "hello\n";
+ while(*a){
+ VCOM_putcharFromISR(*a,&lHigherPriorityTaskWoken);
+ a ++;
+ }
+ iLen = USBHwEPRead(bEP, abDataBuf, sizeof(abDataBuf));
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+static void DataIn(unsigned char bEP, unsigned char bEPStatus) {
+ long lHigherPriorityTaskWoken = pdFALSE;
+ unsigned char buff[16];
+ memcpy(buff, &gyro_angle, sizeof(gyro_angle));
+ USBHwEPWrite(bEP, buff, sizeof(gyro_angle));
+ portEND_SWITCHING_ISR(lHigherPriorityTaskWoken);
+}
+
+/**
+ * Writes one character to VCOM port
+ *
+ * @param [in] c character to write
+ * @returns character written, or EOF if character could not be written
+ */
+int VCOM_putcharFromISR(int c, long *lHigherPriorityTaskWoken) {
+ char cc = (char) c;
+
+ if (xQueueSendFromISR(xCharsForTx, &cc,
+ lHigherPriorityTaskWoken) == pdPASS) {
+ return c;
+ } else {
+ return EOF;
+ }
+}
+
+int VCOM_putchar(int c) {
+ char cc = (char) c;
+
+ // Don't block if not connected to USB.
+ if (xQueueSend(xCharsForTx, &cc,
+ USBIsConnected() ? usbMAX_SEND_BLOCK : 0) == pdPASS) {
+ return c;
+ } else {
+ return EOF;
+ }
+}
+
+
+/**
+ * Reads one character from VCOM port
+ *
+ * @returns character read, or EOF if character could not be read
+ */
+int VCOM_getchar(void) {
+ unsigned char c;
+
+ /* Block the task until a character is available. */
+ if(xQueueReceive(xRxedChars, &c, 0) == pdTRUE){ //portMAX_DELAY);
+ return c;
+ }
+ return -1;
+}
+
+
+/**
+ * Interrupt handler
+ *
+ * Simply calls the USB ISR
+ */
+void USB_IRQHandler(void) {
+ USBHwISR();
+}
+
+
+static void USBFrameHandler(unsigned short wFrame) {
+ (void) wFrame;
+
+ if (uxQueueMessagesWaitingFromISR(xCharsForTx) > 0) {
+ // data available, enable NAK interrupt on bulk in
+ USBHwNakIntEnable(INACK_BI);
+ }
+}
+
+void vUSBTask(void *pvParameters) {
+ portTickType xLastFlashTime;
+
+ /* Just to prevent compiler warnings about the unused parameter. */
+ (void) pvParameters;
+ DBG("Initialising USB stack\n");
+
+ xRxedChars = xQueueCreate(usbRXBUFFER_LEN, sizeof(char));
+ xCharsForTx = xQueueCreate(usbTXBUFFER_LEN, sizeof(char));
+
+ if ((xRxedChars == NULL) || (xCharsForTx == NULL)) {
+ /* Not enough heap available to create the buffer queues, can't do
+ anything so just delete ourselves. */
+ vTaskDelete(NULL);
+ }
+
+ // initialise stack
+ USBInit();
+
+ // register descriptors
+ USBRegisterDescriptors(abDescriptors);
+
+ // register class request handler
+ //USBRegisterRequestHandler(REQTYPE_TYPE_CLASS,
+ // HandleClassRequest, abClassReqData);
+
+ // register endpoint handlers
+ USBHwRegisterEPIntHandler(INT_IN_EP, DataIn);
+ USBHwRegisterEPIntHandler(INT_OUT_EP, DataOut);
+ USBHwRegisterEPIntHandler(BULK_IN_EP, DebugIn);
+ USBHwRegisterEPIntHandler(BULK_OUT_EP, DebugOut);
+
+ // register frame handler
+ USBHwRegisterFrameHandler(USBFrameHandler);
+
+ // enable bulk-in interrupts on NAKs
+ USBHwNakIntEnable(INACK_BI);
+
+ DBG("Starting USB communication\n");
+
+ NVIC_SetPriority(USB_IRQn, configUSB_INTERRUPT_PRIORITY);
+ NVIC_EnableIRQ(USB_IRQn);
+
+ // connect to bus
+
+ DBG("Connecting to USB bus\n");
+ USBHwConnect(TRUE);
+
+ xLastFlashTime = xTaskGetTickCount();
+
+ vTaskDelayUntil(&xLastFlashTime, 1000 / portTICK_RATE_MS * 100);
+
+ //USBHwAllowConnect();
+ // echo any character received (do USB stuff in interrupt)
+ for (;;) {
+ // c = VCOM_getchar();
+ // if (c != EOF) {
+ // // Echo character back with INCREMENT_ECHO_BY offset, so for example if
+ // // INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back.
+ // VCOM_putchar(c + INCREMENT_ECHO_BY);
+ // }
+ vTaskDelayUntil(&xLastFlashTime, 1000 / portTICK_RATE_MS);
+ }
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/type.h b/gyro_board/src/usb/LPCUSB/type.h
new file mode 100644
index 0000000..0727519
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/type.h
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * type.h: Type definition Header file for NXP LPC17xx Family
+ * Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.08.21 ver 1.00 Prelimnary version, first Release
+ *
+******************************************************************************/
+#ifndef __TYPE_H__
+#define __TYPE_H__
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+typedef unsigned int BOOL;
+
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
+
+/* Pointer to Function returning Void (any number of parameters) */
+typedef void (*PFV)();
+
+#endif /* __TYPE_H__ */
diff --git a/gyro_board/src/usb/LPCUSB/usbapi.h b/gyro_board/src/usb/LPCUSB/usbapi.h
new file mode 100644
index 0000000..e1fade8
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbapi.h
@@ -0,0 +1,125 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ @file
+*/
+
+#include "usbstruct.h" // for TSetupPacket
+
+/*************************************************************************
+ USB configuration
+**************************************************************************/
+
+#define MAX_PACKET_SIZE0 64 /**< maximum packet size for EP 0 */
+
+/*************************************************************************
+ USB hardware interface
+**************************************************************************/
+
+// endpoint status sent through callback
+#define EP_STATUS_DATA (1<<0) /**< EP has data */
+#define EP_STATUS_STALLED (1<<1) /**< EP is stalled */
+#define EP_STATUS_SETUP (1<<2) /**< EP received setup packet */
+#define EP_STATUS_ERROR (1<<3) /**< EP data was overwritten by setup packet */
+#define EP_STATUS_NACKED (1<<4) /**< EP sent NAK */
+
+// device status sent through callback
+#define DEV_STATUS_CONNECT (1<<0) /**< device just got connected */
+#define DEV_STATUS_SUSPEND (1<<2) /**< device entered suspend state */
+#define DEV_STATUS_RESET (1<<4) /**< device just got reset */
+
+// interrupt bits for NACK events in USBHwNakIntEnable
+// (these bits conveniently coincide with the LPC176x USB controller bit)
+#define INACK_CI (1<<1) /**< interrupt on NACK for control in */
+#define INACK_CO (1<<2) /**< interrupt on NACK for control out */
+#define INACK_II (1<<3) /**< interrupt on NACK for interrupt in */
+#define INACK_IO (1<<4) /**< interrupt on NACK for interrupt out */
+#define INACK_BI (1<<5) /**< interrupt on NACK for bulk in */
+#define INACK_BO (1<<6) /**< interrupt on NACK for bulk out */
+
+BOOL USBHwInit(void);
+void USBHwISR(void);
+
+void USBHwNakIntEnable(unsigned char bIntBits);
+
+void USBHwConnect(BOOL fConnect);
+int USBIsConnected(void);
+
+void USBHwSetAddress(unsigned char bAddr);
+void USBHwConfigDevice(BOOL fConfigured);
+
+// endpoint operations
+void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize);
+int USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen);
+int USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen);
+void USBHwEPStall(unsigned char bEP, BOOL fStall);
+unsigned char USBHwEPGetStatus(unsigned char bEP);
+
+/** Endpoint interrupt handler callback */
+typedef void (TFnEPIntHandler)(unsigned char bEP, unsigned char bEPStatus);
+void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler);
+
+/** Device status handler callback */
+typedef void (TFnDevIntHandler)(unsigned char bDevStatus);
+void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler);
+
+/** Frame event handler callback */
+typedef void (TFnFrameHandler)(unsigned short wFrame);
+void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler);
+
+/** Configuration event handler callback */
+typedef void (SetConfigHandler)(void);
+void USBHwRegisterSetConfigHandler(SetConfigHandler *handler);
+
+
+/*************************************************************************
+ USB application interface
+**************************************************************************/
+
+// initialise the complete stack, including HW
+BOOL USBInit(void);
+
+/** Request handler callback (standard, vendor, class) */
+typedef BOOL (TFnHandleRequest)(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData);
+void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore);
+void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler);
+
+/** Descriptor handler callback */
+typedef BOOL (TFnGetDescriptor)(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData);
+
+/** Default standard request handler */
+BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData);
+
+/** Default EP0 handler */
+void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat);
+
+/** Descriptor handling */
+void USBRegisterDescriptors(const unsigned char *pabDescriptors);
+BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData);
+
+void USBHwAllowConnect(void);
diff --git a/gyro_board/src/usb/LPCUSB/usbcontrol.c b/gyro_board/src/usb/LPCUSB/usbcontrol.c
new file mode 100644
index 0000000..e02f492
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbcontrol.c
@@ -0,0 +1,236 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+ Control transfer handler.
+
+ This module handles control transfers and is normally installed on the
+ endpoint 0 callback.
+
+ Control transfers can be of the following type:
+ 0 Standard;
+ 1 Class;
+ 2 Vendor;
+ 3 Reserved.
+
+ A callback can be installed for each of these control transfers using
+ USBRegisterRequestHandler.
+ When an OUT request arrives, data is collected in the data store provided
+ with the USBRegisterRequestHandler call. When the transfer is done, the
+ callback is called.
+ When an IN request arrives, the callback is called immediately to either
+ put the control transfer data in the data store, or to get a pointer to
+ control transfer data. The data is then packetised and sent to the host.
+*/
+
+#include "usbdebug.h"
+
+#include "usbstruct.h"
+#include "usbapi.h"
+
+
+
+#define MAX_CONTROL_SIZE 128 /**< maximum total size of control transfer data */
+#define MAX_REQ_HANDLERS 4 /**< standard, class, vendor, reserved */
+
+static TSetupPacket Setup; /**< setup packet */
+
+static unsigned char *pbData; /**< pointer to data buffer */
+static int iResidue; /**< remaining bytes in buffer */
+static int iLen; /**< total length of control transfer */
+
+/** Array of installed request handler callbacks */
+static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
+/** Array of installed request data pointers */
+static unsigned char *apbDataStore[4] = {NULL, NULL, NULL, NULL};
+
+/**
+ Local function to handle a request by calling one of the installed
+ request handlers.
+
+ In case of data going from host to device, the data is at *ppbData.
+ In case of data going from device to host, the handler can either
+ choose to write its data at *ppbData or update the data pointer.
+
+ @param [in] pSetup The setup packet
+ @param [in,out] *piLen Pointer to data length
+ @param [in,out] ppbData Data buffer.
+
+ @return TRUE if the request was handles successfully
+ */
+static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ TFnHandleRequest *pfnHandler;
+ int iType;
+
+ iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
+ pfnHandler = apfnReqHandlers[iType];
+ if (pfnHandler == NULL) {
+ DBG("No handler for reqtype %d\n", iType);
+ return FALSE;
+ }
+
+ return pfnHandler(pSetup, piLen, ppbData);
+}
+
+
+/**
+ Local function to stall the control endpoint
+
+ @param [in] bEPStat Endpoint status
+ */
+static void StallControlPipe(unsigned char bEPStat)
+{
+ unsigned char *pb;
+ int i;
+
+ USBHwEPStall(0x80, TRUE);
+
+// dump setup packet
+ DBG("STALL on [");
+ pb = (unsigned char *) & Setup;
+ for (i = 0; i < 8; i++) {
+ DBG(" %02x", *pb++);
+ }
+ DBG("] stat=%x\n", bEPStat);
+}
+
+
+/**
+ Sends next chunk of data (possibly 0 bytes) to host
+ */
+static void DataIn(void)
+{
+ int iChunk;
+
+ if (MAX_PACKET_SIZE0 < iResidue) {
+ iChunk = MAX_PACKET_SIZE0;
+ } else {
+ iChunk = iResidue;
+ }
+
+ USBHwEPWrite(0x80, pbData, iChunk);
+ pbData += iChunk;
+ iResidue -= iChunk;
+}
+
+
+/**
+ * Handles IN/OUT transfers on EP0
+ *
+ * @param [in] bEP Endpoint address
+ * @param [in] bEPStat Endpoint status
+ */
+void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat)
+{
+ int iChunk, iType;
+
+ if (bEP == 0x00) {
+ // OUT transfer
+ if (bEPStat & EP_STATUS_SETUP) {
+ // setup packet, reset request message state machine
+ USBHwEPRead(0x00, (unsigned char *)&Setup, sizeof(Setup));
+ DBG("S%x", Setup.bRequest);
+
+ // defaults for data pointer and residue
+ iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+ pbData = apbDataStore[iType];
+ iResidue = Setup.wLength;
+ iLen = Setup.wLength;
+
+ if ((Setup.wLength == 0) ||
+ (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
+ // ask installed handler to process request
+ if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+ DBG("_HandleRequest1 failed\n");
+ StallControlPipe(bEPStat);
+ return;
+ }
+ // send smallest of requested and offered length
+ if (iLen < Setup.wLength) {
+ iResidue = iLen;
+ } else {
+ iResidue = Setup.wLength;
+ }
+
+ // send first part (possibly a zero-length status message)
+ DataIn();
+ }
+ } else {
+ if (iResidue > 0) {
+ // store data
+ iChunk = USBHwEPRead(0x00, pbData, iResidue);
+ if (iChunk < 0) {
+ StallControlPipe(bEPStat);
+ return;
+ }
+ pbData += iChunk;
+ iResidue -= iChunk;
+ if (iResidue == 0) {
+ // received all, send data to handler
+ iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+ pbData = apbDataStore[iType];
+ if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+ DBG("_HandleRequest2 failed\n");
+ StallControlPipe(bEPStat);
+ return;
+ }
+ // send status to host
+ DataIn();
+ }
+ } else {
+ // absorb zero-length status message
+ iChunk = USBHwEPRead(0x00, NULL, 0);
+ DBG(iChunk > 0 ? "?" : "");
+ }
+ }
+ } else if (bEP == 0x80) {
+ // IN transfer
+ // send more data if available (possibly a 0-length packet)
+ DataIn();
+ } else {
+ ASSERT(FALSE);
+ }
+}
+
+
+/**
+ Registers a callback for handling requests
+
+ @param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD
+ @param [in] *pfnHandler Callback function pointer
+ @param [in] *pbDataStore Data storage area for this type of request
+ */
+void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore)
+{
+ ASSERT(iType >= 0);
+ ASSERT(iType < 4);
+ apfnReqHandlers[iType] = pfnHandler;
+ apbDataStore[iType] = pbDataStore;
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/usbdebug.h b/gyro_board/src/usb/LPCUSB/usbdebug.h
new file mode 100644
index 0000000..4b3d16b
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbdebug.h
@@ -0,0 +1,41 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// CodeRed - comment out this printf, as will use real one from stdio.h
+// to implement output via semihosting
+
+//int printf(const char *format, ...);
+# include <stdio.h>
+
+#ifdef _DEBUG
+#define DBG printf
+#define ASSERT(x) if(!(x)){DBG("\nAssertion '%s' failed in %s:%s#%d!\n",#x,__FILE__,__FUNCTION__,__LINE__);while(1);}
+#else
+#define DBG(x ...)
+#define ASSERT(x)
+#endif
+
diff --git a/gyro_board/src/usb/LPCUSB/usbhw_lpc.c b/gyro_board/src/usb/LPCUSB/usbhw_lpc.c
new file mode 100644
index 0000000..8229371
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbhw_lpc.c
@@ -0,0 +1,538 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+ USB hardware layer
+ */
+
+
+#include "usbdebug.h"
+#include "usbhw_lpc.h"
+#include "usbapi.h"
+
+#ifdef DEBUG
+// comment out the following line if you don't want to use debug LEDs
+//#define DEBUG_LED
+#endif
+
+/** Installed device interrupt handler */
+static TFnDevIntHandler *_pfnDevIntHandler = NULL;
+/** Installed endpoint interrupt handlers */
+static TFnEPIntHandler *_apfnEPIntHandlers[16];
+/** Installed frame interrupt handlers */
+static TFnFrameHandler *_pfnFrameHandler = NULL;
+
+/** convert from endpoint address to endpoint index */
+#define EP2IDX(bEP) ((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7))
+/** convert from endpoint index to endpoint address */
+#define IDX2EP(idx) ((((idx)<<7)&0x80)|(((idx)>>1)&0xF))
+
+
+
+/**
+ Local function to wait for a device interrupt (and clear it)
+
+ @param [in] dwIntr Bitmask of interrupts to wait for
+ */
+static void Wait4DevInt(unsigned long dwIntr)
+{
+ // wait for specific interrupt
+ while ((USB->USBDevIntSt & dwIntr) != dwIntr);
+ // clear the interrupt bits
+ USB->USBDevIntClr = dwIntr;
+}
+
+
+/**
+ Local function to send a command to the USB protocol engine
+
+ @param [in] bCmd Command to send
+ */
+static void USBHwCmd(unsigned char bCmd)
+{
+ // clear CDFULL/CCEMTY
+ USB->USBDevIntClr = CDFULL | CCEMTY;
+ // write command code
+ USB->USBCmdCode = 0x00000500 | (bCmd << 16);
+ Wait4DevInt(CCEMTY);
+}
+
+
+/**
+ Local function to send a command + data to the USB protocol engine
+
+ @param [in] bCmd Command to send
+ @param [in] bData Data to send
+ */
+static void USBHwCmdWrite(unsigned char bCmd, unsigned short bData)
+{
+ // write command code
+ USBHwCmd(bCmd);
+
+ // write command data
+ USB->USBCmdCode = 0x00000100 | (bData << 16);
+ Wait4DevInt(CCEMTY);
+}
+
+
+/**
+ Local function to send a command to the USB protocol engine and read data
+
+ @param [in] bCmd Command to send
+
+ @return the data
+ */
+static unsigned char USBHwCmdRead(unsigned char bCmd)
+{
+ // write command code
+ USBHwCmd(bCmd);
+
+ // get data
+ USB->USBCmdCode = 0x00000200 | (bCmd << 16);
+ Wait4DevInt(CDFULL);
+ return USB->USBCmdData;
+}
+
+
+/**
+ 'Realizes' an endpoint, meaning that buffer space is reserved for
+ it. An endpoint needs to be realised before it can be used.
+
+ From experiments, it appears that a USB reset causes USBReEP to
+ re-initialise to 3 (= just the control endpoints).
+ However, a USB bus reset does not disturb the USBMaxPSize settings.
+
+ @param [in] idx Endpoint index
+ @param [in] wMaxPSize Maximum packet size for this endpoint
+ */
+static void USBHwEPRealize(int idx, unsigned short wMaxPSize)
+{
+ USB->USBReEP |= (1 << idx);
+ USB->USBEpInd = idx;
+ USB->USBMaxPSize = wMaxPSize;
+ Wait4DevInt(EP_RLZED);
+}
+
+
+/**
+ Enables or disables an endpoint
+
+ @param [in] idx Endpoint index
+ @param [in] fEnable TRUE to enable, FALSE to disable
+ */
+static void USBHwEPEnable(int idx, BOOL fEnable)
+{
+ USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA);
+}
+
+
+/**
+ Configures an endpoint and enables it
+
+ @param [in] bEP Endpoint number
+ @param [in] wMaxPacketSize Maximum packet size for this EP
+ */
+void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize)
+{
+ int idx;
+
+ idx = EP2IDX(bEP);
+
+ // realise EP
+ USBHwEPRealize(idx, wMaxPacketSize);
+
+ // enable EP
+ USBHwEPEnable(idx, TRUE);
+}
+
+
+/**
+ Registers an endpoint event callback
+
+ @param [in] bEP Endpoint number
+ @param [in] pfnHandler Callback function
+ */
+void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler)
+{
+ int idx;
+
+ idx = EP2IDX(bEP);
+
+ ASSERT(idx < 32);
+
+ /* add handler to list of EP handlers */
+ _apfnEPIntHandlers[idx / 2] = pfnHandler;
+
+ /* enable EP interrupt */
+ USB->USBEpIntEn |= (1 << idx);
+ USB->USBDevIntEn |= EP_SLOW;
+
+ DBG("Registered handler for EP 0x%x\n", bEP);
+}
+
+
+/**
+ Registers an device status callback
+
+ @param [in] pfnHandler Callback function
+ */
+void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler)
+{
+ _pfnDevIntHandler = pfnHandler;
+
+ // enable device interrupt
+ USB->USBDevIntEn |= DEV_STAT;
+
+ DBG("Registered handler for device status\n");
+}
+
+
+/**
+ Registers the frame callback
+
+ @param [in] pfnHandler Callback function
+ */
+void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler)
+{
+ _pfnFrameHandler = pfnHandler;
+
+ // enable device interrupt
+ USB->USBDevIntEn |= FRAME;
+
+ DBG("Registered handler for frame\n");
+}
+
+
+/**
+ Sets the USB address.
+
+ @param [in] bAddr Device address to set
+ */
+void USBHwSetAddress(unsigned char bAddr)
+{
+ USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr);
+}
+
+
+/**
+ Connects or disconnects from the USB bus
+
+ @param [in] fConnect If TRUE, connect, otherwise disconnect
+ */
+void USBHwConnect(BOOL fConnect)
+{
+ USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0);
+}
+
+int USBIsConnected(void) {
+ return (GPIO1->FIOPIN >> 18) & 0x1;
+}
+
+
+/**
+ Enables interrupt on NAK condition
+
+ For IN endpoints a NAK is generated when the host wants to read data
+ from the device, but none is available in the endpoint buffer.
+ For OUT endpoints a NAK is generated when the host wants to write data
+ to the device, but the endpoint buffer is still full.
+
+ The endpoint interrupt handlers can distinguish regular (ACK) interrupts
+ from NAK interrupt by checking the bits in their bEPStatus argument.
+
+ @param [in] bIntBits Bitmap indicating which NAK interrupts to enable
+ */
+void USBHwNakIntEnable(unsigned char bIntBits)
+{
+ USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits);
+}
+
+
+/**
+ Gets the status from a specific endpoint.
+
+ @param [in] bEP Endpoint number
+ @return Endpoint status byte (containing EP_STATUS_xxx bits)
+ */
+unsigned char USBHwEPGetStatus(unsigned char bEP)
+{
+ int idx = EP2IDX(bEP);
+
+ return USBHwCmdRead(CMD_EP_SELECT | idx);
+}
+
+
+/**
+ Sets the stalled property of an endpoint
+
+ @param [in] bEP Endpoint number
+ @param [in] fStall TRUE to stall, FALSE to unstall
+ */
+void USBHwEPStall(unsigned char bEP, BOOL fStall)
+{
+ int idx = EP2IDX(bEP);
+
+ USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0);
+}
+
+
+/**
+ Writes data to an endpoint buffer
+
+ @param [in] bEP Endpoint number
+ @param [in] pbBuf Endpoint data
+ @param [in] iLen Number of bytes to write
+
+ @return TRUE if the data was successfully written or <0 in case of error.
+*/
+int USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen)
+{
+ int idx;
+
+ idx = EP2IDX(bEP);
+
+ // set write enable for specific endpoint
+ USB->USBCtrl = WR_EN | ((bEP & 0xF) << 2);
+
+ // set packet length
+ USB->USBTxPLen = iLen;
+
+ // write data
+ while (USB->USBCtrl & WR_EN) {
+ USB->USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0];
+ pbBuf += 4;
+ }
+
+ // select endpoint and validate buffer
+ USBHwCmd(CMD_EP_SELECT | idx);
+ USBHwCmd(CMD_EP_VALIDATE_BUFFER);
+
+ return iLen;
+}
+
+
+/**
+ Reads data from an endpoint buffer
+
+ @param [in] bEP Endpoint number
+ @param [in] pbBuf Endpoint data
+ @param [in] iMaxLen Maximum number of bytes to read
+
+ @return the number of bytes available in the EP (possibly more than iMaxLen),
+ or <0 in case of error.
+ */
+int USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen)
+{
+ int i, idx;
+ unsigned long dwData, dwLen;
+
+ idx = EP2IDX(bEP);
+
+ // set read enable bit for specific endpoint
+ USB->USBCtrl = RD_EN | ((bEP & 0xF) << 2);
+
+ // wait for PKT_RDY
+ do {
+ dwLen = USB->USBRxPLen;
+ } while ((dwLen & PKT_RDY) == 0);
+
+ // packet valid?
+ if ((dwLen & DV) == 0) {
+ return -1;
+ }
+
+ // get length
+ dwLen &= PKT_LNGTH_MASK;
+
+ // get data
+ dwData = 0;
+ for (i = 0; i < dwLen; i++) {
+ if ((i % 4) == 0) {
+ dwData = USB->USBRxData;
+ }
+ if ((pbBuf != NULL) && (i < iMaxLen)) {
+ pbBuf[i] = dwData & 0xFF;
+ }
+ dwData >>= 8;
+ }
+
+ // make sure RD_EN is clear
+ USB->USBCtrl = 0;
+
+ // select endpoint and clear buffer
+ USBHwCmd(CMD_EP_SELECT | idx);
+ USBHwCmd(CMD_EP_CLEAR_BUFFER);
+
+ return dwLen;
+}
+
+
+/**
+ Sets the 'configured' state.
+
+ All registered endpoints are 'realised' and enabled, and the
+ 'configured' bit is set in the device status register.
+
+ @param [in] fConfigured If TRUE, configure device, else unconfigure
+ */
+void USBHwConfigDevice(BOOL fConfigured)
+{
+ // set configured bit
+ USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0);
+}
+
+
+/**
+ * USB interrupt handler
+ *
+ * @todo Get all 11 bits of frame number instead of just 8
+ *
+ * Endpoint interrupts are mapped to the slow interrupt
+ */
+void USBHwISR(void) {
+ unsigned long dwStatus;
+ unsigned long dwIntBit;
+ unsigned char bEPStat, bDevStat, bStat;
+ int i;
+ unsigned short wFrame;
+
+ // handle device interrupts
+ dwStatus = USB->USBDevIntSt;
+
+ // frame interrupt
+ if (dwStatus & FRAME) {
+ // clear int
+ USB->USBDevIntClr = FRAME;
+ // call handler
+ if (_pfnFrameHandler != NULL) {
+ wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR);
+ _pfnFrameHandler(wFrame);
+ }
+ }
+
+ // device status interrupt
+ if (dwStatus & DEV_STAT) {
+ /* Clear DEV_STAT interrupt before reading DEV_STAT register.
+ This prevents corrupted device status reads, see
+ LPC2148 User manual revision 2, 25 july 2006.
+ */
+ USB->USBDevIntClr = DEV_STAT;
+ bDevStat = USBHwCmdRead(CMD_DEV_STATUS);
+ if (bDevStat & (CON_CH | SUS_CH | RST)) {
+ // convert device status into something HW independent
+ bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) |
+ ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) |
+ ((bDevStat & RST) ? DEV_STATUS_RESET : 0);
+ // call handler
+ if (_pfnDevIntHandler != NULL) {
+ _pfnDevIntHandler(bStat);
+ }
+ }
+ }
+
+ // endpoint interrupt
+ if (dwStatus & EP_SLOW) {
+ // clear EP_SLOW
+ USB->USBDevIntClr = EP_SLOW;
+ // check all endpoints
+ for (i = 0; i < 32; i++) {
+ dwIntBit = (1 << i);
+ if (USB->USBEpIntSt & dwIntBit) {
+ // clear int (and retrieve status)
+ USB->USBEpIntClr = dwIntBit;
+ Wait4DevInt(CDFULL);
+ bEPStat = USB->USBCmdData;
+ // convert EP pipe stat into something HW independent
+ bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) |
+ ((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) |
+ ((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) |
+ ((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) |
+ ((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0);
+ // call handler
+ if (_apfnEPIntHandlers[i / 2] != NULL) {
+ _apfnEPIntHandlers[i / 2](IDX2EP(i), bStat);
+ }
+ }
+ }
+ }
+}
+
+
+
+/**
+ Initialises the USB hardware
+
+
+ @return TRUE if the hardware was successfully initialised
+ */
+BOOL USBHwInit(void)
+{
+ // P2.9 -> USB_CONNECT
+ //PINCON->PINSEL4 &= ~0x000C0000;
+ //PINCON->PINSEL4 |= 0x00040000;
+ // Leave it disconnected.
+ // Before the device can be used, it needs to be connected.
+ GPIO2->FIODIR |= (1UL << 9UL);
+ GPIO2->FIOCLR = (1UL << 9UL);
+
+ // P1.18 -> USB_UP_LED
+ // P1.30 -> VBUS
+ PINCON->PINSEL3 &= ~0x30000030;
+ PINCON->PINSEL3 |= 0x00000010;
+
+ // P0.29 -> USB_D+
+ // P0.30 -> USB_D-
+ PINCON->PINSEL1 &= ~0x3C000000;
+ PINCON->PINSEL1 |= 0x14000000;
+
+ // enable PUSB
+ SC->PCONP |= (1 << 31);
+
+ USB->OTGClkCtrl = 0x12; /* Dev clock, AHB clock enable */
+ while ((USB->OTGClkSt & 0x12) != 0x12);
+
+ // disable/clear all interrupts for now
+ USB->USBDevIntEn = 0;
+ USB->USBDevIntClr = 0xFFFFFFFF;
+ USB->USBDevIntPri = 0;
+
+ USB->USBEpIntEn = 0;
+ USB->USBEpIntClr = 0xFFFFFFFF;
+ USB->USBEpIntPri = 0;
+
+ // by default, only ACKs generate interrupts
+ USBHwNakIntEnable(0);
+
+ return TRUE;
+}
+
+void USBHwAllowConnect(void)
+{
+ // Enable USB.
+ GPIO2->FIOSET = (1UL << 9UL);
+}
diff --git a/gyro_board/src/usb/LPCUSB/usbhw_lpc.h b/gyro_board/src/usb/LPCUSB/usbhw_lpc.h
new file mode 100644
index 0000000..d6b60af
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbhw_lpc.h
@@ -0,0 +1,149 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/**
+ Hardware definitions for the LPC176x USB controller
+
+ These are private to the usbhw module
+*/
+
+// CodeRed - pull in defines from NXP header file
+//#include "NXP\LPC17xx\LPC17xx.h"
+#include "LPC17xx.h"
+
+
+// CodeRed - these registers have been renamed on LPC176x
+#define USBReEP USBReEp
+#define OTG_CLK_CTRL USBClkCtrl
+#define OTG_CLK_STAT USBClkSt
+
+/* USBIntSt bits */
+#define USB_INT_REQ_LP (1<<0)
+#define USB_INT_REQ_HP (1<<1)
+#define USB_INT_REQ_DMA (1<<2)
+#define USB_need_clock (1<<8)
+#define EN_USB_BITS (1<<31)
+
+/* USBDevInt... bits */
+#define FRAME (1<<0)
+#define EP_FAST (1<<1)
+#define EP_SLOW (1<<2)
+#define DEV_STAT (1<<3)
+#define CCEMTY (1<<4)
+#define CDFULL (1<<5)
+#define RxENDPKT (1<<6)
+#define TxENDPKT (1<<7)
+#define EP_RLZED (1<<8)
+#define ERR_INT (1<<9)
+
+/* USBRxPLen bits */
+#define PKT_LNGTH (1<<0)
+#define PKT_LNGTH_MASK 0x3FF
+#define DV (1<<10)
+#define PKT_RDY (1<<11)
+
+/* USBCtrl bits */
+#define RD_EN (1<<0)
+#define WR_EN (1<<1)
+#define LOG_ENDPOINT (1<<2)
+
+/* protocol engine command codes */
+/* device commands */
+#define CMD_DEV_SET_ADDRESS 0xD0
+#define CMD_DEV_CONFIG 0xD8
+#define CMD_DEV_SET_MODE 0xF3
+#define CMD_DEV_READ_CUR_FRAME_NR 0xF5
+#define CMD_DEV_READ_TEST_REG 0xFD
+#define CMD_DEV_STATUS 0xFE /* read/write */
+#define CMD_DEV_GET_ERROR_CODE 0xFF
+#define CMD_DEV_READ_ERROR_STATUS 0xFB
+/* endpoint commands */
+#define CMD_EP_SELECT 0x00
+#define CMD_EP_SELECT_CLEAR 0x40
+#define CMD_EP_SET_STATUS 0x40
+#define CMD_EP_CLEAR_BUFFER 0xF2
+#define CMD_EP_VALIDATE_BUFFER 0xFA
+
+/* set address command */
+#define DEV_ADDR (1<<0)
+#define DEV_EN (1<<7)
+
+/* configure device command */
+#define CONF_DEVICE (1<<0)
+
+/* set mode command */
+#define AP_CLK (1<<0)
+#define INAK_CI (1<<1)
+#define INAK_CO (1<<2)
+#define INAK_II (1<<3)
+#define INAK_IO (1<<4)
+#define INAK_BI (1<<5)
+#define INAK_BO (1<<6)
+
+/* set get device status command */
+#define CON (1<<0)
+#define CON_CH (1<<1)
+#define SUS (1<<2)
+#define SUS_CH (1<<3)
+#define RST (1<<4)
+
+/* get error code command */
+// ...
+
+/* Select Endpoint command read bits */
+#define EPSTAT_FE (1<<0)
+#define EPSTAT_ST (1<<1)
+#define EPSTAT_STP (1<<2)
+#define EPSTAT_PO (1<<3)
+#define EPSTAT_EPN (1<<4)
+#define EPSTAT_B1FULL (1<<5)
+#define EPSTAT_B2FULL (1<<6)
+
+/* CMD_EP_SET_STATUS command */
+#define EP_ST (1<<0)
+#define EP_DA (1<<5)
+#define EP_RF_MO (1<<6)
+#define EP_CND_ST (1<<7)
+
+/* read error status command */
+#define PID_ERR (1<<0)
+#define UEPKT (1<<1)
+#define DCRC (1<<2)
+#define TIMEOUT (1<<3)
+#define EOP (1<<4)
+#define B_OVRN (1<<5)
+#define BTSTF (1<<6)
+#define TGL_ERR (1<<7)
+
+
+
+
+
+
+
+
diff --git a/gyro_board/src/usb/LPCUSB/usbinit.c b/gyro_board/src/usb/LPCUSB/usbinit.c
new file mode 100644
index 0000000..49b31a0
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbinit.c
@@ -0,0 +1,82 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+ USB stack initialisation
+ */
+
+
+#include "usbdebug.h"
+#include "usbapi.h"
+
+
+/** data storage area for standard requests */
+static unsigned char abStdReqData[8];
+
+
+/**
+ USB reset handler
+
+ @param [in] bDevStatus Device status
+ */
+static void HandleUsbReset(unsigned char bDevStatus)
+{
+ if (bDevStatus & DEV_STATUS_RESET) {
+ DBG("\n!");
+ }
+}
+
+
+/**
+ Initialises the USB hardware and sets up the USB stack by
+ installing default callbacks.
+
+ @return TRUE if initialisation was successful
+ */
+BOOL USBInit(void)
+{
+ // init hardware
+ USBHwInit();
+
+ // register bus reset handler
+ USBHwRegisterDevIntHandler(HandleUsbReset);
+
+ // register control transfer handler on EP0
+ USBHwRegisterEPIntHandler(0x00, USBHandleControlTransfer);
+ USBHwRegisterEPIntHandler(0x80, USBHandleControlTransfer);
+
+ // setup control endpoints
+ USBHwEPConfig(0x00, MAX_PACKET_SIZE0);
+ USBHwEPConfig(0x80, MAX_PACKET_SIZE0);
+
+ // register standard request handler
+ USBRegisterRequestHandler(REQTYPE_TYPE_STANDARD, USBHandleStandardRequest, abStdReqData);
+
+ return TRUE;
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/usbstdreq.c b/gyro_board/src/usb/LPCUSB/usbstdreq.c
new file mode 100644
index 0000000..6a3fde5
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbstdreq.c
@@ -0,0 +1,438 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/** @file
+ Standard request handler.
+
+ This modules handles the 'chapter 9' processing, specifically the
+ standard device requests in table 9-3 from the universal serial bus
+ specification revision 2.0
+
+ Specific types of devices may specify additional requests (for example
+ HID devices add a GET_DESCRIPTOR request for interfaces), but they
+ will not be part of this module.
+
+ @todo some requests have to return a request error if device not configured:
+ @todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME
+ @todo this applies to the following if endpoint != 0:
+ @todo SET_FEATURE, GET_FEATURE
+*/
+
+#include "usbdebug.h"
+#include "usbstruct.h"
+#include "usbapi.h"
+
+#define MAX_DESC_HANDLERS 4 /**< device, interface, endpoint, other */
+
+
+/* general descriptor field offsets */
+#define DESC_bLength 0 /**< length offset */
+#define DESC_bDescriptorType 1 /**< descriptor type offset */
+
+/* config descriptor field offsets */
+#define CONF_DESC_wTotalLength 2 /**< total length offset */
+#define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */
+#define CONF_DESC_bmAttributes 7 /**< configuration characteristics */
+
+/* interface descriptor field offsets */
+#define INTF_DESC_bAlternateSetting 3 /**< alternate setting offset */
+
+/* endpoint descriptor field offsets */
+#define ENDP_DESC_bEndpointAddress 2 /**< endpoint address offset */
+#define ENDP_DESC_wMaxPacketSize 4 /**< maximum packet size offset */
+
+
+/** Currently selected configuration */
+static unsigned char bConfiguration = 0;
+/** Installed custom request handler */
+static TFnHandleRequest *pfnHandleCustomReq = NULL;
+/** Pointer to registered descriptors */
+static const unsigned char *pabDescrip = NULL;
+
+
+/**
+ Registers a pointer to a descriptor block containing all descriptors
+ for the device.
+
+ @param [in] pabDescriptors The descriptor byte array
+ */
+void USBRegisterDescriptors(const unsigned char *pabDescriptors)
+{
+ pabDescrip = pabDescriptors;
+}
+
+
+/**
+ Parses the list of installed USB descriptors and attempts to find
+ the specified USB descriptor.
+
+ @param [in] wTypeIndex Type and index of the descriptor
+ @param [in] wLangID Language ID of the descriptor (currently unused)
+ @param [out] *piLen Descriptor length
+ @param [out] *ppbData Descriptor data
+
+ @return TRUE if the descriptor was found, FALSE otherwise
+ */
+BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData)
+{
+ unsigned char bType, bIndex;
+ unsigned char *pab;
+ int iCurIndex;
+
+ ASSERT(pabDescrip != NULL);
+
+ bType = GET_DESC_TYPE(wTypeIndex);
+ bIndex = GET_DESC_INDEX(wTypeIndex);
+
+ pab = (unsigned char *)pabDescrip;
+ iCurIndex = 0;
+
+ while (pab[DESC_bLength] != 0) {
+ if (pab[DESC_bDescriptorType] == bType) {
+ if (iCurIndex == bIndex) {
+ // set data pointer
+ *ppbData = pab;
+ // get length from structure
+ if (bType == DESC_CONFIGURATION) {
+ // configuration descriptor is an exception, length is at offset 2 and 3
+ *piLen = (pab[CONF_DESC_wTotalLength]) |
+ (pab[CONF_DESC_wTotalLength + 1] << 8);
+ } else {
+ // normally length is at offset 0
+ *piLen = pab[DESC_bLength];
+ }
+ return TRUE;
+ }
+ iCurIndex++;
+ }
+ // skip to next descriptor
+ pab += pab[DESC_bLength];
+ }
+ // nothing found
+ DBG("Desc %x not found!\n", wTypeIndex);
+ return FALSE;
+}
+
+
+/**
+ Configures the device according to the specified configuration index and
+ alternate setting by parsing the installed USB descriptor list.
+ A configuration index of 0 unconfigures the device.
+
+ @param [in] bConfigIndex Configuration index
+ @param [in] bAltSetting Alternate setting number
+
+ @todo function always returns TRUE, add stricter checking?
+
+ @return TRUE if successfully configured, FALSE otherwise
+ */
+static BOOL USBSetConfiguration(unsigned char bConfigIndex, unsigned char bAltSetting)
+{
+ unsigned char *pab;
+ unsigned char bCurConfig, bCurAltSetting;
+ unsigned char bEP;
+ unsigned short wMaxPktSize;
+
+ ASSERT(pabDescrip != NULL);
+
+ if (bConfigIndex == 0) {
+ // unconfigure device
+ USBHwConfigDevice(FALSE);
+ } else {
+ // configure endpoints for this configuration/altsetting
+ pab = (unsigned char *)pabDescrip;
+ bCurConfig = 0xFF;
+ bCurAltSetting = 0xFF;
+
+ while (pab[DESC_bLength] != 0) {
+
+ switch (pab[DESC_bDescriptorType]) {
+
+ case DESC_CONFIGURATION:
+ // remember current configuration index
+ bCurConfig = pab[CONF_DESC_bConfigurationValue];
+ break;
+
+ case DESC_INTERFACE:
+ // remember current alternate setting
+ bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
+ break;
+
+ case DESC_ENDPOINT:
+ if ((bCurConfig == bConfigIndex) &&
+ (bCurAltSetting == bAltSetting)) {
+ // endpoint found for desired config and alternate setting
+ bEP = pab[ENDP_DESC_bEndpointAddress];
+ wMaxPktSize = (pab[ENDP_DESC_wMaxPacketSize]) |
+ (pab[ENDP_DESC_wMaxPacketSize + 1] << 8);
+ // configure endpoint
+ USBHwEPConfig(bEP, wMaxPktSize);
+ }
+ break;
+
+ default:
+ break;
+ }
+ // skip to next descriptor
+ pab += pab[DESC_bLength];
+ }
+
+ // configure device
+ USBHwConfigDevice(TRUE);
+ }
+
+ return TRUE;
+}
+SetConfigHandler *SetConfig_CallBack = NULL;
+void USBHwRegisterSetConfigHandler(SetConfigHandler *handler){
+ SetConfig_CallBack = handler;
+}
+
+
+/**
+ Local function to handle a standard device request
+
+ @param [in] pSetup The setup packet
+ @param [in,out] *piLen Pointer to data length
+ @param [in,out] ppbData Data buffer.
+
+ @return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ unsigned char *pbData = *ppbData;
+
+ switch (pSetup->bRequest) {
+
+ case REQ_GET_STATUS:
+ // bit 0: self-powered
+ // bit 1: remote wakeup = not supported
+ pbData[0] = 0;
+ pbData[1] = 0;
+ *piLen = 2;
+ break;
+
+ case REQ_SET_ADDRESS:
+ USBHwSetAddress(pSetup->wValue);
+ break;
+
+ case REQ_GET_DESCRIPTOR:
+ DBG("D%x", pSetup->wValue);
+ return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);
+
+ case REQ_GET_CONFIGURATION:
+ // indicate if we are configured
+ pbData[0] = bConfiguration;
+ *piLen = 1;
+ break;
+
+ case REQ_SET_CONFIGURATION:
+ if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {
+ DBG("USBSetConfiguration failed!\n");
+ return FALSE;
+ }
+ // configuration successful, update current configuration
+ bConfiguration = pSetup->wValue & 0xFF;
+ if(SetConfig_CallBack != NULL)
+ SetConfig_CallBack();
+ break;
+
+ case REQ_CLEAR_FEATURE:
+ case REQ_SET_FEATURE:
+ if (pSetup->wValue == FEA_REMOTE_WAKEUP) {
+ // put DEVICE_REMOTE_WAKEUP code here
+ }
+ if (pSetup->wValue == FEA_TEST_MODE) {
+ // put TEST_MODE code here
+ }
+ return FALSE;
+
+ case REQ_SET_DESCRIPTOR:
+ DBG("Device req %d not implemented\n", pSetup->bRequest);
+ return FALSE;
+
+ default:
+ DBG("Illegal device req %d\n", pSetup->bRequest);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ Local function to handle a standard interface request
+
+ @param [in] pSetup The setup packet
+ @param [in,out] *piLen Pointer to data length
+ @param [in] ppbData Data buffer.
+
+ @return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdInterfaceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ unsigned char *pbData = *ppbData;
+
+ switch (pSetup->bRequest) {
+
+ case REQ_GET_STATUS:
+ // no bits specified
+ pbData[0] = 0;
+ pbData[1] = 0;
+ *piLen = 2;
+ break;
+
+ case REQ_CLEAR_FEATURE:
+ case REQ_SET_FEATURE:
+ // not defined for interface
+ return FALSE;
+
+ case REQ_GET_INTERFACE: // TODO use bNumInterfaces
+ // there is only one interface, return n-1 (= 0)
+ pbData[0] = 0;
+ *piLen = 1;
+ break;
+
+ case REQ_SET_INTERFACE: // TODO use bNumInterfaces
+ // there is only one interface (= 0)
+ if (pSetup->wValue != 0) {
+ return FALSE;
+ }
+ *piLen = 0;
+ break;
+
+ default:
+ DBG("Illegal interface req %d\n", pSetup->bRequest);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ Local function to handle a standard endpoint request
+
+ @param [in] pSetup The setup packet
+ @param [in,out] *piLen Pointer to data length
+ @param [in] ppbData Data buffer.
+
+ @return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdEndPointReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ unsigned char *pbData = *ppbData;
+
+ switch (pSetup->bRequest) {
+ case REQ_GET_STATUS:
+ // bit 0 = endpointed halted or not
+ pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
+ pbData[1] = 0;
+ *piLen = 2;
+ break;
+
+ case REQ_CLEAR_FEATURE:
+ if (pSetup->wValue == FEA_ENDPOINT_HALT) {
+ // clear HALT by unstalling
+ USBHwEPStall(pSetup->wIndex, FALSE);
+ break;
+ }
+ // only ENDPOINT_HALT defined for endpoints
+ return FALSE;
+
+ case REQ_SET_FEATURE:
+ if (pSetup->wValue == FEA_ENDPOINT_HALT) {
+ // set HALT by stalling
+ USBHwEPStall(pSetup->wIndex, TRUE);
+ break;
+ }
+ // only ENDPOINT_HALT defined for endpoints
+ return FALSE;
+
+ case REQ_SYNCH_FRAME:
+ DBG("EP req %d not implemented\n", pSetup->bRequest);
+ return FALSE;
+
+ default:
+ DBG("Illegal EP req %d\n", pSetup->bRequest);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ Default handler for standard ('chapter 9') requests
+
+ If a custom request handler was installed, this handler is called first.
+
+ @param [in] pSetup The setup packet
+ @param [in,out] *piLen Pointer to data length
+ @param [in] ppbData Data buffer.
+
+ @return TRUE if the request was handled successfully
+ */
+BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ // try the custom request handler first
+ if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {
+ return TRUE;
+ }
+
+ switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
+ case REQTYPE_RECIP_DEVICE:
+ return HandleStdDeviceReq(pSetup, piLen, ppbData);
+ case REQTYPE_RECIP_INTERFACE:
+ return HandleStdInterfaceReq(pSetup, piLen, ppbData);
+ case REQTYPE_RECIP_ENDPOINT:
+ return HandleStdEndPointReq(pSetup, piLen, ppbData);
+ default:
+ return FALSE;
+ }
+}
+
+
+/**
+ Registers a callback for custom device requests
+
+ In USBHandleStandardRequest, the custom request handler gets a first
+ chance at handling the request before it is handed over to the 'chapter 9'
+ request handler.
+
+ This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
+ request is sent to an interface, which is not covered by the 'chapter 9'
+ specification.
+
+ @param [in] pfnHandler Callback function pointer
+ */
+void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)
+{
+ pfnHandleCustomReq = pfnHandler;
+}
+
diff --git a/gyro_board/src/usb/LPCUSB/usbstruct.h b/gyro_board/src/usb/LPCUSB/usbstruct.h
new file mode 100644
index 0000000..d6bd725
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbstruct.h
@@ -0,0 +1,119 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/**
+ Definitions of structures of standard USB packets
+*/
+
+#ifndef _USBSTRUCT_H_
+#define _USBSTRUCT_H_
+
+// CodeRed - include the LPCUSB type.h file rather than NXP one directly
+#include "type.h"
+
+/** setup packet definitions */
+typedef struct {
+ unsigned char bmRequestType; /**< characteristics of the specific request */
+ unsigned char bRequest; /**< specific request */
+ unsigned short wValue; /**< request specific parameter */
+ unsigned short wIndex; /**< request specific parameter */
+ unsigned short wLength; /**< length of data transfered in data phase */
+} TSetupPacket;
+
+
+#define REQTYPE_GET_DIR(x) (((x)>>7)&0x01)
+#define REQTYPE_GET_TYPE(x) (((x)>>5)&0x03)
+#define REQTYPE_GET_RECIP(x) ((x)&0x1F)
+
+#define REQTYPE_DIR_TO_DEVICE 0
+#define REQTYPE_DIR_TO_HOST 1
+
+#define REQTYPE_TYPE_STANDARD 0
+#define REQTYPE_TYPE_CLASS 1
+#define REQTYPE_TYPE_VENDOR 2
+#define REQTYPE_TYPE_RESERVED 3
+
+#define REQTYPE_RECIP_DEVICE 0
+#define REQTYPE_RECIP_INTERFACE 1
+#define REQTYPE_RECIP_ENDPOINT 2
+#define REQTYPE_RECIP_OTHER 3
+
+/* standard requests */
+#define REQ_GET_STATUS 0x00
+#define REQ_CLEAR_FEATURE 0x01
+#define REQ_SET_FEATURE 0x03
+#define REQ_SET_ADDRESS 0x05
+#define REQ_GET_DESCRIPTOR 0x06
+#define REQ_SET_DESCRIPTOR 0x07
+#define REQ_GET_CONFIGURATION 0x08
+#define REQ_SET_CONFIGURATION 0x09
+#define REQ_GET_INTERFACE 0x0A
+#define REQ_SET_INTERFACE 0x0B
+#define REQ_SYNCH_FRAME 0x0C
+
+/* class requests HID */
+#define HID_GET_REPORT 0x01
+#define HID_GET_IDLE 0x02
+#define HID_GET_PROTOCOL 0x03
+#define HID_SET_REPORT 0x09
+#define HID_SET_IDLE 0x0A
+#define HID_SET_PROTOCOL 0x0B
+
+/* feature selectors */
+#define FEA_ENDPOINT_HALT 0x00
+#define FEA_REMOTE_WAKEUP 0x01
+#define FEA_TEST_MODE 0x02
+
+/*
+ USB descriptors
+*/
+
+/** USB descriptor header */
+typedef struct {
+ unsigned char bLength; /**< descriptor length */
+ unsigned char bDescriptorType; /**< descriptor type */
+} TUSBDescHeader;
+
+#define DESC_DEVICE 1
+#define DESC_CONFIGURATION 2
+#define DESC_STRING 3
+#define DESC_INTERFACE 4
+#define DESC_ENDPOINT 5
+#define DESC_DEVICE_QUALIFIER 6
+#define DESC_OTHER_SPEED 7
+#define DESC_INTERFACE_POWER 8
+
+#define DESC_HID_HID 0x21
+#define DESC_HID_REPORT 0x22
+#define DESC_HID_PHYSICAL 0x23
+
+#define GET_DESC_TYPE(x) (((x)>>8)&0xFF)
+#define GET_DESC_INDEX(x) ((x)&0xFF)
+
+#endif /* _USBSTRUCT_H_ */
+
diff --git a/gyro_board/src/usb/Makefile b/gyro_board/src/usb/Makefile
new file mode 100644
index 0000000..a87936e
--- /dev/null
+++ b/gyro_board/src/usb/Makefile
@@ -0,0 +1,63 @@
+NAME=main
+
+LDSCRIPT=lpc1758_Debug.ld
+
+CSRC=main.c
+
+GCC_PATH=/usr/local/cortex-m3/bin
+
+PORT=/dev/ttyUSB0
+
+CC=$(GCC_PATH)/arm-eabi-gcc
+LD=$(GCC_PATH)/arm-eabi-ld
+OBJCOPY=$(GCC_PATH)/arm-eabi-objcopy
+AS=$(GCC_PATH)/arm-eabi-as
+FLASHER=lpc21isp
+
+CFLAGS=-I. -I./FreeRTOS/include -I./FreeRTOS/portable/GCC/ARM_CM3/ -I./CommonDemoTasks/include -Os -mcpu=cortex-m3 -mthumb -Wl,--gc-sections -ffunction-sections -Wl,-static -Werror
+
+SPEED=38400
+OSC=12000
+
+SOURCES=main.c \
+ ParTest.c \
+ printf-stdarg.c \
+ cr_startup_lpc17.c \
+ CommonDemoTasks/flash.c \
+ FreeRTOS/portable/MemMang/heap_2.c \
+ alloc.c \
+ analog.c \
+ FreeRTOS/portable/GCC/ARM_CM3/port.c \
+ FreeRTOS/tasks.c \
+ FreeRTOS/list.c \
+ FreeRTOS/queue.c \
+ CAN.c \
+ LPCUSB/usbinit.c \
+ LPCUSB/usbcontrol.c \
+ LPCUSB/USB_SENSOR_STREAM.c \
+ LPCUSB/usbhw_lpc.c \
+ spi.c \
+ LPCUSB/usbstdreq.c
+
+all: $(NAME).hex
+
+$(NAME).elf: Makefile $(SOURCES:.c=.o) $(LDSCRIPT)
+ $(CC) $(CFLAGS) -nostartfiles -nostdlib -T $(LDSCRIPT) -o $@ -L/usr/local/cortex-m3/lib/gcc/arm-eabi/4.5.1/ $(SOURCES:.c=.o) -Wa,-Map -Wa,main.map -lgcc
+
+%.o: %.c Makefile
+ $(CC) $(CFLAGS) -nostartfiles -nostdlib -c -o $@ $< -Wall -std=gnu99
+
+run: deploy
+ $(FLASHER) -termonly $(NAME).hex $(PORT) $(SPEED) $(OSC)
+
+deploy: all $(NAME).hex
+ $(FLASHER) -hex -verify $(NAME).hex $(PORT) $(SPEED) $(OSC)
+
+cat:
+ @cd ../../bin; python serial_looper.py
+
+%.hex: %.elf Makefile
+ $(OBJCOPY) -O ihex $< $@
+
+clean:
+ rm -rf $(SOURCES:.c=.o) $(NAME).hex $(NAME).elf
diff --git a/gyro_board/src/usb/ParTest.c b/gyro_board/src/usb/ParTest.c
new file mode 100644
index 0000000..67f3a45
--- /dev/null
+++ b/gyro_board/src/usb/ParTest.c
@@ -0,0 +1,119 @@
+/*
+ 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.
+*/
+
+/* FreeRTOS.org includes. */
+#include "FreeRTOS.h"
+
+/* Demo application includes. */
+#include "partest.h"
+
+#define LED_1 ( 1UL << 8UL )
+#define LED_2 ( 1UL << 7UL )
+#define LED_3 ( 1UL << 6UL )
+
+#define partstFIO1_BITS ( LED_2 | LED_3 | LED_1)
+#define partstNUM_LEDS ( 3 )
+
+static unsigned long ulLEDs[] = {LED_1, LED_2, LED_3};
+
+/*-----------------------------------------------------------
+ * Simple parallel port IO routines.
+ *-----------------------------------------------------------*/
+
+void vParTestInitialise(void)
+{
+ /* LEDs on port 2. */
+ GPIO2->FIODIR |= partstFIO1_BITS;
+ //GPIO0->FIODIR = LED_4;
+
+ /* Start will all LEDs off. */
+ GPIO2->FIOCLR = partstFIO1_BITS;
+ //GPIO0->FIOSET = LED_4;
+ //PINCON->PINMODE0 = (PINCON->PINMODE0 & 0xfffffff0) | 0x00000001;
+}
+/*-----------------------------------------------------------*/
+
+void vParTestSetLED(unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue)
+{
+ if (uxLED < partstNUM_LEDS) {
+ if (xValue) {
+ GPIO2->FIOCLR = ulLEDs[uxLED];
+ } else {
+ GPIO2->FIOSET = ulLEDs[uxLED];
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+void vParTestToggleLED(unsigned portBASE_TYPE uxLED)
+{
+ if (uxLED < partstNUM_LEDS) {
+ if (GPIO2->FIOPIN & ulLEDs[uxLED]) {
+ GPIO2->FIOCLR = ulLEDs[uxLED];
+ } else {
+ GPIO2->FIOSET = ulLEDs[uxLED];
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE uxParTextGetLED(unsigned portBASE_TYPE uxLED)
+{
+ if (uxLED < partstNUM_LEDS) {
+ return (GPIO2->FIOPIN & ulLEDs[uxLED]);
+ } else {
+ return 0;
+ }
+}
+/*-----------------------------------------------------------*/
+
diff --git a/gyro_board/src/usb/alloc.c b/gyro_board/src/usb/alloc.c
new file mode 100644
index 0000000..1684551
--- /dev/null
+++ b/gyro_board/src/usb/alloc.c
@@ -0,0 +1,62 @@
+/*
+ * This is a glue between newlib and FreeRTOS heap2 allocator !
+ * You need to understand how heap2 works and its limitations,
+ * otherwise you will run out of memory.
+ *
+ * Michal Demin - 2010
+ *
+ * TODO: reent is there for a reason !
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* definition of block structure, copied from heap2 allocator */
+typedef struct A_BLOCK_LINK
+{
+ struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
+ size_t xBlockSize; /*<< The size of the free block. */
+} xBlockLink;
+
+static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );
+
+_PTR _realloc_r(struct _reent *re, _PTR oldAddr, size_t newSize) {
+ xBlockLink *block;
+ size_t toCopy;
+ void *newAddr;
+
+ newAddr = pvPortMalloc(newSize);
+
+ if (newAddr == NULL)
+ return NULL;
+
+ /* We need the block struct pointer to get the current size */
+ block = oldAddr;
+ block -= heapSTRUCT_SIZE;
+
+ /* determine the size to be copied */
+ toCopy = (newSize<block->xBlockSize)?(newSize):(block->xBlockSize);
+
+ /* copy old block into new one */
+ memcpy((void *)newAddr, (void *)oldAddr, (size_t)toCopy);
+
+ vPortFree(oldAddr);
+
+ return newAddr;
+}
+
+_PTR _calloc_r(struct _reent *re, size_t num, size_t size) {
+ return pvPortMalloc(num*size);
+}
+
+_PTR _malloc_r(struct _reent *re, size_t size) {
+ return pvPortMalloc(size);
+}
+
+_VOID _free_r(struct _reent *re, _PTR ptr) {
+ vPortFree(ptr);
+}
+
diff --git a/gyro_board/src/usb/analog.c b/gyro_board/src/usb/analog.c
new file mode 100644
index 0000000..9e67dd5
--- /dev/null
+++ b/gyro_board/src/usb/analog.c
@@ -0,0 +1,220 @@
+// ****************************************************************************
+// CopyLeft qwerk Robotics unINC. 2010 All Rights Reserved.
+// ****************************************************************************
+
+// ****************************************************************************
+// **************** IO Pin Setup
+// ****************************************************************************
+
+#include "FreeRTOS.h"
+
+void analog_init (void)
+{
+ // b[1:0] CAN RD1 p0.0
+ // b[3:2] CAN TD1 p0.1
+ //PINCON->PINSEL0 = 0x00000005;
+
+ // b[29:28] USB_DMIN p0.30
+ // b[27:26] USB_DPLUS p0.29
+ // b[21:20] AD0.3 p0.26
+ // b[19:18] AD0.2 p0.25
+ // PINCON->PINSEL1 = 0x14140000;
+
+ // PINCON->PINSEL2 = 0x0;
+
+ // b[31:30] AD0.5 p1.31
+ // b[29:28] V_BUS p1.30
+ // b[21:20] MCOB1 p1.26
+ // b[19:18] MCOA1 p1.25
+ // b[15:14] MCI1 p1.23
+ // b[13:12] MCOB0 p1.22
+ // b[09:08] MCI0 p1.20
+ // b[07:06] MCOA0 p1.19
+ // b[05:04] USB_UP_LED p1.18
+ //PINCON->PINSEL3 = 0xE0145150;
+ SC->PCONP |= PCONP_PCAD;
+
+ // Enable AD0.0, AD0.1, AD0.2, AD0.3
+ PINCON->PINSEL1 &= 0xFFC03FFF;
+ PINCON->PINSEL1 |= 0x00D54000;
+ ADC->ADCR = 0x00200500;
+}
+
+// ****************************************************************************
+// **************** ADC Functions
+// ****************************************************************************
+
+
+// **************** macros
+// starts convertion [26:24] = 001
+
+// **************** functions
+int analog(int channel)
+{
+ ADC->ADCR = ((ADC->ADCR & 0xF8FFFF00) | (0x01000000 | (1 << channel)));
+
+ // Poll until it is done.
+ while(!(ADC->ADGDR & 0x80000000));
+
+ return ((ADC->ADGDR & 0x0000FFF0) >> 4);
+}
+// GPIO1 P0.4
+// GPIO2 P0.5
+// GPIO3 P0.6
+// GPIO4 P0.7
+// GPIO5 P0.8
+// GPIO6 P0.9
+// GPIO7 P2.0
+// GPIO8 P2.1
+// GPIO9 P2.2
+// GPIO10 P2.3
+// GPIO11 P2.4
+// GPIO12 P2.5
+
+// DIP0 P1.29
+// DIP1 P2.13
+// DIP2 P0.11
+// DIP3 P0.10
+#define readGPIO(gpio,chan) ((((gpio)->FIOPIN) >> (chan)) & 1)
+inline int readGPIO_inline(int major,int minor){
+ switch(major){
+ case 0:
+ return readGPIO(GPIO0,minor);
+ case 1:
+ return readGPIO(GPIO1,minor);
+ case 2:
+ return readGPIO(GPIO2,minor);
+ default:
+ return -1;
+ }
+}
+int digital(int channel)
+{
+ if(channel < 1){
+ return -1;
+ }else if(channel < 7){
+ int chan = channel + 3;
+ return readGPIO(GPIO0,chan);
+ }else if(channel < 13){
+ int chan = channel - 7;
+ return readGPIO(GPIO2,chan);
+ }
+ return -1;
+}
+int dip(int channel)
+{
+ switch(channel){
+ case 0:
+ return readGPIO(GPIO1,29);
+ case 1:
+ return readGPIO(GPIO2,13);
+ case 2:
+ return readGPIO(GPIO0,11);
+ case 3:
+ return readGPIO(GPIO0,10);
+ default:
+ return -1;
+
+ }
+}
+//ENC0A 1.20
+//ENC0B 1.23
+//ENC1A 2.11
+//ENC1B 2.12
+//ENC2A 0.21
+//ENC2B 0.22
+//ENC3A 0.19
+//ENC3B 0.20
+
+#define ENC(gpio,a,b) readGPIO(gpio,a) * 2 + readGPIO(gpio,b)
+int encoder_bits(int channel)
+{
+ switch(channel){
+ case 0:
+ return ENC(GPIO1,20,23);
+ case 1:
+ return ENC(GPIO2,11,12);
+ case 2:
+ return ENC(GPIO0,21,22);
+ case 3:
+ return ENC(GPIO0,19,20);
+ default:
+ return -1;
+ }
+ return -1;
+}
+
+volatile int32_t encoder1_val;
+void encoder_init(void)
+{
+// port 0
+ // Setup the encoder interface.
+ SC->PCONP |= PCONP_PCQEI;
+ PINCON->PINSEL3 = ((PINCON->PINSEL3 & 0xffff3dff) | 0x00004100);
+
+ // Reset the count and velocity
+ QEI->QEICON = 0x00000005;
+
+ QEI->QEICONF = 0x00000004;
+ // Wrap back to 0 when we wrap the int...
+ QEI->QEIMAXPOS = 0xffffffff;
+// port 1
+ NVIC_EnableIRQ(EINT1_IRQn);
+ NVIC_EnableIRQ(EINT2_IRQn);
+ //NVIC_EnableIRQ(EINT3_IRQn);
+ //PINSEL4 23/22 0 1
+ //PINSEL4 25 24 0 1
+ PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 22)) | (0x1 << 22);
+ PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 24)) | (0x1 << 24);
+
+ //EXTMODE 1 2 1 1 // all others off
+ SC->EXTMODE = 0x6;
+ SC->EXTINT = 0x6;
+ encoder1_val = 0;
+//ports 2 and 3
+
+
+}
+void EINT1_IRQHandler(void){
+ //ENC1A 2.11
+ int stored_val = encoder1_val;
+ int fiopin = GPIO2->FIOPIN;
+ if(((fiopin >> 1) ^ fiopin) & 0x800){
+ stored_val ++;
+ }else{
+ stored_val --;
+ }
+ encoder1_val = stored_val;
+ SC->EXTPOLAR ^= 0x2;
+ SC->EXTINT = 0x2;
+}
+void EINT2_IRQHandler(void){
+ //ENC1B 2.12
+ int stored_val = encoder1_val;
+ int fiopin = GPIO2->FIOPIN;
+ if(((fiopin >> 1) ^ fiopin) & 0x800){
+ stored_val --;
+ }else{
+ stored_val ++;
+ }
+ encoder1_val = stored_val;
+ SC->EXTPOLAR ^= 0x4;
+ SC->EXTINT = 0x4;
+}
+void EINT3_IRQHandler(void){
+
+}
+int32_t encoder_val(int chan)
+{
+ switch(chan){
+ case 0:
+ return (int32_t)QEI->QEIPOS;
+ case 1:
+ return encoder1_val;
+ case 2:
+ case 3:
+ default:
+ return -1;
+ }
+}
+
diff --git a/gyro_board/src/usb/analog.h b/gyro_board/src/usb/analog.h
new file mode 100644
index 0000000..e9704f6
--- /dev/null
+++ b/gyro_board/src/usb/analog.h
@@ -0,0 +1,11 @@
+#ifndef __ANALOG_H__
+#define __ANALOG_H__
+
+void analog_init (void);
+int analog(int chan);
+int digital(int chan);
+int encoder_bits(int chan);
+void encoder_init(void);
+int32_t encoder_val(int chan);
+int dip(int chan);
+#endif // __ANALOG_H__
diff --git a/gyro_board/src/usb/core_cm3.h b/gyro_board/src/usb/core_cm3.h
new file mode 100644
index 0000000..a6e8707
--- /dev/null
+++ b/gyro_board/src/usb/core_cm3.h
@@ -0,0 +1,1376 @@
+/******************************************************************************
+ * @file: core_cm3.h
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version: V1.20
+ * @date: 22. May 2009
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". 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.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CM3_CORE_H__
+#define __CM3_CORE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x03) /*!< Cortex core */
+
+ /**
+ * Lint configuration \n
+ * ----------------------- \n
+ *
+ * The following Lint messages will be suppressed and not shown: \n
+ * \n
+ * --- Error 10: --- \n
+ * register uint32_t __regBasePri __asm("basepri"); \n
+ * Error 10: Expecting ';' \n
+ * \n
+ * --- Error 530: --- \n
+ * return(__regBasePri); \n
+ * Warning 530: Symbol '__regBasePri' (line 264) not initialized \n
+ * \n
+ * --- Error 550: --- \n
+ * __regBasePri = (basePri & 0x1ff); \n
+ * } \n
+ * Warning 550: Symbol '__regBasePri' (line 271) not accessed \n
+ * \n
+ * --- Error 754: --- \n
+ * uint32_t RESERVED0[24]; \n
+ * Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 750: --- \n
+ * #define __CM3_CORE_H__ \n
+ * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 528: --- \n
+ * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n
+ * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 751: --- \n
+ * } InterruptType_Type; \n
+ * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n
+ * \n
+ * \n
+ * Note: To re-enable a Message, insert a space before 'lint' * \n
+ *
+ */
+
+ /*lint -save */
+ /*lint -e10 */
+ /*lint -e530 */
+ /*lint -e550 */
+ /*lint -e754 */
+ /*lint -e750 */
+ /*lint -e528 */
+ /*lint -e751 */
+
+
+#include <stdint.h> /* Include standard types */
+
+#if defined (__ICCARM__)
+#include <intrinsics.h> /* IAR Intrinsics */
+#endif
+
+
+#ifndef __NVIC_PRIO_BITS
+#define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */
+#endif
+
+
+
+
+ /**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#ifdef __cplusplus
+#define __I volatile /*!< defines 'read only' permissions */
+#else
+#define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+
+
+ /*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+
+
+ /* System Reset */
+#define NVIC_VECTRESET 0 /*!< Vector Reset Bit */
+#define NVIC_SYSRESETREQ 2 /*!< System Reset Request */
+#define NVIC_AIRCR_VECTKEY (0x5FA << 16) /*!< AIRCR Key for write access */
+#define NVIC_AIRCR_ENDIANESS 15 /*!< Endianess */
+
+ /* Core Debug */
+#define CoreDebug_DEMCR_TRCENA (1 << 24) /*!< DEMCR TRCENA enable */
+#define ITM_TCR_ITMENA 1 /*!< ITM enable */
+
+
+
+
+ /* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
+ typedef struct {
+ __IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */
+ uint32_t RESERVED0[24];
+ __IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24];
+ __IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */
+ uint32_t RESERVED2[24];
+ __IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24];
+ __IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */
+ uint32_t RESERVED4[56];
+ __IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */
+ uint32_t RESERVED5[644];
+ __O uint32_t STIR; /*!< Software Trigger Interrupt Register */
+ } NVIC_Type;
+
+
+ /* memory mapping struct for System Control Block */
+ typedef struct {
+ __I uint32_t CPUID; /*!< CPU ID Base Register */
+ __IO uint32_t ICSR; /*!< Interrupt Control State Register */
+ __IO uint32_t VTOR; /*!< Vector Table Offset Register */
+ __IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */
+ __IO uint32_t SCR; /*!< System Control Register */
+ __IO uint32_t CCR; /*!< Configuration Control Register */
+ __IO uint8_t SHP[12]; /*!< System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IO uint32_t SHCSR; /*!< System Handler Control and State Register */
+ __IO uint32_t CFSR; /*!< Configurable Fault Status Register */
+ __IO uint32_t HFSR; /*!< Hard Fault Status Register */
+ __IO uint32_t DFSR; /*!< Debug Fault Status Register */
+ __IO uint32_t MMFAR; /*!< Mem Manage Address Register */
+ __IO uint32_t BFAR; /*!< Bus Fault Address Register */
+ __IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */
+ __I uint32_t PFR[2]; /*!< Processor Feature Register */
+ __I uint32_t DFR; /*!< Debug Feature Register */
+ __I uint32_t ADR; /*!< Auxiliary Feature Register */
+ __I uint32_t MMFR[4]; /*!< Memory Model Feature Register */
+ __I uint32_t ISAR[5]; /*!< ISA Feature Register */
+ } SCB_Type;
+
+
+ /* memory mapping struct for SysTick */
+ typedef struct {
+ __IO uint32_t CTRL; /*!< SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< SysTick Calibration Register */
+ } SysTick_Type;
+
+
+ /* memory mapping structur for ITM */
+ typedef struct {
+ __O union {
+ __O uint8_t u8; /*!< ITM Stimulus Port 8-bit */
+ __O uint16_t u16; /*!< ITM Stimulus Port 16-bit */
+ __O uint32_t u32; /*!< ITM Stimulus Port 32-bit */
+ } PORT [32]; /*!< ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864];
+ __IO uint32_t TER; /*!< ITM Trace Enable Register */
+ uint32_t RESERVED1[15];
+ __IO uint32_t TPR; /*!< ITM Trace Privilege Register */
+ uint32_t RESERVED2[15];
+ __IO uint32_t TCR; /*!< ITM Trace Control Register */
+ uint32_t RESERVED3[29];
+ __IO uint32_t IWR; /*!< ITM Integration Write Register */
+ __IO uint32_t IRR; /*!< ITM Integration Read Register */
+ __IO uint32_t IMCR; /*!< ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43];
+ __IO uint32_t LAR; /*!< ITM Lock Access Register */
+ __IO uint32_t LSR; /*!< ITM Lock Status Register */
+ uint32_t RESERVED5[6];
+ __I uint32_t PID4; /*!< ITM Product ID Registers */
+ __I uint32_t PID5;
+ __I uint32_t PID6;
+ __I uint32_t PID7;
+ __I uint32_t PID0;
+ __I uint32_t PID1;
+ __I uint32_t PID2;
+ __I uint32_t PID3;
+ __I uint32_t CID0;
+ __I uint32_t CID1;
+ __I uint32_t CID2;
+ __I uint32_t CID3;
+ } ITM_Type;
+
+
+ /* memory mapped struct for Interrupt Type */
+ typedef struct {
+ uint32_t RESERVED0;
+ __I uint32_t ICTR; /*!< Interrupt Control Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+ __IO uint32_t ACTLR; /*!< Auxiliary Control Register */
+#else
+ uint32_t RESERVED1;
+#endif
+ } InterruptType_Type;
+
+
+ /* Memory Protection Unit */
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+ typedef struct {
+ __I uint32_t TYPE; /*!< MPU Type Register */
+ __IO uint32_t CTRL; /*!< MPU Control Register */
+ __IO uint32_t RNR; /*!< MPU Region RNRber Register */
+ __IO uint32_t RBAR; /*!< MPU Region Base Address Register */
+ __IO uint32_t RASR; /*!< MPU Region Attribute and Size Register */
+ __IO uint32_t RBAR_A1; /*!< MPU Alias 1 Region Base Address Register */
+ __IO uint32_t RASR_A1; /*!< MPU Alias 1 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A2; /*!< MPU Alias 2 Region Base Address Register */
+ __IO uint32_t RASR_A2; /*!< MPU Alias 2 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A3; /*!< MPU Alias 3 Region Base Address Register */
+ __IO uint32_t RASR_A3; /*!< MPU Alias 3 Region Attribute and Size Register */
+ } MPU_Type;
+#endif
+
+
+ /* Core Debug Register */
+ typedef struct {
+ __IO uint32_t DHCSR; /*!< Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Debug Exception and Monitor Control Register */
+ } CoreDebug_Type;
+
+
+ /* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000) /*!< ITM Base Address */
+#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
+
+#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */
+#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+#define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */
+#define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */
+#endif
+
+
+
+ /*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+#if defined ( __CC_ARM )
+#define __ASM __asm /*!< asm keyword for ARM Compiler */
+#define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+#define __ASM __asm /*!< asm keyword for IAR Compiler */
+#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+#define __ASM __asm /*!< asm keyword for GNU Compiler */
+#define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+#define __ASM __asm /*!< asm keyword for TASKING Compiler */
+#define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+
+ /* ################### Compiler specific Intrinsics ########################### */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+ /* ARM armcc specific functions */
+
+#define __enable_fault_irq __enable_fiq
+#define __disable_fault_irq __disable_fiq
+
+#define __NOP __nop
+#define __WFI __wfi
+#define __WFE __wfe
+#define __SEV __sev
+#define __ISB() __isb(0)
+#define __DSB() __dsb(0)
+#define __DMB() __dmb(0)
+#define __REV __rev
+#define __RBIT __rbit
+#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))
+#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))
+#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))
+#define __STREXB(value, ptr) __strex(value, ptr)
+#define __STREXH(value, ptr) __strex(value, ptr)
+#define __STREXW(value, ptr) __strex(value, ptr)
+
+
+ /* intrinsic unsigned long long __ldrexd(volatile void *ptr) */
+ /* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */
+ /* intrinsic void __enable_irq(); */
+ /* intrinsic void __disable_irq(); */
+
+
+ /**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+ extern uint32_t __get_PSP(void);
+
+ /**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+ extern void __set_PSP(uint32_t topOfProcStack);
+
+ /**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+ extern uint32_t __get_MSP(void);
+
+ /**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+ extern void __set_MSP(uint32_t topOfMainStack);
+
+ /**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+ extern uint32_t __REV16(uint16_t value);
+
+ /*
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+ extern int32_t __REVSH(int16_t value);
+
+
+#if (__ARMCC_VERSION < 400000)
+
+ /**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * @param none
+ * @return none
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+ extern void __CLREX(void);
+
+ /**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+ extern uint32_t __get_BASEPRI(void);
+
+ /**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+ extern void __set_BASEPRI(uint32_t basePri);
+
+ /**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+ extern uint32_t __get_PRIMASK(void);
+
+ /**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+ extern void __set_PRIMASK(uint32_t priMask);
+
+ /**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+ extern uint32_t __get_FAULTMASK(void);
+
+ /**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+ extern void __set_FAULTMASK(uint32_t faultMask);
+
+ /**
+ * @brief Return the Control Register value
+ *
+ * @param none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+ extern uint32_t __get_CONTROL(void);
+
+ /**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+ extern void __set_CONTROL(uint32_t control);
+
+#else /* (__ARMCC_VERSION >= 400000) */
+
+
+ /**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * @param none
+ * @return none
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+#define __CLREX __clrex
+
+ /**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+ static __INLINE uint32_t __get_BASEPRI(void) {
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+ }
+
+ /**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+ static __INLINE void __set_BASEPRI(uint32_t basePri) {
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0x1ff);
+ }
+
+ /**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+ static __INLINE uint32_t __get_PRIMASK(void) {
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+ }
+
+ /**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+ static __INLINE void __set_PRIMASK(uint32_t priMask) {
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+ }
+
+ /**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+ static __INLINE uint32_t __get_FAULTMASK(void) {
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+ }
+
+ /**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+ static __INLINE void __set_FAULTMASK(uint32_t faultMask) {
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & 1);
+ }
+
+ /**
+ * @brief Return the Control Register value
+ *
+ * @param none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+ static __INLINE uint32_t __get_CONTROL(void) {
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+ }
+
+ /**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+ static __INLINE void __set_CONTROL(uint32_t control) {
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+ }
+
+#endif /* __ARMCC_VERSION */
+
+
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+ /* IAR iccarm specific functions */
+
+#define __enable_irq __enable_interrupt /*!< global Interrupt enable */
+#define __disable_irq __disable_interrupt /*!< global Interrupt disable */
+
+ static __INLINE void __enable_fault_irq() {
+ __ASM("cpsie f");
+ }
+ static __INLINE void __disable_fault_irq() {
+ __ASM("cpsid f");
+ }
+
+#define __NOP __no_operation() /*!< no operation intrinsic in IAR Compiler */
+ static __INLINE void __WFI() {
+ __ASM("wfi");
+ }
+ static __INLINE void __WFE() {
+ __ASM("wfe");
+ }
+ static __INLINE void __SEV() {
+ __ASM("sev");
+ }
+ static __INLINE void __CLREX() {
+ __ASM("clrex");
+ }
+
+ /* intrinsic void __ISB(void) */
+ /* intrinsic void __DSB(void) */
+ /* intrinsic void __DMB(void) */
+ /* intrinsic void __set_PRIMASK(); */
+ /* intrinsic void __get_PRIMASK(); */
+ /* intrinsic void __set_FAULTMASK(); */
+ /* intrinsic void __get_FAULTMASK(); */
+ /* intrinsic uint32_t __REV(uint32_t value); */
+ /* intrinsic uint32_t __REVSH(uint32_t value); */
+ /* intrinsic unsigned long __STREX(unsigned long, unsigned long); */
+ /* intrinsic unsigned long __LDREX(unsigned long *); */
+
+
+ /**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+ extern uint32_t __get_PSP(void);
+
+ /**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+ extern void __set_PSP(uint32_t topOfProcStack);
+
+ /**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+ extern uint32_t __get_MSP(void);
+
+ /**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+ extern void __set_MSP(uint32_t topOfMainStack);
+
+ /**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+ extern uint32_t __REV16(uint16_t value);
+
+ /**
+ * @brief Reverse bit order of value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+ extern uint32_t __RBIT(uint32_t value);
+
+ /**
+ * @brief LDR Exclusive
+ *
+ * @param uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+ extern uint8_t __LDREXB(uint8_t *addr);
+
+ /**
+ * @brief LDR Exclusive
+ *
+ * @param uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+ extern uint16_t __LDREXH(uint16_t *addr);
+
+ /**
+ * @brief LDR Exclusive
+ *
+ * @param uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+ extern uint32_t __LDREXW(uint32_t *addr);
+
+ /**
+ * @brief STR Exclusive
+ *
+ * @param uint8_t *address
+ * @param uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+ extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+ /**
+ * @brief STR Exclusive
+ *
+ * @param uint16_t *address
+ * @param uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+ extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+ /**
+ * @brief STR Exclusive
+ *
+ * @param uint32_t *address
+ * @param uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+ extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+ /* GNU gcc specific functions */
+
+ static __INLINE void __enable_irq() {
+ __ASM volatile("cpsie i");
+ }
+ static __INLINE void __disable_irq() {
+ __ASM volatile("cpsid i");
+ }
+
+ static __INLINE void __enable_fault_irq() {
+ __ASM volatile("cpsie f");
+ }
+ static __INLINE void __disable_fault_irq() {
+ __ASM volatile("cpsid f");
+ }
+
+ static __INLINE void __NOP() {
+ __ASM volatile("nop");
+ }
+ static __INLINE void __WFI() {
+ __ASM volatile("wfi");
+ }
+ static __INLINE void __WFE() {
+ __ASM volatile("wfe");
+ }
+ static __INLINE void __SEV() {
+ __ASM volatile("sev");
+ }
+ static __INLINE void __ISB() {
+ __ASM volatile("isb");
+ }
+ static __INLINE void __DSB() {
+ __ASM volatile("dsb");
+ }
+ static __INLINE void __DMB() {
+ __ASM volatile("dmb");
+ }
+ static __INLINE void __CLREX() {
+ __ASM volatile("clrex");
+ }
+
+
+ /**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+ extern uint32_t __get_PSP(void);
+
+ /**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+ extern void __set_PSP(uint32_t topOfProcStack);
+
+ /**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+ extern uint32_t __get_MSP(void);
+
+ /**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+ extern void __set_MSP(uint32_t topOfMainStack);
+
+ /**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+ extern uint32_t __get_BASEPRI(void);
+
+ /**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+ extern void __set_BASEPRI(uint32_t basePri);
+
+ /**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+ extern uint32_t __get_PRIMASK(void);
+
+ /**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+ extern void __set_PRIMASK(uint32_t priMask);
+
+ /**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+ extern uint32_t __get_FAULTMASK(void);
+
+ /**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+ extern void __set_FAULTMASK(uint32_t faultMask);
+
+ /**
+ * @brief Return the Control Register value
+ *
+ * @param none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+ extern uint32_t __get_CONTROL(void);
+
+ /**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+ extern void __set_CONTROL(uint32_t control);
+
+ /**
+ * @brief Reverse byte order in integer value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in integer value
+ */
+ extern uint32_t __REV(uint32_t value);
+
+ /**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+ extern uint32_t __REV16(uint16_t value);
+
+ /*
+ * Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ */
+ extern int32_t __REVSH(int16_t value);
+
+ /**
+ * @brief Reverse bit order of value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+ extern uint32_t __RBIT(uint32_t value);
+
+ /**
+ * @brief LDR Exclusive
+ *
+ * @param uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+ extern uint8_t __LDREXB(uint8_t *addr);
+
+ /**
+ * @brief LDR Exclusive
+ *
+ * @param uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+ extern uint16_t __LDREXH(uint16_t *addr);
+
+ /**
+ * @brief LDR Exclusive
+ *
+ * @param uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+ extern uint32_t __LDREXW(uint32_t *addr);
+
+ /**
+ * @brief STR Exclusive
+ *
+ * @param uint8_t *address
+ * @param uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+ extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+ /**
+ * @brief STR Exclusive
+ *
+ * @param uint16_t *address
+ * @param uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+ extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+ /**
+ * @brief STR Exclusive
+ *
+ * @param uint32_t *address
+ * @param uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+ extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+ /* TASKING carm specific functions */
+
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+
+
+ /* ########################## NVIC functions #################################### */
+
+
+ /**
+ * @brief Set the Priority Grouping in NVIC Interrupt Controller
+ *
+ * @param uint32_t priority_grouping is priority grouping field
+ * @return none
+ *
+ * Set the priority grouping field using the required unlock sequence.
+ * The parameter priority_grouping is assigned to the field
+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ */
+ static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) {
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((0xFFFFU << 16) | (0x0F << 8)); /* clear bits to change */
+ reg_value = ((reg_value | NVIC_AIRCR_VECTKEY | (PriorityGroupTmp << 8))); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+ }
+
+ /**
+ * @brief Get the Priority Grouping from NVIC Interrupt Controller
+ *
+ * @param none
+ * @return uint32_t priority grouping field
+ *
+ * Get the priority grouping from NVIC Interrupt Controller.
+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
+ */
+ static __INLINE uint32_t NVIC_GetPriorityGrouping(void) {
+ return ((SCB->AIRCR >> 8) & 0x07); /* read priority grouping field */
+ }
+
+ /**
+ * @brief Enable Interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn_Type IRQn specifies the interrupt number
+ * @return none
+ *
+ * Enable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+ static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) {
+ NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+ }
+
+ /**
+ * @brief Disable the interrupt line for external interrupt specified
+ *
+ * @param IRQn_Type IRQn is the positive number of the external interrupt
+ * @return none
+ *
+ * Disable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+ static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) {
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+ }
+
+ /**
+ * @brief Read the interrupt pending bit for a device specific interrupt source
+ *
+ * @param IRQn_Type IRQn is the number of the device specifc interrupt
+ * @return uint32_t 1 if pending interrupt else 0
+ *
+ * Read the pending register in NVIC and return 1 if its status is pending,
+ * otherwise it returns 0
+ */
+ static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) {
+ return((uint32_t)((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) ? 1 : 0)); /* Return 1 if pending else 0 */
+ }
+
+ /**
+ * @brief Set the pending bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Set the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+ static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) {
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+ }
+
+ /**
+ * @brief Clear the pending bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Clear the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+ static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) {
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+ }
+
+ /**
+ * @brief Read the active bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return uint32_t 1 if active else 0
+ *
+ * Read the active register in NVIC and returns 1 if its status is active,
+ * otherwise it returns 0.
+ */
+ static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) {
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) ? 1 : 0)); /* Return 1 if active else 0 */
+ }
+
+ /**
+ * @brief Set the priority for an interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @param priority is the priority for the interrupt
+ * @return none
+ *
+ * Set the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt. \n
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+ static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) {
+ if (IRQn < 0) {
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);
+ } /* set Priority for Cortex-M3 System Interrupts */
+ else {
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);
+ } /* set Priority for device specific Interrupts */
+ }
+
+ /**
+ * @brief Read the priority for an interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return uint32_t priority is the priority for the interrupt
+ *
+ * Read the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * The returned priority value is automatically aligned to the implemented
+ * priority bits of the microcontroller.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+ static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) {
+
+ if (IRQn < 0) {
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));
+ } /* get priority for Cortex-M3 system interrupts */
+ else {
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS)));
+ } /* get priority for device specific interrupts */
+ }
+
+
+ /**
+ * @brief Encode the priority for an interrupt
+ *
+ * @param uint32_t PriorityGroup is the used priority group
+ * @param uint32_t PreemptPriority is the preemptive priority value (starting from 0)
+ * @param uint32_t SubPriority is the sub priority value (starting from 0)
+ * @return uint32_t the priority for the interrupt
+ *
+ * Encode the priority for an interrupt with the given priority group,
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The returned priority value can be used for NVIC_SetPriority(...) function
+ */
+ static __INLINE uint32_t NVIC_EncodePriority(uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) {
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ return (
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+ ((SubPriority & ((1 << (SubPriorityBits)) - 1)))
+ );
+ }
+
+
+ /**
+ * @brief Decode the priority of an interrupt
+ *
+ * @param uint32_t Priority the priority for the interrupt
+ * @param uint32_t PrioGroup is the used priority group
+ * @param uint32_t* pPreemptPrio is the preemptive priority value (starting from 0)
+ * @param uint32_t* pSubPrio is the sub priority value (starting from 0)
+ * @return none
+ *
+ * Decode an interrupt priority value with the given priority group to
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The priority value can be retrieved with NVIC_GetPriority(...) function
+ */
+ static __INLINE void NVIC_DecodePriority(uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) {
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+ *pSubPriority = (Priority) & ((1 << (SubPriorityBits)) - 1);
+ }
+
+
+
+ /* ################################## SysTick function ############################################ */
+
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
+
+ /* SysTick constants */
+#define SYSTICK_ENABLE 0 /* Config-Bit to start or stop the SysTick Timer */
+#define SYSTICK_TICKINT 1 /* Config-Bit to enable or disable the SysTick interrupt */
+#define SYSTICK_CLKSOURCE 2 /* Clocksource has the offset 2 in SysTick Control and Status Register */
+#define SYSTICK_MAXCOUNT ((1<<24) -1) /* SysTick MaxCount */
+
+ /**
+ * @brief Initialize and start the SysTick counter and its interrupt.
+ *
+ * @param uint32_t ticks is the number of ticks between two interrupts
+ * @return none
+ *
+ * Initialise the system tick timer and its interrupt and start the
+ * system tick timer / counter in free running mode to generate
+ * periodical interrupts.
+ */
+ static __INLINE uint32_t SysTick_Config(uint32_t ticks) {
+ if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1; /* set reload register */
+ NVIC_SetPriority(SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = (0x00); /* Load the SysTick Counter Value */
+ SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1 << SYSTICK_ENABLE) | (1 << SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+ }
+
+#endif
+
+
+
+
+
+ /* ################################## Reset function ############################################ */
+
+ /**
+ * @brief Initiate a system reset request.
+ *
+ * @param none
+ * @return none
+ *
+ * Initialize a system reset request to reset the MCU
+ */
+ static __INLINE void NVIC_SystemReset(void) {
+ SCB->AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1 << NVIC_SYSRESETREQ)); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+ while (1); /* wait until reset */
+ }
+
+
+ /* ################################## Debug Output function ############################################ */
+
+
+ /**
+ * @brief Outputs a character via the ITM channel 0
+ *
+ * @param uint32_t character to output
+ * @return uint32_t input character
+ *
+ * The function outputs a character via the ITM channel 0.
+ * The function returns when no debugger is connected that has booked the output.
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted.
+ */
+ static __INLINE uint32_t ITM_SendChar(uint32_t ch) {
+ if (ch == '\n') ITM_SendChar('\r');
+
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA) &&
+ (ITM->TCR & ITM_TCR_ITMENA) &&
+ (ITM->TER & (1UL << 0))) {
+ while (ITM->PORT[0].u32 == 0);
+ ITM->PORT[0].u8 = (uint8_t) ch;
+ }
+ return (ch);
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CM3_CORE_H__ */
+
+/*lint -restore */
diff --git a/gyro_board/src/usb/cr_startup_lpc17.c b/gyro_board/src/usb/cr_startup_lpc17.c
new file mode 100644
index 0000000..00f6187
--- /dev/null
+++ b/gyro_board/src/usb/cr_startup_lpc17.c
@@ -0,0 +1,304 @@
+//*****************************************************************************
+// +--+
+// | ++----+
+// +-++ |
+// | |
+// +-+--+ |
+// | +--+--+
+// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
+//
+// Microcontroller Startup code for use with Red Suite
+//
+// Software License Agreement
+//
+// The software is owned by Code Red Technologies and/or its suppliers, and is
+// protected under applicable copyright laws. All rights are reserved. Any
+// use in violation of the foregoing restrictions may subject the user to criminal
+// sanctions under applicable laws, as well as to civil liability for the breach
+// of the terms and conditions of this license.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS". 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.
+// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
+// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
+// CODE RED TECHNOLOGIES LTD.
+//
+//*****************************************************************************
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+//*****************************************************************************
+//
+// Forward declaration of the default handlers.
+//
+//*****************************************************************************
+void Reset_Handler(void);
+void ResetISR(void) ALIAS(Reset_Handler);
+static void NMI_Handler(void);
+static void HardFault_Handler(void);
+static void MemManage_Handler(void);
+static void BusFault_Handler(void);
+static void UsageFault_Handler(void);
+static void DebugMon_Handler(void);
+
+//*****************************************************************************
+//
+// Forward declaration of the specific IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//
+//*****************************************************************************
+void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);
+void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);
+void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PWM1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PLL0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void EINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void EINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void EINT2_IRQHandler(void) ALIAS(IntDefaultHandler);
+void EINT3_IRQHandler(void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USB_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CAN_IRQHandler(void) ALIAS(IntDefaultHandler);
+void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);
+void I2S_IRQHandler(void) ALIAS(IntDefaultHandler);
+void EMAC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void ENET_IRQHandler(void) ALIAS(IntDefaultHandler);
+void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);
+void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);
+void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PLL1_IRQHandler(void) ALIAS(IntDefaultHandler);
+
+extern void xPortSysTickHandler(void);
+extern void xPortPendSVHandler(void);
+extern void vPortSVCHandler(void);
+
+
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern WEAK void __libc_init_array(void);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for redlib based applications
+// main() is the entry point for newlib based applications
+//
+//*****************************************************************************
+extern WEAK void __main(void);
+extern WEAK void main(void);
+//*****************************************************************************
+//
+// External declaration for the pointer to the stack top from the Linker Script
+//
+//*****************************************************************************
+extern int _vStackTop;
+
+//*****************************************************************************
+//
+// The vector table.
+// This relies on the linker script to place at correct location in memory.
+//
+//*****************************************************************************
+typedef void (* const isr_handlers_t)(void);
+__attribute__((section(".isr_vector")))
+isr_handlers_t g_pfnVectors[] = {
+ // Core Level - CM3
+ (isr_handlers_t)&_vStackTop, // The initial stack pointer
+ Reset_Handler, // The reset handler
+ NMI_Handler, // The NMI handler
+ HardFault_Handler, // The hard fault handler
+ MemManage_Handler, // The MPU fault handler
+ BusFault_Handler, // The bus fault handler
+ UsageFault_Handler, // The usage fault handler
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ vPortSVCHandler, // SVCall handler
+ DebugMon_Handler, // Debug monitor handler
+ 0, // Reserved
+ xPortPendSVHandler, // The PendSV handler
+ xPortSysTickHandler, // The SysTick handler
+
+ // Chip Level - LPC17
+ WDT_IRQHandler, // 16, 0x40 - WDT
+ TIMER0_IRQHandler, // 17, 0x44 - TIMER0
+ TIMER1_IRQHandler, // 18, 0x48 - TIMER1
+ TIMER2_IRQHandler, // 19, 0x4c - TIMER2
+ TIMER3_IRQHandler, // 20, 0x50 - TIMER3
+ UART0_IRQHandler, // 21, 0x54 - UART0
+ UART1_IRQHandler, // 22, 0x58 - UART1
+ UART2_IRQHandler, // 23, 0x5c - UART2
+ UART3_IRQHandler, // 24, 0x60 - UART3
+ PWM1_IRQHandler, // 25, 0x64 - PWM1
+ I2C0_IRQHandler, // 26, 0x68 - I2C0
+ I2C1_IRQHandler, // 27, 0x6c - I2C1
+ I2C2_IRQHandler, // 28, 0x70 - I2C2
+ SPI_IRQHandler, // 29, 0x74 - SPI
+ SSP0_IRQHandler, // 30, 0x78 - SSP0
+ SSP1_IRQHandler, // 31, 0x7c - SSP1
+ PLL0_IRQHandler, // 32, 0x80 - PLL0 (Main PLL)
+ RTC_IRQHandler, // 33, 0x84 - RTC
+ EINT0_IRQHandler, // 34, 0x88 - EINT0
+ EINT1_IRQHandler, // 35, 0x8c - EINT1
+ EINT2_IRQHandler, // 36, 0x90 - EINT2
+ EINT3_IRQHandler, // 37, 0x94 - EINT3
+ ADC_IRQHandler, // 38, 0x98 - ADC
+ BOD_IRQHandler, // 39, 0x9c - BOD
+ USB_IRQHandler, // 40, 0xA0 - USB
+ CAN_IRQHandler, // 41, 0xa4 - CAN
+ DMA_IRQHandler, // 42, 0xa8 - GP DMA
+ I2S_IRQHandler, // 43, 0xac - I2S
+ EMAC_IRQHandler, // 44, 0xb0 - Ethernet
+ RIT_IRQHandler, // 45, 0xb4 - RITINT
+ MCPWM_IRQHandler, // 46, 0xb8 - Motor Control PWM
+ QEI_IRQHandler, // 47, 0xbc - Quadrature Encoder
+ PLL1_IRQHandler, // 48, 0xc0 - PLL1 (USB PLL)
+};
+
+//*****************************************************************************
+//
+// The following are constructs created by the linker, indicating where the
+// the "data" and "bss" segments reside in memory. The initializers for the
+// for the "data" segment resides immediately following the "text" segment.
+//
+//*****************************************************************************
+extern unsigned long _etext;
+extern unsigned long _data;
+extern unsigned long _edata;
+extern unsigned long _bss;
+extern unsigned long _ebss;
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//
+//*****************************************************************************
+void Reset_Handler(void)
+{
+ unsigned long *pulSrc, *pulDest;
+
+ //
+ // Copy the data segment initializers from flash to SRAM.
+ //
+ pulSrc = &_etext;
+ for (pulDest = &_data; pulDest < &_edata;) {
+ *pulDest++ = *pulSrc++;
+ }
+
+ //
+ // Zero fill the bss segment. This is done with inline assembly since this
+ // will clear the value of pulDest if it is not kept in a register.
+ //
+ __asm(" ldr r0, =_bss\n"
+ " ldr r1, =_ebss\n"
+ " mov r2, #0\n"
+ " .thumb_func\n"
+ "zero_loop:\n"
+ " cmp r0, r1\n"
+ " it lt\n"
+ " strlt r2, [r0], #4\n"
+ " blt zero_loop");
+
+ //
+ // Call C++ library initilisation, if present
+ //
+ //if (__libc_init_array)
+ //__libc_init_array() ;
+
+ //
+ // Call the application's entry point.
+ // __main() is the entry point for redlib based applications (which calls main())
+ // main() is the entry point for newlib based applications
+ //
+ //if (__main)
+ //__main() ;
+ //else
+ main() ;
+
+ //
+ // main() shouldn't return, but if it does, we'll just enter an infinite loop
+ //
+ while (1) {
+ ;
+ }
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives a NMI. This
+// simply enters an infinite loop, preserving the system state for examination
+// by a debugger.
+//
+//*****************************************************************************
+static void NMI_Handler(void)
+{
+ while (1) {
+ }
+}
+
+static void HardFault_Handler(void)
+{
+ while (1) {
+ }
+}
+
+static void MemManage_Handler(void)
+{
+ while (1) {
+ }
+}
+
+static void BusFault_Handler(void)
+{
+ while (1) {
+ }
+}
+
+static void UsageFault_Handler(void)
+{
+ while (1) {
+ }
+}
+
+static void DebugMon_Handler(void)
+{
+ while (1) {
+ }
+}
+
+//*****************************************************************************
+//
+// Processor ends up here if an unexpected interrupt occurs or a handler
+// is not present in the application code.
+//
+//*****************************************************************************
+static void IntDefaultHandler(void)
+{
+ //
+ // Go into an infinite loop.
+ //
+ while (1) {
+ }
+}
diff --git a/gyro_board/src/usb/lpc1758_Debug.ld b/gyro_board/src/usb/lpc1758_Debug.ld
new file mode 100644
index 0000000..ce6d093
--- /dev/null
+++ b/gyro_board/src/usb/lpc1758_Debug.ld
@@ -0,0 +1,79 @@
+/*
+ * GENERATED FILE - DO NOT EDIT
+ * (C) Code Red Technologies Ltd, 2008-9
+ * Generated C linker script file for LPC1768
+ * (created from nxp_lpc13_c.ld (v2.0.11 (200907061347)) on Thu Jul 09 12:44:31 BST 2009)
+*/
+
+GROUP(libgcc.a libc.a)
+
+MEMORY
+{
+ FLASH(rx) : ORIGIN = 0x00000000, LENGTH = 0x80000
+ SRAM(rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000
+ AHBRAM0 : ORIGIN = 0x2007c000, LENGTH = 0x4000
+ AHBRAM1 : ORIGIN = 0x20080000, LENGTH = 0x4000
+}
+
+_vRamTop = 0x10000000 + 0x8000;
+
+ENTRY(ResetISR)
+
+SECTIONS {
+ .text : {
+ KEEP(*(.isr_vector))
+ *(.text*)
+ *(.rodata*)
+
+ } > FLASH
+
+
+ /* for exception handling/unwind - some Newlib functions (in common with C++ and STDC++) use this. */
+
+ .ARM.extab : {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > FLASH
+
+ __exidx_start = .;
+ .ARM.exidx : {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > FLASH
+ __exidx_end = .;
+
+ _etext = .;
+
+ .data :
+ AT(__exidx_end) {
+ _data = .;
+ *(vtable)
+ *(.data*)
+ _edata = .;
+ } > SRAM
+
+ /* zero initialized data */
+ .bss : {
+ _bss = .;
+ *(.bss*)
+ *(COMMON)
+ _ebss = .;
+ } > SRAM
+
+ /* Where we put the heap with cr_clib */
+ .cr_heap : {
+ end = .;
+ _pvHeapStart = .;
+ } > SRAM
+
+ /*
+ Note: (ref: M0000066)
+ Moving the stack down by 16 is to work around a GDB bug.
+ This space can be reclaimed for Production Builds.
+ */
+ _vStackTop = _vRamTop - 16;
+
+ .ETHRAM : {
+ } > AHBRAM0
+
+ .USBRAM : {
+ } > AHBRAM1
+}
diff --git a/gyro_board/src/usb/main.c b/gyro_board/src/usb/main.c
new file mode 100644
index 0000000..11191a4
--- /dev/null
+++ b/gyro_board/src/usb/main.c
@@ -0,0 +1,398 @@
+/*
+ FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
+
+ 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.
+
+*/
+
+/* Standard includes. */
+#include "stdio.h"
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "task.h"
+
+/* Demo app includes. */
+#include "flash.h"
+#include "partest.h"
+#include "analog.h"
+#include "spi.h"
+#include "LPCUSB/usbapi.h"
+
+/*-----------------------------------------------------------*/
+
+/* The time between cycles of the 'check' functionality (defined within the
+tick hook. */
+#define mainCHECK_DELAY ((portTickType) 5000 / portTICK_RATE_MS)
+
+/* Task priorities. */
+#define mainQUEUE_POLL_PRIORITY (tskIDLE_PRIORITY + 2)
+#define mainSEM_TEST_PRIORITY (tskIDLE_PRIORITY + 1)
+#define mainBLOCK_Q_PRIORITY (tskIDLE_PRIORITY + 2)
+#define mainUIP_TASK_PRIORITY (tskIDLE_PRIORITY + 3)
+#define mainINTEGER_TASK_PRIORITY (tskIDLE_PRIORITY)
+#define mainGEN_QUEUE_TASK_PRIORITY (tskIDLE_PRIORITY)
+#define mainFLASH_TASK_PRIORITY (tskIDLE_PRIORITY + 2)
+
+/* The WEB server has a larger stack as it utilises stack hungry string
+handling library calls. */
+#define mainBASIC_WEB_STACK_SIZE (configMINIMAL_STACK_SIZE * 4)
+
+int32_t goal = 0;
+int64_t gyro_angle = 0;
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Configure the hardware for the demo.
+ */
+static void prvSetupHardware(void);
+
+/*
+ * The task that handles the USB stack.
+ */
+extern void vUSBTask(void *pvParameters);
+
+extern int VCOM_getchar(void);
+
+int VCOM_putchar(int c);
+
+inline int32_t encoder()
+{
+ return (int32_t)QEI->QEIPOS;
+}
+
+static portTASK_FUNCTION(vPrintPeriodic, pvParameters)
+{
+ portTickType xLastFlashTime;
+
+ /* We need to initialise xLastFlashTime prior to the first call to
+ vTaskDelayUntil(). */
+ xLastFlashTime = xTaskGetTickCount();
+
+ analog_init();
+
+ encoder_init();
+
+ // Wait 100 ms for it to boot.
+ vTaskDelayUntil(&xLastFlashTime, 100 / portTICK_RATE_MS);
+ spi_init();
+
+ // Enable USB. The PC has probably disconnected it now.
+ USBHwAllowConnect();
+
+ // TODO(aschuh): Write this into a gyro calibration function, and check all the outputs.
+ vTaskDelayUntil(&xLastFlashTime, 50 / portTICK_RATE_MS);
+ enable_gyro_csel();
+ printf("SPI Gyro Second Response 0x%x %x\n", transfer_spi_bytes(0x2000), transfer_spi_bytes(0x0000));
+ disable_gyro_csel();
+
+ vTaskDelayUntil(&xLastFlashTime, 50 / portTICK_RATE_MS);
+ enable_gyro_csel();
+ printf("SPI Gyro Third Response 0x%x %x\n", transfer_spi_bytes(0x2000), transfer_spi_bytes(0x0000));
+ disable_gyro_csel();
+
+ vTaskDelayUntil(&xLastFlashTime, 10 / portTICK_RATE_MS);
+ enable_gyro_csel();
+ printf("SPI Gyro Fourth Response 0x%x %x\n", transfer_spi_bytes(0x2000), transfer_spi_bytes(0x0000));
+ disable_gyro_csel();
+ const int hz = 200;
+ const int flash_hz = 10;
+ const int startup_cycles = hz * 2;
+ const int zeroing_cycles = hz * 6;
+ int32_t zero_bias = 0;
+ int32_t startup_cycles_left = startup_cycles;
+ int32_t zeroing_cycles_left = zeroing_cycles;
+ int32_t full_units_offset = 0;
+ int32_t remainder_offset = 0;
+ int32_t remainder_sum = 0;
+ int32_t led_flash = 0;
+ vParTestSetLED(0, 0);
+
+ for (;;) {
+ led_flash ++;
+ if (led_flash < hz / flash_hz / 2) {
+ vParTestSetLED(1, 0);
+ } else {
+ vParTestSetLED(1, 1);
+ }
+ if (led_flash >= hz / flash_hz) {
+ led_flash = 0;
+ }
+ /* Delay for half the flash period then turn the LED on. */
+ vTaskDelayUntil(&xLastFlashTime, 1000 / hz / portTICK_RATE_MS);
+ enable_gyro_csel();
+ uint16_t high_value = transfer_spi_bytes(0x2000);
+ uint16_t low_value = transfer_spi_bytes(0x0000);
+ disable_gyro_csel();
+ int16_t gyro_value = -((int16_t)((((uint32_t)high_value << 16) | (uint32_t)low_value) >> 10));
+
+ if (startup_cycles_left) {
+ vParTestSetLED(2, 0);
+ --startup_cycles_left;
+ } else if (zeroing_cycles_left) {
+ vParTestSetLED(2, 1);
+ //printf("Zeroing ");
+ --zeroing_cycles_left;
+ zero_bias -= gyro_value;
+ if (zeroing_cycles_left == 0) {
+ // Do all the nice math
+ full_units_offset = zero_bias / zeroing_cycles;
+ remainder_offset = zero_bias % zeroing_cycles;
+ if (remainder_offset < 0) {
+ remainder_offset += zeroing_cycles;
+ --full_units_offset;
+ }
+ }
+ } else {
+ vParTestSetLED(2, 0);
+ int64_t new_angle = gyro_angle + gyro_value + full_units_offset;
+ if (remainder_sum >= zeroing_cycles) {
+ remainder_sum -= zeroing_cycles;
+ new_angle += 1;
+ }
+ NVIC_DisableIRQ(USB_IRQn);
+ gyro_angle = new_angle;
+ NVIC_EnableIRQ(USB_IRQn);
+ remainder_sum += remainder_offset;
+ }
+ //printf("Angle %d Rate %d\n", (int)(gyro_angle / 16), (int)(gyro_value + full_units_offset));
+
+ //printf("time: %d analog %d encoder %d goal %d\n", (int)i, (int)analog(5), (int)encoder(), (int)goal);
+
+ //printf("time: %d encoder %d goal %d\n", (int)i, (int)encoder(), (int)goal);
+ /*
+ for(i = 0; i < 4; i++){
+ printf("analog(%d) => %d\n",i,analog(i));
+ }
+ for(i = 1; i < 13; i++){
+ printf("digital(%d) => %d\n",i,digital(i));
+ }
+ for(i = 0; i < 4; i++){
+ printf("dip(%d) => %d\n",i,dip(i));
+ }
+ for(i = 0; i < 4; i++){
+ printf("encoder(%d) => %d\n",i,encoder_bits(i));
+ }
+ for(i = 0; i < 4; i++){
+ printf("encoder_val(%d) => %d\n",i,(int)encoder_val(i));
+ }*/
+ }
+}
+
+#include "CAN.h"
+
+
+
+void motor(int32_t speed)
+{
+ if (speed > 2047) speed = 2047;
+ if (speed < -2047) speed = -2047;
+ return;
+ if (speed > 0) {
+ MCPWM->MCMAT1 = 2047 - speed;
+ MCPWM->MCMAT0 = 2048;
+ } else {
+ MCPWM->MCMAT1 = 2048;
+ MCPWM->MCMAT0 = speed + 2047;
+ }
+}
+
+
+
+/*-----------------------------------------------------------*/
+
+int main(void)
+{
+ // Configure the hardware
+ prvSetupHardware();
+
+ /* Start the standard demo tasks. These are just here to exercise the
+ kernel port and provide examples of how the FreeRTOS API can be used. */
+ //vStartLEDFlashTasks(mainFLASH_TASK_PRIORITY);
+
+ /* Create the USB task. */
+ xTaskCreate(vUSBTask, (signed char *) "USB", configMINIMAL_STACK_SIZE + 1020, (void *) NULL, tskIDLE_PRIORITY + 3, NULL);
+
+ xTaskCreate(vPrintPeriodic, (signed char *) "PRINTx", configMINIMAL_STACK_SIZE + 100, NULL, tskIDLE_PRIORITY + 2, NULL);
+
+ initCAN();
+
+ // Start the scheduler.
+ vTaskStartScheduler();
+
+ /* Will only get here if there was insufficient memory to create the idle
+ task. The idle task is created within vTaskStartScheduler(). */
+ for (;;);
+}
+/*-----------------------------------------------------------*/
+
+
+void vApplicationTickHook(void)
+{
+ static unsigned long ulTicksSinceLastDisplay = 0;
+
+ /* Called from every tick interrupt as described in the comments at the top
+ of this file.
+
+ Have enough ticks passed to make it time to perform our health status
+ check again? */
+
+ ulTicksSinceLastDisplay++;
+
+ if (ulTicksSinceLastDisplay >= mainCHECK_DELAY) {
+ /* Reset the counter so these checks run again in mainCHECK_DELAY
+ ticks time. */
+ ulTicksSinceLastDisplay = 0;
+ }
+}
+/*-----------------------------------------------------------*/
+
+void prvSetupHardware(void)
+{
+ // Setup the peripherals.
+ // The CPU will be running at 100 MHz with a 12 MHz clock input.
+
+ // Setup GPIO power.
+ SC->PCONP = PCONP_PCGPIO;
+ // Disable TPIU.
+ PINCON->PINSEL10 = 0;
+
+ // Setup PLL0 so that the CPU runs at 100 MHz.
+ if (SC->PLL0STAT & (1 << 25)) {
+ /* Enable PLL, disconnected. */
+ SC->PLL0CON = 1;
+ SC->PLL0FEED = PLLFEED_FEED1;
+ SC->PLL0FEED = PLLFEED_FEED2;
+ }
+
+ // Disable PLL, disconnected.
+ SC->PLL0CON = 0;
+ SC->PLL0FEED = PLLFEED_FEED1;
+ SC->PLL0FEED = PLLFEED_FEED2;
+
+ // Enable main OSC and wait until it's ready.
+ SC->SCS |= 0x20;
+ while (!(SC->SCS & 0x40));
+
+ // select main OSC, 12MHz, as the PLL clock source.
+ SC->CLKSRCSEL = 0x1;
+
+ SC->PLL0CFG = 0x20031;
+ SC->PLL0FEED = PLLFEED_FEED1;
+ SC->PLL0FEED = PLLFEED_FEED2;
+
+ // Enable PLL, disconnected.
+ SC->PLL0CON = 1;
+ SC->PLL0FEED = PLLFEED_FEED1;
+ SC->PLL0FEED = PLLFEED_FEED2;
+
+ // Set clock divider.
+ SC->CCLKCFG = 0x03;
+
+ // Configure flash accelerator.
+ SC->FLASHCFG = 0x403a;
+
+ // Check lock bit status.
+ while (((SC->PLL0STAT & (1 << 26)) == 0));
+
+ // Enable and connect.
+ SC->PLL0CON = 3;
+ SC->PLL0FEED = PLLFEED_FEED1;
+ SC->PLL0FEED = PLLFEED_FEED2;
+
+ while (((SC->PLL0STAT & (1 << 25)) == 0));
+
+ // Configure the clock for the USB.
+ if (SC->PLL1STAT & (1 << 9)) {
+ // Enable PLL, disconnected.
+ SC->PLL1CON = 1;
+ SC->PLL1FEED = PLLFEED_FEED1;
+ SC->PLL1FEED = PLLFEED_FEED2;
+ }
+
+ // Disable PLL, disconnected.
+ SC->PLL1CON = 0;
+ SC->PLL1FEED = PLLFEED_FEED1;
+ SC->PLL1FEED = PLLFEED_FEED2;
+
+ SC->PLL1CFG = 0x23;
+ SC->PLL1FEED = PLLFEED_FEED1;
+ SC->PLL1FEED = PLLFEED_FEED2;
+
+ /* Enable PLL, disconnected. */
+ SC->PLL1CON = 1;
+ SC->PLL1FEED = PLLFEED_FEED1;
+ SC->PLL1FEED = PLLFEED_FEED2;
+ while (((SC->PLL1STAT & (1 << 10)) == 0));
+
+ /* Enable and connect. */
+ SC->PLL1CON = 3;
+ SC->PLL1FEED = PLLFEED_FEED1;
+ SC->PLL1FEED = PLLFEED_FEED2;
+ while (((SC->PLL1STAT & (1 << 9)) == 0));
+
+ // Setup the peripheral bus to be the same as the CCLK, 100 MHz.
+ // Set CAN to run at CCLK/6, which should have it running about 1 Mbit (1.042)
+ SC->PCLKSEL0 = 0xff555555;
+
+ /* Configure the LEDs. */
+ vParTestInitialise();
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed char *pcTaskName)
+{
+ /* This function will get called if a task overflows its stack. */
+
+ (void) pxTask;
+ (void) pcTaskName;
+
+ for (;;);
+}
+/*-----------------------------------------------------------*/
+
+void vConfigureTimerForRunTimeStats(void)
+{
+ const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
+
+ /* This function configures a timer that is used as the time base when
+ collecting run time statistical information - basically the percentage
+ of CPU time that each task is utilising. It is called automatically when
+ the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
+ to 1). */
+
+ /* Power up and feed the timer. */
+ SC->PCONP |= 0x02UL;
+ SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3 << 2))) | (0x01 << 2);
+
+ /* Reset Timer 0 */
+ TIM0->TCR = TCR_COUNT_RESET;
+
+ /* Just count up. */
+ TIM0->CTCR = CTCR_CTM_TIMER;
+
+ /* Prescale to a frequency that is good enough to get a decent resolution,
+ but not too fast so as to overflow all the time. */
+ TIM0->PR = (configCPU_CLOCK_HZ / 10000UL) - 1UL;
+
+ /* Start the counter. */
+ TIM0->TCR = TCR_COUNT_ENABLE;
+}
+
diff --git a/gyro_board/src/usb/printf-stdarg.c b/gyro_board/src/usb/printf-stdarg.c
new file mode 100644
index 0000000..206c3db
--- /dev/null
+++ b/gyro_board/src/usb/printf-stdarg.c
@@ -0,0 +1,314 @@
+/*
+ Copyright 2001, 2002 Georges Menie (www.menie.org)
+ stdarg version contributed by Christian Ettinger
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ putchar is the only external dependency for this file,
+ if you have a working putchar, leave it commented out.
+ If not, uncomment the define below and
+ replace outbyte(c) by your own function call.
+
+*/
+
+#include <stdarg.h>
+
+int VCOM_putchar(int c);
+
+int putchar (int c)
+{
+ return VCOM_putchar(c);
+}
+
+static void printchar(char **str, int c)
+{
+ //extern int putchar(int c);
+
+ if (str) {
+ **str = (char)c;
+ ++(*str);
+ } else {
+ VCOM_putchar(c);
+ }
+}
+
+int puts (char * str)
+{
+ int pc = 1;
+ while (*str != 0) {
+ VCOM_putchar(*str);
+ str ++;
+ pc ++;
+ }
+ VCOM_putchar('\n');
+ return pc;
+}
+
+#define PAD_RIGHT 1
+#define PAD_ZERO 2
+
+static int prints(char **out, const char *string, int width, int pad)
+{
+ register int pc = 0, padchar = ' ';
+
+ if (width > 0) {
+ register int len = 0;
+ register const char *ptr;
+ for (ptr = string; *ptr; ++ptr) ++len;
+ if (len >= width) width = 0;
+ else width -= len;
+ if (pad & PAD_ZERO) padchar = '0';
+ }
+ if (!(pad & PAD_RIGHT)) {
+ for (; width > 0; --width) {
+ printchar(out, padchar);
+ ++pc;
+ }
+ }
+ for (; *string ; ++string) {
+ printchar(out, *string);
+ ++pc;
+ }
+ for (; width > 0; --width) {
+ printchar(out, padchar);
+ ++pc;
+ }
+
+ return pc;
+}
+
+/* the following should be enough for 32 bit int */
+#define PRINT_BUF_LEN 12
+
+static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
+{
+ char print_buf[PRINT_BUF_LEN];
+ register char *s;
+ register int t, neg = 0, pc = 0;
+ register unsigned int u = (unsigned int)i;
+
+ if (i == 0) {
+ print_buf[0] = '0';
+ print_buf[1] = '\0';
+ return prints(out, print_buf, width, pad);
+ }
+
+ if (sg && b == 10 && i < 0) {
+ neg = 1;
+ u = (unsigned int) - i;
+ }
+
+ s = print_buf + PRINT_BUF_LEN - 1;
+ *s = '\0';
+
+ while (u) {
+ t = (unsigned int)u % b;
+ if (t >= 10)
+ t += letbase - '0' - 10;
+ *--s = (char)(t + '0');
+ u /= b;
+ }
+
+ if (neg) {
+ if (width && (pad & PAD_ZERO)) {
+ printchar(out, '-');
+ ++pc;
+ --width;
+ } else {
+ *--s = '-';
+ }
+ }
+
+ return pc + prints(out, s, width, pad);
+}
+
+static int print(char **out, const char *format, va_list args)
+{
+ register int width, pad;
+ register int pc = 0;
+ char scr[2];
+
+ for (; *format != 0; ++format) {
+ if (*format == '%') {
+ ++format;
+ width = pad = 0;
+ if (*format == '\0') break;
+ if (*format == '%') goto pout;
+ if (*format == '-') {
+ ++format;
+ pad = PAD_RIGHT;
+ }
+ while (*format == '0') {
+ ++format;
+ pad |= PAD_ZERO;
+ }
+ for (; *format >= '0' && *format <= '9'; ++format) {
+ width *= 10;
+ width += *format - '0';
+ }
+ if (*format == 's') {
+ register char *s = (char *)va_arg(args, int);
+ pc += prints(out, s ? s : "(null)", width, pad);
+ continue;
+ }
+ if (*format == 'd') {
+ pc += printi(out, va_arg(args, int), 10, 1, width, pad, 'a');
+ continue;
+ }
+ if (*format == 'x') {
+ pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'a');
+ continue;
+ }
+ if (*format == 'X') {
+ pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'A');
+ continue;
+ }
+ if (*format == 'u') {
+ pc += printi(out, va_arg(args, int), 10, 0, width, pad, 'a');
+ continue;
+ }
+ if (*format == 'c') {
+ /* char are converted to int then pushed on the stack */
+ scr[0] = (char)va_arg(args, int);
+ scr[1] = '\0';
+ pc += prints(out, scr, width, pad);
+ continue;
+ }
+ } else {
+pout:
+ printchar(out, *format);
+ ++pc;
+ }
+ }
+ if (out) **out = '\0';
+ va_end(args);
+ return pc;
+}
+
+int printf(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ return print(0, format, args);
+}
+
+int sprintf(char *out, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ return print(&out, format, args);
+}
+
+
+int snprintf(char *buf, unsigned int count, const char *format, ...)
+{
+ va_list args;
+
+ (void) count;
+
+ va_start(args, format);
+ return print(&buf, format, args);
+}
+
+
+#ifdef TEST_PRINTF
+int main(void)
+{
+ char *ptr = "Hello world!";
+ char *np = 0;
+ int i = 5;
+ unsigned int bs = sizeof(int) * 8;
+ int mi;
+ char buf[80];
+
+ mi = (1 << (bs - 1)) + 1;
+ printf("%s\n", ptr);
+ printf("printf test\n");
+ printf("%s is null pointer\n", np);
+ printf("%d = 5\n", i);
+ printf("%d = - max int\n", mi);
+ printf("char %c = 'a'\n", 'a');
+ printf("hex %x = ff\n", 0xff);
+ printf("hex %02x = 00\n", 0);
+ printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
+ printf("%d %s(s)%", 0, "message");
+ printf("\n");
+ printf("%d %s(s) with %%\n", 0, "message");
+ sprintf(buf, "justif: \"%-10s\"\n", "left");
+ printf("%s", buf);
+ sprintf(buf, "justif: \"%10s\"\n", "right");
+ printf("%s", buf);
+ sprintf(buf, " 3: %04d zero padded\n", 3);
+ printf("%s", buf);
+ sprintf(buf, " 3: %-4d left justif.\n", 3);
+ printf("%s", buf);
+ sprintf(buf, " 3: %4d right justif.\n", 3);
+ printf("%s", buf);
+ sprintf(buf, "-3: %04d zero padded\n", -3);
+ printf("%s", buf);
+ sprintf(buf, "-3: %-4d left justif.\n", -3);
+ printf("%s", buf);
+ sprintf(buf, "-3: %4d right justif.\n", -3);
+ printf("%s", buf);
+
+ return 0;
+}
+
+/*
+ * if you compile this file with
+ * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
+ * you will get a normal warning:
+ * printf.c:214: warning: spurious trailing `%' in format
+ * this line is testing an invalid % at the end of the format string.
+ *
+ * this should display (on 32bit int machine) :
+ *
+ * Hello world!
+ * printf test
+ * (null) is null pointer
+ * 5 = 5
+ * -2147483647 = - max int
+ * char a = 'a'
+ * hex ff = ff
+ * hex 00 = 00
+ * signed -3 = unsigned 4294967293 = hex fffffffd
+ * 0 message(s)
+ * 0 message(s) with %
+ * justif: "left "
+ * justif: " right"
+ * 3: 0003 zero padded
+ * 3: 3 left justif.
+ * 3: 3 right justif.
+ * -3: -003 zero padded
+ * -3: -3 left justif.
+ * -3: -3 right justif.
+ */
+
+#endif
+
+
+/* To keep linker happy. */
+int write(int i, char* c, int n)
+{
+ (void)i;
+ (void)n;
+ (void)c;
+ return 0;
+}
+
diff --git a/gyro_board/src/usb/quad encoder config.txt b/gyro_board/src/usb/quad encoder config.txt
new file mode 100644
index 0000000..4c0fe4e
--- /dev/null
+++ b/gyro_board/src/usb/quad encoder config.txt
@@ -0,0 +1,37 @@
+// Quad Encoder stuff
+
+
+// enable the quadrature encode peripheral and peripherial clock
+
+ SC->PCONP |=0x00040000; // bit 18 of PCONP set to 1
+ SC->PCLKSEL1 |=0x00000001; /* bits 1,0 00 CCLK/4
+ 01 CCLK
+ 10 CCLK/2
+ 11 CCLK/8 */
+
+
+// Enable pins for QEI MCI0, MCI1 (PhA PhB, signals respectively)
+
+
+ PINCON->PINSEL3 = ((PINSEL3 &=0xFFFF3DFF) |= 0x00004100); /* 01 in bits 9:8 and 15:14*/
+ //PINCON->PINSEL3 = ((PINSEL3 &=0xFFFCFFFF) |= 0x00010000); /* Turns on MCI2 index input 17:16 = 01*/
+
+
+
+// Specify Quadriture phase mode
+
+ // QEI->QEICON &= 0xFFFFFFFE; /* Clears position counter */
+ QEI->QEICONF &= 0XFFFFFFFD; /* Sets bit 1 to 0, Signal mode to Quad Phase */
+ // QEI->QEICON |= 0X00000002; /* Bit 2 to 1 counts both PhA and PhB for higher resolution */
+
+
+
+ // QEI->FILTER = ****Whatever Sampling size we want*** /* Sets the number of consecutive pulses for a change in direction, etc to accepted */
+
+
+// Set Various Attributes
+
+ // QEI->QEIMAXPOS = *****insert max position*****;
+
+
+/* Note: QEI->QEIPOS is a read only section that stores the current position */
\ No newline at end of file
diff --git a/gyro_board/src/usb/spi.c b/gyro_board/src/usb/spi.c
new file mode 100644
index 0000000..de41866
--- /dev/null
+++ b/gyro_board/src/usb/spi.c
@@ -0,0 +1,60 @@
+#include "stdio.h"
+#include "FreeRTOS.h"
+#include "spi.h"
+
+void spi_init (void) {
+ SC->PCONP |= PCONP_PCSPI;
+ SC->PCLKSEL0 |= 0x00010000;
+
+ // Hook up the interrupt
+ //NVIC_EnableIRQ(SPI_IRQn);
+
+ // SCK
+ PINCON->PINSEL0 &= 0x3fffffff;
+ PINCON->PINSEL0 |= 0xc0000000;
+
+ // SSEL, MISO, MOSI
+ // SSEL is GPIO, and needs to be done manually.
+ disable_gyro_csel();
+ GPIO0->FIODIR |= 0x00010000;
+ PINCON->PINSEL1 &= 0xffffffc0;
+ PINCON->PINSEL1 |= 0x0000003c;
+
+ // Master mode, 16 bits/frame, enable interrupts
+ SPI->SPCR = 0x000000a4;
+ // 13 clocks per cycle. This works out to a 7.7 mhz buss.
+ SPI->SPCCR = 0x0000000d;
+
+ // TODO(aschuh): Implement the gyro bring-up blocking first.
+ // Then use interrupts.
+ enable_gyro_csel();
+ printf("SPI Gyro Initial Response 0x%x %x\n", transfer_spi_bytes(0x2000), transfer_spi_bytes(0x0003));
+ disable_gyro_csel();
+}
+
+// TODO: DMA? SSP0? SSP0 should have a buffer, which would be very nice.
+uint16_t transfer_spi_bytes(uint16_t data) {
+ SPI->SPDR = (uint32_t)data;
+ while (!(SPI->SPSR & 0x80));
+ return SPI->SPDR;
+}
+
+void disable_gyro_csel (void) {
+ // Set the CSEL pin high to deselect it.
+ GPIO0->FIOSET = 0x00010000;
+}
+
+void enable_gyro_csel (void) {
+ // Clear the CSEL pin high to select it.
+ GPIO0->FIOCLR = 0x00010000;
+}
+
+void SPI_IRQHandler(void) {
+ int status = SPI->SPSR;
+ if (status & 0x80) {
+ // Transfer completed.
+ }
+
+ // Clear the interrupt?
+ SPI->SPINT = 0x00000001;
+}
diff --git a/gyro_board/src/usb/spi.h b/gyro_board/src/usb/spi.h
new file mode 100644
index 0000000..6dbc511
--- /dev/null
+++ b/gyro_board/src/usb/spi.h
@@ -0,0 +1,9 @@
+#ifndef __SPI_H__
+#define __SPI_H__
+
+void spi_init (void);
+uint16_t transfer_spi_bytes(uint16_t data);
+void disable_gyro_csel (void);
+void enable_gyro_csel (void);
+
+#endif // __SPI_H__
diff --git a/gyro_board/src/usb/syscalls.c b/gyro_board/src/usb/syscalls.c
new file mode 100644
index 0000000..b01ad48
--- /dev/null
+++ b/gyro_board/src/usb/syscalls.c
@@ -0,0 +1,82 @@
+/* Don't need anything here. */
+
+#include <stdlib.h>
+#include <sys/stat.h>
+
+int _read_r(struct _reent *r, int file, char * ptr, int len)
+{
+ (void) r;
+ (void) file;
+ (void) ptr;
+ (void) len;
+ return -1;
+}
+
+/***************************************************************************/
+
+int _lseek_r(struct _reent *r, int file, int ptr, int dir)
+{
+ (void) r;
+ (void) file;
+ (void) ptr;
+ (void) dir;
+
+ return 0;
+}
+
+/***************************************************************************/
+
+int _write_r(struct _reent *r, int file, char * ptr, int len)
+{
+ (void) r;
+ (void) file;
+ (void) ptr;
+ (void) len;
+
+ return 0;
+}
+
+/***************************************************************************/
+
+int _close_r(struct _reent *r, int file)
+{
+ (void) r;
+ (void) file;
+
+ return 0;
+}
+
+/***************************************************************************/
+
+caddr_t _sbrk_r(struct _reent *r, int incr)
+{
+ (void) r;
+ (void) incr;
+
+ return 0;
+}
+
+/***************************************************************************/
+
+int _fstat_r(struct _reent *r, int file, struct stat * st)
+{
+ (void) r;
+ (void) file;
+ (void) st;
+
+ return 0;
+}
+
+/***************************************************************************/
+
+int _isatty_r(struct _reent *r, int fd)
+{
+ (void) r;
+ (void) fd;
+
+ return 0;
+}
+
+
+
+
diff --git a/gyro_board/src/usb/system_LPC17xx.h b/gyro_board/src/usb/system_LPC17xx.h
new file mode 100644
index 0000000..0f7d698
--- /dev/null
+++ b/gyro_board/src/usb/system_LPC17xx.h
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * @file: system_LPC17xx.h
+ * @purpose: CMSIS Cortex-M3 Device Peripheral Access Layer Header File
+ * for the NXP LPC17xx Device Series
+ * @version: V1.0
+ * @date: 25. Nov. 2008
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2008 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". 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.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#ifndef __SYSTEM_LPC17xx_H
+#define __SYSTEM_LPC17xx_H
+
+extern uint32_t SystemFrequency; /*!< System Clock Frequency (Core Clock) */
+
+
+/**
+ * Initialize the system
+ *
+ * @param none
+ * @return none
+ *
+ * @brief Setup the microcontroller system.
+ * Initialize the System and update the SystemFrequency variable.
+ */
+extern void SystemInit(void);
+#endif
diff --git a/gyro_board/src/usb/test.py b/gyro_board/src/usb/test.py
new file mode 100644
index 0000000..3344543
--- /dev/null
+++ b/gyro_board/src/usb/test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+
+global DeviceName, AddAction, RemoveAction
+DeviceName = 'usb_device_46d_c408_noserial' # Logitech Trackball
+AddAction = 'xmodmap -e "pointer = 3 2 1 4 5 6 7 9 8"'
+RemoveAction = 'xmodmap -e "pointer = 1 2 3 4 5 6 7 8 9"'
+
+import dbus # needed to do anything
+import dbus.decorators # needed to receive messages
+import dbus.glib # needed to receive messages
+import gobject # needed to loop & monitor
+import os # needed to
+
+def add_device(*args, **keywords):
+ Path = args[0].split('/')
+ if Path[-1] == DeviceName: # Device found
+ os.system(AddAction)
+
+def remove_device(*args, **keywords):
+ Path = args[0].split('/')
+ if Path[-1] == DeviceName: # Device found
+ os.system(RemoveAction)
+
+bus = dbus.SystemBus() # connect to system bus
+hal_manager_obj = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
+hal_manager = dbus.Interface(hal_manager_obj, 'org.freedesktop.Hal.Manager')
+
+# Add listeners for all devices being added or removed
+bus.add_signal_receiver(add_device, 'DeviceAdded', 'org.freedesktop.Hal.Manager',
+ 'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
+bus.add_signal_receiver(remove_device, 'DeviceRemoved', 'org.freedesktop.Hal.Manager',
+ 'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
+
+# get list of all devices, determine if device is connected
+device_names = hal_manager.GetAllDevices()
+for name in device_names:
+ Path = name.split('/')
+ if Path[-1] == DeviceName: # Device found
+ os.system(AddAction)
+ break # no need to keep looking
+
+# monitor
+loop = gobject.MainLoop()
+loop.run()
diff --git a/gyro_board/src/usb/test2.py b/gyro_board/src/usb/test2.py
new file mode 100644
index 0000000..773446b
--- /dev/null
+++ b/gyro_board/src/usb/test2.py
@@ -0,0 +1,5 @@
+import pyudev
+context = pyudev.Context()
+
+devices = context.list_devices()
+print devices
diff --git a/gyro_board/src/usb_driver/90-aschuh.rules b/gyro_board/src/usb_driver/90-aschuh.rules
new file mode 100644
index 0000000..7e7699e
--- /dev/null
+++ b/gyro_board/src/usb_driver/90-aschuh.rules
@@ -0,0 +1 @@
+KERNEL=="aschuh[0-9]*",GROUP="dialout"
diff --git a/gyro_board/src/usb_driver/Makefile b/gyro_board/src/usb_driver/Makefile
new file mode 100644
index 0000000..d7f5b55
--- /dev/null
+++ b/gyro_board/src/usb_driver/Makefile
@@ -0,0 +1,8 @@
+obj-m := deploy-module.o
+deploy-module-y := usb-aschuh_can_driver.o
+
+all:
+ @make -C /lib/modules/`uname -r | tr -d '\n'`/build M=`pwd` modules
+
+clean:
+ @make -C /lib/modules/`uname -r | tr -d '\n'`/build M=`pwd` clean
diff --git a/gyro_board/src/usb_driver/README b/gyro_board/src/usb_driver/README
new file mode 100644
index 0000000..7325d87
--- /dev/null
+++ b/gyro_board/src/usb_driver/README
@@ -0,0 +1,8 @@
+To build, run
+
+make -C /lib/modules/`uname -r | tr -d '\n'`/build M=`pwd` modules
+
+Where 2.6.38... is what you get when you run uname -r
+
+To use from a dialout user (not root)
+cp 90-aschuh.rules /etc/udev/rules.d/
diff --git a/gyro_board/src/usb_driver/aschuh_dev_cat.rb b/gyro_board/src/usb_driver/aschuh_dev_cat.rb
new file mode 100755
index 0000000..2c314d5
--- /dev/null
+++ b/gyro_board/src/usb_driver/aschuh_dev_cat.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/ruby
+
+device_number = 0
+max_device_number = 1
+device = nil
+while !(device)
+ begin
+ device = File.open("/dev/aschuh#{device_number}","r+")
+ rescue
+ puts("Opening /dev/aschuh#{device_number} failed")
+ sleep(0.2)
+ device_number += 1
+ if(device_number == max_device_number)
+ device_number = 0
+ end
+ end
+end
+
+# Set the device in debug mode to view debug prints.
+device.ioctl(1,254)
+while true
+ print device.read(1)
+end
diff --git a/gyro_board/src/usb_driver/usb-aschuh_can_device.c b/gyro_board/src/usb_driver/usb-aschuh_can_device.c
new file mode 100644
index 0000000..400cc91
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_can_device.c
@@ -0,0 +1,190 @@
+#include "usb-aschuh_can_driver.h"
+#include "usb-aschuh_can_device.h"
+
+#define to_aschuh_dev(d) container_of(d, struct aschuh_dev, kref)
+static void aschuh_dev_delete(struct kref *kref)
+{
+ struct aschuh_dev *dev = to_aschuh_dev(kref);
+
+ usb_free_urb(dev->bulk.in_urb);
+ usb_free_urb(dev->intr.in_urb);
+ usb_put_dev(dev->udev);
+ kfree(dev->bulk.in_buffer);
+ kfree(dev->intr.in_buffer);
+ kfree(dev);
+}
+
+#include "usb-aschuh_fops_read.c"
+#include "usb-aschuh_fops_write.c"
+#include "usb-aschuh_fops_open.c"
+#include "usb-aschuh_fops_ioctl.c"
+#include "usb-aschuh_fops_release.c"
+
+static const struct file_operations aschuh_dev_fops = {
+ .owner = THIS_MODULE,
+ .read = aschuh_dev_read,
+ .write = aschuh_dev_write,
+ .open = aschuh_dev_open,
+ .release = aschuh_dev_release,
+ .flush = NULL,
+ .llseek = NULL,
+ .unlocked_ioctl = aschuh_dev_ioctl,
+};
+
+static int init_in_channel(struct aschuh_chan *chan,
+ struct usb_endpoint_descriptor *endpoint){
+ size_t buffer_size;
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ chan->in_size = buffer_size;
+ chan->in_endpointAddr = endpoint->bEndpointAddress;
+ chan->in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!chan->in_buffer) {
+ err("Could not allocate bulk_in_buffer");
+ return -1;
+ }
+ chan->in_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!chan->in_urb) {
+ err("Could not allocate bulk_in_urb");
+ return -1;
+ }
+ return 0;
+}
+int aschuh_dev_connect_endpoints(struct aschuh_dev *dev,
+ struct usb_host_interface *iface_desc){
+ struct usb_endpoint_descriptor *endpoint;
+ int i,rv;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (!dev->bulk.in_endpointAddr &&
+ usb_endpoint_is_bulk_in(endpoint)) {
+ /* we found a bulk in endpoint */
+ printk("ASCHUH: found_bulk_in : 0x%x \n",endpoint->bEndpointAddress);
+ if((rv = init_in_channel(&dev->bulk,endpoint)))
+ return rv;
+ }
+ if (!dev->bulk.out_endpointAddr &&
+ usb_endpoint_is_bulk_out(endpoint)) {
+ /* we found a bulk out endpoint */
+ printk("ASCHUH: found_bulk_out : 0x%x \n",endpoint->bEndpointAddress);
+ dev->bulk.out_endpointAddr = endpoint->bEndpointAddress;
+ }
+ if (!dev->intr.in_endpointAddr &&
+ usb_endpoint_is_int_in(endpoint)) {
+ /* we found a bulk in endpoint */
+ printk("ASCHUH: found_intr_in : 0x%x \n",endpoint->bEndpointAddress);
+ if((rv = init_in_channel(&dev->intr,endpoint)))
+ return rv;
+ dev->intr.bEndpointInterval = endpoint->bInterval;
+ }
+ if (!dev->intr.out_endpointAddr &&
+ usb_endpoint_is_int_out(endpoint)) {
+ /* we found a intr out endpoint */
+ printk("ASCHUH: found_intr_out : 0x%x \n",endpoint->bEndpointAddress);
+ dev->intr.out_endpointAddr = endpoint->bEndpointAddress;
+ }
+ }
+ if (!(dev->bulk.in_endpointAddr && dev->bulk.out_endpointAddr)) {
+ err("Could not find both bulk-in and bulk-out endpoints");
+ return -1;
+ }
+ if (!(dev->intr.in_endpointAddr && dev->intr.out_endpointAddr)) {
+ err("Could not find both intr-in and intr-out endpoints");
+ return -1;
+ }
+ return 0;
+}
+
+#define ASCHUH_DEV_MINOR_BASE 192
+//used in getting the file in /dev/
+static struct usb_class_driver aschuh_dev_class = {
+ .name = "aschuh%d",
+ .fops = &aschuh_dev_fops,
+ .minor_base = ASCHUH_DEV_MINOR_BASE,
+};
+static void init_aschuh_chan(struct aschuh_chan *chan,struct aschuh_dev *dev){
+ sema_init(&chan->limit_sem, WRITES_IN_FLIGHT);
+ mutex_init(&chan->io_mutex);
+ spin_lock_init(&chan->err_lock);
+ init_completion(&chan->in_completion);
+ chan->owner = dev;
+}
+static int aschuh_can_driver_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ // New Drivers Show up Here!
+ struct aschuh_dev *dev;
+ int retval = -ENOMEM;
+
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ err("Out of memory");
+ goto error;
+ }
+ kref_init(&dev->kref);
+
+ init_usb_anchor(&dev->submitted);
+ init_aschuh_chan(&dev->bulk,dev);
+ init_aschuh_chan(&dev->intr,dev);
+
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+ dev->interface = interface;
+
+ /* set up the endpoint information */
+ /* use only the first bulk-in and bulk-out endpoints */
+ if(aschuh_dev_connect_endpoints(dev,interface->cur_altsetting))
+ goto error;
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, dev);
+
+ /* we can register the device now, as it is ready */
+ retval = usb_register_dev(interface, &aschuh_dev_class);
+ if (retval) {
+ /* something prevented us from registering this driver */
+ err("Not able to get a minor for this device.");
+ usb_set_intfdata(interface, NULL);
+ goto error;
+ }
+
+ printk("CAN driver has been probed - %d\n",interface->minor);
+ /* let the user know what node this device is now attached to */
+ dev_info(&interface->dev,
+ "USB aschuh_dev device now attached to USB_ASCHUH-%d",
+ interface->minor);
+ return 0;
+
+error:
+ if (dev)
+ /* this frees allocated memory */
+ kref_put(&dev->kref, aschuh_dev_delete);
+ return -ENOMEM;
+}
+static void aschuh_can_driver_disconnect(struct usb_interface *interface)
+{
+ struct aschuh_dev *dev;
+ int minor = interface->minor;
+
+ dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ /* give back our minor */
+ usb_deregister_dev(interface, &aschuh_dev_class);
+
+ /* prevent more I/O from starting */
+ mutex_lock(&dev->bulk.io_mutex);
+ mutex_lock(&dev->intr.io_mutex);
+ dev->interface = NULL;
+ mutex_unlock(&dev->bulk.io_mutex);
+ mutex_unlock(&dev->intr.io_mutex);
+
+ usb_kill_anchored_urbs(&dev->submitted);
+
+ /* decrement our usage count */
+ kref_put(&dev->kref, aschuh_dev_delete);
+
+ dev_info(&interface->dev, "USB aschuh_dev #%d now disconnected", minor);
+}
+
diff --git a/gyro_board/src/usb_driver/usb-aschuh_can_device.h b/gyro_board/src/usb_driver/usb-aschuh_can_device.h
new file mode 100644
index 0000000..0065839
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_can_device.h
@@ -0,0 +1,37 @@
+#ifndef _USB_ASCHUH_CAN_DEVICE__H_
+#define _USB_ASCHUH_CAN_DEVICE__H_
+struct aschuh_dev;
+struct aschuh_chan{
+ struct urb *in_urb; /* the urb to read data with */
+ unsigned char *in_buffer; /* the buffer to receive data */
+ size_t in_size; /* the size of the receive buffer */
+ size_t in_filled; /* number of bytes in the buffer */
+ size_t in_copied; /* already copied to user space */
+ __u8 in_endpointAddr; /* the address of the in endpoint */
+ __u8 out_endpointAddr; /* the address of the out endpoint */
+ int errors; /* the last request tanked */
+ spinlock_t err_lock; /* lock for errors */
+ struct mutex io_mutex; /* synchronize I/O with disconnect */
+ struct semaphore limit_sem; /* limiting the number of writes in progress */
+ struct completion in_completion; /* to wait for an ongoing read */
+ bool ongoing_read; /* a read is going on */
+ bool processed_urb; /* indicates we haven't processed the urb */
+ __u8 bEndpointInterval; /* used in fill_int_urb */
+ struct aschuh_dev *owner;
+};
+
+struct aschuh_dev{
+ struct usb_device *udev; /* the usb device for this device */
+ struct usb_interface *interface; /* the interface for this device */
+ struct usb_anchor submitted; /* in case we need to retract our submissions */
+ struct aschuh_chan bulk; /* channel for handling bulk requests */
+ struct aschuh_chan intr;
+ int open_count; /* count the number of openers */
+ struct kref kref;
+};
+static void aschuh_can_driver_disconnect(struct usb_interface *interface);
+static int aschuh_can_driver_probe(struct usb_interface *interface,
+ const struct usb_device_id *id);
+
+
+#endif
diff --git a/gyro_board/src/usb_driver/usb-aschuh_can_driver.c b/gyro_board/src/usb_driver/usb-aschuh_can_driver.c
new file mode 100644
index 0000000..44a7f6e
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_can_driver.c
@@ -0,0 +1,46 @@
+#include "usb-aschuh_can_driver.h"
+#include "usb-aschuh_can_device.h"
+#define WRITES_IN_FLIGHT 8
+static const struct usb_device_id aschuh_can_device_table[] = {
+ { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
+ { } /*terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, aschuh_can_device_table);
+
+
+#include "usb-aschuh_can_device.c"
+static struct usb_driver aschuh_can_driver = {
+ .name = "aschuh_can_driver",
+ .probe = aschuh_can_driver_probe,
+ .disconnect = aschuh_can_driver_disconnect,
+ .suspend = NULL,
+ .resume = NULL,
+ .pre_reset = NULL,
+ .post_reset = NULL,
+ .id_table = aschuh_can_device_table,
+ .supports_autosuspend = 0,
+};
+
+static int __init aschuh_can_driver_init(void)
+{
+ int result;
+
+ result = usb_register(&aschuh_can_driver);
+ if(result)
+ err("usb_register failed. Error number %d",result);
+
+ printk("INIT CAN driver\n");
+ return result;
+}
+static void __exit aschuh_can_driver_exit(void)
+{
+ usb_deregister(&aschuh_can_driver);
+ printk("Closing CAN driver\n");
+}
+
+
+module_init(aschuh_can_driver_init);
+module_exit(aschuh_can_driver_exit);
+
+
+MODULE_LICENSE("GPL"); //not sure about this.
diff --git a/gyro_board/src/usb_driver/usb-aschuh_can_driver.h b/gyro_board/src/usb_driver/usb-aschuh_can_driver.h
new file mode 100644
index 0000000..73fcb1f
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_can_driver.h
@@ -0,0 +1,21 @@
+#ifndef __USB_ASCHUH_CAN_DRIVER__H_
+#define __USB_ASCHUH_CAN_DRIVER__H_
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+
+struct aschuh_can_device {
+ struct usb_device *udev;
+ struct usb_interface *interface;
+};
+#define VENDOR_ID 0x1424
+#define PRODUCT_ID 0xd243
+
+#endif
diff --git a/gyro_board/src/usb_driver/usb-aschuh_fops_ioctl.c b/gyro_board/src/usb_driver/usb-aschuh_fops_ioctl.c
new file mode 100644
index 0000000..4229444
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_fops_ioctl.c
@@ -0,0 +1,19 @@
+static long aschuh_dev_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct aschuh_chan *new_chan;
+ struct aschuh_chan *chan = file->private_data;
+ struct aschuh_dev *dev = chan->owner;
+ printk("ioctl(%d,%d)\n",cmd,(int)arg);
+ if(cmd == 1){
+ if(arg == 254){
+ new_chan = &dev->bulk;
+ }else{
+ new_chan = &dev->intr;
+ }
+ file->private_data = new_chan;
+ return 0;
+ }else{
+ return 0;
+ }
+}
diff --git a/gyro_board/src/usb_driver/usb-aschuh_fops_open.c b/gyro_board/src/usb_driver/usb-aschuh_fops_open.c
new file mode 100644
index 0000000..5263acd
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_fops_open.c
@@ -0,0 +1,60 @@
+static struct usb_driver aschuh_can_driver;
+static int aschuh_dev_open(struct inode *inode, struct file *file)
+{
+ struct aschuh_dev *dev;
+ struct usb_interface *interface;
+ int subminor;
+
+ subminor = iminor(inode);
+ printk("opening device!!!\n");
+ interface = usb_find_interface(&aschuh_can_driver, subminor);
+ if (!interface) {
+ err("%s - error, can't find device for minor %d",
+ __func__, subminor);
+ return( -ENODEV);
+ }
+
+ dev = usb_get_intfdata(interface);
+ if (!dev) {
+ return( -ENODEV);
+ }
+
+ /* increment our usage count for the device */
+ kref_get(&dev->kref);
+
+ /* lock the device to allow correctly handling errors
+ * in resumption */
+ mutex_lock(&dev->bulk.io_mutex);
+ mutex_lock(&dev->intr.io_mutex);
+ //TODO(parker): Hey folks! I just commented this out.
+ // it would be a good thing to check what usb_autopm_get_interface
+ // actually does :P. Good thing to check if you find errors.
+ /*
+ if (!dev->open_count++) {
+ int retval = usb_autopm_get_interface(interface);
+ if (retval) {
+ dev->open_count--;
+ mutex_unlock(&dev->bulk.io_mutex);
+ mutex_unlock(&dev->intr.io_mutex);
+ kref_put(&dev->kref, aschuh_dev_delete);
+ return retval;
+ }
+ }
+ */
+ /* else { //uncomment this block if you want exclusive open
+ retval = -EBUSY;
+ dev->open_count--;
+ mutex_unlock(&dev->io_mutex);
+ kref_put(&dev->kref, aschuh_dev_delete);
+ goto exit;
+ } */
+ /* prevent the device from being autosuspended */
+
+ /* save our object in the file's private structure */
+ file->private_data = &dev->intr;
+ mutex_unlock(&dev->bulk.io_mutex);
+ mutex_unlock(&dev->intr.io_mutex);
+
+ return 0;
+}
+
diff --git a/gyro_board/src/usb_driver/usb-aschuh_fops_read.c b/gyro_board/src/usb_driver/usb-aschuh_fops_read.c
new file mode 100644
index 0000000..912e4b6
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_fops_read.c
@@ -0,0 +1,207 @@
+static void aschuh_chan_read_callback(struct urb *urb)
+{
+ struct aschuh_chan *chan;
+
+ chan = urb->context;
+
+ spin_lock(&chan->err_lock);
+ /* sync/async unlink faults aren't errors */
+ if (urb->status) {
+ if (!(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN))
+ err("%s - nonzero write bulk status received: %d",
+ __func__, urb->status);
+
+ chan->errors = urb->status;
+ } else {
+ chan->in_filled = urb->actual_length;
+ }
+ chan->ongoing_read = 0;
+ spin_unlock(&chan->err_lock);
+
+ complete(&chan->in_completion);
+}
+
+static int aschuh_chan_submit(struct aschuh_chan *chan){
+ int rv;
+ /* tell everybody to leave the URB alone */
+ spin_lock_irq(&chan->err_lock);
+ chan->ongoing_read = 1;
+ spin_unlock_irq(&chan->err_lock);
+
+
+ /* do it */
+ rv = usb_submit_urb(chan->in_urb, GFP_KERNEL);
+ if (rv < 0) {
+ err("%s - failed submitting read urb, error %d",
+ __func__, rv);
+ chan->in_filled = 0;
+ rv = (rv == -ENOMEM) ? rv : -EIO;
+ spin_lock_irq(&chan->err_lock);
+ chan->ongoing_read = 0;
+ spin_unlock_irq(&chan->err_lock);
+ }
+
+ return rv;
+}
+
+
+static int aschuh_dev_bulk_do_read_io(struct aschuh_dev *dev,size_t count)
+{
+ struct aschuh_chan *chan = &dev->bulk;
+ /* prepare a read */
+ usb_fill_bulk_urb(chan->in_urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev, chan->in_endpointAddr),
+ chan->in_buffer,
+ min(chan->in_size, count),
+ aschuh_chan_read_callback,
+ chan);
+ return aschuh_chan_submit(chan);
+}
+
+static int aschuh_dev_intr_do_read_io(struct aschuh_dev *dev,size_t count)
+{
+ struct aschuh_chan *chan = &dev->intr;
+ /* prepare a read */
+ usb_fill_int_urb(chan->in_urb, dev->udev,
+ usb_rcvintpipe(dev->udev, chan->in_endpointAddr),
+ chan->in_buffer,
+ chan->in_size,
+ aschuh_chan_read_callback,
+ chan,chan->bEndpointInterval);
+ return aschuh_chan_submit(chan);
+}
+
+static ssize_t aschuh_dev_read(struct file *file, char *buffer, size_t count,
+ loff_t *ppos)
+{
+ int rv;
+ bool ongoing_io;
+ struct aschuh_chan *chan = file->private_data;
+ struct aschuh_dev *dev = chan->owner;
+ enum chan_types{
+ BULK_CHAN, INTR_CHAN
+ } chan_type = INTR_CHAN;
+ size_t available;
+ if(chan == &dev->intr)
+ chan_type = INTR_CHAN;
+ else if(chan == &dev->bulk){
+ chan_type = BULK_CHAN;
+ }else{
+ printk("Chan type not debug or data!!!");
+ return 0;
+ }
+
+
+ /* if we cannot read at all, return EOF */
+ if (!chan->in_urb || !count)
+ return 0;
+
+ rv = mutex_lock_interruptible(&chan->io_mutex);
+ if (rv < 0)
+ return rv;
+
+ if (!dev->interface) { /* disconnect() was called */
+ rv = -ENODEV;
+ goto exit;
+ }
+
+ /* if IO is under way, we must not touch things */
+ while(true){
+ spin_lock_irq(&chan->err_lock);
+ ongoing_io = chan->ongoing_read;
+ spin_unlock_irq(&chan->err_lock);
+
+ if (ongoing_io) {
+ /* nonblocking IO shall not wait */
+ if (file->f_flags & O_NONBLOCK) {
+ rv = -EAGAIN;
+ goto exit;
+ }
+ /*
+ * IO may take forever
+ * hence wait in an interruptible state
+ */
+ mutex_unlock(&chan->io_mutex);
+ rv = wait_for_completion_interruptible(&chan->in_completion);
+ if (rv < 0)
+ return rv;
+
+ rv = mutex_lock_interruptible(&chan->io_mutex);
+ if (rv < 0)
+ return rv;
+ /*
+ * by waiting we also semiprocessed the urb
+ * we must finish now
+ */
+ chan->in_copied = 0;
+ }
+
+
+ /* errors must be reported */
+ rv = chan->errors;
+ if (rv < 0) {
+ /* any error is reported once */
+ chan->errors = 0;
+ /* to preserve notifications about reset */
+ rv = (rv == -EPIPE) ? rv : -EIO;
+ /* no data to deliver */
+ chan->in_filled = 0;
+ /* report it */
+ goto exit;
+ }
+ /*
+ * if the buffer is filled we may satisfy the read
+ * else we need to start IO
+ */
+
+ /* we had read data */
+ available = chan->in_filled - chan->in_copied;
+
+ if (!chan->in_filled || !available) {
+ /*
+ * all data has been used or no data is avaiable.
+ * actual IO needs to be done
+ */
+ if(chan_type == INTR_CHAN)
+ rv = aschuh_dev_intr_do_read_io(dev, count);
+ else if(chan_type == BULK_CHAN){
+ rv = aschuh_dev_bulk_do_read_io(dev, count);
+ }
+ if (rv < 0)
+ goto exit;
+ }else{
+ size_t chunk = min(available, count);
+ /*
+ * data is available
+ * chunk tells us how much shall be copied
+ */
+
+ if (copy_to_user(buffer,
+ chan->in_buffer + chan->in_copied,
+ chunk))
+ rv = -EFAULT;
+ else
+ rv = chunk;
+
+ chan->in_copied += chunk;
+
+ /*
+ * if we are asked for more than we have,
+ * we start IO but don't wait
+ */
+ //if (available < count){
+ // if(chan_type == INTR_CHAN)
+ // aschuh_dev_intr_do_read_io(dev, count);
+ // else if(chan_type == BULK_CHAN){
+ // aschuh_dev_bulk_do_read_io(dev, count);
+ // }
+ //}
+ goto exit;
+ }
+ }
+exit:
+ mutex_unlock(&chan->io_mutex);
+ return rv;
+}
diff --git a/gyro_board/src/usb_driver/usb-aschuh_fops_release.c b/gyro_board/src/usb_driver/usb-aschuh_fops_release.c
new file mode 100644
index 0000000..259a1b9
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_fops_release.c
@@ -0,0 +1,22 @@
+static int aschuh_dev_release(struct inode *inode, struct file *file)
+{
+ struct aschuh_dev *dev;
+ printk("closing device!!!\n");
+
+ dev = ((struct aschuh_chan *)file->private_data)->owner;
+ if (dev == NULL)
+ return -ENODEV;
+
+ /* allow the device to be autosuspended */
+ //mutex_lock(&dev->bulk.io_mutex);
+ //mutex_lock(&dev->intr.io_mutex);
+ //if (!--dev->open_count && dev->interface)
+ // usb_autopm_put_interface(dev->interface);
+ //mutex_unlock(&dev->bulk.io_mutex);
+ //mutex_unlock(&dev->intr.io_mutex);
+
+ /* decrement the count on our device */
+ kref_put(&dev->kref, aschuh_dev_delete);
+ return 0;
+}
+
diff --git a/gyro_board/src/usb_driver/usb-aschuh_fops_write.c b/gyro_board/src/usb_driver/usb-aschuh_fops_write.c
new file mode 100644
index 0000000..7a9e00e
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-aschuh_fops_write.c
@@ -0,0 +1,144 @@
+#include <linux/usb.h>
+static void aschuh_dev_write_callback(struct urb *urb)
+{
+ struct aschuh_chan *chan;
+
+ chan = urb->context;
+ /* sync/async unlink faults aren't errors */
+ if (urb->status) {
+ if (!(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN))
+ err("%s - nonzero write bulk status received: %d",
+ __func__, urb->status);
+
+ spin_lock(&chan->err_lock);
+ chan->errors = urb->status;
+ spin_unlock(&chan->err_lock);
+ }
+
+ /* free up our allocated buffer */
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+ up(&chan->limit_sem);
+}
+//#define WRITES_IN_FLIGHT 8
+#define MAX_TRANSFER 64
+
+static ssize_t aschuh_dev_write(struct file *file, const char *user_buffer,
+ size_t count, loff_t *ppos)
+{
+ struct aschuh_chan *chan;
+ struct aschuh_dev *dev;
+ int retval = 0;
+ struct urb *urb = NULL;
+ char *buf = NULL;
+ size_t writesize = min(count, (size_t)MAX_TRANSFER);
+
+ chan = file->private_data;
+ dev = chan->owner;
+
+ /* verify that we actually have some data to write */
+ if (count == 0)
+ goto exit;
+
+ /*
+ * limit the number of URBs in flight to stop a user from using up all
+ * RAM
+ */
+ if (!(file->f_flags & O_NONBLOCK)) {
+ if (down_interruptible(&chan->limit_sem)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+ } else {
+ if (down_trylock(&chan->limit_sem)) {
+ retval = -EAGAIN;
+ goto exit;
+ }
+ }
+
+ spin_lock_irq(&chan->err_lock);
+ retval = chan->errors;
+ if (retval < 0) {
+ /* any error is reported once */
+ chan->errors = 0;
+ /* to preserve notifications about reset */
+ retval = (retval == -EPIPE) ? retval : -EIO;
+ }
+ spin_unlock_irq(&chan->err_lock);
+ if (retval < 0)
+ goto error;
+
+ /* create a urb, and a buffer for it, and copy the data to the urb */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buf) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ if (copy_from_user(buf, user_buffer, writesize)) {
+ retval = -EFAULT;
+ goto error;
+ }
+
+ /* this lock makes sure we don't submit URBs to gone devices */
+ mutex_lock(&chan->io_mutex);
+ if (!dev->interface) { /* disconnect() was called */
+ mutex_unlock(&chan->io_mutex);
+ printk("Should be exiting shortly.... stay tuned for details\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ /* initialize the urb properly */
+ if(chan == &dev->bulk){
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev, chan->out_endpointAddr),
+ buf, writesize, aschuh_dev_write_callback, chan);
+ }else{
+ usb_fill_int_urb(urb, dev->udev,
+ usb_sndintpipe(dev->udev, chan->out_endpointAddr),
+ buf, writesize, aschuh_dev_write_callback, chan,
+ chan->bEndpointInterval);
+ }
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ usb_anchor_urb(urb, &dev->submitted);
+ /* send the data out the bulk port */
+ retval = usb_submit_urb(urb, GFP_KERNEL);
+ mutex_unlock(&chan->io_mutex);
+ if (retval) {
+ err("%s - failed submitting write urb, error %d", __func__,
+ retval);
+ usb_unanchor_urb(urb);
+ goto error;
+ }
+
+ /*
+ * release our reference to this urb, the USB core will eventually free
+ * it entirely
+ */
+ usb_free_urb(urb);
+
+
+ return writesize;
+
+error:
+ if (urb) {
+ usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
+ usb_free_urb(urb);
+ }
+ up(&chan->limit_sem);
+
+exit:
+ return retval;
+}
+
diff --git a/gyro_board/src/usb_driver/usb-skeleton.c b/gyro_board/src/usb_driver/usb-skeleton.c
new file mode 100644
index 0000000..1409724
--- /dev/null
+++ b/gyro_board/src/usb_driver/usb-skeleton.c
@@ -0,0 +1,713 @@
+/*
+ * USB Skeleton driver - 2.2
+ *
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
+ * but has been rewritten to be easier to read and use.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+
+
+/* Define these values to match your devices */
+#define USB_SKEL_VENDOR_ID 0xfff0
+#define USB_SKEL_PRODUCT_ID 0xfff0
+
+/* table of devices that work with this driver */
+static const struct usb_device_id skel_table[] = {
+ { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, skel_table);
+
+
+/* Get a minor range for your devices from the usb maintainer */
+#define USB_SKEL_MINOR_BASE 192
+
+/* our private defines. if this grows any larger, use your own .h file */
+#define MAX_TRANSFER (PAGE_SIZE - 512)
+/* MAX_TRANSFER is chosen so that the VM is not stressed by
+ allocations > PAGE_SIZE and the number of packets in a page
+ is an integer 512 is the largest possible packet on EHCI */
+#define WRITES_IN_FLIGHT 8
+/* arbitrarily chosen */
+
+/* Structure to hold all of our device specific stuff */
+struct usb_skel {
+ struct usb_device *udev; /* the usb device for this device */
+ struct usb_interface *interface; /* the interface for this device */
+ struct semaphore limit_sem; /* limiting the number of writes in progress */
+ struct usb_anchor submitted; /* in case we need to retract our submissions */
+ struct urb *bulk_in_urb; /* the urb to read data with */
+ unsigned char *bulk_in_buffer; /* the buffer to receive data */
+ size_t bulk_in_size; /* the size of the receive buffer */
+ size_t bulk_in_filled; /* number of bytes in the buffer */
+ size_t bulk_in_copied; /* already copied to user space */
+ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
+ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
+ int errors; /* the last request tanked */
+ int open_count; /* count the number of openers */
+ bool ongoing_read; /* a read is going on */
+ bool processed_urb; /* indicates we haven't processed the urb */
+ spinlock_t err_lock; /* lock for errors */
+ struct kref kref;
+ struct mutex io_mutex; /* synchronize I/O with disconnect */
+ struct completion bulk_in_completion; /* to wait for an ongoing read */
+};
+#define to_skel_dev(d) container_of(d, struct usb_skel, kref)
+
+static struct usb_driver skel_driver;
+static void skel_draw_down(struct usb_skel *dev);
+
+static void skel_delete(struct kref *kref)
+{
+ struct usb_skel *dev = to_skel_dev(kref);
+
+ usb_free_urb(dev->bulk_in_urb);
+ usb_put_dev(dev->udev);
+ kfree(dev->bulk_in_buffer);
+ kfree(dev);
+}
+
+static int skel_open(struct inode *inode, struct file *file)
+{
+ struct usb_skel *dev;
+ struct usb_interface *interface;
+ int subminor;
+ int retval = 0;
+
+ subminor = iminor(inode);
+
+ interface = usb_find_interface(&skel_driver, subminor);
+ if (!interface) {
+ err("%s - error, can't find device for minor %d",
+ __func__, subminor);
+ retval = -ENODEV;
+ goto exit;
+ }
+
+ dev = usb_get_intfdata(interface);
+ if (!dev) {
+ retval = -ENODEV;
+ goto exit;
+ }
+
+ /* increment our usage count for the device */
+ kref_get(&dev->kref);
+
+ /* lock the device to allow correctly handling errors
+ * in resumption */
+ mutex_lock(&dev->io_mutex);
+
+ if (!dev->open_count++) {
+ retval = usb_autopm_get_interface(interface);
+ if (retval) {
+ dev->open_count--;
+ mutex_unlock(&dev->io_mutex);
+ kref_put(&dev->kref, skel_delete);
+ goto exit;
+ }
+ } /* else { //uncomment this block if you want exclusive open
+ retval = -EBUSY;
+ dev->open_count--;
+ mutex_unlock(&dev->io_mutex);
+ kref_put(&dev->kref, skel_delete);
+ goto exit;
+ } */
+ /* prevent the device from being autosuspended */
+
+ /* save our object in the file's private structure */
+ file->private_data = dev;
+ mutex_unlock(&dev->io_mutex);
+
+exit:
+ return retval;
+}
+
+static int skel_release(struct inode *inode, struct file *file)
+{
+ struct usb_skel *dev;
+
+ dev = file->private_data;
+ if (dev == NULL)
+ return -ENODEV;
+
+ /* allow the device to be autosuspended */
+ mutex_lock(&dev->io_mutex);
+ if (!--dev->open_count && dev->interface)
+ usb_autopm_put_interface(dev->interface);
+ mutex_unlock(&dev->io_mutex);
+
+ /* decrement the count on our device */
+ kref_put(&dev->kref, skel_delete);
+ return 0;
+}
+
+static int skel_flush(struct file *file, fl_owner_t id)
+{
+ struct usb_skel *dev;
+ int res;
+
+ dev = file->private_data;
+ if (dev == NULL)
+ return -ENODEV;
+
+ /* wait for io to stop */
+ mutex_lock(&dev->io_mutex);
+ skel_draw_down(dev);
+
+ /* read out errors, leave subsequent opens a clean slate */
+ spin_lock_irq(&dev->err_lock);
+ res = dev->errors ? (dev->errors == -EPIPE ? -EPIPE : -EIO) : 0;
+ dev->errors = 0;
+ spin_unlock_irq(&dev->err_lock);
+
+ mutex_unlock(&dev->io_mutex);
+
+ return res;
+}
+
+static void skel_read_bulk_callback(struct urb *urb)
+{
+ struct usb_skel *dev;
+
+ dev = urb->context;
+
+ spin_lock(&dev->err_lock);
+ /* sync/async unlink faults aren't errors */
+ if (urb->status) {
+ if (!(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN))
+ err("%s - nonzero write bulk status received: %d",
+ __func__, urb->status);
+
+ dev->errors = urb->status;
+ } else {
+ dev->bulk_in_filled = urb->actual_length;
+ }
+ dev->ongoing_read = 0;
+ spin_unlock(&dev->err_lock);
+
+ complete(&dev->bulk_in_completion);
+}
+
+static int skel_do_read_io(struct usb_skel *dev, size_t count)
+{
+ int rv;
+
+ /* prepare a read */
+ usb_fill_bulk_urb(dev->bulk_in_urb,
+ dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in_endpointAddr),
+ dev->bulk_in_buffer,
+ min(dev->bulk_in_size, count),
+ skel_read_bulk_callback,
+ dev);
+ /* tell everybody to leave the URB alone */
+ spin_lock_irq(&dev->err_lock);
+ dev->ongoing_read = 1;
+ spin_unlock_irq(&dev->err_lock);
+
+ /* do it */
+ rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
+ if (rv < 0) {
+ err("%s - failed submitting read urb, error %d",
+ __func__, rv);
+ dev->bulk_in_filled = 0;
+ rv = (rv == -ENOMEM) ? rv : -EIO;
+ spin_lock_irq(&dev->err_lock);
+ dev->ongoing_read = 0;
+ spin_unlock_irq(&dev->err_lock);
+ }
+
+ return rv;
+}
+
+static ssize_t skel_read(struct file *file, char *buffer, size_t count,
+ loff_t *ppos)
+{
+ struct usb_skel *dev;
+ int rv;
+ bool ongoing_io;
+
+ dev = file->private_data;
+
+ /* if we cannot read at all, return EOF */
+ if (!dev->bulk_in_urb || !count)
+ return 0;
+
+ /* no concurrent readers */
+ rv = mutex_lock_interruptible(&dev->io_mutex);
+ if (rv < 0)
+ return rv;
+
+ if (!dev->interface) { /* disconnect() was called */
+ rv = -ENODEV;
+ goto exit;
+ }
+
+ /* if IO is under way, we must not touch things */
+retry:
+ spin_lock_irq(&dev->err_lock);
+ ongoing_io = dev->ongoing_read;
+ spin_unlock_irq(&dev->err_lock);
+
+ if (ongoing_io) {
+ /* nonblocking IO shall not wait */
+ if (file->f_flags & O_NONBLOCK) {
+ rv = -EAGAIN;
+ goto exit;
+ }
+ /*
+ * IO may take forever
+ * hence wait in an interruptible state
+ */
+ rv = wait_for_completion_interruptible(&dev->bulk_in_completion);
+ if (rv < 0)
+ goto exit;
+ /*
+ * by waiting we also semiprocessed the urb
+ * we must finish now
+ */
+ dev->bulk_in_copied = 0;
+ dev->processed_urb = 1;
+ }
+
+ if (!dev->processed_urb) {
+ /*
+ * the URB hasn't been processed
+ * do it now
+ */
+ wait_for_completion(&dev->bulk_in_completion);
+ dev->bulk_in_copied = 0;
+ dev->processed_urb = 1;
+ }
+
+ /* errors must be reported */
+ rv = dev->errors;
+ if (rv < 0) {
+ /* any error is reported once */
+ dev->errors = 0;
+ /* to preserve notifications about reset */
+ rv = (rv == -EPIPE) ? rv : -EIO;
+ /* no data to deliver */
+ dev->bulk_in_filled = 0;
+ /* report it */
+ goto exit;
+ }
+
+ /*
+ * if the buffer is filled we may satisfy the read
+ * else we need to start IO
+ */
+
+ if (dev->bulk_in_filled) {
+ /* we had read data */
+ size_t available = dev->bulk_in_filled - dev->bulk_in_copied;
+ size_t chunk = min(available, count);
+
+ if (!available) {
+ /*
+ * all data has been used
+ * actual IO needs to be done
+ */
+ rv = skel_do_read_io(dev, count);
+ if (rv < 0)
+ goto exit;
+ else
+ goto retry;
+ }
+ /*
+ * data is available
+ * chunk tells us how much shall be copied
+ */
+
+ if (copy_to_user(buffer,
+ dev->bulk_in_buffer + dev->bulk_in_copied,
+ chunk))
+ rv = -EFAULT;
+ else
+ rv = chunk;
+
+ dev->bulk_in_copied += chunk;
+
+ /*
+ * if we are asked for more than we have,
+ * we start IO but don't wait
+ */
+ if (available < count)
+ skel_do_read_io(dev, count - chunk);
+ } else {
+ /* no data in the buffer */
+ rv = skel_do_read_io(dev, count);
+ if (rv < 0)
+ goto exit;
+ else if (!(file->f_flags & O_NONBLOCK))
+ goto retry;
+ rv = -EAGAIN;
+ }
+exit:
+ mutex_unlock(&dev->io_mutex);
+ return rv;
+}
+
+static void skel_write_bulk_callback(struct urb *urb)
+{
+ struct usb_skel *dev;
+
+ dev = urb->context;
+
+ /* sync/async unlink faults aren't errors */
+ if (urb->status) {
+ if (!(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN))
+ err("%s - nonzero write bulk status received: %d",
+ __func__, urb->status);
+
+ spin_lock(&dev->err_lock);
+ dev->errors = urb->status;
+ spin_unlock(&dev->err_lock);
+ }
+
+ /* free up our allocated buffer */
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+ up(&dev->limit_sem);
+}
+
+static ssize_t skel_write(struct file *file, const char *user_buffer,
+ size_t count, loff_t *ppos)
+{
+ struct usb_skel *dev;
+ int retval = 0;
+ struct urb *urb = NULL;
+ char *buf = NULL;
+ size_t writesize = min(count, (size_t)MAX_TRANSFER);
+
+ dev = file->private_data;
+
+ /* verify that we actually have some data to write */
+ if (count == 0)
+ goto exit;
+
+ /*
+ * limit the number of URBs in flight to stop a user from using up all
+ * RAM
+ */
+ if (!(file->f_flags & O_NONBLOCK)) {
+ if (down_interruptible(&dev->limit_sem)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+ } else {
+ if (down_trylock(&dev->limit_sem)) {
+ retval = -EAGAIN;
+ goto exit;
+ }
+ }
+
+ spin_lock_irq(&dev->err_lock);
+ retval = dev->errors;
+ if (retval < 0) {
+ /* any error is reported once */
+ dev->errors = 0;
+ /* to preserve notifications about reset */
+ retval = (retval == -EPIPE) ? retval : -EIO;
+ }
+ spin_unlock_irq(&dev->err_lock);
+ if (retval < 0)
+ goto error;
+
+ /* create a urb, and a buffer for it, and copy the data to the urb */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buf) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ if (copy_from_user(buf, user_buffer, writesize)) {
+ retval = -EFAULT;
+ goto error;
+ }
+
+ /* this lock makes sure we don't submit URBs to gone devices */
+ mutex_lock(&dev->io_mutex);
+ if (!dev->interface) { /* disconnect() was called */
+ mutex_unlock(&dev->io_mutex);
+ retval = -ENODEV;
+ goto error;
+ }
+
+ /* initialize the urb properly */
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
+ buf, writesize, skel_write_bulk_callback, dev);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &dev->submitted);
+
+ /* send the data out the bulk port */
+ retval = usb_submit_urb(urb, GFP_KERNEL);
+ mutex_unlock(&dev->io_mutex);
+ if (retval) {
+ err("%s - failed submitting write urb, error %d", __func__,
+ retval);
+ goto error_unanchor;
+ }
+
+ /*
+ * release our reference to this urb, the USB core will eventually free
+ * it entirely
+ */
+ usb_free_urb(urb);
+
+
+ return writesize;
+
+error_unanchor:
+ usb_unanchor_urb(urb);
+error:
+ if (urb) {
+ usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
+ usb_free_urb(urb);
+ }
+ up(&dev->limit_sem);
+
+exit:
+ return retval;
+}
+
+static const struct file_operations skel_fops = {
+ .owner = THIS_MODULE,
+ .read = skel_read,
+ .write = skel_write,
+ .open = skel_open,
+ .release = skel_release,
+ .flush = skel_flush,
+ .llseek = noop_llseek,
+};
+
+/*
+ * usb class driver info in order to get a minor number from the usb core,
+ * and to have the device registered with the driver core
+ */
+static struct usb_class_driver skel_class = {
+ .name = "skel%d",
+ .fops = &skel_fops,
+ .minor_base = USB_SKEL_MINOR_BASE,
+};
+
+static int skel_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_skel *dev;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ size_t buffer_size;
+ int i;
+ int retval = -ENOMEM;
+
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ err("Out of memory");
+ goto error;
+ }
+ kref_init(&dev->kref);
+ sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
+ mutex_init(&dev->io_mutex);
+ spin_lock_init(&dev->err_lock);
+ init_usb_anchor(&dev->submitted);
+ init_completion(&dev->bulk_in_completion);
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+ dev->interface = interface;
+
+ /* set up the endpoint information */
+ /* use only the first bulk-in and bulk-out endpoints */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (!dev->bulk_in_endpointAddr &&
+ usb_endpoint_is_bulk_in(endpoint)) {
+ /* we found a bulk in endpoint */
+ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ dev->bulk_in_size = buffer_size;
+ dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+ dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!dev->bulk_in_buffer) {
+ err("Could not allocate bulk_in_buffer");
+ goto error;
+ }
+ dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->bulk_in_urb) {
+ err("Could not allocate bulk_in_urb");
+ goto error;
+ }
+ }
+
+ if (!dev->bulk_out_endpointAddr &&
+ usb_endpoint_is_bulk_out(endpoint)) {
+ /* we found a bulk out endpoint */
+ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
+ }
+ }
+ if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
+ err("Could not find both bulk-in and bulk-out endpoints");
+ goto error;
+ }
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, dev);
+
+ /* we can register the device now, as it is ready */
+ retval = usb_register_dev(interface, &skel_class);
+ if (retval) {
+ /* something prevented us from registering this driver */
+ err("Not able to get a minor for this device.");
+ usb_set_intfdata(interface, NULL);
+ goto error;
+ }
+
+ /* let the user know what node this device is now attached to */
+ dev_info(&interface->dev,
+ "USB Skeleton device now attached to USBSkel-%d",
+ interface->minor);
+ return 0;
+
+error:
+ if (dev)
+ /* this frees allocated memory */
+ kref_put(&dev->kref, skel_delete);
+ return retval;
+}
+
+static void skel_disconnect(struct usb_interface *interface)
+{
+ struct usb_skel *dev;
+ int minor = interface->minor;
+
+ dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ /* give back our minor */
+ usb_deregister_dev(interface, &skel_class);
+
+ /* prevent more I/O from starting */
+ mutex_lock(&dev->io_mutex);
+ dev->interface = NULL;
+ mutex_unlock(&dev->io_mutex);
+
+ usb_kill_anchored_urbs(&dev->submitted);
+
+ /* decrement our usage count */
+ kref_put(&dev->kref, skel_delete);
+
+ dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
+}
+
+static void skel_draw_down(struct usb_skel *dev)
+{
+ int time;
+
+ time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000);
+ if (!time)
+ usb_kill_anchored_urbs(&dev->submitted);
+ usb_kill_urb(dev->bulk_in_urb);
+}
+
+static int skel_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct usb_skel *dev = usb_get_intfdata(intf);
+
+ if (!dev)
+ return 0;
+ skel_draw_down(dev);
+ return 0;
+}
+
+static int skel_resume(struct usb_interface *intf)
+{
+ return 0;
+}
+
+static int skel_pre_reset(struct usb_interface *intf)
+{
+ struct usb_skel *dev = usb_get_intfdata(intf);
+
+ mutex_lock(&dev->io_mutex);
+ skel_draw_down(dev);
+
+ return 0;
+}
+
+static int skel_post_reset(struct usb_interface *intf)
+{
+ struct usb_skel *dev = usb_get_intfdata(intf);
+
+ /* we are sure no URBs are active - no locking needed */
+ dev->errors = -EPIPE;
+ mutex_unlock(&dev->io_mutex);
+
+ return 0;
+}
+
+static struct usb_driver skel_driver = {
+ .name = "skeleton",
+ .probe = skel_probe,
+ .disconnect = skel_disconnect,
+ .suspend = skel_suspend,
+ .resume = skel_resume,
+ .pre_reset = skel_pre_reset,
+ .post_reset = skel_post_reset,
+ .id_table = skel_table,
+ .supports_autosuspend = 1,
+};
+
+static int __init usb_skel_init(void)
+{
+ int result;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&skel_driver);
+ if (result)
+ err("usb_register failed. Error number %d", result);
+
+ return result;
+}
+
+static void __exit usb_skel_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&skel_driver);
+}
+
+module_init(usb_skel_init);
+module_exit(usb_skel_exit);
+
+MODULE_LICENSE("GPL");
+