added code from openbeacon.org
This commit is contained in:
parent
51e7d5bbd1
commit
58ff370dd6
|
@ -0,0 +1,11 @@
|
||||||
|
*.o
|
||||||
|
*.asm
|
||||||
|
*.bin
|
||||||
|
*.elf
|
||||||
|
*.map
|
||||||
|
*~
|
||||||
|
.cproject
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
Default
|
||||||
|
ignore
|
|
@ -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
|
|
@ -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/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -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) &&
|
||||||
|
(ITM->TCR & ITM_TCR_ITMENA) &&
|
||||||
|
(ITM->TER & (1UL << 0)) )
|
||||||
|
{
|
||||||
|
while (ITM->PORT[0].u32 == 0);
|
||||||
|
ITM->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 -> 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 -> 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"> </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.
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
||||||
|
}
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
@ -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
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
@ -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"
|
|
@ -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"
|
|
@ -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);
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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) */
|
|
@ -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);
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
||||||
|
******************************************************************************/
|
|
@ -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_ */
|
|
@ -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
|
||||||
|
******************************************************************************/
|
|
@ -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__ */
|
|
@ -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 */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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 */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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
|
||||||
|
******************************************************************************/
|
|
@ -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 */
|
|
@ -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*/
|
|
@ -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
|
@ -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*/
|
|
@ -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*/
|
|
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
||||||
|
Milosch Meriac <meriac@bitmanufaktur.de>
|
|
@ -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>.
|
|
@ -0,0 +1 @@
|
||||||
|
SUBDIRS=src
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
git pull openbeacon master
|
||||||
|
git log . > ChangeLog
|
||||||
|
autoreconf --install
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
||||||
|
AM_CFLAGS = --pedantic -std=gnu99
|
||||||
|
bin_PROGRAMS = lpc-flash
|
||||||
|
lpc_flash_SOURCES = lpc-flash.c
|
||||||
|
lpc_flash_CPPFLAGS = -Wall -Werror
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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 (®, &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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
Loading…
Reference in New Issue