added code from openbeacon.org

This commit is contained in:
schneider 2011-06-12 04:18:11 +02:00
parent 51e7d5bbd1
commit 58ff370dd6
174 changed files with 35448 additions and 0 deletions

11
openbeacon/lpc13xx/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
*.o
*.asm
*.bin
*.elf
*.map
*~
.cproject
.project
.settings
Default
ignore

View File

@ -0,0 +1,94 @@
CROSS=arm-none-eabi-
CC=$(CROSS)gcc
LD=$(CROSS)ld
OBJCOPY=$(CROSS)objcopy
OBJDUMP=$(CROSS)objdump
AR=$(CROSS)ar
LDSCRIPT=$(CORE)linker/$(CPU).ld
CORE=../core/
#
# CFLAGS common to both the THUMB and ARM mode builds
#
CFLAGS= \
-D __$(CPU)__ \
-D __$(ARCH)xx__ \
-Iconfig \
-I$(CORE)cmsis/inc \
-I$(CORE)openbeacon/inc \
-I$(CORE)peripherals/inc \
-I$(CORE)peripherals/inc/usb \
-I$(CORE)freertos/inc \
-Wall \
-Werror \
-Wextra \
-Wno-multichar \
-Wstrict-prototypes \
-Wno-strict-aliasing \
-D CORTEXM3_GCC \
-mcpu=cortex-m3 \
-msoft-float \
-mthumb \
-fno-common \
-T$(LDSCRIPT) \
$(DEBUG) \
$(OPTIM) \
-fomit-frame-pointer \
-ffunction-sections \
-fdata-sections \
$(APP_CFLAGS)
LINKER_FLAGS=$(APP_LDFLAGS) -Xlinker --gc-sections -Xlinker -o$(TARGET).elf -Xlinker -M -Xlinker -Map=$(TARGET).map
ARM_SRC= \
$(APP_SRC) \
$(CORE)cmsis/src/core_cm3.c \
$(CORE)cmsis/src/system_$(ARCH)xx.c \
$(CORE)startup/$(ARCH)xx.c \
$(CORE)peripherals/src/uart.c \
$(CORE)peripherals/src/gpio.c \
$(CORE)peripherals/src/usb/cdcusbdesc.c \
$(CORE)peripherals/src/usb/cdcuser.c \
$(CORE)peripherals/src/usb/usbcore.c \
$(CORE)peripherals/src/usb/usbhw.c \
$(CORE)peripherals/src/usb/usbuser.c \
$(CORE)freertos/src/heap_2.c \
$(CORE)freertos/src/list.c \
$(CORE)freertos/src/port.c \
$(CORE)freertos/src/queue.c \
$(CORE)freertos/src/tasks.c \
$(CORE)openbeacon/src/msd.c \
$(CORE)openbeacon/src/vfs.c \
$(CORE)openbeacon/src/hid.c \
$(CORE)openbeacon/src/spi.c \
$(CORE)openbeacon/src/iap.c \
$(CORE)openbeacon/src/crc16.c \
$(CORE)openbeacon/src/xxtea.c \
$(CORE)openbeacon/src/debug_printf.c
#
# Define all object files.
#
ARM_OBJ = $(ARM_SRC:.c=.o)
APP_ADDITIONAL?=
$(TARGET).bin : $(TARGET).elf
$(OBJCOPY) $(TARGET).elf -O binary $(TARGET).bin
$(TARGET).hex : $(TARGET).elf
$(OBJCOPY) $(TARGET).elf -O ihex $(TARGET).hex
$(TARGET).elf : $(ARM_OBJ) $(CRT0) $(BOOTLOADER) $(APP_ADDITIONAL) Makefile
$(CC) $(CFLAGS) $(ARM_OBJ) $(BOOTLOADER) $(APP_ADDITIONAL) -nostartfiles $(CRT0) $(LINKER_FLAGS)
$(OBJDUMP) -d $(TARGET).elf > $(TARGET).asm
$(ARM_OBJ) : %.o : %.c $(LDSCRIPT) Makefile
$(CC) -c $(CFLAGS) $< -o $@
flash : $(TARGET).bin
../lpc-flash/src/lpc-flash $(TARGET).bin /media/CRP\ DISABLD/firmware.bin
clean : app_clean
find $(CORE) -name '*.o' -exec rm \{\} \;
rm -f $(TARGET).bin $(TARGET).elf $(TARGET).map $(TARGET).asm

View File

@ -0,0 +1,28 @@
CMSIS : Cortex Microcontroller Software Interface Standard
==========================================================
CMSIS defines for a Cortex-M Microcontroller System:
* A common way to access peripheral registers and a
common way to define exception vectors.
* The register names of the Core Peripherals and the
names of the Core Exception Vectors.
* An device independent interface for RTOS Kernels
including a debug channel.
By using CMSIS compliant software components, the user can
easier re-use template code. CMSIS is intended to enable the
combination of software components from multiple middleware
vendors.
This project contains appropriate files for this MCU family
taken from CMSIS. A full copy of the CMSIS files can be found
within your tools installation directory. More information on
CMSIS can be found at:
http://www.onarm.com/
http://www.arm.com/

View File

@ -0,0 +1,320 @@
<html>
<head>
<title>CMSIS Changes</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<style>
<!--
/*-----------------------------------------------------------
Keil Software CHM Style Sheet
-----------------------------------------------------------*/
body { color: #000000; background-color: #FFFFFF; font-size: 75%; font-family:
Verdana, Arial, 'Sans Serif' }
a:link { color: #0000FF; text-decoration: underline }
a:visited { color: #0000FF; text-decoration: underline }
a:active { color: #FF0000; text-decoration: underline }
a:hover { color: #FF0000; text-decoration: underline }
h1 { font-family: Verdana; font-size: 18pt; color: #000080; font-weight: bold;
text-align: Center; margin-right: 3 }
h2 { font-family: Verdana; font-size: 14pt; color: #000080; font-weight: bold;
background-color: #CCCCCC; margin-top: 24; margin-bottom: 3;
padding: 6 }
h3 { font-family: Verdana; font-size: 10pt; font-weight: bold; background-color:
#CCCCCC; margin-top: 24; margin-bottom: 3; padding: 6 }
pre { font-family: Courier New; font-size: 10pt; background-color: #CCFFCC;
margin-left: 24; margin-right: 24 }
ul { list-style-type: square; margin-top: 6pt; margin-bottom: 0 }
ol { margin-top: 6pt; margin-bottom: 0 }
li { clear: both; margin-bottom: 6pt }
table { font-size: 100%; border-width: 0; padding: 0 }
th { color: #FFFFFF; background-color: #000080; text-align: left; vertical-align:
bottom; padding-right: 6pt }
tr { text-align: left; vertical-align: top }
td { text-align: left; vertical-align: top; padding-right: 6pt }
.ToolT { font-size: 8pt; color: #808080 }
.TinyT { font-size: 8pt; text-align: Center }
code { color: #000000; background-color: #E0E0E0; font-family: 'Courier New', Courier;
line-height: 120%; font-style: normal }
/*-----------------------------------------------------------
Notes
-----------------------------------------------------------*/
p.note { font-weight: bold; clear: both; margin-bottom: 3pt; padding-top: 6pt }
/*-----------------------------------------------------------
Expanding/Contracting Divisions
-----------------------------------------------------------*/
#expand { text-decoration: none; margin-bottom: 3pt }
img.expand { border-style: none; border-width: medium }
div.expand { display: none; margin-left: 9pt; margin-top: 0 }
/*-----------------------------------------------------------
Where List Tags
-----------------------------------------------------------*/
p.wh { font-weight: bold; clear: both; margin-top: 6pt; margin-bottom: 3pt }
table.wh { width: 100% }
td.whItem { white-space: nowrap; font-style: italic; padding-right: 6pt; padding-bottom:
6pt }
td.whDesc { padding-bottom: 6pt }
/*-----------------------------------------------------------
Keil Table Tags
-----------------------------------------------------------*/
table.kt { border: 1pt solid #000000 }
th.kt { white-space: nowrap; border-bottom: 1pt solid #000000; padding-left: 6pt;
padding-right: 6pt; padding-top: 4pt; padding-bottom: 4pt }
tr.kt { }
td.kt { color: #000000; background-color: #E0E0E0; border-top: 1pt solid #A0A0A0;
padding-left: 6pt; padding-right: 6pt; padding-top: 2pt;
padding-bottom: 2pt }
/*-----------------------------------------------------------
-----------------------------------------------------------*/
-->
</style>
</head>
<body>
<h1>Changes to CMSIS version V1.20</h1>
<hr>
<h2>1. Removed CMSIS Middelware packages</h2>
<p>
CMSIS Middleware is on hold from ARM side until a agreement between all CMSIS partners is found.
</p>
<h2>2. SystemFrequency renamed to SystemCoreClock</h2>
<p>
The variable name <strong>SystemCoreClock</strong> is more precise than <strong>SystemFrequency</strong>
because the variable holds the clock value at which the core is running.
</p>
<h2>3. Changed startup concept</h2>
<p>
The old startup concept (calling SystemInit_ExtMemCtl from startup file and calling SystemInit
from main) has the weakness that it does not work for controllers which need a already
configuerd clock system to configure the external memory controller.
</p>
<h3>Changed startup concept</h3>
<ul>
<li>
SystemInit() is called from startup file before <strong>premain</strong>.
</li>
<li>
<strong>SystemInit()</strong> configures the clock system and also configures
an existing external memory controller.
</li>
<li>
<strong>SystemInit()</strong> must not use global variables.
</li>
<li>
<strong>SystemCoreClock</strong> is initialized with a correct predefined value.
</li>
<li>
Additional function <strong>void SystemCoreClockUpdate (void)</strong> is provided.<br>
<strong>SystemCoreClockUpdate()</strong> updates the variable <strong>SystemCoreClock</strong>
and must be called whenever the core clock is changed.<br>
<strong>SystemCoreClockUpdate()</strong> evaluates the clock register settings and calculates
the current core clock.
</li>
</ul>
<h2>4. Advanced Debug Functions</h2>
<p>
ITM communication channel is only capable for OUT direction. To allow also communication for
IN direction a simple concept is provided.
</p>
<ul>
<li>
Global variable <strong>volatile int ITM_RxBuffer</strong> used for IN data.
</li>
<li>
Function <strong>int ITM_CheckChar (void)</strong> checks if a new character is available.
</li>
<li>
Function <strong>int ITM_ReceiveChar (void)</strong> retrieves the new character.
</li>
</ul>
<p>
For detailed explanation see file <strong>CMSIS debug support.htm</strong>.
</p>
<h2>5. Core Register Bit Definitions</h2>
<p>
Files core_cm3.h and core_cm0.h contain now bit definitions for Core Registers. The name for the
defines correspond with the Cortex-M Technical Reference Manual.
</p>
<p>
e.g. SysTick structure with bit definitions
</p>
<pre>
/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
memory mapped structure for SysTick
@{
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@}*/ /* end of group CMSIS_CM3_SysTick */</pre>
<h2>7. DoxyGen Tags</h2>
<p>
DoxyGen tags in files core_cm3.[c,h] and core_cm0.[c,h] are reworked to create proper documentation
using DoxyGen.
</p>
<h2>8. Folder Structure</h2>
<p>
The folder structure is changed to differentiate the single support packages.
</p>
<ul>
<li>CM0</li>
<li>CM3
<ul>
<li>CoreSupport</li>
<li>DeviceSupport</li>
<ul>
<li>Vendor
<ul>
<li>Device
<ul>
<li>Startup
<ul>
<li>Toolchain</li>
<li>Toolchain</li>
<li>...</li>
</ul>
</li>
</ul>
</li>
<li>Device</li>
<li>...</li>
</ul>
</li>
<li>Vendor</li>
<li>...</li>
</ul>
</li>
<li>Example
<ul>
<li>Toolchain
<ul>
<li>Device</li>
<li>Device</li>
<li>...</li>
</ul>
</li>
<li>Toolchain</li>
<li>...</li>
</ul>
</li>
</ul>
</li>
<li>Documentation</li>
</ul>
<h2>9. Open Points</h2>
<p>
Following points need to be clarified and solved:
</p>
<ul>
<li>
<p>
Equivalent C and Assembler startup files.
</p>
<p>
Is there a need for having C startup files although assembler startup files are
very efficient and do not need to be changed?
<p/>
</li>
<li>
<p>
Placing of HEAP in external RAM.
</p>
<p>
It must be possible to place HEAP in external RAM if the device supports an
external memory controller.
</p>
</li>
<li>
<p>
Placing of STACK /HEAP.
</p>
<p>
STACK should always be placed at the end of internal RAM.
</p>
<p>
If HEAP is placed in internal RAM than it should be placed after RW ZI section.
</p>
</li>
<li>
<p>
Removing core_cm3.c and core_cm0.c.
</p>
<p>
On a long term the functions in core_cm3.c and core_cm0.c must be replaced with
appropriate compiler intrinsics.
</p>
</li>
</ul>
<h2>10. Limitations</h2>
<p>
The following limitations are not covered with the current CMSIS version:
</p>
<ul>
<li>
No <strong>C startup files</strong> for ARM toolchain are provided.
</li>
<li>
No <strong>C startup files</strong> for GNU toolchain are provided.
</li>
<li>
No <strong>C startup files</strong> for IAR toolchain are provided.
</li>
<li>
No <strong>Tasking</strong> projects are provided yet.
</li>
</ul>

View File

@ -0,0 +1,243 @@
<html>
<head>
<title>CMSIS Debug Support</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<style>
<!--
/*-----------------------------------------------------------
Keil Software CHM Style Sheet
-----------------------------------------------------------*/
body { color: #000000; background-color: #FFFFFF; font-size: 75%; font-family:
Verdana, Arial, 'Sans Serif' }
a:link { color: #0000FF; text-decoration: underline }
a:visited { color: #0000FF; text-decoration: underline }
a:active { color: #FF0000; text-decoration: underline }
a:hover { color: #FF0000; text-decoration: underline }
h1 { font-family: Verdana; font-size: 18pt; color: #000080; font-weight: bold;
text-align: Center; margin-right: 3 }
h2 { font-family: Verdana; font-size: 14pt; color: #000080; font-weight: bold;
background-color: #CCCCCC; margin-top: 24; margin-bottom: 3;
padding: 6 }
h3 { font-family: Verdana; font-size: 10pt; font-weight: bold; background-color:
#CCCCCC; margin-top: 24; margin-bottom: 3; padding: 6 }
pre { font-family: Courier New; font-size: 10pt; background-color: #CCFFCC;
margin-left: 24; margin-right: 24 }
ul { list-style-type: square; margin-top: 6pt; margin-bottom: 0 }
ol { margin-top: 6pt; margin-bottom: 0 }
li { clear: both; margin-bottom: 6pt }
table { font-size: 100%; border-width: 0; padding: 0 }
th { color: #FFFFFF; background-color: #000080; text-align: left; vertical-align:
bottom; padding-right: 6pt }
tr { text-align: left; vertical-align: top }
td { text-align: left; vertical-align: top; padding-right: 6pt }
.ToolT { font-size: 8pt; color: #808080 }
.TinyT { font-size: 8pt; text-align: Center }
code { color: #000000; background-color: #E0E0E0; font-family: 'Courier New', Courier;
line-height: 120%; font-style: normal }
/*-----------------------------------------------------------
Notes
-----------------------------------------------------------*/
p.note { font-weight: bold; clear: both; margin-bottom: 3pt; padding-top: 6pt }
/*-----------------------------------------------------------
Expanding/Contracting Divisions
-----------------------------------------------------------*/
#expand { text-decoration: none; margin-bottom: 3pt }
img.expand { border-style: none; border-width: medium }
div.expand { display: none; margin-left: 9pt; margin-top: 0 }
/*-----------------------------------------------------------
Where List Tags
-----------------------------------------------------------*/
p.wh { font-weight: bold; clear: both; margin-top: 6pt; margin-bottom: 3pt }
table.wh { width: 100% }
td.whItem { white-space: nowrap; font-style: italic; padding-right: 6pt; padding-bottom:
6pt }
td.whDesc { padding-bottom: 6pt }
/*-----------------------------------------------------------
Keil Table Tags
-----------------------------------------------------------*/
table.kt { border: 1pt solid #000000 }
th.kt { white-space: nowrap; border-bottom: 1pt solid #000000; padding-left: 6pt;
padding-right: 6pt; padding-top: 4pt; padding-bottom: 4pt }
tr.kt { }
td.kt { color: #000000; background-color: #E0E0E0; border-top: 1pt solid #A0A0A0;
padding-left: 6pt; padding-right: 6pt; padding-top: 2pt;
padding-bottom: 2pt }
/*-----------------------------------------------------------
-----------------------------------------------------------*/
-->
</style>
</head>
<body>
<h1>CMSIS Debug Support</h1>
<hr>
<h2>Cortex-M3 ITM Debug Access</h2>
<p>
The Cortex-M3 incorporates the Instrumented Trace Macrocell (ITM) that provides together with
the Serial Viewer Output trace capabilities for the microcontroller system. The ITM has
32 communication channels which are able to transmit 32 / 16 / 8 bit values; two ITM
communication channels are used by CMSIS to output the following information:
</p>
<ul>
<li>ITM Channel 0: used for printf-style output via the debug interface.</li>
<li>ITM Channel 31: is reserved for RTOS kernel awareness debugging.</li>
</ul>
<h2>Debug IN / OUT functions</h2>
<p>CMSIS provides following debug functions:</p>
<ul>
<li>ITM_SendChar (uses ITM channel 0)</li>
<li>ITM_ReceiveChar (uses global variable)</li>
<li>ITM_CheckChar (uses global variable)</li>
</ul>
<h3>ITM_SendChar</h3>
<p>
<strong>ITM_SendChar</strong> is used to transmit a character over ITM channel 0 from
the microcontroller system to the debug system. <br>
Only a 8 bit value is transmitted.
</p>
<pre>
static __INLINE uint32_t ITM_SendChar (uint32_t ch)
{
/* check if debugger connected and ITM channel enabled for tracing */
if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA) &amp;&amp;
(ITM-&gt;TCR & ITM_TCR_ITMENA) &amp;&amp;
(ITM-&gt;TER & (1UL &lt;&lt; 0)) )
{
while (ITM-&gt;PORT[0].u32 == 0);
ITM-&gt;PORT[0].u8 = (uint8_t)ch;
}
return (ch);
}</pre>
<h3>ITM_ReceiveChar</h3>
<p>
ITM communication channel is only capable for OUT direction. For IN direction
a globel variable is used. A simple mechansim detects if a character is received.
The project to test need to be build with debug information.
</p>
<p>
The globale variable <strong>ITM_RxBuffer</strong> is used to transmit a 8 bit value from debug system
to microcontroller system. <strong>ITM_RxBuffer</strong> is 32 bit wide to enshure a proper handshake.
</p>
<pre>
extern volatile int ITM_RxBuffer; /* variable to receive characters */
</pre>
<p>
A dedicated bit pattern is used to determin if <strong>ITM_RxBuffer</strong> is empty
or contains a valid value.
</p>
<pre>
#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /* value identifying ITM_RxBuffer is ready for next character */
</pre>
<p>
<strong>ITM_ReceiveChar</strong> is used to receive a 8 bit value from the debug system. The function is nonblocking.
It returns the received character or '-1' if no character was available.
</p>
<pre>
static __INLINE int ITM_ReceiveChar (void) {
int ch = -1; /* no character available */
if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
ch = ITM_RxBuffer;
ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
}
return (ch);
}
</pre>
<h3>ITM_CheckChar</h3>
<p>
<strong>ITM_CheckChar</strong> is used to check if a character is received.
</p>
<pre>
static __INLINE int ITM_CheckChar (void) {
if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
return (0); /* no character available */
} else {
return (1); /* character available */
}
}</pre>
<h2>ITM Debug Support in uVision</h2>
<p>
uVision uses in a debug session the <strong>Debug (printf) Viewer</strong> window to
display the debug data.
</p>
<p>Direction microcontroller system -&gt; uVision:</p>
<ul>
<li>
Characters received via ITM communication channel 0 are written in a printf style
to <strong>Debug (printf) Viewer</strong> window.
</li>
</ul>
<p>Direction uVision -&gt; microcontroller system:</p>
<ul>
<li>Check if <strong>ITM_RxBuffer</strong> variable is available (only performed once).</li>
<li>Read character from <strong>Debug (printf) Viewer</strong> window.</li>
<li>If <strong>ITM_RxBuffer</strong> empty write character to <strong>ITM_RxBuffer</strong>.</li>
</ul>
<p class="Note">Note</p>
<ul>
<li><p>Current solution does not use a buffer machanism for trasmitting the characters.</p>
</li>
</ul>
<h2>RTX Kernel awareness in uVision</h2>
<p>
uVision / RTX are using a simple and efficient solution for RTX Kernel awareness.
No format overhead is necessary.<br>
uVsion debugger decodes the RTX events via the 32 / 16 / 8 bit ITM write access
to ITM communication channel 31.
</p>
<p>Following RTX events are traced:</p>
<ul>
<li>Task Create / Delete event
<ol>
<li>32 bit access. Task start address is transmitted</li>
<li>16 bit access. Task ID and Create/Delete flag are transmitted<br>
High byte holds Create/Delete flag, Low byte holds TASK ID.
</li>
</ol>
</li>
<li>Task switch event
<ol>
<li>8 bit access. Task ID of current task is transmitted</li>
</ol>
</li>
</ul>
<p class="Note">Note</p>
<ul>
<li><p>Other RTOS information could be retrieved via memory read access in a polling mode manner.</p>
</li>
</ul>
<p class="MsoNormal"><span lang="EN-GB">&nbsp;</span></p>
<hr>
<p class="TinyT">Copyright © KEIL - An ARM Company.<br>
All rights reserved.<br>
Visit our web site at <a href="http://www.keil.com">www.keil.com</a>.
</p>
</body>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,8 @@
History of updates to CMSISv1p30_LPC13xx
========================================
18 February 2010
----------------
system_LPC13xx.c updated to new version (dated 18 February 2010),
changing value of SYSPLLCTRL_Val from 0x05 to 0x25

View File

@ -0,0 +1,532 @@
/**************************************************************************//**
* @file lpc13xx.h
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File for
* NXP LPC13xx Device Series
* @version V1.01
* @date 19. October 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __LPC13xx_H__
#define __LPC13xx_H__
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn {
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** LPC13xx Specific Interrupt Numbers *******************************************************/
WAKEUP_PIO0_0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */
WAKEUP_PIO0_1_IRQn = 1, /*!< There are 40 pins in total for LPC17xx */
WAKEUP_PIO0_2_IRQn = 2,
WAKEUP_PIO0_3_IRQn = 3,
WAKEUP_PIO0_4_IRQn = 4,
WAKEUP_PIO0_5_IRQn = 5,
WAKEUP_PIO0_6_IRQn = 6,
WAKEUP_PIO0_7_IRQn = 7,
WAKEUP_PIO0_8_IRQn = 8,
WAKEUP_PIO0_9_IRQn = 9,
WAKEUP_PIO0_10_IRQn = 10,
WAKEUP_PIO0_11_IRQn = 11,
WAKEUP_PIO1_0_IRQn = 12,
WAKEUP_PIO1_1_IRQn = 13,
WAKEUP_PIO1_2_IRQn = 14,
WAKEUP_PIO1_3_IRQn = 15,
WAKEUP_PIO1_4_IRQn = 16,
WAKEUP_PIO1_5_IRQn = 17,
WAKEUP_PIO1_6_IRQn = 18,
WAKEUP_PIO1_7_IRQn = 19,
WAKEUP_PIO1_8_IRQn = 20,
WAKEUP_PIO1_9_IRQn = 21,
WAKEUP_PIO1_10_IRQn = 22,
WAKEUP_PIO1_11_IRQn = 23,
WAKEUP_PIO2_0_IRQn = 24,
WAKEUP_PIO2_1_IRQn = 25,
WAKEUP_PIO2_2_IRQn = 26,
WAKEUP_PIO2_3_IRQn = 27,
WAKEUP_PIO2_4_IRQn = 28,
WAKEUP_PIO2_5_IRQn = 29,
WAKEUP_PIO2_6_IRQn = 30,
WAKEUP_PIO2_7_IRQn = 31,
WAKEUP_PIO2_8_IRQn = 31,
WAKEUP_PIO2_9_IRQn = 33,
WAKEUP_PIO2_10_IRQn = 34,
WAKEUP_PIO2_11_IRQn = 35,
WAKEUP_PIO3_0_IRQn = 36,
WAKEUP_PIO3_1_IRQn = 37,
WAKEUP_PIO3_2_IRQn = 38,
WAKEUP_PIO3_3_IRQn = 39,
I2C_IRQn = 40, /*!< I2C Interrupt */
TIMER_16_0_IRQn = 41, /*!< 16-bit Timer0 Interrupt */
TIMER_16_1_IRQn = 42, /*!< 16-bit Timer1 Interrupt */
TIMER_32_0_IRQn = 43, /*!< 32-bit Timer0 Interrupt */
TIMER_32_1_IRQn = 44, /*!< 32-bit Timer1 Interrupt */
SSP_IRQn = 45, /*!< SSP Interrupt */
UART_IRQn = 46, /*!< UART Interrupt */
USB_IRQn = 47, /*!< USB Regular Interrupt */
USB_FIQn = 48, /*!< USB Fast Interrupt */
ADC_IRQn = 49, /*!< A/D Converter Interrupt */
WDT_IRQn = 50, /*!< Watchdog timer Interrupt */
BOD_IRQn = 51, /*!< Brown Out Detect(BOD) Interrupt */
EINT3_IRQn = 53, /*!< External Interrupt 3 Interrupt */
EINT2_IRQn = 54, /*!< External Interrupt 2 Interrupt */
EINT1_IRQn = 55, /*!< External Interrupt 1 Interrupt */
EINT0_IRQn = 56, /*!< External Interrupt 0 Interrupt */
} IRQn_Type;
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
/* Configuration of the Cortex-M3 Processor and Core Peripherals */
#define __MPU_PRESENT 1 /*!< MPU present or not */
#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
#include "system_LPC13xx.h" /* System Header */
/******************************************************************************/
/* Device Specific Peripheral registers structures */
/******************************************************************************/
#if defined ( __CC_ARM )
#pragma anon_unions
#endif
/*------------- System Control (SYSCON) --------------------------------------*/
typedef struct {
__IO uint32_t SYSMEMREMAP; /* Sys mem. Remap, Offset 0x0 */
__IO uint32_t PRESETCTRL;
__IO uint32_t SYSPLLCTRL; /* Sys PLL control */
__IO uint32_t SYSPLLSTAT;
__IO uint32_t USBPLLCTRL; /* USB PLL control, offset 0x10 */
__IO uint32_t USBPLLSTAT;
uint32_t RESERVED0[2];
__IO uint32_t SYSOSCCTRL; /* Offset 0x20 */
__IO uint32_t WDTOSCCTRL;
__IO uint32_t IRCCTRL;
uint32_t RESERVED1[1];
__IO uint32_t SYSRESSTAT; /* Offset 0x30 */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /* Offset 0x40 */
__IO uint32_t SYSPLLCLKUEN;
__IO uint32_t USBPLLCLKSEL;
__IO uint32_t USBPLLCLKUEN;
uint32_t RESERVED3[8];
__IO uint32_t MAINCLKSEL; /* Offset 0x70 */
__IO uint32_t MAINCLKUEN;
__IO uint32_t SYSAHBCLKDIV;
uint32_t RESERVED4[1];
__IO uint32_t SYSAHBCLKCTRL; /* Offset 0x80 */
uint32_t RESERVED5[4];
__IO uint32_t SSPCLKDIV;
__IO uint32_t UARTCLKDIV;
uint32_t RESERVED6[4];
__IO uint32_t TRACECLKDIV;
__IO uint32_t SYSTICKCLKDIV; /* Offset 0xB0 */
uint32_t RESERVED7[3];
__IO uint32_t USBCLKSEL; /* Offset 0xC0 */
__IO uint32_t USBCLKUEN;
__IO uint32_t USBCLKDIV;
uint32_t RESERVED8[1];
__IO uint32_t WDTCLKSEL; /* Offset 0xD0 */
__IO uint32_t WDTCLKUEN;
__IO uint32_t WDTCLKDIV;
uint32_t RESERVED9[1];
__IO uint32_t CLKOUTCLKSEL; /* Offset 0xE0 */
__IO uint32_t CLKOUTUEN;
__IO uint32_t CLKOUTDIV;
uint32_t RESERVED10[5];
__IO uint32_t PIOPORCAP0; /* Offset 0x100 */
__IO uint32_t PIOPORCAP1;
uint32_t RESERVED11[18];
__IO uint32_t BODCTRL; /* Offset 0x150 */
uint32_t RESERVED12[1];
__IO uint32_t SYSTCKCAL;
uint32_t RESERVED13[41];
__IO uint32_t STARTAPRP0; /* Offset 0x200 */
__IO uint32_t STARTERP0;
__IO uint32_t STARTRSRP0CLR;
__IO uint32_t STARTSRP0;
__IO uint32_t STARTAPRP1;
__IO uint32_t STARTERP1;
__IO uint32_t STARTRSRP1CLR;
__IO uint32_t STARTSRP1;
uint32_t RESERVED14[4];
__IO uint32_t PDSLEEPCFG; /* Offset 0x230 */
__IO uint32_t PDAWAKECFG;
__IO uint32_t PDRUNCFG;
uint32_t RESERVED15[110];
__I uint32_t DEVICE_ID;
} LPC_SYSCON_TypeDef;
/*------------- Pin Connect Block (IOCON) --------------------------------*/
typedef struct {
__IO uint32_t PIO2_6;
uint32_t RESERVED0[1];
__IO uint32_t PIO2_0;
__IO uint32_t RESET_PIO0_0;
__IO uint32_t PIO0_1;
__IO uint32_t PIO1_8;
uint32_t RESERVED1[1];
__IO uint32_t PIO0_2;
__IO uint32_t PIO2_7;
__IO uint32_t PIO2_8;
__IO uint32_t PIO2_1;
__IO uint32_t PIO0_3;
__IO uint32_t PIO0_4;
__IO uint32_t PIO0_5;
__IO uint32_t PIO1_9;
__IO uint32_t PIO3_4;
__IO uint32_t PIO2_4;
__IO uint32_t PIO2_5;
__IO uint32_t PIO3_5;
__IO uint32_t PIO0_6;
__IO uint32_t PIO0_7;
__IO uint32_t PIO2_9;
__IO uint32_t PIO2_10;
__IO uint32_t PIO2_2;
__IO uint32_t PIO0_8;
__IO uint32_t PIO0_9;
__IO uint32_t JTAG_TCK_PIO0_10;
__IO uint32_t PIO1_10;
__IO uint32_t PIO2_11;
__IO uint32_t JTAG_TDI_PIO0_11;
__IO uint32_t JTAG_TMS_PIO1_0;
__IO uint32_t JTAG_TDO_PIO1_1;
__IO uint32_t JTAG_nTRST_PIO1_2;
__IO uint32_t PIO3_0;
__IO uint32_t PIO3_1;
__IO uint32_t PIO2_3;
__IO uint32_t ARM_SWDIO_PIO1_3;
__IO uint32_t PIO1_4;
__IO uint32_t PIO1_11;
__IO uint32_t PIO3_2;
__IO uint32_t PIO1_5;
__IO uint32_t PIO1_6;
__IO uint32_t PIO1_7;
__IO uint32_t PIO3_3;
__IO uint32_t SCKLOC; /* For HB1 only, new feature */
} LPC_IOCON_TypeDef;
/*------------- Power Management Unit (PMU) --------------------------*/
typedef struct {
__IO uint32_t PCON;
__IO uint32_t GPREG0;
__IO uint32_t GPREG1;
__IO uint32_t GPREG2;
__IO uint32_t GPREG3;
__IO uint32_t GPREG4;
} LPC_PMU_TypeDef;
/*------------- General Purpose Input/Output (GPIO) --------------------------*/
typedef struct {
union {
__IO uint32_t MASKED_ACCESS[4096];
struct {
uint32_t RESERVED0[4095];
__IO uint32_t DATA;
};
};
uint32_t RESERVED1[4096];
__IO uint32_t DIR;
__IO uint32_t IS;
__IO uint32_t IBE;
__IO uint32_t IEV;
__IO uint32_t IE;
__IO uint32_t RIS;
__IO uint32_t MIS;
__IO uint32_t IC;
} LPC_GPIO_TypeDef;
/*------------- Timer (TMR) --------------------------------------------------*/
typedef struct {
__IO uint32_t IR;
__IO uint32_t TCR;
__IO uint32_t TC;
__IO uint32_t PR;
__IO uint32_t PC;
__IO uint32_t MCR;
__IO uint32_t MR0;
__IO uint32_t MR1;
__IO uint32_t MR2;
__IO uint32_t MR3;
__IO uint32_t CCR;
__I uint32_t CR0;
uint32_t RESERVED1[3];
__IO uint32_t EMR;
uint32_t RESERVED2[12];
__IO uint32_t CTCR;
__IO uint32_t PWMC;
} LPC_TMR_TypeDef;
/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
typedef struct {
union {
__I uint32_t RBR;
__O uint32_t THR;
__IO uint32_t DLL;
};
union {
__IO uint32_t DLM;
__IO uint32_t IER;
};
union {
__I uint32_t IIR;
__O uint32_t FCR;
};
__IO uint32_t LCR;
__IO uint32_t MCR;
__I uint32_t LSR;
__I uint32_t MSR;
__IO uint32_t SCR;
__IO uint32_t ACR;
__IO uint32_t ICR;
__IO uint32_t FDR;
uint32_t RESERVED0;
__IO uint32_t TER;
uint32_t RESERVED1[6];
__IO uint32_t RS485CTRL;
__IO uint32_t ADRMATCH;
__IO uint32_t RS485DLY;
__I uint32_t FIFOLVL;
} LPC_UART_TypeDef;
/*------------- Synchronous Serial Communication (SSP) -----------------------*/
typedef struct {
__IO uint32_t CR0;
__IO uint32_t CR1;
__IO uint32_t DR;
__I uint32_t SR;
__IO uint32_t CPSR;
__IO uint32_t IMSC;
__IO uint32_t RIS;
__IO uint32_t MIS;
__IO uint32_t ICR;
} LPC_SSP_TypeDef;
/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
typedef struct {
__IO uint32_t CONSET;
__I uint32_t STAT;
__IO uint32_t DAT;
__IO uint32_t ADR0;
__IO uint32_t SCLH;
__IO uint32_t SCLL;
__O uint32_t CONCLR;
__IO uint32_t MMCTRL;
__IO uint32_t ADR1;
__IO uint32_t ADR2;
__IO uint32_t ADR3;
__I uint32_t DATA_BUFFER;
__IO uint32_t MASK0;
__IO uint32_t MASK1;
__IO uint32_t MASK2;
__IO uint32_t MASK3;
} LPC_I2C_TypeDef;
/*------------- Watchdog Timer (WDT) -----------------------------------------*/
typedef struct {
__IO uint32_t MOD;
__IO uint32_t TC;
__O uint32_t FEED;
__I uint32_t TV;
} LPC_WDT_TypeDef;
/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
typedef struct {
__IO uint32_t CR;
__IO uint32_t GDR;
uint32_t RESERVED0;
__IO uint32_t INTEN;
__I uint32_t DR0;
__I uint32_t DR1;
__I uint32_t DR2;
__I uint32_t DR3;
__I uint32_t DR4;
__I uint32_t DR5;
__I uint32_t DR6;
__I uint32_t DR7;
__I uint32_t STAT;
} LPC_ADC_TypeDef;
/*------------- Universal Serial Bus (USB) -----------------------------------*/
typedef struct {
__I uint32_t DevIntSt; /* USB Device Interrupt Registers */
__IO uint32_t DevIntEn;
__O uint32_t DevIntClr;
__O uint32_t DevIntSet;
__O uint32_t CmdCode; /* USB Device SIE Command Registers */
__I uint32_t CmdData;
__I uint32_t RxData; /* USB Device Transfer Registers */
__O uint32_t TxData;
__I uint32_t RxPLen;
__O uint32_t TxPLen;
__IO uint32_t Ctrl;
__O uint32_t DevFIQSel;
} LPC_USB_TypeDef;
#if defined ( __CC_ARM )
#pragma no_anon_unions
#endif
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000)
#define LPC_WDT_BASE (LPC_APB0_BASE + 0x04000)
#define LPC_UART_BASE (LPC_APB0_BASE + 0x08000)
#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000)
#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000)
#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000)
#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000)
#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000)
#define LPC_USB_BASE (LPC_APB0_BASE + 0x20000)
#define LPC_PMU_BASE (LPC_APB0_BASE + 0x38000)
#define LPC_SSP_BASE (LPC_APB0_BASE + 0x40000)
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
/* AHB peripherals */
#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000)
#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000)
#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE )
#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE )
#define LPC_UART ((LPC_UART_TypeDef *) LPC_UART_BASE )
#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE)
#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE)
#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE)
#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE)
#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )
#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE )
#define LPC_SSP ((LPC_SSP_TypeDef *) LPC_SSP_BASE )
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE )
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
/******************************************************************************/
/* IO Start logic Register Delcaration */
/******************************************************************************/
#define STARTxPRP0_PIO0_0 (1UL<<0)
#define STARTxPRP0_PIO0_1 (1UL<<1)
#define STARTxPRP0_PIO0_2 (1UL<<2)
#define STARTxPRP0_PIO0_3 (1UL<<3)
#define STARTxPRP0_PIO0_4 (1UL<<4)
#define STARTxPRP0_PIO0_5 (1UL<<5)
#define STARTxPRP0_PIO0_6 (1UL<<6)
#define STARTxPRP0_PIO0_7 (1UL<<7)
#define STARTxPRP0_PIO0_8 (1UL<<8)
#define STARTxPRP0_PIO0_9 (1UL<<9)
#define STARTxPRP0_PIO0_10 (1UL<<10)
#define STARTxPRP0_PIO0_11 (1UL<<11)
#define STARTxPRP0_PIO1_0 (1UL<<12)
#define STARTxPRP0_PIO1_1 (1UL<<13)
#define STARTxPRP0_PIO1_2 (1UL<<14)
#define STARTxPRP0_PIO1_3 (1UL<<15)
#define STARTxPRP0_PIO1_4 (1UL<<16)
#define STARTxPRP0_PIO1_5 (1UL<<17)
#define STARTxPRP0_PIO1_6 (1UL<<18)
#define STARTxPRP0_PIO1_7 (1UL<<19)
#define STARTxPRP0_PIO1_8 (1UL<<20)
#define STARTxPRP0_PIO1_9 (1UL<<21)
#define STARTxPRP0_PIO1_10 (1UL<<22)
#define STARTxPRP0_PIO1_11 (1UL<<23)
#define STARTxPRP0_PIO2_0 (1UL<<24)
#define STARTxPRP0_PIO2_1 (1UL<<25)
#define STARTxPRP0_PIO2_2 (1UL<<26)
#define STARTxPRP0_PIO2_3 (1UL<<27)
#define STARTxPRP0_PIO2_4 (1UL<<28)
#define STARTxPRP0_PIO2_5 (1UL<<29)
#define STARTxPRP0_PIO2_6 (1UL<<30)
#define STARTxPRP0_PIO2_7 (1UL<<31)
#define STARTxPRP1_PIO2_8 (1UL<<0)
#define STARTxPRP1_PIO2_9 (1UL<<1)
#define STARTxPRP1_PIO2_10 (1UL<<2)
#define STARTxPRP1_PIO2_11 (1UL<<3)
#define STARTxPRP1_PIO3_0 (1UL<<4)
#define STARTxPRP1_PIO3_1 (1UL<<4)
#define STARTxPRP1_PIO3_2 (1UL<<6)
#define STARTxPRP1_PIO3_3 (1UL<<7)
#endif // __LPC13xx_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
/**************************************************************************//**
* @file system_lpc13xx.h
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File
* for the NXP LPC13xx Device Series
* @version V1.01
* @date 19. October 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC13xx_H
#define __SYSTEM_LPC13xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit(void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate(void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC13x_H */

View File

@ -0,0 +1,784 @@
/**************************************************************************//**
* @file core_cm3.c
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
* @version V1.30
* @date 30. October 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/* ################### Compiler specific Intrinsics ########################### */
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
/**
* @brief Return the Process Stack Pointer
*
* @return ProcessStackPointer
*
* Return the actual process stack pointer
*/
__ASM uint32_t __get_PSP(void)
{
mrs r0, psp
bx lr
}
/**
* @brief Set the Process Stack Pointer
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
__ASM void __set_PSP(uint32_t topOfProcStack)
{
msr psp, r0
bx lr
}
/**
* @brief Return the Main Stack Pointer
*
* @return Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
__ASM uint32_t __get_MSP(void)
{
mrs r0, msp
bx lr
}
/**
* @brief Set the Main Stack Pointer
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in unsigned short value
*/
__ASM uint32_t __REV16(uint16_t value)
{
rev16 r0, r0
bx lr
}
/**
* @brief Reverse byte order in signed short value with sign extension to integer
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in signed short value with sign extension to integer
*/
__ASM int32_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#if (__ARMCC_VERSION < 400000)
/**
* @brief Remove the exclusive lock created by ldrex
*
* Removes the exclusive lock which is created by ldrex.
*/
__ASM void __CLREX(void)
{
clrex
}
/**
* @brief Return the Base Priority value
*
* @return BasePriority
*
* Return the content of the base priority register
*/
__ASM uint32_t __get_BASEPRI(void)
{
mrs r0, basepri
bx lr
}
/**
* @brief Set the Base Priority value
*
* @param basePri BasePriority
*
* Set the base priority register
*/
__ASM void __set_BASEPRI(uint32_t basePri)
{
msr basepri, r0
bx lr
}
/**
* @brief Return the Priority Mask value
*
* @return PriMask
*
* Return state of the priority mask bit from the priority mask register
*/
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
/**
* @brief Set the Priority Mask value
*
* @param priMask PriMask
*
* Set the priority mask bit in the priority mask register
*/
__ASM void __set_PRIMASK(uint32_t priMask)
{
msr primask, r0
bx lr
}
/**
* @brief Return the Fault Mask value
*
* @return FaultMask
*
* Return the content of the fault mask register
*/
__ASM uint32_t __get_FAULTMASK(void)
{
mrs r0, faultmask
bx lr
}
/**
* @brief Set the Fault Mask value
*
* @param faultMask faultMask value
*
* Set the fault mask register
*/
__ASM void __set_FAULTMASK(uint32_t faultMask)
{
msr faultmask, r0
bx lr
}
/**
* @brief Return the Control Register value
*
* @return Control value
*
* Return the content of the control register
*/
__ASM uint32_t __get_CONTROL(void)
{
mrs r0, control
bx lr
}
/**
* @brief Set the Control Register value
*
* @param control Control value
*
* Set the control register
*/
__ASM void __set_CONTROL(uint32_t control)
{
msr control, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#pragma diag_suppress=Pe940
/**
* @brief Return the Process Stack Pointer
*
* @return ProcessStackPointer
*
* Return the actual process stack pointer
*/
uint32_t __get_PSP(void)
{
__ASM("mrs r0, psp");
__ASM("bx lr");
}
/**
* @brief Set the Process Stack Pointer
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack)
{
__ASM("msr psp, r0");
__ASM("bx lr");
}
/**
* @brief Return the Main Stack Pointer
*
* @return Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
uint32_t __get_MSP(void)
{
__ASM("mrs r0, msp");
__ASM("bx lr");
}
/**
* @brief Set the Main Stack Pointer
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack)
{
__ASM("msr msp, r0");
__ASM("bx lr");
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in unsigned short value
*/
uint32_t __REV16(uint16_t value)
{
__ASM("rev16 r0, r0");
__ASM("bx lr");
}
/**
* @brief Reverse bit order of value
*
* @param value value to reverse
* @return reversed value
*
* Reverse bit order of value
*/
uint32_t __RBIT(uint32_t value)
{
__ASM("rbit r0, r0");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive (8 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 8 bit values)
*/
uint8_t __LDREXB(uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive (16 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 16 bit values
*/
uint16_t __LDREXH(uint16_t *addr)
{
__ASM("ldrexh r0, [r0]");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive (32 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 32 bit values
*/
uint32_t __LDREXW(uint32_t *addr)
{
__ASM("ldrex r0, [r0]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive (8 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 8 bit values
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
__ASM("strexb r0, r0, [r1]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive (16 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 16 bit values
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
__ASM("strexh r0, r0, [r1]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive (32 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 32 bit values
*/
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
__ASM("strex r0, r0, [r1]");
__ASM("bx lr");
}
#pragma diag_default=Pe940
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/**
* @brief Return the Process Stack Pointer
*
* @return ProcessStackPointer
*
* Return the actual process stack pointer
*/
uint32_t __get_PSP(void) __attribute__( ( naked ) );
uint32_t __get_PSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, psp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
}
/**
* @brief Set the Process Stack Pointer
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n\t"
"BX lr \n\t" : : "r" (topOfProcStack) );
}
/**
* @brief Return the Main Stack Pointer
*
* @return Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
uint32_t __get_MSP(void) __attribute__( ( naked ) );
uint32_t __get_MSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, msp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
}
/**
* @brief Set the Main Stack Pointer
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n\t"
"BX lr \n\t" : : "r" (topOfMainStack) );
}
/**
* @brief Return the Base Priority value
*
* @return BasePriority
*
* Return the content of the base priority register
*/
uint32_t __get_BASEPRI(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/**
* @brief Set the Base Priority value
*
* @param basePri BasePriority
*
* Set the base priority register
*/
void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/**
* @brief Return the Priority Mask value
*
* @return PriMask
*
* Return state of the priority mask bit from the priority mask register
*/
uint32_t __get_PRIMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/**
* @brief Set the Priority Mask value
*
* @param priMask PriMask
*
* Set the priority mask bit in the priority mask register
*/
void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
/**
* @brief Return the Fault Mask value
*
* @return FaultMask
*
* Return the content of the fault mask register
*/
uint32_t __get_FAULTMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/**
* @brief Set the Fault Mask value
*
* @param faultMask faultMask value
*
* Set the fault mask register
*/
void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
/**
* @brief Return the Control Register value
*
* @return Control value
*
* Return the content of the control register
*/
uint32_t __get_CONTROL(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/**
* @brief Set the Control Register value
*
* @param control Control value
*
* Set the control register
*/
void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/**
* @brief Reverse byte order in integer value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in integer value
*/
uint32_t __REV(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in unsigned short value
*/
uint32_t __REV16(uint16_t value)
{
uint32_t result=0;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse byte order in signed short value with sign extension to integer
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in signed short value with sign extension to integer
*/
int32_t __REVSH(int16_t value)
{
uint32_t result=0;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse bit order of value
*
* @param value value to reverse
* @return reversed value
*
* Reverse bit order of value
*/
uint32_t __RBIT(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief LDR Exclusive (8 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 8 bit value
*/
uint8_t __LDREXB(uint8_t *addr)
{
uint8_t result=0;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief LDR Exclusive (16 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 16 bit values
*/
uint16_t __LDREXH(uint16_t *addr)
{
uint16_t result=0;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief LDR Exclusive (32 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 32 bit values
*/
uint32_t __LDREXW(uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief STR Exclusive (8 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 8 bit values
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief STR Exclusive (16 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 16 bit values
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief STR Exclusive (32 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 32 bit values
*/
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif

View File

@ -0,0 +1,487 @@
/**************************************************************************//**
* @file system_LPC13xx.c
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File
* for the NXP LPC13xx Device Series
* @version V1.02
* @date 18. February 2010
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
// ******** Code Red **************
// * Changed USBCLK_SETUP to 1
// * Changed SYSPLLCTRL_Val to 0x25
// ********************************
#include <stdint.h>
#include "LPC13xx.h"
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
/*--------------------- Clock Configuration ----------------------------------
//
// <e> Clock Configuration
// <e1> System Clock Setup
// <e2> System Oscillator Enable
// <o3.1> Select System Oscillator Frequency Range
// <0=> 1 - 20 MHz
// <1=> 15 - 25 MHz
// </e2>
// <e4> Watchdog Oscillator Enable
// <o5.0..4> Select Divider for Fclkana
// <0=> 2 <1=> 4 <2=> 6 <3=> 8
// <4=> 10 <5=> 12 <6=> 14 <7=> 16
// <8=> 18 <9=> 20 <10=> 22 <11=> 24
// <12=> 26 <13=> 28 <14=> 30 <15=> 32
// <16=> 34 <17=> 36 <18=> 38 <19=> 40
// <20=> 42 <21=> 44 <22=> 46 <23=> 48
// <24=> 50 <25=> 52 <26=> 54 <27=> 56
// <28=> 58 <29=> 60 <30=> 62 <31=> 64
// <o5.5..8> Select Watchdog Oscillator Analog Frequency (Fclkana)
// <0=> Disabled
// <1=> 0.5 MHz
// <2=> 0.8 MHz
// <3=> 1.1 MHz
// <4=> 1.4 MHz
// <5=> 1.6 MHz
// <6=> 1.8 MHz
// <7=> 2.0 MHz
// <8=> 2.2 MHz
// <9=> 2.4 MHz
// <10=> 2.6 MHz
// <11=> 2.7 MHz
// <12=> 2.9 MHz
// <13=> 3.1 MHz
// <14=> 3.2 MHz
// <15=> 3.4 MHz
// </e4>
// <o6> Select Input Clock for sys_pllclkin (Register: SYSPLLCLKSEL)
// <0=> IRC Oscillator
// <1=> System Oscillator
// <2=> WDT Oscillator
// <3=> Invalid
// <e7> Use System PLL
// <i> F_pll = M * F_in
// <i> F_in must be in the range of 10 MHz to 25 MHz
// <o8.0..4> M: PLL Multiplier Selection
// <1-32><#-1>
// <o8.5..6> P: PLL Divider Selection
// <0=> 2
// <1=> 4
// <2=> 8
// <3=> 16
// <o8.7> DIRECT: Direct CCO Clock Output Enable
// <o8.8> BYPASS: PLL Bypass Enable
// </e7>
// <o9> Select Input Clock for Main clock (Register: MAINCLKSEL)
// <0=> IRC Oscillator
// <1=> Input Clock to System PLL
// <2=> WDT Oscillator
// <3=> System PLL Clock Out
// </e1>
// <e10> USB Clock Setup
// <e11> Use USB PLL
// <i> F_pll = M * F_in
// <i> F_in must be in the range of 10 MHz to 25 MHz
// <o12.0..1> Select Input Clock for usb_pllclkin (Register: USBPLLCLKSEL)
// <0=> IRC Oscillator
// <1=> System Oscillator
// <o13.0..4> M: PLL Multiplier Selection
// <1-32><#-1>
// <o13.5..6> P: PLL Divider Selection
// <0=> 2
// <1=> 4
// <2=> 8
// <3=> 16
// <o13.7> DIRECT: Direct CCO Clock Output Enable
// <o13.8> BYPASS: PLL Bypass Enable
// </e11>
// </e10>
// <o14.0..7> System AHB Divider <0-255>
// <i> 0 = is disabled
// <o15.0> SYS Clock Enable
// <o15.1> ROM Clock Enable
// <o15.2> RAM Clock Enable
// <o15.3> FLASH1 Clock Enable
// <o15.4> FLASH2 Clock Enable
// <o15.5> I2C Clock Enable
// <o15.6> GPIO Clock Enable
// <o15.7> CT16B0 Clock Enable
// <o15.8> CT16B1 Clock Enable
// <o15.9> CT32B0 Clock Enable
// <o15.10> CT32B1 Clock Enable
// <o15.11> SSP Clock Enable
// <o15.12> UART Clock Enable
// <o15.13> ADC Clock Enable
// <o15.14> USB_REG Clock Enable
// <o15.15> SWDT Clock Enable
// <o15.16> IOCON Clock Enable
// </e>
*/
#define CLOCK_SETUP 1
#define SYSCLK_SETUP 1
#define SYSOSC_SETUP 1
#define SYSOSCCTRL_Val 0x00000000
#define WDTOSC_SETUP 0
#define WDTOSCCTRL_Val 0x000000A0
#define SYSPLLCLKSEL_Val 0x00000001
#define SYSPLL_SETUP 1
#define SYSPLLCTRL_Val 0x00000025
#define MAINCLKSEL_Val 0x00000003
// ******** Code Red *********
// * Changed USBCLK_SETUP to 1
// ***************************
#define USBCLK_SETUP 1
#define USBPLL_SETUP 1
#define USBPLLCLKSEL_Val 0x00000001
#define USBPLLCTRL_Val 0x00000003
#define SYSAHBCLKDIV_Val 0x00000001
#define AHBCLKCTRL_Val 0x0001005F
/*--------------------- Memory Mapping Configuration -------------------------
//
// <e> Memory Mapping
// <o1.0..1> System Memory Remap (Register: SYSMEMREMAP)
// <0=> Bootloader mapped to address 0
// <1=> RAM mapped to address 0
// <2=> Flash mapped to address 0
// <3=> Flash mapped to address 0
// </e>
*/
#define MEMMAP_SETUP 0
#define SYSMEMREMAP_Val 0x00000001
/*
//-------- <<< end of configuration section >>> ------------------------------
*/
/*----------------------------------------------------------------------------
Check the register settings
*----------------------------------------------------------------------------*/
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
#define CHECK_RSVD(val, mask) (val & mask)
/* Clock Configuration -------------------------------------------------------*/
#if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003))
#error "SYSOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF))
#error "WDTOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2))
#error "SYSPLLCLKSEL: Value out of range!"
#endif
#if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF))
#error "SYSPLLCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003))
#error "MAINCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((USBPLLCLKSEL_Val), 0, 1))
#error "USBPLLCLKSEL: Value out of range!"
#endif
#if (CHECK_RSVD((USBPLLCTRL_Val), ~0x000001FF))
#error "USBPLLCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((USBPLLUEN_Val), ~0x00000001))
#error "USBPLLUEN: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
#error "SYSAHBCLKDIV: Value out of range!"
#endif
#if (CHECK_RSVD((AHBCLKCTRL_Val), ~0x0001FFFF))
#error "AHBCLKCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((SYSMEMREMAP_Val), ~0x00000003))
#error "SYSMEMREMAP: Invalid values of reserved bits!"
#endif
/*----------------------------------------------------------------------------
DEFINES
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define __XTAL (12000000UL) /* Oscillator frequency */
#define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */
#define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */
#define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F)
#define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
#if (CLOCK_SETUP) /* Clock Setup */
#if (SYSCLK_SETUP) /* System Clock Setup */
#if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
#if (__FREQSEL == 0)
#define __WDT_OSC_CLK ( 400000 / __DIVSEL)
#elif (__FREQSEL == 1)
#define __WDT_OSC_CLK ( 500000 / __DIVSEL)
#elif (__FREQSEL == 2)
#define __WDT_OSC_CLK ( 800000 / __DIVSEL)
#elif (__FREQSEL == 3)
#define __WDT_OSC_CLK (1100000 / __DIVSEL)
#elif (__FREQSEL == 4)
#define __WDT_OSC_CLK (1400000 / __DIVSEL)
#elif (__FREQSEL == 5)
#define __WDT_OSC_CLK (1600000 / __DIVSEL)
#elif (__FREQSEL == 6)
#define __WDT_OSC_CLK (1800000 / __DIVSEL)
#elif (__FREQSEL == 7)
#define __WDT_OSC_CLK (2000000 / __DIVSEL)
#elif (__FREQSEL == 8)
#define __WDT_OSC_CLK (2200000 / __DIVSEL)
#elif (__FREQSEL == 9)
#define __WDT_OSC_CLK (2400000 / __DIVSEL)
#elif (__FREQSEL == 10)
#define __WDT_OSC_CLK (2600000 / __DIVSEL)
#elif (__FREQSEL == 11)
#define __WDT_OSC_CLK (2700000 / __DIVSEL)
#elif (__FREQSEL == 12)
#define __WDT_OSC_CLK (2900000 / __DIVSEL)
#elif (__FREQSEL == 13)
#define __WDT_OSC_CLK (3100000 / __DIVSEL)
#elif (__FREQSEL == 14)
#define __WDT_OSC_CLK (3200000 / __DIVSEL)
#else
#define __WDT_OSC_CLK (3400000 / __DIVSEL)
#endif
#else
#define __WDT_OSC_CLK (1600000 / 2)
#endif // WDTOSC_SETUP
/* sys_pllclkin calculation */
#if ((SYSPLLCLKSEL_Val & 0x03) == 0)
#define __SYS_PLLCLKIN (__IRC_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
#define __SYS_PLLCLKIN (__SYS_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 2)
#define __SYS_PLLCLKIN (__WDT_OSC_CLK)
#else
#define __SYS_PLLCLKIN (0)
#endif
#if (SYSPLL_SETUP) /* System PLL Setup */
#define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
#else
#define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * (1))
#endif // SYSPLL_SETUP
/* main clock calculation */
#if ((MAINCLKSEL_Val & 0x03) == 0)
#define __MAIN_CLOCK (__IRC_OSC_CLK)
#elif ((MAINCLKSEL_Val & 0x03) == 1)
#define __MAIN_CLOCK (__SYS_PLLCLKIN)
#elif ((MAINCLKSEL_Val & 0x03) == 2)
#define __MAIN_CLOCK (__WDT_OSC_CLK)
#elif ((MAINCLKSEL_Val & 0x03) == 3)
#define __MAIN_CLOCK (__SYS_PLLCLKOUT)
#else
#define __MAIN_CLOCK (0)
#endif
#define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val)
#else // SYSCLK_SETUP
#if (SYSAHBCLKDIV_Val == 0)
#define __SYSTEM_CLOCK (0)
#else
#define __SYSTEM_CLOCK (__XTAL / SYSAHBCLKDIV_Val)
#endif
#endif // SYSCLK_SETUP
#else
#define __SYSTEM_CLOCK (__XTAL)
#endif // CLOCK_SETUP
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
uint32_t wdt_osc = 0;
/* Determine clock frequency according to clock register values */
switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
case 0: wdt_osc = 400000; break;
case 1: wdt_osc = 500000; break;
case 2: wdt_osc = 800000; break;
case 3: wdt_osc = 1100000; break;
case 4: wdt_osc = 1400000; break;
case 5: wdt_osc = 1600000; break;
case 6: wdt_osc = 1800000; break;
case 7: wdt_osc = 2000000; break;
case 8: wdt_osc = 2200000; break;
case 9: wdt_osc = 2400000; break;
case 10: wdt_osc = 2600000; break;
case 11: wdt_osc = 2700000; break;
case 12: wdt_osc = 2900000; break;
case 13: wdt_osc = 3100000; break;
case 14: wdt_osc = 3200000; break;
case 15: wdt_osc = 3400000; break;
}
wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* Input Clock to System PLL */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* System oscillator */
SystemCoreClock = __SYS_OSC_CLK;
break;
case 2: /* WDT Oscillator */
SystemCoreClock = wdt_osc;
break;
case 3: /* Reserved */
SystemCoreClock = 0;
break;
}
break;
case 2: /* WDT Oscillator */
SystemCoreClock = wdt_osc;
break;
case 3: /* System PLL Clock Out */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
SystemCoreClock = __IRC_OSC_CLK;
} else {
SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
}
break;
case 1: /* System oscillator */
if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
SystemCoreClock = __SYS_OSC_CLK;
} else {
SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
}
break;
case 2: /* WDT Oscillator */
if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
SystemCoreClock = wdt_osc;
} else {
SystemCoreClock = wdt_osc * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
}
break;
case 3: /* Reserved */
SystemCoreClock = 0;
break;
}
break;
}
SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;
}
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void)
{
#if (CLOCK_SETUP) /* Clock Setup */
#if (SYSCLK_SETUP) /* System Clock Setup */
#if (SYSOSC_SETUP) /* System Oscillator Setup */
uint32_t i;
LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* Power-up System Osc */
LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
for (i = 0; i < 200; i++) __NOP();
LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */
LPC_SYSCON->SYSPLLCLKUEN = 0x01;
while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
#if (SYSPLL_SETUP) /* System PLL Setup */
LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* Power-up SYSPLL */
while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
#endif
#endif
#if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(1 << 6); /* Power-up WDT Clock */
#endif
LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */
LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
LPC_SYSCON->MAINCLKUEN = 0x01;
while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
#endif
#if (USBCLK_SETUP) /* USB Clock Setup */
LPC_SYSCON->PDRUNCFG &= ~(1 << 10); /* Power-up USB PHY */
#if (USBPLL_SETUP) /* USB PLL Setup */
LPC_SYSCON->PDRUNCFG &= ~(1 << 8); /* Power-up USB PLL */
LPC_SYSCON->USBPLLCLKSEL = USBPLLCLKSEL_Val; /* Select PLL Input */
LPC_SYSCON->USBPLLCLKUEN = 0x01; /* Update Clock Source */
LPC_SYSCON->USBPLLCLKUEN = 0x00; /* Toggle Update Register */
LPC_SYSCON->USBPLLCLKUEN = 0x01;
while (!(LPC_SYSCON->USBPLLCLKUEN & 0x01)); /* Wait Until Updated */
LPC_SYSCON->USBPLLCTRL = USBPLLCTRL_Val;
while (!(LPC_SYSCON->USBPLLSTAT & 0x01)); /* Wait Until PLL Locked */
LPC_SYSCON->USBCLKSEL = 0x00; /* Select USB PLL */
#else
LPC_SYSCON->USBCLKSEL = 0x01; /* Select Main Clock */
#endif
#else
LPC_SYSCON->PDRUNCFG |= (1 << 10); /* Power-down USB PHY */
LPC_SYSCON->PDRUNCFG |= (1 << 8); /* Power-down USB PLL */
#endif
LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
LPC_SYSCON->SYSAHBCLKCTRL = AHBCLKCTRL_Val;
#endif
#if (MEMMAP_SETUP || MEMMAP_INIT) /* Memory Mapping Setup */
LPC_SYSCON->SYSMEMREMAP = SYSMEMREMAP_Val;
#endif
}

View File

@ -0,0 +1,424 @@
/*
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
#define INC_FREERTOS_H
/* include project specific config */
#include <config.h>
#ifdef ENABLE_FREERTOS
/*
* Include the generic headers required for the FreeRTOS port being used.
*/
#include <stddef.h>
/* Basic FreeRTOS definitions. */
#include "projdefs.h"
/* Application specific configuration options. */
#include "FreeRTOSConfig.h"
/* Definitions specific to the port being used. */
#include "portable.h"
/* Defines the prototype to which the application task hook function must
conform. */
typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
/*
* Check all the required application specific macros have been defined.
* These macros are application specific and (as downloaded) are defined
* within FreeRTOSConfig.h.
*/
#ifndef configUSE_PREEMPTION
#error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_IDLE_HOOK
#error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_TICK_HOOK
#error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_CO_ROUTINES
#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskPrioritySet
#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_uxTaskPriorityGet
#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskDelete
#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskCleanUpResources
#error Missing definition: INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskSuspend
#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskDelayUntil
#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef INCLUDE_vTaskDelay
#error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_16_BIT_TICKS
#error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif
#ifndef configUSE_APPLICATION_TASK_TAG
#define configUSE_APPLICATION_TASK_TAG 0
#endif
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#endif
#ifndef configUSE_RECURSIVE_MUTEXES
#define configUSE_RECURSIVE_MUTEXES 0
#endif
#ifndef configUSE_MUTEXES
#define configUSE_MUTEXES 0
#endif
#ifndef configUSE_COUNTING_SEMAPHORES
#define configUSE_COUNTING_SEMAPHORES 0
#endif
#ifndef configUSE_ALTERNATIVE_API
#define configUSE_ALTERNATIVE_API 0
#endif
#ifndef portCRITICAL_NESTING_IN_TCB
#define portCRITICAL_NESTING_IN_TCB 0
#endif
#ifndef configMAX_TASK_NAME_LEN
#define configMAX_TASK_NAME_LEN 16
#endif
#ifndef configIDLE_SHOULD_YIELD
#define configIDLE_SHOULD_YIELD 1
#endif
#if configMAX_TASK_NAME_LEN < 1
#undef configMAX_TASK_NAME_LEN
#define configMAX_TASK_NAME_LEN 1
#endif
#ifndef INCLUDE_xTaskResumeFromISR
#define INCLUDE_xTaskResumeFromISR 1
#endif
#ifndef INCLUDE_xTaskGetSchedulerState
#define INCLUDE_xTaskGetSchedulerState 0
#endif
#if ( configUSE_MUTEXES == 1 )
/* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism
within the mutex implementation so must be available if mutexes are used. */
#undef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#else
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 0
#endif
#endif
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
#endif
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
#endif
#ifndef configQUEUE_REGISTRY_SIZE
#define configQUEUE_REGISTRY_SIZE 0
#endif
#if configQUEUE_REGISTRY_SIZE < 1
#define configQUEUE_REGISTRY_SIZE 0
#define vQueueAddToRegistry( xQueue, pcName )
#define vQueueUnregisterQueue( xQueue )
#endif
/* Remove any unused trace macros. */
#ifndef traceSTART
/* Used to perform any necessary initialisation - for example, open a file
into which trace is to be written. */
#define traceSTART()
#endif
#ifndef traceEND
/* Use to close a trace, for example close a file into which trace has been
written. */
#define traceEND()
#endif
#ifndef traceTASK_SWITCHED_IN
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the selected task. */
#define traceTASK_SWITCHED_IN()
#endif
#ifndef traceTASK_SWITCHED_OUT
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
to the task control block of the task being switched out. */
#define traceTASK_SWITCHED_OUT()
#endif
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
/* Task is about to block because it cannot read from a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the read was attempted. pxCurrentTCB points to the TCB of the
task that attempted the read. */
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
#endif
#ifndef traceBLOCKING_ON_QUEUE_SEND
/* Task is about to block because it cannot write to a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
upon which the write was attempted. pxCurrentTCB points to the TCB of the
task that attempted the write. */
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
#endif
#ifndef configCHECK_FOR_STACK_OVERFLOW
#define configCHECK_FOR_STACK_OVERFLOW 0
#endif
/* The following event macros are embedded in the kernel API calls. */
#ifndef traceQUEUE_CREATE
#define traceQUEUE_CREATE( pxNewQueue )
#endif
#ifndef traceQUEUE_CREATE_FAILED
#define traceQUEUE_CREATE_FAILED()
#endif
#ifndef traceCREATE_MUTEX
#define traceCREATE_MUTEX( pxNewQueue )
#endif
#ifndef traceCREATE_MUTEX_FAILED
#define traceCREATE_MUTEX_FAILED()
#endif
#ifndef traceGIVE_MUTEX_RECURSIVE
#define traceGIVE_MUTEX_RECURSIVE( pxMutex )
#endif
#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
#endif
#ifndef traceTAKE_MUTEX_RECURSIVE
#define traceTAKE_MUTEX_RECURSIVE( pxMutex )
#endif
#ifndef traceCREATE_COUNTING_SEMAPHORE
#define traceCREATE_COUNTING_SEMAPHORE()
#endif
#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
#endif
#ifndef traceQUEUE_SEND
#define traceQUEUE_SEND( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FAILED
#define traceQUEUE_SEND_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE
#define traceQUEUE_RECEIVE( pxQueue )
#endif
#ifndef traceQUEUE_PEEK
#define traceQUEUE_PEEK( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FAILED
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FROM_ISR
#define traceQUEUE_SEND_FROM_ISR( pxQueue )
#endif
#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FROM_ISR
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
#endif
#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
#endif
#ifndef traceQUEUE_DELETE
#define traceQUEUE_DELETE( pxQueue )
#endif
#ifndef traceTASK_CREATE
#define traceTASK_CREATE( pxNewTCB )
#endif
#ifndef traceTASK_CREATE_FAILED
#define traceTASK_CREATE_FAILED( pxNewTCB )
#endif
#ifndef traceTASK_DELETE
#define traceTASK_DELETE( pxTaskToDelete )
#endif
#ifndef traceTASK_DELAY_UNTIL
#define traceTASK_DELAY_UNTIL()
#endif
#ifndef traceTASK_DELAY
#define traceTASK_DELAY()
#endif
#ifndef traceTASK_PRIORITY_SET
#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
#endif
#ifndef traceTASK_SUSPEND
#define traceTASK_SUSPEND( pxTaskToSuspend )
#endif
#ifndef traceTASK_RESUME
#define traceTASK_RESUME( pxTaskToResume )
#endif
#ifndef traceTASK_RESUME_FROM_ISR
#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
#endif
#ifndef traceTASK_INCREMENT_TICK
#define traceTASK_INCREMENT_TICK( xTickCount )
#endif
#ifndef configGENERATE_RUN_TIME_STATS
#define configGENERATE_RUN_TIME_STATS 0
#endif
#if ( configGENERATE_RUN_TIME_STATS == 1 )
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
#error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.
#endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */
#ifndef portGET_RUN_TIME_COUNTER_VALUE
#error If configGENERATE_RUN_TIME_STATS is defined then portGET_RUN_TIME_COUNTER_VALUE must also be defined. portGET_RUN_TIME_COUNTER_VALUE should evaluate to the counter value of the timer/counter peripheral used as the run time counter time base.
#endif /* portGET_RUN_TIME_COUNTER_VALUE */
#endif /* configGENERATE_RUN_TIME_STATS */
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
#endif
#ifndef configUSE_MALLOC_FAILED_HOOK
#define configUSE_MALLOC_FAILED_HOOK 0
#endif
#ifndef portPRIVILEGE_BIT
#define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )
#endif
#ifndef portYIELD_WITHIN_API
#define portYIELD_WITHIN_API portYIELD
#endif
#ifndef pvPortMallocAligned
#define pvPortMallocAligned( x, puxStackBuffer ) ( ( puxStackBuffer == NULL ) ? ( pvPortMalloc( x ) ) : ( puxStackBuffer ) )
#endif
#ifndef vPortFreeAligned
#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
#endif
#endif /* ENABLE_FREERTOS */
#endif /* INC_FREERTOS_H */

View File

@ -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 */

View File

@ -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
*<pre>
portBASE_TYPE xCoRoutineCreate(
crCOROUTINE_CODE pxCoRoutineCode,
unsigned portBASE_TYPE uxPriority,
unsigned portBASE_TYPE uxIndex
);</pre>
*
* Create a new co-routine and add it to the list of co-routines that are
* ready to run.
*
* @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
* functions require special syntax - see the co-routine section of the WEB
* documentation for more information.
*
* @param uxPriority The priority with respect to other co-routines at which
* the co-routine will run.
*
* @param uxIndex Used to distinguish between different co-routines that
* execute the same function. See the example below and the co-routine section
* of the WEB documentation for further information.
*
* @return pdPASS if the co-routine was successfully created and added to a ready
* list, otherwise an error code defined with ProjDefs.h.
*
* Example usage:
<pre>
// Co-routine to be created.
void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables.
static const char cLedToFlash[ 2 ] = { 5, 6 };
static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// This co-routine just delays for a fixed period, then toggles
// an LED. Two co-routines are created using this function, so
// the uxIndex parameter is used to tell the co-routine which
// LED to flash and how long to delay. This assumes xQueue has
// already been created.
vParTestToggleLED( cLedToFlash[ uxIndex ] );
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
}
// Must end every co-routine with a call to crEND();
crEND();
}
// Function that creates two co-routines.
void vOtherFunction( void )
{
unsigned char ucParameterToPass;
xTaskHandle xHandle;
// Create two co-routines at priority 0. The first is given index 0
// so (from the code above) toggles LED 5 every 200 ticks. The second
// is given index 1 so toggles LED 6 every 400 ticks.
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
{
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
}
}
</pre>
* \defgroup xCoRoutineCreate xCoRoutineCreate
* \ingroup Tasks
*/
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
/**
* croutine. h
*<pre>
void vCoRoutineSchedule( void );</pre>
*
* Run a co-routine.
*
* vCoRoutineSchedule() executes the highest priority co-routine that is able
* to run. The co-routine will execute until it either blocks, yields or is
* preempted by a task. Co-routines execute cooperatively so one
* co-routine cannot be preempted by another, but can be preempted by a task.
*
* If an application comprises of both tasks and co-routines then
* vCoRoutineSchedule should be called from the idle task (in an idle task
* hook).
*
* Example usage:
<pre>
// This idle task hook will schedule a co-routine each time it is called.
// The rest of the idle task will execute between co-routine calls.
void vApplicationIdleHook( void )
{
vCoRoutineSchedule();
}
// Alternatively, if you do not require any other part of the idle task to
// execute, the idle task hook can call vCoRoutineScheduler() within an
// infinite loop.
void vApplicationIdleHook( void )
{
for( ;; )
{
vCoRoutineSchedule();
}
}
</pre>
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
* \ingroup Tasks
*/
void vCoRoutineSchedule( void );
/**
* croutine. h
* <pre>
crSTART( xCoRoutineHandle xHandle );</pre>
*
* This macro MUST always be called at the start of a co-routine function.
*
* Example usage:
<pre>
// Co-routine to be created.
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static long ulAVariable;
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// Co-routine functionality goes here.
}
// Must end every co-routine with a call to crEND();
crEND();
}</pre>
* \defgroup crSTART crSTART
* \ingroup Tasks
*/
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
/**
* croutine. h
* <pre>
crEND();</pre>
*
* This macro MUST always be called at the end of a co-routine function.
*
* Example usage:
<pre>
// Co-routine to be created.
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static long ulAVariable;
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// Co-routine functionality goes here.
}
// Must end every co-routine with a call to crEND();
crEND();
}</pre>
* \defgroup crSTART crSTART
* \ingroup Tasks
*/
#define crEND() }
/*
* These macros are intended for internal use by the co-routine implementation
* only. The macros should not be used directly by application writers.
*/
#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
/**
* croutine. h
*<pre>
crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
*
* Delay a co-routine for a fixed period of time.
*
* crDELAY can only be called from the co-routine function itself - not
* from within a function called by the co-routine function. This is because
* co-routines do not maintain their own stack.
*
* @param xHandle The handle of the co-routine to delay. This is the xHandle
* parameter of the co-routine function.
*
* @param xTickToDelay The number of ticks that the co-routine should delay
* for. The actual amount of time this equates to is defined by
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
* can be used to convert ticks to milliseconds.
*
* Example usage:
<pre>
// Co-routine to be created.
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables.
// We are to delay for 200ms.
static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
// Must start every co-routine with a call to crSTART();
crSTART( xHandle );
for( ;; )
{
// Delay for 200ms.
crDELAY( xHandle, xDelayTime );
// Do something here.
}
// Must end every co-routine with a call to crEND();
crEND();
}</pre>
* \defgroup crDELAY crDELAY
* \ingroup Tasks
*/
#define crDELAY( xHandle, xTicksToDelay ) \
if( xTicksToDelay > 0 ) \
{ \
vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \
} \
crSET_STATE0( xHandle );
/**
* <pre>
crQUEUE_SEND(
xCoRoutineHandle xHandle,
xQueueHandle pxQueue,
void *pvItemToQueue,
portTickType xTicksToWait,
portBASE_TYPE *pxResult
)</pre>
*
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
*
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
* xQueueSend() and xQueueReceive() can only be used from tasks.
*
* crQUEUE_SEND can only be called from the co-routine function itself - not
* from within a function called by the co-routine function. This is because
* co-routines do not maintain their own stack.
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xHandle The handle of the calling co-routine. This is the xHandle
* parameter of the co-routine function.
*
* @param pxQueue The handle of the queue on which the data will be posted.
* The handle is obtained as the return value when the queue is created using
* the xQueueCreate() API function.
*
* @param pvItemToQueue A pointer to the data being posted onto the queue.
* The number of bytes of each queued item is specified when the queue is
* created. This number of bytes is copied from pvItemToQueue into the queue
* itself.
*
* @param xTickToDelay The number of ticks that the co-routine should block
* to wait for space to become available on the queue, should space not be
* available immediately. The actual amount of time this equates to is defined
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
* below).
*
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
* data was successfully posted onto the queue, otherwise it will be set to an
* error defined within ProjDefs.h.
*
* Example usage:
<pre>
// Co-routine function that blocks for a fixed period then posts a number onto
// a queue.
static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static portBASE_TYPE xNumberToPost = 0;
static portBASE_TYPE xResult;
// Co-routines must begin with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// This assumes the queue has already been created.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
if( xResult != pdPASS )
{
// The message was not posted!
}
// Increment the number to be posted onto the queue.
xNumberToPost++;
// Delay for 100 ticks.
crDELAY( xHandle, 100 );
}
// Co-routines must end with a call to crEND().
crEND();
}</pre>
* \defgroup crQUEUE_SEND crQUEUE_SEND
* \ingroup Tasks
*/
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
{ \
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \
if( *pxResult == errQUEUE_BLOCKED ) \
{ \
crSET_STATE0( xHandle ); \
*pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \
} \
if( *pxResult == errQUEUE_YIELD ) \
{ \
crSET_STATE1( xHandle ); \
*pxResult = pdPASS; \
} \
}
/**
* croutine. h
* <pre>
crQUEUE_RECEIVE(
xCoRoutineHandle xHandle,
xQueueHandle pxQueue,
void *pvBuffer,
portTickType xTicksToWait,
portBASE_TYPE *pxResult
)</pre>
*
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
*
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
* xQueueSend() and xQueueReceive() can only be used from tasks.
*
* crQUEUE_RECEIVE can only be called from the co-routine function itself - not
* from within a function called by the co-routine function. This is because
* co-routines do not maintain their own stack.
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xHandle The handle of the calling co-routine. This is the xHandle
* parameter of the co-routine function.
*
* @param pxQueue The handle of the queue from which the data will be received.
* The handle is obtained as the return value when the queue is created using
* the xQueueCreate() API function.
*
* @param pvBuffer The buffer into which the received item is to be copied.
* The number of bytes of each queued item is specified when the queue is
* created. This number of bytes is copied into pvBuffer.
*
* @param xTickToDelay The number of ticks that the co-routine should block
* to wait for data to become available from the queue, should data not be
* available immediately. The actual amount of time this equates to is defined
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
* crQUEUE_SEND example).
*
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
* data was successfully retrieved from the queue, otherwise it will be set to
* an error code as defined within ProjDefs.h.
*
* Example usage:
<pre>
// A co-routine receives the number of an LED to flash from a queue. It
// blocks on the queue until the number is received.
static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
static portBASE_TYPE xResult;
static unsigned portBASE_TYPE uxLEDToFlash;
// All co-routines must start with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// Wait for data to become available on the queue.
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
if( xResult == pdPASS )
{
// We received the LED to flash - flash it!
vParTestToggleLED( uxLEDToFlash );
}
}
crEND();
}</pre>
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
* \ingroup Tasks
*/
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
{ \
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \
if( *pxResult == errQUEUE_BLOCKED ) \
{ \
crSET_STATE0( xHandle ); \
*pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \
} \
if( *pxResult == errQUEUE_YIELD ) \
{ \
crSET_STATE1( xHandle ); \
*pxResult = pdPASS; \
} \
}
/**
* croutine. h
* <pre>
crQUEUE_SEND_FROM_ISR(
xQueueHandle pxQueue,
void *pvItemToQueue,
portBASE_TYPE xCoRoutinePreviouslyWoken
)</pre>
*
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
* functions used by tasks.
*
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
* xQueueReceiveFromISR() can only be used to pass data between a task and and
* ISR.
*
* crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
* that is being used from within a co-routine.
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xQueue The handle to the queue on which the item is to be posted.
*
* @param pvItemToQueue A pointer to the item that is to be placed on the
* queue. The size of the items the queue will hold was defined when the
* queue was created, so this many bytes will be copied from pvItemToQueue
* into the queue storage area.
*
* @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
* the same queue multiple times from a single interrupt. The first call
* should always pass in pdFALSE. Subsequent calls should pass in
* the value returned from the previous call.
*
* @return pdTRUE if a co-routine was woken by posting onto the queue. This is
* used by the ISR to determine if a context switch may be required following
* the ISR.
*
* Example usage:
<pre>
// A co-routine that blocks on a queue waiting for characters to be received.
static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
char cRxedChar;
portBASE_TYPE xResult;
// All co-routines must start with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// Wait for data to become available on the queue. This assumes the
// queue xCommsRxQueue has already been created!
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
// Was a character received?
if( xResult == pdPASS )
{
// Process the character here.
}
}
// All co-routines must end with a call to crEND().
crEND();
}
// An ISR that uses a queue to send characters received on a serial port to
// a co-routine.
void vUART_ISR( void )
{
char cRxedChar;
portBASE_TYPE xCRWokenByPost = pdFALSE;
// We loop around reading characters until there are none left in the UART.
while( UART_RX_REG_NOT_EMPTY() )
{
// Obtain the character from the UART.
cRxedChar = UART_RX_REG;
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
// the first time around the loop. If the post causes a co-routine
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
// In this manner we can ensure that if more than one co-routine is
// blocked on the queue only one is woken by this ISR no matter how
// many characters are posted to the queue.
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
}
}</pre>
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
* \ingroup Tasks
*/
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
/**
* croutine. h
* <pre>
crQUEUE_SEND_FROM_ISR(
xQueueHandle pxQueue,
void *pvBuffer,
portBASE_TYPE * pxCoRoutineWoken
)</pre>
*
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
* functions used by tasks.
*
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
* xQueueReceiveFromISR() can only be used to pass data between a task and and
* ISR.
*
* crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
* from a queue that is being used from within a co-routine (a co-routine
* posted to the queue).
*
* See the co-routine section of the WEB documentation for information on
* passing data between tasks and co-routines and between ISR's and
* co-routines.
*
* @param xQueue The handle to the queue on which the item is to be posted.
*
* @param pvBuffer A pointer to a buffer into which the received item will be
* placed. The size of the items the queue will hold was defined when the
* queue was created, so this many bytes will be copied from the queue into
* pvBuffer.
*
* @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
* available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
* co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
* *pxCoRoutineWoken will remain unchanged.
*
* @return pdTRUE an item was successfully received from the queue, otherwise
* pdFALSE.
*
* Example usage:
<pre>
// A co-routine that posts a character to a queue then blocks for a fixed
// period. The character is incremented each time.
static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
{
// cChar holds its value while this co-routine is blocked and must therefore
// be declared static.
static char cCharToTx = 'a';
portBASE_TYPE xResult;
// All co-routines must start with a call to crSTART().
crSTART( xHandle );
for( ;; )
{
// Send the next character to the queue.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
if( xResult == pdPASS )
{
// The character was successfully posted to the queue.
}
else
{
// Could not post the character to the queue.
}
// Enable the UART Tx interrupt to cause an interrupt in this
// hypothetical UART. The interrupt will obtain the character
// from the queue and send it.
ENABLE_RX_INTERRUPT();
// Increment to the next character then block for a fixed period.
// cCharToTx will maintain its value across the delay as it is
// declared static.
cCharToTx++;
if( cCharToTx > 'x' )
{
cCharToTx = 'a';
}
crDELAY( 100 );
}
// All co-routines must end with a call to crEND().
crEND();
}
// An ISR that uses a queue to receive characters to send on a UART.
void vUART_ISR( void )
{
char cCharToTx;
portBASE_TYPE xCRWokenByPost = pdFALSE;
while( UART_TX_REG_EMPTY() )
{
// Are there any characters in the queue waiting to be sent?
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
// is woken by the post - ensuring that only a single co-routine is
// woken no matter how many times we go around this loop.
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
{
SEND_CHARACTER( cCharToTx );
}
}
}</pre>
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
* \ingroup Tasks
*/
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
/*
* This function is intended for internal use by the co-routine macros only.
* The macro nature of the co-routine implementation requires that the
* prototype appears here. The function should not be used by application
* writers.
*
* Removes the current co-routine from its ready list and places it in the
* appropriate delayed list.
*/
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
/*
* This function is intended for internal use by the queue implementation only.
* The function should not be used by application writers.
*
* Removes the highest priority co-routine from the event list and places it in
* the pending ready list.
*/
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
#ifdef __cplusplus
}
#endif
#endif /* CO_ROUTINE_H */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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
* <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
*
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
* The queue length is 1 as this is a binary semaphore. The data size is 0
* as we don't want to actually store any data - we just want to know if the
* queue is empty or full.
*
* This type of semaphore can be used for pure synchronisation between tasks or
* between an interrupt and a task. The semaphore need not be given back once
* obtained, so one task/interrupt can continuously 'give' the semaphore while
* another continuously 'takes' the semaphore. For this reason this type of
* semaphore does not use a priority inheritance mechanism. For an alternative
* that does use priority inheritance see xSemaphoreCreateMutex().
*
* @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
// This is a macro so pass the variable in directly.
vSemaphoreCreateBinary( xSemaphore );
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores
*/
#define vSemaphoreCreateBinary( xSemaphore ) { \
xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
if( xSemaphore != NULL ) \
{ \
xSemaphoreGive( xSemaphore ); \
} \
}
/**
* semphr. h
* <pre>xSemaphoreTake(
* xSemaphoreHandle xSemaphore,
* portTickType xBlockTime
* )</pre>
*
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting().
*
* @param xSemaphore A handle to the semaphore being taken - obtained when
* the semaphore was created.
*
* @param xBlockTime The time in ticks to wait for the semaphore to become
* available. The macro portTICK_RATE_MS can be used to convert this to a
* real time. A block time of zero can be used to poll the semaphore. A block
* time of portMAX_DELAY can be used to block indefinitely (provided
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
*
* @return pdTRUE if the semaphore was obtained. pdFALSE
* if xBlockTime expired without the semaphore becoming available.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore = NULL;
// A task that creates a semaphore.
void vATask( void * pvParameters )
{
// Create the semaphore to guard a shared resource.
vSemaphoreCreateBinary( xSemaphore );
}
// A task that uses the semaphore.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xSemaphore != NULL )
{
// See if we can obtain the semaphore. If the semaphore is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the semaphore and can now access the
// shared resource.
// ...
// We have finished accessing the shared resource. Release the
// semaphore.
xSemaphoreGive( xSemaphore );
}
else
{
// We could not obtain the semaphore and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreTake xSemaphoreTake
* \ingroup Semaphores
*/
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
/**
* semphr. h
* xSemaphoreTakeRecursive(
* xSemaphoreHandle xMutex,
* portTickType xBlockTime
* )
*
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
* The mutex must have previously been created using a call to
* xSemaphoreCreateRecursiveMutex();
*
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
* macro to be available.
*
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being obtained. This is the
* handle returned by xSemaphoreCreateRecursiveMutex();
*
* @param xBlockTime The time in ticks to wait for the semaphore to become
* available. The macro portTICK_RATE_MS can be used to convert this to a
* real time. A block time of zero can be used to poll the semaphore. If
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
* return immediately no matter what the value of xBlockTime.
*
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
* expired without the semaphore becoming available.
*
* Example usage:
<pre>
xSemaphoreHandle xMutex = NULL;
// A task that creates a mutex.
void vATask( void * pvParameters )
{
// Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex();
}
// A task that uses the mutex.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xMutex != NULL )
{
// See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the mutex and can now access the
// shared resource.
// ...
// For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside
// a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
// The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, but instead buried in a more complex
// call structure. This is just for illustrative purposes.
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
// Now the mutex can be taken by other tasks.
}
else
{
// We could not obtain the mutex and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
* \ingroup Semaphores
*/
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime )
/*
* xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
*
* The source code that implements the alternative (Alt) API is much
* simpler because it executes everything from within a critical section.
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
* preferred fully featured API too. The fully featured API has more
* complex code that takes longer to execute, but makes much less use of
* critical sections. Therefore the alternative API sacrifices interrupt
* responsiveness to gain execution speed, whereas the fully featured API
* sacrifices execution speed to ensure better interrupt responsiveness.
*/
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )
/**
* semphr. h
* <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
* xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
*
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
* an alternative which can be used from an ISR.
*
* This macro must also not be used on semaphores created using
* xSemaphoreCreateRecursiveMutex().
*
* @param xSemaphore A handle to the semaphore being released. This is the
* handle returned when the semaphore was created.
*
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
* Semaphores are implemented using queues. An error can occur if there is
* no space on the queue to post a message - indicating that the
* semaphore was not first obtained correctly.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore = NULL;
void vATask( void * pvParameters )
{
// Create the semaphore to guard a shared resource.
vSemaphoreCreateBinary( xSemaphore );
if( xSemaphore != NULL )
{
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{
// We would expect this call to fail because we cannot give
// a semaphore without first "taking" it!
}
// Obtain the semaphore - don't block if the semaphore is not
// immediately available.
if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
{
// We now have the semaphore and can access the shared resource.
// ...
// We have finished accessing the shared resource so can free the
// semaphore.
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{
// We would not expect this call to fail because we must have
// obtained the semaphore to get here.
}
}
}
}
</pre>
* \defgroup xSemaphoreGive xSemaphoreGive
* \ingroup Semaphores
*/
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
*
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
* The mutex must have previously been created using a call to
* xSemaphoreCreateRecursiveMutex();
*
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
* macro to be available.
*
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* @param xMutex A handle to the mutex being released, or 'given'. This is the
* handle returned by xSemaphoreCreateMutex();
*
* @return pdTRUE if the semaphore was given.
*
* Example usage:
<pre>
xSemaphoreHandle xMutex = NULL;
// A task that creates a mutex.
void vATask( void * pvParameters )
{
// Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex();
}
// A task that uses the mutex.
void vAnotherTask( void * pvParameters )
{
// ... Do other things.
if( xMutex != NULL )
{
// See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
{
// We were able to obtain the mutex and can now access the
// shared resource.
// ...
// For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside
// a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
// The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back
// three times. Again it is unlikely that real code would have
// these calls sequentially, it would be more likely that the calls
// to xSemaphoreGiveRecursive() would be called as a call stack
// unwound. This is just for demonstrative purposes.
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex );
// Now the mutex can be taken by other tasks.
}
else
{
// We could not obtain the mutex and can therefore not access
// the shared resource safely.
}
}
}
</pre>
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
* \ingroup Semaphores
*/
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex )
/*
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
*
* The source code that implements the alternative (Alt) API is much
* simpler because it executes everything from within a critical section.
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
* preferred fully featured API too. The fully featured API has more
* complex code that takes longer to execute, but makes much less use of
* critical sections. Therefore the alternative API sacrifices interrupt
* responsiveness to gain execution speed, whereas the fully featured API
* sacrifices execution speed to ensure better interrupt responsiveness.
*/
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>
xSemaphoreGiveFromISR(
xSemaphoreHandle xSemaphore,
signed portBASE_TYPE *pxHigherPriorityTaskWoken
)</pre>
*
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
* created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
*
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
* must not be used with this macro.
*
* This macro can be used from an ISR.
*
* @param xSemaphore A handle to the semaphore being released. This is the
* handle returned when the semaphore was created.
*
* @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
* *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
* to unblock, and the unblocked task has a priority higher than the currently
* running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
* a context switch should be requested before the interrupt is exited.
*
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
*
* Example usage:
<pre>
\#define LONG_TIME 0xffff
\#define TICKS_TO_WAIT 10
xSemaphoreHandle xSemaphore = NULL;
// Repetitive task.
void vATask( void * pvParameters )
{
for( ;; )
{
// We want this task to run every 10 ticks of a timer. The semaphore
// was created before this task was started.
// Block waiting for the semaphore to become available.
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
{
// It is time to execute.
// ...
// We have finished our task. Return to the top of the loop where
// we will block on the semaphore until it is time to execute
// again. Note when using the semaphore for synchronisation with an
// ISR in this manner there is no need to 'give' the semaphore back.
}
}
}
// Timer ISR
void vTimerISR( void * pvParameters )
{
static unsigned char ucLocalTickCount = 0;
static signed portBASE_TYPE xHigherPriorityTaskWoken;
// A timer tick has occurred.
// ... Do other time functions.
// Is it time for vATask () to run?
xHigherPriorityTaskWoken = pdFALSE;
ucLocalTickCount++;
if( ucLocalTickCount >= TICKS_TO_WAIT )
{
// Unblock the task by releasing the semaphore.
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
// Reset the count so we release the semaphore again in 10 ticks time.
ucLocalTickCount = 0;
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
// We can force a context switch here. Context switching from an
// ISR uses port specific syntax. Check the demo task for your port
// to find the syntax required.
}
}
</pre>
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
* \ingroup Semaphores
*/
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK )
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
*
* <i>Macro</i> that implements a mutex semaphore by using the existing queue
* mechanism.
*
* Mutexes created using this macro can be accessed using the xSemaphoreTake()
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
* xSemaphoreGiveRecursive() macros should not be used.
*
* This type of semaphore uses a priority inheritance mechanism so a task
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
* semaphore it is no longer required.
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
* See vSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
* xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateMutex();
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
* \ingroup Semaphores
*/
#define xSemaphoreCreateMutex() xQueueCreateMutex()
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
*
* <i>Macro</i> that implements a recursive mutex by using the existing queue
* mechanism.
*
* Mutexes created using this macro can be accessed using the
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
* xSemaphoreTake() and xSemaphoreGive() macros should not be used.
*
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
* doesn't become available again until the owner has called
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
* if a task successfully 'takes' the same mutex 5 times then the mutex will
* not be available to any other task until it has also 'given' the mutex back
* exactly five times.
*
* This type of semaphore uses a priority inheritance mechanism so a task
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
* semaphore it is no longer required.
*
* Mutex type semaphores cannot be used from within interrupt service routines.
*
* See vSemaphoreCreateBinary() for an alternative implementation that can be
* used for pure synchronisation (where one task or interrupt always 'gives' the
* semaphore and another always 'takes' the semaphore) and from within interrupt
* service routines.
*
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
* xSemaphoreHandle.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateRecursiveMutex();
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
* \ingroup Semaphores
*/
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
/**
* semphr. h
* <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
*
* <i>Macro</i> that creates a counting semaphore by using the existing
* queue mechanism.
*
* Counting semaphores are typically used for two things:
*
* 1) Counting events.
*
* In this usage scenario an event handler will 'give' a semaphore each time
* an event occurs (incrementing the semaphore count value), and a handler
* task will 'take' a semaphore each time it processes an event
* (decrementing the semaphore count value). The count value is therefore
* the difference between the number of events that have occurred and the
* number that have been processed. In this case it is desirable for the
* initial count value to be zero.
*
* 2) Resource management.
*
* In this usage scenario the count value indicates the number of resources
* available. To obtain control of a resource a task must first obtain a
* semaphore - decrementing the semaphore count value. When the count value
* reaches zero there are no free resources. When a task finishes with the
* resource it 'gives' the semaphore back - incrementing the semaphore count
* value. In this case it is desirable for the initial count value to be
* equal to the maximum count value, indicating that all resources are free.
*
* @param uxMaxCount The maximum count value that can be reached. When the
* semaphore reaches this value it can no longer be 'given'.
*
* @param uxInitialCount The count value assigned to the semaphore when it is
* created.
*
* @return Handle to the created semaphore. Null if the semaphore could not be
* created.
*
* Example usage:
<pre>
xSemaphoreHandle xSemaphore;
void vATask( void * pvParameters )
{
xSemaphoreHandle xSemaphore = NULL;
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
// The max value to which the semaphore can count should be 10, and the
// initial value assigned to the count should be 0.
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
if( xSemaphore != NULL )
{
// The semaphore was created successfully.
// The semaphore can now be used.
}
}
</pre>
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
* \ingroup Semaphores
*/
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount )
#endif /* SEMAPHORE_H */

File diff suppressed because it is too large Load Diff

View File

@ -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 <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include <FreeRTOS.h>
#ifdef ENABLE_FREERTOS
/*-----------------------------------------------------------*/
#include <task.h>
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Allocate the memory for the heap. The struct is used to force byte
alignment without using any non-portable code. */
static union xRTOS_HEAP
{
#if portBYTE_ALIGNMENT == 8
volatile portDOUBLE dDummy;
#else
volatile unsigned long ulDummy;
#endif
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
/* Define the linked list structure. This is used to link free blocks in order
of their size. */
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} xBlockLink;
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
/* Create a couple of list links to mark the start and end of the list. */
static xBlockLink xStart, xEnd;
/* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */
static size_t xFreeBytesRemaining = configTOTAL_HEAP_SIZE;
/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
/*
* Insert a block into the list of free blocks - which is ordered by size of
* the block. Small blocks at the start of the list and large blocks at the end
* of the list.
*/
#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \
{ \
xBlockLink *pxIterator; \
size_t xBlockSize; \
\
xBlockSize = pxBlockToInsert->xBlockSize; \
\
/* Iterate through the list until a block is found that has a larger size */ \
/* than the block we are inserting. */ \
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
{ \
/* There is nothing to do here - just iterate to the correct position. */ \
} \
\
/* Update the list to include the block being inserted in the correct */ \
/* position. */ \
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \
pxIterator->pxNextFreeBlock = pxBlockToInsert; \
}
/*-----------------------------------------------------------*/
#define prvHeapInit() \
{ \
xBlockLink *pxFirstFreeBlock; \
\
/* xStart is used to hold a pointer to the first item in the list of free */ \
/* blocks. The void cast is used to prevent compiler warnings. */ \
xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; \
xStart.xBlockSize = ( size_t ) 0; \
\
/* xEnd is used to mark the end of the list of free blocks. */ \
xEnd.xBlockSize = configTOTAL_HEAP_SIZE; \
xEnd.pxNextFreeBlock = NULL; \
\
/* To start with there is a single free block that is sized to take up the \
entire heap space. */ \
pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \
pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \
pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \
}
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE;
void *pvReturn = NULL;
vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
initialisation to setup the list of free blocks. */
if( xHeapHasBeenInitialised == pdFALSE )
{
prvHeapInit();
xHeapHasBeenInitialised = pdTRUE;
}
/* The wanted size is increased so it can contain a xBlockLink
structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += heapSTRUCT_SIZE;
/* Ensure that blocks are always aligned to the required number of bytes. */
if( xWantedSize & portBYTE_ALIGNMENT_MASK )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
}
if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) )
{
/* Blocks are stored in byte order - traverse the list from the start
(smallest) block until one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If we found the end marker then a block of adequate size was not found. */
if( pxBlock != &xEnd )
{
/* Return the memory space - jumping over the xBlockLink structure
at its start. */
pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE );
/* This block is being returned for use so must be taken our of the
list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{
/* This block is to be split into two. Create a new block
following the number of bytes requested. The void cast is
used to prevent byte alignment warnings from the compiler. */
pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize );
/* Calculate the sizes of two blocks split from the single
block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
}
xFreeBytesRemaining -= 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 */

View File

@ -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 <stdlib.h>
#include <FreeRTOS.h>
#ifdef ENABLE_FREERTOS
/*-----------------------------------------------------------*/
#include <list.h>
/*-----------------------------------------------------------
* PUBLIC LIST API documented in list.h
*----------------------------------------------------------*/
void vListInitialise( xList *pxList )
{
/* The list structure contains a list item which is used to mark the
end of the list. To initialise the list the list end is inserted
as the only list entry. */
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );
/* The list end value is the highest possible value in the list to
ensure it remains at the end of the list. */
pxList->xListEnd.xItemValue = portMAX_DELAY;
/* The list end next and previous pointers point to itself so we know
when the list is empty. */
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );
pxList->uxNumberOfItems = 0;
}
/*-----------------------------------------------------------*/
void vListInitialiseItem( xListItem *pxItem )
{
/* Make sure the list item is not recorded as being on a list. */
pxItem->pvContainer = NULL;
}
/*-----------------------------------------------------------*/
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )
{
volatile xListItem * pxIndex;
/* Insert a new list item into pxList, but rather than sort the list,
makes the new list item the last item to be removed by a call to
pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by
the pxIndex member. */
pxIndex = pxList->pxIndex;
pxNewListItem->pxNext = pxIndex->pxNext;
pxNewListItem->pxPrevious = pxList->pxIndex;
pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;
pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;
/* Remember which list the item is in. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/
void vListInsert( xList *pxList, xListItem *pxNewListItem )
{
volatile xListItem *pxIterator;
portTickType xValueOfInsertion;
/* Insert the new list item into the list, sorted in ulListItem order. */
xValueOfInsertion = pxNewListItem->xItemValue;
/* If the list already contains a list item with the same item value then
the new list item should be placed after it. This ensures that TCB's which
are stored in ready lists (all of which have the same ulListItem value)
get an equal share of the CPU. However, if the xItemValue is the same as
the back marker the iteration loop below will not end. This means we need
to guard against this by checking the value first and modifying the
algorithm slightly if necessary. */
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
/* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are:
1) Stack overflow -
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
2) Incorrect interrupt priority assignment, especially on Cortex M3
parts where numerically high priority values denote low actual
interrupt priories, which can seem counter intuitive. See
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when
the scheduler is suspended.
4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?).
See http://www.freertos.org/FAQHelp.html for more tips.
**********************************************************************/
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
/* There is nothing to do here, we are just iterating to the
wanted insertion position. */
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the
item later. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/
void vListRemove( xListItem *pxItemToRemove )
{
xList * pxList;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
/* The list item knows which list it is in. Obtain the list from the list
item. */
pxList = ( xList * ) pxItemToRemove->pvContainer;
/* Make sure the index is left pointing to a valid item. */
if( pxList->pxIndex == pxItemToRemove )
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
pxItemToRemove->pvContainer = NULL;
( pxList->uxNumberOfItems )--;
}
/*-----------------------------------------------------------*/
#endif /* ENABLE_FREERTOS */

View File

@ -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 <FreeRTOS.h>
#ifdef ENABLE_FREERTOS
/*-----------------------------------------------------------*/
#include <task.h>
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
defined. The value should also ensure backward compatibility.
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
#ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY 255
#endif
/* Constants required to manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )
#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )
#define portNVIC_SYSTICK_CLK 0x00000004
#define portNVIC_SYSTICK_INT 0x00000002
#define portNVIC_SYSTICK_ENABLE 0x00000001
#define portNVIC_PENDSVSET 0x10000000
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16 )
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
/* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000 )
/* The priority used by the kernel is assigned to a variable to make access
from inline assembler easier. */
const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY;
/* Each task maintains its own interrupt status in the critical nesting
variable. */
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
/*
* Setup the timer to generate the tick interrupts.
*/
static void prvSetupTimerInterrupt( void );
/*
* Exception handlers.
*/
void xPortPendSVHandler( void ) __attribute__ (( naked ));
void xPortSysTickHandler( void );
void vPortSVCHandler( void ) __attribute__ (( naked ));
/*
* 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 */
/*-----------------------------------------------------------*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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"

View File

@ -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);

View File

@ -0,0 +1,29 @@
/***************************************************************
*
* OpenBeacon.org - CRC16 routine
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -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__*/

View File

@ -0,0 +1,30 @@
/***************************************************************
*
* OpenBeacon.org - HID ROM function code for LPC13xx
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,32 @@
/***************************************************************
*
* OpenBeacon.org - IAP - in application programming
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,52 @@
/***************************************************************
*
* OpenBeacon.org - MSD ROM function code for LPC13xx
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,113 @@
#ifndef __OPENBEACON_H__
#define __OPENBEACON_H__
#include <stdint.h>
#include <stdlib.h>
#include <config.h>
#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 <FreeRTOS.h>
#include <task.h>
#include <semphr.h>
#endif/*ENABLE_FREERTOS*/
#ifdef __LPC13xx__
#include <LPC13xx.h>
#include <uart.h>
#ifdef ENALBLE_USB_FULLFEATURED
#include <cdcusb.h>
#include <usbcfg.h>
#include <usbhw.h>
#include <usbcore.h>
#include <cdc.h>
#include <cdcuser.h>
#else /*ENALBLE_USB_FULLFEATURED*/
#include <usb.h>
#include <usbdesc.h>
#include <rom_drivers.h>
#endif/*ENALBLE_USB_FULLFEATURED*/
#include <gpio.h>
/* 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 <debug_printf.h>
#include <string.h>
#include <crc16.h>
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__*/

View File

@ -0,0 +1,43 @@
/***************************************************************
*
* OpenBeacon.org - SPI routines for LPC13xx
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,70 @@
/***************************************************************
*
* OpenBeacon.org - virtual FAT16 file system support
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -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 <meriac@openbeacon.de>
*
* 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__*/

View File

@ -0,0 +1,43 @@
/***************************************************************
*
* OpenBeacon.org - CRC16 routine
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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;
}

View File

@ -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 <openbeacon.h>
#ifndef UART_DISABLE
#include <ctype.h>
#include <uart.h>
#include <debug_printf.h>
#include <stdarg.h>
#include <string.h>
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 = "<NULL>";
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<len; j+=16) {
debug_printf("%08x:", start+j);
for (i=0; i<16; i++) {
if (start+i+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 */

View File

@ -0,0 +1,112 @@
/***************************************************************
*
* OpenBeacon.org - HID ROM function code for LPC13xx
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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) */

View File

@ -0,0 +1,45 @@
/***************************************************************
*
* OpenBeacon.org - IAP - in application programming
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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);
}

View File

@ -0,0 +1,117 @@
/***************************************************************
*
* OpenBeacon.org - HID ROM function code for LPC13xx
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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 */

View File

@ -0,0 +1,128 @@
/***************************************************************
*
* OpenBeacon.org - SPI routines for LPC13xx
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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;
}

View File

@ -0,0 +1,533 @@
/***************************************************************
*
* OpenBeacon.org - virtual FAT16 file system support
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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 */

View File

@ -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 <meriac@openbeacon.de>
*
* 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 <openbeacon.h>
#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);
}

View File

@ -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<<bitPosi)] ? 1:0;
}
/*****************************************************************************
** Function name: GPIOSetDir
**
** Descriptions: Set the direction in GPIO port
**
** parameters: port num, bit position, direction (1 out, 0 input)
** Returned value: None
**
*****************************************************************************/
static __INLINE void
GPIOSetDir (uint32_t portNum, uint32_t bitPosi, uint32_t dir)
{
if (dir)
LPC_GPIO[portNum]->DIR |= 1 << bitPosi;
else
LPC_GPIO[portNum]->DIR &= ~(1 << bitPosi);
}
#endif /* end __GPIO_H */
/*****************************************************************************
** End Of File
******************************************************************************/

View File

@ -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_ */

View File

@ -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
******************************************************************************/

View File

@ -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__ */

View File

@ -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 */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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 */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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
******************************************************************************/

View File

@ -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 <openbeacon.h>
#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 */

View File

@ -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 <openbeacon.h>
#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*/

View File

@ -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 <openbeacon.h>
#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*/

File diff suppressed because it is too large Load Diff

View File

@ -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 <openbeacon.h>
#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*/

View File

@ -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 <openbeacon.h>
#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*/

View File

@ -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) {
}
}

View File

@ -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"

View File

@ -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

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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<num; count++) {
printf(" 0x%02X",buf[count]);
}
printf("\n");
}
rawhid_close(hid);
printf("\nDevice disconnected.\nWaiting for new device:");
}
return 0;
}

View File

@ -0,0 +1,152 @@
/* Raw HID I/O Routines
* Copyright 2008, PJRC.COM, LLC
* paul@pjrc.com
*
* 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/
*/
// This code will someday be turned into "librawhid", an easy-to-use
// and truly cross platform library for accessing HID reports. But
// there are many complexities not properly handled by this simple
// code that would be expected from a high quality library. In
// particular, how report IDs are handled is not uniform on the 3
// platforms. The mac code uses a single buffer which assumes no
// other functions can cause the "run loop" to process HID callbacks.
// The linux version doesn't extract usage and usage page from the
// report descriptor and just hardcodes a signature for the Teensy
// USB debug example. Lacking from all platforms are functions to
// manage multiple devices and robust detection of device removal
// and attachment. There are probably lots of other issues... this
// code has really only been used in 2 projects. If you use it,
// please report bugs to paul@pjrc.com
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "rawhid.h"
#ifdef OPERATING_SYSTEM
#undef OPERATING_SYSTEM
#endif
/*************************************************************************/
/** **/
/** Linux **/
/** **/
/*************************************************************************/
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/hidraw.h>
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<HIDRAW_MAX_DEVICES; i++) {
if (fd > 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;
}

View File

@ -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

21
openbeacon/lpc13xx/lpc-flash/.gitignore vendored Normal file
View File

@ -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

View File

@ -0,0 +1 @@
Milosch Meriac <meriac@bitmanufaktur.de>

View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 <http://www.gnu.org/licenses/>.
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:
<program> Copyright (C) <year> <name of author>
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
<http://www.gnu.org/licenses/>.
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
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -0,0 +1 @@
SUBDIRS=src

View File

View File

View File

@ -0,0 +1,5 @@
#!/bin/bash
git pull openbeacon master
git log . > ChangeLog
autoreconf --install

View File

@ -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

View File

@ -0,0 +1,4 @@
AM_CFLAGS = --pedantic -std=gnu99
bin_PROGRAMS = lpc-flash
lpc_flash_SOURCES = lpc-flash.c
lpc_flash_CPPFLAGS = -Wall -Werror

View File

@ -0,0 +1,165 @@
/***************************************************************
*
* OpenPCD.org - main entry for LPC flashing tool
*
* Copyright 2010 Milosch Meriac <meriac@bitmanufaktur.de>
* Copyright 2010 Henryk Plötz <henryk@ploetzli.ch>
*
***************************************************************
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 <stdio.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/in.h>
/* 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;
}

View File

@ -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

View File

@ -0,0 +1,32 @@
/***************************************************************
*
* OpenBeacon.org - 3D acceleration sensor support
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,44 @@
/***************************************************************
*
* OpenBeacon.org - config file
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,60 @@
/***************************************************************
*
* OpenBeacon.org - function definitions
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
* 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 <nRF_HW.h>
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 */

View File

@ -0,0 +1,45 @@
/***************************************************************
*
* OpenBeacon.org - midlevel access function defines for
* issuing raw commands to the nRF24L01 2.4Ghz frontend
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
* 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 */

View File

@ -0,0 +1,109 @@
/***************************************************************
*
* OpenBeacon.org - opcode & register definitions for nRF24L01
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
* 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 */

View File

@ -0,0 +1,109 @@
/****************************************************************************
*
* OpenBeacon.org - OnAir protocol specification and definition
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
****************************************************************************
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__*/

View File

@ -0,0 +1,31 @@
/***************************************************************
*
* OpenBeacon.org - LPC13xx Power Management Functions
*
* Copyright 2011 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,33 @@
/***************************************************************
*
* OpenBeacon.org - piezo speaker sound functions
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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__*/

View File

@ -0,0 +1,100 @@
/***************************************************************
*
* OpenBeacon.org - 3D acceleration sensor support
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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);
}

View File

@ -0,0 +1,346 @@
/***************************************************************
*
* OpenBeacon.org - main file for OpenBeacon Sensor (CR123A)
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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;
}

View File

@ -0,0 +1,330 @@
/***************************************************************
*
* OpenBeacon.org - high level nRF24L01 access functions
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
* 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 <openbeacon.h>
#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);
}

View File

@ -0,0 +1,238 @@
/***************************************************************
*
* OpenBeacon.org - midlevel access functions for
* issuing raw commands to the nRF24L01 2.4Ghz frontend
*
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
*
* 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 <openbeacon.h>
#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 (&reg, &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);
}

View File

@ -0,0 +1,160 @@
/***************************************************************
*
* OpenBeacon.org - LPC13xx Power Management Functions
*
* Copyright 2011 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#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;
}

View File

@ -0,0 +1,93 @@
/***************************************************************
*
* OpenBeacon.org - piezo speaker sound functions
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
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 <openbeacon.h>
#include <sound.h>
#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 */

Some files were not shown because too many files have changed in this diff Show More