+
+/* 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 /* ENABLE_FREERTOS */
+#endif /* INC_FREERTOS_H */
+
diff --git a/openbeacon/lpc13xx/core/freertos/inc/StackMacros.h b/openbeacon/lpc13xx/core/freertos/inc/StackMacros.h
new file mode 100644
index 0000000..cd0a061
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/StackMacros.h
@@ -0,0 +1,173 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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/openbeacon/lpc13xx/core/freertos/inc/croutine.h b/openbeacon/lpc13xx/core/freertos/inc/croutine.h
new file mode 100644
index 0000000..8c2f1a6
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/croutine.h
@@ -0,0 +1,749 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+ *
+ portBASE_TYPE xCoRoutineCreate(
+ crCOROUTINE_CODE pxCoRoutineCode,
+ unsigned portBASE_TYPE uxPriority,
+ unsigned portBASE_TYPE uxIndex
+ );
+ *
+ * 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:
+
+ // 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 );
+ }
+ }
+
+ * \defgroup xCoRoutineCreate xCoRoutineCreate
+ * \ingroup Tasks
+ */
+signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
+
+
+/**
+ * croutine. h
+ *
+ void vCoRoutineSchedule( void );
+ *
+ * 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:
+
+ // 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();
+ }
+ }
+
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule
+ * \ingroup Tasks
+ */
+void vCoRoutineSchedule( void );
+
+/**
+ * croutine. h
+ *
+ crSTART( xCoRoutineHandle xHandle );
+ *
+ * This macro MUST always be called at the start of a co-routine function.
+ *
+ * Example usage:
+
+ // 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();
+ }
+ * \defgroup crSTART crSTART
+ * \ingroup Tasks
+ */
+#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
+
+/**
+ * croutine. h
+ *
+ crEND();
+ *
+ * This macro MUST always be called at the end of a co-routine function.
+ *
+ * Example usage:
+
+ // 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();
+ }
+ * \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
+ *
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );
+ *
+ * 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:
+
+ // 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();
+ }
+ * \defgroup crDELAY crDELAY
+ * \ingroup Tasks
+ */
+#define crDELAY( xHandle, xTicksToDelay ) \
+ if( xTicksToDelay > 0 ) \
+ { \
+ vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \
+ } \
+ crSET_STATE0( xHandle );
+
+/**
+ *
+ crQUEUE_SEND(
+ xCoRoutineHandle xHandle,
+ xQueueHandle pxQueue,
+ void *pvItemToQueue,
+ portTickType xTicksToWait,
+ portBASE_TYPE *pxResult
+ )
+ *
+ * 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:
+
+ // 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();
+ }
+ * \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
+ *
+ crQUEUE_RECEIVE(
+ xCoRoutineHandle xHandle,
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait,
+ portBASE_TYPE *pxResult
+ )
+ *
+ * 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:
+
+ // 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();
+ }
+ * \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
+ *
+ crQUEUE_SEND_FROM_ISR(
+ xQueueHandle pxQueue,
+ void *pvItemToQueue,
+ portBASE_TYPE xCoRoutinePreviouslyWoken
+ )
+ *
+ * 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:
+
+ // 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 );
+ }
+ }
+ * \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
+ *
+ crQUEUE_SEND_FROM_ISR(
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portBASE_TYPE * pxCoRoutineWoken
+ )
+ *
+ * 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:
+
+ // 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 );
+ }
+ }
+ }
+ * \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/openbeacon/lpc13xx/core/freertos/inc/list.h b/openbeacon/lpc13xx/core/freertos/inc/list.h
new file mode 100644
index 0000000..1733ecc
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/list.h
@@ -0,0 +1,305 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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/openbeacon/lpc13xx/core/freertos/inc/mpu_wrappers.h b/openbeacon/lpc13xx/core/freertos/inc/mpu_wrappers.h
new file mode 100644
index 0000000..a3a497f
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/mpu_wrappers.h
@@ -0,0 +1,135 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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/openbeacon/lpc13xx/core/freertos/inc/portable.h b/openbeacon/lpc13xx/core/freertos/inc/portable.h
new file mode 100644
index 0000000..d6e42a2
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/portable.h
@@ -0,0 +1,390 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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/openbeacon/lpc13xx/core/freertos/inc/portmacro.h b/openbeacon/lpc13xx/core/freertos/inc/portmacro.h
new file mode 100644
index 0000000..861ebf4
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/portmacro.h
@@ -0,0 +1,156 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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/openbeacon/lpc13xx/core/freertos/inc/projdefs.h b/openbeacon/lpc13xx/core/freertos/inc/projdefs.h
new file mode 100644
index 0000000..5441415
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/projdefs.h
@@ -0,0 +1,77 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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/openbeacon/lpc13xx/core/freertos/inc/queue.h b/openbeacon/lpc13xx/core/freertos/inc/queue.h
new file mode 100644
index 0000000..214ee9c
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/queue.h
@@ -0,0 +1,1261 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+ *
+ xQueueHandle xQueueCreate(
+ unsigned portBASE_TYPE uxQueueLength,
+ unsigned portBASE_TYPE uxItemSize
+ );
+ *
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueCreate xQueueCreate
+ * \ingroup QueueManagement
+ */
+xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueSendToToFront(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ );
+ *
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueSendToBack(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ );
+ *
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueSend(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ );
+ *
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )
+
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueGenericSend(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ portBASE_TYPE xCopyPosition
+ );
+ *
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueuePeek(
+ xQueueHandle xQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait
+ );
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueReceive(
+ xQueueHandle xQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait
+ );
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )
+
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueGenericReceive(
+ xQueueHandle xQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait
+ portBASE_TYPE xJustPeek
+ );
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek );
+
+/**
+ * queue. h
+ * unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
+ *
+ * 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
+ * void vQueueDelete( xQueueHandle xQueue );
+ *
+ * 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
+ *
+ portBASE_TYPE xQueueSendToFrontFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken
+ );
+
+ *
+ * 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):
+
+ 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 ();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_FRONT )
+
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueSendToBackFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken
+ );
+
+ *
+ * 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):
+
+ 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 ();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueSendFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken
+ );
+
+ *
+ * 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):
+
+ 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 ();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueGenericSendFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE *pxHigherPriorityTaskWoken,
+ portBASE_TYPE xCopyPosition
+ );
+
+ *
+ * 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):
+
+ 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();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition );
+
+/**
+ * queue. h
+ *
+ portBASE_TYPE xQueueReceiveFromISR(
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portBASE_TYPE *pxTaskWoken
+ );
+ *
+ *
+ * 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:
+
+
+ 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 ();
+ }
+ }
+
+ * \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/openbeacon/lpc13xx/core/freertos/inc/semphr.h b/openbeacon/lpc13xx/core/freertos/inc/semphr.h
new file mode 100644
index 0000000..fcc75c7
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/semphr.h
@@ -0,0 +1,711 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+ * vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+
+ * \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
+ * xSemaphoreTake(
+ * xSemaphoreHandle xSemaphore,
+ * portTickType xBlockTime
+ * )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+ }
+
+ * \defgroup xSemaphoreTake xSemaphoreTake
+ * \ingroup Semaphores
+ */
+#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
+
+/**
+ * semphr. h
+ * xSemaphoreTakeRecursive(
+ * xSemaphoreHandle xMutex,
+ * portTickType xBlockTime
+ * )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+ }
+
+ * \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
+ * xSemaphoreGive( xSemaphoreHandle xSemaphore )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+ }
+ }
+
+ * \defgroup xSemaphoreGive xSemaphoreGive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+ }
+
+ * \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
+ *
+ xSemaphoreGiveFromISR(
+ xSemaphoreHandle xSemaphore,
+ signed portBASE_TYPE *pxHigherPriorityTaskWoken
+ )
+ *
+ * Macro 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:
+
+ \#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.
+ }
+ }
+
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * xSemaphoreHandle xSemaphoreCreateMutex( void )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateMutex() xQueueCreateMutex()
+
+
+/**
+ * semphr. h
+ * xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
+
+/**
+ * semphr. h
+ * xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
+ * \ingroup Semaphores
+ */
+#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
+
+
+#endif /* SEMAPHORE_H */
+
+
diff --git a/openbeacon/lpc13xx/core/freertos/inc/task.h b/openbeacon/lpc13xx/core/freertos/inc/task.h
new file mode 100644
index 0000000..23beeb6
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/inc/task.h
@@ -0,0 +1,1279 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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.1.0"
+
+/**
+ * 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
+ *
+ portBASE_TYPE xTaskCreate(
+ pdTASK_CODE pvTaskCode,
+ const char * const pcName,
+ unsigned short usStackDepth,
+ void *pvParameters,
+ unsigned portBASE_TYPE uxPriority,
+ xTaskHandle *pvCreatedTask
+ );
+ *
+ * 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:
+
+ // 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 );
+ }
+
+ * \defgroup xTaskCreate xTaskCreate
+ * \ingroup Tasks
+ */
+#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )
+
+/**
+ * task. h
+ *
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );
+ *
+ * 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:
+
+// 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( ;; );
+}
+
+ * \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
+ *
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );
+ *
+ * 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:
+
+// 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).
+}
+
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted
+ * \ingroup Tasks
+ */
+void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskDelete( xTaskHandle pxTask );
+ *
+ * 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:
+
+ 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 );
+ }
+
+ * \defgroup vTaskDelete vTaskDelete
+ * \ingroup Tasks
+ */
+void vTaskDelete( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;
+
+
+/*-----------------------------------------------------------
+ * TASK CONTROL API
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * void vTaskDelay( portTickType xTicksToDelay );
+ *
+ * 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
+ * void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );
+ *
+ * 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:
+
+ // 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.
+ }
+ }
+
+ * \defgroup vTaskDelayUntil vTaskDelayUntil
+ * \ingroup TaskCtrl
+ */
+void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );
+ *
+ * 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:
+
+ 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.
+ }
+ }
+
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet
+ * \ingroup TaskCtrl
+ */
+unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );
+ *
+ * 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:
+
+ 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 );
+ }
+
+ * \defgroup vTaskPrioritySet vTaskPrioritySet
+ * \ingroup TaskCtrl
+ */
+void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskSuspend( xTaskHandle pxTaskToSuspend );
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup vTaskSuspend vTaskSuspend
+ * \ingroup TaskCtrl
+ */
+void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskResume( xTaskHandle pxTaskToResume );
+ *
+ * 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:
+
+ 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.
+ }
+
+ * \defgroup vTaskResume vTaskResume
+ * \ingroup TaskCtrl
+ */
+void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void xTaskResumeFromISR( xTaskHandle pxTaskToResume );
+ *
+ * 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
+ * void vTaskStartScheduler( void );
+ *
+ * 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:
+
+ 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 ()
+ }
+
+ *
+ * \defgroup vTaskStartScheduler vTaskStartScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskEndScheduler( void );
+ *
+ * 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:
+
+ 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.
+ }
+
+ *
+ * \defgroup vTaskEndScheduler vTaskEndScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskSuspendAll( void );
+ *
+ * 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:
+
+ 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 ();
+ }
+ }
+
+ * \defgroup vTaskSuspendAll vTaskSuspendAll
+ * \ingroup SchedulerControl
+ */
+void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * char xTaskResumeAll( void );
+ *
+ * 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:
+
+ 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 ();
+ }
+ }
+ }
+
+ * \defgroup xTaskResumeAll xTaskResumeAll
+ * \ingroup SchedulerControl
+ */
+signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );
+ *
+ * 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
+ * portTickType xTaskGetTickCount( void );
+ *
+ * @return The count of ticks since vTaskStartScheduler was called.
+ *
+ * \page xTaskGetTickCount xTaskGetTickCount
+ * \ingroup TaskUtils
+ */
+portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * portTickType xTaskGetTickCountFromISR( void );
+ *
+ * @return The count of ticks since vTaskStartScheduler was called.
+ *
+ * This is a version of xTaskGetTickCount() that is safe to be called from an
+ * ISR - provided that portTickType is the natural word size of the
+ * microcontroller being used or interrupt nesting is either not supported or
+ * not being used.
+ *
+ * \page xTaskGetTickCount xTaskGetTickCount
+ * \ingroup TaskUtils
+ */
+portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * unsigned short uxTaskGetNumberOfTasks( void );
+ *
+ * @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
+ * void vTaskList( char *pcWriteBuffer );
+ *
+ * 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
+ * void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ *
+ * 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
+ * void vTaskStartTrace( char * pcBuffer, unsigned portBASE_TYPE uxBufferSize );
+ *
+ * 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
+ * unsigned long ulTaskEndTrace( void );
+ *
+ * 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
+ * unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
+ *
+ * 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
+ * void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ *
+ * 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
+ * void xTaskGetApplicationTaskTag( xTaskHandle xTask );
+ *
+ * Returns the pxHookFunction value assigned to the task xTask.
+ */
+pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION;
+
+/**
+ * task.h
+ * portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ *
+ * 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/openbeacon/lpc13xx/core/freertos/src/heap_2.c b/openbeacon/lpc13xx/core/freertos/src/heap_2.c
new file mode 100644
index 0000000..24b2297
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/src/heap_2.c
@@ -0,0 +1,283 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+
+/* 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
+#ifdef ENABLE_FREERTOS
+/*-----------------------------------------------------------*/
+
+#include
+
+#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 -= pxBlock->xBlockSize;
+ }
+ }
+ }
+ 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. */
+}
+
+#endif /* ENABLE_FREERTOS */
\ No newline at end of file
diff --git a/openbeacon/lpc13xx/core/freertos/src/list.c b/openbeacon/lpc13xx/core/freertos/src/list.c
new file mode 100644
index 0000000..bf65620
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/src/list.c
@@ -0,0 +1,193 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+#include
+#ifdef ENABLE_FREERTOS
+/*-----------------------------------------------------------*/
+#include
+
+/*-----------------------------------------------------------
+ * 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 )--;
+}
+/*-----------------------------------------------------------*/
+#endif /* ENABLE_FREERTOS */
diff --git a/openbeacon/lpc13xx/core/freertos/src/port.c b/openbeacon/lpc13xx/core/freertos/src/port.c
new file mode 100644
index 0000000..82e8f5e
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/src/port.c
@@ -0,0 +1,292 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+#ifdef ENABLE_FREERTOS
+/*-----------------------------------------------------------*/
+#include
+
+/* 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 ));
+
+/*
+ * Tap into existing exceptino table
+ */
+void SVCall_Handler (void) __attribute__ ((alias ("vPortSVCHandler")));
+void PendSV_Handler (void) __attribute__ ((alias ("xPortPendSVHandler")));
+void SysTick_Handler (void) __attribute__ ((alias ("xPortSysTickHandler")));
+
+/*
+ * 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;
+}
+
+/*-----------------------------------------------------------*/
+#endif /* ENABLE_FREERTOS */
+/*-----------------------------------------------------------*/
diff --git a/openbeacon/lpc13xx/core/freertos/src/queue.c b/openbeacon/lpc13xx/core/freertos/src/queue.c
new file mode 100644
index 0000000..0b875f9
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/src/queue.c
@@ -0,0 +1,1632 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+#include
+
+/* 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
+#ifdef ENABLE_FREERTOS
+/*-----------------------------------------------------------*/
+#include
+#include
+
+#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
+
+/*-----------------------------------------------------------*/
+#endif /* ENABLE_FREERTOS */
+/*-----------------------------------------------------------*/
diff --git a/openbeacon/lpc13xx/core/freertos/src/tasks.c b/openbeacon/lpc13xx/core/freertos/src/tasks.c
new file mode 100644
index 0000000..ad5572f
--- /dev/null
+++ b/openbeacon/lpc13xx/core/freertos/src/tasks.c
@@ -0,0 +1,2347 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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
+#include
+#include
+
+/* 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
+#ifdef ENABLE_FREERTOS
+/*-----------------------------------------------------------*/
+#include
+#include
+
+#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
+
+ 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;
+ }
+
+ /* 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( pxCurrentTCB == NULL )
+ {
+ /* There are no other tasks, or all the other tasks are in
+ the suspended state - make this the current task. */
+ pxCurrentTCB = pxNewTCB;
+
+ if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 )
+ {
+ /* 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( 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();
+
+ if( ( void * ) pxTaskToSuspend == NULL )
+ {
+ if( xSchedulerRunning != pdFALSE )
+ {
+ /* We have just suspended the current task. */
+ portYIELD_WITHIN_API();
+ }
+ else
+ {
+ /* The scheduler is not running, but the task that was pointed
+ to by pxCurrentTCB has just been suspended and pxCurrentTCB
+ must be adjusted to point to a different task. */
+ if( uxCurrentNumberOfTasks == 1 )
+ {
+ /* No other tasks are defined, so set pxCurrentTCB back to
+ NULL so when the next task is created pxCurrentTCB will
+ be set to point to it no matter what its relative priority
+ is. */
+ pxCurrentTCB = NULL;
+ }
+ else
+ {
+ vTaskSwitchContext();
+ }
+ }
+ }
+ }
+
+#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;
+}
+/*-----------------------------------------------------------*/
+
+portTickType xTaskGetTickCountFromISR( void )
+{
+ return xTickCount;
+}
+/*-----------------------------------------------------------*/
+
+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
+/*-----------------------------------------------------------*/
+#endif /* ENABLE_FREERTOS */
+/*-----------------------------------------------------------*/
+
diff --git a/openbeacon/lpc13xx/core/linker/LPC1342.ld b/openbeacon/lpc13xx/core/linker/LPC1342.ld
new file mode 100644
index 0000000..7c92f4b
--- /dev/null
+++ b/openbeacon/lpc13xx/core/linker/LPC1342.ld
@@ -0,0 +1,9 @@
+MEMORY
+{
+ flash : ORIGIN = 0x00000000, LENGTH = 16K
+ ram : ORIGIN = 0x10000180, LENGTH = 4K - 0x180
+}
+
+__stack_end__ = 0x10000000 + 4K - 32;
+
+INCLUDE "../core/linker/LPC13xx.ld"
\ No newline at end of file
diff --git a/openbeacon/lpc13xx/core/linker/LPC1343.ld b/openbeacon/lpc13xx/core/linker/LPC1343.ld
new file mode 100644
index 0000000..5b9ff6c
--- /dev/null
+++ b/openbeacon/lpc13xx/core/linker/LPC1343.ld
@@ -0,0 +1,9 @@
+MEMORY
+{
+ flash : ORIGIN = 0x00000000, LENGTH = 32K
+ ram : ORIGIN = 0x10000180, LENGTH = 8K - 0x180
+}
+
+__stack_end__ = 0x10000000 + 8K - 32;
+
+INCLUDE "../core/linker/LPC13xx.ld"
\ No newline at end of file
diff --git a/openbeacon/lpc13xx/core/linker/LPC13xx.ld b/openbeacon/lpc13xx/core/linker/LPC13xx.ld
new file mode 100644
index 0000000..bcdca70
--- /dev/null
+++ b/openbeacon/lpc13xx/core/linker/LPC13xx.ld
@@ -0,0 +1,55 @@
+ENTRY(ResetISR)
+
+SECTIONS
+{
+ . = 0;
+ startup : { *(.startup)} >flash
+
+ prog :
+ {
+ KEEP(*(.isr_vector))
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata*)
+ *(.glue_7)
+ *(.glue_7t)
+ } >flash
+
+ __end_of_text__ = .;
+
+ .data :
+ {
+ __data_beg__ = .;
+ __data_beg_src__ = __end_of_text__;
+ *(.data)
+ *(.data.*)
+ *(.fastrun)
+ *(.ramfunc)
+ __data_end__ = .;
+ } >ram AT>flash
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } >ram AT>flash
+ __exidx_end = .;
+
+ .bss :
+ {
+ __bss_beg__ = .;
+ *(.bss)
+ *(.bss.*)
+ __bss_end__ = .;
+ } >ram
+
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+}
+ . = ALIGN(32 / 8);
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/crc16.h b/openbeacon/lpc13xx/core/openbeacon/inc/crc16.h
new file mode 100644
index 0000000..7b0d1d8
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/crc16.h
@@ -0,0 +1,29 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - CRC16 routine
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __CRC16_H__
+#define __CRC16_H__
+
+extern uint16_t crc16 (const uint8_t *buffer, uint32_t size);
+
+#endif/*__CRC16_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/debug_printf.h b/openbeacon/lpc13xx/core/openbeacon/inc/debug_printf.h
new file mode 100644
index 0000000..3d52345
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/debug_printf.h
@@ -0,0 +1,20 @@
+/*
+ * linux/lib/vsprintf.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
+/*
+ * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ */
+
+#ifndef __DEBUG_PRINTF_H__
+#define __DEBUG_PRINTF_H__
+#ifdef UART_DISABLE
+#define debug_printf(...)
+#else /*UART_DISABLE*/
+extern void debug_printf (const char *fmt, ...);
+extern void hex_dump (const unsigned char *buf, unsigned int addr, unsigned int len);
+#endif/*UART_DISABLE*/
+#endif/*__DEBUG_PRINTF_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/hid.h b/openbeacon/lpc13xx/core/openbeacon/inc/hid.h
new file mode 100644
index 0000000..ef2c48b
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/hid.h
@@ -0,0 +1,30 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - HID ROM function code for LPC13xx
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef __HID_H__
+#define __HID_H__
+
+extern void hid_init (void);
+extern void GetInReport (uint8_t *src, uint32_t length);
+extern void SetOutReport (uint8_t *dst, uint32_t length);
+
+#endif/*__HID_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/iap.h b/openbeacon/lpc13xx/core/openbeacon/inc/iap.h
new file mode 100644
index 0000000..6143265
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/iap.h
@@ -0,0 +1,32 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - IAP - in application programming
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __IAP_H__
+#define __IAP_H__
+
+typedef uint32_t TDeviceUID[4];
+
+extern void iap_read_uid (TDeviceUID * uid);
+extern void iap_invoke_isp (void);
+
+#endif/*__IAP_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/msd.h b/openbeacon/lpc13xx/core/openbeacon/inc/msd.h
new file mode 100644
index 0000000..631d95f
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/msd.h
@@ -0,0 +1,52 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - MSD ROM function code for LPC13xx
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef __MSD_H__
+#define __MSD_H__
+
+/***************************************************************
+ * bytes per sector
+ ***************************************************************/
+#define DISK_BLOCK_SIZE 512UL
+
+/***************************************************************
+ * disk geometry - make it small enough
+ * to allow FAT16 with 512 byte cluster size
+ ***************************************************************/
+#define DISK_CYLINDERS 31UL
+#define DISK_HEADS 255UL
+#define DISK_SECTORS_PER_TRACK 63UL
+
+/***************************************************************
+ * derieved values
+ ***************************************************************/
+#define DISK_SECTORS (DISK_CYLINDERS*DISK_HEADS*DISK_SECTORS_PER_TRACK)
+#define DISK_SIZE (DISK_SECTORS*DISK_BLOCK_SIZE)
+
+/***************************************************************
+ * exported functions
+ ***************************************************************/
+extern void msd_init (void);
+extern void msd_read (uint32_t offset, uint8_t *dst, uint32_t length);
+extern void msd_write (uint32_t offset, uint8_t *src, uint32_t length);
+
+#endif/*__MSD_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/openbeacon.h b/openbeacon/lpc13xx/core/openbeacon/inc/openbeacon.h
new file mode 100644
index 0000000..230352c
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/openbeacon.h
@@ -0,0 +1,113 @@
+#ifndef __OPENBEACON_H__
+#define __OPENBEACON_H__
+
+#include
+#include
+#include
+
+#define PACKED __attribute__((packed))
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+typedef uint8_t BOOL;
+#define TRUE 1
+#define FALSE 0
+
+/* this definition is linked weakly against UARTSendChar */
+extern BOOL default_putchar (uint8_t data);
+
+#ifdef ENABLE_FREERTOS
+#include
+#include
+#include
+#endif/*ENABLE_FREERTOS*/
+
+#ifdef __LPC13xx__
+
+#include
+#include
+#ifdef ENALBLE_USB_FULLFEATURED
+#include
+#include
+#include
+#include
+#include
+#include
+#else /*ENALBLE_USB_FULLFEATURED*/
+#include
+#include
+#include
+#endif/*ENALBLE_USB_FULLFEATURED*/
+#include
+
+/* PDSLEEPCFG, PDAWAKECFG, PDRUNCFG */
+#define IRCOUT_PD (1<< 0)
+#define IRC_PD (1<< 1)
+#define FLASH_PD (1<< 2)
+#define BOD_PD (1<< 3)
+#define ADC_PD (1<< 4)
+#define SYSOSC_PD (1<< 5)
+#define WDTOSC_PD (1<< 6)
+#define SYSPLL_PD (1<< 7)
+#define USBPLL_PD (1<< 8)
+#define RESERVED1_PD (1<< 9)
+#define USBPAD_PD (1<<10)
+#define RESERVED2_PD (1<<11)
+
+/* LPC_SYSCON->SYSAHBCLKCTRL bits */
+#define EN_SYS (1<< 0)
+#define EN_ROM (1<< 1)
+#define EN_RAM (1<< 2)
+#define EN_FLASHREG (1<< 3)
+#define EN_FLASHARRAY (1<< 4)
+#define EN_I2C (1<< 5)
+#define EN_GPIO (1<< 6)
+#define EN_CT16B0 (1<< 7)
+#define EN_CT16B1 (1<< 8)
+#define EN_CT32B0 (1<< 9)
+#define EN_CT32B1 (1<<10)
+#define EN_SSP (1<<11)
+#define EN_UART (1<<12)
+#define EN_ADC (1<<13)
+#define EN_USB_REG (1<<14)
+#define EN_WDT (1<<15)
+#define EN_IOCON (1<<16)
+
+#ifdef __LPC1343__
+#define LPC_RAM_SIZE (8*1024)
+#define LPC_FLASH_SIZE (32*1024)
+#endif/*__LPC1343__*/
+#ifdef __LPC1342__
+#define LPC_RAM_SIZE (4*1024)
+#define LPC_FLASH_SIZE (16*1024)
+#endif/*__LPC1342__*/
+
+#else /*__LPC13xx__*/
+#error Please specify architecture
+#endif/*__LPC13xx__*/
+
+#define DEVICEID_LPC1311 0x2C42502BUL
+#define DEVICEID_LPC1313 0x2C40102BUL
+#define DEVICEID_LPC1342 0x3D01402BUL
+#define DEVICEID_LPC1343 0x3D00002BUL
+
+#include
+#include
+#include
+
+static inline uint16_t htons(uint16_t x)
+{
+ __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+
+static inline uint32_t htonl(uint32_t x)
+{
+ __asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+
+#define ntohl(l) htonl(l)
+#define ntohs(s) htons(s)
+
+#endif/*__OPENBEACON_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/spi.h b/openbeacon/lpc13xx/core/openbeacon/inc/spi.h
new file mode 100644
index 0000000..f74a577
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/spi.h
@@ -0,0 +1,43 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - SPI routines for LPC13xx
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef __SPI_H__
+#define __SPI_H__
+
+typedef uint32_t spi_cs;
+
+#define SPI_CS_MODE_NORMAL 0
+#define SPI_CS_MODE_INVERT_CS 1
+#define SPI_CS_MODE_BIT_REVERSED 2
+#define SPI_CS_MODE_SKIP_TX 4
+#define SPI_CS_MODE_SKIP_CS_ASSERT 8
+#define SPI_CS_MODE_SKIP_CS_DEASSERT 0x10
+#define SPI_CS_MODE_SKIP_CS (SPI_CS_MODE_SKIP_CS_ASSERT|SPI_CS_MODE_SKIP_CS_DEASSERT)
+#define SPI_CS(port,pin,CPSDVSR,mode) ((spi_cs)( ((((uint32_t)port)&0xFF)<<24) | ((((uint32_t)pin)&0xFF)<<16) | ((((uint32_t)CPSDVSR)&0xFF)<<8) | (((uint32_t)mode)&0xFF) ))
+
+extern void spi_init (void);
+extern void spi_status (void);
+extern void spi_init_pin (spi_cs chipselect);
+extern int spi_txrx (spi_cs chipselect, const void *tx, uint16_t txlen,
+ void *rx, uint16_t rxlen);
+
+#endif/*__SPI_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/vfs.h b/openbeacon/lpc13xx/core/openbeacon/inc/vfs.h
new file mode 100644
index 0000000..a83103d
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/vfs.h
@@ -0,0 +1,70 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - virtual FAT16 file system support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __VFS_H__
+#define __VFS_H__
+
+typedef void (*TDiskHandler) (uint32_t offset, uint32_t length,
+ const void *src, uint8_t * dst);
+
+typedef struct _TDiskFile
+{
+ uint32_t length;
+ TDiskHandler handler;
+ const void *data;
+ const char *name;
+ const struct _TDiskFile *next;
+} TDiskFile;
+
+typedef struct
+{
+ uint8_t BS_jmpBoot[3];
+ char BS_OEMName[8];
+ uint16_t BPB_BytsPerSec;
+ uint8_t BPB_SecPerClus;
+ uint16_t BPB_RsvdSecCnt;
+ uint8_t BPB_NumFATs;
+ uint16_t BPB_RootEntCnt;
+ uint16_t BPB_TotSec16;
+ uint8_t BPB_Media;
+ uint16_t BPB_FATSz16;
+ uint16_t BPB_SecPerTrk;
+ uint16_t BPB_NumHeads;
+ uint32_t BPB_HiddSec;
+ uint32_t BPB_TotSec32;
+ /* FAT12/FAT16 definition */
+ uint8_t BS_DrvNum;
+ uint8_t BS_Reserved1;
+ uint8_t BS_BootSig;
+ uint32_t BS_VolID;
+ char BS_VolLab[11];
+ char BS_FilSysType[8];
+} PACKED TDiskBPB;
+
+extern const TDiskBPB DiskBPB;
+extern const uint32_t DiskSignature;
+
+extern void vfs_init (const TDiskFile *file);
+extern void vfs_status (void);
+
+#endif/*__VFS_H__*/
diff --git a/openbeacon/lpc13xx/core/openbeacon/inc/xxtea.h b/openbeacon/lpc13xx/core/openbeacon/inc/xxtea.h
new file mode 100644
index 0000000..96a54ca
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/inc/xxtea.h
@@ -0,0 +1,37 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - XXTEA based block encryption
+ *
+ * based on "correction to XTEA" by David J. Wheeler and
+ * Roger M. Needham.
+ * Computer Laboratory - Cambridge University in 1998
+ *
+ * Copyright 2006 Milosch Meriac
+ *
+ * ripped into pieces - optimized for the special case
+ * where 16 bytes are regarded for encryption and decryption
+ * to increase speed and to decrease memory consumption
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __XXTEA_H__
+#define __XXTEA_H__
+
+extern void xxtea_decode (uint32_t * v, uint32_t length, const uint32_t * tea_key);
+extern void xxtea_encode (uint32_t * v, uint32_t length, const uint32_t * tea_key);
+
+#endif/*__XXTEA_H__*/
\ No newline at end of file
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/crc16.c b/openbeacon/lpc13xx/core/openbeacon/src/crc16.c
new file mode 100644
index 0000000..44f2ba0
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/crc16.c
@@ -0,0 +1,43 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - CRC16 routine
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#include
+#include "crc16.h"
+
+uint16_t
+crc16 (const uint8_t *buffer, uint32_t size)
+{
+ uint16_t crc = 0xFFFF;
+
+ if (buffer && size)
+ while (size--)
+ {
+ crc = (crc >> 8) | (crc << 8);
+ crc ^= *buffer++;
+ crc ^= ((unsigned char) crc) >> 4;
+ crc ^= crc << 12;
+ crc ^= (crc & 0xFF) << 5;
+ }
+
+ return crc;
+}
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/debug_printf.c b/openbeacon/lpc13xx/core/openbeacon/src/debug_printf.c
new file mode 100644
index 0000000..51f1c4e
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/debug_printf.c
@@ -0,0 +1,367 @@
+/*
+ * linux/lib/vsprintf.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
+/*
+ * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ */
+
+#include
+#ifndef UART_DISABLE
+#include
+#include
+#include
+#include
+#include
+
+unsigned long
+simple_strtoul (const char *cp, char **endp, unsigned int base)
+{
+ unsigned long result = 0, value;
+
+ if (*cp == '0')
+ {
+ cp++;
+ if ((*cp == 'x') && isxdigit ((int)cp[1]))
+ {
+ base = 16;
+ cp++;
+ }
+ if (!base)
+ {
+ base = 8;
+ }
+ }
+ if (!base)
+ {
+ base = 10;
+ }
+ while (isxdigit ((int)*cp) && (value = isdigit ((int)*cp) ? *cp - '0' : (islower ((int)*cp)
+ ?
+ toupper ((int)*cp)
+ : *cp) -
+ 'A' + 10) < base)
+ {
+ result = result * base + value;
+ cp++;
+ }
+ if (endp)
+ *endp = (char *) cp;
+ return result;
+}
+
+long
+simple_strtol (const char *cp, char **endp, unsigned int base)
+{
+ if (*cp == '-')
+ return -simple_strtoul (cp + 1, endp, base);
+ return simple_strtoul (cp, endp, base);
+}
+
+/* we use this so that we can do without the ctype library */
+#define is_digit(c) ((c) >= '0' && (c) <= '9')
+
+static int
+skip_atoi (const char **s)
+{
+ int i = 0;
+
+ while (is_digit (**s))
+ i = i * 10 + *((*s)++) - '0';
+ return i;
+}
+
+#define ZEROPAD 1 /* pad with zero */
+#define SIGN 2 /* unsigned/signed long */
+#define PLUS 4 /* show plus */
+#define SPACE 8 /* space if plus */
+#define LEFT 16 /* left justified */
+#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
+
+#define do_div(n,base) ({ \
+ int __res; \
+ __res = ((unsigned long) n) % base; \
+ n = ((unsigned long) n) / base; \
+ __res; \
+})
+
+static void
+number (long num, unsigned int base, int size, int precision,
+ int type)
+{
+ char c, sign;
+ static char tmp[66];
+
+ const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+ int i;
+
+ if (type & LARGE)
+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ if (type & LEFT)
+ type &= ~ZEROPAD;
+ if (base < 2 || base > 36)
+ return;
+ c = (type & ZEROPAD) ? '0' : ' ';
+ sign = 0;
+ if (type & SIGN)
+ {
+ if (num < 0)
+ {
+ sign = '-';
+ num = -num;
+ size--;
+ }
+ else if (type & PLUS)
+ {
+ sign = '+';
+ size--;
+ }
+ else if (type & SPACE)
+ {
+ sign = ' ';
+ size--;
+ }
+ }
+ i = 0;
+ if (num == 0)
+ tmp[i++] = '0';
+ else
+ while (num != 0)
+ tmp[i++] = digits[do_div (num, base)];
+ if (i > precision)
+ precision = i;
+ size -= precision;
+ if (!(type & (ZEROPAD + LEFT)))
+ while (size-- > 0)
+ default_putchar(' ');
+ if (sign)
+ default_putchar(sign);
+ if (!(type & LEFT))
+ while (size-- > 0)
+ default_putchar(c);
+ while (i < precision--)
+ default_putchar('0');
+ while (i-- > 0)
+ default_putchar(tmp[i]);
+ while (size-- > 0)
+ default_putchar(' ');
+}
+
+static void
+tiny_vsprintf (const char *fmt, va_list args)
+{
+ int len;
+ unsigned long num;
+ int i, base;
+ const char *s;
+
+ int flags; /* flags to number() */
+
+ int field_width; /* width of output field */
+ int precision; /* min. # of digits for integers; max
+ number of chars for from string */
+ int qualifier; /* 'h', 'l', or 'q' for integer fields */
+
+ for (; *fmt; ++fmt)
+ {
+ if (*fmt != '%')
+ {
+ if(*fmt=='\n')
+ default_putchar('\r');
+ default_putchar(*fmt);
+ continue;
+ }
+
+ /* process flags */
+ flags = 0;
+ repeat:
+ ++fmt; /* this also skips first '%' */
+ switch (*fmt)
+ {
+ case '-':
+ flags |= LEFT;
+ goto repeat;
+ case '+':
+ flags |= PLUS;
+ goto repeat;
+ case ' ':
+ flags |= SPACE;
+ goto repeat;
+ case '0':
+ flags |= ZEROPAD;
+ goto repeat;
+ }
+
+ /* get field width */
+ field_width = -1;
+ if (is_digit (*fmt))
+ field_width = skip_atoi (&fmt);
+ else if (*fmt == '*')
+ {
+ ++fmt;
+ /* it's the next argument */
+ field_width = va_arg (args, int);
+ if (field_width < 0)
+ {
+ field_width = -field_width;
+ flags |= LEFT;
+ }
+ }
+
+ /* get the precision */
+ precision = -1;
+ if (*fmt == '.')
+ {
+ ++fmt;
+ if (is_digit (*fmt))
+ precision = skip_atoi (&fmt);
+ else if (*fmt == '*')
+ {
+ ++fmt;
+ /* it's the next argument */
+ precision = va_arg (args, int);
+ }
+ if (precision < 0)
+ precision = 0;
+ }
+
+ /* get the conversion qualifier */
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
+ *fmt == 'Z' || *fmt == 'z' || *fmt == 't' || *fmt == 'q')
+ {
+ qualifier = *fmt;
+ if (qualifier == 'l' && *(fmt + 1) == 'l')
+ {
+ qualifier = 'q';
+ ++fmt;
+ }
+ ++fmt;
+ }
+
+ /* default base */
+ base = 10;
+
+ switch (*fmt)
+ {
+ case 'c':
+ if (!(flags & LEFT))
+ while (--field_width > 0)
+ default_putchar(' ');
+ default_putchar((unsigned char) va_arg (args, int));
+ while (--field_width > 0)
+ default_putchar(' ');
+ continue;
+
+ case 's':
+ s = va_arg (args, char *);
+ if (!s)
+ s = "";
+
+ len = strnlen (s, precision);
+
+ if (!(flags & LEFT))
+ while (len < field_width--)
+ default_putchar(' ');
+ for (i = 0; i < len; ++i)
+ default_putchar(*s++);
+ while (len < field_width--)
+ default_putchar(' ');
+ continue;
+
+ case '%':
+ default_putchar('%');
+ continue;
+
+ /* integer number formats - set up the flags and "break" */
+ case 'o':
+ base = 8;
+ break;
+
+ case 'X':
+ flags |= LARGE;
+ case 'x':
+ base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+ flags |= SIGN;
+ case 'u':
+ break;
+
+ default:
+ default_putchar('%');
+ if (*fmt)
+ default_putchar(*fmt);
+ else
+ --fmt;
+ continue;
+ }
+
+ if (qualifier == 'l')
+ {
+ num = va_arg (args, unsigned long);
+ }
+ else if (qualifier == 'Z' || qualifier == 'z')
+ {
+ num = va_arg (args, size_t);
+ }
+ else if (qualifier == 'h')
+ {
+ num = (unsigned short) va_arg (args, int);
+ if (flags & SIGN)
+ num = (short) num;
+ }
+ else if (flags & SIGN)
+ num = va_arg (args, int);
+ else
+ num = va_arg (args, unsigned int);
+ number (num, base, field_width, precision, flags);
+ }
+}
+
+void
+debug_printf (const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ tiny_vsprintf (fmt, args);
+ va_end (args);
+}
+
+void hex_dump (const unsigned char *buf, unsigned int addr, unsigned int len)
+{
+ unsigned int start, i, j;
+ char c;
+
+ start = addr & ~0xf;
+
+ for (j=0; j= addr && start+i+j < addr+len)
+ debug_printf(" %02x", buf[start+i+j]);
+ else
+ debug_printf(" ");
+ }
+ debug_printf(" |");
+ for (i=0; i<16; i++) {
+ if (start+i+j >= addr && start+i+j < addr+len) {
+ c = buf[start+i+j];
+ if (c >= ' ' && c < 127)
+ debug_printf("%c", c);
+ else
+ debug_printf(".");
+ } else
+ debug_printf(" ");
+ }
+ debug_printf("|\n\r");
+ }
+}
+#endif /* UART_DISABLE */
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/hid.c b/openbeacon/lpc13xx/core/openbeacon/src/hid.c
new file mode 100644
index 0000000..6e8dc18
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/hid.c
@@ -0,0 +1,112 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - HID ROM function code for LPC13xx
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#include
+#include "hid.h"
+
+#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0)
+
+#define EN_TIMER32_1 (1<<10)
+#define EN_IOCON (1<<16)
+#define EN_USBREG (1<<14)
+
+static ROM **rom = (ROM **) 0x1fff1ff8;
+
+void
+USB_IRQHandler (void)
+{
+ (*rom)->pUSBD->isr ();
+}
+
+/* USB String Descriptor (optional) */
+const uint8_t USB_StringDescriptor[] = {
+ /* Index 0x00: LANGID Codes */
+ 0x04, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL (0x0409), /* US English - wLANGID */
+ /* Index 0x04: Manufacturer */
+ 0x1C, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'B', 0, 'i', 0, 't', 0, 'm', 0, 'a', 0, 'n', 0, 'u', 0, 'f', 0,
+ 'a', 0, 'k', 0, 't', 0, 'u', 0, 'r', 0,
+ /* Index 0x20: Product */
+ 0x28, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'O', 0, 'p', 0, 'e', 0, 'n', 0, 'B', 0, 'e', 0, 'a', 0, 'c', 0,
+ 'o', 0, 'n', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'I', 0,
+ 'I', 0, ' ', 0, ' ', 0,
+ /* Index 0x48: Serial Number */
+ 0x1A, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
+ '0', 0, '0', 0, '0', 0, '0', 0,
+ /* Index 0x62: Interface 0, Alternate Setting 0 */
+ 0x0E, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'H', 0, 'I', 0, 'D', 0, ' ', 0, ' ', 0, ' ', 0,
+};
+
+void
+hid_init (void)
+{
+ volatile int i;
+
+ /* Setup ROM initialization structure */
+ static const HID_DEVICE_INFO HidDevInfo = {
+ .idVendor = USB_VENDOR_ID,
+ .idProduct = USB_PROD_ID,
+ .bcdDevice = USB_DEVICE,
+ .StrDescPtr = (uint32_t) & USB_StringDescriptor[0],
+ .InReportCount = USB_HID_IN_REPORT_SIZE,
+ .OutReportCount = USB_HID_OUT_REPORT_SIZE,
+ .SampleInterval = 0x20,
+ .InReport = GetInReport,
+ .OutReport = SetOutReport
+ };
+
+ /* Point DeviceInfo to HidDevInfo */
+ static const USB_DEV_INFO DeviceInfo = {
+ .DevType = USB_DEVICE_CLASS_HUMAN_INTERFACE,
+ .DevDetailPtr = (uint32_t) & HidDevInfo
+ };
+
+ /* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);
+
+ /* Use pll and pin init function in rom */
+ (*rom)->pUSBD->init_clk_pins ();
+ /* fixing NXP stupidity - they break system clock */
+ SystemCoreClockUpdate ();
+
+ /* insert delay between init_clk_pins() and usb init */
+ for (i = 0; i < 75; i++);
+
+ /* USB Initialization ... */
+ (*rom)->pUSBD->init (&DeviceInfo);
+
+ /* ... and USB Connect */
+ (*rom)->pUSBD->connect (1);
+
+}
+
+#endif /* (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0) */
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/iap.c b/openbeacon/lpc13xx/core/openbeacon/src/iap.c
new file mode 100644
index 0000000..b28e3a8
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/iap.c
@@ -0,0 +1,45 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - IAP - in application programming
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#include
+#include "iap.h"
+
+typedef void (*IAP_FUNC) (const uint32_t * cmd, uint32_t * result);
+
+static const IAP_FUNC iap = (IAP_FUNC) 0x1fff1ff1;
+
+void
+iap_invoke_isp (void)
+{
+ static const uint32_t cmd = 57;
+
+ (*iap) (&cmd, NULL);
+}
+
+void
+iap_read_uid (TDeviceUID * uid)
+{
+ static const uint32_t cmd = 58;
+
+ (*iap) (&cmd, (uint32_t *) uid);
+}
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/msd.c b/openbeacon/lpc13xx/core/openbeacon/src/msd.c
new file mode 100644
index 0000000..b0cba17
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/msd.c
@@ -0,0 +1,117 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - HID ROM function code for LPC13xx
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#include
+#include "msd.h"
+
+#ifdef USB_DISK_SUPPORT
+
+#define EN_TIMER32_1 (1<<10)
+#define EN_IOCON (1<<16)
+#define EN_USBREG (1<<14)
+
+static ROM **rom = (ROM **) 0x1fff1ff8;
+
+void
+USB_IRQHandler (void)
+{
+ (*rom)->pUSBD->isr ();
+}
+
+/* USB String Descriptor (optional) */
+const uint8_t USB_StringDescriptor[] = {
+ /* Index 0x00: LANGID Codes */
+ 0x04, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL (0x0409), /* US English - wLANGID */
+ /* Index 0x04: Manufacturer */
+ 0x1C, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'B', 0, 'i', 0, 't', 0, 'm', 0, 'a', 0, 'n', 0, 'u', 0, 'f', 0,
+ 'a', 0, 'k', 0, 't', 0, 'u', 0, 'r', 0,
+ /* Index 0x20: Product */
+ 0x28, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'O', 0, 'p', 0, 'e', 0, 'n', 0, 'B', 0, 'e', 0, 'a', 0, 'c', 0,
+ 'o', 0, 'n', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'I', 0,
+ 'I', 0, ' ', 0, ' ', 0,
+ /* Index 0x48: Serial Number */
+ 0x1A, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
+ '0', 0, '0', 0, '0', 0, '0', 0,
+ /* Index 0x62: Interface 0, Alternate Setting 0 */
+ 0x0E, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'M', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0,
+};
+
+void
+msd_init (void)
+{
+ volatile int i;
+
+ /* 28 byte long SCSI inquiry string */
+ static const uint8_t SCSI_Inquiry_String[28] =
+ "Logfile OpenBeacon Tag 2.0a";
+
+ /* Setup ROM initialization structure */
+ static const MSC_DEVICE_INFO MscDevInfo = {
+ .idVendor = USB_VENDOR_ID,
+ .idProduct = USB_PROD_ID,
+ .bcdDevice = USB_DEVICE,
+ .StrDescPtr = (uint32_t) & USB_StringDescriptor[0],
+ .MSCInquiryStr = (uint32_t) & SCSI_Inquiry_String,
+ .BlockSize = DISK_BLOCK_SIZE,
+ .BlockCount = DISK_SECTORS,
+ .MemorySize = DISK_SIZE,
+ .MSC_Read = msd_read,
+ .MSC_Write = msd_write
+ };
+
+ /* Point DeviceInfo to MscDevInfo */
+ static const USB_DEV_INFO DeviceInfo = {
+ .DevType = USB_DEVICE_CLASS_STORAGE,
+ .DevDetailPtr = (uint32_t) & MscDevInfo
+ };
+
+ /* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);
+
+ /* Use pll and pin init function in rom */
+ (*rom)->pUSBD->init_clk_pins ();
+ /* fixing NXP stupidity - they break system clock */
+ SystemCoreClockUpdate ();
+
+ /* insert delay between init_clk_pins() and usb init */
+ for (i = 0; i < 75; i++);
+
+ /* USB Initialization ... */
+ (*rom)->pUSBD->init (&DeviceInfo);
+ /* Initialize Storage */
+ init_msdstate ();
+ /* ... and USB Connect */
+ (*rom)->pUSBD->connect (1);
+}
+
+#endif /* USB_DISK_SUPPORT */
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/spi.c b/openbeacon/lpc13xx/core/openbeacon/src/spi.c
new file mode 100644
index 0000000..9656378
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/spi.c
@@ -0,0 +1,128 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - SPI routines for LPC13xx
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "spi.h"
+
+#define BIT_REVERSE(x) ((unsigned char)(__RBIT(x)>>24))
+
+void spi_init_pin(spi_cs chipselect)
+{
+ GPIOSetDir((uint8_t) (chipselect >> 24), (uint8_t) (chipselect >> 16), 1);
+}
+
+int spi_txrx(spi_cs chipselect, const void *tx, uint16_t txlen, void *rx,
+ uint16_t rxlen)
+{
+ uint8_t data, status;
+ uint16_t total, xfered;
+
+ /* SSP0 Clock Prescale Register to SYSCLK/CPSDVSR */
+ LPC_SSP->CPSR = (chipselect >> 8) & 0xFF;
+
+ /* activate chip select */
+ if ((chipselect & SPI_CS_MODE_SKIP_CS_ASSERT) == 0)
+ GPIOSetValue((uint8_t) (chipselect >> 24),
+ (uint8_t) (chipselect >> 16), chipselect
+ & SPI_CS_MODE_INVERT_CS);
+
+ /* calculate SPI transaction size */
+ xfered = total = (chipselect & SPI_CS_MODE_SKIP_TX) ? rxlen + txlen
+ : (txlen >= rxlen) ? txlen : rxlen;
+
+ while (xfered)
+ {
+ status = (uint8_t) LPC_SSP->SR;
+
+ if (total && (status & 0x02))
+ {
+ total--;
+
+ if (txlen)
+ {
+ txlen--;
+ data = *((uint8_t *) tx);
+ tx = ((uint8_t *) tx) + 1;
+ if (chipselect & SPI_CS_MODE_BIT_REVERSED)
+ data = BIT_REVERSE (data);
+ }
+ else
+ data = 0;
+
+ LPC_SSP->DR = data;
+ }
+
+ if (status & 0x04)
+ {
+ data = LPC_SSP->DR;
+ xfered--;
+
+ /* skip txlen in output if SPI_CS_MODE_SKIP_TX */
+ if (rxlen && (xfered < rxlen))
+ {
+ rxlen--;
+ if (chipselect & SPI_CS_MODE_BIT_REVERSED)
+ data = BIT_REVERSE (data);
+ *((uint8_t *) rx) = data;
+ rx = ((uint8_t *) rx) + 1;
+ }
+ }
+ }
+
+ /* de-activate chip select */
+ if ((chipselect & SPI_CS_MODE_SKIP_CS_DEASSERT) == 0)
+ GPIOSetValue((uint8_t) (chipselect >> 24),
+ (uint8_t) (chipselect >> 16), (chipselect
+ & SPI_CS_MODE_INVERT_CS) ^ SPI_CS_MODE_INVERT_CS);
+
+ return 0;
+}
+
+void spi_status(void)
+{
+ debug_printf(" * SPI: CLK:%uMHz\n", (SystemCoreClock / LPC_SSP->CPSR)
+ / 1000000);
+}
+
+void spi_init(void)
+{
+ /* reset SSP peripheral */
+ LPC_SYSCON->PRESETCTRL = 0x01;
+
+ /* Enable SSP clock */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11);
+
+ /* Enable SSP peripheral MISO, Pulldown */
+ LPC_IOCON->PIO0_8 = 0x01 | (0x01 << 3);
+ /* MOSI */
+ LPC_IOCON->PIO0_9 = 0x01;
+ /* route to PIO2_11 */
+ LPC_IOCON->SCKLOC = 0x01;
+ /* SCK */
+ LPC_IOCON->PIO2_11 = 0x01;
+
+ /* Set SSP PCLK to 48MHz DIV=1 */
+ LPC_SYSCON->SSPCLKDIV = 0x01;
+ /* 8 bit, SPI, SCR=0 */
+ LPC_SSP->CR0 = 0x0007;
+ LPC_SSP->CR1 = 0x0002;
+}
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/vfs.c b/openbeacon/lpc13xx/core/openbeacon/src/vfs.c
new file mode 100644
index 0000000..0087133
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/vfs.c
@@ -0,0 +1,533 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - virtual FAT16 file system support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "msd.h"
+#include "vfs.h"
+
+#ifdef USB_DISK_SUPPORT
+
+#define VOLUME_START 1UL
+#define VOLUME_SECTORS (DISK_SECTORS-VOLUME_START)
+#define DISK_SECTORS_PER_CLUSTER 8UL
+#define DISK_CLUSTER_SIZE (DISK_SECTORS_PER_CLUSTER*DISK_BLOCK_SIZE)
+#define FAT16_SIZE_SECTORS ((uint32_t)((((VOLUME_SECTORS/DISK_SECTORS_PER_CLUSTER+2)*2)+DISK_BLOCK_SIZE-1)/DISK_BLOCK_SIZE))
+#define RESERVED_SECTORS_COUNT 1UL
+#define BPB_NUMFATS 2UL
+#define ROOT_DIR_SECTORS 1UL
+#define MAX_FILES_IN_ROOT ((ROOT_DIR_SECTORS*DISK_BLOCK_SIZE)/sizeof(TDiskDirectoryEntry))
+#define FIRST_FAT_SECTOR (RESERVED_SECTORS_COUNT)
+#define FIRST_ROOT_DIR_SECTOR (FIRST_FAT_SECTOR+(BPB_NUMFATS*FAT16_SIZE_SECTORS))
+#define FIRST_DATA_SECTOR (FIRST_ROOT_DIR_SECTOR+ROOT_DIR_SECTORS)
+#define DATA_SECTORS (DISK_SECTORS-FIRST_DATA_SECTOR)
+#define FIRST_SECTOR_OF_CLUSTER(N) (((N-2UL)*DISK_SECTORS_PER_CLUSTER)+FIRST_DATA_SECTOR)
+#define BPB_MEDIA_TYPE 0xF8
+#define DISK_FAT_EOC (0xFF00|BPB_MEDIA_TYPE)
+
+static const TDiskFile *root_directory = NULL;
+
+typedef uint16_t TFatCluster;
+
+typedef struct TDiskRecord
+{
+ uint32_t offset, length;
+ TDiskHandler handler;
+ const void *data;
+} TDiskRecord;
+
+typedef struct
+{
+ uint8_t head, sector, cylinder;
+} PACKED TDiskPartitionTableEntryCHS;
+
+typedef struct
+{
+ uint8_t bootable;
+ TDiskPartitionTableEntryCHS start;
+ uint8_t partition_type;
+ TDiskPartitionTableEntryCHS end;
+ uint32_t start_lba;
+ uint32_t length;
+} PACKED TDiskPartitionTableEntry;
+
+#define ATTR_READ_ONLY 0x01
+#define ATTR_HIDDEN 0x02
+#define ATTR_SYSTEM 0x04
+#define ATTR_VOLUME_ID 0x08
+#define ATTR_DIRECTORY 0x10
+#define ATTR_ARCHIVE 0x20
+#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
+
+typedef struct
+{
+ char DIR_Name[11];
+ uint8_t DIR_Attr;
+ uint8_t DIR_NTRes;
+ uint8_t DIR_CrtTimeTenth;
+ uint16_t DIR_CrtTime;
+ uint16_t DIR_CrtDate;
+ uint16_t DIR_LstAccDate;
+ uint16_t DIR_FstClusHI;
+ uint16_t DIR_WrtTime;
+ uint16_t DIR_WrtDate;
+ uint16_t DIR_FstClusLO;
+ uint32_t DIR_FileSize;
+} PACKED TDiskDirectoryEntry;
+
+/* disk signature */
+const uint32_t DiskSignature = 0x1B07CF6E;
+
+/* BPB - BIOS Parameter Block: actual volume boot block */
+const TDiskBPB DiskBPB = {
+ .BS_jmpBoot = {0xEB, 0x00, 0x90},
+ .BS_OEMName = "MSWIN4.1",
+ .BPB_BytsPerSec = DISK_BLOCK_SIZE,
+ .BPB_SecPerClus = DISK_SECTORS_PER_CLUSTER,
+ .BPB_RsvdSecCnt = RESERVED_SECTORS_COUNT,
+ .BPB_NumFATs = BPB_NUMFATS,
+ .BPB_RootEntCnt = MAX_FILES_IN_ROOT,
+ .BPB_Media = BPB_MEDIA_TYPE,
+ .BPB_FATSz16 = FAT16_SIZE_SECTORS,
+ .BPB_SecPerTrk = DISK_SECTORS_PER_TRACK,
+ .BPB_NumHeads = DISK_HEADS,
+ .BPB_HiddSec = VOLUME_START,
+ .BPB_TotSec32 = VOLUME_SECTORS,
+ /* FAT12/FAT16 definition */
+ .BS_DrvNum = 0x80,
+ .BS_BootSig = 0x29,
+ .BS_VolID = 0xe9d9489f,
+ .BS_VolLab = "OPENBEACON ",
+ .BS_FilSysType = "FAT16 ",
+};
+
+static void
+msd_read_data_area (uint32_t offset, uint32_t length, const void *src,
+ uint8_t * dst)
+{
+ uint32_t t;
+ uint32_t cluster, cluster_start, cluster_end, cluster_count;
+ uint32_t cluster_file_count;
+
+ /* remember variable content over calls to enable caching */
+ static const TDiskFile *file = NULL;
+ static uint32_t cluster_file_start, cluster_file_end;
+
+ /* touch unused parameter 'src' */
+ (void) src;
+
+ /* ignore zero size read requests */
+ if (!length)
+ return;
+
+ /* get extent of read/write request */
+ cluster_start = offset / DISK_CLUSTER_SIZE;
+ cluster_count = (length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE;
+ cluster_end = cluster_start + cluster_count - 1;
+
+ /* check for cached file request */
+ if (file && (cluster_end >= cluster_file_start)
+ && (cluster_start <= cluster_file_end))
+ {
+ if (file->handler)
+ file->handler (offset -
+ (cluster_file_start * DISK_CLUSTER_SIZE),
+ length, file->data, dst);
+ else
+ memset (dst, ' ', length);
+ }
+
+ /* if no file cached, try to find file */
+ cluster = 0;
+ file = root_directory;
+ while (file)
+ {
+ if (file->length)
+ {
+ cluster_file_start = cluster;
+ cluster_file_count =
+ (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE;
+ cluster_file_end = cluster_file_start + cluster_file_count - 1;
+
+ if ((cluster_end >= cluster_file_start)
+ && (cluster_start <= cluster_file_end))
+ {
+ /* normalize offset to file start */
+ offset -= (cluster_file_start * DISK_CLUSTER_SIZE);
+
+ /* if handler exists - run */
+ if (file->handler)
+ file->handler (offset, length, file->data, dst);
+ /* if no handler exists copy data */
+ else if ((file->data) && (offset < file->length))
+ {
+ /* calculate remaining length */
+ if ((t = file->length - offset) > length)
+ t = length;
+
+ /* copy data to output buffer */
+ memcpy (dst, ((uint8_t *) file->data) + offset, t);
+
+ /* if data is smaller, sent remainder to zero */
+ if (t < length)
+ memset (&dst[t], 0, length - t);
+ }
+ /* if no data exists, set to zero */
+ else
+ memset (dst, 0, length);
+
+ /* request could be satisfied - bail out with cached file
+ handle after handling request */
+ return;
+ }
+
+ cluster += cluster_file_count;
+ }
+ file = file->next;
+ }
+
+ /* didn't find a matching request - reset cached file to NULL */
+ file = NULL;
+}
+
+static void
+msd_read_fat_area (uint32_t offset, uint32_t length, const void *src,
+ uint8_t * dst)
+{
+ const TDiskFile *file;
+ uint32_t count, t, index, remaining;
+ uint32_t cluster, cluster_start, cluster_end, cluster_count;
+ uint32_t cluster_file_start, cluster_file_end, cluster_file_count;
+ TFatCluster *fat;
+
+ /* touch unused parameter 'src' */
+ (void) src;
+
+ /* ignore read requests for sizes < cluster table granularity */
+ if (length < sizeof (TFatCluster))
+ return;
+
+ /* get extent of read/write request */
+ cluster_start = offset / sizeof (TFatCluster);
+ cluster_count = length / sizeof (TFatCluster);
+ cluster_end = cluster_start + cluster_count - 1;
+
+ /* pre-set FAT */
+ fat = (TFatCluster *) dst;
+ t = cluster_count;
+
+ /* special treatment for reserved clusters */
+ if (!offset)
+ {
+ /* indicate media type */
+ *fat++ = DISK_FAT_EOC;
+ /* indicate clean volume */
+ *fat++ = (0x8000 | 0x4000);
+ t -= 2;
+ }
+
+ /* mark all custers as bad by default to make
+ sure there is no free space left on the disk
+ for new files */
+ while (t--)
+ *fat++ = 0xFFF7;
+
+ /* first cluster number on disk is 2 */
+ cluster = 2;
+ file = root_directory;
+ while (file)
+ {
+ if (file->length)
+ {
+ cluster_file_start = cluster;
+ cluster_file_count =
+ (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE;
+ cluster_file_end = cluster_file_start + cluster_file_count - 1;
+
+ if ((cluster_end >= cluster_file_start)
+ && (cluster_start < cluster_file_end))
+ {
+ if (cluster_file_start < cluster_start)
+ {
+ index = cluster_start - cluster_file_start;
+ remaining = cluster_file_count - index;
+ index += cluster;
+ count =
+ (cluster_count > remaining) ? remaining : cluster_count;
+ fat = (TFatCluster *) dst;
+ }
+ else
+ {
+ index = cluster;
+ remaining = cluster_file_count;
+ t = (cluster_file_start - cluster_start);
+ count = cluster_count - t;
+ fat = ((TFatCluster *) dst) + t;
+ }
+
+ /* populate FAT entries with linked FAT list */
+ if (remaining)
+ for (t = 1; t <= count; t++)
+ if (remaining-- > 1)
+ *fat++ = index + t;
+ else
+ {
+ /* set last entry to EOC (End Of Chain) */
+ *fat = DISK_FAT_EOC;
+ break;
+ }
+ }
+ cluster += cluster_file_count;
+ }
+ file = file->next;
+ }
+}
+
+static void
+msd_read_root_dir (uint32_t offset, uint32_t length, const void *src,
+ uint8_t * dst)
+{
+ uint32_t cluster, t;
+ const TDiskFile *file;
+ TDiskDirectoryEntry *entry;
+
+ /* touch unused parameter 'src' */
+ (void) src;
+
+ /* initialize response with zero */
+ memset (dst, 0, length);
+
+ /* first cluster number on disk is 2 */
+ cluster = 2;
+ /* skip first entries */
+ file = root_directory;
+ t = offset / sizeof (TDiskDirectoryEntry);
+ while (t--)
+ {
+ if (!file)
+ return;
+ cluster += (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE;
+ file = file->next;
+ }
+
+ entry = (TDiskDirectoryEntry *) dst;
+ t = length / sizeof (TDiskDirectoryEntry);
+ while (t--)
+ {
+ if (!file)
+ return;
+
+ /* turn last entry to volume ID */
+ entry->DIR_Attr = file->next ? ATTR_READ_ONLY : ATTR_VOLUME_ID;
+
+ /* populate directory entry */
+ entry->DIR_FileSize = file->length;
+ entry->DIR_FstClusLO = (file->length) ? cluster : 0;
+ strncpy (entry->DIR_Name, file->name, sizeof (entry->DIR_Name));
+
+ /* increment cluster pos */
+ cluster += (file->length + DISK_CLUSTER_SIZE - 1) / DISK_CLUSTER_SIZE;
+
+ /* go to next entry */
+ entry++;
+ file = file->next;
+ }
+}
+
+static void
+msd_read_memory (uint32_t offset, uint32_t length, const void *src,
+ uint8_t * dst)
+{
+ memcpy (dst, ((const uint8_t *) src) + offset, length);
+}
+
+void
+msd_read (uint32_t offset, uint8_t * dst, uint32_t length)
+{
+ const TDiskRecord *rec;
+ uint32_t t, read_end, rec_start, rec_end, pos, count, written;
+ uint8_t *p;
+
+
+ /* first partition table entry */
+ static const TDiskPartitionTableEntry DiskPartitionTableEntry = {
+ .bootable = 0x00,
+ .start = {
+ .head = 0,
+ .sector = VOLUME_START + 1,
+ .cylinder = 0},
+ .partition_type = 0x06,
+ .end = {
+ .head = DISK_HEADS - 1,
+ .sector = DISK_SECTORS_PER_TRACK,
+ .cylinder = DISK_CYLINDERS - 1},
+ .start_lba = 1,
+ .length = VOLUME_SECTORS
+ };
+
+ /* MBR termination signature */
+ static const uint16_t BootSignature = 0xAA55;
+
+
+ /* data mapping of virtual drive */
+ static const TDiskRecord DiskRecord[] = {
+ /* data area */
+ {
+ .offset = (VOLUME_START + FIRST_DATA_SECTOR) * DISK_BLOCK_SIZE,
+ .length = DATA_SECTORS * DISK_BLOCK_SIZE,
+ .handler = msd_read_data_area,
+ .data = NULL}
+ ,
+ /* FAT area - primary copy */
+ {
+ .offset = (VOLUME_START + FIRST_FAT_SECTOR) * DISK_BLOCK_SIZE,
+ .length = FAT16_SIZE_SECTORS * DISK_BLOCK_SIZE,
+ .handler = msd_read_fat_area,
+ .data = NULL}
+ ,
+ /* FAT area - secondary copy */
+ {
+ .offset =
+ (VOLUME_START + FIRST_FAT_SECTOR + FAT16_SIZE_SECTORS) * DISK_BLOCK_SIZE,
+ .length = FAT16_SIZE_SECTORS * DISK_BLOCK_SIZE,
+ .handler = msd_read_fat_area,
+ .data = NULL}
+ ,
+ /* root dir */
+ {
+ .offset = (VOLUME_START + FIRST_ROOT_DIR_SECTOR) * DISK_BLOCK_SIZE,
+ .length = ROOT_DIR_SECTORS * DISK_BLOCK_SIZE,
+ .handler = msd_read_root_dir,
+ .data = NULL}
+ ,
+ /* disk signature */
+ {
+ .offset = 0x1B8,
+ .length = sizeof (DiskSignature),
+ .handler = msd_read_memory,
+ .data = &DiskSignature}
+ ,
+ /* first partition table entry */
+ {
+ .offset = 0x1BE,
+ .length = sizeof (DiskPartitionTableEntry),
+ .handler = msd_read_memory,
+ .data = &DiskPartitionTableEntry}
+ ,
+ /* MBR termination signature */
+ {
+ .offset = 0x1FE,
+ .length = sizeof (BootSignature),
+ .handler = msd_read_memory,
+ .data = &BootSignature}
+ ,
+ /* BPB - BIOS Parameter Block: actual volume boot block */
+ {
+ .offset = (VOLUME_START * DISK_BLOCK_SIZE),
+ .length = sizeof (DiskBPB),
+ .handler = msd_read_memory,
+ .data = &DiskBPB}
+ ,
+ /* BPB termination signature */
+ {
+ .offset = (VOLUME_START * DISK_BLOCK_SIZE) + 0x1FE,
+ .length = sizeof (BootSignature),
+ .handler = msd_read_memory,
+ .data = &BootSignature}
+ ,
+ };
+
+ /* ignore zero reads and reads outside of disk area */
+ if (!length || (offset >= DISK_SIZE))
+ return;
+
+ /* iterate DiskRecords and fill request with content */
+ rec = DiskRecord;
+ t = sizeof (DiskRecord) / sizeof (DiskRecord[0]);
+ read_end = offset + length;
+ written = 0;
+
+ while (t--)
+ {
+ rec_start = rec->offset;
+ rec_end = rec_start + rec->length;
+
+ if ((read_end >= rec_start) && (offset < rec_end))
+ {
+ if (rec_start >= offset)
+ {
+ pos = 0;
+ p = &dst[rec_start - offset];
+ count = (rec_end <= read_end) ?
+ rec->length : read_end - rec_start;
+ }
+ else
+ {
+ pos = offset - rec_start;
+ p = dst;
+ count = (read_end > rec_end) ? rec_end - offset : length;
+ }
+
+ /* set memory of partial read to zero before filling up */
+ if (!written && (count != length))
+ memset (dst, 0, length);
+
+ /* handle request */
+ rec->handler (pos, count, rec->data, p);
+ written += count;
+
+ /* all bytes handled -> quit */
+ if (written == length)
+ break;
+ }
+ rec++;
+ }
+
+ /* set memory to zero if not written yet */
+ if (!written)
+ memset (dst, 0, length);
+}
+
+void
+msd_write (uint32_t offset, uint8_t * src, uint32_t length)
+{
+ (void) offset;
+ (void) src;
+ (void) length;
+}
+
+void
+vfs_status (void)
+{
+}
+
+void
+vfs_init (const TDiskFile * file)
+{
+ if (file)
+ {
+ root_directory = file;
+ /* init USB mass storage */
+ msd_init ();
+ }
+}
+
+#endif /* USB_DISK_SUPPORT */
diff --git a/openbeacon/lpc13xx/core/openbeacon/src/xxtea.c b/openbeacon/lpc13xx/core/openbeacon/src/xxtea.c
new file mode 100644
index 0000000..888fe90
--- /dev/null
+++ b/openbeacon/lpc13xx/core/openbeacon/src/xxtea.c
@@ -0,0 +1,102 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - XXTEA based block encryption
+ *
+ * based on "correction to XTEA" by David J. Wheeler and
+ * Roger M. Needham.
+ * Computer Laboratory - Cambridge University in 1998
+ *
+ * Copyright 2006 Milosch Meriac
+ *
+ * ripped into pieces - optimized for the special case
+ * where 16 bytes are regarded for encryption and decryption
+ * to increase speed and to decrease memory consumption
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include
+#include "xxtea.h"
+
+static const uint32_t DELTA = 0x9e3779b9UL;
+
+#define MX ( (((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(tea_key[(p&3)^e]^z)) );
+
+static void
+xxtea_shuffle (uint32_t * v, uint32_t length)
+{
+ while (length--)
+ {
+ *v = htonl (*v);
+ v++;
+ }
+}
+
+void
+xxtea_encode (uint32_t * v, uint32_t length, const uint32_t * tea_key)
+{
+ uint32_t z, y, sum, e, p, q;
+
+ if (!v || !tea_key)
+ return;
+
+ xxtea_shuffle (v, length);
+
+ q = 6 + 52 / length;
+ sum = 0;
+ z = v[length - 1];
+ do
+ {
+ sum += DELTA;
+ e = (sum >> 2) & 3;
+
+ for (p = 0; p < (length - 1); p++)
+ y = v[p + 1], z = v[p] += MX;
+
+ y = v[0];
+ z = v[length - 1] += MX;
+ }
+ while (--q);
+
+ xxtea_shuffle (v, length);
+}
+
+void
+xxtea_decode (uint32_t * v, uint32_t length, const uint32_t * tea_key)
+{
+ uint32_t z, y, sum, e, p, q;
+
+ if (!v || !tea_key)
+ return;
+
+ xxtea_shuffle (v, length);
+
+ q = 6 + 52 / length;
+ sum = q * DELTA;
+ y = v[0];
+ while (sum)
+ {
+ e = (sum >> 2) & 3;
+ for (p = length - 1; p > 0; p--)
+ z = v[p - 1], y = v[p] -= MX;
+
+ z = v[length - 1];
+ y = v[0] -= MX;
+ sum -= DELTA;
+ }
+
+ xxtea_shuffle (v, length);
+}
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/gpio.h b/openbeacon/lpc13xx/core/peripherals/inc/gpio.h
new file mode 100644
index 0000000..f7aa3d0
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/gpio.h
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * gpio.h: Header file for NXP LPC13xx Family Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.09.01 ver 1.00 Preliminary version, first Release
+ * 2009.12.09 ver 1.05 Mod to use mask registers for GPIO writes + inlining (.h)
+ *
+******************************************************************************/
+#ifndef __GPIO_H
+#define __GPIO_H
+
+extern void GPIOInit (void);
+extern LPC_GPIO_TypeDef (*const LPC_GPIO[4]);
+
+/*****************************************************************************
+** Function name: GPIOSetValue
+**
+** Descriptions: Set/clear a bitvalue in a specific bit position
+** in GPIO portX(X is the port number.)
+**
+** parameters: port num, bit position, bit value
+** Returned value: None
+**
+*****************************************************************************/
+static __INLINE void
+GPIOSetValue (uint32_t portNum, uint32_t bitPosi, uint32_t bitVal)
+{
+ LPC_GPIO[portNum]->MASKED_ACCESS[(1 << bitPosi)] = (bitVal << bitPosi);
+}
+
+/*****************************************************************************
+** Function name: GPIOGetValue
+**
+** Descriptions: Get a bitvalue in a specific bit position
+** in GPIO portX(X is the port number.)
+**
+** parameters: port num, bit position
+** Returned value: bit value
+**
+*****************************************************************************/
+static __INLINE uint32_t GPIOGetValue( uint32_t portNum, uint32_t bitPosi)
+{
+ return LPC_GPIO[portNum]->MASKED_ACCESS[(1<DIR |= 1 << bitPosi;
+ else
+ LPC_GPIO[portNum]->DIR &= ~(1 << bitPosi);
+}
+
+#endif /* end __GPIO_H */
+/*****************************************************************************
+** End Of File
+******************************************************************************/
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/rom_drivers.h b/openbeacon/lpc13xx/core/peripherals/inc/rom_drivers.h
new file mode 100644
index 0000000..a0b6746
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/rom_drivers.h
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * rom_drivers.h: Header file for NXP LPC13xx Family Microprocessors
+ *
+ * Copyright(C) 2009, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2009.09.17 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+#ifndef ROM_DRIVERS_H_
+#define ROM_DRIVERS_H_
+
+typedef struct _USB_DEVICE_INFO
+{
+ uint16_t DevType;
+ uint32_t DevDetailPtr;
+} USB_DEV_INFO;
+
+typedef struct _USBD
+{
+ void (*init_clk_pins) (void);
+ void (*isr) (void);
+ void (*init) (const USB_DEV_INFO * DevInfoPtr);
+ void (*connect) (uint32_t con);
+} USBD;
+
+#define init_msdstate() *((uint32_t *)(0x10000054)) = 0x0
+
+typedef struct _ROM
+{
+ const USBD *pUSBD;
+} ROM;
+
+typedef struct _MSC_DEVICE_INFO
+{
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint32_t StrDescPtr;
+ uint32_t MSCInquiryStr;
+ uint32_t BlockCount;
+ uint32_t BlockSize;
+ uint32_t MemorySize;
+ void (*MSC_Write) (uint32_t offset, uint8_t *src, uint32_t length);
+ void (*MSC_Read) (uint32_t offset, uint8_t *dst, uint32_t length);
+} MSC_DEVICE_INFO;
+
+typedef struct _HID_DEVICE_INFO
+{
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint32_t StrDescPtr;
+ uint8_t InReportCount;
+ uint8_t OutReportCount;
+ uint8_t SampleInterval;
+ void (*InReport) (uint8_t *src, uint32_t length);
+ void (*OutReport) (uint8_t *dst, uint32_t length);
+} HID_DEVICE_INFO;
+
+#endif /*ROM_DRIVERS_H_ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/uart.h b/openbeacon/lpc13xx/core/peripherals/inc/uart.h
new file mode 100644
index 0000000..d4a655c
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/uart.h
@@ -0,0 +1,60 @@
+/*****************************************************************************
+ * uart.h: Header file for NXP LPC13xx Family Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.08.21 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+#ifndef __UART_H__
+#define __UART_H__
+#ifndef UART_DISABLE
+
+#define RS485_ENABLED 0
+#define TX_INTERRUPT 0 /* 0 if TX uses polling, 1 interrupt driven. */
+#define MODEM_TEST 0
+
+#define IER_RBR 0x01
+#define IER_THRE 0x02
+#define IER_RLS 0x04
+
+#define IIR_PEND 0x01
+#define IIR_RLS 0x03
+#define IIR_RDA 0x02
+#define IIR_CTI 0x06
+#define IIR_THRE 0x01
+
+#define LSR_RDR 0x01
+#define LSR_OE 0x02
+#define LSR_PE 0x04
+#define LSR_FE 0x08
+#define LSR_BI 0x10
+#define LSR_THRE 0x20
+#define LSR_TEMT 0x40
+#define LSR_RXFE 0x80
+
+#define BUFSIZE 0x40
+
+/* RS485 mode definition. */
+#define RS485_NMMEN (0x1<<0)
+#define RS485_RXDIS (0x1<<1)
+#define RS485_AADEN (0x1<<2)
+#define RS485_SEL (0x1<<3)
+#define RS485_DCTRL (0x1<<4)
+#define RS485_OINV (0x1<<5)
+
+extern void UARTInit (uint32_t Baudrate,uint8_t rtscts);
+extern void UART_IRQHandler (void);
+extern BOOL UARTSendChar (uint8_t data);
+extern void UARTSend (const uint8_t * BufferPtr, uint32_t Length);
+
+extern volatile uint32_t UARTCount;
+extern volatile uint8_t UARTBuffer[BUFSIZE];
+
+#endif /* UART_DISABLE */
+#endif /* end __UART_H__ */
+/*****************************************************************************
+** End Of File
+******************************************************************************/
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb.h b/openbeacon/lpc13xx/core/peripherals/inc/usb.h
new file mode 100644
index 0000000..705578b
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb.h
@@ -0,0 +1,237 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usb.h
+ * Purpose: USB Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USB_H__
+#define __USB_H__
+
+typedef union
+{
+ uint16_t W;
+ struct
+ {
+ uint8_t L;
+ uint8_t H;
+ } __attribute__((packed)) WB;
+} __attribute__((packed)) WORD_BYTE;
+
+/* bmRequestType.Dir */
+#define REQUEST_HOST_TO_DEVICE 0
+#define REQUEST_DEVICE_TO_HOST 1
+
+/* bmRequestType.Type */
+#define REQUEST_STANDARD 0
+#define REQUEST_CLASS 1
+#define REQUEST_VENDOR 2
+#define REQUEST_RESERVED 3
+
+/* bmRequestType.Recipient */
+#define REQUEST_TO_DEVICE 0
+#define REQUEST_TO_INTERFACE 1
+#define REQUEST_TO_ENDPOINT 2
+#define REQUEST_TO_OTHER 3
+
+/* bmRequestType Definition */
+typedef union _REQUEST_TYPE
+{
+ struct _BM
+ {
+ uint8_t Recipient:5;
+ uint8_t Type:2;
+ uint8_t Dir:1;
+ } __attribute__((packed)) BM;
+ uint8_t B;
+} __attribute__((packed)) REQUEST_TYPE;
+
+/* USB Standard Request Codes */
+#define USB_REQUEST_GET_STATUS 0
+#define USB_REQUEST_CLEAR_FEATURE 1
+#define USB_REQUEST_SET_FEATURE 3
+#define USB_REQUEST_SET_ADDRESS 5
+#define USB_REQUEST_GET_DESCRIPTOR 6
+#define USB_REQUEST_SET_DESCRIPTOR 7
+#define USB_REQUEST_GET_CONFIGURATION 8
+#define USB_REQUEST_SET_CONFIGURATION 9
+#define USB_REQUEST_GET_INTERFACE 10
+#define USB_REQUEST_SET_INTERFACE 11
+#define USB_REQUEST_SYNC_FRAME 12
+
+/* USB GET_STATUS Bit Values */
+#define USB_GETSTATUS_SELF_POWERED 0x01
+#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
+#define USB_GETSTATUS_ENDPOINT_STALL 0x01
+
+/* USB Standard Feature selectors */
+#define USB_FEATURE_ENDPOINT_STALL 0
+#define USB_FEATURE_REMOTE_WAKEUP 1
+
+/* USB Default Control Pipe Setup Packet */
+typedef struct _USB_SETUP_PACKET
+{
+ REQUEST_TYPE bmRequestType;
+ uint8_t bRequest;
+ WORD_BYTE wValue;
+ WORD_BYTE wIndex;
+ uint16_t wLength;
+} __attribute__((packed)) USB_SETUP_PACKET;
+
+
+/* USB Descriptor Types */
+#define USB_DEVICE_DESCRIPTOR_TYPE 1
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
+#define USB_STRING_DESCRIPTOR_TYPE 3
+#define USB_INTERFACE_DESCRIPTOR_TYPE 4
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
+#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
+#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
+#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
+#define USB_OTG_DESCRIPTOR_TYPE 9
+#define USB_DEBUG_DESCRIPTOR_TYPE 10
+#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11
+
+/* USB Device Classes */
+#define USB_DEVICE_CLASS_RESERVED 0x00
+#define USB_DEVICE_CLASS_AUDIO 0x01
+#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
+#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
+#define USB_DEVICE_CLASS_MONITOR 0x04
+#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
+#define USB_DEVICE_CLASS_POWER 0x06
+#define USB_DEVICE_CLASS_PRINTER 0x07
+#define USB_DEVICE_CLASS_STORAGE 0x08
+#define USB_DEVICE_CLASS_HUB 0x09
+#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF
+#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
+
+/* bmAttributes in Configuration Descriptor */
+#define USB_CONFIG_POWERED_MASK 0x40
+#define USB_CONFIG_BUS_POWERED 0x80
+#define USB_CONFIG_SELF_POWERED 0xC0
+#define USB_CONFIG_REMOTE_WAKEUP 0x20
+
+/* bMaxPower in Configuration Descriptor */
+#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
+
+/* bEndpointAddress in Endpoint Descriptor */
+#define USB_ENDPOINT_DIRECTION_MASK 0x80
+#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
+#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
+
+/* bmAttributes in Endpoint Descriptor */
+#define USB_ENDPOINT_TYPE_MASK 0x03
+#define USB_ENDPOINT_TYPE_CONTROL 0x00
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_TYPE_BULK 0x02
+#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
+#define USB_ENDPOINT_SYNC_MASK 0x0C
+#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
+#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
+#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
+#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
+#define USB_ENDPOINT_USAGE_MASK 0x30
+#define USB_ENDPOINT_USAGE_DATA 0x00
+#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
+#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
+#define USB_ENDPOINT_USAGE_RESERVED 0x30
+
+/* USB Standard Device Descriptor */
+typedef struct _USB_DEVICE_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
+
+/* USB 2.0 Device Qualifier Descriptor */
+typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+} __attribute__((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR;
+
+/* USB Standard Configuration Descriptor */
+typedef struct _USB_CONFIGURATION_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
+
+/* USB Standard Interface Descriptor */
+typedef struct _USB_INTERFACE_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
+
+/* USB Standard Endpoint Descriptor */
+typedef struct _USB_ENDPOINT_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
+
+/* USB String Descriptor */
+typedef struct _USB_STRING_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bString /*[] */ ;
+} __attribute__((packed)) USB_STRING_DESCRIPTOR;
+
+/* USB Common Descriptor */
+typedef struct _USB_COMMON_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+} __attribute__((packed)) USB_COMMON_DESCRIPTOR;
+
+#endif /* __USB_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdc.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdc.h
new file mode 100644
index 0000000..d61b85b
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdc.h
@@ -0,0 +1,241 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: CDC.h
+ * Purpose: USB Communication Device Class Definitions
+ * Version: V1.00
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __CDC_H
+#define __CDC_H
+
+/*----------------------------------------------------------------------------
+ * Definitions based on usbcdc11.pdf (www.usb.org)
+ *---------------------------------------------------------------------------*/
+// Communication device class specification version 1.10
+#define CDC_V1_10 0x0110
+
+// Communication interface class code
+// (usbcdc11.pdf, 4.2, Table 15)
+#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
+
+// Communication interface class subclass codes
+// (usbcdc11.pdf, 4.3, Table 16)
+#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01
+#define CDC_ABSTRACT_CONTROL_MODEL 0x02
+#define CDC_TELEPHONE_CONTROL_MODEL 0x03
+#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04
+#define CDC_CAPI_CONTROL_MODEL 0x05
+#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06
+#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07
+
+// Communication interface class control protocol codes
+// (usbcdc11.pdf, 4.4, Table 17)
+#define CDC_PROTOCOL_COMMON_AT_COMMANDS 0x01
+
+// Data interface class code
+// (usbcdc11.pdf, 4.5, Table 18)
+#define CDC_DATA_INTERFACE_CLASS 0x0A
+
+// Data interface class protocol codes
+// (usbcdc11.pdf, 4.7, Table 19)
+#define CDC_PROTOCOL_ISDN_BRI 0x30
+#define CDC_PROTOCOL_HDLC 0x31
+#define CDC_PROTOCOL_TRANSPARENT 0x32
+#define CDC_PROTOCOL_Q921_MANAGEMENT 0x50
+#define CDC_PROTOCOL_Q921_DATA_LINK 0x51
+#define CDC_PROTOCOL_Q921_MULTIPLEXOR 0x52
+#define CDC_PROTOCOL_V42 0x90
+#define CDC_PROTOCOL_EURO_ISDN 0x91
+#define CDC_PROTOCOL_V24_RATE_ADAPTATION 0x92
+#define CDC_PROTOCOL_CAPI 0x93
+#define CDC_PROTOCOL_HOST_BASED_DRIVER 0xFD
+#define CDC_PROTOCOL_DESCRIBED_IN_PUFD 0xFE
+
+// Type values for bDescriptorType field of functional descriptors
+// (usbcdc11.pdf, 5.2.3, Table 24)
+#define CDC_CS_INTERFACE 0x24
+#define CDC_CS_ENDPOINT 0x25
+
+// Type values for bDescriptorSubtype field of functional descriptors
+// (usbcdc11.pdf, 5.2.3, Table 25)
+#define CDC_HEADER 0x00
+#define CDC_CALL_MANAGEMENT 0x01
+#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
+#define CDC_DIRECT_LINE_MANAGEMENT 0x03
+#define CDC_TELEPHONE_RINGER 0x04
+#define CDC_REPORTING_CAPABILITIES 0x05
+#define CDC_UNION 0x06
+#define CDC_COUNTRY_SELECTION 0x07
+#define CDC_TELEPHONE_OPERATIONAL_MODES 0x08
+#define CDC_USB_TERMINAL 0x09
+#define CDC_NETWORK_CHANNEL 0x0A
+#define CDC_PROTOCOL_UNIT 0x0B
+#define CDC_EXTENSION_UNIT 0x0C
+#define CDC_MULTI_CHANNEL_MANAGEMENT 0x0D
+#define CDC_CAPI_CONTROL_MANAGEMENT 0x0E
+#define CDC_ETHERNET_NETWORKING 0x0F
+#define CDC_ATM_NETWORKING 0x10
+
+// CDC class-specific request codes
+// (usbcdc11.pdf, 6.2, Table 46)
+// see Table 45 for info about the specific requests.
+#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
+#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
+#define CDC_SET_COMM_FEATURE 0x02
+#define CDC_GET_COMM_FEATURE 0x03
+#define CDC_CLEAR_COMM_FEATURE 0x04
+#define CDC_SET_AUX_LINE_STATE 0x10
+#define CDC_SET_HOOK_STATE 0x11
+#define CDC_PULSE_SETUP 0x12
+#define CDC_SEND_PULSE 0x13
+#define CDC_SET_PULSE_TIME 0x14
+#define CDC_RING_AUX_JACK 0x15
+#define CDC_SET_LINE_CODING 0x20
+#define CDC_GET_LINE_CODING 0x21
+#define CDC_SET_CONTROL_LINE_STATE 0x22
+#define CDC_SEND_BREAK 0x23
+#define CDC_SET_RINGER_PARMS 0x30
+#define CDC_GET_RINGER_PARMS 0x31
+#define CDC_SET_OPERATION_PARMS 0x32
+#define CDC_GET_OPERATION_PARMS 0x33
+#define CDC_SET_LINE_PARMS 0x34
+#define CDC_GET_LINE_PARMS 0x35
+#define CDC_DIAL_DIGITS 0x36
+#define CDC_SET_UNIT_PARAMETER 0x37
+#define CDC_GET_UNIT_PARAMETER 0x38
+#define CDC_CLEAR_UNIT_PARAMETER 0x39
+#define CDC_GET_PROFILE 0x3A
+#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
+#define CDC_SET_ETHERNET_PMP_FILTER 0x41
+#define CDC_GET_ETHERNET_PMP_FILTER 0x42
+#define CDC_SET_ETHERNET_PACKET_FILTER 0x43
+#define CDC_GET_ETHERNET_STATISTIC 0x44
+#define CDC_SET_ATM_DATA_FORMAT 0x50
+#define CDC_GET_ATM_DEVICE_STATISTICS 0x51
+#define CDC_SET_ATM_DEFAULT_VC 0x52
+#define CDC_GET_ATM_VC_STATISTICS 0x53
+
+// Communication feature selector codes
+// (usbcdc11.pdf, 6.2.2..6.2.4, Table 47)
+#define CDC_ABSTRACT_STATE 0x01
+#define CDC_COUNTRY_SETTING 0x02
+
+// Feature Status returned for ABSTRACT_STATE Selector
+// (usbcdc11.pdf, 6.2.3, Table 48)
+#define CDC_IDLE_SETTING (1 << 0)
+#define CDC_DATA_MULTPLEXED_STATE (1 << 1)
+
+
+// Control signal bitmap values for the SetControlLineState request
+// (usbcdc11.pdf, 6.2.14, Table 51)
+#define CDC_DTE_PRESENT (1 << 0)
+#define CDC_ACTIVATE_CARRIER (1 << 1)
+
+// CDC class-specific notification codes
+// (usbcdc11.pdf, 6.3, Table 68)
+// see Table 67 for Info about class-specific notifications
+#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00
+#define CDC_RESPONSE_AVAILABLE 0x01
+#define CDC_AUX_JACK_HOOK_STATE 0x08
+#define CDC_RING_DETECT 0x09
+#define CDC_NOTIFICATION_SERIAL_STATE 0x20
+#define CDC_CALL_STATE_CHANGE 0x28
+#define CDC_LINE_STATE_CHANGE 0x29
+#define CDC_CONNECTION_SPEED_CHANGE 0x2A
+
+// UART state bitmap values (Serial state notification).
+// (usbcdc11.pdf, 6.3.5, Table 69)
+#define CDC_SERIAL_STATE_OVERRUN (1 << 6) // receive data overrun error has occurred
+#define CDC_SERIAL_STATE_PARITY (1 << 5) // parity error has occurred
+#define CDC_SERIAL_STATE_FRAMING (1 << 4) // framing error has occurred
+#define CDC_SERIAL_STATE_RING (1 << 3) // state of ring signal detection
+#define CDC_SERIAL_STATE_BREAK (1 << 2) // state of break detection
+#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) // state of transmission carrier
+#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) // state of receiver carrier
+
+
+/*----------------------------------------------------------------------------
+ * Structures based on usbcdc11.pdf (www.usb.org)
+ *---------------------------------------------------------------------------*/
+
+// Header functional descriptor
+// (usbcdc11.pdf, 5.2.3.1)
+// This header must precede any list of class-specific descriptors.
+typedef struct _CDC_HEADER_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // Header functional descriptor subtype
+ uint16_t bcdCDC; // USB CDC specification release version
+} __attribute__ ((packed)) CDC_HEADER_DESCRIPTOR;
+
+//Call management functional descriptor
+// (usbcdc11.pdf, 5.2.3.2)
+// Describes the processing of calls for the communication class interface.
+typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // call management functional descriptor subtype
+ uint8_t bmCapabilities; // capabilities that this configuration supports
+ uint8_t bDataInterface; // interface number of the data class interface used for call management (optional)
+} __attribute__ ((packed)) CDC_CALL_MANAGEMENT_DESCRIPTOR;
+
+// Abstract control management functional descriptor
+// (usbcdc11.pdf, 5.2.3.3)
+// Describes the command supported by the communication interface class with the Abstract Control Model subclass code.
+typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // abstract control management functional descriptor subtype
+ uint8_t bmCapabilities; // capabilities supported by this configuration
+} __attribute__ ((packed)) CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR;
+
+// Union functional descriptors
+// (usbcdc11.pdf, 5.2.3.8)
+// Describes the relationship between a group of interfaces that can be considered to form a functional unit.
+typedef struct _CDC_UNION_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // union functional descriptor subtype
+ uint8_t bMasterInterface; // interface number designated as master
+} __attribute__ ((packed)) CDC_UNION_DESCRIPTOR;
+
+// Union functional descriptors with one slave interface
+// (usbcdc11.pdf, 5.2.3.8)
+typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR
+{
+ CDC_UNION_DESCRIPTOR sUnion; // Union functional descriptor
+ uint8_t bSlaveInterfaces[1]; // Slave interface 0
+} __attribute__ ((packed)) CDC_UNION_1SLAVE_DESCRIPTOR;
+
+// Line coding structure
+// Format of the data returned when a GetLineCoding request is received
+// (usbcdc11.pdf, 6.2.13)
+typedef struct _CDC_LINE_CODING
+{
+ uint32_t dwDTERate; // Data terminal rate in bits per second
+ uint8_t bCharFormat; // Number of stop bits
+ uint8_t bParityType; // Parity bit type
+ uint8_t bDataBits; // Number of data bits
+} __attribute__ ((packed)) CDC_LINE_CODING;
+
+// Notification header
+// Data sent on the notification endpoint must follow this header.
+// see USB_SETUP_PACKET in file usb.h
+typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER;
+
+#endif /* __CDC_H */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusb.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusb.h
new file mode 100644
index 0000000..cef6473
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusb.h
@@ -0,0 +1,240 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usb.h
+ * Purpose: USB Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __CDCUSB_H__
+#define __CDCUSB_H__
+
+
+typedef union
+{
+ uint16_t W;
+ struct
+ {
+ uint8_t L;
+ uint8_t H;
+ } __attribute__ ((packed)) WB;
+} __attribute__ ((packed)) WORD_BYTE;
+
+
+/* bmRequestType.Dir */
+#define REQUEST_HOST_TO_DEVICE 0
+#define REQUEST_DEVICE_TO_HOST 1
+
+/* bmRequestType.Type */
+#define REQUEST_STANDARD 0
+#define REQUEST_CLASS 1
+#define REQUEST_VENDOR 2
+#define REQUEST_RESERVED 3
+
+/* bmRequestType.Recipient */
+#define REQUEST_TO_DEVICE 0
+#define REQUEST_TO_INTERFACE 1
+#define REQUEST_TO_ENDPOINT 2
+#define REQUEST_TO_OTHER 3
+
+/* bmRequestType Definition */
+typedef union _REQUEST_TYPE
+{
+ struct _BM
+ {
+ uint8_t Recipient:5;
+ uint8_t Type:2;
+ uint8_t Dir:1;
+ } __attribute__ ((packed)) BM;
+ uint8_t B;
+} __attribute__ ((packed)) REQUEST_TYPE;
+
+/* USB Standard Request Codes */
+#define USB_REQUEST_GET_STATUS 0
+#define USB_REQUEST_CLEAR_FEATURE 1
+#define USB_REQUEST_SET_FEATURE 3
+#define USB_REQUEST_SET_ADDRESS 5
+#define USB_REQUEST_GET_DESCRIPTOR 6
+#define USB_REQUEST_SET_DESCRIPTOR 7
+#define USB_REQUEST_GET_CONFIGURATION 8
+#define USB_REQUEST_SET_CONFIGURATION 9
+#define USB_REQUEST_GET_INTERFACE 10
+#define USB_REQUEST_SET_INTERFACE 11
+#define USB_REQUEST_SYNC_FRAME 12
+
+/* USB GET_STATUS Bit Values */
+#define USB_GETSTATUS_SELF_POWERED 0x01
+#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
+#define USB_GETSTATUS_ENDPOINT_STALL 0x01
+
+/* USB Standard Feature selectors */
+#define USB_FEATURE_ENDPOINT_STALL 0
+#define USB_FEATURE_REMOTE_WAKEUP 1
+
+/* USB Default Control Pipe Setup Packet */
+typedef struct _USB_SETUP_PACKET
+{
+ REQUEST_TYPE bmRequestType;
+ uint8_t bRequest;
+ WORD_BYTE wValue;
+ WORD_BYTE wIndex;
+ uint16_t wLength;
+} __attribute__ ((packed)) USB_SETUP_PACKET;
+
+
+/* USB Descriptor Types */
+#define USB_DEVICE_DESCRIPTOR_TYPE 1
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
+#define USB_STRING_DESCRIPTOR_TYPE 3
+#define USB_INTERFACE_DESCRIPTOR_TYPE 4
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
+#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
+#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
+#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
+#define USB_OTG_DESCRIPTOR_TYPE 9
+#define USB_DEBUG_DESCRIPTOR_TYPE 10
+#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11
+
+/* USB Device Classes */
+#define USB_DEVICE_CLASS_RESERVED 0x00
+#define USB_DEVICE_CLASS_AUDIO 0x01
+#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
+#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
+#define USB_DEVICE_CLASS_MONITOR 0x04
+#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
+#define USB_DEVICE_CLASS_POWER 0x06
+#define USB_DEVICE_CLASS_PRINTER 0x07
+#define USB_DEVICE_CLASS_STORAGE 0x08
+#define USB_DEVICE_CLASS_HUB 0x09
+#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF
+#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
+
+/* bmAttributes in Configuration Descriptor */
+#define USB_CONFIG_POWERED_MASK 0x40
+#define USB_CONFIG_BUS_POWERED 0x80
+#define USB_CONFIG_SELF_POWERED 0xC0
+#define USB_CONFIG_REMOTE_WAKEUP 0x20
+
+/* bMaxPower in Configuration Descriptor */
+#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
+
+/* bEndpointAddress in Endpoint Descriptor */
+#define USB_ENDPOINT_DIRECTION_MASK 0x80
+#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
+#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
+
+/* bmAttributes in Endpoint Descriptor */
+#define USB_ENDPOINT_TYPE_MASK 0x03
+#define USB_ENDPOINT_TYPE_CONTROL 0x00
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_TYPE_BULK 0x02
+#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
+#define USB_ENDPOINT_SYNC_MASK 0x0C
+#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
+#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
+#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
+#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
+#define USB_ENDPOINT_USAGE_MASK 0x30
+#define USB_ENDPOINT_USAGE_DATA 0x00
+#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
+#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
+#define USB_ENDPOINT_USAGE_RESERVED 0x30
+
+/* USB Standard Device Descriptor */
+typedef struct _USB_DEVICE_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR;
+
+/* USB 2.0 Device Qualifier Descriptor */
+typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+} __attribute__ ((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR;
+
+/* USB Standard Configuration Descriptor */
+typedef struct _USB_CONFIGURATION_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR;
+
+/* USB Standard Interface Descriptor */
+typedef struct _USB_INTERFACE_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR;
+
+/* USB Standard Endpoint Descriptor */
+typedef struct _USB_ENDPOINT_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR;
+
+/* USB String Descriptor */
+typedef struct _USB_STRING_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bString /*[] */ ;
+} __attribute__ ((packed)) USB_STRING_DESCRIPTOR;
+
+/* USB Common Descriptor */
+typedef struct _USB_COMMON_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+} __attribute__ ((packed)) USB_COMMON_DESCRIPTOR;
+
+
+#endif /* __CDCUSB_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusbdesc.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusbdesc.h
new file mode 100644
index 0000000..3bb227d
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcusbdesc.h
@@ -0,0 +1,35 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbdesc.h
+ * Purpose: USB Descriptors Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __CDCUSBDESC_H__
+#define __CDCUSBDESC_H__
+
+
+#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
+
+#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR))
+#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR))
+#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR))
+#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR))
+
+extern const uint8_t USB_DeviceDescriptor[];
+extern const uint8_t USB_ConfigDescriptor[];
+extern const uint8_t USB_StringDescriptor[];
+
+
+#endif /* __CDCUSBDESC_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcuser.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcuser.h
new file mode 100644
index 0000000..6887b8b
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/cdcuser.h
@@ -0,0 +1,60 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: cdcuser.h
+ * Purpose: USB Communication Device Class User module Definitions
+ * Version: V1.10
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __CDCUSER_H__
+#define __CDCUSER_H__
+
+/* CDC Data In/Out Endpoint Address */
+#define CDC_DEP_IN 0x83
+#define CDC_DEP_OUT 0x03
+
+/* CDC Communication In Endpoint Address */
+#define CDC_CEP_IN 0x81
+
+/* CDC Requests Callback Functions */
+extern uint32_t CDC_SendEncapsulatedCommand (void);
+extern uint32_t CDC_GetEncapsulatedResponse (void);
+extern uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector);
+extern uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector);
+extern uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector);
+extern uint32_t CDC_GetLineCoding (void);
+extern uint32_t CDC_SetLineCoding (void);
+extern uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap);
+extern uint32_t CDC_SendBreak (unsigned short wDurationOfBreak);
+
+/* CDC Bulk Callback Functions */
+extern void CDC_BulkIn (void);
+extern void CDC_BulkOut (void);
+
+/* FreeRTOS pipe management for CDC ACM */
+#ifdef ENABLE_FREERTOS
+extern BOOL CDC_PutChar (uint8_t data);
+extern portLONG CDC_Recv (portCHAR *cByte, portLONG size, portTickType xTicksToWait);
+extern void CDC_Flush (void);
+#endif/*ENABLE_FREERTOS*/
+
+/* CDC Notification Callback Function */
+extern void CDC_NotificationIn (void);
+
+/* CDC Initializtion Function */
+extern void CDC_Init (void);
+
+/* CDC prepare the SERAIAL_STATE */
+extern unsigned short CDC_GetSerialState (void);
+
+#endif /* __CDCUSER_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbcore.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbcore.h
new file mode 100644
index 0000000..9549b30
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbcore.h
@@ -0,0 +1,57 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbcore.h
+ * Purpose: USB Core Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBCORE_H__
+#define __USBCORE_H__
+
+
+/* USB Endpoint Data Structure */
+typedef struct _USB_EP_DATA
+{
+ uint8_t *pData;
+ uint16_t Count;
+} USB_EP_DATA;
+
+/* USB Core Global Variables */
+extern uint16_t USB_DeviceStatus;
+extern uint8_t USB_DeviceAddress;
+extern uint8_t USB_Configuration;
+extern uint32_t USB_EndPointMask;
+extern uint32_t USB_EndPointHalt;
+extern uint32_t USB_EndPointStall;
+extern uint8_t USB_AltSetting[USB_IF_NUM];
+
+/* USB Endpoint 0 Buffer */
+extern uint8_t EP0Buf[USB_MAX_PACKET0];
+
+/* USB Endpoint 0 Data Info */
+extern USB_EP_DATA EP0Data;
+
+/* USB Setup Packet */
+extern USB_SETUP_PACKET SetupPacket;
+
+/* USB Core Functions */
+extern void USB_ResetCore (void);
+
+/* Newer C compilers make it really difficult to add
+ * an integer to a pointer */
+__inline void UsbAddPtr (void **vpptr, uint32_t n);
+
+
+
+#endif /* __USBCORE_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbhw.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbhw.h
new file mode 100644
index 0000000..e379aa7
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbhw.h
@@ -0,0 +1,95 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbhw.h
+ * Purpose: USB Hardware Layer Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added USB_ClearEPBuf
+ * V1.00 Initial Version
+ *----------------------------------------------------------------------------*/
+
+#ifndef __USBHW_H__
+#define __USBHW_H__
+
+
+/* USB Error Codes */
+#define USB_ERR_PID 0x0001 /* PID Error */
+#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */
+#define USB_ERR_DCRC 0x0004 /* Data CRC Error */
+#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */
+#define USB_ERR_EOP 0x0010 /* End of Packet Error */
+#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */
+#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */
+#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */
+
+/* USB Hardware Functions */
+extern void USBIOClkConfig (void);
+extern void USB_Init (void);
+extern void USB_Connect (uint32_t con);
+extern void USB_Reset (void);
+extern void USB_Suspend (void);
+extern void USB_Resume (void);
+extern void USB_WakeUp (void);
+extern void USB_WakeUpCfg (uint32_t cfg);
+extern void USB_SetAddress (uint32_t adr);
+extern void USB_Configure (uint32_t cfg);
+extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD);
+extern void USB_DirCtrlEP (uint32_t dir);
+extern void USB_EnableEP (uint32_t EPNum);
+extern void USB_DisableEP (uint32_t EPNum);
+extern void USB_ResetEP (uint32_t EPNum);
+extern void USB_SetStallEP (uint32_t EPNum);
+extern void USB_ClrStallEP (uint32_t EPNum);
+extern void USB_ClearEPBuf (uint32_t EPNum);
+extern uint32_t USB_ReadEP (uint32_t EPNum, uint8_t * pData);
+extern void USB_ReadEP_Terminate (uint32_t EPNum);
+extern uint32_t USB_ReadEP_Count (uint32_t EPNum);
+extern uint32_t USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt);
+extern void USB_WriteEP_Terminate (uint32_t EPNum);
+extern void USB_WriteEP_Count (uint32_t EPNum, uint32_t cnt);
+extern uint32_t USB_GetFrame (void);
+extern void USB_IRQHandler (void);
+
+/*
+ * Read USB Endpoint Data
+ * Parameters: none
+ * Return Value: current block data
+ *
+ * Use USB_ReadEPCount to switch Endpoint and get block count
+ *
+ */
+
+static inline uint32_t
+USB_ReadEP_Block (void)
+{
+ return LPC_USB->RxData;
+}
+
+/*
+ * Write USB Endpoint Data
+ * Parameters: data: transmit block data
+ * Return Value: none
+ *
+ * Use USB_ReadEPCount to switch Endpoint and get block count
+ *
+ */
+
+static inline void
+USB_WriteEP_Block (uint32_t data)
+{
+ LPC_USB->TxData = data;
+}
+
+#endif /* __USBHW_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbreg.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbreg.h
new file mode 100644
index 0000000..f2d1000
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbreg.h
@@ -0,0 +1,134 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: USBREG.H
+ * Purpose: USB Hardware Layer Definitions for NXP LPC13xx
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBREG_H
+#define __USBREG_H
+
+/* Device Interrupt Bit Definitions */
+#define FRAME_INT (0x1<<0)
+#define EP0_INT (0x1<<1)
+#define EP1_INT (0x1<<2)
+#define EP2_INT (0x1<<3)
+#define EP3_INT (0x1<<4)
+#define EP4_INT (0x1<<5)
+#define EP5_INT (0x1<<6)
+#define EP6_INT (0x1<<7)
+#define EP7_INT (0x1<<8)
+#define DEV_STAT_INT (0x1<<9)
+#define CCEMTY_INT (0x1<<10)
+#define CDFULL_INT (0x1<<11)
+#define RxENDPKT_INT (0x1<<12)
+#define TxENDPKT_INT (0x1<<13)
+
+/* Rx & Tx Packet Length Definitions */
+#define PKT_LNGTH_MASK 0x000003FF
+#define PKT_DV 0x00000400
+#define PKT_RDY 0x00000800
+
+/* USB Control Definitions */
+#define CTRL_RD_EN 0x00000001
+#define CTRL_WR_EN 0x00000002
+
+/* Command Codes */
+#define CMD_SET_ADDR 0x00D00500
+#define CMD_CFG_DEV 0x00D80500
+#define CMD_SET_MODE 0x00F30500
+#define CMD_RD_INT 0x00F40500
+#define DAT_RD_INT 0x00F40200
+#define CMD_RD_FRAME 0x00F50500
+#define DAT_RD_FRAME 0x00F50200
+#define CMD_RD_CHIP_ID 0x00FD0500
+#define DAT_RD_CHIP_ID 0x00FD0200
+
+#define CMD_SET_DEV_STAT 0x00FE0500
+#define CMD_GET_DEV_STAT 0x00FE0500
+#define DAT_GET_DEV_STAT 0x00FE0200
+#define CMD_GET_ERR_CODE 0x00FF0500
+#define DAT_GET_ERR_CODE 0x00FF0200
+
+#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16))
+#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16))
+#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16))
+#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16))
+#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16))
+#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16))
+#define CMD_CLR_BUF 0x00F20500
+#define CMD_VALID_BUF 0x00FA0500
+
+/* Device Address Register Definitions */
+#define DEV_ADDR_MASK 0x7F
+#define DEV_EN 0x80
+
+/* Device Configure Register Definitions */
+#define CONF_DVICE 0x01
+
+/* Device Mode Register Definitions */
+#define AP_CLK 0x01
+#define INAK_CI 0x02
+#define INAK_CO 0x04
+#define INAK_AI 0x08
+#define INAK_AO 0x10
+
+/* Device Status Register Definitions */
+#define DEV_CON 0x01
+#define DEV_CON_CH 0x02
+#define DEV_SUS 0x04
+#define DEV_SUS_CH 0x08
+#define DEV_RST 0x10
+
+/* Error Code Register Definitions */
+#define ERR_EC_MASK 0x0F
+#define ERR_EA 0x10
+
+/* Error Status Register Definitions */
+#define ERR_NOERROR 0x00
+#define ERR_PID_ENCODE 0x01
+#define ERR_UNKNOWN_PID 0x02
+#define ERR_UNEXPECT_PKT 0x03
+#define ERR_TCRC 0x04
+#define ERR_DCRC 0x05
+#define ERR_TIMEOUT 0x06
+#define ERR_BABBIE 0x07
+#define ERR_EOF_PKT 0x08
+#define ERR_TX_RX_NAK 0x09
+#define ERR_SENT_STALL 0x0A
+#define ERR_BUF_OVERRUN 0x0B
+#define ERR_SENT_EPT_PKT 0x0C
+#define ERR_BIT_STUFF 0x0D
+#define ERR_SYNC 0x0E
+#define ERR_TOGGLE_BIT 0x0F
+
+/* Endpoint Select Register Definitions */
+#define EP_SEL_F 0x01
+#define EP_SEL_ST 0x02
+#define EP_SEL_STP 0x04
+#define EP_SEL_PO 0x08
+#define EP_SEL_EPN 0x10
+#define EP_SEL_B_1_FULL 0x20
+#define EP_SEL_B_2_FULL 0x40
+
+/* Endpoint Status Register Definitions */
+#define EP_STAT_ST 0x01
+#define EP_STAT_DA 0x20
+#define EP_STAT_RF_MO 0x40
+#define EP_STAT_CND_ST 0x80
+
+/* Clear Buffer Register Definitions */
+#define CLR_BUF_PO 0x01
+
+#endif /* __USBREG_H */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usb/usbuser.h b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbuser.h
new file mode 100644
index 0000000..03a429e
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usb/usbuser.h
@@ -0,0 +1,57 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: USBUSER.H
+ * Purpose: USB Custom User Definitions
+ * Version: V1.10
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2005-2009 Keil Software.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBUSER_H__
+#define __USBUSER_H__
+
+
+/* USB Device Events Callback Functions */
+extern void USB_Power_Event (uint32_t power);
+extern void USB_Reset_Event (void);
+extern void USB_Suspend_Event (void);
+extern void USB_Resume_Event (void);
+extern void USB_WakeUp_Event (void);
+extern void USB_SOF_Event (void);
+extern void USB_Error_Event (uint32_t error);
+
+/* USB Endpoint Callback Events */
+#define USB_EVT_SETUP 1 /* Setup Packet */
+#define USB_EVT_OUT 2 /* OUT Packet */
+#define USB_EVT_IN 3 /* IN Packet */
+#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */
+#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */
+#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */
+#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */
+
+/* USB Endpoint Events Callback Pointers */
+extern void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event);
+
+/* USB Endpoint Events Callback Functions */
+extern void USB_EndPoint0 (uint32_t event);
+extern void USB_EndPoint1 (uint32_t event);
+extern void USB_EndPoint2 (uint32_t event);
+extern void USB_EndPoint3 (uint32_t event);
+extern void USB_EndPoint4 (uint32_t event);
+
+/* USB Core Events Callback Functions */
+extern void USB_Configure_Event (void);
+extern void USB_Interface_Event (void);
+extern void USB_Feature_Event (void);
+
+
+#endif /* __USBUSER_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/inc/usbdesc.h b/openbeacon/lpc13xx/core/peripherals/inc/usbdesc.h
new file mode 100644
index 0000000..64a19ba
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/inc/usbdesc.h
@@ -0,0 +1,42 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbdesc.h
+ * Purpose: USB Descriptors Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBDESC_H__
+#define __USBDESC_H__
+
+
+#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
+
+#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR))
+#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR))
+#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR))
+#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR))
+
+#define HID_DESC_OFFSET 0x0012
+#define HID_DESC_SIZE (sizeof(HID_DESCRIPTOR))
+#define HID_REPORT_DESC_SIZE (sizeof(HID_ReportDescriptor))
+
+extern const uint8_t USB_DeviceDescriptor[];
+extern const uint8_t USB_ConfigDescriptor[];
+extern const uint8_t USB_StringDescriptor[];
+
+extern const uint8_t HID_ReportDescriptor[];
+extern const uint16_t HID_ReportDescSize;
+
+
+#endif /* __USBDESC_H__ */
diff --git a/openbeacon/lpc13xx/core/peripherals/src/gpio.c b/openbeacon/lpc13xx/core/peripherals/src/gpio.c
new file mode 100644
index 0000000..e442207
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/src/gpio.c
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * gpio.c: GPIO C file for NXP LPC13xx Family Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.07.20 ver 1.00 Preliminary version, first Release
+ * 2009.12.09 ver 1.05 Mod to use mask registers for GPIO writes + inlining (.h)
+ *
+*****************************************************************************/
+#include "LPC13xx.h" /* LPC13xx Peripheral Registers */
+#include "gpio.h"
+
+LPC_GPIO_TypeDef (*const LPC_GPIO[4]) = {
+ LPC_GPIO0,
+ LPC_GPIO1,
+ LPC_GPIO2,
+ LPC_GPIO3
+};
+
+/*****************************************************************************
+** Function name: GPIOInit
+**
+** Descriptions: Initialize GPIO, install the
+** GPIO interrupt handler
+**
+** parameters: None
+** Returned value: true or false, return false if the VIC table
+** is full and GPIO interrupt handler can be
+** installed.
+**
+*****************************************************************************/
+void GPIOInit(void)
+{
+ /* Enable AHB clock to the GPIO domain. */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6);
+}
+
+/******************************************************************************
+** End Of File
+******************************************************************************/
diff --git a/openbeacon/lpc13xx/core/peripherals/src/uart.c b/openbeacon/lpc13xx/core/peripherals/src/uart.c
new file mode 100644
index 0000000..6b7e34b
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/src/uart.c
@@ -0,0 +1,190 @@
+/*****************************************************************************
+ * uart.c: UART API file for NXP LPC13xx Family Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.08.21 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+#include
+#ifndef UART_DISABLE
+#include "uart.h"
+
+/* CodeRed - change for CMSIS 1.3 */
+#define SystemFrequency SystemCoreClock
+
+volatile uint32_t UARTStatus;
+volatile uint8_t UARTTxEmpty = 1;
+volatile uint8_t UARTBuffer[BUFSIZE];
+volatile uint32_t UARTCount = 0;
+
+/* allow to override default putchar output from serial to something else */
+BOOL default_putchar (uint8_t data) ALIAS(UARTSendChar);
+
+/*****************************************************************************
+** Function name: UART_IRQHandler
+**
+** Descriptions: UART interrupt handler
+**
+** parameters: None
+** Returned value: None
+**
+*****************************************************************************/
+void UART_IRQHandler(void)
+{
+ uint8_t IIRValue, LSRValue;
+ uint8_t Dummy = Dummy;
+
+ IIRValue = LPC_UART->IIR;
+
+ IIRValue >>= 1; /* skip pending bit in IIR */
+ IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
+ if (IIRValue == IIR_RLS) { /* Receive Line Status */
+ LSRValue = LPC_UART->LSR;
+ /* Receive Line Status */
+ if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI)) {
+ /* There are errors or break interrupt */
+ /* Read LSR will clear the interrupt */
+ UARTStatus = LSRValue;
+ Dummy = LPC_UART->RBR; /* Dummy read on RX to clear
+ interrupt, then bail out */
+ return;
+ }
+ if (LSRValue & LSR_RDR) { /* Receive Data Ready */
+ /* If no error on RLS, normal ready, save into the data buffer. */
+ /* Note: read RBR will clear the interrupt */
+ UARTBuffer[UARTCount++] = LPC_UART->RBR;
+ if (UARTCount == BUFSIZE) {
+ UARTCount = 0; /* buffer overflow */
+ }
+ }
+ } else if (IIRValue == IIR_RDA) { /* Receive Data Available */
+ /* Receive Data Available */
+ UARTBuffer[UARTCount++] = LPC_UART->RBR;
+ if (UARTCount == BUFSIZE) {
+ UARTCount = 0; /* buffer overflow */
+ }
+ } else if (IIRValue == IIR_CTI) { /* Character timeout indicator */
+ /* Character Time-out indicator */
+ UARTStatus |= 0x100; /* Bit 9 as the CTI error */
+ } else if (IIRValue == IIR_THRE) { /* THRE, transmit holding register empty */
+ /* THRE interrupt */
+ LSRValue = LPC_UART->LSR; /* Check status in the LSR to see if
+ valid data in U0THR or not */
+ if (LSRValue & LSR_THRE) {
+ UARTTxEmpty = 1;
+ } else {
+ UARTTxEmpty = 0;
+ }
+ }
+ return;
+}
+
+/*****************************************************************************
+** Function name: UARTInit
+**
+** Descriptions: Initialize UART0 port, setup pin select,
+** clock, parity, stop bits, FIFO, etc.
+**
+** parameters: UART baudrate
+** Returned value: None
+**
+*****************************************************************************/
+void UARTInit(uint32_t baudrate, uint8_t rtscts)
+{
+ uint32_t Fdiv;
+ uint32_t regVal;
+
+ UARTTxEmpty = 1;
+ UARTCount = 0;
+
+ NVIC_DisableIRQ(UART_IRQn);
+
+ /* IO configuration */
+ if(rtscts)
+ {
+ LPC_IOCON->PIO0_7=0x01; /* UART CTS */
+ LPC_IOCON->PIO1_5=0x01; /* UART RTS */
+ }
+ LPC_IOCON->PIO1_6=0x01; /* UART RXD */
+ LPC_IOCON->PIO1_7=0x01; /* UART TXD */
+
+ /* Enable UART clock */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12);
+ LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */
+
+ LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
+ regVal = LPC_SYSCON->UARTCLKDIV;
+ Fdiv = (((SystemFrequency / LPC_SYSCON->SYSAHBCLKDIV) / regVal) / 16) / baudrate; /*baud rate */
+
+ LPC_UART->DLM = Fdiv / 256;
+ LPC_UART->DLL = Fdiv % 256;
+ LPC_UART->LCR = 0x03; /* DLAB = 0 */
+ LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
+
+ /* Read to clear the line status. */
+ regVal = LPC_UART->LSR;
+
+ /* Ensure a clean start, no data in either TX or RX FIFO. */
+ // CodeRed - added parentheses around comparison in operand of &
+ while ((LPC_UART->LSR & (LSR_THRE | LSR_TEMT)) !=
+ (LSR_THRE | LSR_TEMT));
+ while (LPC_UART->LSR & LSR_RDR) {
+ regVal = LPC_UART->RBR; /* Dump data from RX FIFO */
+ }
+
+ /* Enable the UART Interrupt */
+ NVIC_EnableIRQ(UART_IRQn);
+
+#if TX_INTERRUPT
+ LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */
+#else
+ LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */
+#endif
+ return;
+}
+
+BOOL UARTSendChar(uint8_t data)
+{
+ while (!(LPC_UART->LSR & LSR_THRE));
+ LPC_UART->THR = data;
+
+ return TRUE;
+}
+
+/*****************************************************************************
+** Function name: UARTSend
+**
+** Descriptions: Send a block of data to the UART 0 port based
+** on the data length
+**
+** parameters: buffer pointer, and data length
+** Returned value: None
+**
+*****************************************************************************/
+void UARTSend(const uint8_t * BufferPtr, uint32_t Length)
+{
+
+ while (Length != 0) {
+ /* THRE status, contain valid data */
+#if !TX_INTERRUPT
+ while (!(LPC_UART->LSR & LSR_THRE));
+ LPC_UART->THR = *BufferPtr;
+#else
+ /* Below flag is set inside the interrupt handler when THRE occurs. */
+ while (!(UARTTxEmpty & 0x01));
+ LPC_UART->THR = *BufferPtr;
+ UARTTxEmpty = 0; /* not empty in the THR until it shifts out */
+#endif
+ BufferPtr++;
+ Length--;
+ }
+ return;
+}
+
+/******************************************************************************
+** End Of File
+******************************************************************************/
+#endif /* UART_DISABLE */
diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/cdcusbdesc.c b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcusbdesc.c
new file mode 100644
index 0000000..022a6ae
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcusbdesc.c
@@ -0,0 +1,204 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbdesc.c
+ * Purpose: USB Descriptors
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Changed string descriptor handling
+ * V1.00 Initial Version
+ *---------------------------------------------------------------------------*/
+#include
+#ifdef ENALBLE_USB_FULLFEATURED
+
+#include "cdcusb.h"
+#include "cdc.h"
+#include "usbcfg.h"
+#include "cdcusbdesc.h"
+
+
+/* USB Standard Device Descriptor */
+const uint8_t USB_DeviceDescriptor[] = {
+ USB_DEVICE_DESC_SIZE, /* bLength */
+ USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL (0x0200), /* 2.0 *//* bcdUSB */
+ USB_DEVICE_CLASS_COMMUNICATIONS, /* bDeviceClass CDC */
+ 0x00, /* bDeviceSubClass */
+ 0x00, /* bDeviceProtocol */
+ USB_MAX_PACKET0, /* bMaxPacketSize0 */
+ WBVAL (USB_VENDOR_ID), /* idVendor */
+ WBVAL (USB_PROD_ID), /* idProduct */
+ WBVAL (USB_DEVICE), /* 1.00 *//* bcdDevice */
+ 0x01, /* iManufacturer */
+ 0x02, /* iProduct */
+ 0x03, /* iSerialNumber */
+ 0x01 /* bNumConfigurations: one possible configuration */
+};
+
+/* USB Configuration Descriptor */
+/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+const uint8_t USB_ConfigDescriptor[] = {
+/* Configuration 1 */
+ USB_CONFIGUARTION_DESC_SIZE, /* bLength */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL ( /* wTotalLength */
+ 1 * USB_CONFIGUARTION_DESC_SIZE + 1 * USB_INTERFACE_DESC_SIZE + /* communication interface */
+ 0x0013 + /* CDC functions */
+ 1 * USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */
+ 1 * USB_INTERFACE_DESC_SIZE + /* data interface */
+ 2 * USB_ENDPOINT_DESC_SIZE /* bulk endpoints */
+ ),
+ 0x02, /* bNumInterfaces */
+ 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */
+ 0x00, /* iConfiguration: no string to describe this configuration */
+ USB_CONFIG_BUS_POWERED /*| *//* bmAttributes */
+/*USB_CONFIG_REMOTE_WAKEUP*/ ,
+ USB_CONFIG_POWER_MA (100), /* bMaxPower, device power consumption is 100 mA */
+/* Interface 0, Alternate Setting 0, Communication class interface descriptor */
+ USB_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */
+ CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */
+ 0x00, /* bInterfaceProtocol: no protocol used */
+ 0x5E, /* iInterface: */
+/*Header Functional Descriptor*/
+ 0x05, /* bLength: Endpoint Descriptor size */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */
+ WBVAL (CDC_V1_10), /* 1.10 *//* bcdCDC */
+/*Call Management Functional Descriptor*/
+ 0x05, /* bFunctionLength */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x01, /* bmCapabilities: device handles call management */
+ 0x01, /* bDataInterface: CDC data IF ID */
+/*Abstract Control Management Functional Descriptor*/
+ 0x04, /* bFunctionLength */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */
+/*Union Functional Descriptor*/
+ 0x05, /* bFunctionLength */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_UNION, /* bDescriptorSubtype: Union func desc */
+ USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */
+ USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */
+ /*Endpoint 1 Descriptor*//* event notification (optional) */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_IN (1), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
+ WBVAL (0x0010), /* wMaxPacketSize */
+ 0x02, /* 2ms *//* bInterval */
+/* Interface 1, Alternate Setting 0, Data class interface descriptor*/
+ USB_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: no alternate setting */
+ 0x02, /* bNumEndpoints: two endpoints used */
+ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */
+ 0x00, /* bInterfaceSubClass: no subclass available */
+ 0x00, /* bInterfaceProtocol: no protocol used */
+ 0x5E, /* iInterface: */
+/* Endpoint, EP3 Bulk Out */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_OUT (3), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
+ WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */
+ 0x00, /* bInterval: ignore for Bulk transfer */
+/* Endpoint, EP3 Bulk In */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_IN (3), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
+ WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */
+ 0x00, /* bInterval: ignore for Bulk transfer */
+/* Terminator */
+ 0 /* bLength */
+};
+
+
+
+
+/* USB String Descriptor (optional) */
+const uint8_t USB_StringDescriptor[] = {
+/* Index 0x00: LANGID Codes */
+ 0x04, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL (0x0409), /* US English *//* wLANGID */
+/* Index 0x01: Manufacturer */
+ (13 * 2 + 2), /* bLength (13 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'B', 0,
+ 'i', 0,
+ 't', 0,
+ 'm', 0,
+ 'a', 0,
+ 'n', 0,
+ 'u', 0,
+ 'f', 0,
+ 'a', 0,
+ 'k', 0,
+ 't', 0,
+ 'u', 0,
+ 'r', 0,
+/* Index 0x02: Product */
+ (17 * 2 + 2), /* bLength ( 17 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'O', 0,
+ 'p', 0,
+ 'e', 0,
+ 'n', 0,
+ 'B', 0,
+ 'e', 0,
+ 'a', 0,
+ 'c', 0,
+ 'o', 0,
+ 'n', 0,
+ ' ', 0,
+ 'C', 0,
+ 'D', 0,
+ 'C', 0,
+ 'A', 0,
+ 'C', 0,
+ 'M', 0,
+/* Index 0x03: Serial Number */
+ (12 * 2 + 2), /* bLength (12 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+ '0', 0,
+/* Index 0x04: Interface 0, Alternate Setting 0 */
+ (4 * 2 + 2), /* bLength (4 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'V', 0,
+ 'C', 0,
+ 'O', 0,
+ 'M', 0,
+};
+
+#endif/*ENALBLE_USB_FULLFEATURED*/
diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/cdcuser.c b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcuser.c
new file mode 100644
index 0000000..29deb4f
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/src/usb/cdcuser.c
@@ -0,0 +1,372 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: cdcuser.c
+ * Purpose: USB Communication Device Class User module
+ * Version: V1.10
+ *----------------------------------------------------------------------------
+* This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#include
+#ifdef ENALBLE_USB_FULLFEATURED
+
+#include "cdcusb.h"
+#include "usbhw.h"
+#include "usbcfg.h"
+#include "usbcore.h"
+#include "cdc.h"
+#include "cdcuser.h"
+
+static CDC_LINE_CODING CDC_LineCoding = { 115200, 0, 0, 8 };
+
+static unsigned short CDC_SerialState = 0x0000;
+static BOOL CDC_DepInEmpty; // Data IN EP is empty
+
+#ifdef ENABLE_FREERTOS
+static xQueueHandle g_QueueRxUSB = NULL;
+static xQueueHandle g_QueueTxUSB = NULL;
+#endif/*ENABLE_FREERTOS*/
+
+/*----------------------------------------------------------------------------
+ CDC Initialisation
+ Initializes the data structures and serial port
+ Parameters: None
+ Return Value: None
+ *---------------------------------------------------------------------------*/
+void
+CDC_Init (void)
+{
+ USBIOClkConfig();
+
+ CDC_DepInEmpty = TRUE;
+ CDC_SerialState = CDC_GetSerialState ();
+
+#ifdef ENABLE_FREERTOS
+ /* Create the queues used to hold Rx and Tx characters. */
+ g_QueueRxUSB = xQueueCreate (USB_CDC_BUFSIZE*2, sizeof (uint8_t));
+ g_QueueTxUSB = xQueueCreate (USB_CDC_BUFSIZE*2, sizeof (uint8_t));
+#endif/*ENABLE_FREERTOS*/
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SendEncapsulatedCommand Request Callback
+ Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request
+ Parameters: None (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SendEncapsulatedCommand (void)
+{
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC GetEncapsulatedResponse Request Callback
+ Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request
+ Parameters: None (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_GetEncapsulatedResponse (void)
+{
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SetCommFeature Request Callback
+ Called automatically on CDC Set_COMM_FATURE Request
+ Parameters: FeatureSelector
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SetCommFeature (unsigned short wFeatureSelector)
+{
+ (void) wFeatureSelector;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC GetCommFeature Request Callback
+ Called automatically on CDC Get_COMM_FATURE Request
+ Parameters: FeatureSelector
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_GetCommFeature (unsigned short wFeatureSelector)
+{
+ (void) wFeatureSelector;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC ClearCommFeature Request Callback
+ Called automatically on CDC CLEAR_COMM_FATURE Request
+ Parameters: FeatureSelector
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_ClearCommFeature (unsigned short wFeatureSelector)
+{
+ (void) wFeatureSelector;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SetLineCoding Request Callback
+ Called automatically on CDC SET_LINE_CODING Request
+ Parameters: none (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SetLineCoding (void)
+{
+ CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0)
+ | (EP0Buf[1] << 8) | (EP0Buf[2] << 16) | (EP0Buf[3] << 24);
+ CDC_LineCoding.bCharFormat = EP0Buf[4];
+ CDC_LineCoding.bParityType = EP0Buf[5];
+ CDC_LineCoding.bDataBits = EP0Buf[6];
+
+ /* configure serial port hardware settings if needed */
+
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC GetLineCoding Request Callback
+ Called automatically on CDC GET_LINE_CODING Request
+ Parameters: None (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_GetLineCoding (void)
+{
+ EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF;
+ EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF;
+ EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF;
+ EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF;
+ EP0Buf[4] = CDC_LineCoding.bCharFormat;
+ EP0Buf[5] = CDC_LineCoding.bParityType;
+ EP0Buf[6] = CDC_LineCoding.bDataBits;
+
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SetControlLineState Request Callback
+ Called automatically on CDC SET_CONTROL_LINE_STATE Request
+ Parameters: ControlSignalBitmap
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SetControlLineState (unsigned short wControlSignalBitmap)
+{
+ (void) wControlSignalBitmap;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SendBreak Request Callback
+ Called automatically on CDC Set_COMM_FATURE Request
+ Parameters: 0xFFFF start of Break
+ 0x0000 stop of Break
+ 0x#### Duration of Break
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SendBreak (unsigned short wDurationOfBreak)
+{
+ (void) wDurationOfBreak;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+#ifdef ENABLE_FREERTOS
+/*----------------------------------------------------------------------------
+ CDC_BulkIn_Handler call on DataIn Request
+ Parameters: from_isr - set true if called from ISR
+ Return Value: none
+ *---------------------------------------------------------------------------*/
+static void
+CDC_BulkIn_Handler(BOOL from_isr)
+{
+ uint8_t* p;
+ uint32_t data, bs;
+ int count;
+ portBASE_TYPE xTaskWoken = pdFALSE;
+
+ if(!from_isr)
+ vPortEnterCritical ();
+
+ count = uxQueueMessagesWaitingFromISR(g_QueueTxUSB);
+ if(count>USB_CDC_BUFSIZE)
+ count = USB_CDC_BUFSIZE;
+
+ if(!count)
+ CDC_DepInEmpty = 1;
+ else
+ {
+ USB_WriteEP_Count (CDC_DEP_IN, count);
+ while(count>0)
+ {
+ if(count>(int)sizeof(data))
+ {
+ bs = sizeof(data);
+ count -= sizeof(data);
+ }
+ else
+ {
+ bs = count;
+ data = count = 0;
+ }
+ p = (uint8_t*) &data;
+ while(bs--)
+ xQueueReceiveFromISR (g_QueueTxUSB,p++, &xTaskWoken);
+
+ USB_WriteEP_Block (data);
+
+ }
+ USB_WriteEP_Terminate (CDC_DEP_IN);
+
+ if(from_isr && xTaskWoken)
+ taskYIELD ();
+ }
+
+ if(!from_isr)
+ vPortExitCritical ();
+}
+
+/*----------------------------------------------------------------------------
+ CDC_BulkIn call on DataIn Request
+ Parameters: none
+ Return Value: none
+ *---------------------------------------------------------------------------*/
+void
+CDC_BulkIn(void)
+{
+ CDC_BulkIn_Handler(TRUE);
+}
+
+void
+CDC_Flush (void)
+{
+ if(CDC_DepInEmpty)
+ CDC_BulkIn_Handler (FALSE);
+}
+
+BOOL
+CDC_PutChar(uint8_t cByte)
+{
+ BOOL res;
+
+ res = xQueueSend (g_QueueTxUSB, &cByte, 0) ? TRUE : FALSE;
+
+ if(cByte == '\n')
+ CDC_Flush ();
+
+ return res;
+}
+
+/*----------------------------------------------------------------------------
+ CDC_BulkOut call on DataOut Request
+ Parameters: none
+ Return Value: none
+ *---------------------------------------------------------------------------*/
+void CDC_BulkOut(void)
+{
+ int count, bs;
+ uint32_t data;
+ uint8_t* p;
+ portBASE_TYPE xTaskWoken = pdFALSE;
+
+ count = USB_ReadEP_Count(CDC_DEP_OUT);
+
+ while (count > 0)
+ {
+ data = USB_ReadEP_Block();
+ bs = count > (int)sizeof(data) ? (int)sizeof(data) : count;
+ count -= bs;
+ p = (uint8_t*) &data;
+ while (bs--)
+ xQueueSendFromISR (g_QueueRxUSB,p++, &xTaskWoken);
+ }
+ USB_ReadEP_Terminate(CDC_DEP_OUT);
+
+ if(xTaskWoken)
+ taskYIELD ();
+}
+
+portLONG CDC_Recv (portCHAR *cByte, portLONG size, portTickType xTicksToWait)
+{
+ portLONG res;
+
+ if (size <= 0 || !cByte || !g_QueueRxUSB)
+ return 0;
+
+ res = 0;
+ while (size-- && xQueueReceive(g_QueueRxUSB, cByte++, xTicksToWait))
+ res++;
+
+ return res;
+}
+#endif/*ENABLE_FREERTOS*/
+
+
+/*----------------------------------------------------------------------------
+ Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69.
+ Parameters: none
+ Return Value: SerialState as defined in usbcdc11.pdf
+ *---------------------------------------------------------------------------*/
+unsigned short
+CDC_GetSerialState (void)
+{
+ return CDC_SerialState;
+}
+
+
+/*----------------------------------------------------------------------------
+ Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5.
+ *---------------------------------------------------------------------------*/
+void
+CDC_NotificationIn (void)
+{
+ uint8_t NotificationBuf[10];
+
+ NotificationBuf[0] = 0xA1; // bmRequestType
+ NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE)
+ NotificationBuf[2] = 0x00; // wValue
+ NotificationBuf[3] = 0x00;
+ NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first)
+ NotificationBuf[5] = 0x00;
+ NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first)
+ NotificationBuf[7] = 0x00;
+ NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first)
+ NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF;
+
+ USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification
+}
+
+#endif /*ENALBLE_USB_FULLFEATURED*/
diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/usbcore.c b/openbeacon/lpc13xx/core/peripherals/src/usb/usbcore.c
new file mode 100644
index 0000000..73b8d49
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/src/usb/usbcore.c
@@ -0,0 +1,1291 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbcore.c
+ * Purpose: USB Core Module
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added vendor specific requests
+ * Changed string descriptor handling
+ * Reworked Endpoint0
+ * V1.00 Initial Version
+ *----------------------------------------------------------------------------*/
+#include
+#ifdef ENALBLE_USB_FULLFEATURED
+
+#include "cdcusb.h"
+#include "usbcfg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "cdcusbdesc.h"
+#include "usbuser.h"
+
+#if (USB_CLASS)
+
+#if (USB_AUDIO)
+#include "audio.h"
+#include "adcuser.h"
+#endif
+
+#if (USB_HID)
+#include "hid.h"
+#include "hiduser.h"
+#endif
+
+#if (USB_MSC)
+#include "msc.h"
+#include "mscuser.h"
+extern MSC_CSW CSW;
+#endif
+
+#if (USB_CDC)
+#include "cdc.h"
+#include "cdcuser.h"
+#endif
+
+#endif
+
+#if (USB_VENDOR)
+#include "vendor.h"
+#endif
+
+uint16_t USB_DeviceStatus;
+uint8_t USB_DeviceAddress;
+uint8_t USB_Configuration;
+uint32_t USB_EndPointMask;
+uint32_t USB_EndPointHalt;
+uint32_t USB_EndPointStall; /* EP must stay stalled */
+uint8_t USB_NumInterfaces;
+uint8_t USB_AltSetting[USB_IF_NUM];
+
+uint8_t EP0Buf[USB_MAX_PACKET0];
+
+
+USB_EP_DATA EP0Data;
+
+USB_SETUP_PACKET SetupPacket;
+
+
+/*
+ * Reset USB Core
+ * Parameters: None
+ * Return Value: None
+ */
+
+void
+USB_ResetCore (void)
+{
+
+ USB_DeviceStatus = USB_POWER;
+ USB_DeviceAddress = 0;
+ USB_Configuration = 0;
+ USB_EndPointMask = 0x00010001;
+ USB_EndPointHalt = 0x00000000;
+ USB_EndPointStall = 0x00000000;
+}
+
+
+/*
+ * USB Request - Setup Stage
+ * Parameters: None (global SetupPacket)
+ * Return Value: None
+ */
+
+void
+USB_SetupStage (void)
+{
+ USB_ReadEP (0x00, (uint8_t *) & SetupPacket);
+}
+
+
+/*
+ * USB Request - Data In Stage
+ * Parameters: None (global EP0Data)
+ * Return Value: None
+ */
+
+void
+USB_DataInStage (void)
+{
+ uint32_t cnt;
+
+ if (EP0Data.Count > USB_MAX_PACKET0)
+ {
+ cnt = USB_MAX_PACKET0;
+ }
+ else
+ {
+ cnt = EP0Data.Count;
+ }
+ cnt = USB_WriteEP (0x80, EP0Data.pData, cnt);
+ EP0Data.pData += cnt;
+ EP0Data.Count -= cnt;
+}
+
+
+/*
+ * USB Request - Data Out Stage
+ * Parameters: None (global EP0Data)
+ * Return Value: None
+ */
+
+void
+USB_DataOutStage (void)
+{
+ uint32_t cnt;
+
+ cnt = USB_ReadEP (0x00, EP0Data.pData);
+ EP0Data.pData += cnt;
+ EP0Data.Count -= cnt;
+}
+
+
+/*
+ * USB Request - Status In Stage
+ * Parameters: None
+ * Return Value: None
+ */
+
+void
+USB_StatusInStage (void)
+{
+ USB_WriteEP (0x80, NULL, 0);
+}
+
+
+/*
+ * USB Request - Status Out Stage
+ * Parameters: None
+ * Return Value: None
+ */
+
+void
+USB_StatusOutStage (void)
+{
+ USB_ReadEP (0x00, EP0Buf);
+}
+
+
+/*
+ * Get Status USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetStatus (void)
+{
+ uint32_t n, m;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ EP0Data.pData = (uint8_t *) & USB_DeviceStatus;
+ break;
+ case REQUEST_TO_INTERFACE:
+ if ((USB_Configuration != 0)
+ && (SetupPacket.wIndex.WB.L < USB_NumInterfaces))
+ {
+ *((uint16_t __attribute__ ((packed)) *) EP0Buf) = 0;
+ EP0Data.pData = EP0Buf;
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ case REQUEST_TO_ENDPOINT:
+ n = SetupPacket.wIndex.WB.L & 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ if (((USB_Configuration != 0) || ((n & 0x0F) == 0))
+ && (USB_EndPointMask & m))
+ {
+ *((uint16_t __attribute__ ((packed)) *) EP0Buf) =
+ (USB_EndPointHalt & m) ? 1 : 0;
+ EP0Data.pData = EP0Buf;
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Set/Clear Feature USB Request
+ * Parameters: sc: 0 - Clear, 1 - Set
+ * (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetClrFeature (uint32_t sc)
+{
+ uint32_t n, m;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP)
+ {
+ if (sc)
+ {
+ USB_WakeUpCfg (TRUE);
+ USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP;
+ }
+ else
+ {
+ USB_WakeUpCfg (FALSE);
+ USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP;
+ }
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ case REQUEST_TO_INTERFACE:
+ return (FALSE);
+ case REQUEST_TO_ENDPOINT:
+ n = SetupPacket.wIndex.WB.L & 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ if ((USB_Configuration != 0) && ((n & 0x0F) != 0)
+ && (USB_EndPointMask & m))
+ {
+ if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL)
+ {
+ if (sc)
+ {
+ USB_SetStallEP (n);
+ USB_EndPointHalt |= m;
+ }
+ else
+ {
+ if ((USB_EndPointStall & m) != 0)
+ {
+ return (TRUE);
+ }
+ USB_ClrStallEP (n);
+#if (USB_MSC)
+ if ((n == MSC_EP_IN) && ((USB_EndPointHalt & m) != 0))
+ {
+ /* Compliance Test: rewrite CSW after unstall */
+ if (CSW.dSignature == MSC_CSW_Signature)
+ {
+ USB_WriteEP (MSC_EP_IN, (uint8_t *) & CSW,
+ sizeof (CSW));
+ }
+ }
+#endif
+ USB_EndPointHalt &= ~m;
+ }
+ }
+ else
+ {
+ return (FALSE);
+ }
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Set Address USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetAddress (void)
+{
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L;
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Get Descriptor USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetDescriptor (void)
+{
+ uint8_t *pD;
+ uint32_t len, n;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ switch (SetupPacket.wValue.WB.H)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ EP0Data.pData = (uint8_t *) USB_DeviceDescriptor;
+ len = USB_DEVICE_DESC_SIZE;
+ break;
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ pD = (uint8_t *) USB_ConfigDescriptor;
+ for (n = 0; n != SetupPacket.wValue.WB.L; n++)
+ {
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength != 0)
+ {
+ pD += ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength;
+ }
+ }
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength == 0)
+ {
+ return (FALSE);
+ }
+ EP0Data.pData = pD;
+ len = ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength;
+ break;
+ case USB_STRING_DESCRIPTOR_TYPE:
+ pD = (uint8_t *) USB_StringDescriptor;
+ for (n = 0; n != SetupPacket.wValue.WB.L; n++)
+ {
+ if (((USB_STRING_DESCRIPTOR *) pD)->bLength != 0)
+ {
+ pD += ((USB_STRING_DESCRIPTOR *) pD)->bLength;
+ }
+ }
+ if (((USB_STRING_DESCRIPTOR *) pD)->bLength == 0)
+ {
+ return (FALSE);
+ }
+ EP0Data.pData = pD;
+ len = ((USB_STRING_DESCRIPTOR *) EP0Data.pData)->bLength;
+ break;
+ default:
+ return (FALSE);
+ }
+ break;
+ case REQUEST_TO_INTERFACE:
+ switch (SetupPacket.wValue.WB.H)
+ {
+#if USB_HID
+ case HID_HID_DESCRIPTOR_TYPE:
+ if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM)
+ {
+ return (FALSE); /* Only Single HID Interface is supported */
+ }
+ EP0Data.pData = (uint8_t *) USB_ConfigDescriptor + HID_DESC_OFFSET;
+ len = HID_DESC_SIZE;
+ break;
+ case HID_REPORT_DESCRIPTOR_TYPE:
+ if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM)
+ {
+ return (FALSE); /* Only Single HID Interface is supported */
+ }
+ EP0Data.pData = (uint8_t *) HID_ReportDescriptor;
+ len = HID_ReportDescSize;
+ break;
+ case HID_PHYSICAL_DESCRIPTOR_TYPE:
+ return (FALSE); /* HID Physical Descriptor is not supported */
+#endif
+ default:
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+
+ if (EP0Data.Count > len)
+ {
+ EP0Data.Count = len;
+ }
+
+ return (TRUE);
+}
+
+
+/*
+ * Get Configuration USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetConfiguration (void)
+{
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ EP0Data.pData = &USB_Configuration;
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Add a number of bytes to a pointer's address
+ * Harder than you might think. Some compilers say:
+ * Expected an lvalue -- Assignment expects its first operand to be
+ * an lvalue. Please note that a cast removes the lvaluedness of an
+ * expression.
+ *
+ * vpptr = void pointer to pointer
+ * n = number of bytes to add to pointer
+ * Call looks like: AddPtr((void **)&myPointer, 8);
+ */
+
+__inline void
+UsbAddPtr (void **vpptr, uint32_t n)
+{
+ /* Declare a pointer to a pointer to a byte. Only a byte pointer
+ * can be incremented by a number of bytes. Other pointers will
+ * increment by a multiple of what they point to.
+ */
+ uint8_t **bpptr;
+
+ /* Convert our void pointer to a pointer to a byte pointer to a pointer */
+ bpptr = (uint8_t **) vpptr;
+
+ /* Add 'n' bytes to our pointer value */
+ (*bpptr) += n;
+}
+
+/*
+ * Set Configuration USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetConfiguration (void)
+{
+ USB_COMMON_DESCRIPTOR *pD;
+ uint32_t alt = 0;
+ uint32_t n, m;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+
+ if (SetupPacket.wValue.WB.L)
+ {
+ pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor;
+ while (pD->bLength)
+ {
+ switch (pD->bDescriptorType)
+ {
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ if (((USB_CONFIGURATION_DESCRIPTOR *)
+ pD)->bConfigurationValue == SetupPacket.wValue.WB.L)
+ {
+ USB_Configuration = SetupPacket.wValue.WB.L;
+ USB_NumInterfaces =
+ ((USB_CONFIGURATION_DESCRIPTOR *) pD)->bNumInterfaces;
+ for (n = 0; n < USB_IF_NUM; n++)
+ {
+ USB_AltSetting[n] = 0;
+ }
+ for (n = 1; n < 16; n++)
+ {
+ if (USB_EndPointMask & (1 << n))
+ {
+ USB_DisableEP (n);
+ }
+ if (USB_EndPointMask & ((1 << 16) << n))
+ {
+ USB_DisableEP (n | 0x80);
+ }
+ }
+ USB_EndPointMask = 0x00010001;
+ USB_EndPointHalt = 0x00000000;
+ USB_EndPointStall = 0x00000000;
+ USB_Configure (TRUE);
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bmAttributes
+ & USB_CONFIG_POWERED_MASK)
+ {
+ USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED;
+ }
+ else
+ {
+ USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED;
+ }
+ }
+ else
+ {
+ UsbAddPtr ((void **) &pD,
+ ((USB_CONFIGURATION_DESCRIPTOR *)
+ pD)->wTotalLength);
+ continue;
+ }
+ break;
+ case USB_INTERFACE_DESCRIPTOR_TYPE:
+ alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting;
+ break;
+ case USB_ENDPOINT_DESCRIPTOR_TYPE:
+ if (alt == 0)
+ {
+ n =
+ ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress &
+ 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ USB_EndPointMask |= m;
+ USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD);
+ USB_EnableEP (n);
+ USB_ResetEP (n);
+ }
+ break;
+ }
+ UsbAddPtr ((void **) &pD, pD->bLength);
+ }
+ }
+ else
+ {
+ USB_Configuration = 0;
+ for (n = 1; n < 16; n++)
+ {
+ if (USB_EndPointMask & (1 << n))
+ {
+ USB_DisableEP (n);
+ }
+ if (USB_EndPointMask & ((1 << 16) << n))
+ {
+ USB_DisableEP (n | 0x80);
+ }
+ }
+ USB_EndPointMask = 0x00010001;
+ USB_EndPointHalt = 0x00000000;
+ USB_EndPointStall = 0x00000000;
+ USB_Configure (FALSE);
+ }
+
+ if (USB_Configuration != SetupPacket.wValue.WB.L)
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Get Interface USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetInterface (void)
+{
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_INTERFACE:
+ if ((USB_Configuration != 0)
+ && (SetupPacket.wIndex.WB.L < USB_NumInterfaces))
+ {
+ EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L;
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Set Interface USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetInterface (void)
+{
+ USB_COMMON_DESCRIPTOR *pD;
+ uint32_t ifn = 0, alt = 0, old = 0, msk = 0;
+ uint32_t n, m;
+ uint32_t set;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_INTERFACE:
+ if (USB_Configuration == 0)
+ return (FALSE);
+ set = FALSE;
+ pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor;
+ while (pD->bLength)
+ {
+ switch (pD->bDescriptorType)
+ {
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bConfigurationValue
+ != USB_Configuration)
+ {
+ UsbAddPtr ((void **) &pD,
+ ((USB_CONFIGURATION_DESCRIPTOR *)
+ pD)->wTotalLength);
+ continue;
+ }
+ break;
+ case USB_INTERFACE_DESCRIPTOR_TYPE:
+ ifn = ((USB_INTERFACE_DESCRIPTOR *) pD)->bInterfaceNumber;
+ alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting;
+ msk = 0;
+ if ((ifn == SetupPacket.wIndex.WB.L)
+ && (alt == SetupPacket.wValue.WB.L))
+ {
+ set = TRUE;
+ old = USB_AltSetting[ifn];
+ USB_AltSetting[ifn] = (uint8_t) alt;
+ }
+ break;
+ case USB_ENDPOINT_DESCRIPTOR_TYPE:
+ if (ifn == SetupPacket.wIndex.WB.L)
+ {
+ n =
+ ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress & 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ if (alt == SetupPacket.wValue.WB.L)
+ {
+ USB_EndPointMask |= m;
+ USB_EndPointHalt &= ~m;
+ USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD);
+ USB_EnableEP (n);
+ USB_ResetEP (n);
+ msk |= m;
+ }
+ else if ((alt == old) && ((msk & m) == 0))
+ {
+ USB_EndPointMask &= ~m;
+ USB_EndPointHalt &= ~m;
+ USB_DisableEP (n);
+ }
+ }
+ break;
+ }
+ UsbAddPtr ((void **) &pD, pD->bLength);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+
+ return (set);
+}
+
+
+/*
+ * USB Endpoint 0 Event Callback
+ * Parameters: event
+ * Return Value: none
+ */
+
+void
+USB_EndPoint0 (uint32_t event)
+{
+
+ switch (event)
+ {
+ case USB_EVT_SETUP:
+ USB_SetupStage ();
+ USB_DirCtrlEP (SetupPacket.bmRequestType.BM.Dir);
+ EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */
+ switch (SetupPacket.bmRequestType.BM.Type)
+ {
+
+ case REQUEST_STANDARD:
+ switch (SetupPacket.bRequest)
+ {
+ case USB_REQUEST_GET_STATUS:
+ if (!USB_ReqGetStatus ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_CLEAR_FEATURE:
+ if (!USB_ReqSetClrFeature (0))
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_FEATURE_EVENT
+ USB_Feature_Event ();
+#endif
+ break;
+
+ case USB_REQUEST_SET_FEATURE:
+ if (!USB_ReqSetClrFeature (1))
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_FEATURE_EVENT
+ USB_Feature_Event ();
+#endif
+ break;
+
+ case USB_REQUEST_SET_ADDRESS:
+ if (!USB_ReqSetAddress ())
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+ break;
+
+ case USB_REQUEST_GET_DESCRIPTOR:
+ if (!USB_ReqGetDescriptor ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_SET_DESCRIPTOR:
+ /*stall_o: */ USB_SetStallEP (0x00);
+ /* not supported */
+ EP0Data.Count = 0;
+ break;
+
+ case USB_REQUEST_GET_CONFIGURATION:
+ if (!USB_ReqGetConfiguration ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_SET_CONFIGURATION:
+ if (!USB_ReqSetConfiguration ())
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_CONFIGURE_EVENT
+ USB_Configure_Event ();
+#endif
+ break;
+
+ case USB_REQUEST_GET_INTERFACE:
+ if (!USB_ReqGetInterface ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_SET_INTERFACE:
+ if (!USB_ReqSetInterface ())
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_INTERFACE_EVENT
+ USB_Interface_Event ();
+#endif
+ break;
+
+ default:
+ goto stall_i;
+ }
+ break; /* end case REQUEST_STANDARD */
+
+#if USB_CLASS
+ case REQUEST_CLASS:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+
+ case REQUEST_TO_DEVICE:
+ goto stall_i; /* not supported */
+
+ case REQUEST_TO_INTERFACE:
+#if USB_HID
+ if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM)
+ { /* IF number correct? */
+ switch (SetupPacket.bRequest)
+ {
+ case HID_REQUEST_GET_REPORT:
+ if (HID_GetReport ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_SET_REPORT:
+ EP0Data.pData = EP0Buf; /* data to be received */
+ goto setup_class_ok;
+ case HID_REQUEST_GET_IDLE:
+ if (HID_GetIdle ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_SET_IDLE:
+ if (HID_SetIdle ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_GET_PROTOCOL:
+ if (HID_GetProtocol ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_SET_PROTOCOL:
+ if (HID_SetProtocol ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_HID */
+#if USB_MSC
+ if (SetupPacket.wIndex.WB.L == USB_MSC_IF_NUM)
+ { /* IF number correct? */
+ switch (SetupPacket.bRequest)
+ {
+ case MSC_REQUEST_RESET:
+ if ((SetupPacket.wValue.W == 0) && /* RESET with invalid parameters -> STALL */
+ (SetupPacket.wLength == 0))
+ {
+ if (MSC_Reset ())
+ {
+ USB_StatusInStage ();
+ goto setup_class_ok;
+ }
+ }
+ break;
+ case MSC_REQUEST_GET_MAX_LUN:
+ if ((SetupPacket.wValue.W == 0) && /* GET_MAX_LUN with invalid parameters -> STALL */
+ (SetupPacket.wLength == 1))
+ {
+ if (MSC_GetMaxLUN ())
+ {
+ EP0Data.pData = EP0Buf;
+ USB_DataInStage ();
+ goto setup_class_ok;
+ }
+ }
+ break;
+ }
+ }
+#endif /* USB_MSC */
+#if USB_AUDIO
+ if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) ||
+ (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_GET_CUR:
+ case AUDIO_REQUEST_GET_MIN:
+ case AUDIO_REQUEST_GET_MAX:
+ case AUDIO_REQUEST_GET_RES:
+ if (ADC_IF_GetRequest ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ EP0Data.pData = EP0Buf; /* data to be received */
+ goto setup_class_ok;
+ }
+ }
+#endif /* USB_AUDIO */
+#if USB_CDC
+ if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case CDC_SEND_ENCAPSULATED_COMMAND:
+ EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */
+ goto setup_class_ok;
+ case CDC_GET_ENCAPSULATED_RESPONSE:
+ if (CDC_GetEncapsulatedResponse ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SET_COMM_FEATURE:
+ EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */
+ goto setup_class_ok;
+ case CDC_GET_COMM_FEATURE:
+ if (CDC_GetCommFeature (SetupPacket.wValue.W))
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_CLEAR_COMM_FEATURE:
+ if (CDC_ClearCommFeature (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SET_LINE_CODING:
+ EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */
+ goto setup_class_ok;
+ case CDC_GET_LINE_CODING:
+ if (CDC_GetLineCoding ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SET_CONTROL_LINE_STATE:
+ if (CDC_SetControlLineState (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SEND_BREAK:
+ if (CDC_SendBreak (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_CDC */
+ goto stall_i; /* not supported */
+ /* end case REQUEST_TO_INTERFACE */
+
+ case REQUEST_TO_ENDPOINT:
+#if USB_AUDIO
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_GET_CUR:
+ case AUDIO_REQUEST_GET_MIN:
+ case AUDIO_REQUEST_GET_MAX:
+ case AUDIO_REQUEST_GET_RES:
+ if (ADC_EP_GetRequest ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ EP0Data.pData = EP0Buf; /* data to be received */
+ goto setup_class_ok;
+ }
+#endif /* USB_AUDIO */
+ goto stall_i;
+ /* end case REQUEST_TO_ENDPOINT */
+
+ default:
+ goto stall_i;
+ }
+ setup_class_ok: /* request finished successfully */
+ break; /* end case REQUEST_CLASS */
+#endif /* USB_CLASS */
+
+#if USB_VENDOR
+ case REQUEST_VENDOR:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+
+ case REQUEST_TO_DEVICE:
+ if (!USB_ReqVendorDev (TRUE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_INTERFACE:
+ if (!USB_ReqVendorIF (TRUE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_ENDPOINT:
+ if (!USB_ReqVendorEP (TRUE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ default:
+ goto stall_i;
+ }
+
+ if (SetupPacket.wLength)
+ {
+ if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST)
+ {
+ USB_DataInStage ();
+ }
+ }
+ else
+ {
+ USB_StatusInStage ();
+ }
+
+ break; /* end case REQUEST_VENDOR */
+#endif /* USB_VENDOR */
+
+ default:
+ stall_i:USB_SetStallEP (0x80);
+ EP0Data.Count = 0;
+ break;
+ }
+ break; /* end case USB_EVT_SETUP */
+
+ case USB_EVT_OUT:
+ if (SetupPacket.bmRequestType.BM.Dir == REQUEST_HOST_TO_DEVICE)
+ {
+ if (EP0Data.Count)
+ { /* still data to receive ? */
+ USB_DataOutStage (); /* receive data */
+ if (EP0Data.Count == 0)
+ { /* data complete ? */
+ switch (SetupPacket.bmRequestType.BM.Type)
+ {
+
+ case REQUEST_STANDARD:
+ goto stall_i; /* not supported */
+
+#if (USB_CLASS)
+ case REQUEST_CLASS:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ goto stall_i; /* not supported */
+
+ case REQUEST_TO_INTERFACE:
+#if USB_HID
+ if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM)
+ { /* IF number correct? */
+ switch (SetupPacket.bRequest)
+ {
+ case HID_REQUEST_SET_REPORT:
+ if (HID_SetReport ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_HID */
+#if USB_AUDIO
+ if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) ||
+ (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ if (ADC_IF_SetRequest ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_AUDIO */
+#if USB_CDC
+ if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case CDC_SEND_ENCAPSULATED_COMMAND:
+ if (CDC_SendEncapsulatedCommand ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ case CDC_SET_COMM_FEATURE:
+ if (CDC_SetCommFeature
+ (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ case CDC_SET_LINE_CODING:
+ if (CDC_SetLineCoding ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_CDC */
+ goto stall_i;
+ /* end case REQUEST_TO_INTERFACE */
+
+ case REQUEST_TO_ENDPOINT:
+#if USB_AUDIO
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ if (ADC_EP_SetRequest ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+#endif /* USB_AUDIO */
+ goto stall_i;
+ /* end case REQUEST_TO_ENDPOINT */
+
+ default:
+ goto stall_i;
+ }
+ out_class_ok: /* request finished successfully */
+ break; /* end case REQUEST_CLASS */
+#endif /* USB_CLASS */
+
+#if USB_VENDOR
+ case REQUEST_VENDOR:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+
+ case REQUEST_TO_DEVICE:
+ if (!USB_ReqVendorDev (FALSE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_INTERFACE:
+ if (!USB_ReqVendorIF (FALSE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_ENDPOINT:
+ if (!USB_ReqVendorEP (FALSE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ default:
+ goto stall_i;
+ }
+
+ USB_StatusInStage ();
+
+ break; /* end case REQUEST_VENDOR */
+#endif /* USB_VENDOR */
+
+ default:
+ goto stall_i;
+ }
+ }
+ }
+ }
+ else
+ {
+ USB_StatusOutStage (); /* receive Acknowledge */
+ }
+ break; /* end case USB_EVT_OUT */
+
+ case USB_EVT_IN:
+ if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST)
+ {
+ USB_DataInStage (); /* send data */
+ }
+ else
+ {
+ if (USB_DeviceAddress & 0x80)
+ {
+ USB_DeviceAddress &= 0x7F;
+ USB_SetAddress (USB_DeviceAddress);
+ }
+ }
+ break; /* end case USB_EVT_IN */
+
+ case USB_EVT_OUT_STALL:
+ USB_ClrStallEP (0x00);
+ break;
+
+ case USB_EVT_IN_STALL:
+ USB_ClrStallEP (0x80);
+ break;
+
+ }
+}
+
+#endif /*ENALBLE_USB_FULLFEATURED*/
diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/usbhw.c b/openbeacon/lpc13xx/core/peripherals/src/usb/usbhw.c
new file mode 100644
index 0000000..f6cb202
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/src/usb/usbhw.c
@@ -0,0 +1,687 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbhw.c
+ * Purpose: USB Hardware Layer Module for Philips LPC17xx
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added USB_ClearEPBuf
+ * V1.00 Initial Version
+ *----------------------------------------------------------------------------*/
+#include
+#ifdef ENALBLE_USB_FULLFEATURED
+
+#include "cdcusb.h"
+#include "usbcfg.h"
+#include "usbreg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "usbuser.h"
+
+
+/*
+ * USB and IO Clock configuration only.
+ * The same as call PeriClkIOInit(IOCON_USB);
+ * The purpose is to reduce the code space for
+ * overall USB project and reserve code space for
+ * USB debugging.
+ * Parameters: None
+ * Return Value: None
+ */
+void
+USBIOClkConfig (void)
+{
+ /* Enable AHB clock to the GPIO domain. */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6);
+
+ /* Enable AHB clock to the USB block. */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 14);
+ LPC_IOCON->PIO0_3 &= ~0x1F;
+ LPC_IOCON->PIO0_3 |= 0x01; /* Secondary function VBUS */
+ LPC_IOCON->PIO0_6 &= ~0x07;
+ LPC_IOCON->PIO0_6 |= 0x01; /* Secondary function SoftConn */
+ return;
+}
+
+/*
+ * Delay number of clock cycles
+ * Parameters: Delay length
+ * Return Value: None
+ */
+
+void
+delay (uint32_t length)
+{
+ volatile uint32_t i;
+
+ for (i = 0; i < length; i++);
+ return;
+}
+
+/*
+ * Get Endpoint Physical Address
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: Endpoint Physical Address
+ */
+
+uint32_t
+EPAdr (uint32_t EPNum)
+{
+ uint32_t val;
+
+ val = (EPNum & 0x0F) << 1;
+ if (EPNum & 0x80)
+ {
+ val += 1;
+ }
+ return (val);
+}
+
+
+/*
+ * Write Command
+ * Parameters: cmd: Command
+ * Return Value: None
+ */
+
+void
+WrCmd (uint32_t cmd)
+{
+
+ LPC_USB->DevIntClr = CCEMTY_INT;
+ LPC_USB->CmdCode = cmd;
+ while ((LPC_USB->DevIntSt & (CCEMTY_INT | DEV_STAT_INT)) == 0);
+}
+
+
+/*
+ * Write Command Data
+ * Parameters: cmd: Command
+ * val: Data
+ * Return Value: None
+ */
+
+void
+WrCmdDat (uint32_t cmd, uint32_t val)
+{
+
+ WrCmd (cmd);
+ WrCmd (val);
+}
+
+
+/*
+ * Write Command to Endpoint
+ * Parameters: cmd: Command
+ * val: Data
+ * Return Value: None
+ */
+
+void
+WrCmdEP (uint32_t EPNum, uint32_t cmd)
+{
+
+ WrCmd (CMD_SEL_EP (EPAdr (EPNum)));
+ WrCmd (cmd);
+}
+
+
+/*
+ * Read Command Data
+ * Parameters: cmd: Command
+ * Return Value: Data Value
+ */
+
+uint32_t
+RdCmdDat (uint32_t cmd)
+{
+
+ LPC_USB->DevIntClr = CCEMTY_INT | CDFULL_INT;
+ LPC_USB->CmdCode = cmd;
+ while ((LPC_USB->DevIntSt & (CDFULL_INT | DEV_STAT_INT)) == 0);
+ return (LPC_USB->CmdData);
+}
+
+
+/*
+ * USB Initialize Function
+ * Called by the User to initialize USB
+ * Return Value: None
+ */
+
+void
+USB_Init (void)
+{
+
+#if USB_FIQ_EVENT
+ /* It's important that only BULK and FRAME(ISO) can be routed
+ to FIQ. */
+ LPC_USB->DevFIQSel = 0x01; /* SOF Use FIQ */
+
+ /* Enable the USB Interrupt */
+ NVIC_EnableIRQ (USB_FIQn);
+#endif
+
+ /* Enable the USB Interrupt */
+ NVIC_EnableIRQ (USB_IRQn);
+
+ USB_Reset ();
+ USB_SetAddress (0);
+ return;
+}
+
+
+/*
+ * USB Connect Function
+ * Called by the User to Connect/Disconnect USB
+ * Parameters: con: Connect/Disconnect
+ * Return Value: None
+ */
+
+void
+USB_Connect (uint32_t con)
+{
+ WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (con ? DEV_CON : 0));
+}
+
+
+/*
+ * USB Reset Function
+ * Called automatically on USB Reset
+ * Return Value: None
+ */
+
+void
+USB_Reset (void)
+{
+
+ LPC_USB->DevIntClr = 0x000FFFFF;
+ /* Enable all eight(8) EPs, note: EP won't be ready until it's
+ configured/enabled when device sending SetEPStatus command
+ to the command engine. */
+ LPC_USB->DevIntEn = DEV_STAT_INT | (0xFF << 1) |
+ (USB_SOF_EVENT ? FRAME_INT : 0);
+ return;
+}
+
+
+/*
+ * USB Suspend Function
+ * Called automatically on USB Suspend
+ * Return Value: None
+ */
+
+void
+USB_Suspend (void)
+{
+ /* Performed by Hardware */
+}
+
+
+/*
+ * USB Resume Function
+ * Called automatically on USB Resume
+ * Return Value: None
+ */
+
+void
+USB_Resume (void)
+{
+ /* Performed by Hardware */
+}
+
+
+/*
+ * USB Remote Wakeup Function
+ * Called automatically on USB Remote Wakeup
+ * Return Value: None
+ */
+
+void
+USB_WakeUp (void)
+{
+
+ if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP)
+ {
+ WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (DEV_CON));
+ }
+}
+
+
+/*
+ * USB Remote Wakeup Configuration Function
+ * Parameters: cfg: Enable/Disable
+ * Return Value: None
+ */
+
+void
+USB_WakeUpCfg (uint32_t cfg)
+{
+ cfg = cfg; /* Not needed */
+}
+
+
+/*
+ * USB Set Address Function
+ * Parameters: adr: USB Address
+ * Return Value: None
+ */
+
+void
+USB_SetAddress (uint32_t adr)
+{
+ WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Don't wait for next */
+ WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Setup Status Phase */
+}
+
+
+/*
+ * USB Configure Function
+ * Parameters: cfg: Configure/Deconfigure
+ * Return Value: None
+ */
+
+void
+USB_Configure (uint32_t cfg)
+{
+
+ WrCmdDat (CMD_CFG_DEV, DAT_WR_BYTE (cfg ? CONF_DVICE : 0));
+ return;
+}
+
+
+/*
+ * Configure USB Endpoint according to Descriptor
+ * Parameters: pEPD: Pointer to Endpoint Descriptor
+ * Return Value: None
+ */
+
+void
+USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD)
+{
+ (void) pEPD;
+ return;
+}
+
+
+/*
+ * Set Direction for USB Control Endpoint
+ * Parameters: dir: Out (dir == 0), In (dir <> 0)
+ * Return Value: None
+ */
+
+void
+USB_DirCtrlEP (uint32_t dir)
+{
+ (void) dir;
+}
+
+
+/*
+ * Enable USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_EnableEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0));
+}
+
+
+/*
+ * Disable USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_DisableEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_DA));
+}
+
+
+/*
+ * Reset USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_ResetEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0));
+}
+
+
+/*
+ * Set Stall for USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_SetStallEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_ST));
+}
+
+
+/*
+ * Clear Stall for USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_ClrStallEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0));
+}
+
+
+/*
+ * Clear USB Endpoint Buffer
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_ClearEPBuf (uint32_t EPNum)
+{
+ WrCmdEP (EPNum, CMD_CLR_BUF);
+}
+
+
+/*
+ * Read USB Endpoint Size
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: Number of bytes read
+ */
+
+uint32_t
+USB_ReadEP_Count (uint32_t EPNum)
+{
+ uint32_t cnt;
+
+ LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN;
+ /* 3 clock cycles to fetch the packet length from RAM. */
+ delay (5);
+
+ while(((cnt = LPC_USB->RxPLen) & PKT_DV) == 0);
+
+ return cnt & PKT_LNGTH_MASK;
+}
+
+
+/*
+ * Read USB Endpoint Data: Finalize Read
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: Number of bytes read
+ *
+ *
+ */
+
+void
+USB_ReadEP_Terminate (uint32_t EPNum)
+{
+ LPC_USB->Ctrl = 0;
+
+ WrCmdEP (EPNum, CMD_CLR_BUF);
+}
+
+
+/*
+ * Read USB Endpoint Data
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * pData: Pointer to Data Buffer
+ * Return Value: Number of bytes read
+ */
+
+uint32_t
+USB_ReadEP (uint32_t EPNum, uint8_t * pData)
+{
+ uint32_t res, cnt, data;
+ uint8_t* p;
+
+ res = cnt = USB_ReadEP_Count (EPNum);
+
+ while(cnt>=sizeof(uint32_t))
+ {
+ *((uint32_t __attribute__ ((packed)) *) pData) = USB_ReadEP_Block ();
+ pData += sizeof(uint32_t);
+ cnt-=sizeof(uint32_t);
+ }
+
+ if(cnt>0)
+ {
+ data = USB_ReadEP_Block ();
+ p = (uint8_t*)&data;
+ while(cnt--)
+ *pData++ = *p++;
+ }
+
+ USB_ReadEP_Terminate (EPNum);
+
+ return res;
+}
+
+
+void
+USB_WriteEP_Count (uint32_t EPNum, uint32_t cnt)
+{
+ LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
+ /* 3 clock cycles to fetch the packet length from RAM. */
+ delay (5);
+ LPC_USB->TxPLen = cnt;
+}
+
+
+void
+USB_WriteEP_Terminate (uint32_t EPNum)
+{
+ LPC_USB->Ctrl = 0;
+
+ WrCmdEP (EPNum, CMD_VALID_BUF);
+}
+
+
+/*
+ * Write USB Endpoint Data
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * pData: Pointer to Data Buffer
+ * cnt: Number of bytes to write
+ * Return Value: Number of bytes written
+ */
+
+uint32_t
+USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt)
+{
+ uint32_t n;
+
+ USB_WriteEP_Count (EPNum, cnt);
+
+ for (n = 0; n < (cnt + 3) / 4; n++)
+ {
+ USB_WriteEP_Block (*((uint32_t __attribute__ ((packed)) *) pData));
+ pData += sizeof(uint32_t);
+ }
+
+ USB_WriteEP_Terminate (EPNum);
+
+ return cnt;
+}
+
+/*
+ * Get USB Last Frame Number
+ * Parameters: None
+ * Return Value: Frame Number
+ */
+
+uint32_t
+USB_GetFrame (void)
+{
+ uint32_t val;
+
+ WrCmd (CMD_RD_FRAME);
+ val = RdCmdDat (DAT_RD_FRAME);
+ val = val | (RdCmdDat (DAT_RD_FRAME) << 8);
+
+ return (val);
+}
+
+
+/*
+ * USB Interrupt Service Routine
+ */
+
+void
+USB_IRQHandler (void)
+{
+ uint32_t disr, val, n, m;
+
+ disr = LPC_USB->DevIntSt; /* Device Interrupt Status */
+ LPC_USB->DevIntClr = disr;
+
+ /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
+ if (disr & DEV_STAT_INT)
+ {
+ WrCmd (CMD_GET_DEV_STAT);
+ val = RdCmdDat (DAT_GET_DEV_STAT); /* Device Status */
+ if (val & DEV_RST)
+ { /* Reset */
+ USB_Reset ();
+#if USB_RESET_EVENT
+ USB_Reset_Event ();
+#endif
+ }
+ if (val & DEV_CON_CH)
+ { /* Connect change */
+#if USB_POWER_EVENT
+ USB_Power_Event (val & DEV_CON);
+#endif
+ }
+ if (val & DEV_SUS_CH)
+ { /* Suspend/Resume */
+ if (val & DEV_SUS)
+ { /* Suspend */
+ USB_Suspend ();
+#if USB_SUSPEND_EVENT
+ USB_Suspend_Event ();
+#endif
+ }
+ else
+ { /* Resume */
+ USB_Resume ();
+#if USB_RESUME_EVENT
+ USB_Resume_Event ();
+#endif
+ }
+ }
+ goto isr_end;
+ }
+
+#if USB_SOF_EVENT
+ /* Start of Frame Interrupt */
+ if (disr & FRAME_INT)
+ {
+ LPC_USB->DevIntClr = FRAME_INT;
+ USB_SOF_Event ();
+ SOFIRQCount++;
+ }
+#endif
+
+#if USB_ERROR_EVENT
+ /* NO error interrupt anymore, below code can be used
+ as example to get error status from command engine. */
+ /* Error Interrupt */
+ if (disr & ERR_INT)
+ {
+ WrCmd (CMD_RD_ERR_STAT);
+ val = RdCmdDat (DAT_RD_ERR_STAT);
+ USB_Error_Event (val);
+ }
+#endif
+
+ /* Endpoint's Interrupt */
+ if (disr & (0xFF << 1))
+ {
+ /* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */
+ for (n = 0; n < USB_EP_NUM; n++)
+ { /* Check All Endpoints */
+ /* skip frame interrupt at bit 0 in disr */
+// if (disr & ((1 << n)<<1)) {
+ if ((disr >> 1) & (1 << n))
+ {
+ m = n >> 1;
+ /* clear EP interrupt by sending cmd to the command engine. */
+ WrCmd (CMD_SEL_EP_CLRI (n));
+ val = RdCmdDat (DAT_SEL_EP_CLRI (n));
+ if ((n & 1) == 0)
+ { /* OUT Endpoint */
+ if (n == 0)
+ { /* Control OUT Endpoint */
+ if (val & EP_SEL_STP)
+ { /* Setup Packet */
+ if (USB_P_EP[0])
+ {
+ USB_P_EP[0] (USB_EVT_SETUP);
+ continue;
+ }
+ }
+ }
+ if (USB_P_EP[m])
+ {
+ USB_P_EP[m] (USB_EVT_OUT);
+ }
+ }
+ else
+ { /* IN Endpoint */
+ if (USB_P_EP[m])
+ {
+ USB_P_EP[m] (USB_EVT_IN);
+ }
+ }
+ }
+ }
+ }
+isr_end:
+ return;
+}
+
+#endif /*ENALBLE_USB_FULLFEATURED*/
diff --git a/openbeacon/lpc13xx/core/peripherals/src/usb/usbuser.c b/openbeacon/lpc13xx/core/peripherals/src/usb/usbuser.c
new file mode 100644
index 0000000..d97f466
--- /dev/null
+++ b/openbeacon/lpc13xx/core/peripherals/src/usb/usbuser.c
@@ -0,0 +1,234 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbuser.c
+ * Purpose: USB Custom User Module
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+#include
+#ifdef ENALBLE_USB_FULLFEATURED
+
+#include "cdcusb.h"
+#include "usbcfg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "usbuser.h"
+#include "cdcuser.h"
+
+
+/*
+ * USB Power Event Callback
+ * Called automatically on USB Power Event
+ * Parameter: power: On(TRUE)/Off(FALSE)
+ */
+
+#if USB_POWER_EVENT
+void
+USB_Power_Event (uint32_t power)
+{
+}
+#endif
+
+
+/*
+ * USB Reset Event Callback
+ * Called automatically on USB Reset Event
+ */
+
+#if USB_RESET_EVENT
+void
+USB_Reset_Event (void)
+{
+ USB_ResetCore ();
+}
+#endif
+
+
+/*
+ * USB Suspend Event Callback
+ * Called automatically on USB Suspend Event
+ */
+
+#if USB_SUSPEND_EVENT
+void
+USB_Suspend_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Resume Event Callback
+ * Called automatically on USB Resume Event
+ */
+
+#if USB_RESUME_EVENT
+void
+USB_Resume_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Remote Wakeup Event Callback
+ * Called automatically on USB Remote Wakeup Event
+ */
+
+#if USB_WAKEUP_EVENT
+void
+USB_WakeUp_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Start of Frame Event Callback
+ * Called automatically on USB Start of Frame Event
+ */
+
+#if USB_SOF_EVENT
+void
+USB_SOF_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Error Event Callback
+ * Called automatically on USB Error Event
+ * Parameter: error: Error Code
+ */
+
+#if USB_ERROR_EVENT
+void
+USB_Error_Event (uint32_t error)
+{
+}
+#endif
+
+
+/*
+ * USB Set Configuration Event Callback
+ * Called automatically on USB Set Configuration Request
+ */
+
+#if USB_CONFIGURE_EVENT
+void
+USB_Configure_Event (void)
+{
+
+ if (USB_Configuration)
+ { /* Check if USB is configured */
+ /* add your code here */
+ }
+}
+#endif
+
+
+/*
+ * USB Set Interface Event Callback
+ * Called automatically on USB Set Interface Request
+ */
+
+#if USB_INTERFACE_EVENT
+void
+USB_Interface_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Set/Clear Feature Event Callback
+ * Called automatically on USB Set/Clear Feature Request
+ */
+
+#if USB_FEATURE_EVENT
+void
+USB_Feature_Event (void)
+{
+}
+#endif
+
+
+#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL)
+
+/* USB Endpoint Events Callback Pointers */
+void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) =
+{
+P_EP (0), P_EP (1), P_EP (2), P_EP (3), P_EP (4),};
+
+
+/*
+ * USB Endpoint 1 Event Callback
+ * Called automatically on USB Endpoint 1 Event
+ * Parameter: event
+ */
+
+void
+USB_EndPoint1 (uint32_t event)
+{
+ uint16_t temp;
+ static uint16_t serialState;
+
+ switch (event)
+ {
+ case USB_EVT_IN:
+ temp = CDC_GetSerialState ();
+ if (serialState != temp)
+ {
+ serialState = temp;
+ CDC_NotificationIn (); /* send SERIAL_STATE notification */
+ }
+ break;
+ }
+}
+
+
+/*
+ * USB Endpoint 2 Event Callback
+ * Called automatically on USB Endpoint 2 Event
+ * Parameter: event
+ */
+
+void
+USB_EndPoint2 (uint32_t event)
+{
+ (void) event;
+}
+
+
+/*
+ * USB Endpoint 3 Event Callback
+ * Called automatically on USB Endpoint 3 Event
+ * Parameter: event
+ */
+
+void
+USB_EndPoint3 (uint32_t event)
+{
+ switch (event)
+ {
+ case USB_EVT_OUT:
+ CDC_BulkOut (); /* data received from Host */
+ break;
+ case USB_EVT_IN:
+ CDC_BulkIn (); /* data expected from Host */
+ break;
+ }
+}
+
+#endif /*ENALBLE_USB_FULLFEATURED*/
diff --git a/openbeacon/lpc13xx/core/startup/LPC13xx.c b/openbeacon/lpc13xx/core/startup/LPC13xx.c
new file mode 100644
index 0000000..1f1a225
--- /dev/null
+++ b/openbeacon/lpc13xx/core/startup/LPC13xx.c
@@ -0,0 +1,368 @@
+//*****************************************************************************
+// +--+
+// | ++----+
+// +-++ |
+// | |
+// +-+--+ |
+// | +--+--+
+// +----+ 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)))
+
+// Code Red - if CMSIS is being used, then SystemInit() routine
+// will be called by startup code rather than in application's main()
+#ifdef __USE_CMSIS
+#include "system_LPC13xx.h"
+#endif
+
+//*****************************************************************************
+//
+// Forward declaration of the default handlers. These are aliased.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions
+//
+//*****************************************************************************
+void Reset_Handler(void);
+void ResetISR(void) ALIAS(Reset_Handler);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void MemManage_Handler(void);
+WEAK void BusFault_Handler(void);
+WEAK void UsageFault_Handler(void);
+WEAK void SVCall_Handler(void);
+WEAK void DebugMon_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_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 I2C_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER16_0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER16_1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER32_0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void TIMER32_1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SSP_IRQHandler(void) ALIAS(IntDefaultHandler);
+void UART_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USB_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USB_FIQHandler(void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
+void FMC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIOINT3_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIOINT2_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIOINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIOINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
+
+void WAKEUP_IRQHandlerPIO0_0 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_1 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_2 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_3 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_4 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_5 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_6 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_7 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_8 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_9 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_10(void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO0_11(void) ALIAS(IntDefaultHandler);
+
+void WAKEUP_IRQHandlerPIO1_0 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_1 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_2 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_3 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_4 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_5 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_6 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_7 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_8 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_9 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_10(void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO1_11(void) ALIAS(IntDefaultHandler);
+
+void WAKEUP_IRQHandlerPIO2_0 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_1 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_2 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_3 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_4 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_5 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_6 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_7 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_8 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_9 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_10(void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO2_11(void) ALIAS(IntDefaultHandler);
+
+void WAKEUP_IRQHandlerPIO3_0 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO3_1 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO3_2 (void) ALIAS(IntDefaultHandler);
+void WAKEUP_IRQHandlerPIO3_3 (void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+//
+// 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 void __stack_end__(void);
+
+//*****************************************************************************
+//
+// The vector table. Note that the proper constructs must be placed on this to
+// ensure that it ends up at physical address 0x0000.0000.
+//
+//*****************************************************************************
+__attribute__ ((section(".isr_vector")))
+void (*const g_pfnVectors[]) (void) =
+{
+ // Core Level - CM3
+ __stack_end__, // 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
+ SVCall_Handler, // SVCall handler
+ DebugMon_Handler, // Debug monitor handler
+ 0, // Reserved
+ PendSV_Handler, // The PendSV handler
+ SysTick_Handler, // The SysTick handler
+ // Wakeup sources (40 ea.) for the I/O pins:
+ // PIO0 (0:11)
+ // PIO1 (0:11)
+ // PIO2 (0:11)
+ // PIO3 (0:3)
+ WAKEUP_IRQHandlerPIO0_0, // PIO0_0 Wakeup
+ WAKEUP_IRQHandlerPIO0_1, // PIO0_1 Wakeup
+ WAKEUP_IRQHandlerPIO0_2, // PIO0_2 Wakeup
+ WAKEUP_IRQHandlerPIO0_3, // PIO0_3 Wakeup
+ WAKEUP_IRQHandlerPIO0_4, // PIO0_4 Wakeup
+ WAKEUP_IRQHandlerPIO0_5, // PIO0_5 Wakeup
+ WAKEUP_IRQHandlerPIO0_6, // PIO0_6 Wakeup
+ WAKEUP_IRQHandlerPIO0_7, // PIO0_7 Wakeup
+ WAKEUP_IRQHandlerPIO0_8, // PIO0_8 Wakeup
+ WAKEUP_IRQHandlerPIO0_9, // PIO0_9 Wakeup
+ WAKEUP_IRQHandlerPIO0_10, // PIO0_10 Wakeup
+ WAKEUP_IRQHandlerPIO0_11, // PIO0_11 Wakeup
+ WAKEUP_IRQHandlerPIO1_0, // PIO1_0 Wakeup
+ WAKEUP_IRQHandlerPIO1_1, // PIO1_1 Wakeup
+ WAKEUP_IRQHandlerPIO1_2, // PIO1_2 Wakeup
+ WAKEUP_IRQHandlerPIO1_3, // PIO1_3 Wakeup
+ WAKEUP_IRQHandlerPIO1_4, // PIO1_4 Wakeup
+ WAKEUP_IRQHandlerPIO1_5, // PIO1_5 Wakeup
+ WAKEUP_IRQHandlerPIO1_6, // PIO1_6 Wakeup
+ WAKEUP_IRQHandlerPIO1_7, // PIO1_7 Wakeup
+ WAKEUP_IRQHandlerPIO1_8, // PIO1_8 Wakeup
+ WAKEUP_IRQHandlerPIO1_9, // PIO1_9 Wakeup
+ WAKEUP_IRQHandlerPIO1_10, // PIO1_10 Wakeup
+ WAKEUP_IRQHandlerPIO1_11, // PIO1_11 Wakeup
+ WAKEUP_IRQHandlerPIO2_0, // PIO2_0 Wakeup
+ WAKEUP_IRQHandlerPIO2_1, // PIO2_1 Wakeup
+ WAKEUP_IRQHandlerPIO2_2, // PIO2_2 Wakeup
+ WAKEUP_IRQHandlerPIO2_3, // PIO2_3 Wakeup
+ WAKEUP_IRQHandlerPIO2_4, // PIO2_4 Wakeup
+ WAKEUP_IRQHandlerPIO2_5, // PIO2_5 Wakeup
+ WAKEUP_IRQHandlerPIO2_6, // PIO2_6 Wakeup
+ WAKEUP_IRQHandlerPIO2_7, // PIO2_7 Wakeup
+ WAKEUP_IRQHandlerPIO2_8, // PIO2_8 Wakeup
+ WAKEUP_IRQHandlerPIO2_9, // PIO2_9 Wakeup
+ WAKEUP_IRQHandlerPIO2_10, // PIO2_10 Wakeup
+ WAKEUP_IRQHandlerPIO2_11, // PIO2_11 Wakeup
+ WAKEUP_IRQHandlerPIO3_0, // PIO3_0 Wakeup
+ WAKEUP_IRQHandlerPIO3_1, // PIO3_1 Wakeup
+ WAKEUP_IRQHandlerPIO3_2, // PIO3_2 Wakeup
+ WAKEUP_IRQHandlerPIO3_3, // PIO3_3 Wakeup
+ I2C_IRQHandler, // I2C0
+ TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0)
+ TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1)
+ TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0)
+ TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1)
+ SSP_IRQHandler, // SSP0
+ UART_IRQHandler, // UART0
+ USB_IRQHandler, // USB IRQ
+ USB_FIQHandler, // USB FIQ
+ ADC_IRQHandler, // ADC (A/D Converter)
+ WDT_IRQHandler, // WDT (Watchdog Timer)
+ BOD_IRQHandler, // BOD (Brownout Detect)
+ FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller)
+ PIOINT3_IRQHandler, // PIO INT3
+ PIOINT2_IRQHandler, // PIO INT2
+ PIOINT1_IRQHandler, // PIO INT1
+ PIOINT0_IRQHandler, // PIO INT0
+};
+
+//*****************************************************************************
+//
+// 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 __end_of_text__;
+extern unsigned long __data_beg__;
+extern unsigned long __data_end__;
+extern unsigned long __bss_beg__;
+extern unsigned long __bss_end__;
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor first starts execution
+// following a reset event. Only the absolutely necessary set is performed,
+// after which the application supplied entry() routine is called. Any fancy
+// actions (such as making decisions based on the reset cause register, and
+// resetting the bits in that register) are left solely in the hands of the
+// application.
+//
+//*****************************************************************************
+void
+//ResetISR(void)
+Reset_Handler(void)
+{
+ unsigned long *pulSrc, *pulDest;
+
+ //
+ // Copy the data segment initializers from flash to SRAM.
+ //
+ pulSrc = &__end_of_text__;
+ for (pulDest = &__data_beg__; pulDest < &__data_end__;) {
+ *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_beg__\n" " ldr r1, =__bss_end__\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");
+
+#ifdef __USE_CMSIS
+ SystemInit();
+#endif
+
+ 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.
+//
+//*****************************************************************************
+void NMI_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void HardFault_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void MemManage_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void BusFault_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void UsageFault_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void SVCall_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void DebugMon_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void PendSV_Handler(void)
+{
+ while (1) {
+ }
+}
+
+void SysTick_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/openbeacon/lpc13xx/drivers/bitmanufaktur.inf b/openbeacon/lpc13xx/drivers/bitmanufaktur.inf
new file mode 100644
index 0000000..1d9afe4
--- /dev/null
+++ b/openbeacon/lpc13xx/drivers/bitmanufaktur.inf
@@ -0,0 +1,60 @@
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%BITMANUFAKTUR%
+DriverVer=28/03/11
+
+[Manufacturer]
+%BITMANUFAKTUR%=BitmanufakturDevices
+
+[DestinationDirs]
+DefaultDestDir=12
+
+[SourceDisksFiles]
+
+[SourceDisksNames]
+
+[BitmanufakturDevices]
+%OPENBEACON_USB2%=OpenBeacon_CDC_ACM, USB\VID_2366&PID_0002
+%OPENPCD2_BASIC%=OpenBeacon_CDC_ACM, USB\VID_2366&PID_0003
+
+;------------------------------------------------------------------------------
+; Windows 2000/XP Sections
+;------------------------------------------------------------------------------
+
+[OpenBeacon_CDC_ACM.nt]
+include=mdmcpq.inf
+CopyFiles=DriverCopyFiles
+AddReg=OpenBeacon_CDC_ACM.nt.AddReg
+
+[DriverCopyFiles]
+usbser.sys,,,0x20
+
+[OpenBeacon_CDC_ACM.nt.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[OpenBeacon_CDC_ACM.nt.Services]
+include=mdmcpq.inf
+AddService=usbser, 0x00000002, DriverService
+
+[OpenBeacon_CDC_ACM.nt.HW]
+include=mdmcpq.inf
+
+[DriverService]
+DisplayName=%DESCRIPTION%
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\usbser.sys
+
+;------------------------------------------------------------------------------
+; String Definitions
+;------------------------------------------------------------------------------
+
+[Strings]
+BITMANUFAKTUR="Bitmanufaktur GmbH"
+OPENPCD2_BASIC="OpenPCD 2 basic RFID Reader for 13.56MHz"
+OPENBEACON_USB2="OpenBeacon USB 2 active 2.4GHz RFID"
diff --git a/openbeacon/lpc13xx/hid-client/Makefile b/openbeacon/lpc13xx/hid-client/Makefile
new file mode 100644
index 0000000..23e8535
--- /dev/null
+++ b/openbeacon/lpc13xx/hid-client/Makefile
@@ -0,0 +1,68 @@
+PROG = hid_listen
+
+OS = LINUX
+#OS = DARWIN
+#OS = WINDOWS
+
+
+ifeq ($(OS), LINUX)
+TARGET = $(PROG)
+CC = gcc
+STRIP = strip
+CFLAGS = -O2 -Wall -D$(OS)
+LIBS =
+else ifeq ($(OS), DARWIN)
+TARGET = $(PROG)
+CC = gcc
+STRIP = strip
+SDK = /Developer/SDKs/MacOSX10.5.sdk
+CFLAGS = -O2 -Wall -isysroot $(SDK) -D$(OS) -arch ppc -arch i386
+LIBS = -Xlinker -syslibroot -Xlinker $(SDK) -framework IOKit -framework CoreFoundation
+else ifeq ($(OS), WINDOWS)
+TARGET = $(PROG).exe
+CC = i586-mingw32msvc-gcc
+STRIP = i586-mingw32msvc-strip
+WINDRES = i586-mingw32msvc-windres
+CFLAGS = -O2 -Wall -D$(OS)
+LIBS = -lhid -lsetupapi
+KEY_SPC = ~/bin/cert/mykey.spc
+KEY_PVK = ~/bin/cert/mykey.pvk
+KEY_TS = http://timestamp.comodoca.com/authenticode
+endif
+
+
+MAKEFLAGS = --jobs=2
+OBJS = hid_listen.o rawhid.o
+
+all: $(TARGET)
+
+$(PROG): $(OBJS)
+ gcc -o $(PROG) $(OBJS) $(LIBS)
+ $(STRIP) $(PROG)
+
+$(PROG).app: $(PROG) Info.plist
+ mkdir -p $(PROG).app/Contents/MacOS
+ mkdir -p $(PROG).app/Contents/Resources/English.lproj
+ cp Info.plist $(PROG).app/Contents/
+ echo -n 'APPL????' > $(PROG).app/Contents/PkgInfo
+ cp $(PROG) $(PROG).app/Contents/MacOS/$(PROG)
+ cp icons/$(PROG).icns $(PROG).app/Contents/Resources/$(PROG).icns
+ touch $(PROG).app
+
+$(PROG).dmg: $(PROG).app
+ hdiutil create -ov -srcfolder $(PROG).app $(PROG).dmg
+
+$(PROG).exe: $(OBJS)
+ $(CC) $(OBJS) -o $(PROG).exe $(LIBS)
+ $(STRIP) $(PROG).exe
+ -signcode -spc $(KEY_SPC) -v $(KEY_PVK) -t $(KEY_TS) $(PROG).exe
+
+resource.o: resource.rs icons/$(PROG).ico
+ $(WINDRES) -o resource.o resource.rs
+
+
+
+clean:
+ rm -f *.o $(PROG) $(PROG).exe $(PROG).exe.bak $(PROG).dmg
+ rm -rf $(PROG).app
+
diff --git a/openbeacon/lpc13xx/hid-client/hid_listen.c b/openbeacon/lpc13xx/hid-client/hid_listen.c
new file mode 100644
index 0000000..a313ca7
--- /dev/null
+++ b/openbeacon/lpc13xx/hid-client/hid_listen.c
@@ -0,0 +1,65 @@
+/* HID Listen, http://www.pjrc.com/teensy/hid_listen.html
+ * Listens (and prints) all communication received from a USB HID device,
+ * which is useful for view debug messages from the Teensy USB Board.
+ * Copyright 2008, PJRC.COM, LLC
+ *
+ * You may redistribute this program and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/
+ */
+
+#include
+#include
+#include
+#include
+#include "rawhid.h"
+
+static void delay_ms(unsigned int msec)
+{
+ usleep(msec * 1000);
+}
+
+int main(void)
+{
+ unsigned char buf[64],prev;
+ rawhid_t *hid;
+ int num, count;
+
+ printf("Waiting for device:");
+ fflush(stdout);
+ prev=0;
+ while (1) {
+ hid = rawhid_open_only1(0x16c0, 0x08b4, 0,0);
+ if (hid == NULL) {
+ printf(".");
+ fflush(stdout);
+ delay_ms(1000);
+ continue;
+ }
+ printf("\nListening:\n");
+ while (1) {
+ num = rawhid_read(hid, buf, sizeof(buf), 200);
+ if (num < 0) break;
+ if (num == 0) continue;
+ if(prev==buf[0]) continue;
+ prev=buf[0];
+ printf("RX:");
+ for (count=0; count
+#include
+#include
+#include
+#include "rawhid.h"
+
+#ifdef OPERATING_SYSTEM
+#undef OPERATING_SYSTEM
+#endif
+
+
+/*************************************************************************/
+/** **/
+/** Linux **/
+/** **/
+/*************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct rawhid_struct {
+ int fd;
+ int name;
+ int isok;
+};
+
+rawhid_t * rawhid_open_only1(int vid, int pid, int usage_page, int usage)
+{
+ struct rawhid_struct *hid;
+ struct stat devstat;
+ struct hidraw_devinfo info;
+ struct hidraw_report_descriptor *desc;
+ char buf[512];
+ int r, i, fd=-1, len, found=0;
+
+ printf("Searching for device using hidraw....\n");
+ for (i=0; i 0) close(fd);
+ snprintf(buf, sizeof(buf), "/dev/hidraw%d", i);
+ r = stat(buf, &devstat);
+ if (r < 0) continue;
+ printf("device: %s\n", buf);
+ fd = open(buf, O_RDWR);
+ if (fd < 0) continue;
+ printf(" opened\n");
+ r = ioctl(fd, HIDIOCGRAWINFO, &info);
+ if (r < 0) continue;
+ printf(" vid=%04X, pid=%04X\n", info.vendor & 0xFFFF, info.product & 0xFFFF);
+ r = ioctl(fd, HIDIOCGRDESCSIZE, &len);
+ if (r < 0 || len < 1) continue;
+ printf(" len=%u\n", len);
+ desc = (struct hidraw_report_descriptor *)buf;
+ if (len > sizeof(buf)-sizeof(int)) len = sizeof(buf)-sizeof(int);
+ desc->size = len;
+ r = ioctl(fd, HIDIOCGRDESC, desc);
+ if (r < 0) continue;
+ printf(" Match\n");
+ found = 1;
+ break;
+ }
+ if (!found) {
+ if (fd > 0) close(fd);
+ return NULL;
+ }
+ hid = (struct rawhid_struct *)malloc(sizeof(struct rawhid_struct));
+ if (!hid) {
+ close(fd);
+ return NULL;
+ }
+ hid->fd = fd;
+ return hid;
+}
+
+int rawhid_status(rawhid_t *hid)
+{
+ // TODO: how to check if device is still online?
+ return -1;
+}
+
+int rawhid_read(rawhid_t *h, void *buf, int bufsize, int timeout_ms)
+{
+ struct rawhid_struct *hid;
+ int num;
+
+ hid = (struct rawhid_struct *)h;
+ if (!hid || hid->fd < 0) return -1;
+
+ while (1) {
+ num = read(hid->fd, buf, bufsize);
+ if (num < 0) {
+ if (errno == EINTR || errno == EAGAIN) continue;
+ if (errno == EIO) {
+ return -1;
+ printf("I/O Error\n");
+ }
+ printf("read error, r=%d, errno=%d\n", num, errno);
+ return -1;
+ }
+ //printf("read %d bytes\n", num);
+ return num;
+ }
+}
+
+void rawhid_close(rawhid_t *h)
+{
+ struct rawhid_struct *hid;
+
+ hid = (struct rawhid_struct *)h;
+ if (!hid || hid->fd < 0) return;
+ close(hid->fd);
+ hid->fd = -1;
+}
diff --git a/openbeacon/lpc13xx/hid-client/rawhid.h b/openbeacon/lpc13xx/hid-client/rawhid.h
new file mode 100644
index 0000000..47d24d1
--- /dev/null
+++ b/openbeacon/lpc13xx/hid-client/rawhid.h
@@ -0,0 +1,12 @@
+#ifndef rawhid_included_h__
+#define rawhid_included_h__
+
+// Raw HID, Basic API
+typedef void rawhid_t;
+rawhid_t * rawhid_open_only1(int vid, int pid, int usage_page, int usage);
+int rawhid_status(rawhid_t *hid);
+int rawhid_read(rawhid_t *h, void *buf, int bufsize, int timeout_ms);
+int rawhid_write(rawhid_t *hid, const void *buf, int len, int timeout_ms);
+void rawhid_close(rawhid_t *h);
+
+#endif
diff --git a/openbeacon/lpc13xx/lpc-flash/.gitignore b/openbeacon/lpc13xx/lpc-flash/.gitignore
new file mode 100644
index 0000000..2ba63ef
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/.gitignore
@@ -0,0 +1,21 @@
+aclocal.m4
+autom4te.cache
+ChangeLog
+compile
+config.h
+config.h.in
+config.log
+config.status
+configure
+depcomp
+INSTALL
+install-sh
+Makefile
+Makefile.in
+missing
+src/.deps/
+src/lpc-flash
+src/*.o
+src/Makefile
+src/Makefile.in
+stamp-h1
diff --git a/openbeacon/lpc13xx/lpc-flash/AUTHORS b/openbeacon/lpc13xx/lpc-flash/AUTHORS
new file mode 100644
index 0000000..311b448
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/AUTHORS
@@ -0,0 +1 @@
+Milosch Meriac
\ No newline at end of file
diff --git a/openbeacon/lpc13xx/lpc-flash/COPYING b/openbeacon/lpc13xx/lpc-flash/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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, either version 3 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/openbeacon/lpc13xx/lpc-flash/Makefile.am b/openbeacon/lpc13xx/lpc-flash/Makefile.am
new file mode 100644
index 0000000..1bfdcf4
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=src
diff --git a/openbeacon/lpc13xx/lpc-flash/NEWS b/openbeacon/lpc13xx/lpc-flash/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/openbeacon/lpc13xx/lpc-flash/README b/openbeacon/lpc13xx/lpc-flash/README
new file mode 100644
index 0000000..e69de29
diff --git a/openbeacon/lpc13xx/lpc-flash/bootstrap b/openbeacon/lpc13xx/lpc-flash/bootstrap
new file mode 100755
index 0000000..8f9a824
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/bootstrap
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+git pull openbeacon master
+git log . > ChangeLog
+autoreconf --install
diff --git a/openbeacon/lpc13xx/lpc-flash/configure.ac b/openbeacon/lpc13xx/lpc-flash/configure.ac
new file mode 100644
index 0000000..cdff695
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/configure.ac
@@ -0,0 +1,16 @@
+AC_INIT([lpc-flash],[0.1],[meriac@bitmanufaktur.de])
+AM_INIT_AUTOMAKE([-Wall -Werror])
+AC_PROG_CC
+AC_PROG_CXX
+AM_PROG_CC_C_O
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_FILES([
+ Makefile
+ src/Makefile
+])
+AC_OUTPUT
+AC_CHECK_HEADERS([stdio.h])
+AC_C_INLINE
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_UINT8_T
diff --git a/openbeacon/lpc13xx/lpc-flash/src/Makefile.am b/openbeacon/lpc13xx/lpc-flash/src/Makefile.am
new file mode 100644
index 0000000..ce0d8d4
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/src/Makefile.am
@@ -0,0 +1,4 @@
+AM_CFLAGS = --pedantic -std=gnu99
+bin_PROGRAMS = lpc-flash
+lpc_flash_SOURCES = lpc-flash.c
+lpc_flash_CPPFLAGS = -Wall -Werror
diff --git a/openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c b/openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c
new file mode 100644
index 0000000..2e53a75
--- /dev/null
+++ b/openbeacon/lpc13xx/lpc-flash/src/lpc-flash.c
@@ -0,0 +1,165 @@
+/***************************************************************
+ *
+ * OpenPCD.org - main entry for LPC flashing tool
+ *
+ * Copyright 2010 Milosch Meriac
+ * Copyright 2010 Henryk Plötz
+ *
+ ***************************************************************
+
+ 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 3.
+
+ 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+/* Library includes. */
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* static buffer for the maximal flash size: 32 kibibytes
+ */
+static uint8_t data[32 * 1024];
+
+static void print_usage(char *progname)
+{
+ fprintf(stderr,
+ "usage: %s inputfirmware.bin \"/media/CRP DISABLD/firmware.bin\"\n\n"
+ "Either or both input and output may be -, which indicates to work\n"
+ "on stdin or stdout\n\n", progname);
+}
+
+static int parse_arguments(int argc, char **argv, int *input, int *output)
+{
+ if (argc != 3) {
+ print_usage(argv[0]);
+ return 0;
+ }
+
+ /* open input file */
+ if (strcmp(argv[1], "-") != 0) {
+ if ((*input = open(argv[1], O_RDONLY)) == -1) {
+ perror("Can't open input file for reading");
+ return 0;
+ }
+ } else {
+ *input = 0;
+ }
+
+ /* open output file */
+ if (strcmp(argv[2], "-") != 0) {
+ if ((*output = open(argv[2], O_WRONLY | O_CREAT, 00664)) == -1) {
+ perror("Can't open output file for writing");
+ close(*input);
+ return 0;
+ }
+ } else {
+ *output = 1;
+ }
+
+ return 1;
+}
+
+/**
+ * Converts Little-Endian data to host byte order
+ * \param ledata is a 32-bit integer stored in little endian order
+ * \return \e ledata converted to host byte order
+ */
+uint32_t letohl(uint32_t ledata)
+{
+ /* first convert input to big endian, then use ntohl */
+ uint32_t bedata =
+ (((ledata >> 0) & 0xff) << 24) | (((ledata >> 8) & 0xff) << 16) |
+ (((ledata >> 16) & 0xff) << 8) | (((ledata >> 24) & 0xff) << 0);
+ return ntohl(bedata);
+}
+
+/**
+ * Converts host byte order data to Little-Endian
+ * \param hdata is a 32-bit integer stored in host byte order
+ * \return \e hdata converted to little endian order
+ */
+uint32_t htolel(uint32_t hdata)
+{
+ /* use htonl, then convert from big endian */
+ uint32_t bedata = htonl(hdata);
+ return (((bedata >> 0) & 0xff) << 24) | (((bedata >> 8) & 0xff) << 16)
+ | (((bedata >> 16) & 0xff) << 8) | (((bedata >> 24) & 0xff) << 0);
+}
+
+
+int main(int argc, char **argv)
+{
+ int input = -1, output = -1;
+
+ if (!parse_arguments(argc, argv, &input, &output)) {
+ return 1;
+ }
+
+ /* Read in the entire input file */
+ ssize_t len_read, input_size = 0;
+ while ((len_read =
+ read(input, data + input_size,
+ sizeof(data) - input_size)) > 0) {
+ input_size += len_read;
+ }
+
+ if (input_size < 8 * 4) {
+ fprintf(stderr,
+ "Error: Input file is too small, does not contain \n"
+ "at least 8 interrupt vectors\n");
+ print_usage(argv[0]);
+ return 2;
+ }
+
+ /* Now sum over the first 7 ISR values */
+ uint32_t accumulator = 0, isr_value;
+ for (int i = 0; i < 7; i++) {
+ isr_value = ((uint32_t *) data)[i];
+ /* The contents in the file are stored in little endian, need to
+ * convert to host byte order.
+ */
+ isr_value = letohl(isr_value);
+
+ accumulator += isr_value;
+ }
+
+ /* The checksum is the twos complement of the sum */
+ uint32_t checksum = ~accumulator + 1;
+
+ /* Needs to be converted to little endian when storing */
+ ((uint32_t *) data)[7] = htolel(checksum);
+
+ /* Now write out the whole file */
+ ssize_t len_written, output_size = 0;
+ while ((len_written =
+ write(output, data + output_size,
+ input_size - output_size)) > 0) {
+ output_size += len_written;
+ }
+
+ if (output_size != input_size) {
+ perror("couldn't write complete output file, flash size might be"
+ "smaller than input size");
+ }
+
+ /* close & flush files */
+ close(input);
+ fsync(output);
+ close(output);
+
+ return 0;
+}
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/Makefile b/openbeacon/lpc13xx/openbeacon-sensor/Makefile
new file mode 100644
index 0000000..86afebc
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/Makefile
@@ -0,0 +1,32 @@
+TARGET=openbeacon-sensor
+ARCH=LPC13
+CPU=$(ARCH)42
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/main.c \
+ src/pmu.c \
+ src/sound.c \
+ src/nRF_CMD.c \
+ src/nRF_API.c \
+ src/3d_acceleration.c
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+publish: clean $(TARGET).bin
+ rm -f $(TARGET).zip
+ ../lpc-flash/src/lpc-flash $(TARGET).bin firmware.bin
+ zip $(TARGET).zip firmware.bin
+ scp $(TARGET).zip firmware.bin meri@bitmanufaktur.net:/home/wwwrun/open.bitmanufaktur.com/web/www/people/milosch/usb2tag/
+
+app_clean:
+ rm -f $(TARGET).zip $(TARGET)-firmware.bin
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/3d_acceleration.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/3d_acceleration.h
new file mode 100644
index 0000000..344acb6
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/3d_acceleration.h
@@ -0,0 +1,32 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - 3D acceleration sensor support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __3D_ACCELERATION_H__
+#define __3D_ACCELERATION_H__
+
+extern void acc_init (uint8_t enabled);
+extern void acc_power (uint8_t enabled);
+extern void acc_status (void);
+extern void acc_xyz_read (int *x, int *y, int *z);
+
+#endif/*__3D_ACCELERATION_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/config.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/config.h
new file mode 100644
index 0000000..d3c3453
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/config.h
@@ -0,0 +1,44 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - config file
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/* Treshold for detecting 3D accelerometer movement */
+#define ACC_TRESHOLD 3
+#define ACC_MOVING_TRESHOLD 20
+
+/* Clock Definition */
+#define SYSTEM_CRYSTAL_CLOCK 12000000
+#define SYSTEM_CORE_CLOCK (SYSTEM_CRYSTAL_CLOCK*6)
+
+/* Enable Sound Output */
+#define SOUND_ENABLE
+
+/* SPI_CS(io_port, io_pin, CPSDVSR frequency, mode) */
+#define SPI_CS_NRF SPI_CS( 1,10, 8, SPI_CS_MODE_NORMAL ) /* 9.0MHz */
+#define SPI_CS_ACC3D SPI_CS( 0, 4,18, SPI_CS_MODE_NORMAL ) /* 4.0MHz */
+
+#define NRF_MAX_MAC_SIZE 5
+
+#endif/*__CONFIG_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_API.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_API.h
new file mode 100644
index 0000000..c246d57
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_API.h
@@ -0,0 +1,60 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - function definitions
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides high level initialization and startup sanity
+ * checks and test routines to verify that the chip is working
+ * properly and no soldering errors occored on the digital part.
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef NRF_API_H
+#define NRF_API_H
+
+#include
+
+extern uint8_t nRFAPI_Init (uint8_t channel, const uint8_t * mac, uint8_t mac_size, uint8_t features);
+extern void nRFAPI_SetTxPower (uint8_t power);
+extern void nRFAPI_TxRetries (uint8_t count);
+extern void nRFAPI_SetRxMode (uint8_t receive);
+extern void nRFAPI_PipesEnable (uint8_t mask);
+extern void nRFAPI_PipesAck (uint8_t mask);
+extern uint8_t nRFAPI_GetSizeMac (void);
+extern uint8_t nRFAPI_SetSizeMac (uint8_t addr_size);
+extern void nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size);
+extern void nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size);
+extern void nRFAPI_SetRxMAC (const uint8_t * addr, uint8_t addr_size, uint8_t pipe);
+extern void nRFAPI_SetChannel (uint8_t channel);
+extern uint8_t nRFAPI_GetChannel (void);
+extern uint8_t nRFAPI_ClearIRQ (uint8_t status);
+extern void nRFAPI_TX (uint8_t * buf, uint8_t count);
+extern uint8_t nRFAPI_GetStatus (void);
+extern uint8_t nRFAPI_GetPipeSizeRX (uint8_t pipe);
+extern void nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size);
+extern uint8_t nRFAPI_GetPipeCurrent (void);
+extern uint8_t nRFAPI_RX (uint8_t * buf, uint8_t count);
+extern void nRFAPI_FlushRX (void);
+extern void nRFAPI_FlushTX (void);
+extern void nRFAPI_ReuseTX (void);
+extern uint8_t nRFAPI_GetFifoStatus (void);
+extern uint8_t nRFAPI_CarrierDetect (void);
+extern void nRFAPI_SetFeatures (uint8_t features);
+extern void nRFAPI_PowerDown (void);
+
+#endif /*NRF_API_H */
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_CMD.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_CMD.h
new file mode 100644
index 0000000..15723f8
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_CMD.h
@@ -0,0 +1,45 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - midlevel access function defines for
+ * issuing raw commands to the nRF24L01 2.4Ghz frontend
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides generic register level access functions
+ * for accessing nRF24L01 registers at a generic level
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef NRF_CMD_H
+#define NRF_CMD_H
+
+extern uint8_t nRFCMD_CmdExec (uint8_t reg);
+extern uint8_t nRFCMD_RegRead (uint8_t reg);
+extern uint8_t nRFCMD_RegWriteStatusRead (uint8_t reg, uint8_t value);
+extern uint8_t nRFCMD_RegWriteBuf (uint8_t reg, const uint8_t * buf, uint8_t count);
+extern uint8_t nRFCMD_RegReadBuf (uint8_t reg, uint8_t * buf, uint8_t count);
+extern uint8_t nRFCMD_GetRegSize (uint8_t reg);
+extern uint8_t nRFCMD_WaitRx (uint32_t ticks);
+extern void nRFCMD_CE (uint8_t enable);
+extern void nRFCMD_Power (uint8_t enable);
+extern void nRFCMD_ReadWriteBuffer (const uint8_t * tx_data, uint8_t * rx_data, uint32_t len);
+extern void nRFCMD_ExecMacro (const uint8_t * macro);
+extern void nRFCMD_RegisterDump (void);
+extern void nRFCMD_Init (void);
+extern void nRFCMD_Status (void);
+
+#endif /*NRF_CMD_H */
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_HW.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_HW.h
new file mode 100644
index 0000000..c4d17dc
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/nRF_HW.h
@@ -0,0 +1,109 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - opcode & register definitions for nRF24L01
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides a nice set of defines to work properly with the
+ * nRF24L01 CPU
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef NRF_HW_H
+#define NRF_HW_H
+
+//********************************************************************************************************************//
+// SPI(nRF24L01) commands
+#define READ_REG 0x00 // Define read command to register
+#define WRITE_REG 0x20 // Define write command to register
+#define RD_RX_PLOAD 0x61 // Define RX payload register address
+#define WR_TX_PLOAD 0xA0 // Define TX payload register address
+#define FLUSH_TX 0xE1 // Define flush TX register command
+#define FLUSH_RX 0xE2 // Define flush RX register command
+#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
+#define OP_NOP 0xFF // Define No Operation, might be used to read status register
+#define ACTIVATE 0x50 // ACTIVATE additional features
+#define R_RX_PL_WID 0x60 // Define Read RX-payload width command
+#define W_ACK_PAYLOAD 0xA8 // Write payload to be used in ACK packet on pipe PPP
+#define W_TX_PAYLOAD_NOACK 0xB0 // Used in TX mode, Disable AUTOACK on this specific packet
+
+
+//********************************************************************************************************************//
+// SPI(nRF24L01) registers(addresses)
+#define CONFIG 0x00 // 'Config' register address
+#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
+#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
+#define SETUP_AW 0x03 // 'Setup address width' register address
+#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
+#define RF_CH 0x05 // 'RF channel' register address
+#define RF_SETUP 0x06 // 'RF setup' register address
+#define STATUS 0x07 // 'Status' register address
+#define OBSERVE_TX 0x08 // 'Observe TX' register address
+#define CD 0x09 // 'Carrier Detect' register address
+#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
+#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
+#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
+#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
+#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
+#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
+#define TX_ADDR 0x10 // 'TX address' register address
+#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
+#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
+#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
+#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
+#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
+#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
+#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
+#define FEATURE 0x1D // Additional features register, needed to enable the additional commands
+
+//********************************************************************************************************************//
+// SPI(nRF24L01) registers(bitmasks)
+#define ERX_P0 0x01 // Enable Pipe 0 (register EN_RXADDR)
+#define ERX_P1 0x02 // Enable Pipe 1 (register EN_RXADDR)
+#define ERX_P2 0x04 // Enable Pipe 2 (register EN_RXADDR)
+#define ERX_P3 0x08 // Enable Pipe 3 (register EN_RXADDR)
+#define ERX_P4 0x10 // Enable Pipe 4 (register EN_RXADDR)
+#define ERX_P5 0x20 // Enable Pipe 5 (register EN_RXADDR)
+
+//********************************************************************************************************************//
+// 'Config' register mask bits
+#define NRF_CONFIG_PRIM_RX 0x01
+#define NRF_CONFIG_PWR_UP 0x02
+#define NRF_CONFIG_CRCO 0x04
+#define NRF_CONFIG_EN_CRC 0x08
+#define NRF_CONFIG_MASK_MAX_RT 0x10
+#define NRF_CONFIG_MASK_TX_DS 0x20
+#define NRF_CONFIG_MASK_RX_DR 0x40
+#define NRF_CONFIG_MASK_IRQS (NRF_CONFIG_MASK_MAX_RT|NRF_CONFIG_MASK_TX_DS|NRF_CONFIG_MASK_RX_DR)
+
+
+#define MASK_RX_DR_FLAG 0x40
+#define MASK_TX_DS_FLAG 0x20
+#define MASK_MAX_RT_FLAG 0x10
+#define MASK_IRQ_FLAGS (MASK_MAX_RT_FLAG|MASK_TX_DS_FLAG|MASK_RX_DR_FLAG)
+
+#define FIFO_RX_EMPTY 0x01
+#define FIFO_RX_FULL 0x02
+#define FIFO_TX_EMPTY 0x10
+#define FIFO_TX_FULL 0x20
+#define FIFO_TX_REUSE 0x40
+
+#define NRF_MIN_MAC_SIZE 3
+#define NRF_MAX_MAC_SIZE 5
+#define NRF_MAX_BUFFER_SIZE 32
+
+#endif /*NRF_HW_H */
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/openbeacon-proto.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/openbeacon-proto.h
new file mode 100644
index 0000000..6e7dded
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/openbeacon-proto.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+ *
+ * OpenBeacon.org - OnAir protocol specification and definition
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ ****************************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __OPENBEACON_PROTO_H__
+#define __OPENBEACON_PROTO_H__
+
+#define CONFIG_TRACKER_CHANNEL 81
+#define CONFIG_PROX_CHANNEL 76
+
+#define XXTEA_BLOCK_COUNT 4
+
+#define RFBPROTO_READER_ANNOUNCE 22
+#define RFBPROTO_READER_COMMAND 23
+#define RFBPROTO_BEACONTRACKER 24
+#define RFBPROTO_PROXTRACKER 42
+#define RFBPROTO_PROXREPORT 69
+
+#define PROX_MAX 4
+
+#define RFBFLAGS_ACK 0x01
+#define RFBFLAGS_SENSOR 0x02
+#define RFBFLAGS_INFECTED 0x04
+
+/* RFBPROTO_READER_COMMAND related opcodes */
+#define READER_CMD_NOP 0x00
+#define READER_CMD_RESET 0x01
+#define READER_CMD_RESET_CONFIG 0x02
+#define READER_CMD_RESET_FACTORY 0x03
+#define READER_CMD_RESET_WIFI 0x04
+#define READER_CMD_SET_OID 0x05
+/* RFBPROTO_READER_COMMAND related results */
+#define READ_RES__OK 0x00
+#define READ_RES__DENIED 0x01
+#define READ_RES__UNKNOWN_CMD 0xFF
+
+typedef struct
+{
+ uint8_t strength;
+ uint16_t oid_last_seen;
+ uint16_t powerup_count;
+ uint8_t reserved;
+ uint32_t seq;
+} PACKED TBeaconTracker;
+
+typedef struct
+{
+ uint16_t oid_prox[PROX_MAX];
+ uint16_t seq;
+} PACKED TBeaconProx;
+
+typedef struct
+{
+ uint8_t opcode, res;
+ uint32_t data[2];
+} PACKED TBeaconReaderCommand;
+
+typedef struct
+{
+ uint8_t opcode, strength;
+ uint32_t uptime, ip;
+} PACKED TBeaconReaderAnnounce;
+
+typedef union
+{
+ TBeaconProx prox;
+ TBeaconTracker tracker;
+ TBeaconReaderCommand reader_command;
+ TBeaconReaderAnnounce reader_announce;
+} PACKED TBeaconPayload;
+
+typedef struct
+{
+ uint8_t proto;
+ uint16_t oid;
+ uint8_t flags;
+
+ TBeaconPayload p;
+
+ uint16_t crc;
+} PACKED TBeaconWrapper;
+
+typedef union
+{
+ TBeaconWrapper pkt;
+ uint32_t block[XXTEA_BLOCK_COUNT];
+ uint8_t byte[XXTEA_BLOCK_COUNT * 4];
+} PACKED TBeaconEnvelope;
+
+#endif/*__OPENBEACON_PROTO_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/pmu.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/pmu.h
new file mode 100644
index 0000000..f19494a
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/pmu.h
@@ -0,0 +1,31 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - LPC13xx Power Management Functions
+ *
+ * Copyright 2011 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+extern void pmu_wait_ms (uint16_t ms);
+extern void pmu_sleep_ms (uint16_t ms);
+extern void pmu_init (void);
+
+#endif/*__PMU_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/inc/sound.h b/openbeacon/lpc13xx/openbeacon-sensor/inc/sound.h
new file mode 100644
index 0000000..5c7f1aa
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/inc/sound.h
@@ -0,0 +1,33 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - piezo speaker sound functions
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifndef __SOUND_H__
+#define __SOUND_H__
+
+#define TONES_MAX 32
+
+extern void snd_beep (uint16_t frequency);
+extern void snd_tone (uint8_t tone);
+extern void snd_init (void);
+
+#endif/*__SOUND_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/3d_acceleration.c b/openbeacon/lpc13xx/openbeacon-sensor/src/3d_acceleration.c
new file mode 100644
index 0000000..1cc3eba
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/src/3d_acceleration.c
@@ -0,0 +1,100 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - 3D acceleration sensor support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "3d_acceleration.h"
+#include "spi.h"
+
+static void
+acc_reg_write (uint8_t addr, uint8_t data)
+{
+ uint8_t tx[2];
+
+ /* assemble SPI write request */
+ tx[0] = 0x80 | addr << 1;
+ tx[1] = data;
+
+ /* transmit packet */
+ spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), NULL, 0);
+}
+
+static uint8_t
+acc_reg_read (uint8_t addr)
+{
+ uint8_t tx[2], rx[2];
+
+ /* assemble SPI read request */
+ tx[0] = addr << 1;
+ tx[1] = 0;
+ /* transmit packet */
+ spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), rx, sizeof (rx));
+
+ return rx[1];
+}
+
+void
+acc_xyz_read (int *x, int *y, int *z)
+{
+ /* dummy read - FIXME */
+ acc_reg_read (0);
+
+ /* get acceleration values */
+ *x = (int8_t) acc_reg_read (6);
+ *y = (int8_t) acc_reg_read (7);
+ *z = (int8_t) acc_reg_read (8);
+}
+
+void
+acc_status (void)
+{
+ int x, y, z;
+
+ acc_xyz_read (&x, &y, &z);
+
+ debug_printf (" * 3D_ACC: X=%04i Y=%04i Z=%04i\n", x, y, z);
+}
+
+void
+acc_power (uint8_t enabled)
+{
+ /* dummy read - FIXME */
+ acc_reg_read (0);
+ /* set 3D acceleration sensor active, 2g - FIXME power saving */
+ acc_reg_write (0x16, enabled ? (0x01 | 0x01 << 2) : 0x00);
+}
+
+void
+acc_init (uint8_t enabled)
+{
+ /* PIO, PIO0_4 in standard IO functionality */
+ LPC_IOCON->PIO0_4 = 1 << 8;
+
+ /* setup SPI chipselect pin */
+ spi_init_pin (SPI_CS_ACC3D);
+
+ /* PIO, Inactive Pull, Digital Mode */
+ LPC_IOCON->PIO1_11 = 0x80;
+ GPIOSetDir (1, 11, 0);
+
+ /* propagate power settings */
+ acc_power (enabled);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/main.c b/openbeacon/lpc13xx/openbeacon-sensor/src/main.c
new file mode 100644
index 0000000..ad236a2
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/src/main.c
@@ -0,0 +1,346 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - main file for OpenBeacon Sensor (CR123A)
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "3d_acceleration.h"
+#include "sound.h"
+#include "xxtea.h"
+#include "pmu.h"
+#include "iap.h"
+#include "spi.h"
+#include "nRF_API.h"
+#include "nRF_CMD.h"
+#include "openbeacon-proto.h"
+
+uint32_t g_sysahbclkctrl;
+
+#define FIFO_DEPTH 10
+typedef struct {
+ int x,y,z;
+} TFifoEntry;
+
+#define MAINCLKSEL_IRC 0
+#define MAINCLKSEL_SYSPLL_IN 1
+#define MAINCLKSEL_WDT 2
+#define MAINCLKSEL_SYSPLL_OUT 3
+
+/* device UUID */
+static uint16_t tag_id;
+static TDeviceUID device_uuid;
+
+/* OpenBeacon packet */
+static TBeaconEnvelope g_Beacon;
+
+/* Default TEA encryption key of the tag - MUST CHANGE ! */
+static const uint32_t xxtea_key[4] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
+
+/* set nRF24L01 broadcast mac */
+static const unsigned char broadcast_mac[NRF_MAX_MAC_SIZE] = { 1, 2, 3, 2, 1 };
+
+static void
+nRF_tx (uint8_t power)
+{
+ /* encrypt data */
+ xxtea_encode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key);
+
+ /* set TX power */
+ nRFAPI_SetTxPower (power & 0x3);
+
+ /* upload data to nRF24L01 */
+ nRFAPI_TX ((uint8_t*)&g_Beacon, sizeof(g_Beacon));
+
+ /* transmit data */
+ nRFCMD_CE (1);
+
+ /* wait for packet to be transmitted */
+ pmu_sleep_ms (10);
+
+ /* transmit data */
+ nRFCMD_CE (0);
+}
+
+void
+nrf_off (void)
+{
+ /* disable RX mode */
+ nRFCMD_CE (0);
+
+ /* wait till RX is done */
+ pmu_sleep_ms (5);
+
+ /* switch to TX mode */
+ nRFAPI_SetRxMode (0);
+
+}
+
+int
+main (void)
+{
+ /* accelerometer readings fifo */
+ TFifoEntry acc_lowpass;
+ TFifoEntry fifo_buf[FIFO_DEPTH];
+ int fifo_pos;
+ TFifoEntry *fifo;
+ uint32_t seq;
+
+ volatile int i;
+ int x, y, z, firstrun, tamper, moving;
+
+ /* wait on boot - debounce */
+ for (i = 0; i < 2000000; i++);
+
+ /* Initialize GPIO (sets up clock) */
+ GPIOInit ();
+
+ /* initialize power management */
+ pmu_init ();
+
+ /* NVIC is installed inside UARTInit file. */
+ UARTInit (115200, 0);
+
+ LPC_IOCON->PIO2_0 = 0;
+ GPIOSetDir (2, 0, 1); //OUT
+ GPIOSetValue (2, 0, 0);
+
+ LPC_IOCON->RESET_PIO0_0 = 0;
+ GPIOSetDir (0, 0, 0); //IN
+
+ LPC_IOCON->PIO0_1 = 0;
+ GPIOSetDir (0, 1, 0); //IN
+
+ LPC_IOCON->PIO1_8 = 0;
+ GPIOSetDir (1, 8, 1); //OUT
+ GPIOSetValue (1, 8, 0);
+
+ LPC_IOCON->PIO0_2 = 0;
+ GPIOSetDir (0, 2, 1); //OUT
+ GPIOSetValue (0, 2, 0);
+
+ LPC_IOCON->PIO0_3 = 0;
+ GPIOSetDir (0, 3, 0); //IN
+
+ LPC_IOCON->PIO0_4 = 1 << 8;
+ GPIOSetDir (0, 4, 1); //OUT
+ GPIOSetValue (0, 4, 1);
+
+ LPC_IOCON->PIO0_5 = 1 << 8;
+ GPIOSetDir (0, 5, 1); //OUT
+ GPIOSetValue (0, 5, 1);
+
+ LPC_IOCON->PIO1_9 = 0; //FIXME
+ GPIOSetDir (1, 9, 1); //OUT
+ GPIOSetValue (1, 9, 0);
+
+ LPC_IOCON->PIO0_6 = 0;
+ GPIOSetDir (0, 6, 1); //OUT
+ GPIOSetValue (0, 6, 1);
+
+ LPC_IOCON->PIO0_7 = 0;
+ GPIOSetDir (0, 7, 1); //OUT
+ GPIOSetValue (0, 7, 0);
+
+ /* select UART_TXD */
+ LPC_IOCON->PIO1_7 = 1;
+
+ LPC_IOCON->PIO1_6 = 0;
+ GPIOSetDir (1, 6, 1); //OUT
+ GPIOSetValue (1, 6, 0);
+
+ LPC_IOCON->PIO1_5 = 0;
+ GPIOSetDir (1, 5, 1); //OUT
+ GPIOSetValue (1, 5, 0);
+
+ LPC_IOCON->PIO3_2 = 0; // FIXME
+ GPIOSetDir (3, 2, 1); //OUT
+ GPIOSetValue (3, 2, 1);
+
+ LPC_IOCON->PIO1_11 = 0x80; //FIXME
+ GPIOSetDir (1, 11, 1); // OUT
+ GPIOSetValue (1, 11, 0);
+
+ LPC_IOCON->PIO1_4 = 0x80;
+ GPIOSetDir (1, 4, 0); // IN
+
+ LPC_IOCON->ARM_SWDIO_PIO1_3 = 0x81;
+ GPIOSetDir (1, 3, 1); // OUT
+ GPIOSetValue (1, 3, 0);
+
+ LPC_IOCON->JTAG_nTRST_PIO1_2 = 0x81;
+ GPIOSetDir (1, 2, 1); // OUT
+ GPIOSetValue (1, 2, 0);
+
+ LPC_IOCON->JTAG_TDO_PIO1_1 = 0x81;
+ GPIOSetDir (1, 1, 1); // OUT
+ GPIOSetValue (1, 1, 0);
+
+ LPC_IOCON->JTAG_TMS_PIO1_0 = 0x81;
+ GPIOSetDir (1, 0, 1); // OUT
+ GPIOSetValue (1, 0, 0);
+
+ LPC_IOCON->JTAG_TDI_PIO0_11 = 0x81;
+ GPIOSetDir (0, 11, 1); // OUT
+ GPIOSetValue (0, 11, 0);
+
+ LPC_IOCON->PIO1_10 = 0x80;
+ GPIOSetDir (1, 10, 1); // OUT
+ GPIOSetValue (1, 10, 1);
+
+ LPC_IOCON->JTAG_TCK_PIO0_10 = 0x81;
+ GPIOSetDir (0, 10, 1); // OUT
+ GPIOSetValue (0, 10, 0);
+
+ LPC_IOCON->PIO0_9 = 0;
+ GPIOSetDir (0, 9, 1); // OUT
+ GPIOSetValue (0, 9, 0);
+
+ /* select MISO function for PIO0_8 */
+ LPC_IOCON->PIO0_8 = 1;
+
+ /* initialize SPI */
+ spi_init ();
+
+#ifdef SOUND_ENABLE
+ /* Init Speaker Output */
+ snd_init ();
+#endif /*SOUND_ENABLE */
+
+ /* Init 3D acceleration sensor */
+ acc_init (0);
+
+ /* read device UUID */
+ bzero (&device_uuid, sizeof (device_uuid));
+ iap_read_uid (&device_uuid);
+ tag_id = crc16 ((uint8_t *) & device_uuid, sizeof (device_uuid));
+
+ /* Initialize OpenBeacon nRF24L01 interface */
+ if (!nRFAPI_Init (81, broadcast_mac, sizeof (broadcast_mac), 0))
+ for (;;)
+ {
+ GPIOSetValue (1, 3, 1);
+ pmu_sleep_ms (100);
+ GPIOSetValue (1, 3, 0);
+ pmu_sleep_ms (400);
+ }
+ /* set tx power power to high */
+ nRFCMD_Power (1);
+
+ /* blink LED for 1s to show readyness */
+ GPIOSetValue (1, 3, 1);
+ pmu_sleep_ms (1000);
+ GPIOSetValue (1, 3, 0);
+
+ /* reset fifo */
+ fifo_pos=0;
+ bzero(&fifo_buf,sizeof(fifo_buf));
+ bzero(&acc_lowpass,sizeof(acc_lowpass));
+
+ seq = firstrun = tamper = moving = 0;
+ while (1)
+ {
+ /* read acceleration sensor */
+ nRFAPI_SetRxMode(0);
+ acc_power (1);
+ pmu_sleep_ms (20);
+ acc_xyz_read (&x, &y, &z);
+ acc_power (0);
+
+ /* prepare packet */
+ bzero (&g_Beacon, sizeof (g_Beacon));
+ g_Beacon.pkt.proto = RFBPROTO_BEACONTRACKER;
+ g_Beacon.pkt.oid = htons (tag_id);
+ g_Beacon.pkt.p.tracker.strength = 5;
+ g_Beacon.pkt.p.tracker.seq = htonl (seq++);
+ g_Beacon.pkt.p.tracker.reserved = moving;
+ g_Beacon.pkt.crc = htons(crc16 (g_Beacon.byte, sizeof (g_Beacon) - sizeof (g_Beacon.pkt.crc)));
+ /* transmit packet */
+ nRF_tx (g_Beacon.pkt.p.tracker.strength);
+ /* powering down */
+ nRFAPI_PowerDown ();
+
+ /* add new accelerometer values to lowpass */
+ fifo = &fifo_buf[fifo_pos];
+ if(fifo_pos>=(FIFO_DEPTH-1))
+ fifo_pos=0;
+ else
+ fifo_pos++;
+
+ acc_lowpass.x += x - fifo->x;
+ fifo->x = x;
+ acc_lowpass.y += y - fifo->y;
+ fifo->y = y;
+ acc_lowpass.z += z - fifo->z;
+ fifo->z = z;
+
+ if (!firstrun)
+ {
+ if(fifo_pos)
+ {
+ pmu_sleep_ms (500);
+ continue;
+ }
+ else
+ {
+ /* confirm finalized initialization by double-blink */
+ firstrun = 1;
+ GPIOSetValue (1, 3, 1);
+ pmu_sleep_ms (100);
+ GPIOSetValue (1, 3, 0);
+ pmu_sleep_ms (300);
+ GPIOSetValue (1, 3, 1);
+ pmu_sleep_ms (100);
+ GPIOSetValue (1, 3, 0);
+ }
+ }
+ else
+ if ((abs (acc_lowpass.x/FIFO_DEPTH - x) >= ACC_TRESHOLD) ||
+ (abs (acc_lowpass.y/FIFO_DEPTH - y) >= ACC_TRESHOLD) ||
+ (abs (acc_lowpass.z/FIFO_DEPTH - z) >= ACC_TRESHOLD))
+ tamper = 5;
+
+ if (tamper)
+ {
+ pmu_sleep_ms (750);
+ tamper--;
+ if (moving < ACC_MOVING_TRESHOLD)
+ moving++;
+ else
+ {
+ snd_tone (22);
+ GPIOSetValue (1, 3, 1);
+ pmu_wait_ms (20);
+ GPIOSetValue (1, 3, 0);
+ snd_tone (23);
+ pmu_wait_ms (50);
+ snd_tone (24);
+ pmu_wait_ms (30);
+ snd_tone (0);
+ }
+ }
+ else
+ {
+ pmu_sleep_ms (5000);
+ moving = 0;
+ }
+ }
+
+ return 0;
+}
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_API.c b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_API.c
new file mode 100644
index 0000000..eb37f10
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_API.c
@@ -0,0 +1,330 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - high level nRF24L01 access functions
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides high level initialization and startup sanity
+ * checks and test routines to verify that the chip is working
+ * properly and no soldering errors occored on the digital part.
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "pmu.h"
+#include "nRF_HW.h"
+#include "nRF_CMD.h"
+#include "nRF_API.h"
+
+#ifndef NRF_RFOPTIONS
+#define NRF_RFOPTIONS 0x09
+#endif /*NRF_RFOPTIONS */
+
+// set broadcast MAC to 'BCAST'
+const uint8_t rfbroadcast_mac[NRF_MAX_MAC_SIZE] = { 'T', 'S', 'A', 'C', 'B' };
+
+uint8_t
+nRFAPI_DetectChip (void)
+{
+ uint8_t mac[NRF_MAX_MAC_SIZE], i;
+
+ // blank read
+ nRFAPI_GetStatus ();
+
+ // set dummy MAC size
+ nRFAPI_SetSizeMac (NRF_MIN_MAC_SIZE);
+
+ // verify dummy MAC size
+ if (nRFAPI_GetSizeMac () != NRF_MIN_MAC_SIZE)
+ return 0;
+
+ // set dummy MAC size
+ nRFAPI_SetSizeMac (NRF_MAX_MAC_SIZE);
+
+ // verify dummy MAC size
+ if (nRFAPI_GetSizeMac () != NRF_MAX_MAC_SIZE)
+ return 0;
+
+ // set dummy MAC
+ nRFAPI_SetTxMAC (rfbroadcast_mac, NRF_MAX_MAC_SIZE);
+
+ // get dummy MAC
+ memset (&mac, 0, sizeof (mac));
+ nRFAPI_GetTxMAC (mac, NRF_MAX_MAC_SIZE);
+
+ // if can't verify written MAC - return with error
+ for (i = 0; i < NRF_MAX_MAC_SIZE; i++)
+ if (mac[i] != rfbroadcast_mac[i])
+ return 0;
+
+ // everything is fine
+ return 1;
+}
+
+void
+nRFAPI_SetRxMode (uint8_t receive)
+{
+ nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, receive ? 0x3B : 0x3A);
+}
+
+void
+nRFAPI_PowerDown (void)
+{
+ nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, 0x00);
+}
+
+uint8_t
+nRFAPI_Init (uint8_t channel,
+ const uint8_t * mac, uint8_t mac_size, uint8_t features)
+{
+ uint8_t i;
+
+ // init IO layer of nRF24L01
+ nRFCMD_Init ();
+
+ /* wait for nRF to boot */
+ pmu_sleep_ms(10);
+
+ // check validity
+ if (mac_size < 3 || mac_size > 5 || !nRFAPI_DetectChip ())
+ return 0;
+
+ // update mac
+ nRFAPI_SetSizeMac (mac_size);
+ nRFAPI_SetTxMAC (mac, mac_size);
+
+ // enables pipe
+ nRFAPI_SetRxMAC (mac, mac_size, 0);
+ nRFAPI_PipesEnable (ERX_P0);
+ nRFAPI_PipesAck (0);
+
+ // set payload sizes
+ for (i = 0; i <= 5; i++)
+ nRFAPI_SetPipeSizeRX (i, 16);
+
+ // set TX retry count
+ nRFAPI_TxRetries (0);
+
+ // set selected channel
+ nRFAPI_SetChannel (channel);
+
+ // set Tx power
+ nRFAPI_SetTxPower (3);
+
+ // flush FIFOs
+ nRFAPI_FlushRX ();
+ nRFAPI_FlushTX ();
+
+ if (features != 0)
+ nRFAPI_SetFeatures (features);
+
+ return 1;
+}
+
+void
+nRFAPI_SetTxPower (uint8_t power)
+{
+ if (power > 3)
+ power = 3;
+
+ nRFCMD_RegWriteStatusRead (RF_SETUP | WRITE_REG,
+ NRF_RFOPTIONS | (power << 1));
+}
+
+void
+nRFAPI_TxRetries (uint8_t count)
+{
+ if (count > 15)
+ count = 15;
+
+ // setup delay of 500us+86us
+ nRFCMD_RegWriteStatusRead (SETUP_RETR | WRITE_REG, 0x10 | count);
+}
+
+void
+nRFAPI_PipesEnable (uint8_t mask)
+{
+ nRFCMD_RegWriteStatusRead (EN_RXADDR | WRITE_REG, mask & 0x3F);
+}
+
+void
+nRFAPI_PipesAck (uint8_t mask)
+{
+ nRFCMD_RegWriteStatusRead (EN_AA | WRITE_REG, mask & 0x3F);
+}
+
+uint8_t
+nRFAPI_GetSizeMac (void)
+{
+ uint8_t addr_size;
+
+ addr_size = nRFCMD_RegRead (SETUP_AW) & 0x03;
+
+ return addr_size ? addr_size + 2 : 0;
+}
+
+uint8_t
+nRFAPI_SetSizeMac (uint8_t addr_size)
+{
+ if (addr_size >= 3 && addr_size <= 5)
+ addr_size -= 2;
+ else
+ addr_size = 0;
+
+ nRFCMD_RegWriteStatusRead (SETUP_AW | WRITE_REG, addr_size);
+
+ return addr_size;
+}
+
+void
+nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size)
+{
+ if (addr_size >= 3 && addr_size <= 5)
+ nRFCMD_RegReadBuf (TX_ADDR, addr, addr_size);
+}
+
+void
+nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size)
+{
+ if (addr_size >= 3 && addr_size <= 5)
+ nRFCMD_RegWriteBuf (TX_ADDR | WRITE_REG, addr, addr_size);
+}
+
+void
+nRFAPI_SetRxMAC (const uint8_t * addr, uint8_t addr_size, uint8_t pipe)
+{
+ if ((pipe <= 1 && addr_size >= 3 && addr_size <= 5)
+ || (addr_size == 1 && pipe >= 2 && pipe <= 5))
+ nRFCMD_RegWriteBuf ((RX_ADDR_P0 + pipe) | WRITE_REG, addr, addr_size);
+}
+
+void
+nRFAPI_SetChannel (uint8_t channel)
+{
+ nRFCMD_RegWriteStatusRead (RF_CH | WRITE_REG, channel & 0x7f);
+}
+
+uint8_t
+nRFAPI_GetChannel (void)
+{
+ return nRFCMD_RegRead (RF_CH) & 0x7F;
+}
+
+uint8_t
+nRFAPI_ClearIRQ (uint8_t status)
+{
+ return nRFCMD_RegWriteStatusRead (STATUS | WRITE_REG,
+ status & MASK_IRQ_FLAGS);
+}
+
+void
+nRFAPI_TX (uint8_t * buf, uint8_t count)
+{
+ nRFCMD_RegWriteBuf (WR_TX_PLOAD, buf, count);
+}
+
+uint8_t
+nRFAPI_GetStatus (void)
+{
+ return nRFCMD_CmdExec (OP_NOP);
+}
+
+uint8_t
+nRFAPI_GetPipeSizeRX (uint8_t pipe)
+{
+ if (pipe <= 5)
+ return nRFCMD_RegRead (RX_PW_P0 + pipe);
+ else
+ return 0;
+}
+
+void
+nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size)
+{
+ if (pipe <= 5)
+ nRFCMD_RegWriteStatusRead ((RX_PW_P0 + pipe) | WRITE_REG, size);
+}
+
+uint8_t
+nRFAPI_GetPipeCurrent (void)
+{
+ return (nRFAPI_GetStatus () >> 1) & 0x7;
+}
+
+uint8_t
+nRFAPI_RX (uint8_t * buf, uint8_t count)
+{
+ uint8_t size, pipe;
+
+ pipe = nRFAPI_GetPipeCurrent ();
+ if (pipe >= 7)
+ size = 0;
+ else
+ {
+ size = nRFAPI_GetPipeSizeRX (pipe);
+
+ if (size <= count)
+ nRFCMD_RegReadBuf (RD_RX_PLOAD, buf, size);
+ else
+ {
+ nRFAPI_FlushRX ();
+ size = 0;
+ }
+ }
+
+ return size;
+}
+
+void
+nRFAPI_FlushRX (void)
+{
+ nRFCMD_CmdExec (FLUSH_RX);
+}
+
+void
+nRFAPI_FlushTX (void)
+{
+ nRFCMD_CmdExec (FLUSH_TX);
+}
+
+void
+nRFAPI_ReuseTX (void)
+{
+ nRFCMD_CmdExec (REUSE_TX_PL);
+}
+
+uint8_t
+nRFAPI_GetFifoStatus (void)
+{
+ return nRFCMD_RegRead (FIFO_STATUS);
+}
+
+uint8_t
+nRFAPI_CarrierDetect (void)
+{
+ return nRFCMD_RegRead (CD);
+}
+
+void
+nRFAPI_SetFeatures (uint8_t features)
+{
+ unsigned const char ACTIVATE_SEQUENCE[] = { ACTIVATE, 0x73 };
+ uint8_t dummy_buffer[sizeof (ACTIVATE_SEQUENCE)] = { 0, 0 };
+ nRFCMD_ReadWriteBuffer (ACTIVATE_SEQUENCE, dummy_buffer,
+ sizeof (ACTIVATE_SEQUENCE));
+ nRFCMD_RegWriteStatusRead (FEATURE, features);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_CMD.c b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_CMD.c
new file mode 100644
index 0000000..a87e477
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/src/nRF_CMD.c
@@ -0,0 +1,238 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - midlevel access functions for
+ * issuing raw commands to the nRF24L01 2.4Ghz frontend
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides generic register level access functions
+ * for accessing nRF24L01 registers at a generic level
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "pmu.h"
+#include "nRF_API.h"
+#include "nRF_HW.h"
+#include "nRF_CMD.h"
+#include "spi.h"
+
+/* IO definitions */
+#define RF_IRQ_CPU_PORT 1
+#define RF_IRQ_CPU_PIN 9
+#define CPU_CE_RF_PORT 0
+#define CPU_CE_RF_PIN 11
+#define CPU_SWITCH_RF_PORT 0
+#define CPU_SWITCH_RF_PIN 2
+
+#define SPI_MAX_XFER_LEN 33
+#define NRFCMD_MACRO_READ 0x80
+
+#define SPI_MAX_XFER_LEN 33
+#define NRFCMD_MACRO_READ 0x80
+static uint8_t spi_outbuf[SPI_MAX_XFER_LEN];
+static uint8_t spi_inbuf[SPI_MAX_XFER_LEN];
+
+void
+nRFCMD_CE (uint8_t enable)
+{
+ GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, enable ? 1 : 0);
+}
+
+void
+nRFCMD_Power (uint8_t enable)
+{
+ GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, enable ? 0 : 1);
+}
+
+void
+nRFCMD_ReadWriteBuffer (const uint8_t * tx_data, uint8_t * rx_data,
+ uint32_t len)
+{
+ spi_txrx (SPI_CS_NRF, tx_data, len, rx_data, len);
+}
+
+static uint8_t
+nRFCMD_ReadWriteByte (uint8_t reg)
+{
+ uint8_t res;
+
+ nRFCMD_ReadWriteBuffer (®, &res, 1);
+
+ return res;
+}
+
+uint8_t
+nRFCMD_CmdExec (uint8_t cmd)
+{
+ uint8_t res;
+
+ res = nRFCMD_ReadWriteByte (cmd);
+
+ return res;
+}
+
+uint8_t
+nRFCMD_RegRead (uint8_t reg)
+{
+ spi_outbuf[0] = reg;
+ spi_outbuf[1] = 0;
+
+ nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, 2);
+
+ return spi_inbuf[1];
+}
+
+uint8_t
+nRFCMD_RegWriteStatusRead (uint8_t reg, uint8_t value)
+{
+ spi_outbuf[0] = reg;
+ spi_outbuf[1] = value;
+
+ nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, 2);
+
+ return spi_inbuf[0];
+}
+
+uint8_t
+nRFCMD_RegWriteBuf (uint8_t reg, const uint8_t * buf, uint8_t count)
+{
+ spi_outbuf[0] = reg;
+ memcpy (spi_outbuf + 1, buf, count);
+ nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, count + 1);
+
+ return spi_inbuf[0];
+}
+
+uint8_t
+nRFCMD_RegReadBuf (uint8_t reg, uint8_t * buf, uint8_t count)
+{
+ spi_outbuf[0] = reg;
+ nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, count + 2);
+ memcpy (buf, spi_inbuf + 1, count);
+
+ return spi_inbuf[0];
+}
+
+uint8_t
+nRFCMD_GetRegSize (uint8_t reg)
+{
+ uint8_t res;
+
+ if (reg > 0x17)
+ res = 0;
+ else
+ switch (reg)
+ {
+ case RX_ADDR_P0:
+ case RX_ADDR_P1:
+ case TX_ADDR:
+ res = NRF_MAX_MAC_SIZE;
+ break;
+ default:
+ res = 1;
+ }
+ return res;
+}
+
+void
+nRFCMD_ExecMacro (const uint8_t * macro)
+{
+ unsigned char size;
+
+ while ((size = *macro++) != 0)
+ {
+ nRFCMD_ReadWriteBuffer (macro, NULL, size - 1);
+ macro += size;
+ }
+}
+
+void
+nRFCMD_RegisterDump (void)
+{
+ uint8_t t, size, reg, buf[32];
+
+ reg = 0;
+ debug_printf ("\nnRFCMD_RegisterDump:\n");
+ while (((size = nRFCMD_GetRegSize (reg)) > 0) && (reg < 0xFF))
+ {
+ nRFCMD_RegReadBuf (reg, buf, size);
+
+ debug_printf ("\treg[0x%02X]:", reg);
+ for (t = 0; t < size; t++)
+ debug_printf (" 0x%02X", buf[t]);
+ debug_printf ("\n");
+
+ reg++;
+ }
+ debug_printf ("\n");
+}
+
+void
+WAKEUP_IRQHandlerPIO1_9 (void)
+{
+ /* Clear pending IRQ */
+ LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9;
+
+ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
+ __NOP ();
+}
+
+void
+nRFCMD_Shutdown (void)
+{
+ /* disable RX mode */
+ nRFCMD_CE (0);
+
+ /* wait 5ms */
+ pmu_sleep_ms (5);
+
+ /* switch to TX mode */
+ nRFAPI_SetRxMode (0);
+
+ /* powering down */
+ nRFAPI_PowerDown ();
+
+ /* set pins to lowest power */
+ GPIOSetDir (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 1);
+ GPIOSetValue (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0);
+ GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0);
+ GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0);
+}
+
+void
+nRFCMD_Init (void)
+{
+ /* setup SPI chipselect pin */
+ spi_init_pin (SPI_CS_NRF);
+
+ /* setup IOs */
+ LPC_IOCON->PIO1_9 = 0;
+ GPIOSetDir (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0);
+ NVIC_EnableIRQ (WAKEUP_PIO1_9_IRQn);
+ LPC_SYSCON->STARTAPRP0 = (LPC_SYSCON->STARTAPRP0 & ~STARTxPRP0_PIO1_9);
+ LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9;
+ LPC_SYSCON->STARTERP0 |= STARTxPRP0_PIO1_9;
+
+ LPC_IOCON->JTAG_TDI_PIO0_11 = 0x81;
+ GPIOSetDir (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 1);
+ GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0);
+
+ LPC_IOCON->PIO0_2 = 0;
+ GPIOSetDir (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 1);
+ GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/pmu.c b/openbeacon/lpc13xx/openbeacon-sensor/src/pmu.c
new file mode 100644
index 0000000..83167b6
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/src/pmu.c
@@ -0,0 +1,160 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - LPC13xx Power Management Functions
+ *
+ * Copyright 2011 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "pmu.h"
+#include "spi.h"
+#include "nRF_API.h"
+#include "nRF_CMD.h"
+#include "openbeacon-proto.h"
+
+static uint32_t g_sysahbclkctrl;
+
+#define MAINCLKSEL_IRC 0
+#define MAINCLKSEL_SYSPLL_IN 1
+#define MAINCLKSEL_WDT 2
+#define MAINCLKSEL_SYSPLL_OUT 3
+
+#define SYSTEM_TMR16B0_PRESCALER 10000
+
+void
+WAKEUP_IRQHandlerPIO0_8 (void)
+{
+ if(LPC_SYSCON->MAINCLKSEL != MAINCLKSEL_SYSPLL_OUT)
+ {
+ /* switch to IRC oscillator */
+ LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_SYSPLL_OUT;
+ /* push clock change */
+ LPC_SYSCON->MAINCLKUEN = 0;
+ LPC_SYSCON->MAINCLKUEN = 1;
+ /* wait for clock change to be finished */
+ while (!(LPC_SYSCON->MAINCLKUEN & 1));
+ /* power down watchdog oscillator */
+ LPC_SYSCON->PDRUNCFG |= WDTOSC_PD;
+ }
+
+ /* re-trigger match output */
+ LPC_TMR16B0->EMR &= ~1;
+ /* reset wakeup logic */
+ LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO0_8;
+ /* disable deep sleep */
+ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
+
+ /* enable previous clock settings */
+ LPC_SYSCON->SYSAHBCLKCTRL = g_sysahbclkctrl;
+ /* select MISO function for PIO0_8 */
+ LPC_IOCON->PIO0_8 = 1;
+
+ /* vodoo -NOP */
+ __NOP ();
+}
+
+void
+pmu_wait_ms (uint16_t ms)
+{
+ LPC_IOCON->PIO0_8 = 2;
+
+ g_sysahbclkctrl = LPC_SYSCON->SYSAHBCLKCTRL;
+ LPC_SYSCON->SYSAHBCLKCTRL |= EN_CT16B0;
+
+ /* prepare 16B0 timer */
+ LPC_TMR16B0->TCR = 2;
+ LPC_TMR16B0->PR = SYSTEM_CORE_CLOCK/SYSTEM_TMR16B0_PRESCALER;
+ LPC_TMR16B0->EMR = 2 << 4;
+ LPC_TMR16B0->MR0 = ms*10;
+ /* enable IRQ, reset and timer stop in MR0 match */
+ LPC_TMR16B0->MCR = 7;
+
+ /* prepare sleep */
+ LPC_PMU->PCON = (1 << 11) | (1 << 8);
+ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
+
+ /* start timer */
+ LPC_TMR16B0->TCR = 1;
+ /* sleep */
+ __WFI ();
+}
+
+void
+pmu_sleep_ms (uint16_t ms)
+{
+ if (ms < 10)
+ ms = 10;
+
+ /* select CT16B0_MAT0 function for PIO0_8 */
+ LPC_IOCON->PIO0_8 = 2;
+
+ /* Turn off all other peripheral dividers FIXME save settings */
+/* LPC_SYSCON->SSPCLKDIV = 0;
+ LPC_SYSCON->USBCLKDIV = 0;
+ LPC_SYSCON->WDTCLKDIV = 0;
+ LPC_SYSCON->SYSTICKCLKDIV = 0;*/
+
+ g_sysahbclkctrl = LPC_SYSCON->SYSAHBCLKCTRL;
+ LPC_SYSCON->SYSAHBCLKCTRL = EN_RAM | EN_GPIO | EN_CT16B0 | EN_FLASHARRAY | EN_IOCON;
+
+ /* prepare 16B0 timer */
+ LPC_TMR16B0->TCR = 2;
+ LPC_TMR16B0->PR = 8;
+ LPC_TMR16B0->EMR = 2 << 4;
+ LPC_TMR16B0->MR0 = ms - 7;
+ /* enable IRQ, reset and timer stop in MR0 match */
+ LPC_TMR16B0->MCR = 7;
+
+ /* prepare sleep */
+ LPC_PMU->PCON = (1 << 11) | (1 << 8);
+ SCB->SCR = SCB_SCR_SLEEPDEEP_Msk;
+
+ /* power up watchdog */
+ LPC_SYSCON->PDRUNCFG &= ~WDTOSC_PD;
+ /* save current power settings, power WDT on wake */
+ LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
+ /* power watchdog oscillator in deep sleep mode */
+ LPC_SYSCON->PDSLEEPCFG = (~WDTOSC_PD) & 0xFFF;
+ /* switch MAINCLKSEL to Watchdog Oscillator */
+ LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_WDT;
+ /* push clock change */
+ LPC_SYSCON->MAINCLKUEN = 0;
+ LPC_SYSCON->MAINCLKUEN = 1;
+ /* wait for clock change to be executed */
+ while (!(LPC_SYSCON->MAINCLKUEN & 1));
+
+ /* start timer */
+ LPC_TMR16B0->TCR = 1;
+ /* sleep */
+ __WFI ();
+}
+
+void
+pmu_init (void)
+{
+ /* reset 16B0 timer */
+ LPC_TMR16B0->TCR = 2;
+ /* Turn on the watchdog oscillator */
+ LPC_SYSCON->WDTOSCCTRL = 0x3F;
+ /* enable IRQ routine for PIO0_8 */
+ NVIC_EnableIRQ (WAKEUP_PIO0_8_IRQn);
+ /* initialize start logic for PIO0_8 */
+ LPC_SYSCON->STARTAPRP0 |= STARTxPRP0_PIO0_8;
+ LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO0_8;
+ LPC_SYSCON->STARTERP0 |= STARTxPRP0_PIO0_8;
+}
diff --git a/openbeacon/lpc13xx/openbeacon-sensor/src/sound.c b/openbeacon/lpc13xx/openbeacon-sensor/src/sound.c
new file mode 100644
index 0000000..78f0b72
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-sensor/src/sound.c
@@ -0,0 +1,93 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - piezo speaker sound functions
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include
+
+#ifdef SOUND_ENABLE
+
+#define ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0]))
+
+void
+snd_beep (uint16_t frequency)
+{
+ uint32_t t;
+
+ LPC_TMR32B1->TCR = 0;
+ if (frequency)
+ {
+ t = (SYSTEM_CORE_CLOCK / 2) / frequency;
+
+ LPC_TMR32B1->MR0 = LPC_TMR32B1->MR1 = t;
+
+ if (LPC_TMR32B1->TC >= t)
+ LPC_TMR32B1->TC = t;
+
+ LPC_TMR32B1->TCR = 1;
+ }
+}
+
+static inline uint16_t
+snd_get_frequency_for_tone (uint8_t tone)
+{
+ static const uint16_t frequency[] = { 26263, 29366, 32963, 34923, 39200, 44000, 49388 };
+ return (((uint32_t) frequency[tone % ARRAY_COUNT (frequency)]) * (1 << (tone/ARRAY_COUNT(frequency))))/100;
+}
+
+void
+snd_tone (uint8_t tone)
+{
+ static uint8_t lasttone = 0;
+
+ if (tone != lasttone)
+ {
+ if (tone)
+ {
+ LPC_SYSCON->SYSAHBCLKCTRL |= EN_CT32B1;
+ LPC_TMR32B1->EMR = 1 | (0x3 << 4) | (0x3 << 6);
+ snd_beep (tone ? snd_get_frequency_for_tone (tone - 1) : 0);
+ }
+ else
+ {
+ LPC_TMR32B1->EMR = 0;
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~EN_CT32B1;
+ }
+
+ lasttone = tone;
+ }
+}
+
+void
+snd_init (void)
+{
+ /* Set sound port to PIO1_1 and PIO1_2 */
+ LPC_GPIO1->DIR |= 0x6;
+ LPC_IOCON->JTAG_TDO_PIO1_1 = 3;
+ LPC_IOCON->JTAG_nTRST_PIO1_2 = 3;
+
+ /* run 32 bit timer for sound generation */
+ LPC_SYSCON->SYSAHBCLKCTRL |= EN_CT32B1;
+ LPC_TMR32B1->TCR = 2;
+ LPC_TMR32B1->MCR = 1 << 4;
+ LPC_TMR32B1->EMR = 0;
+}
+#endif /*SOUND_ENABLE */
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/.gitignore b/openbeacon/lpc13xx/openbeacon-usb2/.gitignore
new file mode 100644
index 0000000..86b18f5
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/.gitignore
@@ -0,0 +1,2 @@
+.cproject
+.project
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/Makefile b/openbeacon/lpc13xx/openbeacon-usb2/Makefile
new file mode 100644
index 0000000..689585f
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/Makefile
@@ -0,0 +1,32 @@
+TARGET=openbeacon-usb2
+ARCH=LPC13
+CPU=$(ARCH)43
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/main.c \
+ src/nRF_CMD.c \
+ src/nRF_API.c \
+ src/pin.c \
+ src/pmu.c \
+ src/storage.c
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+publish: clean $(TARGET).bin
+ rm -f $(TARGET).zip
+ ../lpc-flash/src/lpc-flash $(TARGET).bin firmware.bin
+ zip $(TARGET).zip firmware.bin
+ scp $(TARGET).zip firmware.bin meri@bitmanufaktur.net:/home/wwwrun/open.bitmanufaktur.com/web/www/people/milosch/usb2tag/
+
+app_clean:
+ rm -f $(TARGET).zip $(TARGET)-firmware.bin
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/3d_acceleration.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/3d_acceleration.h
new file mode 100644
index 0000000..941d839
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/3d_acceleration.h
@@ -0,0 +1,31 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - 3D acceleration sensor support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __3D_ACCELERATION_H__
+#define __3D_ACCELERATION_H__
+
+extern void acc_init (uint8_t enabled);
+extern void acc_status (void);
+extern void acc_xyz_read (int *x, int *y, int *z);
+
+#endif/*__3D_ACCELERATION_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/FreeRTOSConfig.h
new file mode 100644
index 0000000..68126cc
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/FreeRTOSConfig.h
@@ -0,0 +1,103 @@
+/*
+ FreeRTOS V6.0.0 - Copyright (C) 2009 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.
+
+ 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.
+ */
+
+/******************************************************************************
+ See http://www.freertos.org/a00110.html for an explanation of the
+ definitions contained in this file.
+ ******************************************************************************/
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include "LPC13xx.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 0
+#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock )
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 128 ) )
+#define configMAX_TASK_NAME_LEN ( 12 )
+#define configUSE_TRACE_FACILITY 0
+#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 1
+#define configUSE_ALTERNATIVE_API 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configQUEUE_REGISTRY_SIZE 0
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+
+/* 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 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) )
+
+#endif /* FREERTOS_CONFIG_H */
+
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/bluetooth.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/bluetooth.h
new file mode 100644
index 0000000..9c9d81a
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/bluetooth.h
@@ -0,0 +1,29 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - Bluetooth related functions
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __BLUETOOTH_H__
+#define __BLUETOOTH_H__
+
+extern void bt_init (uint8_t enabled);
+
+#endif/*__BLUETOOTH_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/config.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/config.h
new file mode 100644
index 0000000..820edfc
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/config.h
@@ -0,0 +1,47 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - config file
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/* enable USB disk support */
+#define USB_DISK_SUPPORT
+#define USB_VENDOR_ID 0x2366
+#define USB_PROD_ID 0x0003
+#define USB_DEVICE 1
+
+/* SPI_CS(io_port, io_pin, CPSDVSR frequency, mode) */
+#define SPI_CS_FLASH SPI_CS( 2, 0, 24, SPI_CS_MODE_SKIP_TX ) /* 24.0MHz */
+#define SPI_CS_NRF SPI_CS( 1,10, 24, SPI_CS_MODE_NORMAL ) /* 9.6MHz */
+//#define SPI_CS_ACC3D SPI_CS( 0, 4, 6, SPI_CS_MODE_NORMAL ) /* 8.0MHz */
+
+#define NRF_MAX_MAC_SIZE 5
+
+/* FreeRTOS configuration */
+#define ENABLE_FREERTOS
+#define TASK_NRF_STACK_SIZE 256
+#define TASK_NRF_PRIORITY (tskIDLE_PRIORITY + 2)
+
+#define UPDATE_INTERVAL_MS 50
+
+#endif/*__CONFIG_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_API.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_API.h
new file mode 100644
index 0000000..068e73f
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_API.h
@@ -0,0 +1,63 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - function definitions
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides high level initialization and startup sanity
+ * checks and test routines to verify that the chip is working
+ * properly and no soldering errors occored on the digital part.
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef NRF_API_H
+#define NRF_API_H
+
+#include
+
+extern uint8_t nRFAPI_Init (uint8_t channel,
+ const uint8_t * mac,
+ uint8_t mac_size, uint8_t features);
+extern void nRFAPI_SetTxPower (uint8_t power);
+extern void nRFAPI_TxRetries (uint8_t count);
+extern void nRFAPI_SetRxMode (uint8_t receive);
+extern void nRFAPI_PipesEnable (uint8_t mask);
+extern void nRFAPI_PipesAck (uint8_t mask);
+extern uint8_t nRFAPI_GetSizeMac (void);
+extern uint8_t nRFAPI_SetSizeMac (uint8_t addr_size);
+extern void nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size);
+extern void nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size);
+extern void nRFAPI_SetRxMAC (const uint8_t * addr,
+ uint8_t addr_size, uint8_t pipe);
+extern void nRFAPI_SetChannel (uint8_t channel);
+extern uint8_t nRFAPI_GetChannel (void);
+extern uint8_t nRFAPI_ClearIRQ (uint8_t status);
+extern void nRFAPI_TX (uint8_t * buf, uint8_t count);
+extern uint8_t nRFAPI_GetStatus (void);
+extern uint8_t nRFAPI_GetPipeSizeRX (uint8_t pipe);
+extern void nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size);
+extern uint8_t nRFAPI_GetPipeCurrent (void);
+extern uint8_t nRFAPI_RX (uint8_t * buf, uint8_t count);
+extern void nRFAPI_FlushRX (void);
+extern void nRFAPI_FlushTX (void);
+extern void nRFAPI_ReuseTX (void);
+extern uint8_t nRFAPI_GetFifoStatus (void);
+extern uint8_t nRFAPI_CarrierDetect (void);
+extern void nRFAPI_SetFeatures (uint8_t features);
+extern void nRFAPI_PowerDown (void);
+
+#endif /*NRF_API_H */
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_CMD.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_CMD.h
new file mode 100644
index 0000000..6f63908
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_CMD.h
@@ -0,0 +1,46 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - midlevel access function defines for
+ * issuing raw commands to the nRF24L01 2.4Ghz frontend
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides generic register level access functions
+ * for accessing nRF24L01 registers at a generic level
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef NRF_CMD_H
+#define NRF_CMD_H
+
+extern uint8_t nRFCMD_CmdExec (uint8_t reg);
+extern uint8_t nRFCMD_RegRead (uint8_t reg);
+extern uint8_t nRFCMD_RegWriteStatusRead (uint8_t reg, uint8_t value);
+extern uint8_t nRFCMD_RegWriteBuf (uint8_t reg, const uint8_t * buf, uint8_t count);
+extern uint8_t nRFCMD_RegReadBuf (uint8_t reg, uint8_t * buf, uint8_t count);
+extern uint8_t nRFCMD_GetRegSize (uint8_t reg);
+extern uint8_t nRFCMD_WaitRx(uint32_t ticks);
+extern void nRFCMD_CE (uint8_t enable);
+extern void nRFCMD_Power (uint8_t enable);
+extern void nRFCMD_ReadWriteBuffer (const uint8_t * tx_data, uint8_t * rx_data, uint32_t len);
+extern void nRFCMD_ExecMacro (const uint8_t * macro);
+extern void nRFCMD_RegisterDump (void);
+extern void nRFCMD_Init (void);
+extern void nRFCMD_Status (void);
+
+#endif /*NRF_CMD_H */
+
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_HW.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_HW.h
new file mode 100644
index 0000000..c4d17dc
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/nRF_HW.h
@@ -0,0 +1,109 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - opcode & register definitions for nRF24L01
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides a nice set of defines to work properly with the
+ * nRF24L01 CPU
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#ifndef NRF_HW_H
+#define NRF_HW_H
+
+//********************************************************************************************************************//
+// SPI(nRF24L01) commands
+#define READ_REG 0x00 // Define read command to register
+#define WRITE_REG 0x20 // Define write command to register
+#define RD_RX_PLOAD 0x61 // Define RX payload register address
+#define WR_TX_PLOAD 0xA0 // Define TX payload register address
+#define FLUSH_TX 0xE1 // Define flush TX register command
+#define FLUSH_RX 0xE2 // Define flush RX register command
+#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
+#define OP_NOP 0xFF // Define No Operation, might be used to read status register
+#define ACTIVATE 0x50 // ACTIVATE additional features
+#define R_RX_PL_WID 0x60 // Define Read RX-payload width command
+#define W_ACK_PAYLOAD 0xA8 // Write payload to be used in ACK packet on pipe PPP
+#define W_TX_PAYLOAD_NOACK 0xB0 // Used in TX mode, Disable AUTOACK on this specific packet
+
+
+//********************************************************************************************************************//
+// SPI(nRF24L01) registers(addresses)
+#define CONFIG 0x00 // 'Config' register address
+#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
+#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
+#define SETUP_AW 0x03 // 'Setup address width' register address
+#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
+#define RF_CH 0x05 // 'RF channel' register address
+#define RF_SETUP 0x06 // 'RF setup' register address
+#define STATUS 0x07 // 'Status' register address
+#define OBSERVE_TX 0x08 // 'Observe TX' register address
+#define CD 0x09 // 'Carrier Detect' register address
+#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
+#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
+#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
+#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
+#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
+#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
+#define TX_ADDR 0x10 // 'TX address' register address
+#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
+#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
+#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
+#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
+#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
+#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
+#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
+#define FEATURE 0x1D // Additional features register, needed to enable the additional commands
+
+//********************************************************************************************************************//
+// SPI(nRF24L01) registers(bitmasks)
+#define ERX_P0 0x01 // Enable Pipe 0 (register EN_RXADDR)
+#define ERX_P1 0x02 // Enable Pipe 1 (register EN_RXADDR)
+#define ERX_P2 0x04 // Enable Pipe 2 (register EN_RXADDR)
+#define ERX_P3 0x08 // Enable Pipe 3 (register EN_RXADDR)
+#define ERX_P4 0x10 // Enable Pipe 4 (register EN_RXADDR)
+#define ERX_P5 0x20 // Enable Pipe 5 (register EN_RXADDR)
+
+//********************************************************************************************************************//
+// 'Config' register mask bits
+#define NRF_CONFIG_PRIM_RX 0x01
+#define NRF_CONFIG_PWR_UP 0x02
+#define NRF_CONFIG_CRCO 0x04
+#define NRF_CONFIG_EN_CRC 0x08
+#define NRF_CONFIG_MASK_MAX_RT 0x10
+#define NRF_CONFIG_MASK_TX_DS 0x20
+#define NRF_CONFIG_MASK_RX_DR 0x40
+#define NRF_CONFIG_MASK_IRQS (NRF_CONFIG_MASK_MAX_RT|NRF_CONFIG_MASK_TX_DS|NRF_CONFIG_MASK_RX_DR)
+
+
+#define MASK_RX_DR_FLAG 0x40
+#define MASK_TX_DS_FLAG 0x20
+#define MASK_MAX_RT_FLAG 0x10
+#define MASK_IRQ_FLAGS (MASK_MAX_RT_FLAG|MASK_TX_DS_FLAG|MASK_RX_DR_FLAG)
+
+#define FIFO_RX_EMPTY 0x01
+#define FIFO_RX_FULL 0x02
+#define FIFO_TX_EMPTY 0x10
+#define FIFO_TX_FULL 0x20
+#define FIFO_TX_REUSE 0x40
+
+#define NRF_MIN_MAC_SIZE 3
+#define NRF_MAX_MAC_SIZE 5
+#define NRF_MAX_BUFFER_SIZE 32
+
+#endif /*NRF_HW_H */
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/openbeacon-proto.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/openbeacon-proto.h
new file mode 100644
index 0000000..6e7dded
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/openbeacon-proto.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+ *
+ * OpenBeacon.org - OnAir protocol specification and definition
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ ****************************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __OPENBEACON_PROTO_H__
+#define __OPENBEACON_PROTO_H__
+
+#define CONFIG_TRACKER_CHANNEL 81
+#define CONFIG_PROX_CHANNEL 76
+
+#define XXTEA_BLOCK_COUNT 4
+
+#define RFBPROTO_READER_ANNOUNCE 22
+#define RFBPROTO_READER_COMMAND 23
+#define RFBPROTO_BEACONTRACKER 24
+#define RFBPROTO_PROXTRACKER 42
+#define RFBPROTO_PROXREPORT 69
+
+#define PROX_MAX 4
+
+#define RFBFLAGS_ACK 0x01
+#define RFBFLAGS_SENSOR 0x02
+#define RFBFLAGS_INFECTED 0x04
+
+/* RFBPROTO_READER_COMMAND related opcodes */
+#define READER_CMD_NOP 0x00
+#define READER_CMD_RESET 0x01
+#define READER_CMD_RESET_CONFIG 0x02
+#define READER_CMD_RESET_FACTORY 0x03
+#define READER_CMD_RESET_WIFI 0x04
+#define READER_CMD_SET_OID 0x05
+/* RFBPROTO_READER_COMMAND related results */
+#define READ_RES__OK 0x00
+#define READ_RES__DENIED 0x01
+#define READ_RES__UNKNOWN_CMD 0xFF
+
+typedef struct
+{
+ uint8_t strength;
+ uint16_t oid_last_seen;
+ uint16_t powerup_count;
+ uint8_t reserved;
+ uint32_t seq;
+} PACKED TBeaconTracker;
+
+typedef struct
+{
+ uint16_t oid_prox[PROX_MAX];
+ uint16_t seq;
+} PACKED TBeaconProx;
+
+typedef struct
+{
+ uint8_t opcode, res;
+ uint32_t data[2];
+} PACKED TBeaconReaderCommand;
+
+typedef struct
+{
+ uint8_t opcode, strength;
+ uint32_t uptime, ip;
+} PACKED TBeaconReaderAnnounce;
+
+typedef union
+{
+ TBeaconProx prox;
+ TBeaconTracker tracker;
+ TBeaconReaderCommand reader_command;
+ TBeaconReaderAnnounce reader_announce;
+} PACKED TBeaconPayload;
+
+typedef struct
+{
+ uint8_t proto;
+ uint16_t oid;
+ uint8_t flags;
+
+ TBeaconPayload p;
+
+ uint16_t crc;
+} PACKED TBeaconWrapper;
+
+typedef union
+{
+ TBeaconWrapper pkt;
+ uint32_t block[XXTEA_BLOCK_COUNT];
+ uint8_t byte[XXTEA_BLOCK_COUNT * 4];
+} PACKED TBeaconEnvelope;
+
+#endif/*__OPENBEACON_PROTO_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h
new file mode 100644
index 0000000..2702f74
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/pin.h
@@ -0,0 +1,36 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - GPIO declaration
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __PIN_H__
+#define __PIN_H__
+
+#define GPIO_LEDS_OFF 0
+#define GPIO_LED0 1
+#define GPIO_LED1 2
+
+extern void pin_init (void);
+extern void pin_led (uint8_t led);
+extern void pin_mode_pmu (uint8_t mode);
+extern uint8_t pin_button0 (void);
+
+#endif /*__PIN_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h
new file mode 100644
index 0000000..6616ff9
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/pmu.h
@@ -0,0 +1,49 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - Power Management
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#define PMU_IRCOUT_PD (1UL << 0)
+#define PMU_IRC_PD (1UL << 1)
+#define PMU_FLASH_PD (1UL << 2)
+#define PMU_BOD_PD (1UL << 3)
+#define PMU_ADC_PD (1UL << 4)
+#define PMU_SYSOSC_PD (1UL << 5)
+#define PMU_WDTOSC_PD (1UL << 6)
+#define PMU_SYSPLL_PD (1UL << 7)
+#define PMU_USBPLL_PD (1UL << 8)
+#define PMU_RESERVED1_DEEP_PD (1UL << 9)
+#define PMU_USBPAD_PD (1UL <<10)
+#define PMU_RESERVED2_DEEP_PD (1UL <<11)
+
+#define NVIC_LP_SEVONPEND (0x10)
+#define NVIC_LP_SLEEPDEEP (0x04)
+#define NVIC_LP_SLEEPONEXIT (0x02)
+
+extern void pmu_init (void);
+extern void pmu_status (void);
+extern void pmu_off (uint32_t reason);
+extern uint32_t pmu_reason (void);
+
+#endif /*__PMU_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/inc/storage.h b/openbeacon/lpc13xx/openbeacon-usb2/inc/storage.h
new file mode 100644
index 0000000..948998d
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/inc/storage.h
@@ -0,0 +1,32 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - FLASH storage support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#ifndef __STORAGE_H__
+#define __STORAGE_H__
+
+#include "msd.h"
+
+extern void storage_init (void);
+extern void storage_status (void);
+
+#endif/*__STORAGE_H__*/
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/3d_acceleration.c b/openbeacon/lpc13xx/openbeacon-usb2/src/3d_acceleration.c
new file mode 100644
index 0000000..263b5ac
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/3d_acceleration.c
@@ -0,0 +1,100 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - 3D acceleration sensor support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "3d_acceleration.h"
+#include "spi.h"
+
+/* IO definitions */
+#define ACC_INT_PORT 1
+#define ACC_INT_PIN 11
+
+static void
+acc_reg_write (uint8_t addr, uint8_t data)
+{
+ uint8_t tx[2];
+
+ /* assemble SPI write request */
+ tx[0] = 0x80 | addr << 1;
+ tx[1] = data;
+
+ /* transmit packet */
+ spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), NULL, 0);
+}
+
+static uint8_t
+acc_reg_read (uint8_t addr)
+{
+ uint8_t tx[2], rx[2];
+
+ /* assemble SPI read request */
+ tx[0] = addr << 1;
+ tx[1] = 0;
+ /* transmit packet */
+ spi_txrx (SPI_CS_ACC3D, tx, sizeof (tx), rx, sizeof (rx));
+
+ return rx[1];
+}
+
+void
+acc_xyz_read (int *x, int *y, int *z)
+{
+ /* dummy read - FIXME */
+ acc_reg_read (0);
+
+ /* get acceleration values */
+ *x = (int8_t) acc_reg_read (6);
+ *y = (int8_t) acc_reg_read (7);
+ *z = (int8_t) acc_reg_read (8);
+}
+
+void
+acc_status (void)
+{
+ int x, y, z;
+
+ acc_xyz_read (&x, &y, &z);
+
+ debug_printf (" * 3D_ACC: X=%04i Y=%04i Z=%04i\n", x, y, z);
+}
+
+void
+acc_init (uint8_t enabled)
+{
+ /* PIO, PIO0_4 in standard IO functionality */
+ LPC_IOCON->PIO0_4 = 1 << 8;
+
+ /* PIO, Inactive Pull, Digital Mode */
+ LPC_IOCON->PIO1_11 = (1<<7)|(2<<3);
+
+ /* setup SPI chipselect pin */
+ spi_init_pin (SPI_CS_ACC3D);
+
+ /* Set ACC_INT port to input */
+ GPIOSetDir (ACC_INT_PORT, ACC_INT_PIN, 0);
+
+ /* dummy read - FIXME */
+ acc_reg_read (0);
+
+ /* set 3D acceleration sensor active, 2g - FIXME power saving */
+ acc_reg_write (0x16, enabled ? (0x01 | 0x01 << 2) : 0x00);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/bluetooth.c b/openbeacon/lpc13xx/openbeacon-usb2/src/bluetooth.c
new file mode 100644
index 0000000..91c76ec
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/bluetooth.c
@@ -0,0 +1,87 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - Bluetooth related functions
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "bluetooth.h"
+
+#define CPU_WAKEUP_BLT_PORT 1
+#define CPU_WAKEUP_BLT_PIN 3
+#define CPU_BLT_WAKEUP_PORT 2
+#define CPU_BLT_WAKEUP_PIN 0
+#define CPU_ON_OFF_BLT_PORT 1
+#define CPU_ON_OFF_BLT_PIN 0
+
+static const char *bt_init_strings[] = {
+ "SEC=3,2,2,04,0000",
+ "SLN=17,OpenBeacon USB II",
+ "RLS=1101,13,Debug Console,01,000000",
+ "DIS=3",
+ "AAC=1",
+ "SCR"
+};
+
+#define BT_INIT_STRINGS_COUNT ((int)(sizeof(bt_init_strings)/sizeof(bt_init_strings[0])))
+
+void
+bt_init (uint8_t enabled)
+{
+ int bt_init_pos = 0;
+
+ /* Init UART for Bluetooth module without RTS/CTS */
+ UARTInit (115200, 0);
+
+ /* fake CTS for now */
+ GPIOSetDir (1, 5, 1);
+ GPIOSetValue (1, 5, 0);
+
+ /* Set CPU_WAKEUP_BLT port pin to output */
+ LPC_IOCON->ARM_SWDIO_PIO1_3 = 1;
+ GPIOSetDir (CPU_WAKEUP_BLT_PORT, CPU_WAKEUP_BLT_PIN, 1);
+ GPIOSetValue (CPU_WAKEUP_BLT_PORT, CPU_WAKEUP_BLT_PIN, enabled ? 1 : 0);
+
+ /* Set CPU_BLT_WAKEUP port pin to input */
+ LPC_IOCON->PIO2_0 = 0;
+ GPIOSetDir (CPU_BLT_WAKEUP_PORT, CPU_BLT_WAKEUP_PIN, 0);
+ GPIOSetValue (CPU_BLT_WAKEUP_PORT, CPU_BLT_WAKEUP_PIN, 0);
+
+ /* Set CPU_ON-OFF_BLT port pin to output */
+ LPC_IOCON->JTAG_TMS_PIO1_0 = 1;
+ GPIOSetDir (CPU_ON_OFF_BLT_PORT, CPU_ON_OFF_BLT_PIN, 1);
+ GPIOSetValue (CPU_ON_OFF_BLT_PORT, CPU_ON_OFF_BLT_PIN, enabled ? 1 : 0);
+
+ /* iterate through all bt_init_strings if activated */
+ if (enabled)
+ while (bt_init_pos <= BT_INIT_STRINGS_COUNT)
+ {
+ /* wait for CR */
+ while (UARTCount)
+ if (UARTBuffer[--UARTCount] == '\n')
+ {
+ /* emmpty buffers */
+ UARTCount = 0;
+ /* output next init string */
+ if (bt_init_pos < BT_INIT_STRINGS_COUNT)
+ debug_printf ("AT+J%s\n", bt_init_strings[bt_init_pos]);
+ bt_init_pos++;
+ }
+ }
+}
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/main.c b/openbeacon/lpc13xx/openbeacon-usb2/src/main.c
new file mode 100644
index 0000000..36e55ae
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/main.c
@@ -0,0 +1,379 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - main file for OpenBeacon USB II Bluetooth
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "pin.h"
+#include "hid.h"
+#include "spi.h"
+#include "iap.h"
+#include "pmu.h"
+#include "crc16.h"
+#include "xxtea.h"
+#include "bluetooth.h"
+#include "storage.h"
+#include "nRF_API.h"
+#include "nRF_CMD.h"
+#include "openbeacon-proto.h"
+
+/* OpenBeacon packet */
+static TBeaconEnvelope g_Beacon;
+
+/* Default TEA encryption key of the tag - MUST CHANGE ! */
+static const uint32_t xxtea_key[4] =
+{ 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
+
+/* set nRF24L01 broadcast mac */
+static const unsigned char broadcast_mac[NRF_MAX_MAC_SIZE] =
+{ 1, 2, 3, 2, 1 };
+
+/* device UUID */
+static uint16_t tag_id;
+static TDeviceUID device_uuid;
+
+#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0)
+static uint8_t hid_buffer[USB_HID_IN_REPORT_SIZE];
+
+void
+GetInReport (uint8_t * src, uint32_t length)
+{
+ (void) src;
+ (void) length;
+
+ if (length > USB_HID_IN_REPORT_SIZE)
+ length = USB_HID_IN_REPORT_SIZE;
+
+ memcpy (src, hid_buffer, length);
+}
+
+void
+SetOutReport (uint8_t * dst, uint32_t length)
+{
+ (void) dst;
+ (void) length;
+}
+#endif
+
+static void show_version(void)
+{
+ debug_printf(" * Tag ID: %i\n", (uint16_t) device_uuid[3]);
+ debug_printf(" * Device UID: %08X:%08X:%08X:%08X\n", device_uuid[0],
+ device_uuid[1], device_uuid[2], device_uuid[3]);
+ debug_printf(" * free heap memory: %i bytes\n",xPortGetFreeHeapSize());
+}
+
+void main_menue(uint8_t cmd)
+{
+ /* ignore non-printable characters */
+ if (cmd <= ' ')
+ return;
+ /* show key pressed */
+ debug_printf("%c\n", cmd);
+ /* map lower case to upper case */
+ if (cmd > 'a' && cmd < 'z')
+ cmd -= ('a' - 'A');
+
+ switch (cmd)
+ {
+ case '?':
+ case 'H':
+ debug_printf("\n"
+ " *****************************************************\n"
+ " * OpenBeacon USB II - Bluetooth Console *\n"
+ " * (C) 2010 Milosch Meriac *\n"
+ " *****************************************************\n"
+ " * H,? - this help screen\n"
+#ifdef MENUE_ALLOW_ISP_REBOOT
+ " * P - invoke ISP programming mode\n"
+#endif
+ " * S - show device status\n"
+ " * R - OpenBeacon nRF24L01 register dump\n"
+ " *****************************************************\n"
+ "\n");
+ break;
+#ifdef MENUE_ALLOW_ISP_REBOOT
+ case 'P':
+ debug_printf ("\nRebooting...");
+ iap_invoke_isp ();
+ break;
+#endif
+ case 'R':
+ nRFCMD_RegisterDump();
+ break;
+ case 'S':
+ debug_printf("\n"
+ " *****************************************************\n"
+ " * OpenBeacon Status Information *\n"
+ " *****************************************************\n");
+ show_version();
+ spi_status();
+ nRFCMD_Status();
+ // pmu_status ();
+#if (DISK_SIZE>0)
+ storage_status();
+#endif
+ nRFCMD_Status();
+ debug_printf(" *****************************************************\n"
+ "\n");
+ break;
+ default:
+ debug_printf("Unknown command '%c' - please press 'H' for help \n", cmd);
+ }
+ debug_printf("\n# ");
+}
+
+static
+void nRF_tx(uint8_t power)
+{
+ /* update crc */
+ g_Beacon.pkt.crc = htons(crc16(g_Beacon.byte, sizeof(g_Beacon)
+ - sizeof(uint16_t)));
+ /* encrypt data */
+ xxtea_encode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key);
+
+ pin_led(GPIO_LED0);
+
+ /* update power pin */
+ nRFCMD_Power(power & 0x4);
+
+ /* disable RX mode */
+ nRFCMD_CE(0);
+ vTaskDelay(5 / portTICK_RATE_MS);
+
+ /* switch to TX mode */
+ nRFAPI_SetRxMode(0);
+
+ /* set TX power */
+ nRFAPI_SetTxPower(power & 0x3);
+
+ /* upload data to nRF24L01 */
+ nRFAPI_TX(g_Beacon.byte, sizeof(g_Beacon));
+
+ /* transmit data */
+ nRFCMD_CE(1);
+
+ /* wait until packet is transmitted */
+ vTaskDelay(2 / portTICK_RATE_MS);
+
+ /* switch to RX mode again */
+ nRFAPI_SetRxMode(1);
+
+ pin_led(GPIO_LEDS_OFF);
+
+ if (power & 0x4)
+ nRFCMD_Power(0);
+}
+
+static
+void nRF_Task(void *pvParameters)
+{
+ int t, active;
+ uint8_t strength, status;
+ uint16_t crc;
+ uint32_t seq, oid;
+ portTickType LastUpdateTicks, Ticks;
+
+ (void) pvParameters;
+
+ /* Initialize OpenBeacon nRF24L01 interface */
+ if (!nRFAPI_Init(81, broadcast_mac, sizeof(broadcast_mac), 0))
+ /* bail out if can't initialize */
+ // for (;;)
+ {
+ pin_led(GPIO_LED0 | GPIO_LED1);
+ vTaskDelay(500 / portTICK_RATE_MS);
+
+ pin_led(GPIO_LEDS_OFF);
+ vTaskDelay(500 / portTICK_RATE_MS);
+ }
+
+ /* blink as a sign of boot to detect crashes */
+ for (t = 0; t < 20; t++)
+ {
+ pin_led(GPIO_LED0);
+ vTaskDelay(50 / portTICK_RATE_MS);
+
+ pin_led(GPIO_LEDS_OFF);
+ vTaskDelay(50 / portTICK_RATE_MS);
+ }
+
+ nRFAPI_SetRxMode(1);
+ nRFCMD_CE(1);
+
+ LastUpdateTicks = xTaskGetTickCount();
+
+ /* main loop */
+ active = 0;
+ seq = t = 0;
+ UARTCount = 0;
+ while (1)
+ {
+ /* turn off after button press */
+ if (!pin_button0())
+ {
+ pin_mode_pmu(0);
+ pmu_off(0);
+ }
+
+ if (nRFCMD_WaitRx(10 / portTICK_RATE_MS))
+ do
+ {
+ // read packet from nRF chip
+ nRFCMD_RegReadBuf(RD_RX_PLOAD, g_Beacon.byte, sizeof(g_Beacon));
+
+ // adjust byte order and decode
+ xxtea_decode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key);
+
+ // verify the CRC checksum
+ crc = crc16(g_Beacon.byte, sizeof(g_Beacon) - sizeof(uint16_t));
+
+ if (ntohs (g_Beacon.pkt.crc) == crc)
+ {
+ pin_led(GPIO_LED1);
+
+ oid = ntohs (g_Beacon.pkt.oid);
+ if (((g_Beacon.pkt.flags & RFBFLAGS_SENSOR) > 0) && active)
+ debug_printf("BUTTON: %i\n", oid);
+
+ switch (g_Beacon.pkt.proto)
+ {
+ case RFBPROTO_READER_ANNOUNCE:
+ strength = g_Beacon.pkt.p.reader_announce.strength;
+ break;
+
+ case RFBPROTO_BEACONTRACKER:
+ strength = g_Beacon.pkt.p.tracker.strength;
+ if (active)
+ debug_printf(" R: %04i={%i,0x%08X}\n", (int) oid,
+ (int) strength,
+ ntohl (g_Beacon.pkt.p.tracker.seq));
+ break;
+
+ case RFBPROTO_PROXREPORT:
+ strength = 3;
+ if (active)
+ debug_printf(" P: %04i={%i,0x%04X}\n", (int) oid,
+ (int) strength,
+ (int) ntohs (g_Beacon.pkt.p.prox.seq));
+ for (t = 0; t < PROX_MAX; t++)
+ {
+ crc = (ntohs (g_Beacon.pkt.p.prox.oid_prox[t]));
+ if (crc && active)
+ debug_printf("PX: %04i={%04i,%i,%i}\n",
+ (int) oid, (int) ((crc >> 0) & 0x7FF),
+ (int) ((crc >> 14) & 0x3), (int) ((crc
+ >> 11) & 0x7));
+ }
+ break;
+
+ default:
+ strength = 0xFF;
+ if (active)
+ debug_printf("Unknown Protocol: %i\n",
+ (int) g_Beacon.pkt.proto);
+ }
+
+ if (strength < 0xFF)
+ {
+ /* do something with the data */
+ }
+ pin_led(GPIO_LEDS_OFF);
+ }
+ status = nRFAPI_GetFifoStatus();
+ } while ((status & FIFO_RX_EMPTY) == 0);
+
+ nRFAPI_ClearIRQ(MASK_IRQ_FLAGS);
+
+ // update regularly
+ if (((Ticks = xTaskGetTickCount()) - LastUpdateTicks)
+ > UPDATE_INTERVAL_MS)
+ {
+ LastUpdateTicks = Ticks;
+
+ /* setup tracking packet */
+ bzero(&g_Beacon, sizeof(g_Beacon));
+ g_Beacon.pkt.oid = ntohs ((uint16_t)device_uuid[3]);
+ g_Beacon.pkt.proto = RFBPROTO_BEACONTRACKER;
+ g_Beacon.pkt.p.tracker.strength = seq % 8;
+ g_Beacon.pkt.p.tracker.seq = htonl(seq++);
+
+ /* send away packet */
+ nRF_tx(g_Beacon.pkt.p.tracker.strength);
+ }
+
+ if (UARTCount)
+ {
+ /* blink LED1 upon Bluetooth command */
+ pin_led(GPIO_LED1);
+
+ /* show help screen upon Bluetooth connect */
+ if (!active)
+ {
+ active = 1;
+ debug_printf("press 'H' for help...\n# ");
+ }
+ else
+ /* execute menu command with last character received */
+ main_menue(UARTBuffer[UARTCount - 1]);
+
+ /* LED1 off again */
+ pin_led(GPIO_LEDS_OFF);
+
+ /* clear UART buffer */
+ UARTCount = 0;
+ }
+ }
+}
+
+int main(void)
+{
+ volatile int i;
+ /* wait on boot - debounce */
+ for (i = 0; i < 2000000; i++)
+ ;
+ /* initialize pins */
+ pin_init();
+ /* Init SPI */
+ spi_init();
+ /* Init Storage */
+#ifdef USB_DISK_SUPPORT
+ storage_init();
+#endif
+ /* Init USB HID interface */
+#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0)
+ hid_init ();
+ #error hid
+#endif
+ /* power management init */
+ pmu_init();
+ /* read device UUID */
+ bzero(&device_uuid, sizeof(device_uuid));
+ iap_read_uid(&device_uuid);
+ tag_id = crc16((uint8_t*) &device_uuid, sizeof(device_uuid));
+
+ xTaskCreate(nRF_Task, (const signed char*) "nRF", TASK_NRF_STACK_SIZE,
+ NULL, TASK_NRF_PRIORITY, NULL);
+
+ /* Start the tasks running. */
+ vTaskStartScheduler();
+
+ return 0;
+}
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_API.c b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_API.c
new file mode 100644
index 0000000..7941852
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_API.c
@@ -0,0 +1,329 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - high level nRF24L01 access functions
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides high level initialization and startup sanity
+ * checks and test routines to verify that the chip is working
+ * properly and no soldering errors occored on the digital part.
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "nRF_HW.h"
+#include "nRF_CMD.h"
+#include "nRF_API.h"
+
+#ifndef NRF_RFOPTIONS
+#define NRF_RFOPTIONS 0x09
+#endif /*NRF_RFOPTIONS */
+
+// set broadcast MAC to 'BCAST'
+const uint8_t rfbroadcast_mac[NRF_MAX_MAC_SIZE] = { 'T', 'S', 'A', 'C', 'B' };
+
+uint8_t
+nRFAPI_DetectChip (void)
+{
+ uint8_t mac[NRF_MAX_MAC_SIZE], i;
+
+ // blank read
+ nRFAPI_GetStatus ();
+
+ // set dummy MAC size
+ nRFAPI_SetSizeMac (NRF_MIN_MAC_SIZE);
+
+ // verify dummy MAC size
+ if (nRFAPI_GetSizeMac () != NRF_MIN_MAC_SIZE)
+ return 0;
+
+ // set dummy MAC size
+ nRFAPI_SetSizeMac (NRF_MAX_MAC_SIZE);
+
+ // verify dummy MAC size
+ if (nRFAPI_GetSizeMac () != NRF_MAX_MAC_SIZE)
+ return 0;
+
+ // set dummy MAC
+ nRFAPI_SetTxMAC (rfbroadcast_mac, NRF_MAX_MAC_SIZE);
+
+ // get dummy MAC
+ memset (&mac, 0, sizeof (mac));
+ nRFAPI_GetTxMAC (mac, NRF_MAX_MAC_SIZE);
+
+ // if can't verify written MAC - return with error
+ for (i = 0; i < NRF_MAX_MAC_SIZE; i++)
+ if (mac[i] != rfbroadcast_mac[i])
+ return 0;
+
+ // everything is fine
+ return 1;
+}
+
+void
+nRFAPI_SetRxMode (uint8_t receive)
+{
+ nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, receive ? 0x3B : 0x3A);
+}
+
+void
+nRFAPI_PowerDown (void)
+{
+ nRFCMD_RegWriteStatusRead (CONFIG | WRITE_REG, 0x00);
+}
+
+uint8_t
+nRFAPI_Init (uint8_t channel,
+ const uint8_t * mac, uint8_t mac_size, uint8_t features)
+{
+ uint8_t i;
+
+ // init IO layer of nRF24L01
+ nRFCMD_Init ();
+
+ /* wait for nRF to boot */
+ vTaskDelay(10 / portTICK_RATE_MS);
+
+ // check validity
+ if (mac_size < 3 || mac_size > 5 || !nRFAPI_DetectChip ())
+ return 0;
+
+ // update mac
+ nRFAPI_SetSizeMac (mac_size);
+ nRFAPI_SetTxMAC (mac, mac_size);
+
+ // enables pipe
+ nRFAPI_SetRxMAC (mac, mac_size, 0);
+ nRFAPI_PipesEnable (ERX_P0);
+ nRFAPI_PipesAck (0);
+
+ // set payload sizes
+ for (i = 0; i <= 5; i++)
+ nRFAPI_SetPipeSizeRX (i, 16);
+
+ // set TX retry count
+ nRFAPI_TxRetries (0);
+
+ // set selected channel
+ nRFAPI_SetChannel (channel);
+
+ // set Tx power
+ nRFAPI_SetTxPower (3);
+
+ // flush FIFOs
+ nRFAPI_FlushRX ();
+ nRFAPI_FlushTX ();
+
+ if (features != 0)
+ nRFAPI_SetFeatures (features);
+
+ return 1;
+}
+
+void
+nRFAPI_SetTxPower (uint8_t power)
+{
+ if (power > 3)
+ power = 3;
+
+ nRFCMD_RegWriteStatusRead (RF_SETUP | WRITE_REG,
+ NRF_RFOPTIONS | (power << 1));
+}
+
+void
+nRFAPI_TxRetries (uint8_t count)
+{
+ if (count > 15)
+ count = 15;
+
+ // setup delay of 500us+86us
+ nRFCMD_RegWriteStatusRead (SETUP_RETR | WRITE_REG, 0x10 | count);
+}
+
+void
+nRFAPI_PipesEnable (uint8_t mask)
+{
+ nRFCMD_RegWriteStatusRead (EN_RXADDR | WRITE_REG, mask & 0x3F);
+}
+
+void
+nRFAPI_PipesAck (uint8_t mask)
+{
+ nRFCMD_RegWriteStatusRead (EN_AA | WRITE_REG, mask & 0x3F);
+}
+
+uint8_t
+nRFAPI_GetSizeMac (void)
+{
+ uint8_t addr_size;
+
+ addr_size = nRFCMD_RegRead (SETUP_AW) & 0x03;
+
+ return addr_size ? addr_size + 2 : 0;
+}
+
+uint8_t
+nRFAPI_SetSizeMac (uint8_t addr_size)
+{
+ if (addr_size >= 3 && addr_size <= 5)
+ addr_size -= 2;
+ else
+ addr_size = 0;
+
+ nRFCMD_RegWriteStatusRead (SETUP_AW | WRITE_REG, addr_size);
+
+ return addr_size;
+}
+
+void
+nRFAPI_GetTxMAC (uint8_t * addr, uint8_t addr_size)
+{
+ if (addr_size >= 3 && addr_size <= 5)
+ nRFCMD_RegReadBuf (TX_ADDR, addr, addr_size);
+}
+
+void
+nRFAPI_SetTxMAC (const uint8_t * addr, uint8_t addr_size)
+{
+ if (addr_size >= 3 && addr_size <= 5)
+ nRFCMD_RegWriteBuf (TX_ADDR | WRITE_REG, addr, addr_size);
+}
+
+void
+nRFAPI_SetRxMAC (const uint8_t * addr, uint8_t addr_size, uint8_t pipe)
+{
+ if ((pipe <= 1 && addr_size >= 3 && addr_size <= 5)
+ || (addr_size == 1 && pipe >= 2 && pipe <= 5))
+ nRFCMD_RegWriteBuf ((RX_ADDR_P0 + pipe) | WRITE_REG, addr, addr_size);
+}
+
+void
+nRFAPI_SetChannel (uint8_t channel)
+{
+ nRFCMD_RegWriteStatusRead (RF_CH | WRITE_REG, channel & 0x7f);
+}
+
+uint8_t
+nRFAPI_GetChannel (void)
+{
+ return nRFCMD_RegRead (RF_CH) & 0x7F;
+}
+
+uint8_t
+nRFAPI_ClearIRQ (uint8_t status)
+{
+ return nRFCMD_RegWriteStatusRead (STATUS | WRITE_REG,
+ status & MASK_IRQ_FLAGS);
+}
+
+void
+nRFAPI_TX (uint8_t * buf, uint8_t count)
+{
+ nRFCMD_RegWriteBuf (WR_TX_PLOAD, buf, count);
+}
+
+uint8_t
+nRFAPI_GetStatus (void)
+{
+ return nRFCMD_CmdExec (OP_NOP);
+}
+
+uint8_t
+nRFAPI_GetPipeSizeRX (uint8_t pipe)
+{
+ if (pipe <= 5)
+ return nRFCMD_RegRead (RX_PW_P0 + pipe);
+ else
+ return 0;
+}
+
+void
+nRFAPI_SetPipeSizeRX (uint8_t pipe, uint8_t size)
+{
+ if (pipe <= 5)
+ nRFCMD_RegWriteStatusRead ((RX_PW_P0 + pipe) | WRITE_REG, size);
+}
+
+uint8_t
+nRFAPI_GetPipeCurrent (void)
+{
+ return (nRFAPI_GetStatus () >> 1) & 0x7;
+}
+
+uint8_t
+nRFAPI_RX (uint8_t * buf, uint8_t count)
+{
+ uint8_t size, pipe;
+
+ pipe = nRFAPI_GetPipeCurrent ();
+ if (pipe >= 7)
+ size = 0;
+ else
+ {
+ size = nRFAPI_GetPipeSizeRX (pipe);
+
+ if (size <= count)
+ nRFCMD_RegReadBuf (RD_RX_PLOAD, buf, size);
+ else
+ {
+ nRFAPI_FlushRX ();
+ size = 0;
+ }
+ }
+
+ return size;
+}
+
+void
+nRFAPI_FlushRX (void)
+{
+ nRFCMD_CmdExec (FLUSH_RX);
+}
+
+void
+nRFAPI_FlushTX (void)
+{
+ nRFCMD_CmdExec (FLUSH_TX);
+}
+
+void
+nRFAPI_ReuseTX (void)
+{
+ nRFCMD_CmdExec (REUSE_TX_PL);
+}
+
+uint8_t
+nRFAPI_GetFifoStatus (void)
+{
+ return nRFCMD_RegRead (FIFO_STATUS);
+}
+
+uint8_t
+nRFAPI_CarrierDetect (void)
+{
+ return nRFCMD_RegRead (CD);
+}
+
+void
+nRFAPI_SetFeatures (uint8_t features)
+{
+ unsigned const char ACTIVATE_SEQUENCE[] = { ACTIVATE, 0x73 };
+ uint8_t dummy_buffer[sizeof (ACTIVATE_SEQUENCE)] = { 0, 0 };
+ nRFCMD_ReadWriteBuffer (ACTIVATE_SEQUENCE, dummy_buffer,
+ sizeof (ACTIVATE_SEQUENCE));
+ nRFCMD_RegWriteStatusRead (FEATURE, features);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_CMD.c b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_CMD.c
new file mode 100644
index 0000000..1cfbb94
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/nRF_CMD.c
@@ -0,0 +1,226 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - midlevel access functions for
+ * issuing raw commands to the nRF24L01 2.4Ghz frontend
+ *
+ * Copyright 2007 Milosch Meriac
+ *
+ * provides generic register level access functions
+ * for accessing nRF24L01 registers at a generic level
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "nRF_HW.h"
+#include "nRF_CMD.h"
+#include "spi.h"
+
+/* IO definitions */
+#define RF_IRQ_CPU_PORT 0
+#define RF_IRQ_CPU_PIN 7
+#define CPU_CE_RF_PORT 1
+#define CPU_CE_RF_PIN 5
+//#define CPU_SWITCH_RF_PORT 0
+//#define CPU_SWITCH_RF_PIN 2
+
+#define SPI_MAX_XFER_LEN 33
+#define NRFCMD_MACRO_READ 0x80
+
+#define SPI_MAX_XFER_LEN 33
+#define NRFCMD_MACRO_READ 0x80
+static uint8_t spi_outbuf[SPI_MAX_XFER_LEN];
+static uint8_t spi_inbuf[SPI_MAX_XFER_LEN];
+static volatile uint8_t g_packet_rxed = 0;
+
+static xSemaphoreHandle xnRF_SemaphoreACK;
+
+void nRFCMD_CE(uint8_t enable)
+{
+ GPIOSetValue(CPU_CE_RF_PORT, CPU_CE_RF_PIN, enable ? 1 : 0);
+}
+
+void nRFCMD_Power(uint8_t enable)
+{
+ enable = 0;
+ //GPIOSetValue(CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, enable ? 0 : 1);
+}
+
+void nRFCMD_ReadWriteBuffer(const uint8_t * tx_data, uint8_t * rx_data,
+ uint32_t len)
+{
+ spi_txrx(SPI_CS_NRF, tx_data, len, rx_data, len);
+}
+
+static uint8_t nRFCMD_ReadWriteByte(uint8_t reg)
+{
+ uint8_t res;
+
+ nRFCMD_ReadWriteBuffer(®, &res, 1);
+
+ return res;
+}
+
+uint8_t nRFCMD_CmdExec(uint8_t cmd)
+{
+ uint8_t res;
+
+ res = nRFCMD_ReadWriteByte(cmd);
+
+ return res;
+}
+
+uint8_t nRFCMD_RegRead(uint8_t reg)
+{
+ spi_outbuf[0] = reg;
+ spi_outbuf[1] = 0;
+
+ nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, 2);
+
+ return spi_inbuf[1];
+}
+
+uint8_t nRFCMD_RegWriteStatusRead(uint8_t reg, uint8_t value)
+{
+ spi_outbuf[0] = reg;
+ spi_outbuf[1] = value;
+
+ nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, 2);
+
+ return spi_inbuf[0];
+}
+
+uint8_t nRFCMD_RegWriteBuf(uint8_t reg, const uint8_t * buf, uint8_t count)
+{
+ spi_outbuf[0] = reg;
+ memcpy(spi_outbuf + 1, buf, count);
+ nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, count + 1);
+
+ return spi_inbuf[0];
+}
+
+uint8_t nRFCMD_RegReadBuf(uint8_t reg, uint8_t * buf, uint8_t count)
+{
+ spi_outbuf[0] = reg;
+ nRFCMD_ReadWriteBuffer(spi_outbuf, spi_inbuf, count + 2);
+ memcpy(buf, spi_inbuf + 1, count);
+
+ return spi_inbuf[0];
+}
+
+uint8_t nRFCMD_GetRegSize(uint8_t reg)
+{
+ uint8_t res;
+
+ if (reg > 0x17)
+ res = 0;
+ else
+ switch (reg)
+ {
+ case RX_ADDR_P0:
+ case RX_ADDR_P1:
+ case TX_ADDR:
+ res = NRF_MAX_MAC_SIZE;
+ break;
+ default:
+ res = 1;
+ }
+ return res;
+}
+
+void nRFCMD_ExecMacro(const uint8_t * macro)
+{
+ unsigned char size;
+
+ while ((size = *macro++) != 0)
+ {
+ nRFCMD_ReadWriteBuffer(macro, NULL, size - 1);
+ macro += size;
+ }
+}
+
+void nRFCMD_RegisterDump(void)
+{
+ uint8_t t, size, reg, buf[32];
+
+ reg = 0;
+ debug_printf("\nnRFCMD_RegisterDump:\n");
+ while (((size = nRFCMD_GetRegSize(reg)) > 0) && (reg < 0xFF))
+ {
+ nRFCMD_RegReadBuf(reg, buf, size);
+
+ debug_printf("\treg[0x%02X]:", reg);
+ for (t = 0; t < size; t++)
+ debug_printf(" 0x%02X", buf[t]);
+ debug_printf("\n");
+
+ reg++;
+ }
+ debug_printf("\n");
+}
+
+void nRFCMD_Status(void)
+{
+ debug_printf(" * nRF24L01+: rxed=%u\n", g_packet_rxed);
+}
+
+void WAKEUP_IRQHandlerPIO1_9(void)
+{
+ portBASE_TYPE xTaskWoken = pdFALSE;
+
+ xTaskWoken = xSemaphoreGiveFromISR(xnRF_SemaphoreACK, &xTaskWoken);
+
+ /* Clear pending IRQ */
+ LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9;
+
+ portEND_SWITCHING_ISR (xTaskWoken);
+}
+
+uint8_t nRFCMD_WaitRx(uint32_t ticks)
+{
+ if (xSemaphoreTake(xnRF_SemaphoreACK, ticks))
+ {
+ g_packet_rxed++;
+ return pdTRUE;
+ }
+ else
+ return pdFALSE;
+}
+
+void nRFCMD_Init(void)
+{
+ /* setup SPI chipselect pin */
+ spi_init_pin(SPI_CS_NRF);
+
+ /* initialize semaphores */
+ vSemaphoreCreateBinary(xnRF_SemaphoreACK);
+
+ /* setup IOs */
+ /*
+ LPC_IOCON->PIO0_7 = 0;
+ GPIOSetDir(RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0);
+ NVIC_EnableIRQ(WAKEUP_PIO0_7_IRQn);
+ LPC_SYSCON->STARTAPRP0 = (LPC_SYSCON->STARTAPRP0 & ~STARTxPRP0_PIO0_7);
+ LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO0_7;
+ LPC_SYSCON->STARTERP0 |= STARTxPRP0_PIO0_7;
+*/
+ GPIOSetDir(CPU_CE_RF_PORT, CPU_CE_RF_PIN, 1);
+ GPIOSetValue(CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0);
+
+ //LPC_IOCON->PIO0_2 = 0;
+ //GPIOSetDir(CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 1);
+ //GPIOSetValue(CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/pin.c b/openbeacon/lpc13xx/openbeacon-usb2/src/pin.c
new file mode 100644
index 0000000..d4fdf9e
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/pin.c
@@ -0,0 +1,78 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - GPIO declaration
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "pin.h"
+
+/* IO definitions */
+#define BUTTON0_PORT 2
+#define BUTTON0_BIT 7
+#define LED0_PORT 2
+#define LED0_BIT 5
+#define LED1_PORT 2
+#define LED1_BIT 4
+#define CPU_MODE_PMU_PORT 2
+#define CPU_MODE_PMU_BIT 8
+
+void
+pin_led (uint8_t led)
+{
+ GPIOSetValue (LED0_PORT, LED0_BIT, (led & GPIO_LED0) > 0);
+ GPIOSetValue (LED1_PORT, LED1_BIT, (led & GPIO_LED1) > 0);
+}
+
+void
+pin_mode_pmu (uint8_t mode)
+{
+ GPIOSetValue (CPU_MODE_PMU_PORT, CPU_MODE_PMU_BIT, mode);
+}
+
+uint8_t
+pin_button0 (void)
+{
+ return GPIOGetValue (BUTTON0_PORT, BUTTON0_BIT);
+}
+
+void
+pin_init (void)
+{
+ /* Initialize GPIO (sets up clock) */
+ GPIOInit ();
+
+ /* switch ISP button pin to input */
+ GPIOSetDir (BUTTON0_PORT, BUTTON0_BIT, 0);
+
+ /* Set LED0 port pin to output */
+ //LPC_IOCON->JTAG_nTRST_PIO1_2 = 1;
+ GPIOSetDir (LED0_PORT, LED0_BIT, 1);
+ GPIOSetValue (LED0_PORT, LED0_BIT, 0);
+
+ /* Set LED1 port pin to output */
+ //LPC_IOCON->JTAG_TDO_PIO1_1 = 1;
+ GPIOSetDir (LED1_PORT, LED1_BIT, 1);
+ GPIOSetValue (LED1_PORT, LED1_BIT, 0);
+
+ /* Set to PMU high power mode by default */
+ //LPC_IOCON->PIO0_5 = 0;
+ GPIOSetDir (CPU_MODE_PMU_PORT, CPU_MODE_PMU_BIT, 1);
+ pin_mode_pmu (0);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c b/openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c
new file mode 100644
index 0000000..5854c45
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/pmu.c
@@ -0,0 +1,78 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - Power Management
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "pin.h"
+#include "pmu.h"
+
+/* Watchdog oscillator control register setup */
+#define FREQSEL 1
+#define FCLKANA 500000.0
+#define DIVSEL 0x1F
+#define WDT_OSC_CLK (FCLKANA/(2.0*(1+DIVSEL)))
+
+#define MAINCLKSEL_IRC_OSC 0
+#define MAINCLKSEL_SYS_PLL 1
+#define MAINCLKSEL_WDT_OSC 2
+#define MAINCLKSEL_SYS_PLL_OUT 3
+
+static const uint32_t pmu_reason_signature = 0xDEADBEEF;
+
+void
+deep_sleep_ms (uint32_t milliseconds)
+{
+ (void) milliseconds;
+
+ /* back up current power states */
+ LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
+ __asm volatile ("WFI");
+}
+
+void
+pmu_sleep (void)
+{
+}
+
+void
+pmu_off (uint32_t reason)
+{
+ LPC_PMU->GPREG0 = pmu_reason_signature;
+ LPC_PMU->GPREG1 = reason;
+
+ LPC_SYSCON->PDSLEEPCFG = 0xFFFFFFFF;
+ SCB->SCR |= NVIC_LP_SLEEPDEEP;
+ LPC_PMU->PCON = 0x2;
+ pin_mode_pmu (1);
+ __WFI ();
+}
+
+uint32_t
+pmu_reason (void)
+{
+ return (LPC_PMU->GPREG0==pmu_reason_signature)?LPC_PMU->GPREG1:0;
+}
+
+void
+pmu_init (void)
+{
+ pin_mode_pmu (0);
+}
diff --git a/openbeacon/lpc13xx/openbeacon-usb2/src/storage.c b/openbeacon/lpc13xx/openbeacon-usb2/src/storage.c
new file mode 100644
index 0000000..c8a93f1
--- /dev/null
+++ b/openbeacon/lpc13xx/openbeacon-usb2/src/storage.c
@@ -0,0 +1,110 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - virtual FAT16 file system support
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+#include
+#include "vfs.h"
+#include "storage.h"
+
+#if DISK_SIZE>0
+#include "spi.h"
+
+#define LOGFILE_STORAGE_SIZE (4*1024*1024)
+
+void
+storage_status (void)
+{
+ static const uint8_t cmd_jedec_read_id = 0x9F;
+ uint8_t rx[3];
+ spi_txrx (SPI_CS_FLASH, &cmd_jedec_read_id, sizeof (cmd_jedec_read_id), rx,
+ sizeof (rx));
+
+ /* Show FLASH ID */
+ debug_printf (" * FLASH: ID:%02X-%02X-%02X\n", rx[0], rx[1], rx[2]);
+}
+
+static void
+storage_logfile_read_raw (uint32_t offset, uint32_t length, const void *src,
+ uint8_t * dst)
+{
+ (void) src;
+
+ uint8_t tx[5];
+
+ tx[0]=0x03; /* 25MHz Read */
+ tx[1]=(uint8_t)(offset>>16);
+ tx[2]=(uint8_t)(offset>> 8);
+ tx[3]=(uint8_t)(offset);
+ tx[4]=0x00;
+
+ spi_txrx (SPI_CS_FLASH, tx, sizeof(tx), dst, length);
+}
+
+void
+storage_init (void)
+{
+ /* last entry in file chain is volume label */
+ static const TDiskFile f_volume_label = {
+ .name = DiskBPB.BS_VolLab,
+ };
+
+ static const TDiskFile f_logfile = {
+ .length = LOGFILE_STORAGE_SIZE,
+ .handler = storage_logfile_read_raw,
+ .data = &f_logfile,
+ .name = "LOGFILE BIN",
+ .next = &f_volume_label,
+ };
+
+ /* read-me.htm file that redirects to project page */
+ static const char readme[] =
+ "";
+
+ static const TDiskFile f_readme = {
+ .length = sizeof (readme) - 1,
+ .handler = NULL,
+ .data = &readme,
+ .name = "READ-ME HTM",
+ .next = &f_logfile,
+ };
+
+ /* autorun.inf file that redirects to READ-ME.HTM */
+ static const char autorun_inf[] =
+ "[AutoRun]\n"
+ "shellexecute=READ-ME.HTM\n";
+
+ static const TDiskFile f_autorun = {
+ .length = sizeof (autorun_inf) - 1,
+ .handler = NULL,
+ .data = &autorun_inf,
+ .name = "AUTORUN INF",
+ .next = &f_readme,
+ };
+
+ /* init virtual file system */
+ vfs_init (&f_autorun);
+
+ /* setup SPI chipselect pin */
+ spi_init_pin (SPI_CS_FLASH);
+}
+
+#endif /* DISK_SIZE>0 */
diff --git a/openbeacon/lpc13xx/openpcd2/Makefile b/openbeacon/lpc13xx/openpcd2/Makefile
new file mode 100644
index 0000000..5a582e6
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/Makefile
@@ -0,0 +1,22 @@
+TARGET=rfid
+ARCH=LPC13
+CPU=$(ARCH)42
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/main.c \
+ src/rfid.c
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+app_clean:
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
+
diff --git a/openbeacon/lpc13xx/openpcd2/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/openpcd2/inc/FreeRTOSConfig.h
new file mode 100644
index 0000000..ef4ba7f
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/inc/FreeRTOSConfig.h
@@ -0,0 +1,104 @@
+/*
+ FreeRTOS V6.0.0 - Copyright (C) 2009 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.
+
+ 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.
+*/
+
+
+/******************************************************************************
+ See http://www.freertos.org/a00110.html for an explanation of the
+ definitions contained in this file.
+******************************************************************************/
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include "LPC13xx.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 0
+#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock )
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 100 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) )
+#define configMAX_TASK_NAME_LEN ( 12 )
+#define configUSE_TRACE_FACILITY 0
+#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 1
+#define configUSE_ALTERNATIVE_API 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configQUEUE_REGISTRY_SIZE 0
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+
+/* 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 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) )
+
+#endif /* FREERTOS_CONFIG_H */
+
diff --git a/openbeacon/lpc13xx/openpcd2/inc/config.h b/openbeacon/lpc13xx/openpcd2/inc/config.h
new file mode 100644
index 0000000..ce22b9a
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/inc/config.h
@@ -0,0 +1,50 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - config file
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define LED_PORT 1 /* Port for led */
+#define LED_BIT 9 /* Bit on port for led */
+#define LED_ON 1 /* Level to set port to turn on led */
+#define LED_OFF 0 /* Level to set port to turn off led */
+
+/* USB device settings */
+#define ENALBLE_USB_FULLFEATURED
+#define USB_VENDOR_ID 0x2366
+#define USB_PROD_ID 0x0003
+#define USB_DEVICE 0x0100
+
+/* PN532 pin definitions */
+#define PN532_RESET_PORT 1
+#define PN532_RESET_PIN 11
+#define PN532_CS_PORT 0
+#define PN532_CS_PIN 2
+
+
+/* FreeRTOS configuration */
+#define ENABLE_FREERTOS
+#define TASK_RFID_STACK_SIZE 64
+#define TASK_RFID_PRIORITY (tskIDLE_PRIORITY + 2)
+
+#endif/*__CONFIG_H__*/
diff --git a/openbeacon/lpc13xx/openpcd2/inc/pn532.h b/openbeacon/lpc13xx/openpcd2/inc/pn532.h
new file mode 100644
index 0000000..c5d2501
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/inc/pn532.h
@@ -0,0 +1,71 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - PN532 definitions for LPC13xx based OpenPCD2
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifndef __PN532_H__
+#define __PN532_H__
+
+/* PN532 Hardware Settings */
+#define PN532_FIFO_SIZE 64
+#define PN532_ACK_NACK_SIZE 6
+
+/* PN532 Miscellaneous command set */
+#define PN532_CMD_Diagnose 0x00
+#define PN532_CMD_GetFirmwareVersion 0x02
+#define PN532_CMD_GetGeneralStatus 0x04
+#define PN532_CMD_ReadRegister 0x06
+#define PN532_CMD_WriteRegister 0x08
+#define PN532_CMD_ReadGPIO 0x0C
+#define PN532_CMD_WriteGPIO 0x0E
+#define PN532_CMD_SetSerialBaudRate 0x10
+#define PN532_CMD_SetParameters 0x12
+#define PN532_CMD_SAMConfiguration 0x14
+#define PN532_CMD_PowerDown 0x16
+
+/* PN532 RF Communication command set */
+#define PN532_CMD_RFConfiguration 0x32
+#define PN532_CMD_RFRegulationTest 0x58
+
+/* PN532 as Initiator */
+#define PN532_CMD_InJumpForDEP 0x56
+#define PN532_CMD_InJumpForPSL 0x46
+#define PN532_CMD_InListPassiveTarget 0x4A
+#define PN532_CMD_InATR 0x50
+#define PN532_CMD_InPSL 0x4E
+#define PN532_CMD_InDataExchange 0x40
+#define PN532_CMD_InCommunicateThru 0x42
+#define PN532_CMD_InDeselect 0x44
+#define PN532_CMD_InRelease 0x52
+#define PN532_CMD_InSelect 0x54
+#define PN532_CMD_InAutoPoll 0x60
+
+/* PN532 as Target */
+#define PN532_CMD_TgInitAsTarget 0x8C
+#define PN532_CMD_TgSetGeneralBytes 0x92
+#define PN532_CMD_TgGetData 0x86
+#define PN532_CMD_TgSetData 0x8E
+#define PN532_CMD_TgSetMetaData 0x94
+#define PN532_CMD_TgGetInitiatorCommand 0x88
+#define PN532_CMD_TgResponseToInitiator 0x90
+#define PN532_CMD_TgGetTargetStatus 0x8A
+
+#endif/*__PN532_H__*/
diff --git a/openbeacon/lpc13xx/openpcd2/inc/rfid.h b/openbeacon/lpc13xx/openpcd2/inc/rfid.h
new file mode 100644
index 0000000..5cb04c1
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/inc/rfid.h
@@ -0,0 +1,30 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - PN532 routines for LPC13xx based OpenPCD2
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifndef __RFID_H__
+#define __RFID_H__
+
+extern void rfid_init(void);
+extern int rfid_read(void *data, unsigned char size);
+extern int rfid_write(const void *data, int len);
+
+#endif/*__RFID_H__*/
diff --git a/openbeacon/lpc13xx/openpcd2/inc/usbcfg.h b/openbeacon/lpc13xx/openpcd2/inc/usbcfg.h
new file mode 100644
index 0000000..8fef7c2
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/inc/usbcfg.h
@@ -0,0 +1,157 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbcfg.h
+ * Purpose: USB Custom Configuration
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added vendor specific support
+ * V1.00 Initial Version
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBCFG_H__
+#define __USBCFG_H__
+
+
+//*** <<< Use Configuration Wizard in Context Menu >>> ***
+
+
+/*
+// USB Configuration
+// USB Power
+// Default Power Setting
+// <0=> Bus-powered
+// <1=> Self-powered
+// Max Number of Interfaces <1-256>
+// Max Number of Endpoints <1-32>
+// Max Endpoint 0 Packet Size
+// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
+// DMA Transfer
+// Use DMA for selected Endpoints
+// Endpoint 0 Out
+// Endpoint 0 In
+// Endpoint 1 Out
+// Endpoint 1 In
+// Endpoint 2 Out
+// Endpoint 2 In
+// Endpoint 3 Out
+// Endpoint 3 In
+// Endpoint 4 Out
+// Endpoint 4 In
+//
+//
+*/
+
+#define USB_POWER 0
+#define USB_IF_NUM 1
+#define USB_LOGIC_EP_NUM 5
+#define USB_EP_NUM 10
+#define USB_MAX_PACKET0 64
+
+/*
+// USB Event Handlers
+// Device Events
+// Power Event
+// Reset Event
+// Suspend Event
+// Resume Event
+// Remote Wakeup Event
+// Start of Frame Event
+// Error Event
+//
+// Endpoint Events
+// Endpoint 0 Event
+// Endpoint 1 Event
+// Endpoint 2 Event
+// Endpoint 3 Event
+// Endpoint 4 Event
+// Endpoint 5 Event
+// Endpoint 6 Event
+// Endpoint 7 Event
+// Endpoint 8 Event
+// Endpoint 9 Event
+// Endpoint 10 Event
+// Endpoint 11 Event
+// Endpoint 12 Event
+// Endpoint 13 Event
+// Endpoint 14 Event
+// Endpoint 15 Event
+//
+// USB Core Events
+// Set Configuration Event
+// Set Interface Event
+// Set/Clear Feature Event
+//
+//
+*/
+
+#define USB_POWER_EVENT 0
+#define USB_RESET_EVENT 1
+#define USB_SUSPEND_EVENT 1
+#define USB_RESUME_EVENT 1
+#define USB_WAKEUP_EVENT 0
+#define USB_SOF_EVENT 0
+#define USB_ERROR_EVENT 0
+#define USB_EP_EVENT 0x000B
+#define USB_CONFIGURE_EVENT 1
+#define USB_INTERFACE_EVENT 0
+#define USB_FEATURE_EVENT 0
+
+
+/*
+// USB Class Support
+// enables USB Class specific Requests
+// Human Interface Device (HID)
+// Interface Number <0-255>
+//
+// Mass Storage
+// Interface Number <0-255>
+//
+// Audio Device
+// Control Interface Number <0-255>
+// Streaming Interface 1 Number <0-255>
+// Streaming Interface 2 Number <0-255>
+//
+// Communication Device
+// Control Interface Number <0-255>
+// Bulk Interface Number <0-255>
+// Max Communication Device Buffer Size
+// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
+//
+//
+*/
+
+#define USB_CLASS 1
+#define USB_HID 0
+#define USB_HID_IF_NUM 0
+#define USB_MSC 0
+#define USB_MSC_IF_NUM 0
+#define USB_AUDIO 0
+#define USB_ADC_CIF_NUM 0
+#define USB_ADC_SIF1_NUM 1
+#define USB_ADC_SIF2_NUM 2
+#define USB_CDC 1
+#define USB_CDC_CIF_NUM 0
+#define USB_CDC_DIF_NUM 1
+#define USB_CDC_BUFSIZE 64
+
+/*
+// USB Vendor Support
+// enables USB Vendor specific Requests
+//
+*/
+#define USB_VENDOR 0
+
+
+#endif /* __USBCFG_H__ */
diff --git a/openbeacon/lpc13xx/openpcd2/src/main.c b/openbeacon/lpc13xx/openpcd2/src/main.c
new file mode 100644
index 0000000..5dbac07
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/src/main.c
@@ -0,0 +1,72 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - main file for OpenPCD2 basic demo
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "rfid.h"
+
+static BOOL vTasksRunning = FALSE;
+
+/*
+ * overwrite default_putchar with USB CDC ACM
+ * output to enable USB support for debug_printf
+ */
+BOOL default_putchar(uint8_t data)
+{
+ if (vTasksRunning)
+ CDC_PutChar (data);
+
+ /* always send out over serial port as well */
+ UARTSendChar (data);
+
+ return TRUE;
+}
+
+int main(void)
+{
+ /* Initialize GPIO (sets up clock) */
+ GPIOInit();
+
+ /* Set LED port pin to output */
+ GPIOSetDir(LED_PORT, LED_BIT, LED_ON);
+
+ /* CDC Initialization */
+ CDC_Init();
+ /* USB Initialization */
+ USB_Init();
+ /* Connect to USB port */
+ USB_Connect(1);
+
+ /* UART setup */
+ UARTInit(115200, 0);
+
+ /* Init RFID */
+ rfid_init();
+
+ /* Update Core Clock */
+ SystemCoreClockUpdate ();
+
+ /* Start the tasks running. */
+ vTasksRunning = TRUE;
+ vTaskStartScheduler();
+
+ return 0;
+}
diff --git a/openbeacon/lpc13xx/openpcd2/src/rfid.c b/openbeacon/lpc13xx/openpcd2/src/rfid.c
new file mode 100644
index 0000000..1a9eb2b
--- /dev/null
+++ b/openbeacon/lpc13xx/openpcd2/src/rfid.c
@@ -0,0 +1,359 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - PN532 routines for LPC13xx based OpenPCD2
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#include
+#include "pn532.h"
+#include "rfid.h"
+
+#define BIT_REVERSE(x) ((unsigned char)(__RBIT(x)>>24))
+
+static void rfid_reset(unsigned char reset)
+{
+ GPIOSetValue(PN532_RESET_PORT, PN532_RESET_PIN, reset ? 1 : 0);
+}
+
+static void rfid_cs(unsigned char cs)
+{
+ GPIOSetValue(PN532_CS_PORT, PN532_CS_PIN, cs ? 1 : 0);
+}
+
+static unsigned char rfid_tx(unsigned char data)
+{
+ while ((LPC_SSP->SR & 0x02) == 0);
+ LPC_SSP->DR = BIT_REVERSE (data);
+ while ((LPC_SSP->SR & 0x04) == 0);
+ data = BIT_REVERSE (LPC_SSP->DR);
+ return data;
+}
+
+static unsigned char rfid_rx(void)
+{
+ return rfid_tx(0x00);
+}
+
+static unsigned char rfid_status(void)
+{
+ unsigned char res;
+
+ /* enable chip select */
+ rfid_cs(0);
+
+ /* transmit status request */
+ rfid_tx(0x02);
+ res = rfid_rx();
+
+ /* release chip select */
+ rfid_cs(1);
+
+ return res;
+}
+
+int rfid_read(void *data, unsigned char size)
+{
+ int res;
+ unsigned char *p, c, pkt_size, crc, prev, t;
+
+ /* wait 100ms max till PN532 response is ready */
+ t=0;
+ while ((rfid_status() & 1) == 0)
+ {
+ if(t++>10)
+ return -8;
+ vTaskDelay( 10 / portTICK_RATE_MS);
+ }
+
+ /* enable chip select */
+ rfid_cs(0);
+
+ /* read from FIFO command */
+ rfid_tx(0x03);
+
+ /* default result */
+ res = -1;
+
+ /* find preamble */
+ t = 0;
+ prev = rfid_rx();
+ while ((!(((c = rfid_rx()) == 0xFF) && (prev == 0x00))) && (t
+ < PN532_FIFO_SIZE))
+ {
+ prev = c;
+ t++;
+ }
+
+ if (t >= PN532_FIFO_SIZE)
+ res = -3;
+ else
+ {
+ /* read packet size */
+ pkt_size = rfid_rx();
+
+ /* special treatment for NACK and ACK */
+ if ((pkt_size == 0x00) || (pkt_size == 0xFF))
+ {
+ /* verify if second length byte is inverted */
+ if (rfid_rx() != (unsigned char) (~pkt_size))
+ res = -2;
+ else
+ {
+ /* eat Postamble */
+ rfid_rx();
+ /* -1 for NACK, 0 for ACK */
+ res = pkt_size ? 0 : -1;
+ }
+ }
+ else
+ {
+ /* verify packet size against LCS */
+ if (((pkt_size + rfid_rx()) & 0xFF) != 0)
+ res = -4;
+ else
+ {
+ /* remove TFI from packet size */
+ pkt_size--;
+ /* verify if packet fits into buffer */
+ if (pkt_size > size)
+ res = -5;
+ else
+ {
+ /* remember actual packet size */
+ size = pkt_size;
+ /* verify TFI */
+ if ((crc = rfid_rx()) != 0xD5)
+ res = -6;
+ else
+ {
+ /* read packet */
+ p = (unsigned char *) data;
+ while (pkt_size--)
+ {
+ /* read data */
+ c = rfid_rx();
+ /* maintain crc */
+ crc += c;
+ /* save payload */
+ if (p)
+ *p++ = c;
+ }
+
+ /* add DCS to CRC */
+ crc += rfid_rx();
+ /* verify CRC */
+ if (crc)
+ res = -7;
+ else
+ {
+ /* eat Postamble */
+ rfid_rx();
+ /* return actual size as result */
+ res = size;
+ }
+ }
+ }
+ }
+ }
+ }
+ rfid_cs(1);
+
+ /* everything fine */
+ return res;
+}
+
+int rfid_write(const void *data, int len)
+{
+ int i;
+ static const unsigned char preamble[] =
+ { 0x01, 0x00, 0x00, 0xFF };
+ const unsigned char *p = preamble;
+ unsigned char tfi = 0xD4, c;
+
+ if (!data)
+ len = 0xFF;
+
+ /* enable chip select */
+ rfid_cs(0);
+
+ p = preamble; /* Praeamble */
+ for (i = 0; i < (int) sizeof(preamble); i++)
+ rfid_tx(*p++);
+ rfid_tx(len + 1); /* LEN */
+ rfid_tx(0x100 - (len + 1)); /* LCS */
+ rfid_tx(tfi); /* TFI */
+ /* PDn */
+ p = (const unsigned char *) data;
+ while (len--)
+ {
+ c = *p++;
+ rfid_tx(c);
+ tfi += c;
+ }
+ rfid_tx(0x100 - tfi); /* DCS */
+ rfid_rx(); /* Postamble */
+
+ /* release chip select */
+ rfid_cs(1);
+
+ /* check for ack */
+ return rfid_read(NULL, 0);
+}
+
+static void rfid_hexdump(const void *buffer, int size)
+{
+ int i;
+ const unsigned char *p = (unsigned char *) buffer;
+
+ for (i = 0; i < size; i++)
+ {
+ if (i && ((i & 3) == 0))
+ debug_printf(" ");
+ debug_printf(" %02X", *p++);
+ }
+ debug_printf(" [size=%02i]\n", size);
+}
+
+static int rfid_execute(void *data, unsigned int isize, unsigned int osize)
+{
+ int res;
+ if (rfid_write(data, isize))
+ {
+ debug_printf("getting result\n");
+ res = rfid_read(data, osize);
+ if (res > 0)
+ rfid_hexdump(data, res);
+ else
+ debug_printf("error: res=%i\n", res);
+ }
+ else
+ {
+ debug_printf("->NACK!\n");
+ res = -1;
+ }
+ return res;
+}
+
+void WriteRegister(unsigned short address, unsigned char data)
+{
+ unsigned char cmd[4];
+
+ /* write register */
+ cmd[0] = 0x08;
+ /* high byte of address */
+ cmd[1] = address >> 8;
+ /* low byte of address */
+ cmd[2] = address & 0xFF;
+ /* data value */
+ cmd[3] = data;
+
+ rfid_execute(&cmd, sizeof(cmd), sizeof(data));
+}
+
+static
+void rfid_task(void *pvParameters)
+{
+ int i;
+ static unsigned char data[80];
+
+ /* touch unused Parameter */
+ (void) pvParameters;
+
+ /* release reset line after 400ms */
+ vTaskDelay( 400 / portTICK_RATE_MS);
+ rfid_reset(1);
+ /* wait for PN532 to boot */
+ vTaskDelay( 100 / portTICK_RATE_MS);
+
+ /* read firmware revision */
+ debug_printf("\nreading firmware version...\n");
+ data[0] = PN532_CMD_GetFirmwareVersion;
+ rfid_execute(&data, 1, sizeof(data));
+
+ /* enable debug output */
+ debug_printf("\nenabling debug output...\n");
+ WriteRegister(0x6328, 0xFC);
+ // select test bus signal
+ WriteRegister(0x6321, 6);
+ // select test bus type
+ WriteRegister(0x6322, 0x07);
+
+ while (1)
+ {
+ /* wait 500ms */
+ vTaskDelay( 500 / portTICK_RATE_MS);
+
+ /* detect cards in field */
+ GPIOSetValue(LED_PORT, LED_BIT, LED_ON);
+ debug_printf("\nchecking for cards...\n");
+ data[0] = PN532_CMD_InListPassiveTarget;
+ data[1] = 0x01; /* MaxTg - maximum cards */
+ data[2] = 0x00; /* BrTy - 106 kbps type A */
+ if (((i = rfid_execute(&data, 3, sizeof(data))) >= 11) && (data[1]
+ == 0x01) && (data[2] == 0x01))
+ {
+ debug_printf("card id: ");
+ rfid_hexdump(&data[7], data[6]);
+ }
+ else
+ debug_printf("unknown response of %i bytes\n", i);
+ GPIOSetValue(LED_PORT, LED_BIT, LED_OFF);
+
+ /* turning field off */
+ debug_printf("\nturning field off again...\n");
+ data[0] = PN532_CMD_RFConfiguration;
+ data[1] = 0x01; /* CfgItem = 0x01 */
+ data[2] = 0x00; /* RF Field = off */
+ rfid_execute(&data, 3, sizeof(data));
+ }
+}
+
+void rfid_init(void)
+{
+ /* reset SSP peripheral */
+ LPC_SYSCON->PRESETCTRL = 0x01;
+
+ /* Enable SSP clock */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11);
+
+ // Enable SSP peripheral
+ LPC_IOCON->PIO0_8 = 0x01 | (0x01 << 3); /* MISO, Pulldown */
+ LPC_IOCON->PIO0_9 = 0x01; /* MOSI */
+
+ LPC_IOCON->SCKLOC = 0x00; /* route to PIO0_10 */
+ LPC_IOCON->JTAG_TCK_PIO0_10 = 0x02; /* SCK */
+
+ /* Set SSP clock to 4.5MHz */
+ LPC_SYSCON->SSPCLKDIV = 0x01;
+ LPC_SSP->CR0 = 0x0707;
+ LPC_SSP->CR1 = 0x0002;
+ LPC_SSP->CPSR = 0x02;
+
+ /* Initialize chip select line */
+ rfid_cs(1);
+ GPIOSetDir(PN532_CS_PORT, PN532_CS_PIN, 1);
+
+ /* Initialize RESET line */
+ rfid_reset(0);
+ GPIOSetDir(PN532_RESET_PORT, PN532_RESET_PIN, 1);
+
+ /* Create PN532 task */
+ xTaskCreate(rfid_task, (const signed char*) "RFID", TASK_RFID_STACK_SIZE,
+ NULL, TASK_RFID_PRIORITY, NULL);
+}
diff --git a/openbeacon/lpc13xx/rtos-simple-demo/Makefile b/openbeacon/lpc13xx/rtos-simple-demo/Makefile
new file mode 100644
index 0000000..d00aa79
--- /dev/null
+++ b/openbeacon/lpc13xx/rtos-simple-demo/Makefile
@@ -0,0 +1,21 @@
+TARGET=rtos-simple-demo
+ARCH=LPC13
+CPU=$(ARCH)43
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/main.c
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+app_clean:
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
+
diff --git a/openbeacon/lpc13xx/rtos-simple-demo/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/rtos-simple-demo/inc/FreeRTOSConfig.h
new file mode 100644
index 0000000..ef4ba7f
--- /dev/null
+++ b/openbeacon/lpc13xx/rtos-simple-demo/inc/FreeRTOSConfig.h
@@ -0,0 +1,104 @@
+/*
+ FreeRTOS V6.0.0 - Copyright (C) 2009 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.
+
+ 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.
+*/
+
+
+/******************************************************************************
+ See http://www.freertos.org/a00110.html for an explanation of the
+ definitions contained in this file.
+******************************************************************************/
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include "LPC13xx.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 0
+#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock )
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 100 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) )
+#define configMAX_TASK_NAME_LEN ( 12 )
+#define configUSE_TRACE_FACILITY 0
+#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 1
+#define configUSE_ALTERNATIVE_API 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configQUEUE_REGISTRY_SIZE 0
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+
+/* 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 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) )
+
+#endif /* FREERTOS_CONFIG_H */
+
diff --git a/openbeacon/lpc13xx/rtos-simple-demo/inc/config.h b/openbeacon/lpc13xx/rtos-simple-demo/inc/config.h
new file mode 100644
index 0000000..b796958
--- /dev/null
+++ b/openbeacon/lpc13xx/rtos-simple-demo/inc/config.h
@@ -0,0 +1,9 @@
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define ENABLE_FREERTOS
+
+#define LED_PORT 1 // Port for led
+#define LED_BIT 9 // Bit on port for led
+
+#endif/*__CONFIG_H__*/
diff --git a/openbeacon/lpc13xx/rtos-simple-demo/src/main.c b/openbeacon/lpc13xx/rtos-simple-demo/src/main.c
new file mode 100644
index 0000000..27631d8
--- /dev/null
+++ b/openbeacon/lpc13xx/rtos-simple-demo/src/main.c
@@ -0,0 +1,190 @@
+/*
+ FreeRTOS V6.1.0 - 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 books - available as PDF or paperback *
+ * *
+ * "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.
+
+ 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 a very simple demo that demonstrates task and queue usages only.
+ * Details of other FreeRTOS features (API functions, tracing features,
+ * diagnostic hook functions, memory management, etc.) can be found on the
+ * FreeRTOS web site (http://www.FreeRTOS.org) and in the FreeRTOS book.
+ * Details of this demo (what it does, how it should behave, etc.) can be found
+ * in the accompanying PDF application note.
+ *
+*/
+
+/* Kernel includes. */
+#include
+#include
+#include
+#include
+#include "config.h"
+
+/* Priorities at which the tasks are created. */
+#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
+
+/* The rate at which data is sent to the queue, specified in milliseconds. */
+#define mainQUEUE_SEND_FREQUENCY_MS ( 500 / portTICK_RATE_MS )
+
+/* The number of items the queue can hold. This is 1 as the receive task
+will remove items as they are added, meaning the send task should always find
+the queue empty. */
+#define mainQUEUE_LENGTH ( 1 )
+
+/*
+ * The tasks as described in the accompanying PDF application note.
+ */
+static void prvQueueReceiveTask (void *pvParameters);
+static void prvQueueSendTask (void *pvParameters);
+
+/* The queue used by both tasks. */
+static xQueueHandle xQueue = NULL;
+/*-----------------------------------------------------------*/
+
+int
+main (void)
+{
+ /* Initialize GPIO (sets up clock) */
+ GPIOInit ();
+ /* Set LED port pin to output */
+ GPIOSetDir (LED_PORT, LED_BIT, 1);
+ GPIOSetValue (LED_PORT, LED_BIT, 0);
+
+ /* Create the queue. */
+ xQueue = xQueueCreate (mainQUEUE_LENGTH, sizeof (unsigned long));
+
+ if (xQueue != NULL)
+ {
+ /* Start the two tasks as described in the accompanying application
+ note. */
+ xTaskCreate (prvQueueReceiveTask, (signed char *) "Rx",
+ configMINIMAL_STACK_SIZE, NULL,
+ mainQUEUE_RECEIVE_TASK_PRIORITY, NULL);
+ xTaskCreate (prvQueueSendTask, (signed char *) "TX",
+ configMINIMAL_STACK_SIZE, NULL,
+ mainQUEUE_SEND_TASK_PRIORITY, NULL);
+
+ /* Start the tasks running. */
+ vTaskStartScheduler ();
+ }
+
+ /* If all is well we will never reach here as the scheduler will now be
+ running. If we do reach here then it is likely that there was insufficient
+ heap available for the idle task to be created. */
+ for (;;);
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvQueueSendTask (void *pvParameters)
+{
+ portTickType xNextWakeTime;
+ unsigned long ulValueToSend;
+
+ (void) pvParameters;
+
+ /* Initialise xNextWakeTime - this only needs to be done once. */
+ xNextWakeTime = xTaskGetTickCount ();
+
+ for (;;)
+ {
+ /* Place this task in the blocked state until it is time to run again.
+ The block state is specified in ticks, the constant used converts ticks
+ to ms. While in the blocked state this task will not consume any CPU
+ time. */
+ vTaskDelayUntil (&xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS);
+
+ /* Send to the queue - causing the queue receive task to flash its LED.
+ 0 is used as the block time so the sending operation will not block -
+ it shouldn't need to block as the queue should always be empty at this
+ point in the code. */
+ ulValueToSend = 100;
+ xQueueSend (xQueue, &ulValueToSend, 0);
+
+ /* Place this task in the blocked state until it is time to run again.
+ The block state is specified in ticks, the constant used converts ticks
+ to ms. While in the blocked state this task will not consume any CPU
+ time. */
+ vTaskDelayUntil (&xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS);
+
+ /* Send to the queue - causing the queue receive task to flash its LED.
+ 0 is used as the block time so the sending operation will not block -
+ it shouldn't need to block as the queue should always be empty at this
+ point in the code. */
+ ulValueToSend = 0;
+ xQueueSend (xQueue, &ulValueToSend, 0);
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvQueueReceiveTask (void *pvParameters)
+{
+ unsigned long ulReceivedValue;
+
+ (void) pvParameters;
+
+ for (;;)
+ {
+ /* Wait until something arrives in the queue - this task will block
+ indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
+ FreeRTOSConfig.h. */
+ xQueueReceive (xQueue, &ulReceivedValue, portMAX_DELAY);
+
+ /* To get here something must have been received from the queue, but
+ is it the expected value? If it is, toggle the LED. */
+ if (ulReceivedValue == 100UL)
+ GPIOSetValue (LED_PORT, LED_BIT, 1);
+ else
+ GPIOSetValue (LED_PORT, LED_BIT, 0);
+ }
+}
diff --git a/openbeacon/lpc13xx/sound/Makefile b/openbeacon/lpc13xx/sound/Makefile
new file mode 100644
index 0000000..41a04f5
--- /dev/null
+++ b/openbeacon/lpc13xx/sound/Makefile
@@ -0,0 +1,21 @@
+TARGET=sound
+ARCH=LPC13
+CPU=$(ARCH)43
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/soundtest.c
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+app_clean:
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
+
diff --git a/openbeacon/lpc13xx/sound/inc/config.h b/openbeacon/lpc13xx/sound/inc/config.h
new file mode 100644
index 0000000..5c3065b
--- /dev/null
+++ b/openbeacon/lpc13xx/sound/inc/config.h
@@ -0,0 +1,9 @@
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define BUT1_PORT 2 // Port for Button 1
+#define BUT1_PIN 9 // Bit on port forButton 1
+#define BUT2_PORT 1 // Port for Button 2
+#define BUT2_PIN 4 // Bit on port forButton 2
+
+#endif/*__CONFIG_H__*/
diff --git a/openbeacon/lpc13xx/sound/src/soundtest.c b/openbeacon/lpc13xx/sound/src/soundtest.c
new file mode 100644
index 0000000..09dada3
--- /dev/null
+++ b/openbeacon/lpc13xx/sound/src/soundtest.c
@@ -0,0 +1,143 @@
+#include
+
+#define TONES_MAX 32
+#define ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0]))
+
+/* 8xLED bar display */
+static void
+set_led (uint8_t led)
+{
+ led = ~led;
+ LPC_GPIO2->MASKED_ACCESS[0xF0] = led;
+ LPC_GPIO3->MASKED_ACCESS[0x0F] = led;
+}
+
+static void
+beep (double frequency)
+{
+ uint32_t t;
+
+ LPC_TMR32B1->TCR = 0;
+ if (frequency)
+ {
+ t = (SystemCoreClock / 2) / frequency;
+
+ LPC_TMR32B1->MR0 = LPC_TMR32B1->MR1 = t;
+
+ if (LPC_TMR32B1->TC >= t)
+ LPC_TMR32B1->TC = t;
+
+ LPC_TMR32B1->TCR = 1;
+ }
+}
+
+static double
+get_frequency_for_tone (uint8_t tone)
+{
+ static const double frequency[] = {
+ 262.63, 293.66, 329.63,
+ 349.23, 392.00, 440.00, 493.88
+ };
+ return frequency[tone % ARRAY_COUNT (frequency)] *
+ (1 << (tone / ARRAY_COUNT (frequency)));
+}
+
+static void
+tone (uint8_t tone)
+{
+ static uint8_t lasttone = 0;
+
+ if (tone != lasttone)
+ {
+ lasttone = tone;
+ beep (tone ? get_frequency_for_tone (tone - 1) : 0);
+ }
+}
+
+int
+main (void)
+{
+ volatile int t;
+ int i, mode, index, start;
+
+ /* Get System Clock */
+ SystemCoreClockUpdate ();
+
+ /* Initialize GPIO (sets up clock) */
+ GPIOInit ();
+ GPIOSetDir (BUT1_PORT, BUT1_PIN, 0);
+ GPIOSetDir (BUT2_PORT, BUT2_PIN, 0);
+
+ /* Set LED port pin to output */
+ LPC_GPIO2->DIR |= 0xF0;
+ LPC_GPIO3->DIR |= 0x0F;
+
+ /* Set sound port to PIO1_1 and PIO1_2 */
+ LPC_GPIO1->DIR |= 0x6;
+ LPC_IOCON->JTAG_TDO_PIO1_1 = 3;
+ LPC_IOCON->JTAG_nTRST_PIO1_2 = 3;
+
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
+ LPC_TMR32B1->TCR = 2;
+ LPC_TMR32B1->MCR = 1 << 4;
+ LPC_TMR32B1->EMR = 1 | (0x3 << 4) | (0x3 << 6);
+
+ mode = 2;
+ index = 24;
+ while (1)
+ {
+ /* BUTTON1 press cycles through tones */
+ if (!GPIOGetValue (BUT1_PORT, BUT1_PIN))
+ {
+ mode = (mode + 1) & 0x7;
+ /* debounce */
+ for (t = 0; t < 1000000; t++);
+ }
+
+ /* BUTTON2 plays tone */
+ if (!GPIOGetValue (BUT2_PORT, BUT2_PIN))
+ {
+ set_led (0xFF);
+ /* debounce */
+
+ switch (mode)
+ {
+
+ case 0:
+ index++;
+ if (index > TONES_MAX)
+ index = 1;
+ tone (index);
+ for (t = 0; t < 2000000; t++);
+ break;
+
+ case 1:
+ if (index > 1)
+ index--;
+ else
+ index = TONES_MAX;
+ tone (index);
+ for (t = 0; t < 2000000; t++);
+ break;
+
+ case 2:
+ tone (index);
+ break;
+
+ default:
+ start = get_frequency_for_tone (index) - 500;
+ for (i = 100; i > 0; i--)
+ {
+ beep (start + (i * 10));
+ for (t = 0; t < (mode * 5000); t++);
+ }
+ beep (0);
+ break;
+ }
+ }
+ else if (mode <= 2)
+ tone (0);
+
+ set_led (1 << mode);
+ }
+}
diff --git a/openbeacon/lpc13xx/uart/Makefile b/openbeacon/lpc13xx/uart/Makefile
new file mode 100644
index 0000000..0df7138
--- /dev/null
+++ b/openbeacon/lpc13xx/uart/Makefile
@@ -0,0 +1,21 @@
+TARGET=uart
+ARCH=LPC13
+CPU=$(ARCH)42
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/uarttest.c
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+app_clean:
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
+
diff --git a/openbeacon/lpc13xx/uart/inc/config.h b/openbeacon/lpc13xx/uart/inc/config.h
new file mode 100644
index 0000000..d522ba7
--- /dev/null
+++ b/openbeacon/lpc13xx/uart/inc/config.h
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * config.h: config file for uart example for NXP LPC13xx Family
+ * Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.07.19 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+
+/*
+Overview:
+ This example shows how to use a timer to blink an LED. It works by using
+ libLPC to configure a I/O port and a 32-bit timer, then setting up a timer
+ interrupt to increment a counter. The main loop polls the counter to
+ determine when to toggle the LED state.
+
+User #defines:
+ LED_PORT I/O port driving an LED
+ LED_BIT I/O port bit driving an LED
+ LED_ON Value to set the bit to turn on the LED
+ LED_OFF Value to set the bit to turn off the LED
+ LED_TOGGLE_TICKS
+ Number of timer ticks per flash. The timer is configured to generate
+ an interrupt 100 times a second or every 10mS.
+
+How to use:
+ Click the debug toolbar button.
+
+ * You should see an LED flashing.
+*/
+
+#define LED_PORT 1 // Port for led
+#define LED_BIT 9 // Bit on port for led
+#define LED_ON 1 // Level to set port to turn on led
+#define LED_OFF 0 // Level to set port to turn off led
+#define LED_TOGGLE_TICKS 100 // 100 ticks = 1 Hz flash rate
+
+/*********************************************************************************
+** End Of File
+*********************************************************************************/
diff --git a/openbeacon/lpc13xx/uart/src/uarttest.c b/openbeacon/lpc13xx/uart/src/uarttest.c
new file mode 100644
index 0000000..03b897f
--- /dev/null
+++ b/openbeacon/lpc13xx/uart/src/uarttest.c
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * uarttest.c: UART test C file for NXP LPC13xx Family Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.08.20 ver 1.00 Preliminary version, first Release
+ * 2010.07.21 ver 1.01 Added OpenBeacon stakc and debug_printf
+ *
+******************************************************************************/
+
+#include
+
+int
+main (void)
+{
+ volatile int i;
+
+ /* Basic chip initialization is taken care of in SystemInit() called
+ * from the startup code. SystemInit() and chip settings are defined
+ * in the CMSIS system_.c file.
+ */
+
+ /* NVIC is installed inside UARTInit file. */
+ UARTInit (115200, 0);
+
+ /* Initialize GPIO (sets up clock) */
+ GPIOInit ();
+
+ /* Set LED port pin to output */
+ GPIOSetDir (LED_PORT, LED_BIT, 1);
+
+ debug_printf ("Hello World!\n");
+
+ while (1)
+ { /* Loop forever */
+ if (UARTCount != 0)
+ {
+ /* Send back everything we receive */
+ UARTSend ((uint8_t *) UARTBuffer, UARTCount);
+ UARTCount = 0;
+
+ /* Blink on every TX packet */
+ GPIOSetValue (LED_PORT, LED_BIT, LED_OFF);
+ /* Small Delay to make blink visible */
+ for(i=0;i<200000;i++);
+ /* Turn off LED on exit */
+ GPIOSetValue (LED_PORT, LED_BIT, LED_ON);
+ }
+ }
+}
diff --git a/openbeacon/lpc13xx/usbcdc-storage/Makefile b/openbeacon/lpc13xx/usbcdc-storage/Makefile
new file mode 100644
index 0000000..e2ffe82
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/Makefile
@@ -0,0 +1,28 @@
+TARGET=usbcdc-storage
+ARCH=LPC13
+CPU=$(ARCH)43
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/main.c \
+ src/cdcuser.c \
+ src/clkconfig.c \
+ src/DiskImg.c \
+ src/mscuser.c \
+ src/usbcore.c \
+ src/compusbdesc.c \
+ src/usbhw.c \
+ src/usbuser.c
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+app_clean:
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h b/openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h
new file mode 100644
index 0000000..d61b85b
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/cdc.h
@@ -0,0 +1,241 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: CDC.h
+ * Purpose: USB Communication Device Class Definitions
+ * Version: V1.00
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __CDC_H
+#define __CDC_H
+
+/*----------------------------------------------------------------------------
+ * Definitions based on usbcdc11.pdf (www.usb.org)
+ *---------------------------------------------------------------------------*/
+// Communication device class specification version 1.10
+#define CDC_V1_10 0x0110
+
+// Communication interface class code
+// (usbcdc11.pdf, 4.2, Table 15)
+#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
+
+// Communication interface class subclass codes
+// (usbcdc11.pdf, 4.3, Table 16)
+#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01
+#define CDC_ABSTRACT_CONTROL_MODEL 0x02
+#define CDC_TELEPHONE_CONTROL_MODEL 0x03
+#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04
+#define CDC_CAPI_CONTROL_MODEL 0x05
+#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06
+#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07
+
+// Communication interface class control protocol codes
+// (usbcdc11.pdf, 4.4, Table 17)
+#define CDC_PROTOCOL_COMMON_AT_COMMANDS 0x01
+
+// Data interface class code
+// (usbcdc11.pdf, 4.5, Table 18)
+#define CDC_DATA_INTERFACE_CLASS 0x0A
+
+// Data interface class protocol codes
+// (usbcdc11.pdf, 4.7, Table 19)
+#define CDC_PROTOCOL_ISDN_BRI 0x30
+#define CDC_PROTOCOL_HDLC 0x31
+#define CDC_PROTOCOL_TRANSPARENT 0x32
+#define CDC_PROTOCOL_Q921_MANAGEMENT 0x50
+#define CDC_PROTOCOL_Q921_DATA_LINK 0x51
+#define CDC_PROTOCOL_Q921_MULTIPLEXOR 0x52
+#define CDC_PROTOCOL_V42 0x90
+#define CDC_PROTOCOL_EURO_ISDN 0x91
+#define CDC_PROTOCOL_V24_RATE_ADAPTATION 0x92
+#define CDC_PROTOCOL_CAPI 0x93
+#define CDC_PROTOCOL_HOST_BASED_DRIVER 0xFD
+#define CDC_PROTOCOL_DESCRIBED_IN_PUFD 0xFE
+
+// Type values for bDescriptorType field of functional descriptors
+// (usbcdc11.pdf, 5.2.3, Table 24)
+#define CDC_CS_INTERFACE 0x24
+#define CDC_CS_ENDPOINT 0x25
+
+// Type values for bDescriptorSubtype field of functional descriptors
+// (usbcdc11.pdf, 5.2.3, Table 25)
+#define CDC_HEADER 0x00
+#define CDC_CALL_MANAGEMENT 0x01
+#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
+#define CDC_DIRECT_LINE_MANAGEMENT 0x03
+#define CDC_TELEPHONE_RINGER 0x04
+#define CDC_REPORTING_CAPABILITIES 0x05
+#define CDC_UNION 0x06
+#define CDC_COUNTRY_SELECTION 0x07
+#define CDC_TELEPHONE_OPERATIONAL_MODES 0x08
+#define CDC_USB_TERMINAL 0x09
+#define CDC_NETWORK_CHANNEL 0x0A
+#define CDC_PROTOCOL_UNIT 0x0B
+#define CDC_EXTENSION_UNIT 0x0C
+#define CDC_MULTI_CHANNEL_MANAGEMENT 0x0D
+#define CDC_CAPI_CONTROL_MANAGEMENT 0x0E
+#define CDC_ETHERNET_NETWORKING 0x0F
+#define CDC_ATM_NETWORKING 0x10
+
+// CDC class-specific request codes
+// (usbcdc11.pdf, 6.2, Table 46)
+// see Table 45 for info about the specific requests.
+#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
+#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
+#define CDC_SET_COMM_FEATURE 0x02
+#define CDC_GET_COMM_FEATURE 0x03
+#define CDC_CLEAR_COMM_FEATURE 0x04
+#define CDC_SET_AUX_LINE_STATE 0x10
+#define CDC_SET_HOOK_STATE 0x11
+#define CDC_PULSE_SETUP 0x12
+#define CDC_SEND_PULSE 0x13
+#define CDC_SET_PULSE_TIME 0x14
+#define CDC_RING_AUX_JACK 0x15
+#define CDC_SET_LINE_CODING 0x20
+#define CDC_GET_LINE_CODING 0x21
+#define CDC_SET_CONTROL_LINE_STATE 0x22
+#define CDC_SEND_BREAK 0x23
+#define CDC_SET_RINGER_PARMS 0x30
+#define CDC_GET_RINGER_PARMS 0x31
+#define CDC_SET_OPERATION_PARMS 0x32
+#define CDC_GET_OPERATION_PARMS 0x33
+#define CDC_SET_LINE_PARMS 0x34
+#define CDC_GET_LINE_PARMS 0x35
+#define CDC_DIAL_DIGITS 0x36
+#define CDC_SET_UNIT_PARAMETER 0x37
+#define CDC_GET_UNIT_PARAMETER 0x38
+#define CDC_CLEAR_UNIT_PARAMETER 0x39
+#define CDC_GET_PROFILE 0x3A
+#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
+#define CDC_SET_ETHERNET_PMP_FILTER 0x41
+#define CDC_GET_ETHERNET_PMP_FILTER 0x42
+#define CDC_SET_ETHERNET_PACKET_FILTER 0x43
+#define CDC_GET_ETHERNET_STATISTIC 0x44
+#define CDC_SET_ATM_DATA_FORMAT 0x50
+#define CDC_GET_ATM_DEVICE_STATISTICS 0x51
+#define CDC_SET_ATM_DEFAULT_VC 0x52
+#define CDC_GET_ATM_VC_STATISTICS 0x53
+
+// Communication feature selector codes
+// (usbcdc11.pdf, 6.2.2..6.2.4, Table 47)
+#define CDC_ABSTRACT_STATE 0x01
+#define CDC_COUNTRY_SETTING 0x02
+
+// Feature Status returned for ABSTRACT_STATE Selector
+// (usbcdc11.pdf, 6.2.3, Table 48)
+#define CDC_IDLE_SETTING (1 << 0)
+#define CDC_DATA_MULTPLEXED_STATE (1 << 1)
+
+
+// Control signal bitmap values for the SetControlLineState request
+// (usbcdc11.pdf, 6.2.14, Table 51)
+#define CDC_DTE_PRESENT (1 << 0)
+#define CDC_ACTIVATE_CARRIER (1 << 1)
+
+// CDC class-specific notification codes
+// (usbcdc11.pdf, 6.3, Table 68)
+// see Table 67 for Info about class-specific notifications
+#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00
+#define CDC_RESPONSE_AVAILABLE 0x01
+#define CDC_AUX_JACK_HOOK_STATE 0x08
+#define CDC_RING_DETECT 0x09
+#define CDC_NOTIFICATION_SERIAL_STATE 0x20
+#define CDC_CALL_STATE_CHANGE 0x28
+#define CDC_LINE_STATE_CHANGE 0x29
+#define CDC_CONNECTION_SPEED_CHANGE 0x2A
+
+// UART state bitmap values (Serial state notification).
+// (usbcdc11.pdf, 6.3.5, Table 69)
+#define CDC_SERIAL_STATE_OVERRUN (1 << 6) // receive data overrun error has occurred
+#define CDC_SERIAL_STATE_PARITY (1 << 5) // parity error has occurred
+#define CDC_SERIAL_STATE_FRAMING (1 << 4) // framing error has occurred
+#define CDC_SERIAL_STATE_RING (1 << 3) // state of ring signal detection
+#define CDC_SERIAL_STATE_BREAK (1 << 2) // state of break detection
+#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) // state of transmission carrier
+#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) // state of receiver carrier
+
+
+/*----------------------------------------------------------------------------
+ * Structures based on usbcdc11.pdf (www.usb.org)
+ *---------------------------------------------------------------------------*/
+
+// Header functional descriptor
+// (usbcdc11.pdf, 5.2.3.1)
+// This header must precede any list of class-specific descriptors.
+typedef struct _CDC_HEADER_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // Header functional descriptor subtype
+ uint16_t bcdCDC; // USB CDC specification release version
+} __attribute__ ((packed)) CDC_HEADER_DESCRIPTOR;
+
+//Call management functional descriptor
+// (usbcdc11.pdf, 5.2.3.2)
+// Describes the processing of calls for the communication class interface.
+typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // call management functional descriptor subtype
+ uint8_t bmCapabilities; // capabilities that this configuration supports
+ uint8_t bDataInterface; // interface number of the data class interface used for call management (optional)
+} __attribute__ ((packed)) CDC_CALL_MANAGEMENT_DESCRIPTOR;
+
+// Abstract control management functional descriptor
+// (usbcdc11.pdf, 5.2.3.3)
+// Describes the command supported by the communication interface class with the Abstract Control Model subclass code.
+typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // abstract control management functional descriptor subtype
+ uint8_t bmCapabilities; // capabilities supported by this configuration
+} __attribute__ ((packed)) CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR;
+
+// Union functional descriptors
+// (usbcdc11.pdf, 5.2.3.8)
+// Describes the relationship between a group of interfaces that can be considered to form a functional unit.
+typedef struct _CDC_UNION_DESCRIPTOR
+{
+ uint8_t bFunctionLength; // size of this descriptor in bytes
+ uint8_t bDescriptorType; // CS_INTERFACE descriptor type
+ uint8_t bDescriptorSubtype; // union functional descriptor subtype
+ uint8_t bMasterInterface; // interface number designated as master
+} __attribute__ ((packed)) CDC_UNION_DESCRIPTOR;
+
+// Union functional descriptors with one slave interface
+// (usbcdc11.pdf, 5.2.3.8)
+typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR
+{
+ CDC_UNION_DESCRIPTOR sUnion; // Union functional descriptor
+ uint8_t bSlaveInterfaces[1]; // Slave interface 0
+} __attribute__ ((packed)) CDC_UNION_1SLAVE_DESCRIPTOR;
+
+// Line coding structure
+// Format of the data returned when a GetLineCoding request is received
+// (usbcdc11.pdf, 6.2.13)
+typedef struct _CDC_LINE_CODING
+{
+ uint32_t dwDTERate; // Data terminal rate in bits per second
+ uint8_t bCharFormat; // Number of stop bits
+ uint8_t bParityType; // Parity bit type
+ uint8_t bDataBits; // Number of data bits
+} __attribute__ ((packed)) CDC_LINE_CODING;
+
+// Notification header
+// Data sent on the notification endpoint must follow this header.
+// see USB_SETUP_PACKET in file usb.h
+typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER;
+
+#endif /* __CDC_H */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/cdcuser.h b/openbeacon/lpc13xx/usbcdc-storage/inc/cdcuser.h
new file mode 100644
index 0000000..0a3c21c
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/cdcuser.h
@@ -0,0 +1,62 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: cdcuser.h
+ * Purpose: USB Communication Device Class User module Definitions
+ * Version: V1.10
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __CDCUSER_H__
+#define __CDCUSER_H__
+
+/* CDC buffer handling */
+extern int CDC_RdOutBuf (char *buffer, const int *length);
+extern int CDC_WrOutBuf (const char *buffer, int *length);
+extern int CDC_OutBufAvailChar (int *availChar);
+
+
+/* CDC Data In/Out Endpoint Address */
+#define CDC_DEP_IN 0x83
+#define CDC_DEP_OUT 0x03
+
+/* CDC Communication In Endpoint Address */
+#define CDC_CEP_IN 0x81
+
+/* CDC Requests Callback Functions */
+extern uint32_t CDC_SendEncapsulatedCommand (void);
+extern uint32_t CDC_GetEncapsulatedResponse (void);
+extern uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector);
+extern uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector);
+extern uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector);
+extern uint32_t CDC_GetLineCoding (void);
+extern uint32_t CDC_SetLineCoding (void);
+extern uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap);
+extern uint32_t CDC_SendBreak (unsigned short wDurationOfBreak);
+
+/* CDC Bulk Callback Functions */
+extern void CDC_BulkIn (void);
+extern void CDC_BulkOut (void);
+
+/* CDC Notification Callback Function */
+extern void CDC_NotificationIn (void);
+
+/* CDC Initializtion Function */
+extern void CDC_Init (void);
+
+/* CDC prepare the SERAIAL_STATE */
+extern unsigned short CDC_GetSerialState (void);
+
+/* flow control */
+extern unsigned short CDC_DepInEmpty; // DataEndPoint IN empty
+
+#endif /* __CDCUSER_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/clkconfig.h b/openbeacon/lpc13xx/usbcdc-storage/inc/clkconfig.h
new file mode 100644
index 0000000..33efd24
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/clkconfig.h
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * clkconfig.h: Header file for NXP LPC13xx Family Microprocessors
+ *
+ * Copyright(C) 2009, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2009.08.20 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+#ifndef __CLKCONFIG_H
+#define __CLKCONFIG_H
+
+#define WDTCLK_SRC_IRC_OSC 0
+#define WDTCLK_SRC_MAIN_CLK 1
+#define WDTCLK_SRC_WDT_OSC 2
+
+#define CLKOUTCLK_SRC_IRC_OSC 0
+#define CLKOUTCLK_SRC_SYS_OSC 1
+#define CLKOUTCLK_SRC_WDT_OSC 2
+#define CLKOUTCLK_SRC_MAIN_CLK 3
+
+void WDT_CLK_Setup (uint32_t timer_num);
+void CLKOUT_Setup (uint32_t timer_num);
+#endif /* end __CLKCONFIG_H */
+/*****************************************************************************
+** End Of File
+******************************************************************************/
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/compusb.h b/openbeacon/lpc13xx/usbcdc-storage/inc/compusb.h
new file mode 100644
index 0000000..3032dfe
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/compusb.h
@@ -0,0 +1,252 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usb.h
+ * Purpose: USB Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __COMPUSB_H__
+#define __COMPUSB_H__
+
+typedef union
+{
+ uint16_t W;
+ struct
+ {
+ uint8_t L;
+ uint8_t H;
+ } __attribute__ ((packed)) WB;
+} __attribute__ ((packed)) WORD_BYTE;
+
+
+/* bmRequestType.Dir */
+#define REQUEST_HOST_TO_DEVICE 0
+#define REQUEST_DEVICE_TO_HOST 1
+
+/* bmRequestType.Type */
+#define REQUEST_STANDARD 0
+#define REQUEST_CLASS 1
+#define REQUEST_VENDOR 2
+#define REQUEST_RESERVED 3
+
+/* bmRequestType.Recipient */
+#define REQUEST_TO_DEVICE 0
+#define REQUEST_TO_INTERFACE 1
+#define REQUEST_TO_ENDPOINT 2
+#define REQUEST_TO_OTHER 3
+
+/* bmRequestType Definition */
+typedef union _REQUEST_TYPE
+{
+ struct _BM
+ {
+ uint8_t Recipient:5;
+ uint8_t Type:2;
+ uint8_t Dir:1;
+ } __attribute__ ((packed)) BM;
+ uint8_t B;
+} __attribute__ ((packed)) REQUEST_TYPE;
+
+/* USB Standard Request Codes */
+#define USB_REQUEST_GET_STATUS 0
+#define USB_REQUEST_CLEAR_FEATURE 1
+#define USB_REQUEST_SET_FEATURE 3
+#define USB_REQUEST_SET_ADDRESS 5
+#define USB_REQUEST_GET_DESCRIPTOR 6
+#define USB_REQUEST_SET_DESCRIPTOR 7
+#define USB_REQUEST_GET_CONFIGURATION 8
+#define USB_REQUEST_SET_CONFIGURATION 9
+#define USB_REQUEST_GET_INTERFACE 10
+#define USB_REQUEST_SET_INTERFACE 11
+#define USB_REQUEST_SYNC_FRAME 12
+
+/* USB GET_STATUS Bit Values */
+#define USB_GETSTATUS_SELF_POWERED 0x01
+#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
+#define USB_GETSTATUS_ENDPOINT_STALL 0x01
+
+/* USB Standard Feature selectors */
+#define USB_FEATURE_ENDPOINT_STALL 0
+#define USB_FEATURE_REMOTE_WAKEUP 1
+
+/* USB Default Control Pipe Setup Packet */
+typedef struct _USB_SETUP_PACKET
+{
+ REQUEST_TYPE bmRequestType;
+ uint8_t bRequest;
+ WORD_BYTE wValue;
+ WORD_BYTE wIndex;
+ uint16_t wLength;
+} __attribute__ ((packed)) USB_SETUP_PACKET;
+
+
+/* USB Descriptor Types */
+#define USB_DEVICE_DESCRIPTOR_TYPE 1
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
+#define USB_STRING_DESCRIPTOR_TYPE 3
+#define USB_INTERFACE_DESCRIPTOR_TYPE 4
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
+#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
+#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
+#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
+#define USB_OTG_DESCRIPTOR_TYPE 9
+#define USB_DEBUG_DESCRIPTOR_TYPE 10
+#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11
+
+/* USB Device Classes */
+#define USB_DEVICE_CLASS_RESERVED 0x00
+#define USB_DEVICE_CLASS_AUDIO 0x01
+#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
+#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
+#define USB_DEVICE_CLASS_MONITOR 0x04
+#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
+#define USB_DEVICE_CLASS_POWER 0x06
+#define USB_DEVICE_CLASS_PRINTER 0x07
+#define USB_DEVICE_CLASS_STORAGE 0x08
+#define USB_DEVICE_CLASS_HUB 0x09
+#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF
+#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
+
+/* bmAttributes in Configuration Descriptor */
+#define USB_CONFIG_POWERED_MASK 0x40
+#define USB_CONFIG_BUS_POWERED 0x80
+#define USB_CONFIG_SELF_POWERED 0xC0
+#define USB_CONFIG_REMOTE_WAKEUP 0x20
+
+/* bMaxPower in Configuration Descriptor */
+#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
+
+/* bEndpointAddress in Endpoint Descriptor */
+#define USB_ENDPOINT_DIRECTION_MASK 0x80
+#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
+#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
+
+/* bmAttributes in Endpoint Descriptor */
+#define USB_ENDPOINT_TYPE_MASK 0x03
+#define USB_ENDPOINT_TYPE_CONTROL 0x00
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_TYPE_BULK 0x02
+#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
+#define USB_ENDPOINT_SYNC_MASK 0x0C
+#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
+#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
+#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
+#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
+#define USB_ENDPOINT_USAGE_MASK 0x30
+#define USB_ENDPOINT_USAGE_DATA 0x00
+#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
+#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
+#define USB_ENDPOINT_USAGE_RESERVED 0x30
+
+/* USB Standard Device Descriptor */
+typedef struct _USB_DEVICE_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR;
+
+/* USB 2.0 Device Qualifier Descriptor */
+typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+} __attribute__ ((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR;
+
+/* USB Standard Configuration Descriptor */
+typedef struct _USB_CONFIGURATION_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR;
+
+/* USB Standard Interface Association Descriptor */
+typedef struct _USB_INTERFACE_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR;
+
+/* USB Interface Descriptor */
+typedef struct _USB_INTERFACE_ASSOCIATION_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bFirstInterface;
+ uint8_t bInterfaceCount;
+ uint8_t bFunctionClass;
+ uint8_t bFunctionSubClass;
+ uint8_t bFunctionProtocol;
+ uint8_t iFunction;
+} __attribute__ ((packed)) USB_INTERFACE_ASSOCIATION_DESCRIPTOR;
+
+/* USB Standard Endpoint Descriptor */
+typedef struct _USB_ENDPOINT_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR;
+
+/* USB String Descriptor */
+typedef struct _USB_STRING_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bString /*[] */ ;
+} __attribute__ ((packed)) USB_STRING_DESCRIPTOR;
+
+/* USB Common Descriptor */
+typedef struct _USB_COMMON_DESCRIPTOR
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+} __attribute__ ((packed)) USB_COMMON_DESCRIPTOR;
+
+
+#endif /* __COMPUSB_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/compusbdesc.h b/openbeacon/lpc13xx/usbcdc-storage/inc/compusbdesc.h
new file mode 100644
index 0000000..b1c0f5d
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/compusbdesc.h
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbdesc.h
+ * Purpose: USB Descriptors Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __COMPUSBDESC_H__
+#define __COMPUSBDESC_H__
+
+#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
+
+#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR))
+#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR))
+#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR))
+#define USB_INTERFACE_ASSOCIATION_DESC_SIZE (sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR))
+#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR))
+
+extern const uint8_t USB_DeviceDescriptor[];
+extern const uint8_t USB_ConfigDescriptor[];
+extern const uint8_t USB_StringDescriptor[];
+
+#endif /* __COMPUSBDESC_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/config.h b/openbeacon/lpc13xx/usbcdc-storage/inc/config.h
new file mode 100644
index 0000000..0fa55fb
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/config.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * config.h: config file for usbcdc example for NXP LPC13xx Family
+ * Microprocessors
+ *
+ * Copyright(C) 2008, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2008.07.19 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+
+/*
+Overview:
+ This example shows how to use the USB driver to implement a CDC class USB peripheral.
+ To run this example, you must attach a USB cable to the board. See
+ the "Getting Started Guide" appendix for details.
+
+How to use:
+ Click the debug toolbar button.
+ Click the go button.
+ Plug the LPCXpresso's target side into a PC using a USB cable retrofit
+ or a 3rd party base board.
+
+ * You should be able to see a new COM port on your PC.
+*/
+
+#define NXP_VID 0x1FC9
+#define MY_VID 0x????
+
+#define USB_VENDOR_ID NXP_VID // Vendor ID
+#define USB_PROD_ID 0x0003 // Product ID
+#define USB_DEVICE 0x0100 // Device ID
+
+#define LED_PORT 1 // Port for led
+#define LED_BIT 9 // Bit on port for led
+
+/*********************************************************************************
+** End Of File
+*********************************************************************************/
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/memory.h b/openbeacon/lpc13xx/usbcdc-storage/inc/memory.h
new file mode 100644
index 0000000..711cf07
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/memory.h
@@ -0,0 +1,20 @@
+/*----------------------------------------------------------------------------
+ * Name: memory.h
+ * Purpose: USB Memory Storage Demo Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+/* MSC Disk Image Definitions */
+#define MSC_ImageSize 6144
+
+extern const unsigned char DiskImage[MSC_ImageSize]; /* Disk Image */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/msc.h b/openbeacon/lpc13xx/usbcdc-storage/inc/msc.h
new file mode 100644
index 0000000..4001850
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/msc.h
@@ -0,0 +1,103 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: msc.h
+ * Purpose: USB Mass Storage Class Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __MSC_H__
+#define __MSC_H__
+
+
+/* MSC Subclass Codes */
+#define MSC_SUBCLASS_RBC 0x01
+#define MSC_SUBCLASS_SFF8020I_MMC2 0x02
+#define MSC_SUBCLASS_QIC157 0x03
+#define MSC_SUBCLASS_UFI 0x04
+#define MSC_SUBCLASS_SFF8070I 0x05
+#define MSC_SUBCLASS_SCSI 0x06
+
+/* MSC Protocol Codes */
+#define MSC_PROTOCOL_CBI_INT 0x00
+#define MSC_PROTOCOL_CBI_NOINT 0x01
+#define MSC_PROTOCOL_BULK_ONLY 0x50
+
+
+/* MSC Request Codes */
+#define MSC_REQUEST_RESET 0xFF
+#define MSC_REQUEST_GET_MAX_LUN 0xFE
+
+
+/* MSC Bulk-only Stage */
+#define MSC_BS_CBW 0 /* Command Block Wrapper */
+#define MSC_BS_DATA_OUT 1 /* Data Out Phase */
+#define MSC_BS_DATA_IN 2 /* Data In Phase */
+#define MSC_BS_DATA_IN_LAST 3 /* Data In Last Phase */
+#define MSC_BS_DATA_IN_LAST_STALL 4 /* Data In Last Phase with Stall */
+#define MSC_BS_CSW 5 /* Command Status Wrapper */
+#define MSC_BS_ERROR 6 /* Error */
+
+
+/* Bulk-only Command Block Wrapper */
+typedef struct _MSC_CBW
+{
+ uint32_t dSignature;
+ uint32_t dTag;
+ uint32_t dDataLength;
+ uint8_t bmFlags;
+ uint8_t bLUN;
+ uint8_t bCBLength;
+ uint8_t CB[16];
+} __attribute__ ((packed)) MSC_CBW;
+
+/* Bulk-only Command Status Wrapper */
+typedef struct _MSC_CSW
+{
+ uint32_t dSignature;
+ uint32_t dTag;
+ uint32_t dDataResidue;
+ uint8_t bStatus;
+} __attribute__ ((packed)) MSC_CSW;
+
+#define MSC_CBW_Signature 0x43425355
+#define MSC_CSW_Signature 0x53425355
+
+
+/* CSW Status Definitions */
+#define CSW_CMD_PASSED 0x00
+#define CSW_CMD_FAILED 0x01
+#define CSW_PHASE_ERROR 0x02
+
+
+/* SCSI Commands */
+#define SCSI_TEST_UNIT_READY 0x00
+#define SCSI_REQUEST_SENSE 0x03
+#define SCSI_FORMAT_UNIT 0x04
+#define SCSI_INQUIRY 0x12
+#define SCSI_MODE_SELECT6 0x15
+#define SCSI_MODE_SENSE6 0x1A
+#define SCSI_START_STOP_UNIT 0x1B
+#define SCSI_MEDIA_REMOVAL 0x1E
+#define SCSI_READ_FORMAT_CAPACITIES 0x23
+#define SCSI_READ_CAPACITY 0x25
+#define SCSI_READ10 0x28
+#define SCSI_WRITE10 0x2A
+#define SCSI_VERIFY10 0x2F
+#define SCSI_READ12 0xA8
+#define SCSI_WRITE12 0xAA
+#define SCSI_MODE_SELECT10 0x55
+#define SCSI_MODE_SENSE10 0x5A
+
+
+#endif /* __MSC_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/mscuser.h b/openbeacon/lpc13xx/usbcdc-storage/inc/mscuser.h
new file mode 100644
index 0000000..e889e6f
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/mscuser.h
@@ -0,0 +1,47 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: mscuser.h
+ * Purpose: Mass Storage Class Custom User Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __MSCUSER_H__
+#define __MSCUSER_H__
+
+
+/* Mass Storage Memory Layout */
+#define MSC_MemorySize 6144
+#define MSC_BlockSize 512
+#define MSC_BlockCount (MSC_MemorySize / MSC_BlockSize)
+
+
+/* Max In/Out Packet Size */
+#define MSC_MAX_PACKET 64
+
+/* MSC In/Out Endpoint Address */
+#define MSC_EP_IN 0x82
+#define MSC_EP_OUT 0x02
+
+/* MSC Requests Callback Functions */
+extern uint32_t MSC_Reset (void);
+extern uint32_t MSC_GetMaxLUN (void);
+
+/* MSC Bulk Callback Functions */
+extern void MSC_GetCBW (void);
+extern void MSC_SetCSW (void);
+extern void MSC_BulkIn (void);
+extern void MSC_BulkOut (void);
+
+
+#endif /* __MSCUSER_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/type.h b/openbeacon/lpc13xx/usbcdc-storage/inc/type.h
new file mode 100644
index 0000000..dc74760
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/type.h
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * type.h: Type definition Header file for NXP Family
+ * Microprocessors
+ *
+ * Copyright(C) 2006, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2009.04.01 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+#ifndef __TYPE_H__
+#define __TYPE_H__
+
+// CodeRed - ifdef for GNU added to avoid potential clash with stdint.h
+#if defined ( __GNUC__ )
+#include
+#else
+
+/* exact-width signed integer types */
+typedef signed char int8_t;
+typedef signed short int int16_t;
+typedef signed int int32_t;
+typedef signed __int64 int64_t;
+
+ /* exact-width unsigned integer types */
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#endif // __GNUC__
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#endif /* __TYPE_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbcfg.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcfg.h
new file mode 100644
index 0000000..49e54cf
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcfg.h
@@ -0,0 +1,157 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbcfg.h
+ * Purpose: USB Custom Configuration
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added vendor specific support
+ * V1.00 Initial Version
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBCFG_H__
+#define __USBCFG_H__
+
+
+//*** <<< Use Configuration Wizard in Context Menu >>> ***
+
+
+/*
+// USB Configuration
+// USB Power
+// Default Power Setting
+// <0=> Bus-powered
+// <1=> Self-powered
+// Max Number of Interfaces <1-256>
+// Max Number of Endpoints <1-32>
+// Max Endpoint 0 Packet Size
+// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
+// DMA Transfer
+// Use DMA for selected Endpoints
+// Endpoint 0 Out
+// Endpoint 0 In
+// Endpoint 1 Out
+// Endpoint 1 In
+// Endpoint 2 Out
+// Endpoint 2 In
+// Endpoint 3 Out
+// Endpoint 3 In
+// Endpoint 4 Out
+// Endpoint 4 In
+//
+//
+*/
+
+#define USB_POWER 0
+#define USB_IF_NUM 1
+#define USB_LOGIC_EP_NUM 5
+#define USB_EP_NUM 10
+#define USB_MAX_PACKET0 64
+
+/*
+// USB Event Handlers
+// Device Events
+// Power Event
+// Reset Event
+// Suspend Event
+// Resume Event
+// Remote Wakeup Event
+// Start of Frame Event
+// Error Event
+//
+// Endpoint Events
+// Endpoint 0 Event
+// Endpoint 1 Event
+// Endpoint 2 Event
+// Endpoint 3 Event
+// Endpoint 4 Event
+// Endpoint 5 Event
+// Endpoint 6 Event
+// Endpoint 7 Event
+// Endpoint 8 Event
+// Endpoint 9 Event
+// Endpoint 10 Event
+// Endpoint 11 Event
+// Endpoint 12 Event
+// Endpoint 13 Event
+// Endpoint 14 Event
+// Endpoint 15 Event
+//
+// USB Core Events
+// Set Configuration Event
+// Set Interface Event
+// Set/Clear Feature Event
+//
+//
+*/
+
+#define USB_POWER_EVENT 0
+#define USB_RESET_EVENT 1
+#define USB_SUSPEND_EVENT 1
+#define USB_RESUME_EVENT 1
+#define USB_WAKEUP_EVENT 0
+#define USB_SOF_EVENT 0
+#define USB_ERROR_EVENT 0
+#define USB_EP_EVENT 0x000f
+#define USB_CONFIGURE_EVENT 1
+#define USB_INTERFACE_EVENT 0
+#define USB_FEATURE_EVENT 0
+
+
+/*
+// USB Class Support
+// enables USB Class specific Requests
+// Human Interface Device (HID)
+// Interface Number <0-255>
+//
+// Mass Storage
+// Interface Number <0-255>
+//
+// Audio Device
+// Control Interface Number <0-255>
+// Streaming Interface 1 Number <0-255>
+// Streaming Interface 2 Number <0-255>
+//
+// Communication Device
+// Control Interface Number <0-255>
+// Bulk Interface Number <0-255>
+// Max Communication Device Buffer Size
+// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
+//
+//
+*/
+
+#define USB_CLASS 1
+#define USB_HID 0
+#define USB_HID_IF_NUM 0
+#define USB_MSC 1
+#define USB_MSC_IF_NUM 0
+#define USB_AUDIO 0
+#define USB_ADC_CIF_NUM 0
+#define USB_ADC_SIF1_NUM 1
+#define USB_ADC_SIF2_NUM 2
+#define USB_CDC 1
+#define USB_CDC_CIF_NUM 1
+#define USB_CDC_DIF_NUM 2
+#define USB_CDC_BUFSIZE 64
+
+/*
+// USB Vendor Support
+// enables USB Vendor specific Requests
+//
+*/
+#define USB_VENDOR 0
+
+
+#endif /* __USBCFG_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbcore.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcore.h
new file mode 100644
index 0000000..6ba7838
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbcore.h
@@ -0,0 +1,56 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbcore.h
+ * Purpose: USB Core Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBCORE_H__
+#define __USBCORE_H__
+
+
+/* USB Endpoint Data Structure */
+typedef struct _USB_EP_DATA
+{
+ uint8_t *pData;
+ uint16_t Count;
+} USB_EP_DATA;
+
+/* USB Core Global Variables */
+extern uint16_t USB_DeviceStatus;
+extern uint8_t USB_DeviceAddress;
+extern uint8_t USB_Configuration;
+extern uint32_t USB_EndPointMask;
+extern uint32_t USB_EndPointHalt;
+extern uint32_t USB_EndPointStall;
+extern uint8_t USB_AltSetting[USB_IF_NUM];
+
+/* USB Endpoint 0 Buffer */
+extern uint8_t EP0Buf[USB_MAX_PACKET0];
+
+/* USB Endpoint 0 Data Info */
+extern USB_EP_DATA EP0Data;
+
+/* USB Setup Packet */
+extern USB_SETUP_PACKET SetupPacket;
+
+/* USB Core Functions */
+extern void USB_ResetCore (void);
+
+/* Newer C compilers make it really difficult to add
+ * an integer to a pointer */
+__inline void UsbAddPtr (void **vpptr, uint32_t n);
+
+
+#endif /* __USBCORE_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h
new file mode 100644
index 0000000..641a8e9
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbhw.h
@@ -0,0 +1,62 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbhw.h
+ * Purpose: USB Hardware Layer Definitions
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added USB_ClearEPBuf
+ * V1.00 Initial Version
+ *----------------------------------------------------------------------------*/
+
+#ifndef __USBHW_H__
+#define __USBHW_H__
+
+
+/* USB Error Codes */
+#define USB_ERR_PID 0x0001 /* PID Error */
+#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */
+#define USB_ERR_DCRC 0x0004 /* Data CRC Error */
+#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */
+#define USB_ERR_EOP 0x0010 /* End of Packet Error */
+#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */
+#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */
+#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */
+
+/* USB Hardware Functions */
+extern void USBIOClkConfig (void);
+extern void USB_Init (void);
+extern void USB_Connect (uint32_t con);
+extern void USB_Reset (void);
+extern void USB_Suspend (void);
+extern void USB_Resume (void);
+extern void USB_WakeUp (void);
+extern void USB_WakeUpCfg (uint32_t cfg);
+extern void USB_SetAddress (uint32_t adr);
+extern void USB_Configure (uint32_t cfg);
+extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD);
+extern void USB_DirCtrlEP (uint32_t dir);
+extern void USB_EnableEP (uint32_t EPNum);
+extern void USB_DisableEP (uint32_t EPNum);
+extern void USB_ResetEP (uint32_t EPNum);
+extern void USB_SetStallEP (uint32_t EPNum);
+extern void USB_ClrStallEP (uint32_t EPNum);
+extern void USB_ClearEPBuf (uint32_t EPNum);
+extern uint32_t USB_ReadEP (uint32_t EPNum, uint8_t * pData);
+extern uint32_t USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt);
+extern uint32_t USB_GetFrame (void);
+extern void USB_IRQHandler (void);
+
+
+#endif /* __USBHW_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbreg.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbreg.h
new file mode 100644
index 0000000..f2d1000
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbreg.h
@@ -0,0 +1,134 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: USBREG.H
+ * Purpose: USB Hardware Layer Definitions for NXP LPC13xx
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBREG_H
+#define __USBREG_H
+
+/* Device Interrupt Bit Definitions */
+#define FRAME_INT (0x1<<0)
+#define EP0_INT (0x1<<1)
+#define EP1_INT (0x1<<2)
+#define EP2_INT (0x1<<3)
+#define EP3_INT (0x1<<4)
+#define EP4_INT (0x1<<5)
+#define EP5_INT (0x1<<6)
+#define EP6_INT (0x1<<7)
+#define EP7_INT (0x1<<8)
+#define DEV_STAT_INT (0x1<<9)
+#define CCEMTY_INT (0x1<<10)
+#define CDFULL_INT (0x1<<11)
+#define RxENDPKT_INT (0x1<<12)
+#define TxENDPKT_INT (0x1<<13)
+
+/* Rx & Tx Packet Length Definitions */
+#define PKT_LNGTH_MASK 0x000003FF
+#define PKT_DV 0x00000400
+#define PKT_RDY 0x00000800
+
+/* USB Control Definitions */
+#define CTRL_RD_EN 0x00000001
+#define CTRL_WR_EN 0x00000002
+
+/* Command Codes */
+#define CMD_SET_ADDR 0x00D00500
+#define CMD_CFG_DEV 0x00D80500
+#define CMD_SET_MODE 0x00F30500
+#define CMD_RD_INT 0x00F40500
+#define DAT_RD_INT 0x00F40200
+#define CMD_RD_FRAME 0x00F50500
+#define DAT_RD_FRAME 0x00F50200
+#define CMD_RD_CHIP_ID 0x00FD0500
+#define DAT_RD_CHIP_ID 0x00FD0200
+
+#define CMD_SET_DEV_STAT 0x00FE0500
+#define CMD_GET_DEV_STAT 0x00FE0500
+#define DAT_GET_DEV_STAT 0x00FE0200
+#define CMD_GET_ERR_CODE 0x00FF0500
+#define DAT_GET_ERR_CODE 0x00FF0200
+
+#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16))
+#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16))
+#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16))
+#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16))
+#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16))
+#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16))
+#define CMD_CLR_BUF 0x00F20500
+#define CMD_VALID_BUF 0x00FA0500
+
+/* Device Address Register Definitions */
+#define DEV_ADDR_MASK 0x7F
+#define DEV_EN 0x80
+
+/* Device Configure Register Definitions */
+#define CONF_DVICE 0x01
+
+/* Device Mode Register Definitions */
+#define AP_CLK 0x01
+#define INAK_CI 0x02
+#define INAK_CO 0x04
+#define INAK_AI 0x08
+#define INAK_AO 0x10
+
+/* Device Status Register Definitions */
+#define DEV_CON 0x01
+#define DEV_CON_CH 0x02
+#define DEV_SUS 0x04
+#define DEV_SUS_CH 0x08
+#define DEV_RST 0x10
+
+/* Error Code Register Definitions */
+#define ERR_EC_MASK 0x0F
+#define ERR_EA 0x10
+
+/* Error Status Register Definitions */
+#define ERR_NOERROR 0x00
+#define ERR_PID_ENCODE 0x01
+#define ERR_UNKNOWN_PID 0x02
+#define ERR_UNEXPECT_PKT 0x03
+#define ERR_TCRC 0x04
+#define ERR_DCRC 0x05
+#define ERR_TIMEOUT 0x06
+#define ERR_BABBIE 0x07
+#define ERR_EOF_PKT 0x08
+#define ERR_TX_RX_NAK 0x09
+#define ERR_SENT_STALL 0x0A
+#define ERR_BUF_OVERRUN 0x0B
+#define ERR_SENT_EPT_PKT 0x0C
+#define ERR_BIT_STUFF 0x0D
+#define ERR_SYNC 0x0E
+#define ERR_TOGGLE_BIT 0x0F
+
+/* Endpoint Select Register Definitions */
+#define EP_SEL_F 0x01
+#define EP_SEL_ST 0x02
+#define EP_SEL_STP 0x04
+#define EP_SEL_PO 0x08
+#define EP_SEL_EPN 0x10
+#define EP_SEL_B_1_FULL 0x20
+#define EP_SEL_B_2_FULL 0x40
+
+/* Endpoint Status Register Definitions */
+#define EP_STAT_ST 0x01
+#define EP_STAT_DA 0x20
+#define EP_STAT_RF_MO 0x40
+#define EP_STAT_CND_ST 0x80
+
+/* Clear Buffer Register Definitions */
+#define CLR_BUF_PO 0x01
+
+#endif /* __USBREG_H */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/usbuser.h b/openbeacon/lpc13xx/usbcdc-storage/inc/usbuser.h
new file mode 100644
index 0000000..03a429e
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/usbuser.h
@@ -0,0 +1,57 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: USBUSER.H
+ * Purpose: USB Custom User Definitions
+ * Version: V1.10
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2005-2009 Keil Software.
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBUSER_H__
+#define __USBUSER_H__
+
+
+/* USB Device Events Callback Functions */
+extern void USB_Power_Event (uint32_t power);
+extern void USB_Reset_Event (void);
+extern void USB_Suspend_Event (void);
+extern void USB_Resume_Event (void);
+extern void USB_WakeUp_Event (void);
+extern void USB_SOF_Event (void);
+extern void USB_Error_Event (uint32_t error);
+
+/* USB Endpoint Callback Events */
+#define USB_EVT_SETUP 1 /* Setup Packet */
+#define USB_EVT_OUT 2 /* OUT Packet */
+#define USB_EVT_IN 3 /* IN Packet */
+#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */
+#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */
+#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */
+#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */
+
+/* USB Endpoint Events Callback Pointers */
+extern void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event);
+
+/* USB Endpoint Events Callback Functions */
+extern void USB_EndPoint0 (uint32_t event);
+extern void USB_EndPoint1 (uint32_t event);
+extern void USB_EndPoint2 (uint32_t event);
+extern void USB_EndPoint3 (uint32_t event);
+extern void USB_EndPoint4 (uint32_t event);
+
+/* USB Core Events Callback Functions */
+extern void USB_Configure_Event (void);
+extern void USB_Interface_Event (void);
+extern void USB_Feature_Event (void);
+
+
+#endif /* __USBUSER_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/inc/vcomdemo.h b/openbeacon/lpc13xx/usbcdc-storage/inc/vcomdemo.h
new file mode 100644
index 0000000..c668d7c
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/inc/vcomdemo.h
@@ -0,0 +1,30 @@
+/*----------------------------------------------------------------------------
+ * Name: vcomdemo.h
+ * Purpose: USB virtual COM port Demo Definitions
+ * Version: V1.02
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+/* Push Button Definitions */
+#define S2 0x00000400 /* P2.10 */
+
+/* LED Definitions */
+#define LED1 0x00000001 /* P2.00 */
+#define LED2 0x00000002 /* P2.01 */
+#define LED3 0x00000004 /* P2.02 */
+#define LED4 0x00000008 /* P2.03 */
+#define LED5 0x00000010 /* P2.04 */
+#define LED6 0x00000020 /* P2.05 */
+#define LED7 0x00000040 /* P2.06 */
+#define LED8 0x00000080 /* P2.07 */
+
+#define LEDMSK 0x000000FF /* P2.0..7 */
diff --git a/openbeacon/lpc13xx/usbcdc-storage/lpc134x-vcom.inf b/openbeacon/lpc13xx/usbcdc-storage/lpc134x-vcom.inf
new file mode 100644
index 0000000..abc7e66
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/lpc134x-vcom.inf
@@ -0,0 +1,60 @@
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%NXP%
+;LayoutFile=layout.inf
+DriverVer=01/06/07
+
+[Manufacturer]
+%NXP%=DeviceList
+
+[DestinationDirs]
+DefaultDestDir=12
+
+[SourceDisksFiles]
+
+[SourceDisksNames]
+
+[DeviceList]
+%DESCRIPTION%=LPC134xUSB, USB\VID_1FC9&PID_0003&MI_01
+
+;------------------------------------------------------------------------------
+; Windows 2000/XP Sections
+;------------------------------------------------------------------------------
+
+[LPC134xUSB.nt]
+include=mdmcpq.inf
+CopyFiles=DriverCopyFiles
+AddReg=LPC134xUSB.nt.AddReg
+
+[DriverCopyFiles]
+usbser.sys,,,0x20
+
+[LPC134xUSB.nt.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[LPC134xUSB.nt.Services]
+include=mdmcpq.inf
+AddService=usbser, 0x00000002, DriverService
+
+
+[LPC134xUSB.nt.HW]
+include=mdmcpq.inf
+
+[DriverService]
+DisplayName=%DESCRIPTION%
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\usbser.sys
+
+;------------------------------------------------------------------------------
+; String Definitions
+;------------------------------------------------------------------------------
+
+[Strings]
+NXP="NXP - Founded by Philips"
+DESCRIPTION="LPC134x USB VCom Port"
diff --git a/openbeacon/lpc13xx/usbcdc-storage/readme.txt b/openbeacon/lpc13xx/usbcdc-storage/readme.txt
new file mode 100644
index 0000000..eb3a9ce
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/readme.txt
@@ -0,0 +1,40 @@
+usbcomp_msd_cdc
+=====================
+This project implements a USB composite class device that includes
+a mass storage device and a virtual COM device.
+
+To run this example, you must attach a USB cable to the board. See
+the "Getting Started Guide" appendix for details. You may also
+connect the LPCXpresso board to a base board from a 3rd party tool
+partner.
+
+When downloaded to the board and executed, the PC will first recognize
+a USB mass storage device and mount a new drive that contains a text
+file, and then it will recognize a USB "VCOM" device and ask for a
+driver. Point windows to the .inf file in the usbcomp_msd_cdc project
+directory to cause Windows to install the default USB serial driver.
+
+At this point, you should be able to read/write files in the newly
+mounted drive and send/receive characters through the USB virtual
+COM port at the same time. The transmit baud rate will equal the
+CDC port configured baud rate.
+
+One thing we have seen that can cause trouble with the USB examples
+is the Windows driver install. Since the example projects all use
+the same USB Vendor ID and Product ID, if you try out the HID
+example and then try out the CDC example, Windows may try
+to use the HID driver it had already installed with the CDC
+example code. To fix this, go to the Windows Device Manager,
+find the broken "HID" device and select "Uninstall." Then unplug the
+device and plug it back in. Windows should correctly identify the
+device as being a CDC device and install the correct
+driver.
+
+The project makes use of code from the following library projects:
+- CMSISv1p30_LPC13xx : for CMSIS 1.30 files relevant to LPC13xx
+
+This library project must exist in the same workspace in order
+for the project to successfully build.
+
+For more details, read the comments in config.h and
+http://www.nxp.com/documents/application_note/AN11018.pdf
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/DiskImg.c b/openbeacon/lpc13xx/usbcdc-storage/src/DiskImg.c
new file mode 100644
index 0000000..01d9819
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/DiskImg.c
@@ -0,0 +1,166 @@
+/* Disk Image */
+
+#include "memory.h"
+
+const unsigned char DiskImage[MSC_ImageSize] = {
+0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x01,0x01,0x00,
+0x01,0x10,0x00,0x20,0x00,0xF8,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x74,0x19,0x02,0x27,0x4C,0x50,0x43,0x32,0x33,
+0x36,0x38,0x20,0x55,0x53,0x42,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x33,0xC9,
+0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C,
+0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A,
+0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,
+0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7,
+0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11,
+0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,
+0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6,
+0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6,
+0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0,
+0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E,
+0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB,
+0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8,
+0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0,
+0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6,
+0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8,
+0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8,
+0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB,
+0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33,
+0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8,
+0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42,
+0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03,
+0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB,
+0xB0,0x4E,0x54,0x4C,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65,
+0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74,
+0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73,
+0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20,
+0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61,
+0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA,
+0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x4C,0x50,0x43,0x31,0x33,0x34,0x78,0x20,0x55,0x53,0x42,0x28,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x52,0x45,0x41,0x44,0x4D,0x45,0x20,0x20,0x54,0x58,0x54,0x21,0x00,0x00,0x00,0x00,
+0x21,0x00,0xBB,0x32,0x00,0x00,0xDC,0x83,0xBB,0x32,0x02,0x00,0x5D,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x55,0x53,0x42,0x20,0x4D,0x65,
+0x6D,0x6F,0x72,0x79,0x20,0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x64,0x65,0x6D,0x6F,
+0x6E,0x73,0x74,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x6F,0x72,0x0D,0x0A,0x74,
+0x68,0x65,0x20,0x4E,0x58,0x50,0x20,0x20,0x4E,0x58,0x50,0x31,0x33,0x58,0x58,0x20,
+0x42,0x6F,0x61,0x72,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x4E,0x58,0x50,0x20,0x4C,
+0x50,0x43,0x31,0x33,0x34,0x33,0x2E,0x20,0x20,0x20,0x20,0x0D,0x0A,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/cdcuser.c b/openbeacon/lpc13xx/usbcdc-storage/src/cdcuser.c
new file mode 100644
index 0000000..79877c5
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/cdcuser.c
@@ -0,0 +1,392 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: cdcuser.c
+ * Purpose: USB Communication Device Class User module
+ * Version: V1.10
+ *----------------------------------------------------------------------------
+* This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#include "type.h"
+
+#include "usb.h"
+#include "usbhw.h"
+#include "usbcfg.h"
+#include "usbcore.h"
+#include "cdc.h"
+#include "cdcuser.h"
+#include "uart.h"
+
+
+unsigned char BulkBufIn[USB_CDC_BUFSIZE]; // Buffer to store USB IN packet
+unsigned char BulkBufOut[USB_CDC_BUFSIZE]; // Buffer to store USB OUT packet
+unsigned char NotificationBuf[10];
+
+CDC_LINE_CODING CDC_LineCoding = { 9600, 0, 0, 8 };
+
+unsigned short CDC_SerialState = 0x0000;
+unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty
+
+/*----------------------------------------------------------------------------
+ We need a buffer for incomming data on USB port because USB receives
+ much faster than UART transmits
+ *---------------------------------------------------------------------------*/
+/* Buffer masks */
+#define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2)
+ // large enough for file transfer
+#define CDC_BUF_MASK (CDC_BUF_SIZE-1ul)
+
+/* Buffer read / write macros */
+#define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0)
+#define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn))
+#define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++])
+#define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx)
+#define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1)
+#define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx))
+
+
+// CDC output buffer
+typedef struct __CDC_BUF_T
+{
+ unsigned char data[CDC_BUF_SIZE];
+ unsigned int wrIdx;
+ unsigned int rdIdx;
+} CDC_BUF_T;
+
+CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data
+
+/*----------------------------------------------------------------------------
+ read data from CDC_OutBuf
+ *---------------------------------------------------------------------------*/
+int
+CDC_RdOutBuf (char *buffer, const int *length)
+{
+ int bytesToRead, bytesRead;
+
+ /* Read *length bytes, block if *bytes are not avaialable */
+ bytesToRead = *length;
+ bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
+ bytesRead = bytesToRead;
+
+
+ // ... add code to check for underrun
+
+ while (bytesToRead--)
+ {
+ *buffer++ = CDC_BUF_RD (CDC_OutBuf);
+ }
+ return (bytesRead);
+}
+
+/*----------------------------------------------------------------------------
+ write data to CDC_OutBuf
+ *---------------------------------------------------------------------------*/
+int
+CDC_WrOutBuf (const char *buffer, int *length)
+{
+ int bytesToWrite, bytesWritten;
+
+ // Write *length bytes
+ bytesToWrite = *length;
+ bytesWritten = bytesToWrite;
+
+
+ // ... add code to check for overwrite
+
+ while (bytesToWrite)
+ {
+ CDC_BUF_WR (CDC_OutBuf, *buffer++); // Copy Data to buffer
+ bytesToWrite--;
+ }
+
+ return (bytesWritten);
+}
+
+/*----------------------------------------------------------------------------
+ check if character(s) are available at CDC_OutBuf
+ *---------------------------------------------------------------------------*/
+int
+CDC_OutBufAvailChar (int *availChar)
+{
+
+ *availChar = CDC_BUF_COUNT (CDC_OutBuf);
+
+ return (0);
+}
+
+/* end Buffer handling */
+
+
+/*----------------------------------------------------------------------------
+ CDC Initialisation
+ Initializes the data structures and serial port
+ Parameters: None
+ Return Value: None
+ *---------------------------------------------------------------------------*/
+void
+CDC_Init (void)
+{
+
+// ser_OpenPort ();
+// ser_InitPort (CDC_LineCoding.dwDTERate, CDC_LineCoding.bDataBits, CDC_LineCoding.bParityType, CDC_LineCoding.bCharFormat);
+
+ CDC_DepInEmpty = 1;
+ CDC_SerialState = CDC_GetSerialState ();
+
+ CDC_BUF_RESET (CDC_OutBuf);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SendEncapsulatedCommand Request Callback
+ Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request
+ Parameters: None (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SendEncapsulatedCommand (void)
+{
+
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC GetEncapsulatedResponse Request Callback
+ Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request
+ Parameters: None (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_GetEncapsulatedResponse (void)
+{
+
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SetCommFeature Request Callback
+ Called automatically on CDC Set_COMM_FATURE Request
+ Parameters: FeatureSelector
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SetCommFeature (unsigned short wFeatureSelector)
+{
+ (void)wFeatureSelector;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC GetCommFeature Request Callback
+ Called automatically on CDC Get_COMM_FATURE Request
+ Parameters: FeatureSelector
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_GetCommFeature (unsigned short wFeatureSelector)
+{
+ (void)wFeatureSelector;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC ClearCommFeature Request Callback
+ Called automatically on CDC CLEAR_COMM_FATURE Request
+ Parameters: FeatureSelector
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_ClearCommFeature (unsigned short wFeatureSelector)
+{
+ (void)wFeatureSelector;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SetLineCoding Request Callback
+ Called automatically on CDC SET_LINE_CODING Request
+ Parameters: none (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SetLineCoding (void)
+{
+
+ CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0) | (EP0Buf[1] << 8) | (EP0Buf[2] << 16) | (EP0Buf[3] << 24);
+ CDC_LineCoding.bCharFormat = EP0Buf[4];
+ CDC_LineCoding.bParityType = EP0Buf[5];
+ CDC_LineCoding.bDataBits = EP0Buf[6];
+
+// ser_ClosePort ();
+// ser_OpenPort ();
+// ser_InitPort (CDC_LineCoding.dwDTERate, CDC_LineCoding.bDataBits, CDC_LineCoding.bParityType, CDC_LineCoding.bCharFormat);
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC GetLineCoding Request Callback
+ Called automatically on CDC GET_LINE_CODING Request
+ Parameters: None (global SetupPacket and EP0Buf)
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_GetLineCoding (void)
+{
+
+ EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF;
+ EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF;
+ EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF;
+ EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF;
+ EP0Buf[4] = CDC_LineCoding.bCharFormat;
+ EP0Buf[5] = CDC_LineCoding.bParityType;
+ EP0Buf[6] = CDC_LineCoding.bDataBits;
+
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SetControlLineState Request Callback
+ Called automatically on CDC SET_CONTROL_LINE_STATE Request
+ Parameters: ControlSignalBitmap
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SetControlLineState (unsigned short wControlSignalBitmap)
+{
+ (void)wControlSignalBitmap;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC SendBreak Request Callback
+ Called automatically on CDC Set_COMM_FATURE Request
+ Parameters: 0xFFFF start of Break
+ 0x0000 stop of Break
+ 0x#### Duration of Break
+ Return Value: TRUE - Success, FALSE - Error
+ *---------------------------------------------------------------------------*/
+uint32_t
+CDC_SendBreak (unsigned short wDurationOfBreak)
+{
+ (void)wDurationOfBreak;
+ /* ... add code to handle request */
+ return (TRUE);
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC_BulkIn call on DataIn Request
+ Parameters: none
+ Return Value: none
+ *---------------------------------------------------------------------------*/
+void
+CDC_BulkIn (void)
+{
+ // send over USB
+ if (UARTCount > 0)
+ {
+ USB_WriteEP (CDC_DEP_IN, (uint8_t*)UARTBuffer, UARTCount);
+ UARTCount = 0;
+ }
+ else
+ {
+ CDC_DepInEmpty = 1;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ CDC_BulkOut call on DataOut Request
+ Parameters: none
+ Return Value: none
+ *---------------------------------------------------------------------------*/
+void
+CDC_BulkOut (void)
+{
+ int numBytesRead;
+
+ // get data from USB into intermediate buffer
+ numBytesRead = USB_ReadEP (CDC_DEP_OUT, &BulkBufOut[0]);
+
+ // ... add code to check for overwrite
+
+ // store data in a buffer to transmit it over serial interface
+ CDC_WrOutBuf ((char *) &BulkBufOut[0], &numBytesRead);
+
+}
+
+
+/*----------------------------------------------------------------------------
+ Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69.
+ Parameters: none
+ Return Value: SerialState as defined in usbcdc11.pdf
+ *---------------------------------------------------------------------------*/
+unsigned short
+CDC_GetSerialState (void)
+{
+// unsigned short temp;
+
+ CDC_SerialState = 0;
+/* ser_LineState (&temp);
+
+ if (temp & 0x8000)
+ CDC_SerialState |= CDC_SERIAL_STATE_RX_CARRIER;
+ if (temp & 0x2000)
+ CDC_SerialState |= CDC_SERIAL_STATE_TX_CARRIER;
+ if (temp & 0x0010)
+ CDC_SerialState |= CDC_SERIAL_STATE_BREAK;
+ if (temp & 0x4000)
+ CDC_SerialState |= CDC_SERIAL_STATE_RING;
+ if (temp & 0x0008)
+ CDC_SerialState |= CDC_SERIAL_STATE_FRAMING;
+ if (temp & 0x0004)
+ CDC_SerialState |= CDC_SERIAL_STATE_PARITY;
+ if (temp & 0x0002)
+ CDC_SerialState |= CDC_SERIAL_STATE_OVERRUN;*/
+
+ return (CDC_SerialState);
+}
+
+
+/*----------------------------------------------------------------------------
+ Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5.
+ *---------------------------------------------------------------------------*/
+void
+CDC_NotificationIn (void)
+{
+
+ NotificationBuf[0] = 0xA1; // bmRequestType
+ NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE)
+ NotificationBuf[2] = 0x00; // wValue
+ NotificationBuf[3] = 0x00;
+ NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first)
+ NotificationBuf[5] = 0x00;
+ NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first)
+ NotificationBuf[7] = 0x00;
+ NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first)
+ NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF;
+
+ USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification
+}
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/clkconfig.c b/openbeacon/lpc13xx/usbcdc-storage/src/clkconfig.c
new file mode 100644
index 0000000..786ca7e
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/clkconfig.c
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * clkconfig.c: clock configuration C file for NXP LPC13xx Family
+ * Microprocessors
+ *
+ * Copyright(C) 2009, NXP Semiconductor
+ * All rights reserved.
+ *
+ * History
+ * 2009.08.20 ver 1.00 Preliminary version, first Release
+ *
+******************************************************************************/
+#include "LPC13xx.h"
+#include "clkconfig.h"
+
+/*****************************************************************************
+** Function name: WDT_CLK_Setup
+**
+** Descriptions: Configure WDT clock.
+** parameters: clock source: irc_osc(0), main_clk(1), wdt_osc(2).
+**
+** Returned value: None
+**
+*****************************************************************************/
+void
+WDT_CLK_Setup (uint32_t clksrc)
+{
+ /* Watchdog configuration. */
+ /* Freq = 0.5Mhz, div_sel is 0, divided by 2. WDT_OSC should be 250khz */
+ LPC_SYSCON->WDTOSCCTRL = (0x1 << 5) | 0x00;
+ LPC_SYSCON->WDTCLKSEL = clksrc; /* Select clock source */
+ LPC_SYSCON->WDTCLKUEN = 0x01; /* Update clock */
+ LPC_SYSCON->WDTCLKUEN = 0x00; /* Toggle update register once */
+ LPC_SYSCON->WDTCLKUEN = 0x01;
+ while (!(LPC_SYSCON->WDTCLKUEN & 0x01)); /* Wait until updated */
+ LPC_SYSCON->WDTCLKDIV = 1; /* Divided by 1 */
+ LPC_SYSCON->PDRUNCFG &= ~(0x1 << 6); /* Let WDT clock run */
+ return;
+}
+
+/*****************************************************************************
+** Function name: CLKOUT_Setup
+**
+** Descriptions: Configure CLKOUT for reference clock check.
+** parameters: clock source: irc_osc(0), sys_osc(1), wdt_osc(2),
+** main_clk(3).
+**
+** Returned value: None
+**
+*****************************************************************************/
+void
+CLKOUT_Setup (uint32_t clksrc)
+{
+ /* debug PLL after configuration. */
+ LPC_SYSCON->CLKOUTCLKSEL = clksrc; /* Select Main clock */
+ LPC_SYSCON->CLKOUTUEN = 0x01; /* Update clock */
+ LPC_SYSCON->CLKOUTUEN = 0x00; /* Toggle update register once */
+ LPC_SYSCON->CLKOUTUEN = 0x01;
+ while (!(LPC_SYSCON->CLKOUTUEN & 0x01)); /* Wait until updated */
+ LPC_SYSCON->CLKOUTDIV = 1; /* Divided by 1 */
+ return;
+}
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/compusbdesc.c b/openbeacon/lpc13xx/usbcdc-storage/src/compusbdesc.c
new file mode 100644
index 0000000..ae5e15b
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/compusbdesc.c
@@ -0,0 +1,273 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbdesc.c
+ * Purpose: USB Descriptors
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Changed string descriptor handling
+ * V1.00 Initial Version
+ *---------------------------------------------------------------------------*/
+#include "type.h"
+
+#include "compusb.h"
+#include "cdc.h"
+#include "usbcfg.h"
+#include "compusbdesc.h"
+
+#include "msc.h"
+#include "config.h"
+
+
+/* USB Standard Device Descriptor */
+const uint8_t USB_DeviceDescriptor[] = {
+ USB_DEVICE_DESC_SIZE, /* bLength */
+ USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL (0x0200), /* 2.0 *//* bcdUSB */
+ USB_DEVICE_CLASS_MISCELLANEOUS, /* bDeviceClass */
+ 0x02, /* bDeviceSubClass */
+ 0x01, /* bDeviceProtocol */
+ USB_MAX_PACKET0, /* bMaxPacketSize0 */
+ WBVAL (USB_VENDOR_ID), /* idVendor */
+ WBVAL (USB_PROD_ID), /* idProduct */
+ WBVAL (USB_DEVICE), /* 1.00 *//* bcdDevice */
+ 0x01, /* iManufacturer */
+ 0x02, /* iProduct */
+ 0x03, /* iSerialNumber */
+ 0x01 /* bNumConfigurations: one possible configuration */
+};
+
+/* USB Configuration Descriptor */
+/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */
+const uint8_t USB_ConfigDescriptor[] = {
+ /* Configuration 1 */
+ USB_CONFIGUARTION_DESC_SIZE, /* bLength */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL ( /* wTotalLength */
+ 1 * USB_CONFIGUARTION_DESC_SIZE + 1 * USB_INTERFACE_DESC_SIZE + /* mass storage interface */
+ 2 * USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */
+ 1 * USB_INTERFACE_ASSOCIATION_DESC_SIZE + /* interface association */
+ 1 * USB_INTERFACE_DESC_SIZE + /* communication interface */
+ 0x0013 + /* CDC functions */
+ 1 * USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */
+ 1 * USB_INTERFACE_DESC_SIZE + /* data interface */
+ 2 * USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */
+ 0),
+
+ 0x03, /* bNumInterfaces */
+ 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */
+ 0x00, /* iConfiguration: no string to describe this configuration */
+ USB_CONFIG_BUS_POWERED /*| *//* bmAttributes */
+ /*USB_CONFIG_REMOTE_WAKEUP */ ,
+ USB_CONFIG_POWER_MA (100), /* bMaxPower, device power consumption is 100 mA */
+
+ /* Interface 0, Alternate Setting 0, MSC Class */
+ USB_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_MSC_IF_NUM, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x02, /* bNumEndpoints */
+ USB_DEVICE_CLASS_STORAGE, /* bInterfaceClass */
+ MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */
+ MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */
+ 0x04, /* iInterface */
+
+ /* Endpoint, EP2 Bulk IN */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_IN (2), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
+ WBVAL (0x0040), /* wMaxPacketSize */
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint, EP2 Bulk OUT */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_OUT (2), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
+ WBVAL (0x0040), /* wMaxPacketSize */
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* IAD to associate the two CDC interfaces */
+ USB_INTERFACE_ASSOCIATION_DESC_SIZE, /* bLength */
+ USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_CDC_CIF_NUM, /* bFirstInterface */
+ 2, /* bInterfaceCount */
+ CDC_COMMUNICATION_INTERFACE_CLASS, /* bFunctionClass */
+ CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */
+ 0, /* bFunctionProtocol */
+ 0x06, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface 0, Alternate Setting 0, Communication class interface descriptor */
+ USB_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */
+ CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */
+ 0x00, /* bInterfaceProtocol: no protocol used */
+ 0x05, /* iInterface: */
+ /*Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */
+ WBVAL (CDC_V1_10), /* 1.10 *//* bcdCDC */
+ /*Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x01, /* bmCapabilities: device handles call management */
+ USB_CDC_DIF_NUM, /* bDataInterface: CDC data IF ID */
+ /*Abstract Control Management Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */
+ /*Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ CDC_UNION, /* bDescriptorSubtype: Union func desc */
+ USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */
+ USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */
+ /*Endpoint 1 Descriptor *//* event notification (optional) */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_IN (1), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
+ WBVAL (0x0010), /* wMaxPacketSize */
+ 0x02, /* 2ms *//* bInterval */
+ /* Interface 1, Alternate Setting 0, Data class interface descriptor */
+ USB_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: no alternate setting */
+ 0x02, /* bNumEndpoints: two endpoints used */
+ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */
+ 0x00, /* bInterfaceSubClass: no subclass available */
+ 0x00, /* bInterfaceProtocol: no protocol used */
+ 0x05, /* iInterface: */
+ /* Endpoint, EP3 Bulk Out */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_OUT (3), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
+ WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */
+ 0x00, /* bInterval: ignore for Bulk transfer */
+ /* Endpoint, EP3 Bulk In */
+ USB_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ USB_ENDPOINT_IN (3), /* bEndpointAddress */
+ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
+ WBVAL (USB_CDC_BUFSIZE), /* wMaxPacketSize */
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Terminator */
+ 0 /* bLength */
+};
+
+
+/* USB String Descriptor (optional) */
+const uint8_t USB_StringDescriptor[] = {
+ /* Index 0x00: LANGID Codes */
+ 0x04, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ WBVAL (0x0409), /* US English *//* wLANGID */
+ /* Index 0x01: Manufacturer */
+ (13 * 2 + 2), /* bLength (13 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'N', 0,
+ 'X', 0,
+ 'P', 0,
+ ' ', 0,
+ 'S', 0,
+ 'E', 0,
+ 'M', 0,
+ 'I', 0,
+ 'C', 0,
+ 'O', 0,
+ 'N', 0,
+ 'D', 0,
+ ' ', 0,
+ /* Index 0x02: Product */
+ (21 * 2 + 2), /* bLength ( 21 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'N', 0,
+ 'X', 0,
+ 'P', 0,
+ ' ', 0,
+ 'L', 0,
+ 'P', 0,
+ 'C', 0,
+ '1', 0,
+ '3', 0,
+ 'x', 0,
+ 'x', 0,
+ ' ', 0,
+ 'M', 0,
+ 'S', 0,
+ 'D', 0,
+ '/', 0,
+ 'V', 0,
+ 'C', 0,
+ 'O', 0,
+ 'M', 0,
+ ' ', 0,
+ /* Index 0x03: Serial Number */
+ (16 * 2 + 2), /* bLength (12 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'C', 0,
+ 'O', 0,
+ 'M', 0,
+ 'P', 0,
+ 'O', 0,
+ 'S', 0,
+ 'I', 0,
+ 'T', 0,
+ 'E', 0,
+ ' ', 0,
+ 'D', 0,
+ 'E', 0,
+ 'M', 0,
+ 'O', 0,
+ ' ', 0,
+ ' ', 0,
+ /* Index 0x04: Interface 0, Alternate Setting 0 */
+ (6 * 2 + 2), /* bLength (6 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'M', 0,
+ 'e', 0,
+ 'm', 0,
+ 'o', 0,
+ 'r', 0,
+ 'y', 0,
+ /* Index 0x05: Interface 0, Alternate Setting 0 */
+ (4 * 2 + 2), /* bLength (4 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'V', 0,
+ 'C', 0,
+ 'O', 0,
+ 'M', 0,
+ /* Index 0x05: Interface 0, Alternate Setting 0 */
+ (8 * 2 + 2), /* bLength (4 Char + Type + lenght) */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'C', 0,
+ 'O', 0,
+ 'M', 0,
+ '/', 0,
+ 'D', 0,
+ 'A', 0,
+ 'T', 0,
+ 'A', 0,
+};
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/main.c b/openbeacon/lpc13xx/usbcdc-storage/src/main.c
new file mode 100644
index 0000000..327d9bf
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/main.c
@@ -0,0 +1,163 @@
+/*----------------------------------------------------------------------------
+ * Name: vcomdemo.c
+ * Purpose: USB virtual COM port Demo
+ * Version: V1.02
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#include "LPC13xx.h"
+#include "type.h"
+
+#include "usb.h"
+#include "usbcfg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "cdc.h"
+#include "cdcuser.h"
+#include "uart.h"
+#include "vcomdemo.h"
+#include "mscuser.h"
+#include "memory.h"
+#include "stdio.h"
+#include "string.h"
+#include "debug_printf.h"
+
+extern uint8_t Memory[MSC_MemorySize]; /* MSC Memory in RAM */
+
+#define EN_TIMER32_1 (1<<10)
+#define EN_IOCON (1<<16)
+#define EN_USBREG (1<<14)
+
+/*----------------------------------------------------------------------------
+ Initializes the VCOM port.
+ Call this function before using VCOM_putchar or VCOM_getchar
+ *---------------------------------------------------------------------------*/
+void
+VCOM_Init (void)
+{
+
+ CDC_Init ();
+}
+
+
+/*----------------------------------------------------------------------------
+ Reads character from serial port buffer and writes to USB buffer
+ *---------------------------------------------------------------------------*/
+void
+VCOM_Serial2Usb (void)
+{
+ int numBytesRead;
+
+ if (UARTCount > 0)
+ {
+ if (CDC_DepInEmpty)
+ {
+ numBytesRead = (UARTCount 0)
+ {
+ numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
+ numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);
+ UARTSend ((uint8_t*)&serBuf, numBytesRead);
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+ Reads character from USB buffer and writes to serial port buffer
+ *---------------------------------------------------------------------------*/
+void
+VCOM_Usb2SerialTest (void)
+{
+ debug_printf("Hello World!\n");
+}
+
+
+/*----------------------------------------------------------------------------
+ checks the serial state and initiates notification
+ *---------------------------------------------------------------------------*/
+void
+VCOM_CheckSerialState (void)
+{
+ unsigned short temp;
+ static unsigned short serialState;
+
+ temp = CDC_GetSerialState ();
+ if (serialState != temp)
+ {
+ serialState = temp;
+ CDC_NotificationIn (); // send SERIAL_STATE notification
+ }
+}
+
+/*----------------------------------------------------------------------------
+ Main Program
+ *---------------------------------------------------------------------------*/
+int
+main (void)
+{
+ uint32_t n;
+
+ for (n = 0; n < MSC_ImageSize; n++)
+ { /* Copy Initial Disk Image */
+ Memory[n] = DiskImage[n]; /* from Flash to RAM */
+ }
+
+ /* Basic chip initialization is taken care of in SystemInit() called
+ * from the startup code. SystemInit() and chip settings are defined
+ * in the CMSIS system_.c file.
+ */
+
+ /* Enable Timer32_1, IOCON, and USB blocks */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);
+
+
+ USBIOClkConfig ();
+
+ VCOM_Init (); // VCOM Initialization
+
+ USB_Init (); // USB Initialization
+ USB_Connect (TRUE); // USB Connect
+
+ while (!USB_Configuration); // wait until USB is configured
+
+ /* NVIC is installed inside UARTInit file. */
+ SystemCoreClockUpdate ();
+ UARTInit (115200, 0);
+
+ VCOM_Usb2SerialTest ();
+
+ while (1)
+ { // Loop forever
+ VCOM_Serial2Usb (); // read serial port and initiate USB event
+ VCOM_CheckSerialState ();
+ VCOM_Usb2Serial ();
+ } // end while
+} // end main ()
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/mscuser.c b/openbeacon/lpc13xx/usbcdc-storage/src/mscuser.c
new file mode 100644
index 0000000..dbf5e6e
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/mscuser.c
@@ -0,0 +1,795 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: mscuser.c
+ * Purpose: Mass Storage Class Custom User Module
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added SCSI_READ12, SCSI_WRITE12
+ * V1.00 Initial Version
+ *---------------------------------------------------------------------------*/
+#include "type.h"
+
+#include "usb.h"
+#include "msc.h"
+#include "usbcfg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "mscuser.h"
+#include "memory.h"
+
+
+uint8_t Memory[MSC_MemorySize]; /* MSC RAM */
+
+uint32_t MemOK; /* Memory OK */
+
+uint32_t Offset; /* R/W Offset */
+uint32_t Length; /* R/W Length */
+
+uint8_t BulkStage = MSC_BS_CBW; /* Bulk Stage */
+
+uint8_t BulkBuf[MSC_MAX_PACKET] __attribute__ ((aligned (4))); /* Bulk In/Out Buffer */
+uint8_t BulkLen; /* Bulk In/Out Length */
+
+MSC_CBW CBW; /* Command Block Wrapper */
+MSC_CSW CSW; /* Command Status Wrapper */
+
+
+
+/*
+ * Set Stall for MSC Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+MSC_SetStallEP (uint32_t EPNum)
+{ /* set EP halt status according stall status */
+ USB_SetStallEP (EPNum);
+ USB_EndPointHalt |= (EPNum & 0x80) ? ((1 << 16) << (EPNum & 0x0F)) : (1 << EPNum);
+}
+
+
+/*
+ * MSC Mass Storage Reset Request Callback
+ * Called automatically on Mass Storage Reset Request
+ * Parameters: None (global SetupPacket and EP0Buf)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+uint32_t
+MSC_Reset (void)
+{
+
+
+ USB_EndPointStall = 0x00000000; /* EP must stay stalled */
+ CSW.dSignature = 0; /* invalid signature */
+
+ BulkStage = MSC_BS_CBW;
+
+ return (TRUE);
+}
+
+
+/*
+ * MSC Get Max LUN Request Callback
+ * Called automatically on Get Max LUN Request
+ * Parameters: None (global SetupPacket and EP0Buf)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+uint32_t
+MSC_GetMaxLUN (void)
+{
+
+ EP0Buf[0] = 0; /* No LUN associated with this device */
+ return (TRUE);
+}
+
+
+/*
+ * MSC Memory Read Callback
+ * Called automatically on Memory Read Event
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_MemoryRead (void)
+{
+ uint32_t n;
+
+ if (Length > MSC_MAX_PACKET)
+ {
+ n = MSC_MAX_PACKET;
+ }
+ else
+ {
+ n = Length;
+ }
+
+ if ((Offset + n) > MSC_MemorySize)
+ {
+ n = MSC_MemorySize - Offset;
+ BulkStage = MSC_BS_DATA_IN_LAST_STALL;
+ }
+
+ USB_WriteEP (MSC_EP_IN, &Memory[Offset], n);
+ Offset += n;
+ Length -= n;
+
+ CSW.dDataResidue -= n;
+
+ if (Length == 0)
+ {
+ BulkStage = MSC_BS_DATA_IN_LAST;
+ }
+
+ if (BulkStage != MSC_BS_DATA_IN)
+ {
+ CSW.bStatus = CSW_CMD_PASSED;
+ }
+}
+
+
+/*
+ * MSC Memory Write Callback
+ * Called automatically on Memory Write Event
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_MemoryWrite (void)
+{
+ uint32_t n;
+
+ if ((Offset + BulkLen) > MSC_MemorySize)
+ {
+ BulkLen = MSC_MemorySize - Offset;
+ BulkStage = MSC_BS_CSW;
+ MSC_SetStallEP (MSC_EP_OUT);
+ }
+
+ for (n = 0; n < BulkLen; n++)
+ {
+ Memory[Offset + n] = BulkBuf[n];
+ }
+
+ Offset += BulkLen;
+ Length -= BulkLen;
+
+ CSW.dDataResidue -= BulkLen;
+
+ if ((Length == 0) || (BulkStage == MSC_BS_CSW))
+ {
+ CSW.bStatus = CSW_CMD_PASSED;
+ MSC_SetCSW ();
+ }
+}
+
+
+/*
+ * MSC Memory Verify Callback
+ * Called automatically on Memory Verify Event
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_MemoryVerify (void)
+{
+ uint32_t n;
+
+ if ((Offset + BulkLen) > MSC_MemorySize)
+ {
+ BulkLen = MSC_MemorySize - Offset;
+ BulkStage = MSC_BS_CSW;
+ MSC_SetStallEP (MSC_EP_OUT);
+ }
+
+ for (n = 0; n < BulkLen; n++)
+ {
+ if (Memory[Offset + n] != BulkBuf[n])
+ {
+ MemOK = FALSE;
+ break;
+ }
+ }
+
+ Offset += BulkLen;
+ Length -= BulkLen;
+
+ CSW.dDataResidue -= BulkLen;
+
+ if ((Length == 0) || (BulkStage == MSC_BS_CSW))
+ {
+ CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED;
+ MSC_SetCSW ();
+ }
+}
+
+
+/*
+ * MSC SCSI Read/Write Setup Callback
+ * Parameters: None (global variables)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+uint32_t
+MSC_RWSetup (void)
+{
+ uint32_t n;
+
+ /* Logical Block Address of First Block */
+ n = (CBW.CB[2] << 24) | (CBW.CB[3] << 16) | (CBW.CB[4] << 8) | (CBW.CB[5] << 0);
+
+ Offset = n * MSC_BlockSize;
+
+ /* Number of Blocks to transfer */
+ switch (CBW.CB[0])
+ {
+ case SCSI_READ10:
+ case SCSI_WRITE10:
+ case SCSI_VERIFY10:
+ n = (CBW.CB[7] << 8) | (CBW.CB[8] << 0);
+ break;
+
+ case SCSI_READ12:
+ case SCSI_WRITE12:
+ n = (CBW.CB[6] << 24) | (CBW.CB[7] << 16) | (CBW.CB[8] << 8) | (CBW.CB[9] << 0);
+ break;
+ }
+
+ Length = n * MSC_BlockSize;
+
+ if (CBW.dDataLength == 0)
+ { /* host requests no data */
+ CSW.bStatus = CSW_CMD_FAILED;
+ MSC_SetCSW ();
+ return (FALSE);
+ }
+
+ if (CBW.dDataLength != Length)
+ {
+ if ((CBW.bmFlags & 0x80) != 0)
+ { /* stall appropriate EP */
+ MSC_SetStallEP (MSC_EP_IN);
+ }
+ else
+ {
+ MSC_SetStallEP (MSC_EP_OUT);
+ }
+
+ CSW.bStatus = CSW_CMD_FAILED;
+ MSC_SetCSW ();
+
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+
+/*
+ * Check Data IN Format
+ * Parameters: None (global variables)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+uint32_t
+DataInFormat (void)
+{
+
+ if (CBW.dDataLength == 0)
+ {
+ CSW.bStatus = CSW_PHASE_ERROR;
+ MSC_SetCSW ();
+ return (FALSE);
+ }
+ if ((CBW.bmFlags & 0x80) == 0)
+ {
+ MSC_SetStallEP (MSC_EP_OUT);
+ CSW.bStatus = CSW_PHASE_ERROR;
+ MSC_SetCSW ();
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Perform Data IN Transfer
+ * Parameters: None (global variables)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+void
+DataInTransfer (void)
+{
+
+ if (BulkLen >= CBW.dDataLength)
+ BulkLen = CBW.dDataLength;
+
+ BulkStage = MSC_BS_DATA_IN_LAST;
+
+ USB_WriteEP (MSC_EP_IN, BulkBuf, BulkLen);
+
+ CSW.dDataResidue -= BulkLen;
+ CSW.bStatus = CSW_CMD_PASSED;
+}
+
+
+/*
+ * MSC SCSI Test Unit Ready Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_TestUnitReady (void)
+{
+
+ if (CBW.dDataLength != 0)
+ {
+ if ((CBW.bmFlags & 0x80) != 0)
+ {
+ MSC_SetStallEP (MSC_EP_IN);
+ }
+ else
+ {
+ MSC_SetStallEP (MSC_EP_OUT);
+ }
+ }
+
+ CSW.bStatus = CSW_CMD_PASSED;
+ MSC_SetCSW ();
+}
+
+
+/*
+ * MSC SCSI Request Sense Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_RequestSense (void)
+{
+
+ if (!DataInFormat ())
+ return;
+
+ BulkBuf[0] = 0x70; /* Response Code */
+ BulkBuf[1] = 0x00;
+ BulkBuf[2] = 0x02; /* Sense Key */
+ BulkBuf[3] = 0x00;
+ BulkBuf[4] = 0x00;
+ BulkBuf[5] = 0x00;
+ BulkBuf[6] = 0x00;
+ BulkBuf[7] = 0x0A; /* Additional Length */
+ BulkBuf[8] = 0x00;
+ BulkBuf[9] = 0x00;
+ BulkBuf[10] = 0x00;
+ BulkBuf[11] = 0x00;
+ BulkBuf[12] = 0x30; /* ASC */
+ BulkBuf[13] = 0x01; /* ASCQ */
+ BulkBuf[14] = 0x00;
+ BulkBuf[15] = 0x00;
+ BulkBuf[16] = 0x00;
+ BulkBuf[17] = 0x00;
+
+ BulkLen = 18;
+ DataInTransfer ();
+}
+
+
+/*
+ * MSC SCSI Inquiry Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_Inquiry (void)
+{
+
+ if (!DataInFormat ())
+ return;
+
+ BulkBuf[0] = 0x00; /* Direct Access Device */
+ BulkBuf[1] = 0x80; /* RMB = 1: Removable Medium */
+ BulkBuf[2] = 0x00; /* Version: No conformance claim to standard */
+ BulkBuf[3] = 0x01;
+
+ BulkBuf[4] = 36 - 4; /* Additional Length */
+ BulkBuf[5] = 0x80; /* SCCS = 1: Storage Controller Component */
+ BulkBuf[6] = 0x00;
+ BulkBuf[7] = 0x00;
+
+ BulkBuf[8] = 'K'; /* Vendor Identification */
+ BulkBuf[9] = 'e';
+ BulkBuf[10] = 'i';
+ BulkBuf[11] = 'l';
+ BulkBuf[12] = ' ';
+ BulkBuf[13] = ' ';
+ BulkBuf[14] = ' ';
+ BulkBuf[15] = ' ';
+
+ BulkBuf[16] = 'L'; /* Product Identification */
+ BulkBuf[17] = 'P';
+ BulkBuf[18] = 'C';
+ BulkBuf[19] = '1';
+ BulkBuf[20] = '3';
+ BulkBuf[21] = '4';
+ BulkBuf[22] = 'x';
+ BulkBuf[23] = ' ';
+ BulkBuf[24] = 'D';
+ BulkBuf[25] = 'i';
+ BulkBuf[26] = 's';
+ BulkBuf[27] = 'k';
+ BulkBuf[28] = ' ';
+ BulkBuf[29] = ' ';
+ BulkBuf[30] = ' ';
+ BulkBuf[31] = ' ';
+
+ BulkBuf[32] = '1'; /* Product Revision Level */
+ BulkBuf[33] = '.';
+ BulkBuf[34] = '0';
+ BulkBuf[35] = ' ';
+
+ BulkLen = 36;
+ DataInTransfer ();
+}
+
+
+/*
+ * MSC SCSI Mode Sense (6-Byte) Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_ModeSense6 (void)
+{
+
+ if (!DataInFormat ())
+ return;
+
+ BulkBuf[0] = 0x03;
+ BulkBuf[1] = 0x00;
+ BulkBuf[2] = 0x00;
+ BulkBuf[3] = 0x00;
+
+ BulkLen = 4;
+ DataInTransfer ();
+}
+
+
+/*
+ * MSC SCSI Mode Sense (10-Byte) Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_ModeSense10 (void)
+{
+
+ if (!DataInFormat ())
+ return;
+
+ BulkBuf[0] = 0x00;
+ BulkBuf[1] = 0x06;
+ BulkBuf[2] = 0x00;
+ BulkBuf[3] = 0x00;
+ BulkBuf[4] = 0x00;
+ BulkBuf[5] = 0x00;
+ BulkBuf[6] = 0x00;
+ BulkBuf[7] = 0x00;
+
+ BulkLen = 8;
+ DataInTransfer ();
+}
+
+
+/*
+ * MSC SCSI Read Capacity Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_ReadCapacity (void)
+{
+
+ if (!DataInFormat ())
+ return;
+
+ /* Last Logical Block */
+ BulkBuf[0] = ((MSC_BlockCount - 1) >> 24) & 0xFF;
+ BulkBuf[1] = ((MSC_BlockCount - 1) >> 16) & 0xFF;
+ BulkBuf[2] = ((MSC_BlockCount - 1) >> 8) & 0xFF;
+ BulkBuf[3] = ((MSC_BlockCount - 1) >> 0) & 0xFF;
+
+ /* Block Length */
+ BulkBuf[4] = (MSC_BlockSize >> 24) & 0xFF;
+ BulkBuf[5] = (MSC_BlockSize >> 16) & 0xFF;
+ BulkBuf[6] = (MSC_BlockSize >> 8) & 0xFF;
+ BulkBuf[7] = (MSC_BlockSize >> 0) & 0xFF;
+
+ BulkLen = 8;
+ DataInTransfer ();
+}
+
+
+/*
+ * MSC SCSI Read Format Capacity Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_ReadFormatCapacity (void)
+{
+
+ if (!DataInFormat ())
+ return;
+
+ BulkBuf[0] = 0x00;
+ BulkBuf[1] = 0x00;
+ BulkBuf[2] = 0x00;
+ BulkBuf[3] = 0x08; /* Capacity List Length */
+
+ /* Block Count */
+ BulkBuf[4] = (MSC_BlockCount >> 24) & 0xFF;
+ BulkBuf[5] = (MSC_BlockCount >> 16) & 0xFF;
+ BulkBuf[6] = (MSC_BlockCount >> 8) & 0xFF;
+ BulkBuf[7] = (MSC_BlockCount >> 0) & 0xFF;
+
+ /* Block Length */
+ BulkBuf[8] = 0x02; /* Descriptor Code: Formatted Media */
+ BulkBuf[9] = (MSC_BlockSize >> 16) & 0xFF;
+ BulkBuf[10] = (MSC_BlockSize >> 8) & 0xFF;
+ BulkBuf[11] = (MSC_BlockSize >> 0) & 0xFF;
+
+ BulkLen = 12;
+ DataInTransfer ();
+}
+
+
+/*
+ * MSC Get Command Block Wrapper Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_GetCBW (void)
+{
+ uint32_t n;
+
+ for (n = 0; n < BulkLen; n++)
+ {
+ *((uint8_t *) & CBW + n) = BulkBuf[n];
+ }
+ if ((BulkLen == sizeof (CBW)) && (CBW.dSignature == MSC_CBW_Signature))
+ {
+ /* Valid CBW */
+ CSW.dTag = CBW.dTag;
+ CSW.dDataResidue = CBW.dDataLength;
+ if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || (CBW.bCBLength > 16))
+ {
+ fail:
+ CSW.bStatus = CSW_CMD_FAILED;
+ MSC_SetCSW ();
+ }
+ else
+ {
+ switch (CBW.CB[0])
+ {
+ case SCSI_TEST_UNIT_READY:
+ MSC_TestUnitReady ();
+ break;
+ case SCSI_REQUEST_SENSE:
+ MSC_RequestSense ();
+ break;
+ case SCSI_FORMAT_UNIT:
+ goto fail;
+ case SCSI_INQUIRY:
+ MSC_Inquiry ();
+ break;
+ case SCSI_START_STOP_UNIT:
+ goto fail;
+ case SCSI_MEDIA_REMOVAL:
+ goto fail;
+ case SCSI_MODE_SELECT6:
+ goto fail;
+ case SCSI_MODE_SENSE6:
+ MSC_ModeSense6 ();
+ break;
+ case SCSI_MODE_SELECT10:
+ goto fail;
+ case SCSI_MODE_SENSE10:
+ MSC_ModeSense10 ();
+ break;
+ case SCSI_READ_FORMAT_CAPACITIES:
+ MSC_ReadFormatCapacity ();
+ break;
+ case SCSI_READ_CAPACITY:
+ MSC_ReadCapacity ();
+ break;
+ case SCSI_READ10:
+ case SCSI_READ12:
+ if (MSC_RWSetup ())
+ {
+ if ((CBW.bmFlags & 0x80) != 0)
+ {
+ BulkStage = MSC_BS_DATA_IN;
+ MSC_MemoryRead ();
+ }
+ else
+ { /* direction mismatch */
+ MSC_SetStallEP (MSC_EP_OUT);
+ CSW.bStatus = CSW_PHASE_ERROR;
+ MSC_SetCSW ();
+ }
+ }
+ break;
+ case SCSI_WRITE10:
+ case SCSI_WRITE12:
+ if (MSC_RWSetup ())
+ {
+ if ((CBW.bmFlags & 0x80) == 0)
+ {
+ BulkStage = MSC_BS_DATA_OUT;
+ }
+ else
+ { /* direction mismatch */
+ MSC_SetStallEP (MSC_EP_IN);
+ CSW.bStatus = CSW_PHASE_ERROR;
+ MSC_SetCSW ();
+ }
+ }
+ break;
+ case SCSI_VERIFY10:
+ if ((CBW.CB[1] & 0x02) == 0)
+ {
+ // BYTCHK = 0 -> CRC Check (not implemented)
+ CSW.bStatus = CSW_CMD_PASSED;
+ MSC_SetCSW ();
+ break;
+ }
+ if (MSC_RWSetup ())
+ {
+ if ((CBW.bmFlags & 0x80) == 0)
+ {
+ BulkStage = MSC_BS_DATA_OUT;
+ MemOK = TRUE;
+ }
+ else
+ {
+ MSC_SetStallEP (MSC_EP_IN);
+ CSW.bStatus = CSW_PHASE_ERROR;
+ MSC_SetCSW ();
+ }
+ }
+ break;
+ default:
+ goto fail;
+ }
+ }
+ }
+ else
+ {
+ /* Invalid CBW */
+ MSC_SetStallEP (MSC_EP_IN);
+ /* set EP to stay stalled */
+ USB_EndPointStall |= (MSC_EP_IN & 0x80) ? ((1 << 16) << (MSC_EP_IN & 0x0F)) : (1 << MSC_EP_IN);
+ MSC_SetStallEP (MSC_EP_OUT);
+ /* set EP to stay stalled */
+ USB_EndPointStall |= (MSC_EP_OUT & 0x80) ? ((1 << 16) << (MSC_EP_OUT & 0x0F)) : (1 << MSC_EP_OUT);
+ BulkStage = MSC_BS_ERROR;
+ }
+}
+
+
+/*
+ * MSC Set Command Status Wrapper Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_SetCSW (void)
+{
+
+ CSW.dSignature = MSC_CSW_Signature;
+ USB_WriteEP (MSC_EP_IN, (uint8_t *) & CSW, sizeof (CSW));
+ BulkStage = MSC_BS_CSW;
+}
+
+
+/*
+ * MSC Bulk In Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_BulkIn (void)
+{
+
+ switch (BulkStage)
+ {
+ case MSC_BS_DATA_IN:
+ switch (CBW.CB[0])
+ {
+ case SCSI_READ10:
+ case SCSI_READ12:
+ MSC_MemoryRead ();
+ break;
+ }
+ break;
+ case MSC_BS_DATA_IN_LAST:
+ MSC_SetCSW ();
+ break;
+ case MSC_BS_DATA_IN_LAST_STALL:
+ MSC_SetStallEP (MSC_EP_IN);
+ MSC_SetCSW ();
+ break;
+ case MSC_BS_CSW:
+ BulkStage = MSC_BS_CBW;
+ break;
+ }
+}
+
+
+/*
+ * MSC Bulk Out Callback
+ * Parameters: None (global variables)
+ * Return Value: None
+ */
+
+void
+MSC_BulkOut (void)
+{
+
+ BulkLen = USB_ReadEP (MSC_EP_OUT, BulkBuf);
+ switch (BulkStage)
+ {
+ case MSC_BS_CBW:
+ MSC_GetCBW ();
+ break;
+ case MSC_BS_DATA_OUT:
+ switch (CBW.CB[0])
+ {
+ case SCSI_WRITE10:
+ case SCSI_WRITE12:
+ MSC_MemoryWrite ();
+ break;
+ case SCSI_VERIFY10:
+ MSC_MemoryVerify ();
+ break;
+ }
+ break;
+ default:
+ MSC_SetStallEP (MSC_EP_OUT);
+ CSW.bStatus = CSW_PHASE_ERROR;
+ MSC_SetCSW ();
+ break;
+ }
+}
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/usbcore.c b/openbeacon/lpc13xx/usbcdc-storage/src/usbcore.c
new file mode 100644
index 0000000..fff47a9
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/usbcore.c
@@ -0,0 +1,1267 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbcore.c
+ * Purpose: USB Core Module
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added vendor specific requests
+ * Changed string descriptor handling
+ * Reworked Endpoint0
+ * V1.00 Initial Version
+ *----------------------------------------------------------------------------*/
+#include "type.h"
+
+#include "usb.h"
+#include "usbcfg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "usbdesc.h"
+#include "usbuser.h"
+
+#if (USB_CLASS)
+
+#if (USB_AUDIO)
+#include "audio.h"
+#include "adcuser.h"
+#endif
+
+#if (USB_HID)
+#include "hid.h"
+#include "hiduser.h"
+#endif
+
+#if (USB_MSC)
+#include "msc.h"
+#include "mscuser.h"
+extern MSC_CSW CSW;
+#endif
+
+#if (USB_CDC)
+#include "cdc.h"
+#include "cdcuser.h"
+#endif
+
+#endif
+
+#if (USB_VENDOR)
+#include "vendor.h"
+#endif
+
+uint16_t USB_DeviceStatus;
+uint8_t USB_DeviceAddress;
+uint8_t USB_Configuration;
+uint32_t USB_EndPointMask;
+uint32_t USB_EndPointHalt;
+uint32_t USB_EndPointStall; /* EP must stay stalled */
+uint8_t USB_NumInterfaces;
+uint8_t USB_AltSetting[USB_IF_NUM];
+
+uint8_t EP0Buf[USB_MAX_PACKET0];
+
+
+USB_EP_DATA EP0Data;
+
+USB_SETUP_PACKET SetupPacket;
+
+
+/*
+ * Reset USB Core
+ * Parameters: None
+ * Return Value: None
+ */
+
+void
+USB_ResetCore (void)
+{
+
+ USB_DeviceStatus = USB_POWER;
+ USB_DeviceAddress = 0;
+ USB_Configuration = 0;
+ USB_EndPointMask = 0x00010001;
+ USB_EndPointHalt = 0x00000000;
+ USB_EndPointStall = 0x00000000;
+}
+
+
+/*
+ * USB Request - Setup Stage
+ * Parameters: None (global SetupPacket)
+ * Return Value: None
+ */
+
+void
+USB_SetupStage (void)
+{
+ USB_ReadEP (0x00, (uint8_t *) & SetupPacket);
+}
+
+
+/*
+ * USB Request - Data In Stage
+ * Parameters: None (global EP0Data)
+ * Return Value: None
+ */
+
+void
+USB_DataInStage (void)
+{
+ uint32_t cnt;
+
+ if (EP0Data.Count > USB_MAX_PACKET0)
+ {
+ cnt = USB_MAX_PACKET0;
+ }
+ else
+ {
+ cnt = EP0Data.Count;
+ }
+ cnt = USB_WriteEP (0x80, EP0Data.pData, cnt);
+ EP0Data.pData += cnt;
+ EP0Data.Count -= cnt;
+}
+
+
+/*
+ * USB Request - Data Out Stage
+ * Parameters: None (global EP0Data)
+ * Return Value: None
+ */
+
+void
+USB_DataOutStage (void)
+{
+ uint32_t cnt;
+
+ cnt = USB_ReadEP (0x00, EP0Data.pData);
+ EP0Data.pData += cnt;
+ EP0Data.Count -= cnt;
+}
+
+
+/*
+ * USB Request - Status In Stage
+ * Parameters: None
+ * Return Value: None
+ */
+
+void
+USB_StatusInStage (void)
+{
+ USB_WriteEP (0x80, NULL, 0);
+}
+
+
+/*
+ * USB Request - Status Out Stage
+ * Parameters: None
+ * Return Value: None
+ */
+
+void
+USB_StatusOutStage (void)
+{
+ USB_ReadEP (0x00, EP0Buf);
+}
+
+
+/*
+ * Get Status USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetStatus (void)
+{
+ uint32_t n, m;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ EP0Data.pData = (uint8_t *) & USB_DeviceStatus;
+ break;
+ case REQUEST_TO_INTERFACE:
+ if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces))
+ {
+ *((uint16_t __attribute__ ((packed)) *) EP0Buf) = 0;
+ EP0Data.pData = EP0Buf;
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ case REQUEST_TO_ENDPOINT:
+ n = SetupPacket.wIndex.WB.L & 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) && (USB_EndPointMask & m))
+ {
+ *((uint16_t __attribute__ ((packed)) *) EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0;
+ EP0Data.pData = EP0Buf;
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Set/Clear Feature USB Request
+ * Parameters: sc: 0 - Clear, 1 - Set
+ * (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetClrFeature (uint32_t sc)
+{
+ uint32_t n, m;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP)
+ {
+ if (sc)
+ {
+ USB_WakeUpCfg (TRUE);
+ USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP;
+ }
+ else
+ {
+ USB_WakeUpCfg (FALSE);
+ USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP;
+ }
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ case REQUEST_TO_INTERFACE:
+ return (FALSE);
+ case REQUEST_TO_ENDPOINT:
+ n = SetupPacket.wIndex.WB.L & 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ if ((USB_Configuration != 0) && ((n & 0x0F) != 0) && (USB_EndPointMask & m))
+ {
+ if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL)
+ {
+ if (sc)
+ {
+ USB_SetStallEP (n);
+ USB_EndPointHalt |= m;
+ }
+ else
+ {
+ if ((USB_EndPointStall & m) != 0)
+ {
+ return (TRUE);
+ }
+ USB_ClrStallEP (n);
+#if (USB_MSC)
+ if ((n == MSC_EP_IN) && ((USB_EndPointHalt & m) != 0))
+ {
+ /* Compliance Test: rewrite CSW after unstall */
+ if (CSW.dSignature == MSC_CSW_Signature)
+ {
+ USB_WriteEP (MSC_EP_IN, (uint8_t *) & CSW, sizeof (CSW));
+ }
+ }
+#endif
+ USB_EndPointHalt &= ~m;
+ }
+ }
+ else
+ {
+ return (FALSE);
+ }
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Set Address USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetAddress (void)
+{
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L;
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Get Descriptor USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetDescriptor (void)
+{
+ uint8_t *pD;
+ uint32_t len, n;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ switch (SetupPacket.wValue.WB.H)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ EP0Data.pData = (uint8_t *) USB_DeviceDescriptor;
+ len = USB_DEVICE_DESC_SIZE;
+ break;
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ pD = (uint8_t *) USB_ConfigDescriptor;
+ for (n = 0; n != SetupPacket.wValue.WB.L; n++)
+ {
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength != 0)
+ {
+ pD += ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength;
+ }
+ }
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bLength == 0)
+ {
+ return (FALSE);
+ }
+ EP0Data.pData = pD;
+ len = ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength;
+ break;
+ case USB_STRING_DESCRIPTOR_TYPE:
+ pD = (uint8_t *) USB_StringDescriptor;
+ for (n = 0; n != SetupPacket.wValue.WB.L; n++)
+ {
+ if (((USB_STRING_DESCRIPTOR *) pD)->bLength != 0)
+ {
+ pD += ((USB_STRING_DESCRIPTOR *) pD)->bLength;
+ }
+ }
+ if (((USB_STRING_DESCRIPTOR *) pD)->bLength == 0)
+ {
+ return (FALSE);
+ }
+ EP0Data.pData = pD;
+ len = ((USB_STRING_DESCRIPTOR *) EP0Data.pData)->bLength;
+ break;
+ default:
+ return (FALSE);
+ }
+ break;
+ case REQUEST_TO_INTERFACE:
+ switch (SetupPacket.wValue.WB.H)
+ {
+#if USB_HID
+ case HID_HID_DESCRIPTOR_TYPE:
+ if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM)
+ {
+ return (FALSE); /* Only Single HID Interface is supported */
+ }
+ EP0Data.pData = (uint8_t *) USB_ConfigDescriptor + HID_DESC_OFFSET;
+ len = HID_DESC_SIZE;
+ break;
+ case HID_REPORT_DESCRIPTOR_TYPE:
+ if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM)
+ {
+ return (FALSE); /* Only Single HID Interface is supported */
+ }
+ EP0Data.pData = (uint8_t *) HID_ReportDescriptor;
+ len = HID_ReportDescSize;
+ break;
+ case HID_PHYSICAL_DESCRIPTOR_TYPE:
+ return (FALSE); /* HID Physical Descriptor is not supported */
+#endif
+ default:
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+
+ if (EP0Data.Count > len)
+ {
+ EP0Data.Count = len;
+ }
+
+ return (TRUE);
+}
+
+
+/*
+ * Get Configuration USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetConfiguration (void)
+{
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ EP0Data.pData = &USB_Configuration;
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Add a number of bytes to a pointer's address
+ * Harder than you might think. Some compilers say:
+ * Expected an lvalue -- Assignment expects its first operand to be
+ * an lvalue. Please note that a cast removes the lvaluedness of an
+ * expression.
+ *
+ * vpptr = void pointer to pointer
+ * n = number of bytes to add to pointer
+ * Call looks like: AddPtr((void **)&myPointer, 8);
+ */
+
+__inline void
+UsbAddPtr (void **vpptr, uint32_t n)
+{
+ /* Declare a pointer to a pointer to a byte. Only a byte pointer
+ * can be incremented by a number of bytes. Other pointers will
+ * increment by a multiple of what they point to.
+ */
+ uint8_t **bpptr;
+
+ /* Convert our void pointer to a pointer to a byte pointer to a pointer */
+ bpptr = (uint8_t **) vpptr;
+
+ /* Add 'n' bytes to our pointer value */
+ (*bpptr) += n;
+}
+
+/*
+ * Set Configuration USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetConfiguration (void)
+{
+ USB_COMMON_DESCRIPTOR *pD;
+ uint32_t alt = 0;
+ uint32_t n, m;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+
+ if (SetupPacket.wValue.WB.L)
+ {
+ pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor;
+ while (pD->bLength)
+ {
+ switch (pD->bDescriptorType)
+ {
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bConfigurationValue == SetupPacket.wValue.WB.L)
+ {
+ USB_Configuration = SetupPacket.wValue.WB.L;
+ USB_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *) pD)->bNumInterfaces;
+ for (n = 0; n < USB_IF_NUM; n++)
+ {
+ USB_AltSetting[n] = 0;
+ }
+ for (n = 1; n < 16; n++)
+ {
+ if (USB_EndPointMask & (1 << n))
+ {
+ USB_DisableEP (n);
+ }
+ if (USB_EndPointMask & ((1 << 16) << n))
+ {
+ USB_DisableEP (n | 0x80);
+ }
+ }
+ USB_EndPointMask = 0x00010001;
+ USB_EndPointHalt = 0x00000000;
+ USB_EndPointStall = 0x00000000;
+ USB_Configure (TRUE);
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bmAttributes & USB_CONFIG_POWERED_MASK)
+ {
+ USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED;
+ }
+ else
+ {
+ USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED;
+ }
+ }
+ else
+ {
+ UsbAddPtr ((void **) &pD, ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength);
+ continue;
+ }
+ break;
+ case USB_INTERFACE_DESCRIPTOR_TYPE:
+ alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting;
+ break;
+ case USB_ENDPOINT_DESCRIPTOR_TYPE:
+ if (alt == 0)
+ {
+ n = ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress & 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ USB_EndPointMask |= m;
+ USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD);
+ USB_EnableEP (n);
+ USB_ResetEP (n);
+ }
+ break;
+ }
+ UsbAddPtr ((void **) &pD, pD->bLength);
+ }
+ }
+ else
+ {
+ USB_Configuration = 0;
+ for (n = 1; n < 16; n++)
+ {
+ if (USB_EndPointMask & (1 << n))
+ {
+ USB_DisableEP (n);
+ }
+ if (USB_EndPointMask & ((1 << 16) << n))
+ {
+ USB_DisableEP (n | 0x80);
+ }
+ }
+ USB_EndPointMask = 0x00010001;
+ USB_EndPointHalt = 0x00000000;
+ USB_EndPointStall = 0x00000000;
+ USB_Configure (FALSE);
+ }
+
+ if (USB_Configuration != SetupPacket.wValue.WB.L)
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Get Interface USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqGetInterface (void)
+{
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_INTERFACE:
+ if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces))
+ {
+ EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L;
+ }
+ else
+ {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * Set Interface USB Request
+ * Parameters: None (global SetupPacket)
+ * Return Value: TRUE - Success, FALSE - Error
+ */
+
+__inline uint32_t
+USB_ReqSetInterface (void)
+{
+ USB_COMMON_DESCRIPTOR *pD;
+ uint32_t ifn = 0, alt = 0, old = 0, msk = 0;
+ uint32_t n, m;
+ uint32_t set;
+
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_INTERFACE:
+ if (USB_Configuration == 0)
+ return (FALSE);
+ set = FALSE;
+ pD = (USB_COMMON_DESCRIPTOR *) USB_ConfigDescriptor;
+ while (pD->bLength)
+ {
+ switch (pD->bDescriptorType)
+ {
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ if (((USB_CONFIGURATION_DESCRIPTOR *) pD)->bConfigurationValue != USB_Configuration)
+ {
+ UsbAddPtr ((void **) &pD, ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength);
+ continue;
+ }
+ break;
+ case USB_INTERFACE_DESCRIPTOR_TYPE:
+ ifn = ((USB_INTERFACE_DESCRIPTOR *) pD)->bInterfaceNumber;
+ alt = ((USB_INTERFACE_DESCRIPTOR *) pD)->bAlternateSetting;
+ msk = 0;
+ if ((ifn == SetupPacket.wIndex.WB.L) && (alt == SetupPacket.wValue.WB.L))
+ {
+ set = TRUE;
+ old = USB_AltSetting[ifn];
+ USB_AltSetting[ifn] = (uint8_t) alt;
+ }
+ break;
+ case USB_ENDPOINT_DESCRIPTOR_TYPE:
+ if (ifn == SetupPacket.wIndex.WB.L)
+ {
+ n = ((USB_ENDPOINT_DESCRIPTOR *) pD)->bEndpointAddress & 0x8F;
+ m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
+ if (alt == SetupPacket.wValue.WB.L)
+ {
+ USB_EndPointMask |= m;
+ USB_EndPointHalt &= ~m;
+ USB_ConfigEP ((USB_ENDPOINT_DESCRIPTOR *) pD);
+ USB_EnableEP (n);
+ USB_ResetEP (n);
+ msk |= m;
+ }
+ else if ((alt == old) && ((msk & m) == 0))
+ {
+ USB_EndPointMask &= ~m;
+ USB_EndPointHalt &= ~m;
+ USB_DisableEP (n);
+ }
+ }
+ break;
+ }
+ UsbAddPtr ((void **) &pD, pD->bLength);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+
+ return (set);
+}
+
+
+/*
+ * USB Endpoint 0 Event Callback
+ * Parameters: event
+ * Return Value: none
+ */
+
+void
+USB_EndPoint0 (uint32_t event)
+{
+
+ switch (event)
+ {
+ case USB_EVT_SETUP:
+ USB_SetupStage ();
+ USB_DirCtrlEP (SetupPacket.bmRequestType.BM.Dir);
+ EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */
+ switch (SetupPacket.bmRequestType.BM.Type)
+ {
+
+ case REQUEST_STANDARD:
+ switch (SetupPacket.bRequest)
+ {
+ case USB_REQUEST_GET_STATUS:
+ if (!USB_ReqGetStatus ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_CLEAR_FEATURE:
+ if (!USB_ReqSetClrFeature (0))
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_FEATURE_EVENT
+ USB_Feature_Event ();
+#endif
+ break;
+
+ case USB_REQUEST_SET_FEATURE:
+ if (!USB_ReqSetClrFeature (1))
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_FEATURE_EVENT
+ USB_Feature_Event ();
+#endif
+ break;
+
+ case USB_REQUEST_SET_ADDRESS:
+ if (!USB_ReqSetAddress ())
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+ break;
+
+ case USB_REQUEST_GET_DESCRIPTOR:
+ if (!USB_ReqGetDescriptor ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_SET_DESCRIPTOR:
+ /*stall_o: */ USB_SetStallEP (0x00);
+ /* not supported */
+ EP0Data.Count = 0;
+ break;
+
+ case USB_REQUEST_GET_CONFIGURATION:
+ if (!USB_ReqGetConfiguration ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_SET_CONFIGURATION:
+ if (!USB_ReqSetConfiguration ())
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_CONFIGURE_EVENT
+ USB_Configure_Event ();
+#endif
+ break;
+
+ case USB_REQUEST_GET_INTERFACE:
+ if (!USB_ReqGetInterface ())
+ {
+ goto stall_i;
+ }
+ USB_DataInStage ();
+ break;
+
+ case USB_REQUEST_SET_INTERFACE:
+ if (!USB_ReqSetInterface ())
+ {
+ goto stall_i;
+ }
+ USB_StatusInStage ();
+#if USB_INTERFACE_EVENT
+ USB_Interface_Event ();
+#endif
+ break;
+
+ default:
+ goto stall_i;
+ }
+ break; /* end case REQUEST_STANDARD */
+
+#if USB_CLASS
+ case REQUEST_CLASS:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+
+ case REQUEST_TO_DEVICE:
+ goto stall_i; /* not supported */
+
+ case REQUEST_TO_INTERFACE:
+#if USB_HID
+ if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM)
+ { /* IF number correct? */
+ switch (SetupPacket.bRequest)
+ {
+ case HID_REQUEST_GET_REPORT:
+ if (HID_GetReport ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_SET_REPORT:
+ EP0Data.pData = EP0Buf; /* data to be received */
+ goto setup_class_ok;
+ case HID_REQUEST_GET_IDLE:
+ if (HID_GetIdle ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_SET_IDLE:
+ if (HID_SetIdle ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_GET_PROTOCOL:
+ if (HID_GetProtocol ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case HID_REQUEST_SET_PROTOCOL:
+ if (HID_SetProtocol ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_HID */
+#if USB_MSC
+ if (SetupPacket.wIndex.WB.L == USB_MSC_IF_NUM)
+ { /* IF number correct? */
+ switch (SetupPacket.bRequest)
+ {
+ case MSC_REQUEST_RESET:
+ if ((SetupPacket.wValue.W == 0) && /* RESET with invalid parameters -> STALL */
+ (SetupPacket.wLength == 0))
+ {
+ if (MSC_Reset ())
+ {
+ USB_StatusInStage ();
+ goto setup_class_ok;
+ }
+ }
+ break;
+ case MSC_REQUEST_GET_MAX_LUN:
+ if ((SetupPacket.wValue.W == 0) && /* GET_MAX_LUN with invalid parameters -> STALL */
+ (SetupPacket.wLength == 1))
+ {
+ if (MSC_GetMaxLUN ())
+ {
+ EP0Data.pData = EP0Buf;
+ USB_DataInStage ();
+ goto setup_class_ok;
+ }
+ }
+ break;
+ }
+ }
+#endif /* USB_MSC */
+#if USB_AUDIO
+ if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_GET_CUR:
+ case AUDIO_REQUEST_GET_MIN:
+ case AUDIO_REQUEST_GET_MAX:
+ case AUDIO_REQUEST_GET_RES:
+ if (ADC_IF_GetRequest ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ EP0Data.pData = EP0Buf; /* data to be received */
+ goto setup_class_ok;
+ }
+ }
+#endif /* USB_AUDIO */
+#if USB_CDC
+ if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case CDC_SEND_ENCAPSULATED_COMMAND:
+ EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */
+ goto setup_class_ok;
+ case CDC_GET_ENCAPSULATED_RESPONSE:
+ if (CDC_GetEncapsulatedResponse ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SET_COMM_FEATURE:
+ EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */
+ goto setup_class_ok;
+ case CDC_GET_COMM_FEATURE:
+ if (CDC_GetCommFeature (SetupPacket.wValue.W))
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_CLEAR_COMM_FEATURE:
+ if (CDC_ClearCommFeature (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SET_LINE_CODING:
+ EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */
+ goto setup_class_ok;
+ case CDC_GET_LINE_CODING:
+ if (CDC_GetLineCoding ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SET_CONTROL_LINE_STATE:
+ if (CDC_SetControlLineState (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ case CDC_SEND_BREAK:
+ if (CDC_SendBreak (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto setup_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_CDC */
+ goto stall_i; /* not supported */
+ /* end case REQUEST_TO_INTERFACE */
+
+ case REQUEST_TO_ENDPOINT:
+#if USB_AUDIO
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_GET_CUR:
+ case AUDIO_REQUEST_GET_MIN:
+ case AUDIO_REQUEST_GET_MAX:
+ case AUDIO_REQUEST_GET_RES:
+ if (ADC_EP_GetRequest ())
+ {
+ EP0Data.pData = EP0Buf; /* point to data to be sent */
+ USB_DataInStage (); /* send requested data */
+ goto setup_class_ok;
+ }
+ break;
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ EP0Data.pData = EP0Buf; /* data to be received */
+ goto setup_class_ok;
+ }
+#endif /* USB_AUDIO */
+ goto stall_i;
+ /* end case REQUEST_TO_ENDPOINT */
+
+ default:
+ goto stall_i;
+ }
+ setup_class_ok: /* request finished successfully */
+ break; /* end case REQUEST_CLASS */
+#endif /* USB_CLASS */
+
+#if USB_VENDOR
+ case REQUEST_VENDOR:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+
+ case REQUEST_TO_DEVICE:
+ if (!USB_ReqVendorDev (TRUE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_INTERFACE:
+ if (!USB_ReqVendorIF (TRUE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_ENDPOINT:
+ if (!USB_ReqVendorEP (TRUE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ default:
+ goto stall_i;
+ }
+
+ if (SetupPacket.wLength)
+ {
+ if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST)
+ {
+ USB_DataInStage ();
+ }
+ }
+ else
+ {
+ USB_StatusInStage ();
+ }
+
+ break; /* end case REQUEST_VENDOR */
+#endif /* USB_VENDOR */
+
+ default:
+ stall_i:USB_SetStallEP (0x80);
+ EP0Data.Count = 0;
+ break;
+ }
+ break; /* end case USB_EVT_SETUP */
+
+ case USB_EVT_OUT:
+ if (SetupPacket.bmRequestType.BM.Dir == REQUEST_HOST_TO_DEVICE)
+ {
+ if (EP0Data.Count)
+ { /* still data to receive ? */
+ USB_DataOutStage (); /* receive data */
+ if (EP0Data.Count == 0)
+ { /* data complete ? */
+ switch (SetupPacket.bmRequestType.BM.Type)
+ {
+
+ case REQUEST_STANDARD:
+ goto stall_i; /* not supported */
+
+#if (USB_CLASS)
+ case REQUEST_CLASS:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+ case REQUEST_TO_DEVICE:
+ goto stall_i; /* not supported */
+
+ case REQUEST_TO_INTERFACE:
+#if USB_HID
+ if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM)
+ { /* IF number correct? */
+ switch (SetupPacket.bRequest)
+ {
+ case HID_REQUEST_SET_REPORT:
+ if (HID_SetReport ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_HID */
+#if USB_AUDIO
+ if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ if (ADC_IF_SetRequest ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_AUDIO */
+#if USB_CDC
+ if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */
+ (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM))
+ {
+ switch (SetupPacket.bRequest)
+ {
+ case CDC_SEND_ENCAPSULATED_COMMAND:
+ if (CDC_SendEncapsulatedCommand ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ case CDC_SET_COMM_FEATURE:
+ if (CDC_SetCommFeature (SetupPacket.wValue.W))
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ case CDC_SET_LINE_CODING:
+ if (CDC_SetLineCoding ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+ }
+#endif /* USB_CDC */
+ goto stall_i;
+ /* end case REQUEST_TO_INTERFACE */
+
+ case REQUEST_TO_ENDPOINT:
+#if USB_AUDIO
+ switch (SetupPacket.bRequest)
+ {
+ case AUDIO_REQUEST_SET_CUR:
+// case AUDIO_REQUEST_SET_MIN:
+// case AUDIO_REQUEST_SET_MAX:
+// case AUDIO_REQUEST_SET_RES:
+ if (ADC_EP_SetRequest ())
+ {
+ USB_StatusInStage (); /* send Acknowledge */
+ goto out_class_ok;
+ }
+ break;
+ }
+#endif /* USB_AUDIO */
+ goto stall_i;
+ /* end case REQUEST_TO_ENDPOINT */
+
+ default:
+ goto stall_i;
+ }
+ out_class_ok: /* request finished successfully */
+ break; /* end case REQUEST_CLASS */
+#endif /* USB_CLASS */
+
+#if USB_VENDOR
+ case REQUEST_VENDOR:
+ switch (SetupPacket.bmRequestType.BM.Recipient)
+ {
+
+ case REQUEST_TO_DEVICE:
+ if (!USB_ReqVendorDev (FALSE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_INTERFACE:
+ if (!USB_ReqVendorIF (FALSE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ case REQUEST_TO_ENDPOINT:
+ if (!USB_ReqVendorEP (FALSE))
+ {
+ goto stall_i; /* not supported */
+ }
+ break;
+
+ default:
+ goto stall_i;
+ }
+
+ USB_StatusInStage ();
+
+ break; /* end case REQUEST_VENDOR */
+#endif /* USB_VENDOR */
+
+ default:
+ goto stall_i;
+ }
+ }
+ }
+ }
+ else
+ {
+ USB_StatusOutStage (); /* receive Acknowledge */
+ }
+ break; /* end case USB_EVT_OUT */
+
+ case USB_EVT_IN:
+ if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST)
+ {
+ USB_DataInStage (); /* send data */
+ }
+ else
+ {
+ if (USB_DeviceAddress & 0x80)
+ {
+ USB_DeviceAddress &= 0x7F;
+ USB_SetAddress (USB_DeviceAddress);
+ }
+ }
+ break; /* end case USB_EVT_IN */
+
+ case USB_EVT_OUT_STALL:
+ USB_ClrStallEP (0x00);
+ break;
+
+ case USB_EVT_IN_STALL:
+ USB_ClrStallEP (0x80);
+ break;
+
+ }
+}
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c b/openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c
new file mode 100644
index 0000000..9687921
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/usbhw.c
@@ -0,0 +1,630 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbhw.c
+ * Purpose: USB Hardware Layer Module for Philips LPC17xx
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added USB_ClearEPBuf
+ * V1.00 Initial Version
+ *----------------------------------------------------------------------------*/
+#include "LPC13xx.h" /* LPC13xx definitions */
+#include "usb.h"
+#include "usbcfg.h"
+#include "usbreg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "usbuser.h"
+
+
+/*
+ * USB and IO Clock configuration only.
+ * The same as call PeriClkIOInit(IOCON_USB);
+ * The purpose is to reduce the code space for
+ * overall USB project and reserve code space for
+ * USB debugging.
+ * Parameters: None
+ * Return Value: None
+ */
+void
+USBIOClkConfig (void)
+{
+ /* Enable AHB clock to the GPIO domain. */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6);
+
+ LPC_IOCON->PIO0_1 &= ~0x07;
+ LPC_IOCON->PIO0_1 |= 0x01; /* CLK OUT */
+
+ /* Enable AHB clock to the USB block. */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 14);
+ LPC_IOCON->PIO0_3 &= ~0x1F;
+ LPC_IOCON->PIO0_3 |= 0x01; /* Secondary function VBUS */
+ LPC_IOCON->PIO0_6 &= ~0x07;
+ LPC_IOCON->PIO0_6 |= 0x01; /* Secondary function SoftConn */
+ return;
+}
+
+/*
+ * Delay number of clock cycles
+ * Parameters: Delay length
+ * Return Value: None
+ */
+
+void
+delay (uint32_t length)
+{
+ uint32_t i;
+
+ for (i = 0; i < length; i++);
+ return;
+}
+
+/*
+ * Get Endpoint Physical Address
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: Endpoint Physical Address
+ */
+
+uint32_t
+EPAdr (uint32_t EPNum)
+{
+ uint32_t val;
+
+ val = (EPNum & 0x0F) << 1;
+ if (EPNum & 0x80)
+ {
+ val += 1;
+ }
+ return (val);
+}
+
+
+/*
+ * Write Command
+ * Parameters: cmd: Command
+ * Return Value: None
+ */
+
+void
+WrCmd (uint32_t cmd)
+{
+
+ LPC_USB->DevIntClr = CCEMTY_INT;
+ LPC_USB->CmdCode = cmd;
+ while ((LPC_USB->DevIntSt & (CCEMTY_INT | DEV_STAT_INT)) == 0);
+}
+
+
+/*
+ * Write Command Data
+ * Parameters: cmd: Command
+ * val: Data
+ * Return Value: None
+ */
+
+void
+WrCmdDat (uint32_t cmd, uint32_t val)
+{
+
+ WrCmd (cmd);
+ WrCmd (val);
+}
+
+
+/*
+ * Write Command to Endpoint
+ * Parameters: cmd: Command
+ * val: Data
+ * Return Value: None
+ */
+
+void
+WrCmdEP (uint32_t EPNum, uint32_t cmd)
+{
+
+ WrCmd (CMD_SEL_EP (EPAdr (EPNum)));
+ WrCmd (cmd);
+}
+
+
+/*
+ * Read Command Data
+ * Parameters: cmd: Command
+ * Return Value: Data Value
+ */
+
+uint32_t
+RdCmdDat (uint32_t cmd)
+{
+
+ LPC_USB->DevIntClr = CCEMTY_INT | CDFULL_INT;
+ LPC_USB->CmdCode = cmd;
+ while ((LPC_USB->DevIntSt & (CDFULL_INT | DEV_STAT_INT)) == 0);
+ return (LPC_USB->CmdData);
+}
+
+
+/*
+ * USB Initialize Function
+ * Called by the User to initialize USB
+ * Return Value: None
+ */
+
+void
+USB_Init (void)
+{
+
+#if USB_FIQ_EVENT
+ /* It's important that only BULK and FRAME(ISO) can be routed
+ to FIQ. */
+ LPC_USB->DevFIQSel = 0x01; /* SOF Use FIQ */
+
+ /* Enable the USB Interrupt */
+ NVIC_EnableIRQ (USB_FIQn);
+#endif
+
+ /* Enable the USB Interrupt */
+ NVIC_EnableIRQ (USB_IRQn);
+
+ USB_Reset ();
+ USB_SetAddress (0);
+ return;
+}
+
+
+/*
+ * USB Connect Function
+ * Called by the User to Connect/Disconnect USB
+ * Parameters: con: Connect/Disconnect
+ * Return Value: None
+ */
+
+void
+USB_Connect (uint32_t con)
+{
+ WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (con ? DEV_CON : 0));
+}
+
+
+/*
+ * USB Reset Function
+ * Called automatically on USB Reset
+ * Return Value: None
+ */
+
+void
+USB_Reset (void)
+{
+
+ LPC_USB->DevIntClr = 0x000FFFFF;
+ /* Enable all eight(8) EPs, note: EP won't be ready until it's
+ configured/enabled when device sending SetEPStatus command
+ to the command engine. */
+ LPC_USB->DevIntEn = DEV_STAT_INT | (0xFF << 1) | (USB_SOF_EVENT ? FRAME_INT : 0);
+ return;
+}
+
+
+/*
+ * USB Suspend Function
+ * Called automatically on USB Suspend
+ * Return Value: None
+ */
+
+void
+USB_Suspend (void)
+{
+ /* Performed by Hardware */
+}
+
+
+/*
+ * USB Resume Function
+ * Called automatically on USB Resume
+ * Return Value: None
+ */
+
+void
+USB_Resume (void)
+{
+ /* Performed by Hardware */
+}
+
+
+/*
+ * USB Remote Wakeup Function
+ * Called automatically on USB Remote Wakeup
+ * Return Value: None
+ */
+
+void
+USB_WakeUp (void)
+{
+ if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP)
+ {
+ WrCmdDat (CMD_SET_DEV_STAT, DAT_WR_BYTE (DEV_CON));
+ }
+}
+
+
+/*
+ * USB Remote Wakeup Configuration Function
+ * Parameters: cfg: Enable/Disable
+ * Return Value: None
+ */
+
+void
+USB_WakeUpCfg (uint32_t cfg)
+{
+ cfg = cfg; /* Not needed */
+}
+
+
+/*
+ * USB Set Address Function
+ * Parameters: adr: USB Address
+ * Return Value: None
+ */
+
+void
+USB_SetAddress (uint32_t adr)
+{
+ WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Don't wait for next */
+ WrCmdDat (CMD_SET_ADDR, DAT_WR_BYTE (DEV_EN | adr)); /* Setup Status Phase */
+}
+
+
+/*
+ * USB Configure Function
+ * Parameters: cfg: Configure/Deconfigure
+ * Return Value: None
+ */
+
+void
+USB_Configure (uint32_t cfg)
+{
+ WrCmdDat (CMD_CFG_DEV, DAT_WR_BYTE (cfg ? CONF_DVICE : 0));
+ return;
+}
+
+
+/*
+ * Configure USB Endpoint according to Descriptor
+ * Parameters: pEPD: Pointer to Endpoint Descriptor
+ * Return Value: None
+ */
+
+void
+USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD)
+{
+ (void)pEPD;
+}
+
+
+/*
+ * Set Direction for USB Control Endpoint
+ * Parameters: dir: Out (dir == 0), In (dir <> 0)
+ * Return Value: None
+ */
+
+void
+USB_DirCtrlEP (uint32_t dir)
+{
+ (void)dir;
+}
+
+
+/*
+ * Enable USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_EnableEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0));
+}
+
+
+/*
+ * Disable USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_DisableEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_DA));
+}
+
+
+/*
+ * Reset USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_ResetEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0));
+}
+
+
+/*
+ * Set Stall for USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_SetStallEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (EP_STAT_ST));
+}
+
+
+/*
+ * Clear Stall for USB Endpoint
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_ClrStallEP (uint32_t EPNum)
+{
+ WrCmdDat (CMD_SET_EP_STAT (EPAdr (EPNum)), DAT_WR_BYTE (0));
+}
+
+
+/*
+ * Clear USB Endpoint Buffer
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * Return Value: None
+ */
+
+void
+USB_ClearEPBuf (uint32_t EPNum)
+{
+ WrCmdEP (EPNum, CMD_CLR_BUF);
+}
+
+
+/*
+ * Read USB Endpoint Data
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * pData: Pointer to Data Buffer
+ * Return Value: Number of bytes read
+ */
+
+uint32_t
+USB_ReadEP (uint32_t EPNum, uint8_t * pData)
+{
+ uint32_t cnt, n;
+
+ LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN;
+ /* 3 clock cycles to fetch the packet length from RAM. */
+ delay (5);
+
+ do
+ {
+ cnt = LPC_USB->RxPLen;
+ }
+ while ((cnt & PKT_DV) == 0);
+ cnt &= PKT_LNGTH_MASK;
+
+ for (n = 0; n < (cnt + 3) / 4; n++)
+ {
+ *((uint32_t __attribute__ ((packed)) *) pData) = LPC_USB->RxData;
+ pData += 4;
+ }
+
+ LPC_USB->Ctrl = 0;
+
+ if ((EPNum & 0x80) != 0x04)
+ { /* Non-Isochronous Endpoint */
+ WrCmdEP (EPNum, CMD_CLR_BUF);
+ }
+
+ return (cnt);
+}
+
+
+/*
+ * Write USB Endpoint Data
+ * Parameters: EPNum: Endpoint Number
+ * EPNum.0..3: Address
+ * EPNum.7: Dir
+ * pData: Pointer to Data Buffer
+ * cnt: Number of bytes to write
+ * Return Value: Number of bytes written
+ */
+
+uint32_t
+USB_WriteEP (uint32_t EPNum, uint8_t * pData, uint32_t cnt)
+{
+ uint32_t n;
+
+ LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
+ /* 3 clock cycles to fetch the packet length from RAM. */
+ delay (5);
+ LPC_USB->TxPLen = cnt;
+
+ for (n = 0; n < (cnt + 3) / 4; n++)
+ {
+ LPC_USB->TxData = *((uint32_t __attribute__ ((packed)) *) pData);
+ pData += 4;
+ }
+
+ LPC_USB->Ctrl = 0;
+
+ WrCmdEP (EPNum, CMD_VALID_BUF);
+
+ return (cnt);
+}
+
+/*
+ * Get USB Last Frame Number
+ * Parameters: None
+ * Return Value: Frame Number
+ */
+
+uint32_t
+USB_GetFrame (void)
+{
+ uint32_t val;
+
+ WrCmd (CMD_RD_FRAME);
+ val = RdCmdDat (DAT_RD_FRAME);
+ val = val | (RdCmdDat (DAT_RD_FRAME) << 8);
+
+ return (val);
+}
+
+
+/*
+ * USB Interrupt Service Routine
+ */
+
+void
+USB_IRQHandler (void)
+{
+ uint32_t disr, val, n, m;
+
+ disr = LPC_USB->DevIntSt; /* Device Interrupt Status */
+ LPC_USB->DevIntClr = disr;
+
+ /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
+ if (disr & DEV_STAT_INT)
+ {
+ WrCmd (CMD_GET_DEV_STAT);
+ val = RdCmdDat (DAT_GET_DEV_STAT); /* Device Status */
+ if (val & DEV_RST)
+ { /* Reset */
+ USB_Reset ();
+#if USB_RESET_EVENT
+ USB_Reset_Event ();
+#endif
+ }
+ if (val & DEV_CON_CH)
+ { /* Connect change */
+#if USB_POWER_EVENT
+ USB_Power_Event (val & DEV_CON);
+#endif
+ }
+ if (val & DEV_SUS_CH)
+ { /* Suspend/Resume */
+ if (val & DEV_SUS)
+ { /* Suspend */
+ USB_Suspend ();
+#if USB_SUSPEND_EVENT
+ USB_Suspend_Event ();
+#endif
+ }
+ else
+ { /* Resume */
+ USB_Resume ();
+#if USB_RESUME_EVENT
+ USB_Resume_Event ();
+#endif
+ }
+ }
+ goto isr_end;
+ }
+
+#if USB_SOF_EVENT
+ /* Start of Frame Interrupt */
+ if (disr & FRAME_INT)
+ {
+ LPC_USB->DevIntClr = FRAME_INT;
+ USB_SOF_Event ();
+ SOFIRQCount++;
+ }
+#endif
+
+#if USB_ERROR_EVENT
+ /* NO error interrupt anymore, below code can be used
+ as example to get error status from command engine. */
+ /* Error Interrupt */
+ if (disr & ERR_INT)
+ {
+ WrCmd (CMD_RD_ERR_STAT);
+ val = RdCmdDat (DAT_RD_ERR_STAT);
+ USB_Error_Event (val);
+ }
+#endif
+
+ /* Endpoint's Interrupt */
+ if (disr & (0xFF << 1))
+ {
+ /* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */
+ for (n = 0; n < USB_EP_NUM; n++)
+ { /* Check All Endpoints */
+ /* skip frame interrupt at bit 0 in disr */
+// if (disr & ((1 << n)<<1)) {
+ if ((disr >> 1) & (1 << n))
+ {
+ m = n >> 1;
+ /* clear EP interrupt by sending cmd to the command engine. */
+ WrCmd (CMD_SEL_EP_CLRI (n));
+ val = RdCmdDat (DAT_SEL_EP_CLRI (n));
+ if ((n & 1) == 0)
+ { /* OUT Endpoint */
+ if (n == 0)
+ { /* Control OUT Endpoint */
+ if (val & EP_SEL_STP)
+ { /* Setup Packet */
+ if (USB_P_EP[0])
+ {
+ USB_P_EP[0] (USB_EVT_SETUP);
+ continue;
+ }
+ }
+ }
+ if (USB_P_EP[m])
+ {
+ USB_P_EP[m] (USB_EVT_OUT);
+ }
+ }
+ else
+ { /* IN Endpoint */
+ if (USB_P_EP[m])
+ {
+ USB_P_EP[m] (USB_EVT_IN);
+ }
+ }
+ }
+ }
+ }
+isr_end:
+ return;
+}
diff --git a/openbeacon/lpc13xx/usbcdc-storage/src/usbuser.c b/openbeacon/lpc13xx/usbcdc-storage/src/usbuser.c
new file mode 100644
index 0000000..370f088
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc-storage/src/usbuser.c
@@ -0,0 +1,242 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbuser.c
+ * Purpose: USB Custom User Module
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+#include "type.h"
+
+#include "usb.h"
+#include "usbcfg.h"
+#include "usbhw.h"
+#include "usbcore.h"
+#include "usbuser.h"
+#include "cdcuser.h"
+#include "mscuser.h"
+#include "memory.h"
+
+
+/*
+ * USB Power Event Callback
+ * Called automatically on USB Power Event
+ * Parameter: power: On(TRUE)/Off(FALSE)
+ */
+
+#if USB_POWER_EVENT
+void
+USB_Power_Event (uint32_t power)
+{
+}
+#endif
+
+
+/*
+ * USB Reset Event Callback
+ * Called automatically on USB Reset Event
+ */
+
+#if USB_RESET_EVENT
+void
+USB_Reset_Event (void)
+{
+ USB_ResetCore ();
+}
+#endif
+
+
+/*
+ * USB Suspend Event Callback
+ * Called automatically on USB Suspend Event
+ */
+
+#if USB_SUSPEND_EVENT
+void
+USB_Suspend_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Resume Event Callback
+ * Called automatically on USB Resume Event
+ */
+
+#if USB_RESUME_EVENT
+void
+USB_Resume_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Remote Wakeup Event Callback
+ * Called automatically on USB Remote Wakeup Event
+ */
+
+#if USB_WAKEUP_EVENT
+void
+USB_WakeUp_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Start of Frame Event Callback
+ * Called automatically on USB Start of Frame Event
+ */
+
+#if USB_SOF_EVENT
+void
+USB_SOF_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Error Event Callback
+ * Called automatically on USB Error Event
+ * Parameter: error: Error Code
+ */
+
+#if USB_ERROR_EVENT
+void
+USB_Error_Event (uint32_t error)
+{
+}
+#endif
+
+
+/*
+ * USB Set Configuration Event Callback
+ * Called automatically on USB Set Configuration Request
+ */
+
+#if USB_CONFIGURE_EVENT
+void
+USB_Configure_Event (void)
+{
+
+ if (USB_Configuration)
+ { /* Check if USB is configured */
+ /* add your code here */
+ }
+}
+#endif
+
+
+/*
+ * USB Set Interface Event Callback
+ * Called automatically on USB Set Interface Request
+ */
+
+#if USB_INTERFACE_EVENT
+void
+USB_Interface_Event (void)
+{
+}
+#endif
+
+
+/*
+ * USB Set/Clear Feature Event Callback
+ * Called automatically on USB Set/Clear Feature Request
+ */
+
+#if USB_FEATURE_EVENT
+void
+USB_Feature_Event (void)
+{
+}
+#endif
+
+
+#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL)
+
+/* USB Endpoint Events Callback Pointers */
+void (*const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) =
+{
+P_EP (0), P_EP (1), P_EP (2), P_EP (3), P_EP (4),};
+
+
+/*
+ * USB Endpoint 1 Event Callback
+ * Called automatically on USB Endpoint 1 Event
+ * Parameter: event
+ */
+
+void
+USB_EndPoint1 (uint32_t event)
+{
+ uint16_t temp;
+ static uint16_t serialState;
+
+ switch (event)
+ {
+ case USB_EVT_IN:
+ temp = CDC_GetSerialState ();
+ if (serialState != temp)
+ {
+ serialState = temp;
+ CDC_NotificationIn (); /* send SERIAL_STATE notification */
+ }
+ break;
+ }
+}
+
+
+/*
+ * USB Endpoint 2 Event Callback
+ * Called automatically on USB Endpoint 2 Event
+ * Parameter: event
+ */
+
+void
+USB_EndPoint2 (uint32_t event)
+{
+
+ switch (event)
+ {
+ case USB_EVT_OUT:
+ MSC_BulkOut ();
+ break;
+ case USB_EVT_IN:
+ MSC_BulkIn ();
+ break;
+ }
+}
+
+
+/*
+ * USB Endpoint 3 Event Callback
+ * Called automatically on USB Endpoint 3 Event
+ * Parameter: event
+ */
+
+void
+USB_EndPoint3 (uint32_t event)
+{
+ switch (event)
+ {
+ case USB_EVT_OUT:
+ CDC_BulkOut (); /* data received from Host */
+ break;
+ case USB_EVT_IN:
+ CDC_BulkIn (); /* data expected from Host */
+ break;
+ }
+}
diff --git a/openbeacon/lpc13xx/usbcdc/Makefile b/openbeacon/lpc13xx/usbcdc/Makefile
new file mode 100644
index 0000000..20e0a1a
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc/Makefile
@@ -0,0 +1,20 @@
+TARGET=usbcdc
+ARCH=LPC13
+CPU=$(ARCH)42
+DEBUG=-g
+OPTIM=-Os -mword-relocations
+
+APP_CFLAGS=-Iinc -std=gnu99 -fgnu89-inline -D__USE_CMSIS
+APP_LDFLAGS=-lm
+
+APP_SRC= \
+ src/main.c \
+
+APP_SRC+=$(IMAGES_C)
+
+all: $(TARGET).bin
+
+app_clean:
+ find src -name '*.o' -exec rm \{\} \;
+
+include ../core/Makefile.rules
diff --git a/openbeacon/lpc13xx/usbcdc/inc/FreeRTOSConfig.h b/openbeacon/lpc13xx/usbcdc/inc/FreeRTOSConfig.h
new file mode 100644
index 0000000..ef4ba7f
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc/inc/FreeRTOSConfig.h
@@ -0,0 +1,104 @@
+/*
+ FreeRTOS V6.0.0 - Copyright (C) 2009 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.
+
+ 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.
+*/
+
+
+/******************************************************************************
+ See http://www.freertos.org/a00110.html for an explanation of the
+ definitions contained in this file.
+******************************************************************************/
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include "LPC13xx.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 0
+#define configCPU_CLOCK_HZ ( ( unsigned long ) SystemCoreClock )
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 100 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) )
+#define configMAX_TASK_NAME_LEN ( 12 )
+#define configUSE_TRACE_FACILITY 0
+#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 1
+#define configUSE_ALTERNATIVE_API 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configQUEUE_REGISTRY_SIZE 0
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+
+/* 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 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) )
+
+#endif /* FREERTOS_CONFIG_H */
+
diff --git a/openbeacon/lpc13xx/usbcdc/inc/config.h b/openbeacon/lpc13xx/usbcdc/inc/config.h
new file mode 100644
index 0000000..3d76055
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc/inc/config.h
@@ -0,0 +1,43 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - config file
+ *
+ * Copyright 2010 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define LED_PORT 1 /* Port for led */
+#define LED_BIT 9 /* Bit on port for led */
+#define LED_ON 1 /* Level to set port to turn on led */
+#define LED_OFF 0 /* Level to set port to turn off led */
+
+/* USB device settings */
+#define ENALBLE_USB_FULLFEATURED
+#define USB_VENDOR_ID 0x2366
+#define USB_PROD_ID 0x0003
+#define USB_DEVICE 0x0100
+
+/* FreeRTOS configuration */
+#define ENABLE_FREERTOS
+#define TASK_SERIAL_STACK_SIZE 64
+#define TASK_SERIAL_PRIORITY (tskIDLE_PRIORITY + 2)
+
+#endif/*__CONFIG_H__*/
diff --git a/openbeacon/lpc13xx/usbcdc/inc/usbcfg.h b/openbeacon/lpc13xx/usbcdc/inc/usbcfg.h
new file mode 100644
index 0000000..8fef7c2
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc/inc/usbcfg.h
@@ -0,0 +1,157 @@
+/*----------------------------------------------------------------------------
+ * U S B - K e r n e l
+ *----------------------------------------------------------------------------
+ * Name: usbcfg.h
+ * Purpose: USB Custom Configuration
+ * Version: V1.20
+ *----------------------------------------------------------------------------
+ * This software is supplied "AS IS" without any warranties, express,
+ * implied or statutory, including but not limited to the implied
+ * warranties of fitness for purpose, satisfactory quality and
+ * noninfringement. Keil extends you a royalty-free right to reproduce
+ * and distribute executable files created using this software for use
+ * on NXP Semiconductors LPC microcontroller devices only. Nothing else
+ * gives you the right to use this software.
+ *
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
+ *----------------------------------------------------------------------------
+ * History:
+ * V1.20 Added vendor specific support
+ * V1.00 Initial Version
+ *---------------------------------------------------------------------------*/
+
+#ifndef __USBCFG_H__
+#define __USBCFG_H__
+
+
+//*** <<< Use Configuration Wizard in Context Menu >>> ***
+
+
+/*
+// USB Configuration
+// USB Power
+// Default Power Setting
+// <0=> Bus-powered
+// <1=> Self-powered
+// Max Number of Interfaces <1-256>
+// Max Number of Endpoints <1-32>
+// Max Endpoint 0 Packet Size
+// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
+// DMA Transfer
+// Use DMA for selected Endpoints
+// Endpoint 0 Out
+// Endpoint 0 In
+// Endpoint 1 Out
+// Endpoint 1 In
+// Endpoint 2 Out
+// Endpoint 2 In
+// Endpoint 3 Out
+// Endpoint 3 In
+// Endpoint 4 Out
+// Endpoint 4 In
+//
+//
+*/
+
+#define USB_POWER 0
+#define USB_IF_NUM 1
+#define USB_LOGIC_EP_NUM 5
+#define USB_EP_NUM 10
+#define USB_MAX_PACKET0 64
+
+/*
+// USB Event Handlers
+// Device Events
+// Power Event
+// Reset Event
+// Suspend Event
+// Resume Event
+// Remote Wakeup Event
+// Start of Frame Event
+// Error Event
+//
+// Endpoint Events
+// Endpoint 0 Event
+// Endpoint 1 Event
+// Endpoint 2 Event
+// Endpoint 3 Event
+// Endpoint 4 Event
+// Endpoint 5 Event
+// Endpoint 6 Event
+// Endpoint 7 Event
+// Endpoint 8 Event
+// Endpoint 9 Event
+// Endpoint 10 Event
+// Endpoint 11 Event
+// Endpoint 12 Event
+// Endpoint 13 Event
+// Endpoint 14 Event
+// Endpoint 15 Event
+//
+// USB Core Events
+// Set Configuration Event
+// Set Interface Event
+// Set/Clear Feature Event
+//
+//
+*/
+
+#define USB_POWER_EVENT 0
+#define USB_RESET_EVENT 1
+#define USB_SUSPEND_EVENT 1
+#define USB_RESUME_EVENT 1
+#define USB_WAKEUP_EVENT 0
+#define USB_SOF_EVENT 0
+#define USB_ERROR_EVENT 0
+#define USB_EP_EVENT 0x000B
+#define USB_CONFIGURE_EVENT 1
+#define USB_INTERFACE_EVENT 0
+#define USB_FEATURE_EVENT 0
+
+
+/*
+// USB Class Support
+// enables USB Class specific Requests
+// Human Interface Device (HID)
+// Interface Number <0-255>
+//
+// Mass Storage
+// Interface Number <0-255>
+//
+// Audio Device
+// Control Interface Number <0-255>
+// Streaming Interface 1 Number <0-255>
+// Streaming Interface 2 Number <0-255>
+//
+// Communication Device
+// Control Interface Number <0-255>
+// Bulk Interface Number <0-255>
+// Max Communication Device Buffer Size
+// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
+//
+//
+*/
+
+#define USB_CLASS 1
+#define USB_HID 0
+#define USB_HID_IF_NUM 0
+#define USB_MSC 0
+#define USB_MSC_IF_NUM 0
+#define USB_AUDIO 0
+#define USB_ADC_CIF_NUM 0
+#define USB_ADC_SIF1_NUM 1
+#define USB_ADC_SIF2_NUM 2
+#define USB_CDC 1
+#define USB_CDC_CIF_NUM 0
+#define USB_CDC_DIF_NUM 1
+#define USB_CDC_BUFSIZE 64
+
+/*
+// USB Vendor Support
+// enables USB Vendor specific Requests
+//
+*/
+#define USB_VENDOR 0
+
+
+#endif /* __USBCFG_H__ */
diff --git a/openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf b/openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf
new file mode 100644
index 0000000..f1f919f
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc/lpc134x-vcom.inf
@@ -0,0 +1,65 @@
+;
+; Keil - An ARM Company Comunication Device Class driver installation file
+; (C)2007 Copyright
+;
+
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%Keil%
+;LayoutFile=layout.inf
+DriverVer=01/06/07
+
+[Manufacturer]
+%Keil%=DeviceList
+
+[DestinationDirs]
+DefaultDestDir=12
+
+[SourceDisksFiles]
+
+[SourceDisksNames]
+
+[DeviceList]
+%DESCRIPTION%=LPC134xUSB, USB\VID_1FC9&PID_0003
+
+;------------------------------------------------------------------------------
+; Windows 2000/XP Sections
+;------------------------------------------------------------------------------
+
+[LPC134xUSB.nt]
+include=mdmcpq.inf
+CopyFiles=DriverCopyFiles
+AddReg=LPC134xUSB.nt.AddReg
+
+[DriverCopyFiles]
+usbser.sys,,,0x20
+
+[LPC134xUSB.nt.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[LPC134xUSB.nt.Services]
+include=mdmcpq.inf
+AddService=usbser, 0x00000002, DriverService
+
+
+[LPC134xUSB.nt.HW]
+include=mdmcpq.inf
+
+[DriverService]
+DisplayName=%DESCRIPTION%
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\usbser.sys
+
+;------------------------------------------------------------------------------
+; String Definitions
+;------------------------------------------------------------------------------
+
+[Strings]
+NXP="NXP - Founded by Philips"
+DESCRIPTION="LPC134x USB VCom Port"
diff --git a/openbeacon/lpc13xx/usbcdc/readme.txt b/openbeacon/lpc13xx/usbcdc/readme.txt
new file mode 100644
index 0000000..37aa02c
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc/readme.txt
@@ -0,0 +1,36 @@
+usbcdc
+=====================
+This project contains an CDC USB example for the LPCXpresso board
+mounted with an LPC1343 Cortex-M3 part.
+
+To run this example, you must attach a USB cable to the board. See
+the "Getting Started Guide" appendix for details. You may also
+connect the LPCXpresso board to a base board from a 3rd party tool
+partner.
+
+When downloaded to the board and executed, the PC will recognize
+a USB "VCOM" device. Point windows to the .inf file in the usbcdc
+project directory. Windows should install the default UART driver.
+At this point, you should be able to send characters into the USB
+virtual COM port and have them transmitted out of the serial port
+on the LPC1343. The transmit baud rate will equal the CDC port
+configured baud rate.
+
+One thing we have seen that can cause trouble with the USB examples
+is the Windows driver install. Since the example projects all use
+the same USB Vendor ID and Product ID, if you try out the HID
+example and then try out the CDC example, Windows may try
+to use the HID driver it had already installed with the CDC
+example code. To fix this, go to the Windows Device Manager,
+find the broken "HID" device and select "Uninstall." Then unplug the
+device and plug it back in. Windows should correctly identify the
+device as being a CDC device and install the correct
+driver.
+
+The project makes use of code from the following library projects:
+- CMSISv1p30_LPC13xx : for CMSIS 1.30 files relevant to LPC13xx
+
+This library project must exist in the same workspace in order
+for the project to successfully build.
+
+For more details, read the comments in config.h
diff --git a/openbeacon/lpc13xx/usbcdc/src/main.c b/openbeacon/lpc13xx/usbcdc/src/main.c
new file mode 100644
index 0000000..5956b1f
--- /dev/null
+++ b/openbeacon/lpc13xx/usbcdc/src/main.c
@@ -0,0 +1,102 @@
+/***************************************************************
+ *
+ * OpenBeacon.org - USB CDC + FreeRTOS Pipes Demo
+ *
+ * Copyright 2011 Milosch Meriac
+ *
+ ***************************************************************
+
+ 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+#include
+
+static BOOL vTasksRunning = FALSE;
+
+/*
+ * overwrite default_putchar with USB CDC ACM
+ * output to enable USB support for debug_printf
+ */
+BOOL default_putchar(uint8_t data)
+{
+ if (vTasksRunning)
+ CDC_PutChar (data);
+ /* always send out over serial port as well */
+ UARTSendChar (data);
+
+ return TRUE;
+}
+
+static void serial_task(void *handle)
+{
+ int i;
+ (void) handle;
+ portCHAR data;
+
+ vTasksRunning = TRUE;
+
+ i = 0;
+ for (;;)
+ {
+ debug_printf("%04i: Hello Task! (%04i bytes free heap memory)\n", i++,
+ xPortGetFreeHeapSize());
+
+ GPIOSetValue(LED_PORT, LED_BIT, LED_ON);
+ vTaskDelay(10 / portTICK_RATE_MS);
+ GPIOSetValue(LED_PORT, LED_BIT, LED_OFF);
+
+ while (CDC_Recv(&data, sizeof(data), 990))
+ UARTSendChar(data);
+ }
+}
+
+int main(void)
+{
+ /* Enable CT32B1 Timer, IOCON, and USB */
+ LPC_SYSCON->SYSAHBCLKCTRL |= (EN_CT32B1 | EN_USB_REG | EN_IOCON);
+
+ /* Initialize GPIO */
+ GPIOInit();
+ /* Set LED port pin to output */
+ GPIOSetDir(LED_PORT, LED_BIT, 1);
+ GPIOSetValue(LED_PORT, LED_BIT, 0);
+
+ /* CDC Initialization */
+ CDC_Init();
+ /* USB Initialization */
+ USB_Init();
+ /* Connect to USB port */
+ USB_Connect(1);
+
+ /* Update System Core Clock Value */
+ SystemCoreClockUpdate();
+
+ /* NVIC is installed inside UARTInit file. */
+ UARTInit(115200, 0);
+
+ /* the following text is printed on the serial port as vTasksRunning
+ * is not yet set to TRUE in serial_task - which will redirect
+ * debug output to the CDC ACM USB serial device.
+ */
+ debug_printf("Hello World!\n");
+
+ /* Create CDC ACM task */
+ xTaskCreate(serial_task, (const signed char*) "Serial", TASK_SERIAL_STACK_SIZE, NULL, TASK_SERIAL_PRIORITY, NULL);
+
+ /* Start the tasks running. */
+ vTaskStartScheduler();
+
+ return 0;
+}