From 12b102d3460d6eb4e9e6c014d7ed0986bb72c0cf Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sun, 9 Aug 2009 12:19:17 +0000 Subject: [PATCH] Initial IAR LPC1768 demo. Work in progress at this point. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@841 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Demo/CORTEX_LPC1768_IAR/Flash.mac | 13 + Demo/CORTEX_LPC1768_IAR/FreeRTOSConfig.h | 154 ++ Demo/CORTEX_LPC1768_IAR/LED.h | 55 + Demo/CORTEX_LPC1768_IAR/LPC1768_Flash.icf | 37 + Demo/CORTEX_LPC1768_IAR/LPC17xx.h | 1081 +++++++++++ Demo/CORTEX_LPC1768_IAR/LPCUSB/USB_CDC.c | 437 +++++ Demo/CORTEX_LPC1768_IAR/LPCUSB/type.h | 38 + Demo/CORTEX_LPC1768_IAR/LPCUSB/usbapi.h | 118 ++ Demo/CORTEX_LPC1768_IAR/LPCUSB/usbcontrol.c | 246 +++ Demo/CORTEX_LPC1768_IAR/LPCUSB/usbdebug.h | 41 + Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c | 521 +++++ .../CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c.bak | 521 +++++ Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.h | 149 ++ Demo/CORTEX_LPC1768_IAR/LPCUSB/usbinit.c | 82 + Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstdreq.c | 430 +++++ Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstruct.h | 119 ++ Demo/CORTEX_LPC1768_IAR/ParTest.c | 138 ++ Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewd | 1387 ++++++++++++++ Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewp | 1700 +++++++++++++++++ Demo/CORTEX_LPC1768_IAR/RTOSDemo.eww | 10 + Demo/CORTEX_LPC1768_IAR/core_cm3.h | 1367 +++++++++++++ Demo/CORTEX_LPC1768_IAR/cstartup_M.s | 271 +++ Demo/CORTEX_LPC1768_IAR/main.c | 369 ++++ Demo/CORTEX_LPC1768_IAR/printf-stdarg.c | 293 +++ .../settings/RTOSDemo.cspy.bat | 33 + .../settings/RTOSDemo.dbgdt | 79 + Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dni | 48 + .../CORTEX_LPC1768_IAR/settings/RTOSDemo.wsdt | 67 + .../settings/RTOSDemo_Debug.jlink | 14 + Demo/CORTEX_LPC1768_IAR/system_LPC17xx.h | 40 + Demo/CORTEX_LPC1768_IAR/webserver/EthDev.h | 111 ++ .../webserver/EthDev_LPC17xx.h | 321 ++++ .../CORTEX_LPC1768_IAR/webserver/clock-arch.h | 42 + Demo/CORTEX_LPC1768_IAR/webserver/emac.c | 600 ++++++ .../CORTEX_LPC1768_IAR/webserver/http-strings | 35 + .../webserver/http-strings.c | 102 + .../webserver/http-strings.h | 34 + Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.c | 304 +++ Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.h | 84 + Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.c | 132 ++ Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.h | 57 + .../webserver/httpd-fs/404.html | 8 + .../webserver/httpd-fs/index.html | 13 + .../webserver/httpd-fs/index.shtml | 20 + .../webserver/httpd-fs/io.shtml | 28 + .../webserver/httpd-fs/runtime.shtml | 20 + .../webserver/httpd-fs/stats.shtml | 41 + .../webserver/httpd-fs/tcp.shtml | 21 + .../webserver/httpd-fsdata.c | 557 ++++++ .../webserver/httpd-fsdata.h | 64 + Demo/CORTEX_LPC1768_IAR/webserver/httpd.c | 346 ++++ Demo/CORTEX_LPC1768_IAR/webserver/httpd.h | 62 + Demo/CORTEX_LPC1768_IAR/webserver/makefsdata | 78 + Demo/CORTEX_LPC1768_IAR/webserver/makestrings | 40 + Demo/CORTEX_LPC1768_IAR/webserver/uIP_Task.c | 264 +++ Demo/CORTEX_LPC1768_IAR/webserver/uip-conf.h | 159 ++ Demo/CORTEX_LPC1768_IAR/webserver/webserver.h | 49 + 57 files changed, 13450 insertions(+) create mode 100644 Demo/CORTEX_LPC1768_IAR/Flash.mac create mode 100644 Demo/CORTEX_LPC1768_IAR/FreeRTOSConfig.h create mode 100644 Demo/CORTEX_LPC1768_IAR/LED.h create mode 100644 Demo/CORTEX_LPC1768_IAR/LPC1768_Flash.icf create mode 100644 Demo/CORTEX_LPC1768_IAR/LPC17xx.h create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/USB_CDC.c create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/type.h create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbapi.h create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbcontrol.c create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbdebug.h create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c.bak create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.h create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbinit.c create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstdreq.c create mode 100644 Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstruct.h create mode 100644 Demo/CORTEX_LPC1768_IAR/ParTest.c create mode 100644 Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewd create mode 100644 Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewp create mode 100644 Demo/CORTEX_LPC1768_IAR/RTOSDemo.eww create mode 100644 Demo/CORTEX_LPC1768_IAR/core_cm3.h create mode 100644 Demo/CORTEX_LPC1768_IAR/cstartup_M.s create mode 100644 Demo/CORTEX_LPC1768_IAR/main.c create mode 100644 Demo/CORTEX_LPC1768_IAR/printf-stdarg.c create mode 100644 Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.cspy.bat create mode 100644 Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dbgdt create mode 100644 Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dni create mode 100644 Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.wsdt create mode 100644 Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo_Debug.jlink create mode 100644 Demo/CORTEX_LPC1768_IAR/system_LPC17xx.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/EthDev.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/EthDev_LPC17xx.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/clock-arch.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/emac.c create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/http-strings create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/http-strings.c create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/http-strings.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.c create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.c create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/404.html create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.html create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.shtml create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/io.shtml create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/runtime.shtml create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/stats.shtml create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/tcp.shtml create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.c create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd.c create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/httpd.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/makefsdata create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/makestrings create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/uIP_Task.c create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/uip-conf.h create mode 100644 Demo/CORTEX_LPC1768_IAR/webserver/webserver.h diff --git a/Demo/CORTEX_LPC1768_IAR/Flash.mac b/Demo/CORTEX_LPC1768_IAR/Flash.mac new file mode 100644 index 000000000..95eeeaa81 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/Flash.mac @@ -0,0 +1,13 @@ +execUserReset() +{ + __writeMemory32(0x00000000, 0xE000ED08, "Memory"); //Vector table remap at 0x00000000 +} + +execUserPreload() +{ + // If the MAM values was wrong, a dummy read is necessary to get the flash memory in sync. + __writeMemory32(0x00000001, 0x400FC040, "Memory"); // MEMMAP = 1 + __readMemory32(0x00000000, "Memory"); + __writeMemory32(0x00000000, 0xE000ED08, "Memory"); //Vector table remap at 0x00000000 +} + diff --git a/Demo/CORTEX_LPC1768_IAR/FreeRTOSConfig.h b/Demo/CORTEX_LPC1768_IAR/FreeRTOSConfig.h new file mode 100644 index 000000000..44dbc5d94 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/FreeRTOSConfig.h @@ -0,0 +1,154 @@ +/* + FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation and modified by the FreeRTOS exception. + **NOTE** The exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + Alternative commercial license and support terms are also available upon + request. See the licensing section of http://www.FreeRTOS.org for full + license details. + + 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 along + with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + + *************************************************************************** + * * + * Looking for a quick start? Then check out the FreeRTOS eBook! * + * See http://www.FreeRTOS.org/Documentation for details * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 99000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 80 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 19 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 + +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 10 +#define configGENERATE_RUN_TIME_STATS 1 + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 + +/*----------------------------------------------------------- + * Ethernet configuration. + *-----------------------------------------------------------*/ + +/* MAC address configuration. */ +#define configMAC_ADDR0 0x00 +#define configMAC_ADDR1 0x12 +#define configMAC_ADDR2 0x13 +#define configMAC_ADDR3 0x10 +#define configMAC_ADDR4 0x15 +#define configMAC_ADDR5 0x11 + +/* IP address configuration. */ +#define configIP_ADDR0 192 +#define configIP_ADDR1 168 +#define configIP_ADDR2 0 +#define configIP_ADDR3 201 + +/* Netmask configuration. */ +#define configNET_MASK0 255 +#define configNET_MASK1 255 +#define configNET_MASK2 255 +#define configNET_MASK3 0 + +/* Use the system definition, if there is one */ +#ifdef __NVIC_PRIO_BITS + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 5 /* 32 priority levels */ +#endif + +/* The lowest priority. */ +#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) ) +/* Priority 5, or 160 as only the top three bits are implemented. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) ) + +/* Priorities passed to NVIC_SetPriority() do not require shifting as the +function does the shifting itself. Note these priorities need to be equal to +or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY - therefore the numeric +value needs to be equal to or greater than 5 (on the Cortex M3 the lower the +numeric value the higher the interrupt priority). */ +#define configEMAC_INTERRUPT_PRIORITY 5 +#define configUSB_INTERRUPT_PRIORITY 6 + + + +/*----------------------------------------------------------- + * Macros required to setup the timer for the run time stats. + *-----------------------------------------------------------*/ +#ifdef __ICCARM__ + #include "LPC17xx.h" + extern void vConfigureTimerForRunTimeStats( void ); + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() + #define portGET_RUN_TIME_COUNTER_VALUE() TIM0->TC +#endif + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Demo/CORTEX_LPC1768_IAR/LED.h b/Demo/CORTEX_LPC1768_IAR/LED.h new file mode 100644 index 000000000..2aae6cb56 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LED.h @@ -0,0 +1,55 @@ +/* + FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation and modified by the FreeRTOS exception. + **NOTE** The exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + Alternative commercial license and support terms are also available upon + request. See the licensing section of http://www.FreeRTOS.org for full + license details. + + 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 along + with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + + *************************************************************************** + * * + * Looking for a quick start? Then check out the FreeRTOS eBook! * + * See http://www.FreeRTOS.org/Documentation for details * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + 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 LED_HH +#define LED_HH + +void vToggleLED( unsigned long ulLED ); +void vSetLEDState( unsigned long ulLED, long lState ); +long lGetLEDState( unsigned long ulLED ); + +#endif diff --git a/Demo/CORTEX_LPC1768_IAR/LPC1768_Flash.icf b/Demo/CORTEX_LPC1768_IAR/LPC1768_Flash.icf new file mode 100644 index 000000000..1f035952e --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPC1768_Flash.icf @@ -0,0 +1,37 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000100; +define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x10000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x10007FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x400; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define symbol _AHB_RAM_start__ = 0x2007C000; +define symbol _AHB_RAM_end__ = 0x20083FFF; +define region AHB_RAM_region = mem:[from _AHB_RAM_start__ to _AHB_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; +do not initialize { section USB_DMA_RAM }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in AHB_RAM_region + { readwrite data section AHB_RAM_MEMORY, section USB_DMA_RAM, section EMAC_DMA_RAM}; + diff --git a/Demo/CORTEX_LPC1768_IAR/LPC17xx.h b/Demo/CORTEX_LPC1768_IAR/LPC17xx.h new file mode 100644 index 000000000..f2480b138 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPC17xx.h @@ -0,0 +1,1081 @@ +#ifndef __LPC17xx_H +#define __LPC17xx_H + +/* System Control Block (SCB) includes: + Flash Accelerator Module, Clocking and Power Control, External Interrupts, + Reset, System Control and Status +*/ +#define SCB_BASE_ADDR 0x400FC000 + +#define PCONP_PCTIM0 0x00000002 +#define PCONP_PCTIM1 0x00000004 +#define PCONP_PCUART0 0x00000008 +#define PCONP_PCUART1 0x00000010 +#define PCONP_PCPWM1 0x00000040 +#define PCONP_PCI2C0 0x00000080 +#define PCONP_PCSPI 0x00000100 +#define PCONP_PCRTC 0x00000200 +#define PCONP_PCSSP1 0x00000400 +#define PCONP_PCAD 0x00001000 +#define PCONP_PCCAN1 0x00002000 +#define PCONP_PCCAN2 0x00004000 +#define PCONP_PCGPIO 0x00008000 +#define PCONP_PCRIT 0x00010000 +#define PCONP_PCMCPWM 0x00020000 +#define PCONP_PCQEI 0x00040000 +#define PCONP_PCI2C1 0x00080000 +#define PCONP_PCSSP0 0x00200000 +#define PCONP_PCTIM2 0x00400000 +#define PCONP_PCTIM3 0x00800000 +#define PCONP_PCUART2 0x01000000 +#define PCONP_PCUART3 0x02000000 +#define PCONP_PCI2C2 0x04000000 +#define PCONP_PCI2S 0x08000000 +#define PCONP_PCGPDMA 0x20000000 +#define PCONP_PCENET 0x40000000 +#define PCONP_PCUSB 0x80000000 + +#define PLLCON_PLLE 0x00000001 +#define PLLCON_PLLC 0x00000002 +#define PLLCON_MASK 0x00000003 + +#define PLLCFG_MUL1 0x00000000 +#define PLLCFG_MUL2 0x00000001 +#define PLLCFG_MUL3 0x00000002 +#define PLLCFG_MUL4 0x00000003 +#define PLLCFG_MUL5 0x00000004 +#define PLLCFG_MUL6 0x00000005 +#define PLLCFG_MUL7 0x00000006 +#define PLLCFG_MUL8 0x00000007 +#define PLLCFG_MUL9 0x00000008 +#define PLLCFG_MUL10 0x00000009 +#define PLLCFG_MUL11 0x0000000A +#define PLLCFG_MUL12 0x0000000B +#define PLLCFG_MUL13 0x0000000C +#define PLLCFG_MUL14 0x0000000D +#define PLLCFG_MUL15 0x0000000E +#define PLLCFG_MUL16 0x0000000F +#define PLLCFG_MUL17 0x00000010 +#define PLLCFG_MUL18 0x00000011 +#define PLLCFG_MUL19 0x00000012 +#define PLLCFG_MUL20 0x00000013 +#define PLLCFG_MUL21 0x00000014 +#define PLLCFG_MUL22 0x00000015 +#define PLLCFG_MUL23 0x00000016 +#define PLLCFG_MUL24 0x00000017 +#define PLLCFG_MUL25 0x00000018 +#define PLLCFG_MUL26 0x00000019 +#define PLLCFG_MUL27 0x0000001A +#define PLLCFG_MUL28 0x0000001B +#define PLLCFG_MUL29 0x0000001C +#define PLLCFG_MUL30 0x0000001D +#define PLLCFG_MUL31 0x0000001E +#define PLLCFG_MUL32 0x0000001F +#define PLLCFG_MUL33 0x00000020 +#define PLLCFG_MUL34 0x00000021 +#define PLLCFG_MUL35 0x00000022 +#define PLLCFG_MUL36 0x00000023 + +#define PLLCFG_DIV1 0x00000000 +#define PLLCFG_DIV2 0x00010000 +#define PLLCFG_DIV3 0x00020000 +#define PLLCFG_DIV4 0x00030000 +#define PLLCFG_DIV5 0x00040000 +#define PLLCFG_DIV6 0x00050000 +#define PLLCFG_DIV7 0x00060000 +#define PLLCFG_DIV8 0x00070000 +#define PLLCFG_DIV9 0x00080000 +#define PLLCFG_DIV10 0x00090000 +#define PLLCFG_MASK 0x00FF7FFF + +#define PLLSTAT_MSEL_MASK 0x00007FFF +#define PLLSTAT_NSEL_MASK 0x00FF0000 + +#define PLLSTAT_PLLE (1 << 24) +#define PLLSTAT_PLLC (1 << 25) +#define PLLSTAT_PLOCK (1 << 26) + +#define PLLFEED_FEED1 0x000000AA +#define PLLFEED_FEED2 0x00000055 + +#define NVIC_IRQ_WDT 0u // IRQ0, exception number 16 +#define NVIC_IRQ_TIMER0 1u // IRQ1, exception number 17 +#define NVIC_IRQ_TIMER1 2u // IRQ2, exception number 18 +#define NVIC_IRQ_TIMER2 3u // IRQ3, exception number 19 +#define NVIC_IRQ_TIMER3 4u // IRQ4, exception number 20 +#define NVIC_IRQ_UART0 5u // IRQ5, exception number 21 +#define NVIC_IRQ_UART1 6u // IRQ6, exception number 22 +#define NVIC_IRQ_UART2 7u // IRQ7, exception number 23 +#define NVIC_IRQ_UART3 8u // IRQ8, exception number 24 +#define NVIC_IRQ_PWM1 9u // IRQ9, exception number 25 +#define NVIC_IRQ_I2C0 10u // IRQ10, exception number 26 +#define NVIC_IRQ_I2C1 11u // IRQ11, exception number 27 +#define NVIC_IRQ_I2C2 12u // IRQ12, exception number 28 +#define NVIC_IRQ_SPI 13u // IRQ13, exception number 29 +#define NVIC_IRQ_SSP0 14u // IRQ14, exception number 30 +#define NVIC_IRQ_SSP1 15u // IRQ15, exception number 31 +#define NVIC_IRQ_PLL0 16u // IRQ16, exception number 32 +#define NVIC_IRQ_RTC 17u // IRQ17, exception number 33 +#define NVIC_IRQ_EINT0 18u // IRQ18, exception number 34 +#define NVIC_IRQ_EINT1 19u // IRQ19, exception number 35 +#define NVIC_IRQ_EINT2 20u // IRQ20, exception number 36 +#define NVIC_IRQ_EINT3 21u // IRQ21, exception number 37 +#define NVIC_IRQ_ADC 22u // IRQ22, exception number 38 +#define NVIC_IRQ_BOD 23u // IRQ23, exception number 39 +#define NVIC_IRQ_USB 24u // IRQ24, exception number 40 +#define NVIC_IRQ_CAN 25u // IRQ25, exception number 41 +#define NVIC_IRQ_GPDMA 26u // IRQ26, exception number 42 +#define NVIC_IRQ_I2S 27u // IRQ27, exception number 43 +#define NVIC_IRQ_ETHERNET 28u // IRQ28, exception number 44 +#define NVIC_IRQ_RIT 29u // IRQ29, exception number 45 +#define NVIC_IRQ_MCPWM 30u // IRQ30, exception number 46 +#define NVIC_IRQ_QE 31u // IRQ31, exception number 47 +#define NVIC_IRQ_PLL1 32u // IRQ32, exception number 48 +#define NVIC_IRQ_USB_ACT 33u // IRQ33, exception number 49 +#define NVIC_IRQ_CAN_ACT 34u // IRQ34, exception number 50 + + +#endif // __LPC17xx_H + + +#ifndef CMSIS_17xx_H +#define CMSIS_17xx_H + +/****************************************************************************** + * @file: LPC17xx.h + * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File for + * NXP LPC17xx Device Series + * @version: V1.1 + * @date: 14th May 2009 + *---------------------------------------------------------------------------- + * + * Copyright (C) 2008 ARM Limited. All rights reserved. + * + * ARM Limited (ARM) is supplying this software for use with Cortex-M3 + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + + +#ifndef __LPC17xx_H__ +#define __LPC17xx_H__ + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ + +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** LPC17xx Specific Interrupt Numbers *******************************************************/ + WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */ + TIMER0_IRQn = 1, /*!< Timer0 Interrupt */ + TIMER1_IRQn = 2, /*!< Timer1 Interrupt */ + TIMER2_IRQn = 3, /*!< Timer2 Interrupt */ + TIMER3_IRQn = 4, /*!< Timer3 Interrupt */ + UART0_IRQn = 5, /*!< UART0 Interrupt */ + UART1_IRQn = 6, /*!< UART1 Interrupt */ + UART2_IRQn = 7, /*!< UART2 Interrupt */ + UART3_IRQn = 8, /*!< UART3 Interrupt */ + PWM1_IRQn = 9, /*!< PWM1 Interrupt */ + I2C0_IRQn = 10, /*!< I2C0 Interrupt */ + I2C1_IRQn = 11, /*!< I2C1 Interrupt */ + I2C2_IRQn = 12, /*!< I2C2 Interrupt */ + SPI_IRQn = 13, /*!< SPI Interrupt */ + SSP0_IRQn = 14, /*!< SSP0 Interrupt */ + SSP1_IRQn = 15, /*!< SSP1 Interrupt */ + PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */ + RTC_IRQn = 17, /*!< Real Time Clock Interrupt */ + EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */ + EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */ + EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */ + EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */ + ADC_IRQn = 22, /*!< A/D Converter Interrupt */ + BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */ + USB_IRQn = 24, /*!< USB Interrupt */ + CAN_IRQn = 25, /*!< CAN Interrupt */ + DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */ + I2S_IRQn = 27, /*!< I2S Interrupt */ + ENET_IRQn = 28, /*!< Ethernet Interrupt */ + RIT_IRQn = 29, /*!< Repetitive Interrupt Timer Interrupt */ + MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */ + QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */ + PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */ +} IRQn_Type; + + +/* + * ========================================================================== + * ----------- Processor and Core Peripheral Section ------------------------ + * ========================================================================== + */ + +/* Configuration of the Cortex-M3 Processor and Core Peripherals */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + + +//#include "..\core_cm3.h" /* Cortex-M3 processor and core peripherals */ +#include "core_cm3.h" +#include "system_LPC17xx.h" /* System Header */ + + + +/** + * Initialize the system clock + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemFrequency variable. + */ +extern void SystemInit (void); + + +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ + +/*------------- System Control (SC) ------------------------------------------*/ +typedef struct +{ + __IO uint32_t FLASHCFG; /* Flash Accelerator Module */ + uint32_t RESERVED0[31]; + __IO uint32_t PLL0CON; /* Clocking and Power Control */ + __IO uint32_t PLL0CFG; + __I uint32_t PLL0STAT; + __O uint32_t PLL0FEED; + uint32_t RESERVED1[4]; + __IO uint32_t PLL1CON; + __IO uint32_t PLL1CFG; + __I uint32_t PLL1STAT; + __O uint32_t PLL1FEED; + uint32_t RESERVED2[4]; + __IO uint32_t PCON; + __IO uint32_t PCONP; + uint32_t RESERVED3[15]; + __IO uint32_t CCLKCFG; + __IO uint32_t USBCLKCFG; + __IO uint32_t CLKSRCSEL; + uint32_t RESERVED4[12]; + __IO uint32_t EXTINT; /* External Interrupts */ + uint32_t RESERVED5; + __IO uint32_t EXTMODE; + __IO uint32_t EXTPOLAR; + uint32_t RESERVED6[12]; + __IO uint32_t RSID; /* Reset */ + uint32_t RESERVED7[7]; + __IO uint32_t SCS; /* Syscon Miscellaneous Registers */ + __IO uint32_t IRCTRIM; /* Clock Dividers */ + __IO uint32_t PCLKSEL0; + __IO uint32_t PCLKSEL1; + uint32_t RESERVED8[4]; + __IO uint32_t USBIntSt; /* USB Device/OTG Interrupt Register */ + uint32_t RESERVED9; + __IO uint32_t CLKOUTCFG; /* Clock Output Configuration */ + } SC_TypeDef; + +/*------------- Pin Connect Block (PINCON) -----------------------------------*/ +typedef struct +{ + __IO uint32_t PINSEL0; + __IO uint32_t PINSEL1; + __IO uint32_t PINSEL2; + __IO uint32_t PINSEL3; + __IO uint32_t PINSEL4; + __IO uint32_t PINSEL5; + __IO uint32_t PINSEL6; + __IO uint32_t PINSEL7; + __IO uint32_t PINSEL8; + __IO uint32_t PINSEL9; + __IO uint32_t PINSEL10; + uint32_t RESERVED0[5]; + __IO uint32_t PINMODE0; + __IO uint32_t PINMODE1; + __IO uint32_t PINMODE2; + __IO uint32_t PINMODE3; + __IO uint32_t PINMODE4; + __IO uint32_t PINMODE5; + __IO uint32_t PINMODE6; + __IO uint32_t PINMODE7; + __IO uint32_t PINMODE8; + __IO uint32_t PINMODE9; + __IO uint32_t PINMODE_OD0; + __IO uint32_t PINMODE_OD1; + __IO uint32_t PINMODE_OD2; + __IO uint32_t PINMODE_OD3; + __IO uint32_t PINMODE_OD4; +} PINCON_TypeDef; + +/*------------- General Purpose Input/Output (GPIO) --------------------------*/ +typedef struct +{ + __IO uint32_t FIODIR; + uint32_t RESERVED0[3]; + __IO uint32_t FIOMASK; + __IO uint32_t FIOPIN; + __IO uint32_t FIOSET; + __O uint32_t FIOCLR; +} GPIO_TypeDef; + +typedef struct +{ + __I uint32_t IntStatus; + __I uint32_t IO0IntStatR; + __I uint32_t IO0IntStatF; + __O uint32_t IO0IntClr; + __IO uint32_t IO0IntEnR; + __IO uint32_t IO0IntEnF; + uint32_t RESERVED0[3]; + __I uint32_t IO2IntStatR; + __I uint32_t IO2IntStatF; + __O uint32_t IO2IntClr; + __IO uint32_t IO2IntEnR; + __IO uint32_t IO2IntEnF; +} GPIOINT_TypeDef; + +/*------------- Timer (TIM) --------------------------------------------------*/ +typedef struct +{ + __IO uint32_t IR; + __IO uint32_t TCR; + __IO uint32_t TC; + __IO uint32_t PR; + __IO uint32_t PC; + __IO uint32_t MCR; + __IO uint32_t MR0; + __IO uint32_t MR1; + __IO uint32_t MR2; + __IO uint32_t MR3; + __IO uint32_t CCR; + __I uint32_t CR0; + __I uint32_t CR1; + uint32_t RESERVED0[2]; + __IO uint32_t EMR; + uint32_t RESERVED1[24]; + __IO uint32_t CTCR; +} TIM_TypeDef; + +/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/ +typedef struct +{ + __IO uint32_t IR; + __IO uint32_t TCR; + __IO uint32_t TC; + __IO uint32_t PR; + __IO uint32_t PC; + __IO uint32_t MCR; + __IO uint32_t MR0; + __IO uint32_t MR1; + __IO uint32_t MR2; + __IO uint32_t MR3; + __IO uint32_t CCR; + __I uint32_t CR0; + __I uint32_t CR1; + __I uint32_t CR2; + __I uint32_t CR3; + __IO uint32_t MR4; + __IO uint32_t MR5; + __IO uint32_t MR6; + __IO uint32_t PCR; + __IO uint32_t LER; + uint32_t RESERVED0[7]; + __IO uint32_t CTCR; +} PWM_TypeDef; + +/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/ +typedef struct +{ + union { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[7]; + __IO uint8_t LSR; + uint8_t RESERVED2[7]; + __IO uint8_t SCR; + uint8_t RESERVED3[3]; + __IO uint32_t ACR; + __IO uint8_t ICR; + uint8_t RESERVED4[3]; + __IO uint8_t FDR; + uint8_t RESERVED5[7]; + __IO uint8_t TER; + uint8_t RESERVED6[27]; + __IO uint8_t RS485CTRL; + uint8_t RESERVED7[3]; + __IO uint8_t ADRMATCH; +} UART_TypeDef; + +typedef struct +{ + union { + __I uint8_t RBR; + __O uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; + }; + union { + __IO uint8_t DLM; + __IO uint32_t IER; + }; + union { + __I uint32_t IIR; + __O uint8_t FCR; + }; + __IO uint8_t LCR; + uint8_t RESERVED1[3]; + __IO uint8_t MCR; + uint8_t RESERVED2[3]; + __IO uint8_t LSR; + uint8_t RESERVED3[3]; + __IO uint8_t MSR; + uint8_t RESERVED4[3]; + __IO uint8_t SCR; + uint8_t RESERVED5[3]; + __IO uint32_t ACR; + uint32_t RESERVED6; + __IO uint32_t FDR; + uint32_t RESERVED7; + __IO uint8_t TER; + uint8_t RESERVED8[27]; + __IO uint8_t RS485CTRL; + uint8_t RESERVED9[3]; + __IO uint8_t ADRMATCH; + uint8_t RESERVED10[3]; + __IO uint8_t RS485DLY; +} UART1_TypeDef; + +/*------------- Serial Peripheral Interface (SPI) ----------------------------*/ +typedef struct +{ + __IO uint32_t SPCR; + __I uint32_t SPSR; + __IO uint32_t SPDR; + __IO uint32_t SPCCR; + uint32_t RESERVED0[3]; + __IO uint32_t SPINT; +} SPI_TypeDef; + +/*------------- Synchronous Serial Communication (SSP) -----------------------*/ +typedef struct +{ + __IO uint32_t CR0; + __IO uint32_t CR1; + __IO uint32_t DR; + __I uint32_t SR; + __IO uint32_t CPSR; + __IO uint32_t IMSC; + __IO uint32_t RIS; + __IO uint32_t MIS; + __IO uint32_t ICR; + __IO uint32_t DMACR; +} SSP_TypeDef; + +/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/ +typedef struct +{ + __IO uint32_t I2CONSET; + __I uint32_t I2STAT; + __IO uint32_t I2DAT; + __IO uint32_t I2ADR0; + __IO uint32_t I2SCLH; + __IO uint32_t I2SCLL; + __O uint32_t I2CONCLR; + __IO uint32_t MMCTRL; + __IO uint32_t I2ADR1; + __IO uint32_t I2ADR2; + __IO uint32_t I2ADR3; + __I uint32_t I2DATA_BUFFER; + __IO uint32_t I2MASK0; + __IO uint32_t I2MASK1; + __IO uint32_t I2MASK2; + __IO uint32_t I2MASK3; +} I2C_TypeDef; + +/*------------- Inter IC Sound (I2S) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t I2SDAO; + __IO uint32_t I2SDAI; + __O uint32_t I2STXFIFO; + __I uint32_t I2SRXFIFO; + __I uint32_t I2SSTATE; + __IO uint32_t I2SDMA1; + __IO uint32_t I2SDMA2; + __IO uint32_t I2SIRQ; + __IO uint32_t I2STXRATE; + __IO uint32_t I2SRXRATE; + __IO uint32_t I2STXBITRATE; + __IO uint32_t I2SRXBITRATE; + __IO uint32_t I2STXMODE; + __IO uint32_t I2SRXMODE; +} I2S_TypeDef; + +/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/ +typedef struct +{ + __IO uint32_t RICOMPVAL; + __IO uint32_t RIMASK; + __IO uint8_t RICTRL; + uint8_t RESERVED0[3]; + __IO uint32_t RICOUNTER; +} RIT_TypeDef; + +/*------------- Real-Time Clock (RTC) ----------------------------------------*/ +typedef struct +{ + __IO uint8_t ILR; + uint8_t RESERVED0[3]; + __IO uint8_t CCR; + uint8_t RESERVED1[3]; + __IO uint8_t CIIR; + uint8_t RESERVED2[3]; + __IO uint8_t AMR; + uint8_t RESERVED3[3]; + __I uint32_t CTIME0; + __I uint32_t CTIME1; + __I uint32_t CTIME2; + __IO uint8_t SEC; + uint8_t RESERVED4[3]; + __IO uint8_t MIN; + uint8_t RESERVED5[3]; + __IO uint8_t HOUR; + uint8_t RESERVED6[3]; + __IO uint8_t DOM; + uint8_t RESERVED7[3]; + __IO uint8_t DOW; + uint8_t RESERVED8[3]; + __IO uint16_t DOY; + uint16_t RESERVED9; + __IO uint8_t MONTH; + uint8_t RESERVED10[3]; + __IO uint16_t YEAR; + uint16_t RESERVED11; + __IO uint32_t CALIBRATION; + __IO uint32_t GPREG0; + __IO uint32_t GPREG1; + __IO uint32_t GPREG2; + __IO uint32_t GPREG3; + __IO uint32_t GPREG4; + __IO uint8_t WAKEUPDIS; + uint8_t RESERVED12[3]; + __IO uint8_t PWRCTRL; + uint8_t RESERVED13[3]; + __IO uint8_t ALSEC; + uint8_t RESERVED14[3]; + __IO uint8_t ALMIN; + uint8_t RESERVED15[3]; + __IO uint8_t ALHOUR; + uint8_t RESERVED16[3]; + __IO uint8_t ALDOM; + uint8_t RESERVED17[3]; + __IO uint8_t ALDOW; + uint8_t RESERVED18[3]; + __IO uint16_t ALDOY; + uint16_t RESERVED19; + __IO uint8_t ALMON; + uint8_t RESERVED20[3]; + __IO uint16_t ALYEAR; + uint16_t RESERVED21; +} RTC_TypeDef; + +/*------------- Watchdog Timer (WDT) -----------------------------------------*/ +typedef struct +{ + __IO uint8_t WDMOD; + uint8_t RESERVED0[3]; + __IO uint32_t WDTC; + __O uint8_t WDFEED; + uint8_t RESERVED1[3]; + __I uint32_t WDTV; + __IO uint32_t WDCLKSEL; +} WDT_TypeDef; + +/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/ +typedef struct +{ + __IO uint32_t ADCR; + __IO uint32_t ADGDR; + uint32_t RESERVED0; + __IO uint32_t ADINTEN; + __I uint32_t ADDR0; + __I uint32_t ADDR1; + __I uint32_t ADDR2; + __I uint32_t ADDR3; + __I uint32_t ADDR4; + __I uint32_t ADDR5; + __I uint32_t ADDR6; + __I uint32_t ADDR7; + __I uint32_t ADSTAT; + __IO uint32_t ADTRM; +} ADC_TypeDef; + +/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/ +typedef struct +{ + __IO uint32_t DACR; + __IO uint32_t DACCTRL; + __IO uint16_t DACCNTVAL; +} DAC_TypeDef; + +/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/ +typedef struct +{ + __I uint32_t MCCON; + __O uint32_t MCCON_SET; + __O uint32_t MCCON_CLR; + __I uint32_t MCCAPCON; + __O uint32_t MCCAPCON_SET; + __O uint32_t MCCAPCON_CLR; + __IO uint32_t MCTIM0; + __IO uint32_t MCTIM1; + __IO uint32_t MCTIM2; + __IO uint32_t MCPER0; + __IO uint32_t MCPER1; + __IO uint32_t MCPER2; + __IO uint32_t MCPW0; + __IO uint32_t MCPW1; + __IO uint32_t MCPW2; + __IO uint32_t MCDEADTIME; + __IO uint32_t MCCCP; + __IO uint32_t MCCR0; + __IO uint32_t MCCR1; + __IO uint32_t MCCR2; + __I uint32_t MCINTEN; + __O uint32_t MCINTEN_SET; + __O uint32_t MCINTEN_CLR; + __I uint32_t MCCNTCON; + __O uint32_t MCCNTCON_SET; + __O uint32_t MCCNTCON_CLR; + __I uint32_t MCINTFLAG; + __O uint32_t MCINTFLAG_SET; + __O uint32_t MCINTFLAG_CLR; + __O uint32_t MCCAP_CLR; +} MCPWM_TypeDef; + +/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/ +typedef struct +{ + __O uint32_t QEICON; + __I uint32_t QEISTAT; + __IO uint32_t QEICONF; + __I uint32_t QEIPOS; + __IO uint32_t QEIMAXPOS; + __IO uint32_t CMPOS0; + __IO uint32_t CMPOS1; + __IO uint32_t CMPOS2; + __I uint32_t INXCNT; + __IO uint32_t INXCMP; + __IO uint32_t QEILOAD; + __I uint32_t QEITIME; + __I uint32_t QEIVEL; + __I uint32_t QEICAP; + __IO uint32_t VELCOMP; + __IO uint32_t FILTER; + uint32_t RESERVED0[998]; + __O uint32_t QEIIEC; + __O uint32_t QEIIES; + __I uint32_t QEIINTSTAT; + __I uint32_t QEIIE; + __O uint32_t QEICLR; + __O uint32_t QEISET; +} QEI_TypeDef; + +/*------------- Controller Area Network (CAN) --------------------------------*/ +typedef struct +{ + __IO uint32_t mask[512]; /* ID Masks */ +} CANAF_RAM_TypeDef; + +typedef struct /* Acceptance Filter Registers */ +{ + __IO uint32_t AFMR; + __IO uint32_t SFF_sa; + __IO uint32_t SFF_GRP_sa; + __IO uint32_t EFF_sa; + __IO uint32_t EFF_GRP_sa; + __IO uint32_t ENDofTable; + __I uint32_t LUTerrAd; + __I uint32_t LUTerr; +} CANAF_TypeDef; + +typedef struct /* Central Registers */ +{ + __I uint32_t CANTxSR; + __I uint32_t CANRxSR; + __I uint32_t CANMSR; +} CANCR_TypeDef; + +typedef struct /* Controller Registers */ +{ + __IO uint32_t MOD; + __O uint32_t CMR; + __IO uint32_t GSR; + __I uint32_t ICR; + __IO uint32_t IER; + __IO uint32_t BTR; + __IO uint32_t EWL; + __I uint32_t SR; + __IO uint32_t RFS; + __IO uint32_t RID; + __IO uint32_t RDA; + __IO uint32_t RDB; + __IO uint32_t TFI1; + __IO uint32_t TID1; + __IO uint32_t TDA1; + __IO uint32_t TDB1; + __IO uint32_t TFI2; + __IO uint32_t TID2; + __IO uint32_t TDA2; + __IO uint32_t TDB2; + __IO uint32_t TFI3; + __IO uint32_t TID3; + __IO uint32_t TDA3; + __IO uint32_t TDB3; +} CAN_TypeDef; + +/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/ +typedef struct /* Common Registers */ +{ + __I uint32_t DMACIntStat; + __I uint32_t DMACIntTCStat; + __O uint32_t DMACIntTCClear; + __I uint32_t DMACIntErrStat; + __O uint32_t DMACIntErrClr; + __I uint32_t DMACRawIntTCStat; + __I uint32_t DMACRawIntErrStat; + __I uint32_t DMACEnbldChns; + __IO uint32_t DMACSoftBReq; + __IO uint32_t DMACSoftSReq; + __IO uint32_t DMACSoftLBReq; + __IO uint32_t DMACSoftLSReq; + __IO uint32_t DMACConfig; + __IO uint32_t DMACSync; +} GPDMA_TypeDef; + +typedef struct /* Channel Registers */ +{ + __IO uint32_t DMACCSrcAddr; + __IO uint32_t DMACCDestAddr; + __IO uint32_t DMACCLLI; + __IO uint32_t DMACCControl; + __IO uint32_t DMACCConfig; +} GPDMACH_TypeDef; + +/*------------- Universal Serial Bus (USB) -----------------------------------*/ +typedef struct +{ + __I uint32_t HcRevision; /* USB Host Registers */ + __IO uint32_t HcControl; + __IO uint32_t HcCommandStatus; + __IO uint32_t HcInterruptStatus; + __IO uint32_t HcInterruptEnable; + __IO uint32_t HcInterruptDisable; + __IO uint32_t HcHCCA; + __I uint32_t HcPeriodCurrentED; + __IO uint32_t HcControlHeadED; + __IO uint32_t HcControlCurrentED; + __IO uint32_t HcBulkHeadED; + __IO uint32_t HcBulkCurrentED; + __I uint32_t HcDoneHead; + __IO uint32_t HcFmInterval; + __I uint32_t HcFmRemaining; + __I uint32_t HcFmNumber; + __IO uint32_t HcPeriodicStart; + __IO uint32_t HcLSTreshold; + __IO uint32_t HcRhDescriptorA; + __IO uint32_t HcRhDescriptorB; + __IO uint32_t HcRhStatus; + __IO uint32_t HcRhPortStatus1; + __IO uint32_t HcRhPortStatus2; + uint32_t RESERVED0[40]; + __I uint32_t Module_ID; + + __I uint32_t OTGIntSt; /* USB On-The-Go Registers */ + __IO uint32_t OTGIntEn; + __O uint32_t OTGIntSet; + __O uint32_t OTGIntClr; + __IO uint32_t OTGStCtrl; + __IO uint32_t OTGTmr; + uint32_t RESERVED1[58]; + + __I uint32_t USBDevIntSt; /* USB Device Interrupt Registers */ + __IO uint32_t USBDevIntEn; + __O uint32_t USBDevIntClr; + __O uint32_t USBDevIntSet; + + __O uint32_t USBCmdCode; /* USB Device SIE Command Registers */ + __I uint32_t USBCmdData; + + __I uint32_t USBRxData; /* USB Device Transfer Registers */ + __O uint32_t USBTxData; + __I uint32_t USBRxPLen; + __O uint32_t USBTxPLen; + __IO uint32_t USBCtrl; + __O uint32_t USBDevIntPri; + + __I uint32_t USBEpIntSt; /* USB Device Endpoint Interrupt Regs */ + __IO uint32_t USBEpIntEn; + __O uint32_t USBEpIntClr; + __O uint32_t USBEpIntSet; + __O uint32_t USBEpIntPri; + + __IO uint32_t USBReEp; /* USB Device Endpoint Realization Reg*/ + __O uint32_t USBEpInd; + __IO uint32_t USBMaxPSize; + + __I uint32_t USBDMARSt; /* USB Device DMA Registers */ + __O uint32_t USBDMARClr; + __O uint32_t USBDMARSet; + uint32_t RESERVED2[9]; + __IO uint32_t USBUDCAH; + __I uint32_t USBEpDMASt; + __O uint32_t USBEpDMAEn; + __O uint32_t USBEpDMADis; + __I uint32_t USBDMAIntSt; + __IO uint32_t USBDMAIntEn; + uint32_t RESERVED3[2]; + __I uint32_t USBEoTIntSt; + __O uint32_t USBEoTIntClr; + __O uint32_t USBEoTIntSet; + __I uint32_t USBNDDRIntSt; + __O uint32_t USBNDDRIntClr; + __O uint32_t USBNDDRIntSet; + __I uint32_t USBSysErrIntSt; + __O uint32_t USBSysErrIntClr; + __O uint32_t USBSysErrIntSet; + uint32_t RESERVED4[15]; + + __I uint32_t I2C_RX; /* USB OTG I2C Registers */ + __O uint32_t I2C_WO; + __I uint32_t I2C_STS; + __IO uint32_t I2C_CTL; + __IO uint32_t I2C_CLKHI; + __O uint32_t I2C_CLKLO; + uint32_t RESERVED5[823]; + + union { + __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */ + __IO uint32_t OTGClkCtrl; + } ; + union { + __I uint32_t USBClkSt; + __I uint32_t OTGClkSt; + }; +} USB_TypeDef; + +/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/ +typedef struct +{ + __IO uint32_t MAC1; /* MAC Registers */ + __IO uint32_t MAC2; + __IO uint32_t IPGT; + __IO uint32_t IPGR; + __IO uint32_t CLRT; + __IO uint32_t MAXF; + __IO uint32_t SUPP; + __IO uint32_t TEST; + __IO uint32_t MCFG; + __IO uint32_t MCMD; + __IO uint32_t MADR; + __O uint32_t MWTD; + __I uint32_t MRDD; + __I uint32_t MIND; + uint32_t RESERVED0[2]; + __IO uint32_t SA0; + __IO uint32_t SA1; + __IO uint32_t SA2; + uint32_t RESERVED1[45]; + __IO uint32_t Command; /* Control Registers */ + __I uint32_t Status; + __IO uint32_t RxDescriptor; + __IO uint32_t RxStatus; + __IO uint32_t RxDescriptorNumber; + __I uint32_t RxProduceIndex; + __IO uint32_t RxConsumeIndex; + __IO uint32_t TxDescriptor; + __IO uint32_t TxStatus; + __IO uint32_t TxDescriptorNumber; + __IO uint32_t TxProduceIndex; + __I uint32_t TxConsumeIndex; + uint32_t RESERVED2[10]; + __I uint32_t TSV0; + __I uint32_t TSV1; + __I uint32_t RSV; + uint32_t RESERVED3[3]; + __IO uint32_t FlowControlCounter; + __I uint32_t FlowControlStatus; + uint32_t RESERVED4[34]; + __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */ + __IO uint32_t RxFilterWoLStatus; + __IO uint32_t RxFilterWoLClear; + uint32_t RESERVED5; + __IO uint32_t HashFilterL; + __IO uint32_t HashFilterH; + uint32_t RESERVED6[882]; + __I uint32_t IntStatus; /* Module Control Registers */ + __IO uint32_t IntEnable; + __O uint32_t IntClear; + __O uint32_t IntSet; + uint32_t RESERVED7; + __IO uint32_t PowerDown; + uint32_t RESERVED8; + __IO uint32_t Module_ID; +} EMAC_TypeDef; + + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ +/* Base addresses */ +#define FLASH_BASE (0x00000000UL) +#define RAM_BASE (0x10000000UL) +#define GPIO_BASE (0x2009C000UL) +#define APB0_BASE (0x40000000UL) +#define APB1_BASE (0x40080000UL) +#define AHB_BASE (0x50000000UL) +#define CM3_BASE (0xE0000000UL) + +/* APB0 peripherals */ +#define WDT_BASE (APB0_BASE + 0x00000) +#define TIM0_BASE (APB0_BASE + 0x04000) +#define TIM1_BASE (APB0_BASE + 0x08000) +#define UART0_BASE (APB0_BASE + 0x0C000) +#define UART1_BASE (APB0_BASE + 0x10000) +#define PWM1_BASE (APB0_BASE + 0x18000) +#define I2C0_BASE (APB0_BASE + 0x1C000) +#define SPI_BASE (APB0_BASE + 0x20000) +#define RTC_BASE (APB0_BASE + 0x24000) +#define GPIOINT_BASE (APB0_BASE + 0x28080) +#define PINCON_BASE (APB0_BASE + 0x2C000) +#define SSP1_BASE (APB0_BASE + 0x30000) +#define ADC_BASE (APB0_BASE + 0x34000) +#define CANAF_RAM_BASE (APB0_BASE + 0x38000) +#define CANAF_BASE (APB0_BASE + 0x3C000) +#define CANCR_BASE (APB0_BASE + 0x40000) +#define CAN1_BASE (APB0_BASE + 0x44000) +#define CAN2_BASE (APB0_BASE + 0x48000) +#define I2C1_BASE (APB0_BASE + 0x5C000) + +/* APB1 peripherals */ +#define SSP0_BASE (APB1_BASE + 0x08000) +#define DAC_BASE (APB1_BASE + 0x0C000) +#define TIM2_BASE (APB1_BASE + 0x10000) +#define TIM3_BASE (APB1_BASE + 0x14000) +#define UART2_BASE (APB1_BASE + 0x18000) +#define UART3_BASE (APB1_BASE + 0x1C000) +#define I2C2_BASE (APB1_BASE + 0x20000) +#define I2S_BASE (APB1_BASE + 0x28000) +#define RIT_BASE (APB1_BASE + 0x30000) +#define MCPWM_BASE (APB1_BASE + 0x38000) +#define QEI_BASE (APB1_BASE + 0x3C000) +#define SC_BASE (APB1_BASE + 0x7C000) + +/* AHB peripherals */ +#define EMAC_BASE (AHB_BASE + 0x00000) +#define GPDMA_BASE (AHB_BASE + 0x04000) +#define GPDMACH0_BASE (AHB_BASE + 0x04100) +#define GPDMACH1_BASE (AHB_BASE + 0x04120) +#define GPDMACH2_BASE (AHB_BASE + 0x04140) +#define GPDMACH3_BASE (AHB_BASE + 0x04160) +#define GPDMACH4_BASE (AHB_BASE + 0x04180) +#define GPDMACH5_BASE (AHB_BASE + 0x041A0) +#define GPDMACH6_BASE (AHB_BASE + 0x041C0) +#define GPDMACH7_BASE (AHB_BASE + 0x041E0) +#define USB_BASE (AHB_BASE + 0x0C000) + +/* GPIOs */ +#define GPIO0_BASE (GPIO_BASE + 0x00000) +#define GPIO1_BASE (GPIO_BASE + 0x00020) +#define GPIO2_BASE (GPIO_BASE + 0x00040) +#define GPIO3_BASE (GPIO_BASE + 0x00060) +#define GPIO4_BASE (GPIO_BASE + 0x00080) + + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ +#define SC (( SC_TypeDef *) SC_BASE) +#define GPIO0 (( GPIO_TypeDef *) GPIO0_BASE) +#define GPIO1 (( GPIO_TypeDef *) GPIO1_BASE) +#define GPIO2 (( GPIO_TypeDef *) GPIO2_BASE) +#define GPIO3 (( GPIO_TypeDef *) GPIO3_BASE) +#define GPIO4 (( GPIO_TypeDef *) GPIO4_BASE) +#define WDT (( WDT_TypeDef *) WDT_BASE) +#define TIM0 (( TIM_TypeDef *) TIM0_BASE) +#define TIM1 (( TIM_TypeDef *) TIM1_BASE) +#define TIM2 (( TIM_TypeDef *) TIM2_BASE) +#define TIM3 (( TIM_TypeDef *) TIM3_BASE) +#define RIT (( RIT_TypeDef *) RIT_BASE) +#define UART0 (( UART_TypeDef *) UART0_BASE) +#define UART1 (( UART1_TypeDef *) UART1_BASE) +#define UART2 (( UART_TypeDef *) UART2_BASE) +#define UART3 (( UART_TypeDef *) UART3_BASE) +#define PWM1 (( PWM_TypeDef *) PWM1_BASE) +#define I2C0 (( I2C_TypeDef *) I2C0_BASE) +#define I2C1 (( I2C_TypeDef *) I2C1_BASE) +#define I2C2 (( I2C_TypeDef *) I2C2_BASE) +#define I2S (( I2S_TypeDef *) I2S_BASE) +#define SPI (( SPI_TypeDef *) SPI_BASE) +#define RTC (( RTC_TypeDef *) RTC_BASE) +#define GPIOINT (( GPIOINT_TypeDef *) GPIOINT_BASE) +#define PINCON (( PINCON_TypeDef *) PINCON_BASE) +#define SSP0 (( SSP_TypeDef *) SSP0_BASE) +#define SSP1 (( SSP_TypeDef *) SSP1_BASE) +#define ADC (( ADC_TypeDef *) ADC_BASE) +#define DAC (( DAC_TypeDef *) DAC_BASE) +#define CANAF_RAM ((CANAF_RAM_TypeDef *) CANAF_RAM_BASE) +#define CANAF (( CANAF_TypeDef *) CANAF_BASE) +#define CANCR (( CANCR_TypeDef *) CANCR_BASE) +#define CAN1 (( CAN_TypeDef *) CAN1_BASE) +#define CAN2 (( CAN_TypeDef *) CAN2_BASE) +#define MCPWM (( MCPWM_TypeDef *) MCPWM_BASE) +#define QEI (( QEI_TypeDef *) QEI_BASE) +#define EMAC (( EMAC_TypeDef *) EMAC_BASE) +#define GPDMA (( GPDMA_TypeDef *) GPDMA_BASE) +#define GPDMACH0 (( GPDMACH_TypeDef *) GPDMACH0_BASE) +#define GPDMACH1 (( GPDMACH_TypeDef *) GPDMACH1_BASE) +#define GPDMACH2 (( GPDMACH_TypeDef *) GPDMACH2_BASE) +#define GPDMACH3 (( GPDMACH_TypeDef *) GPDMACH3_BASE) +#define GPDMACH4 (( GPDMACH_TypeDef *) GPDMACH4_BASE) +#define GPDMACH5 (( GPDMACH_TypeDef *) GPDMACH5_BASE) +#define GPDMACH6 (( GPDMACH_TypeDef *) GPDMACH6_BASE) +#define GPDMACH7 (( GPDMACH_TypeDef *) GPDMACH7_BASE) +#define USB (( USB_TypeDef *) USB_BASE) + +#endif // __LPC17xx_H__ + + +#endif diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/USB_CDC.c b/Demo/CORTEX_LPC1768_IAR/LPCUSB/USB_CDC.c new file mode 100644 index 000000000..f27542d16 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/USB_CDC.c @@ -0,0 +1,437 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + Minimal implementation of a USB serial port, using the CDC class. + This example application simply echoes everything it receives right back + to the host. + + Windows: + Extract the usbser.sys file from .cab file in C:\WINDOWS\Driver Cache\i386 + and store it somewhere (C:\temp is a good place) along with the usbser.inf + file. Then plug in the LPC176x and direct windows to the usbser driver. + Windows then creates an extra COMx port that you can open in a terminal + program, like hyperterminal. [Note for FreeRTOS users - the required .inf + file is included in the project directory.] + + Linux: + The device should be recognised automatically by the cdc_acm driver, + which creates a /dev/ttyACMx device file that acts just like a regular + serial port. + +*/ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#include +#include + +#include "usbapi.h" +#include "usbdebug.h" +#include "usbstruct.h" + +#include "LPC17xx.h" + +#define usbMAX_SEND_BLOCK ( 20 / portTICK_RATE_MS ) +#define usbBUFFER_LEN ( 20 ) + +#define INCREMENT_ECHO_BY 1 +#define BAUD_RATE 115200 + +#define INT_IN_EP 0x81 +#define BULK_OUT_EP 0x05 +#define BULK_IN_EP 0x82 + +#define MAX_PACKET_SIZE 64 + +#define LE_WORD(x) ((x)&0xFF),((x)>>8) + +// CDC definitions +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 + +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_CONTROL_LINE_STATE 0x22 + +// data structure for GET_LINE_CODING / SET_LINE_CODING class requests +typedef struct { + unsigned long dwDTERate; + unsigned char bCharFormat; + unsigned char bParityType; + unsigned char bDataBits; +} TLineCoding; + +static TLineCoding LineCoding = {115200, 0, 0, 8}; +static unsigned char abBulkBuf[64]; +static unsigned char abClassReqData[8]; + +static xQueueHandle xRxedChars = NULL, xCharsForTx = NULL; + +// forward declaration of interrupt handler +void USBIntHandler(void); + +static const unsigned char abDescriptors[] = { + +// device descriptor + 0x12, + DESC_DEVICE, + LE_WORD(0x0101), // bcdUSB + 0x02, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + MAX_PACKET_SIZE0, // bMaxPacketSize + LE_WORD(0xFFFF), // idVendor + LE_WORD(0x0005), // idProduct + LE_WORD(0x0100), // bcdDevice + 0x01, // iManufacturer + 0x02, // iProduct + 0x03, // iSerialNumber + 0x01, // bNumConfigurations + +// configuration descriptor + 0x09, + DESC_CONFIGURATION, + LE_WORD(67), // wTotalLength + 0x02, // bNumInterfaces + 0x01, // bConfigurationValue + 0x00, // iConfiguration + 0xC0, // bmAttributes + 0x32, // bMaxPower +// control class interface + 0x09, + DESC_INTERFACE, + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x01, // bNumEndPoints + 0x02, // bInterfaceClass + 0x02, // bInterfaceSubClass + 0x01, // bInterfaceProtocol, linux requires value of 1 for the cdc_acm module + 0x00, // iInterface +// header functional descriptor + 0x05, + CS_INTERFACE, + 0x00, + LE_WORD(0x0110), +// call management functional descriptor + 0x05, + CS_INTERFACE, + 0x01, + 0x01, // bmCapabilities = device handles call management + 0x01, // bDataInterface +// ACM functional descriptor + 0x04, + CS_INTERFACE, + 0x02, + 0x02, // bmCapabilities +// union functional descriptor + 0x05, + CS_INTERFACE, + 0x06, + 0x00, // bMasterInterface + 0x01, // bSlaveInterface0 +// notification EP + 0x07, + DESC_ENDPOINT, + INT_IN_EP, // bEndpointAddress + 0x03, // bmAttributes = intr + LE_WORD(8), // wMaxPacketSize + 0x0A, // bInterval +// data class interface descriptor + 0x09, + DESC_INTERFACE, + 0x01, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndPoints + 0x0A, // bInterfaceClass = data + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0x00, // iInterface +// data EP OUT + 0x07, + DESC_ENDPOINT, + BULK_OUT_EP, // bEndpointAddress + 0x02, // bmAttributes = bulk + LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize + 0x00, // bInterval +// data EP in + 0x07, + DESC_ENDPOINT, + BULK_IN_EP, // bEndpointAddress + 0x02, // bmAttributes = bulk + LE_WORD(MAX_PACKET_SIZE), // wMaxPacketSize + 0x00, // bInterval + + // string descriptors + 0x04, + DESC_STRING, + LE_WORD(0x0409), + + 0x0E, + DESC_STRING, + 'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0, + + 0x14, + DESC_STRING, + 'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0, + + 0x12, + DESC_STRING, + 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'C', 0, '0', 0, 'D', 0, 'E', 0, + +// terminating zero + 0 +}; + + +/** + Local function to handle incoming bulk data + + @param [in] bEP + @param [in] bEPStatus + */ +static void BulkOut(unsigned char bEP, unsigned char bEPStatus) +{ + int i, iLen; + long lHigherPriorityTaskWoken = pdFALSE; + + ( void ) bEPStatus; + + // get data from USB into intermediate buffer + iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf)); + for (i = 0; i < iLen; i++) { + // put into queue + xQueueSendFromISR( xRxedChars, &( abBulkBuf[ i ] ), &lHigherPriorityTaskWoken ); + } + + portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); +} + + +/** + Local function to handle outgoing bulk data + + @param [in] bEP + @param [in] bEPStatus + */ +static void BulkIn(unsigned char bEP, unsigned char bEPStatus) +{ + int i, iLen; + long lHigherPriorityTaskWoken = pdFALSE; + + ( void ) bEPStatus; + + if (uxQueueMessagesWaitingFromISR( xCharsForTx ) == 0) { + // no more data, disable further NAK interrupts until next USB frame + USBHwNakIntEnable(0); + return; + } + + // get bytes from transmit FIFO into intermediate buffer + for (i = 0; i < MAX_PACKET_SIZE; i++) { + if( xQueueReceiveFromISR( xCharsForTx, ( &abBulkBuf[i] ), &lHigherPriorityTaskWoken ) != pdPASS ) + { + break; + } + } + iLen = i; + + // send over USB + if (iLen > 0) { + USBHwEPWrite(bEP, abBulkBuf, iLen); + } + + portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); +} + + +/** + Local function to handle the USB-CDC class requests + + @param [in] pSetup + @param [out] piLen + @param [out] ppbData + */ +static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData) +{ + switch (pSetup->bRequest) { + + // set line coding + case SET_LINE_CODING: +DBG("SET_LINE_CODING\n"); + memcpy((unsigned char *)&LineCoding, *ppbData, 7); + *piLen = 7; +DBG("dwDTERate=%u, bCharFormat=%u, bParityType=%u, bDataBits=%u\n", + LineCoding.dwDTERate, + LineCoding.bCharFormat, + LineCoding.bParityType, + LineCoding.bDataBits); + break; + + // get line coding + case GET_LINE_CODING: +DBG("GET_LINE_CODING\n"); + *ppbData = (unsigned char *)&LineCoding; + *piLen = 7; + break; + + // set control line state + case SET_CONTROL_LINE_STATE: + // bit0 = DTR, bit = RTS +DBG("SET_CONTROL_LINE_STATE %X\n", pSetup->wValue); + break; + + default: + return FALSE; + } + return TRUE; +} + + +/** + Writes one character to VCOM port + + @param [in] c character to write + @returns character written, or EOF if character could not be written + */ +int VCOM_putchar(int c) +{ +char cc = ( char ) c; + + if( xQueueSend( xCharsForTx, &cc, usbMAX_SEND_BLOCK ) == pdPASS ) + { + return c; + } + else + { + return EOF; + } +} + + +/** + Reads one character from VCOM port + + @returns character read, or EOF if character could not be read + */ +int VCOM_getchar(void) +{ + unsigned char c; + + /* Block the task until a character is available. */ + xQueueReceive( xRxedChars, &c, portMAX_DELAY ); + return c; +} + + +/** + Interrupt handler + + Simply calls the USB ISR + */ +//void USBIntHandler(void) +void USB_IRQHandler(void) +{ + USBHwISR(); +} + + +static void USBFrameHandler(unsigned short wFrame) +{ + ( void ) wFrame; + + if( uxQueueMessagesWaitingFromISR( xCharsForTx ) > 0 ) + { + // data available, enable NAK interrupt on bulk in + USBHwNakIntEnable(INACK_BI); + } +} + +void vUSBTask( void *pvParameters ) +{ + int c; + + /* Just to prevent compiler warnings about the unused parameter. */ + ( void ) pvParameters; + DBG("Initialising USB stack\n"); + + xRxedChars = xQueueCreate( usbBUFFER_LEN, sizeof( char ) ); + xCharsForTx = xQueueCreate( usbBUFFER_LEN, sizeof( char ) ); + + if( ( xRxedChars == NULL ) || ( xCharsForTx == NULL ) ) + { + /* Not enough heap available to create the buffer queues, can't do + anything so just delete ourselves. */ + vTaskDelete( NULL ); + } + + + // initialise stack + USBInit(); + + // register descriptors + USBRegisterDescriptors(abDescriptors); + + // register class request handler + USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abClassReqData); + + // register endpoint handlers + USBHwRegisterEPIntHandler(INT_IN_EP, NULL); + USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn); + USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut); + + // register frame handler + USBHwRegisterFrameHandler(USBFrameHandler); + + // enable bulk-in interrupts on NAKs + USBHwNakIntEnable(INACK_BI); + + DBG("Starting USB communication\n"); + + NVIC_SetPriority( USB_IRQn, configUSB_INTERRUPT_PRIORITY ); + NVIC_EnableIRQ( USB_IRQn ); + + // connect to bus + + DBG("Connecting to USB bus\n"); + USBHwConnect(TRUE); + + // echo any character received (do USB stuff in interrupt) + for( ;; ) + { + c = VCOM_getchar(); + if (c != EOF) + { + // Echo character back with INCREMENT_ECHO_BY offset, so for example if + // INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back. + VCOM_putchar(c + INCREMENT_ECHO_BY ); + } + } +} + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/type.h b/Demo/CORTEX_LPC1768_IAR/LPCUSB/type.h new file mode 100644 index 000000000..89d36850a --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/type.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * type.h: Type definition Header file for NXP LPC17xx Family + * Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.08.21 ver 1.00 Prelimnary version, first Release + * +******************************************************************************/ +#ifndef __TYPE_H__ +#define __TYPE_H__ + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef unsigned int BOOL; + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; + +/* Pointer to Function returning Void (any number of parameters) */ +typedef void (*PFV)(); + +#endif /* __TYPE_H__ */ diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbapi.h b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbapi.h new file mode 100644 index 000000000..050f0d95b --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbapi.h @@ -0,0 +1,118 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + @file +*/ + +#include "usbstruct.h" // for TSetupPacket + +/************************************************************************* + USB configuration +**************************************************************************/ + +#define MAX_PACKET_SIZE0 64 /**< maximum packet size for EP 0 */ + +/************************************************************************* + USB hardware interface +**************************************************************************/ + +// endpoint status sent through callback +#define EP_STATUS_DATA (1<<0) /**< EP has data */ +#define EP_STATUS_STALLED (1<<1) /**< EP is stalled */ +#define EP_STATUS_SETUP (1<<2) /**< EP received setup packet */ +#define EP_STATUS_ERROR (1<<3) /**< EP data was overwritten by setup packet */ +#define EP_STATUS_NACKED (1<<4) /**< EP sent NAK */ + +// device status sent through callback +#define DEV_STATUS_CONNECT (1<<0) /**< device just got connected */ +#define DEV_STATUS_SUSPEND (1<<2) /**< device entered suspend state */ +#define DEV_STATUS_RESET (1<<4) /**< device just got reset */ + +// interrupt bits for NACK events in USBHwNakIntEnable +// (these bits conveniently coincide with the LPC176x USB controller bit) +#define INACK_CI (1<<1) /**< interrupt on NACK for control in */ +#define INACK_CO (1<<2) /**< interrupt on NACK for control out */ +#define INACK_II (1<<3) /**< interrupt on NACK for interrupt in */ +#define INACK_IO (1<<4) /**< interrupt on NACK for interrupt out */ +#define INACK_BI (1<<5) /**< interrupt on NACK for bulk in */ +#define INACK_BO (1<<6) /**< interrupt on NACK for bulk out */ + +BOOL USBHwInit (void); +void USBHwISR (void); + +void USBHwNakIntEnable (unsigned char bIntBits); + +void USBHwConnect (BOOL fConnect); + +void USBHwSetAddress (unsigned char bAddr); +void USBHwConfigDevice (BOOL fConfigured); + +// endpoint operations +void USBHwEPConfig (unsigned char bEP, unsigned short wMaxPacketSize); +int USBHwEPRead (unsigned char bEP, unsigned char *pbBuf, int iMaxLen); +int USBHwEPWrite (unsigned char bEP, unsigned char *pbBuf, int iLen); +void USBHwEPStall (unsigned char bEP, BOOL fStall); +unsigned char USBHwEPGetStatus (unsigned char bEP); + +/** Endpoint interrupt handler callback */ +typedef void (TFnEPIntHandler) (unsigned char bEP, unsigned char bEPStatus); +void USBHwRegisterEPIntHandler (unsigned char bEP, TFnEPIntHandler *pfnHandler); + +/** Device status handler callback */ +typedef void (TFnDevIntHandler) (unsigned char bDevStatus); +void USBHwRegisterDevIntHandler (TFnDevIntHandler *pfnHandler); + +/** Frame event handler callback */ +typedef void (TFnFrameHandler)(unsigned short wFrame); +void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler); + + +/************************************************************************* + USB application interface +**************************************************************************/ + +// initialise the complete stack, including HW +BOOL USBInit(void); + +/** Request handler callback (standard, vendor, class) */ +typedef BOOL (TFnHandleRequest)(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData); +void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore); +void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler); + +/** Descriptor handler callback */ +typedef BOOL (TFnGetDescriptor)(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData); + +/** Default standard request handler */ +BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData); + +/** Default EP0 handler */ +void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat); + +/** Descriptor handling */ +void USBRegisterDescriptors(const unsigned char *pabDescriptors); +BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData); diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbcontrol.c b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbcontrol.c new file mode 100644 index 000000000..d78e553ec --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbcontrol.c @@ -0,0 +1,246 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** @file + Control transfer handler. + + This module handles control transfers and is normally installed on the + endpoint 0 callback. + + Control transfers can be of the following type: + 0 Standard; + 1 Class; + 2 Vendor; + 3 Reserved. + + A callback can be installed for each of these control transfers using + USBRegisterRequestHandler. + When an OUT request arrives, data is collected in the data store provided + with the USBRegisterRequestHandler call. When the transfer is done, the + callback is called. + When an IN request arrives, the callback is called immediately to either + put the control transfer data in the data store, or to get a pointer to + control transfer data. The data is then packetised and sent to the host. +*/ + +#include "usbdebug.h" + +#include "usbstruct.h" +#include "usbapi.h" + + + +#define MAX_CONTROL_SIZE 128 /**< maximum total size of control transfer data */ +#define MAX_REQ_HANDLERS 4 /**< standard, class, vendor, reserved */ + +static TSetupPacket Setup; /**< setup packet */ + +static unsigned char *pbData; /**< pointer to data buffer */ +static int iResidue; /**< remaining bytes in buffer */ +static int iLen; /**< total length of control transfer */ + +/** Array of installed request handler callbacks */ +static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL}; +/** Array of installed request data pointers */ +static unsigned char *apbDataStore[4] = {NULL, NULL, NULL, NULL}; + +/** + Local function to handle a request by calling one of the installed + request handlers. + + In case of data going from host to device, the data is at *ppbData. + In case of data going from device to host, the handler can either + choose to write its data at *ppbData or update the data pointer. + + @param [in] pSetup The setup packet + @param [in,out] *piLen Pointer to data length + @param [in,out] ppbData Data buffer. + + @return TRUE if the request was handles successfully + */ +static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData) +{ + TFnHandleRequest *pfnHandler; + int iType; + + iType = REQTYPE_GET_TYPE(pSetup->bmRequestType); + pfnHandler = apfnReqHandlers[iType]; + if (pfnHandler == NULL) { + DBG("No handler for reqtype %d\n", iType); + return FALSE; + } + + return pfnHandler(pSetup, piLen, ppbData); +} + + +/** + Local function to stall the control endpoint + + @param [in] bEPStat Endpoint status + */ +static void StallControlPipe(unsigned char bEPStat) +{ + unsigned char *pb; + int i; + + USBHwEPStall(0x80, TRUE); + +// dump setup packet + DBG("STALL on ["); + pb = (unsigned char *)&Setup; + for (i = 0; i < 8; i++) { + DBG(" %02x", *pb++); + } + DBG("] stat=%x\n", bEPStat); +} + + +/** + Sends next chunk of data (possibly 0 bytes) to host + */ +static void DataIn(void) +{ + int iChunk; + + if( MAX_PACKET_SIZE0 < iResidue ) + { + iChunk = MAX_PACKET_SIZE0; + } + else + { + iChunk = iResidue; + } + + USBHwEPWrite(0x80, pbData, iChunk); + pbData += iChunk; + iResidue -= iChunk; +} + + +/** + * Handles IN/OUT transfers on EP0 + * + * @param [in] bEP Endpoint address + * @param [in] bEPStat Endpoint status + */ +void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat) +{ + int iChunk, iType; + + if (bEP == 0x00) { + // OUT transfer + if (bEPStat & EP_STATUS_SETUP) { + // setup packet, reset request message state machine + USBHwEPRead(0x00, (unsigned char *)&Setup, sizeof(Setup)); + DBG("S%x", Setup.bRequest); + + // defaults for data pointer and residue + iType = REQTYPE_GET_TYPE(Setup.bmRequestType); + pbData = apbDataStore[iType]; + iResidue = Setup.wLength; + iLen = Setup.wLength; + + if ((Setup.wLength == 0) || + (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) { + // ask installed handler to process request + if (!_HandleRequest(&Setup, &iLen, &pbData)) { + DBG("_HandleRequest1 failed\n"); + StallControlPipe(bEPStat); + return; + } + // send smallest of requested and offered length + if( iLen < Setup.wLength ) + { + iResidue = iLen; + } + else + { + iResidue = Setup.wLength; + } + + // send first part (possibly a zero-length status message) + DataIn(); + } + } + else { + if (iResidue > 0) { + // store data + iChunk = USBHwEPRead(0x00, pbData, iResidue); + if (iChunk < 0) { + StallControlPipe(bEPStat); + return; + } + pbData += iChunk; + iResidue -= iChunk; + if (iResidue == 0) { + // received all, send data to handler + iType = REQTYPE_GET_TYPE(Setup.bmRequestType); + pbData = apbDataStore[iType]; + if (!_HandleRequest(&Setup, &iLen, &pbData)) { + DBG("_HandleRequest2 failed\n"); + StallControlPipe(bEPStat); + return; + } + // send status to host + DataIn(); + } + } + else { + // absorb zero-length status message + iChunk = USBHwEPRead(0x00, NULL, 0); + DBG(iChunk > 0 ? "?" : ""); + } + } + } + else if (bEP == 0x80) { + // IN transfer + // send more data if available (possibly a 0-length packet) + DataIn(); + } + else { + ASSERT(FALSE); + } +} + + +/** + Registers a callback for handling requests + + @param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD + @param [in] *pfnHandler Callback function pointer + @param [in] *pbDataStore Data storage area for this type of request + */ +void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore) +{ + ASSERT(iType >= 0); + ASSERT(iType < 4); + apfnReqHandlers[iType] = pfnHandler; + apbDataStore[iType] = pbDataStore; +} + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbdebug.h b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbdebug.h new file mode 100644 index 000000000..490f0a7f7 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbdebug.h @@ -0,0 +1,41 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// CodeRed - comment out this printf, as will use real one from stdio.h +// to implement output via semihosting + +//int printf(const char *format, ...); +# include + +#ifdef _DEBUG +#define DBG printf +#define ASSERT(x) if(!(x)){DBG("\nAssertion '%s' failed in %s:%s#%d!\n",#x,__FILE__,__FUNCTION__,__LINE__);while(1);} +#else +#define DBG(...) +#define ASSERT(x) +#endif + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c new file mode 100644 index 000000000..3105685f5 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c @@ -0,0 +1,521 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** @file + USB hardware layer + */ + + +#include "usbdebug.h" +#include "usbhw_lpc.h" +#include "usbapi.h" + +/** Installed device interrupt handler */ +static TFnDevIntHandler *_pfnDevIntHandler = NULL; +/** Installed endpoint interrupt handlers */ +static TFnEPIntHandler *_apfnEPIntHandlers[16]; +/** Installed frame interrupt handlers */ +static TFnFrameHandler *_pfnFrameHandler = NULL; + +/** convert from endpoint address to endpoint index */ +#define EP2IDX(bEP) ((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7)) +/** convert from endpoint index to endpoint address */ +#define IDX2EP(idx) ((((idx)<<7)&0x80)|(((idx)>>1)&0xF)) + + + +/** + Local function to wait for a device interrupt (and clear it) + + @param [in] dwIntr Bitmask of interrupts to wait for + */ +static void Wait4DevInt(unsigned long dwIntr) +{ + // wait for specific interrupt + while ((USB->USBDevIntSt & dwIntr) != dwIntr); + // clear the interrupt bits + USB->USBDevIntClr = dwIntr; +} + + +/** + Local function to send a command to the USB protocol engine + + @param [in] bCmd Command to send + */ +static void USBHwCmd(unsigned char bCmd) +{ + // clear CDFULL/CCEMTY + USB->USBDevIntClr = CDFULL | CCEMTY; + // write command code + USB->USBCmdCode = 0x00000500 | (bCmd << 16); + Wait4DevInt(CCEMTY); +} + + +/** + Local function to send a command + data to the USB protocol engine + + @param [in] bCmd Command to send + @param [in] bData Data to send + */ +static void USBHwCmdWrite(unsigned char bCmd, unsigned short bData) +{ + // write command code + USBHwCmd(bCmd); + + // write command data + USB->USBCmdCode = 0x00000100 | (bData << 16); + Wait4DevInt(CCEMTY); +} + + +/** + Local function to send a command to the USB protocol engine and read data + + @param [in] bCmd Command to send + + @return the data + */ +static unsigned char USBHwCmdRead(unsigned char bCmd) +{ + // write command code + USBHwCmd(bCmd); + + // get data + USB->USBCmdCode = 0x00000200 | (bCmd << 16); + Wait4DevInt(CDFULL); + return USB->USBCmdData; +} + + +/** + 'Realizes' an endpoint, meaning that buffer space is reserved for + it. An endpoint needs to be realised before it can be used. + + From experiments, it appears that a USB reset causes USBReEP to + re-initialise to 3 (= just the control endpoints). + However, a USB bus reset does not disturb the USBMaxPSize settings. + + @param [in] idx Endpoint index + @param [in] wMaxPSize Maximum packet size for this endpoint + */ +static void USBHwEPRealize(int idx, unsigned short wMaxPSize) +{ + USB->USBReEP |= (1 << idx); + USB->USBEpInd = idx; + USB->USBMaxPSize = wMaxPSize; + Wait4DevInt(EP_RLZED); +} + + +/** + Enables or disables an endpoint + + @param [in] idx Endpoint index + @param [in] fEnable TRUE to enable, FALSE to disable + */ +static void USBHwEPEnable(int idx, BOOL fEnable) +{ + USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA); +} + + +/** + Configures an endpoint and enables it + + @param [in] bEP Endpoint number + @param [in] wMaxPacketSize Maximum packet size for this EP + */ +void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize) +{ + int idx; + + idx = EP2IDX(bEP); + + // realise EP + USBHwEPRealize(idx, wMaxPacketSize); + + // enable EP + USBHwEPEnable(idx, TRUE); +} + + +/** + Registers an endpoint event callback + + @param [in] bEP Endpoint number + @param [in] pfnHandler Callback function + */ +void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler) +{ + int idx; + + idx = EP2IDX(bEP); + + ASSERT(idx<32); + + /* add handler to list of EP handlers */ + _apfnEPIntHandlers[idx / 2] = pfnHandler; + + /* enable EP interrupt */ + USB->USBEpIntEn |= (1 << idx); + USB->USBDevIntEn |= EP_SLOW; + + DBG("Registered handler for EP 0x%x\n", bEP); +} + + +/** + Registers an device status callback + + @param [in] pfnHandler Callback function + */ +void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler) +{ + _pfnDevIntHandler = pfnHandler; + + // enable device interrupt + USB->USBDevIntEn |= DEV_STAT; + + DBG("Registered handler for device status\n"); +} + + +/** + Registers the frame callback + + @param [in] pfnHandler Callback function + */ +void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler) +{ + _pfnFrameHandler = pfnHandler; + + // enable device interrupt + USB->USBDevIntEn |= FRAME; + + DBG("Registered handler for frame\n"); +} + + +/** + Sets the USB address. + + @param [in] bAddr Device address to set + */ +void USBHwSetAddress(unsigned char bAddr) +{ + USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr); +} + + +/** + Connects or disconnects from the USB bus + + @param [in] fConnect If TRUE, connect, otherwise disconnect + */ +void USBHwConnect(BOOL fConnect) +{ + USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0); +} + + +/** + Enables interrupt on NAK condition + + For IN endpoints a NAK is generated when the host wants to read data + from the device, but none is available in the endpoint buffer. + For OUT endpoints a NAK is generated when the host wants to write data + to the device, but the endpoint buffer is still full. + + The endpoint interrupt handlers can distinguish regular (ACK) interrupts + from NAK interrupt by checking the bits in their bEPStatus argument. + + @param [in] bIntBits Bitmap indicating which NAK interrupts to enable + */ +void USBHwNakIntEnable(unsigned char bIntBits) +{ + USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits); +} + + +/** + Gets the status from a specific endpoint. + + @param [in] bEP Endpoint number + @return Endpoint status byte (containing EP_STATUS_xxx bits) + */ +unsigned char USBHwEPGetStatus(unsigned char bEP) +{ + int idx = EP2IDX(bEP); + + return USBHwCmdRead(CMD_EP_SELECT | idx); +} + + +/** + Sets the stalled property of an endpoint + + @param [in] bEP Endpoint number + @param [in] fStall TRUE to stall, FALSE to unstall + */ +void USBHwEPStall(unsigned char bEP, BOOL fStall) +{ + int idx = EP2IDX(bEP); + + USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0); +} + + +/** + Writes data to an endpoint buffer + + @param [in] bEP Endpoint number + @param [in] pbBuf Endpoint data + @param [in] iLen Number of bytes to write + + @return TRUE if the data was successfully written or <0 in case of error. +*/ +int USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen) +{ + int idx; + + idx = EP2IDX(bEP); + + // set write enable for specific endpoint + USB->USBCtrl = WR_EN | ((bEP & 0xF) << 2); + + // set packet length + USB->USBTxPLen = iLen; + + // write data + while (USB->USBCtrl & WR_EN) { + USB->USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0]; + pbBuf += 4; + } + + // select endpoint and validate buffer + USBHwCmd(CMD_EP_SELECT | idx); + USBHwCmd(CMD_EP_VALIDATE_BUFFER); + + return iLen; +} + + +/** + Reads data from an endpoint buffer + + @param [in] bEP Endpoint number + @param [in] pbBuf Endpoint data + @param [in] iMaxLen Maximum number of bytes to read + + @return the number of bytes available in the EP (possibly more than iMaxLen), + or <0 in case of error. + */ +int USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen) +{ + unsigned int i, idx; + unsigned long dwData, dwLen; + + idx = EP2IDX(bEP); + + // set read enable bit for specific endpoint + USB->USBCtrl = RD_EN | ((bEP & 0xF) << 2); + + // wait for PKT_RDY + do { + dwLen = USB->USBRxPLen; + } while ((dwLen & PKT_RDY) == 0); + + // packet valid? + if ((dwLen & DV) == 0) { + return -1; + } + + // get length + dwLen &= PKT_LNGTH_MASK; + + // get data + dwData = 0; + for (i = 0; i < dwLen; i++) { + if ((i % 4) == 0) { + dwData = USB->USBRxData; + } + if ((pbBuf != NULL) && ((int)i < iMaxLen)) { + pbBuf[i] = dwData & 0xFF; + } + dwData >>= 8; + } + + // make sure RD_EN is clear + USB->USBCtrl = 0; + + // select endpoint and clear buffer + USBHwCmd(CMD_EP_SELECT | idx); + USBHwCmd(CMD_EP_CLEAR_BUFFER); + + return dwLen; +} + + +/** + Sets the 'configured' state. + + All registered endpoints are 'realised' and enabled, and the + 'configured' bit is set in the device status register. + + @param [in] fConfigured If TRUE, configure device, else unconfigure + */ +void USBHwConfigDevice(BOOL fConfigured) +{ + // set configured bit + USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0); +} + + +/** + USB interrupt handler + + @todo Get all 11 bits of frame number instead of just 8 + + Endpoint interrupts are mapped to the slow interrupt + */ +void USBHwISR(void) +{ + unsigned long dwStatus; + unsigned long dwIntBit; + unsigned char bEPStat, bDevStat, bStat; + int i; + unsigned short wFrame; + + // handle device interrupts + dwStatus = USB->USBDevIntSt; + + // frame interrupt + if (dwStatus & FRAME) { + // clear int + USB->USBDevIntClr = FRAME; + // call handler + if (_pfnFrameHandler != NULL) { + wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR); + _pfnFrameHandler(wFrame); + } + } + + // device status interrupt + if (dwStatus & DEV_STAT) { + /* Clear DEV_STAT interrupt before reading DEV_STAT register. + This prevents corrupted device status reads, see + LPC2148 User manual revision 2, 25 july 2006. + */ + USB->USBDevIntClr = DEV_STAT; + bDevStat = USBHwCmdRead(CMD_DEV_STATUS); + if (bDevStat & (CON_CH | SUS_CH | RST)) { + // convert device status into something HW independent + bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) | + ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) | + ((bDevStat & RST) ? DEV_STATUS_RESET : 0); + // call handler + if (_pfnDevIntHandler != NULL) { + _pfnDevIntHandler(bStat); + } + } + } + + // endpoint interrupt + if (dwStatus & EP_SLOW) { + // clear EP_SLOW + USB->USBDevIntClr = EP_SLOW; + // check all endpoints + for (i = 0; i < 32; i++) { + dwIntBit = (1 << i); + if (USB->USBEpIntSt & dwIntBit) { + // clear int (and retrieve status) + USB->USBEpIntClr = dwIntBit; + Wait4DevInt(CDFULL); + bEPStat = USB->USBCmdData; + // convert EP pipe stat into something HW independent + bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) | + ((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) | + ((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) | + ((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) | + ((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0); + // call handler + if (_apfnEPIntHandlers[i / 2] != NULL) { + _apfnEPIntHandlers[i / 2](IDX2EP(i), bStat); + } + } + } + } +} + + + +/** + Initialises the USB hardware + + + @return TRUE if the hardware was successfully initialised + */ +BOOL USBHwInit(void) +{ + // P2.9 -> USB_CONNECT + PINCON->PINSEL4 &= ~0x000C0000; + PINCON->PINSEL4 |= 0x00040000; + + // P1.18 -> USB_UP_LED + // P1.30 -> VBUS + PINCON->PINSEL3 &= ~0x30000030; + PINCON->PINSEL3 |= 0x20000010; + + // P0.29 -> USB_D+ + // P0.30 -> USB_D- + PINCON->PINSEL1 &= ~0x3C000000; + PINCON->PINSEL1 |= 0x14000000; + + // enable PUSB + SC->PCONP |= (1UL << 31UL); + + USB->OTGClkCtrl = 0x12; /* Dev clock, AHB clock enable */ + while ((USB->OTGClkSt & 0x12) != 0x12); + + // disable/clear all interrupts for now + USB->USBDevIntEn = 0; + USB->USBDevIntClr = 0xFFFFFFFF; + USB->USBDevIntPri = 0; + + USB->USBEpIntEn = 0; + USB->USBEpIntClr = 0xFFFFFFFF; + USB->USBEpIntPri = 0; + + // by default, only ACKs generate interrupts + USBHwNakIntEnable(0); + + return TRUE; +} + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c.bak b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c.bak new file mode 100644 index 000000000..29de3ded9 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.c.bak @@ -0,0 +1,521 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** @file + USB hardware layer + */ + + +#include "usbdebug.h" +#include "usbhw_lpc.h" +#include "usbapi.h" + +/** Installed device interrupt handler */ +static TFnDevIntHandler *_pfnDevIntHandler = NULL; +/** Installed endpoint interrupt handlers */ +static TFnEPIntHandler *_apfnEPIntHandlers[16]; +/** Installed frame interrupt handlers */ +static TFnFrameHandler *_pfnFrameHandler = NULL; + +/** convert from endpoint address to endpoint index */ +#define EP2IDX(bEP) ((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7)) +/** convert from endpoint index to endpoint address */ +#define IDX2EP(idx) ((((idx)<<7)&0x80)|(((idx)>>1)&0xF)) + + + +/** + Local function to wait for a device interrupt (and clear it) + + @param [in] dwIntr Bitmask of interrupts to wait for + */ +static void Wait4DevInt(unsigned long dwIntr) +{ + // wait for specific interrupt + while ((USB->USBDevIntSt & dwIntr) != dwIntr); + // clear the interrupt bits + USB->USBDevIntClr = dwIntr; +} + + +/** + Local function to send a command to the USB protocol engine + + @param [in] bCmd Command to send + */ +static void USBHwCmd(unsigned char bCmd) +{ + // clear CDFULL/CCEMTY + USB->USBDevIntClr = CDFULL | CCEMTY; + // write command code + USB->USBCmdCode = 0x00000500 | (bCmd << 16); + Wait4DevInt(CCEMTY); +} + + +/** + Local function to send a command + data to the USB protocol engine + + @param [in] bCmd Command to send + @param [in] bData Data to send + */ +static void USBHwCmdWrite(unsigned char bCmd, unsigned short bData) +{ + // write command code + USBHwCmd(bCmd); + + // write command data + USB->USBCmdCode = 0x00000100 | (bData << 16); + Wait4DevInt(CCEMTY); +} + + +/** + Local function to send a command to the USB protocol engine and read data + + @param [in] bCmd Command to send + + @return the data + */ +static unsigned char USBHwCmdRead(unsigned char bCmd) +{ + // write command code + USBHwCmd(bCmd); + + // get data + USB->USBCmdCode = 0x00000200 | (bCmd << 16); + Wait4DevInt(CDFULL); + return USB->USBCmdData; +} + + +/** + 'Realizes' an endpoint, meaning that buffer space is reserved for + it. An endpoint needs to be realised before it can be used. + + From experiments, it appears that a USB reset causes USBReEP to + re-initialise to 3 (= just the control endpoints). + However, a USB bus reset does not disturb the USBMaxPSize settings. + + @param [in] idx Endpoint index + @param [in] wMaxPSize Maximum packet size for this endpoint + */ +static void USBHwEPRealize(int idx, unsigned short wMaxPSize) +{ + USB->USBReEP |= (1 << idx); + USB->USBEpInd = idx; + USB->USBMaxPSize = wMaxPSize; + Wait4DevInt(EP_RLZED); +} + + +/** + Enables or disables an endpoint + + @param [in] idx Endpoint index + @param [in] fEnable TRUE to enable, FALSE to disable + */ +static void USBHwEPEnable(int idx, BOOL fEnable) +{ + USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA); +} + + +/** + Configures an endpoint and enables it + + @param [in] bEP Endpoint number + @param [in] wMaxPacketSize Maximum packet size for this EP + */ +void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize) +{ + int idx; + + idx = EP2IDX(bEP); + + // realise EP + USBHwEPRealize(idx, wMaxPacketSize); + + // enable EP + USBHwEPEnable(idx, TRUE); +} + + +/** + Registers an endpoint event callback + + @param [in] bEP Endpoint number + @param [in] pfnHandler Callback function + */ +void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler) +{ + int idx; + + idx = EP2IDX(bEP); + + ASSERT(idx<32); + + /* add handler to list of EP handlers */ + _apfnEPIntHandlers[idx / 2] = pfnHandler; + + /* enable EP interrupt */ + USB->USBEpIntEn |= (1 << idx); + USB->USBDevIntEn |= EP_SLOW; + + DBG("Registered handler for EP 0x%x\n", bEP); +} + + +/** + Registers an device status callback + + @param [in] pfnHandler Callback function + */ +void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler) +{ + _pfnDevIntHandler = pfnHandler; + + // enable device interrupt + USB->USBDevIntEn |= DEV_STAT; + + DBG("Registered handler for device status\n"); +} + + +/** + Registers the frame callback + + @param [in] pfnHandler Callback function + */ +void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler) +{ + _pfnFrameHandler = pfnHandler; + + // enable device interrupt + USB->USBDevIntEn |= FRAME; + + DBG("Registered handler for frame\n"); +} + + +/** + Sets the USB address. + + @param [in] bAddr Device address to set + */ +void USBHwSetAddress(unsigned char bAddr) +{ + USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr); +} + + +/** + Connects or disconnects from the USB bus + + @param [in] fConnect If TRUE, connect, otherwise disconnect + */ +void USBHwConnect(BOOL fConnect) +{ + USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0); +} + + +/** + Enables interrupt on NAK condition + + For IN endpoints a NAK is generated when the host wants to read data + from the device, but none is available in the endpoint buffer. + For OUT endpoints a NAK is generated when the host wants to write data + to the device, but the endpoint buffer is still full. + + The endpoint interrupt handlers can distinguish regular (ACK) interrupts + from NAK interrupt by checking the bits in their bEPStatus argument. + + @param [in] bIntBits Bitmap indicating which NAK interrupts to enable + */ +void USBHwNakIntEnable(unsigned char bIntBits) +{ + USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits); +} + + +/** + Gets the status from a specific endpoint. + + @param [in] bEP Endpoint number + @return Endpoint status byte (containing EP_STATUS_xxx bits) + */ +unsigned char USBHwEPGetStatus(unsigned char bEP) +{ + int idx = EP2IDX(bEP); + + return USBHwCmdRead(CMD_EP_SELECT | idx); +} + + +/** + Sets the stalled property of an endpoint + + @param [in] bEP Endpoint number + @param [in] fStall TRUE to stall, FALSE to unstall + */ +void USBHwEPStall(unsigned char bEP, BOOL fStall) +{ + int idx = EP2IDX(bEP); + + USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0); +} + + +/** + Writes data to an endpoint buffer + + @param [in] bEP Endpoint number + @param [in] pbBuf Endpoint data + @param [in] iLen Number of bytes to write + + @return TRUE if the data was successfully written or <0 in case of error. +*/ +int USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen) +{ + int idx; + + idx = EP2IDX(bEP); + + // set write enable for specific endpoint + USB->USBCtrl = WR_EN | ((bEP & 0xF) << 2); + + // set packet length + USB->USBTxPLen = iLen; + + // write data + while (USB->USBCtrl & WR_EN) { + USB->USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0]; + pbBuf += 4; + } + + // select endpoint and validate buffer + USBHwCmd(CMD_EP_SELECT | idx); + USBHwCmd(CMD_EP_VALIDATE_BUFFER); + + return iLen; +} + + +/** + Reads data from an endpoint buffer + + @param [in] bEP Endpoint number + @param [in] pbBuf Endpoint data + @param [in] iMaxLen Maximum number of bytes to read + + @return the number of bytes available in the EP (possibly more than iMaxLen), + or <0 in case of error. + */ +int USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen) +{ + unsigned int i, idx; + unsigned long dwData, dwLen; + + idx = EP2IDX(bEP); + + // set read enable bit for specific endpoint + USB->USBCtrl = RD_EN | ((bEP & 0xF) << 2); + + // wait for PKT_RDY + do { + dwLen = USB->USBRxPLen; + } while ((dwLen & PKT_RDY) == 0); + + // packet valid? + if ((dwLen & DV) == 0) { + return -1; + } + + // get length + dwLen &= PKT_LNGTH_MASK; + + // get data + dwData = 0; + for (i = 0; i < dwLen; i++) { + if ((i % 4) == 0) { + dwData = USB->USBRxData; + } + if ((pbBuf != NULL) && (i < iMaxLen)) { + pbBuf[i] = dwData & 0xFF; + } + dwData >>= 8; + } + + // make sure RD_EN is clear + USB->USBCtrl = 0; + + // select endpoint and clear buffer + USBHwCmd(CMD_EP_SELECT | idx); + USBHwCmd(CMD_EP_CLEAR_BUFFER); + + return dwLen; +} + + +/** + Sets the 'configured' state. + + All registered endpoints are 'realised' and enabled, and the + 'configured' bit is set in the device status register. + + @param [in] fConfigured If TRUE, configure device, else unconfigure + */ +void USBHwConfigDevice(BOOL fConfigured) +{ + // set configured bit + USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0); +} + + +/** + USB interrupt handler + + @todo Get all 11 bits of frame number instead of just 8 + + Endpoint interrupts are mapped to the slow interrupt + */ +void USBHwISR(void) +{ + unsigned long dwStatus; + unsigned long dwIntBit; + unsigned char bEPStat, bDevStat, bStat; + int i; + unsigned short wFrame; + + // handle device interrupts + dwStatus = USB->USBDevIntSt; + + // frame interrupt + if (dwStatus & FRAME) { + // clear int + USB->USBDevIntClr = FRAME; + // call handler + if (_pfnFrameHandler != NULL) { + wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR); + _pfnFrameHandler(wFrame); + } + } + + // device status interrupt + if (dwStatus & DEV_STAT) { + /* Clear DEV_STAT interrupt before reading DEV_STAT register. + This prevents corrupted device status reads, see + LPC2148 User manual revision 2, 25 july 2006. + */ + USB->USBDevIntClr = DEV_STAT; + bDevStat = USBHwCmdRead(CMD_DEV_STATUS); + if (bDevStat & (CON_CH | SUS_CH | RST)) { + // convert device status into something HW independent + bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) | + ((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) | + ((bDevStat & RST) ? DEV_STATUS_RESET : 0); + // call handler + if (_pfnDevIntHandler != NULL) { + _pfnDevIntHandler(bStat); + } + } + } + + // endpoint interrupt + if (dwStatus & EP_SLOW) { + // clear EP_SLOW + USB->USBDevIntClr = EP_SLOW; + // check all endpoints + for (i = 0; i < 32; i++) { + dwIntBit = (1 << i); + if (USB->USBEpIntSt & dwIntBit) { + // clear int (and retrieve status) + USB->USBEpIntClr = dwIntBit; + Wait4DevInt(CDFULL); + bEPStat = USB->USBCmdData; + // convert EP pipe stat into something HW independent + bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) | + ((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) | + ((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) | + ((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) | + ((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0); + // call handler + if (_apfnEPIntHandlers[i / 2] != NULL) { + _apfnEPIntHandlers[i / 2](IDX2EP(i), bStat); + } + } + } + } +} + + + +/** + Initialises the USB hardware + + + @return TRUE if the hardware was successfully initialised + */ +BOOL USBHwInit(void) +{ + // P2.9 -> USB_CONNECT + PINCON->PINSEL4 &= ~0x000C0000; + PINCON->PINSEL4 |= 0x00040000; + + // P1.18 -> USB_UP_LED + // P1.30 -> VBUS + PINCON->PINSEL3 &= ~0x30000030; + PINCON->PINSEL3 |= 0x20000010; + + // P0.29 -> USB_D+ + // P0.30 -> USB_D- + PINCON->PINSEL1 &= ~0x3C000000; + PINCON->PINSEL1 |= 0x14000000; + + // enable PUSB + SC->PCONP |= (1 << 31); + + USB->OTGClkCtrl = 0x12; /* Dev clock, AHB clock enable */ + while ((USB->OTGClkSt & 0x12) != 0x12); + + // disable/clear all interrupts for now + USB->USBDevIntEn = 0; + USB->USBDevIntClr = 0xFFFFFFFF; + USB->USBDevIntPri = 0; + + USB->USBEpIntEn = 0; + USB->USBEpIntClr = 0xFFFFFFFF; + USB->USBEpIntPri = 0; + + // by default, only ACKs generate interrupts + USBHwNakIntEnable(0); + + return TRUE; +} + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.h b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.h new file mode 100644 index 000000000..8578177e5 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbhw_lpc.h @@ -0,0 +1,149 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** + Hardware definitions for the LPC176x USB controller + + These are private to the usbhw module +*/ + +// CodeRed - pull in defines from NXP header file +//#include "NXP\LPC17xx\LPC17xx.h" +#include "LPC17xx.h" + + +// CodeRed - these registers have been renamed on LPC176x +#define USBReEP USBReEp +#define OTG_CLK_CTRL USBClkCtrl +#define OTG_CLK_STAT USBClkSt + +/* USBIntSt bits */ +#define USB_INT_REQ_LP (1<<0) +#define USB_INT_REQ_HP (1<<1) +#define USB_INT_REQ_DMA (1<<2) +#define USB_need_clock (1<<8) +#define EN_USB_BITS (1<<31) + +/* USBDevInt... bits */ +#define FRAME (1<<0) +#define EP_FAST (1<<1) +#define EP_SLOW (1<<2) +#define DEV_STAT (1<<3) +#define CCEMTY (1<<4) +#define CDFULL (1<<5) +#define RxENDPKT (1<<6) +#define TxENDPKT (1<<7) +#define EP_RLZED (1<<8) +#define ERR_INT (1<<9) + +/* USBRxPLen bits */ +#define PKT_LNGTH (1<<0) +#define PKT_LNGTH_MASK 0x3FF +#define DV (1<<10) +#define PKT_RDY (1<<11) + +/* USBCtrl bits */ +#define RD_EN (1<<0) +#define WR_EN (1<<1) +#define LOG_ENDPOINT (1<<2) + +/* protocol engine command codes */ + /* device commands */ +#define CMD_DEV_SET_ADDRESS 0xD0 +#define CMD_DEV_CONFIG 0xD8 +#define CMD_DEV_SET_MODE 0xF3 +#define CMD_DEV_READ_CUR_FRAME_NR 0xF5 +#define CMD_DEV_READ_TEST_REG 0xFD +#define CMD_DEV_STATUS 0xFE /* read/write */ +#define CMD_DEV_GET_ERROR_CODE 0xFF +#define CMD_DEV_READ_ERROR_STATUS 0xFB + /* endpoint commands */ +#define CMD_EP_SELECT 0x00 +#define CMD_EP_SELECT_CLEAR 0x40 +#define CMD_EP_SET_STATUS 0x40 +#define CMD_EP_CLEAR_BUFFER 0xF2 +#define CMD_EP_VALIDATE_BUFFER 0xFA + +/* set address command */ +#define DEV_ADDR (1<<0) +#define DEV_EN (1<<7) + +/* configure device command */ +#define CONF_DEVICE (1<<0) + +/* set mode command */ +#define AP_CLK (1<<0) +#define INAK_CI (1<<1) +#define INAK_CO (1<<2) +#define INAK_II (1<<3) +#define INAK_IO (1<<4) +#define INAK_BI (1<<5) +#define INAK_BO (1<<6) + +/* set get device status command */ +#define CON (1<<0) +#define CON_CH (1<<1) +#define SUS (1<<2) +#define SUS_CH (1<<3) +#define RST (1<<4) + +/* get error code command */ +// ... + +/* Select Endpoint command read bits */ +#define EPSTAT_FE (1<<0) +#define EPSTAT_ST (1<<1) +#define EPSTAT_STP (1<<2) +#define EPSTAT_PO (1<<3) +#define EPSTAT_EPN (1<<4) +#define EPSTAT_B1FULL (1<<5) +#define EPSTAT_B2FULL (1<<6) + +/* CMD_EP_SET_STATUS command */ +#define EP_ST (1<<0) +#define EP_DA (1<<5) +#define EP_RF_MO (1<<6) +#define EP_CND_ST (1<<7) + +/* read error status command */ +#define PID_ERR (1<<0) +#define UEPKT (1<<1) +#define DCRC (1<<2) +#define TIMEOUT (1<<3) +#define EOP (1<<4) +#define B_OVRN (1<<5) +#define BTSTF (1<<6) +#define TGL_ERR (1<<7) + + + + + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbinit.c b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbinit.c new file mode 100644 index 000000000..f1784c20b --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbinit.c @@ -0,0 +1,82 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** @file + USB stack initialisation + */ + + +#include "usbdebug.h" +#include "usbapi.h" + + +/** data storage area for standard requests */ +static unsigned char abStdReqData[8]; + + +/** + USB reset handler + + @param [in] bDevStatus Device status + */ +static void HandleUsbReset(unsigned char bDevStatus) +{ + if (bDevStatus & DEV_STATUS_RESET) { + DBG("\n!"); + } +} + + +/** + Initialises the USB hardware and sets up the USB stack by + installing default callbacks. + + @return TRUE if initialisation was successful + */ +BOOL USBInit(void) +{ + // init hardware + USBHwInit(); + + // register bus reset handler + USBHwRegisterDevIntHandler(HandleUsbReset); + + // register control transfer handler on EP0 + USBHwRegisterEPIntHandler(0x00, USBHandleControlTransfer); + USBHwRegisterEPIntHandler(0x80, USBHandleControlTransfer); + + // setup control endpoints + USBHwEPConfig(0x00, MAX_PACKET_SIZE0); + USBHwEPConfig(0x80, MAX_PACKET_SIZE0); + + // register standard request handler + USBRegisterRequestHandler(REQTYPE_TYPE_STANDARD, USBHandleStandardRequest, abStdReqData); + + return TRUE; +} + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstdreq.c b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstdreq.c new file mode 100644 index 000000000..05e58b417 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstdreq.c @@ -0,0 +1,430 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** @file + Standard request handler. + + This modules handles the 'chapter 9' processing, specifically the + standard device requests in table 9-3 from the universal serial bus + specification revision 2.0 + + Specific types of devices may specify additional requests (for example + HID devices add a GET_DESCRIPTOR request for interfaces), but they + will not be part of this module. + + @todo some requests have to return a request error if device not configured: + @todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME + @todo this applies to the following if endpoint != 0: + @todo SET_FEATURE, GET_FEATURE +*/ + +#include "usbdebug.h" +#include "usbstruct.h" +#include "usbapi.h" + +#define MAX_DESC_HANDLERS 4 /**< device, interface, endpoint, other */ + + +/* general descriptor field offsets */ +#define DESC_bLength 0 /**< length offset */ +#define DESC_bDescriptorType 1 /**< descriptor type offset */ + +/* config descriptor field offsets */ +#define CONF_DESC_wTotalLength 2 /**< total length offset */ +#define CONF_DESC_bConfigurationValue 5 /**< configuration value offset */ +#define CONF_DESC_bmAttributes 7 /**< configuration characteristics */ + +/* interface descriptor field offsets */ +#define INTF_DESC_bAlternateSetting 3 /**< alternate setting offset */ + +/* endpoint descriptor field offsets */ +#define ENDP_DESC_bEndpointAddress 2 /**< endpoint address offset */ +#define ENDP_DESC_wMaxPacketSize 4 /**< maximum packet size offset */ + + +/** Currently selected configuration */ +static unsigned char bConfiguration = 0; +/** Installed custom request handler */ +static TFnHandleRequest *pfnHandleCustomReq = NULL; +/** Pointer to registered descriptors */ +static const unsigned char *pabDescrip = NULL; + + +/** + Registers a pointer to a descriptor block containing all descriptors + for the device. + + @param [in] pabDescriptors The descriptor byte array + */ +void USBRegisterDescriptors(const unsigned char *pabDescriptors) +{ + pabDescrip = pabDescriptors; +} + + +/** + Parses the list of installed USB descriptors and attempts to find + the specified USB descriptor. + + @param [in] wTypeIndex Type and index of the descriptor + @param [in] wLangID Language ID of the descriptor (currently unused) + @param [out] *piLen Descriptor length + @param [out] *ppbData Descriptor data + + @return TRUE if the descriptor was found, FALSE otherwise + */ +BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData) +{ + unsigned char bType, bIndex; + unsigned char *pab; + int iCurIndex; + + ASSERT(pabDescrip != NULL); + + bType = GET_DESC_TYPE(wTypeIndex); + bIndex = GET_DESC_INDEX(wTypeIndex); + + pab = (unsigned char *)pabDescrip; + iCurIndex = 0; + + while (pab[DESC_bLength] != 0) { + if (pab[DESC_bDescriptorType] == bType) { + if (iCurIndex == bIndex) { + // set data pointer + *ppbData = pab; + // get length from structure + if (bType == DESC_CONFIGURATION) { + // configuration descriptor is an exception, length is at offset 2 and 3 + *piLen = (pab[CONF_DESC_wTotalLength]) | + (pab[CONF_DESC_wTotalLength + 1] << 8); + } + else { + // normally length is at offset 0 + *piLen = pab[DESC_bLength]; + } + return TRUE; + } + iCurIndex++; + } + // skip to next descriptor + pab += pab[DESC_bLength]; + } + // nothing found + DBG("Desc %x not found!\n", wTypeIndex); + return FALSE; +} + + +/** + Configures the device according to the specified configuration index and + alternate setting by parsing the installed USB descriptor list. + A configuration index of 0 unconfigures the device. + + @param [in] bConfigIndex Configuration index + @param [in] bAltSetting Alternate setting number + + @todo function always returns TRUE, add stricter checking? + + @return TRUE if successfully configured, FALSE otherwise + */ +static BOOL USBSetConfiguration(unsigned char bConfigIndex, unsigned char bAltSetting) +{ + unsigned char *pab; + unsigned char bCurConfig, bCurAltSetting; + unsigned char bEP; + unsigned short wMaxPktSize; + + ASSERT(pabDescrip != NULL); + + if (bConfigIndex == 0) { + // unconfigure device + USBHwConfigDevice(FALSE); + } + else { + // configure endpoints for this configuration/altsetting + pab = (unsigned char *)pabDescrip; + bCurConfig = 0xFF; + bCurAltSetting = 0xFF; + + while (pab[DESC_bLength] != 0) { + + switch (pab[DESC_bDescriptorType]) { + + case DESC_CONFIGURATION: + // remember current configuration index + bCurConfig = pab[CONF_DESC_bConfigurationValue]; + break; + + case DESC_INTERFACE: + // remember current alternate setting + bCurAltSetting = pab[INTF_DESC_bAlternateSetting]; + break; + + case DESC_ENDPOINT: + if ((bCurConfig == bConfigIndex) && + (bCurAltSetting == bAltSetting)) { + // endpoint found for desired config and alternate setting + bEP = pab[ENDP_DESC_bEndpointAddress]; + wMaxPktSize = (pab[ENDP_DESC_wMaxPacketSize]) | + (pab[ENDP_DESC_wMaxPacketSize + 1] << 8); + // configure endpoint + USBHwEPConfig(bEP, wMaxPktSize); + } + break; + + default: + break; + } + // skip to next descriptor + pab += pab[DESC_bLength]; + } + + // configure device + USBHwConfigDevice(TRUE); + } + + return TRUE; +} + + +/** + Local function to handle a standard device request + + @param [in] pSetup The setup packet + @param [in,out] *piLen Pointer to data length + @param [in,out] ppbData Data buffer. + + @return TRUE if the request was handled successfully + */ +static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData) +{ + unsigned char *pbData = *ppbData; + + switch (pSetup->bRequest) { + + case REQ_GET_STATUS: + // bit 0: self-powered + // bit 1: remote wakeup = not supported + pbData[0] = 0; + pbData[1] = 0; + *piLen = 2; + break; + + case REQ_SET_ADDRESS: + USBHwSetAddress(pSetup->wValue); + break; + + case REQ_GET_DESCRIPTOR: + DBG("D%x", pSetup->wValue); + return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData); + + case REQ_GET_CONFIGURATION: + // indicate if we are configured + pbData[0] = bConfiguration; + *piLen = 1; + break; + + case REQ_SET_CONFIGURATION: + if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) { + DBG("USBSetConfiguration failed!\n"); + return FALSE; + } + // configuration successful, update current configuration + bConfiguration = pSetup->wValue & 0xFF; + break; + + case REQ_CLEAR_FEATURE: + case REQ_SET_FEATURE: + if (pSetup->wValue == FEA_REMOTE_WAKEUP) { + // put DEVICE_REMOTE_WAKEUP code here + } + if (pSetup->wValue == FEA_TEST_MODE) { + // put TEST_MODE code here + } + return FALSE; + + case REQ_SET_DESCRIPTOR: + DBG("Device req %d not implemented\n", pSetup->bRequest); + return FALSE; + + default: + DBG("Illegal device req %d\n", pSetup->bRequest); + return FALSE; + } + + return TRUE; +} + + +/** + Local function to handle a standard interface request + + @param [in] pSetup The setup packet + @param [in,out] *piLen Pointer to data length + @param [in] ppbData Data buffer. + + @return TRUE if the request was handled successfully + */ +static BOOL HandleStdInterfaceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData) +{ + unsigned char *pbData = *ppbData; + + switch (pSetup->bRequest) { + + case REQ_GET_STATUS: + // no bits specified + pbData[0] = 0; + pbData[1] = 0; + *piLen = 2; + break; + + case REQ_CLEAR_FEATURE: + case REQ_SET_FEATURE: + // not defined for interface + return FALSE; + + case REQ_GET_INTERFACE: // TODO use bNumInterfaces + // there is only one interface, return n-1 (= 0) + pbData[0] = 0; + *piLen = 1; + break; + + case REQ_SET_INTERFACE: // TODO use bNumInterfaces + // there is only one interface (= 0) + if (pSetup->wValue != 0) { + return FALSE; + } + *piLen = 0; + break; + + default: + DBG("Illegal interface req %d\n", pSetup->bRequest); + return FALSE; + } + + return TRUE; +} + + +/** + Local function to handle a standard endpoint request + + @param [in] pSetup The setup packet + @param [in,out] *piLen Pointer to data length + @param [in] ppbData Data buffer. + + @return TRUE if the request was handled successfully + */ +static BOOL HandleStdEndPointReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData) +{ + unsigned char *pbData = *ppbData; + + switch (pSetup->bRequest) { + case REQ_GET_STATUS: + // bit 0 = endpointed halted or not + pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0; + pbData[1] = 0; + *piLen = 2; + break; + + case REQ_CLEAR_FEATURE: + if (pSetup->wValue == FEA_ENDPOINT_HALT) { + // clear HALT by unstalling + USBHwEPStall(pSetup->wIndex, FALSE); + break; + } + // only ENDPOINT_HALT defined for endpoints + return FALSE; + + case REQ_SET_FEATURE: + if (pSetup->wValue == FEA_ENDPOINT_HALT) { + // set HALT by stalling + USBHwEPStall(pSetup->wIndex, TRUE); + break; + } + // only ENDPOINT_HALT defined for endpoints + return FALSE; + + case REQ_SYNCH_FRAME: + DBG("EP req %d not implemented\n", pSetup->bRequest); + return FALSE; + + default: + DBG("Illegal EP req %d\n", pSetup->bRequest); + return FALSE; + } + + return TRUE; +} + + +/** + Default handler for standard ('chapter 9') requests + + If a custom request handler was installed, this handler is called first. + + @param [in] pSetup The setup packet + @param [in,out] *piLen Pointer to data length + @param [in] ppbData Data buffer. + + @return TRUE if the request was handled successfully + */ +BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData) +{ + // try the custom request handler first + if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) { + return TRUE; + } + + switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) { + case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData); + case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData); + case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData); + default: return FALSE; + } +} + + +/** + Registers a callback for custom device requests + + In USBHandleStandardRequest, the custom request handler gets a first + chance at handling the request before it is handed over to the 'chapter 9' + request handler. + + This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR + request is sent to an interface, which is not covered by the 'chapter 9' + specification. + + @param [in] pfnHandler Callback function pointer + */ +void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler) +{ + pfnHandleCustomReq = pfnHandler; +} + diff --git a/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstruct.h b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstruct.h new file mode 100644 index 000000000..a4b5fa72d --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/LPCUSB/usbstruct.h @@ -0,0 +1,119 @@ +/* + LPCUSB, an USB device driver for LPC microcontrollers + Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** + Definitions of structures of standard USB packets +*/ + +#ifndef _USBSTRUCT_H_ +#define _USBSTRUCT_H_ + +// CodeRed - include the LPCUSB type.h file rather than NXP one directly +#include "type.h" + +/** setup packet definitions */ +typedef struct { + unsigned char bmRequestType; /**< characteristics of the specific request */ + unsigned char bRequest; /**< specific request */ + unsigned short wValue; /**< request specific parameter */ + unsigned short wIndex; /**< request specific parameter */ + unsigned short wLength; /**< length of data transfered in data phase */ +} TSetupPacket; + + +#define REQTYPE_GET_DIR(x) (((x)>>7)&0x01) +#define REQTYPE_GET_TYPE(x) (((x)>>5)&0x03) +#define REQTYPE_GET_RECIP(x) ((x)&0x1F) + +#define REQTYPE_DIR_TO_DEVICE 0 +#define REQTYPE_DIR_TO_HOST 1 + +#define REQTYPE_TYPE_STANDARD 0 +#define REQTYPE_TYPE_CLASS 1 +#define REQTYPE_TYPE_VENDOR 2 +#define REQTYPE_TYPE_RESERVED 3 + +#define REQTYPE_RECIP_DEVICE 0 +#define REQTYPE_RECIP_INTERFACE 1 +#define REQTYPE_RECIP_ENDPOINT 2 +#define REQTYPE_RECIP_OTHER 3 + +/* standard requests */ +#define REQ_GET_STATUS 0x00 +#define REQ_CLEAR_FEATURE 0x01 +#define REQ_SET_FEATURE 0x03 +#define REQ_SET_ADDRESS 0x05 +#define REQ_GET_DESCRIPTOR 0x06 +#define REQ_SET_DESCRIPTOR 0x07 +#define REQ_GET_CONFIGURATION 0x08 +#define REQ_SET_CONFIGURATION 0x09 +#define REQ_GET_INTERFACE 0x0A +#define REQ_SET_INTERFACE 0x0B +#define REQ_SYNCH_FRAME 0x0C + +/* class requests HID */ +#define HID_GET_REPORT 0x01 +#define HID_GET_IDLE 0x02 +#define HID_GET_PROTOCOL 0x03 +#define HID_SET_REPORT 0x09 +#define HID_SET_IDLE 0x0A +#define HID_SET_PROTOCOL 0x0B + +/* feature selectors */ +#define FEA_ENDPOINT_HALT 0x00 +#define FEA_REMOTE_WAKEUP 0x01 +#define FEA_TEST_MODE 0x02 + +/* + USB descriptors +*/ + +/** USB descriptor header */ +typedef struct { + unsigned char bLength; /**< descriptor length */ + unsigned char bDescriptorType; /**< descriptor type */ +} TUSBDescHeader; + +#define DESC_DEVICE 1 +#define DESC_CONFIGURATION 2 +#define DESC_STRING 3 +#define DESC_INTERFACE 4 +#define DESC_ENDPOINT 5 +#define DESC_DEVICE_QUALIFIER 6 +#define DESC_OTHER_SPEED 7 +#define DESC_INTERFACE_POWER 8 + +#define DESC_HID_HID 0x21 +#define DESC_HID_REPORT 0x22 +#define DESC_HID_PHYSICAL 0x23 + +#define GET_DESC_TYPE(x) (((x)>>8)&0xFF) +#define GET_DESC_INDEX(x) ((x)&0xFF) + +#endif /* _USBSTRUCT_H_ */ + diff --git a/Demo/CORTEX_LPC1768_IAR/ParTest.c b/Demo/CORTEX_LPC1768_IAR/ParTest.c new file mode 100644 index 000000000..e64243701 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/ParTest.c @@ -0,0 +1,138 @@ +/* + FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation and modified by the FreeRTOS exception. + **NOTE** The exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + Alternative commercial license and support terms are also available upon + request. See the licensing section of http://www.FreeRTOS.org for full + license details. + + 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 along + with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + + *************************************************************************** + * * + * Looking for a quick start? Then check out the FreeRTOS eBook! * + * See http://www.FreeRTOS.org/Documentation for details * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* FreeRTOS.org includes. */ +#include "FreeRTOS.h" + +/* Demo application includes. */ +#include "partest.h" + +/*----------------------------------------------------------- + * Simple parallel port IO routines. + *-----------------------------------------------------------*/ + +#define partstNUM_LEDS ( 1 ) +#define partstLED_OUTPUT ( 1 << 25 ) + +void vParTestInitialise( void ) +{ + /* Only one LED on P1.25. */ + GPIO1->FIODIR = partstLED_OUTPUT; + + /* Start with LED off. */ + GPIO1->FIOSET = partstLED_OUTPUT; +} +/*-----------------------------------------------------------*/ + +void vParTestSetLED( unsigned long ulLEDIn, signed long xValue ) +{ + /* Used to set and clear LEDs on FIO2. */ + + if( ulLEDIn < partstNUM_LEDS ) + { + /* Set of clear the output. */ + if( xValue ) + { + GPIO1->FIOCLR = partstLED_OUTPUT; + } + else + { + GPIO1->FIOSET = partstLED_OUTPUT; + } + } +} +/*-----------------------------------------------------------*/ + +void vParTestToggleLED( unsigned long ulLEDIn ) +{ +unsigned long ulCurrentState; + + /* Used to toggle LEDs on FIO2. */ + + if( ulLEDIn < partstNUM_LEDS ) + { + /* If this bit is already set, clear it, and visa versa. */ + ulCurrentState = GPIO1->FIOPIN; + if( ulCurrentState & partstLED_OUTPUT ) + { + GPIO1->FIOCLR = partstLED_OUTPUT; + } + else + { + GPIO1->FIOSET = partstLED_OUTPUT; + } + } +} +/*-----------------------------------------------------------*/ + +long lParTestGetLEDState( void ) +{ + if( ( GPIO1->FIOPIN & partstLED_OUTPUT ) != 0 ) + { + return pdFALSE; + } + else + { + return pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +void vParTestSetLEDState( long lState ) +{ + /* Used to set and clear the LEDs on FIO1. */ + if( lState != pdFALSE ) + { + GPIO1->FIOSET = partstLED_OUTPUT; + } + else + { + GPIO1->FIOCLR = partstLED_OUTPUT; + } +} +/*-----------------------------------------------------------*/ + diff --git a/Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewd b/Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewd new file mode 100644 index 000000000..da9d540dd --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewd @@ -0,0 +1,1387 @@ + + + + 2 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + JLINK_ID + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 0 + 1 + 1 + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OSE\OseEpsilonPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\FreeRTOS\FreeRTOSPlugin.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 21 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IARROM_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + JLINK_ID + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 0 + 1 + 0 + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OSE\OseEpsilonPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\FreeRTOS\FreeRTOSPlugin.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewp b/Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewp new file mode 100644 index 000000000..44825cfe6 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/RTOSDemo.ewp @@ -0,0 +1,1700 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 17 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 17 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 21 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 7 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + Common Demo Tasks + + $PROJ_DIR$\..\Common\Minimal\BlockQ.c + + + $PROJ_DIR$\..\Common\Minimal\blocktim.c + + + $PROJ_DIR$\..\Common\Minimal\flash.c + + + $PROJ_DIR$\..\Common\Minimal\GenQTest.c + + + $PROJ_DIR$\..\Common\Minimal\integer.c + + + $PROJ_DIR$\..\Common\Minimal\PollQ.c + + + $PROJ_DIR$\..\Common\Minimal\QPeek.c + + + $PROJ_DIR$\..\Common\Minimal\recmutex.c + + + $PROJ_DIR$\..\Common\Minimal\semtest.c + + + + FreeRTOS + + $PROJ_DIR$\..\..\Source\portable\MemMang\heap_2.c + + + $PROJ_DIR$\..\..\Source\list.c + + + $PROJ_DIR$\..\..\Source\portable\IAR\ARM_CM3\port.c + + + $PROJ_DIR$\..\..\Source\portable\IAR\ARM_CM3\portasm.s + + + $PROJ_DIR$\..\..\Source\queue.c + + + $PROJ_DIR$\..\..\Source\tasks.c + + + + LPCUSB + + $PROJ_DIR$\LPCUSB\USB_CDC.c + + + $PROJ_DIR$\LPCUSB\usbcontrol.c + + + $PROJ_DIR$\LPCUSB\usbhw_lpc.c + + + $PROJ_DIR$\LPCUSB\usbinit.c + + + $PROJ_DIR$\LPCUSB\usbstdreq.c + + + + WEB Server + + $PROJ_DIR$\webserver\emac.c + + + $PROJ_DIR$\webserver\http-strings.c + + + $PROJ_DIR$\webserver\httpd-cgi.c + + + $PROJ_DIR$\webserver\httpd-fs.c + + + $PROJ_DIR$\webserver\httpd.c + + + $PROJ_DIR$\..\Common\ethernet\uIP\uip-1.0\uip\psock.c + + + $PROJ_DIR$\..\Common\ethernet\uIP\uip-1.0\uip\timer.c + + + $PROJ_DIR$\..\Common\ethernet\uIP\uip-1.0\uip\uip.c + + + $PROJ_DIR$\..\Common\ethernet\uIP\uip-1.0\uip\uip_arp.c + + + $PROJ_DIR$\webserver\uIP_Task.c + + + + $PROJ_DIR$\cstartup_M.s + + + $PROJ_DIR$\main.c + + + $PROJ_DIR$\ParTest.c + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/RTOSDemo.eww b/Demo/CORTEX_LPC1768_IAR/RTOSDemo.eww new file mode 100644 index 000000000..239a9381e --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/RTOSDemo.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\RTOSDemo.ewp + + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/core_cm3.h b/Demo/CORTEX_LPC1768_IAR/core_cm3.h new file mode 100644 index 000000000..b6f9696bf --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/core_cm3.h @@ -0,0 +1,1367 @@ +/****************************************************************************** + * @file: core_cm3.h + * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version: V1.20 + * @date: 22. May 2009 + *---------------------------------------------------------------------------- + * + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * ARM Limited (ARM) is supplying this software for use with Cortex-Mx + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CM3_CORE_H__ +#define __CM3_CORE_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< Cortex core */ + +/** + * Lint configuration \n + * ----------------------- \n + * + * The following Lint messages will be suppressed and not shown: \n + * \n + * --- Error 10: --- \n + * register uint32_t __regBasePri __asm("basepri"); \n + * Error 10: Expecting ';' \n + * \n + * --- Error 530: --- \n + * return(__regBasePri); \n + * Warning 530: Symbol '__regBasePri' (line 264) not initialized \n + * \n + * --- Error 550: --- \n + * __regBasePri = (basePri & 0x1ff); \n + * } \n + * Warning 550: Symbol '__regBasePri' (line 271) not accessed \n + * \n + * --- Error 754: --- \n + * uint32_t RESERVED0[24]; \n + * Info 754: local structure member '' (line 109, file ./cm3_core.h) not referenced \n + * \n + * --- Error 750: --- \n + * #define __CM3_CORE_H__ \n + * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n + * \n + * --- Error 528: --- \n + * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n + * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n + * \n + * --- Error 751: --- \n + * } InterruptType_Type; \n + * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n + * \n + * \n + * Note: To re-enable a Message, insert a space before 'lint' * \n + * + */ + +/*lint -save */ +/*lint -e10 */ +/*lint -e530 */ +/*lint -e550 */ +/*lint -e754 */ +/*lint -e750 */ +/*lint -e528 */ +/*lint -e751 */ + + +#include /* Include standard types */ + +#if defined (__ICCARM__) + #include /* IAR Intrinsics */ +#endif + + +#ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */ +#endif + + + + +/** + * IO definitions + * + * define access restrictions to peripheral registers + */ + +#ifdef __cplusplus +#define __I volatile /*!< defines 'read only' permissions */ +#else +#define __I volatile const /*!< defines 'read only' permissions */ +#endif +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ + + + +/******************************************************************************* + * Register Abstraction + ******************************************************************************/ + + +/* System Reset */ +#define NVIC_VECTRESET 0 /*!< Vector Reset Bit */ +#define NVIC_SYSRESETREQ 2 /*!< System Reset Request */ +#define NVIC_AIRCR_VECTKEY (0x5FA << 16) /*!< AIRCR Key for write access */ +#define NVIC_AIRCR_ENDIANESS 15 /*!< Endianess */ + +/* Core Debug */ +#define CoreDebug_DEMCR_TRCENA (1 << 24) /*!< DEMCR TRCENA enable */ +#define ITM_TCR_ITMENA 1 /*!< ITM enable */ + + + + +/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Software Trigger Interrupt Register */ +} NVIC_Type; + + +/* memory mapping struct for System Control Block */ +typedef struct +{ + __I uint32_t CPUID; /*!< CPU ID Base Register */ + __IO uint32_t ICSR; /*!< Interrupt Control State Register */ + __IO uint32_t VTOR; /*!< Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */ + __IO uint32_t SCR; /*!< System Control Register */ + __IO uint32_t CCR; /*!< Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Hard Fault Status Register */ + __IO uint32_t DFSR; /*!< Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Mem Manage Address Register */ + __IO uint32_t BFAR; /*!< Bus Fault Address Register */ + __IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Processor Feature Register */ + __I uint32_t DFR; /*!< Debug Feature Register */ + __I uint32_t ADR; /*!< Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< ISA Feature Register */ +} SCB_Type; + + +/* memory mapping struct for SysTick */ +typedef struct +{ + __IO uint32_t CTRL; /*!< SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< SysTick Current Value Register */ + __I uint32_t CALIB; /*!< SysTick Calibration Register */ +} SysTick_Type; + + +/* memory mapping structur for ITM */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __IO uint32_t IWR; /*!< ITM Integration Write Register */ + __IO uint32_t IRR; /*!< ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __IO uint32_t LAR; /*!< ITM Lock Access Register */ + __IO uint32_t LSR; /*!< ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< ITM Product ID Registers */ + __I uint32_t PID5; + __I uint32_t PID6; + __I uint32_t PID7; + __I uint32_t PID0; + __I uint32_t PID1; + __I uint32_t PID2; + __I uint32_t PID3; + __I uint32_t CID0; + __I uint32_t CID1; + __I uint32_t CID2; + __I uint32_t CID3; +} ITM_Type; + + +/* memory mapped struct for Interrupt Type */ +typedef struct +{ + uint32_t RESERVED0; + __I uint32_t ICTR; /*!< Interrupt Control Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Auxiliary Control Register */ +#else + uint32_t RESERVED1; +#endif +} InterruptType_Type; + + +/* Memory Protection Unit */ +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1) +typedef struct +{ + __I uint32_t TYPE; /*!< MPU Type Register */ + __IO uint32_t CTRL; /*!< MPU Control Register */ + __IO uint32_t RNR; /*!< MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; +#endif + + +/* Core Debug Register */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000) /*!< ITM Base Address */ +#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */ + +#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */ +#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */ +#endif + + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + + +/* ################### Compiler specific Intrinsics ########################### */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#define __enable_fault_irq __enable_fiq +#define __disable_fault_irq __disable_fiq + +#define __NOP __nop +#define __WFI __wfi +#define __WFE __wfe +#define __SEV __sev +#define __ISB() __isb(0) +#define __DSB() __dsb(0) +#define __DMB() __dmb(0) +#define __REV __rev +#define __RBIT __rbit +#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr)) +#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr)) +#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr)) +#define __STREXB(value, ptr) __strex(value, ptr) +#define __STREXH(value, ptr) __strex(value, ptr) +#define __STREXW(value, ptr) __strex(value, ptr) + + +/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */ +/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */ +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + + +/** + * @brief Return the Process Stack Pointer + * + * @param none + * @return uint32_t ProcessStackPointer + * + * Return the actual process stack pointer + */ +extern uint32_t __get_PSP(void); + +/** + * @brief Set the Process Stack Pointer + * + * @param uint32_t Process Stack Pointer + * @return none + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +extern void __set_PSP(uint32_t topOfProcStack); + +/** + * @brief Return the Main Stack Pointer + * + * @param none + * @return uint32_t Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +extern uint32_t __get_MSP(void); + +/** + * @brief Set the Main Stack Pointer + * + * @param uint32_t Main Stack Pointer + * @return none + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +extern void __set_MSP(uint32_t topOfMainStack); + +/** + * @brief Reverse byte order in unsigned short value + * + * @param uint16_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in unsigned short value + */ +extern uint32_t __REV16(uint16_t value); + +/* + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param int16_t value to reverse + * @return int32_t reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ +extern int32_t __REVSH(int16_t value); + + +#if (__ARMCC_VERSION < 400000) + +/** + * @brief Remove the exclusive lock created by ldrex + * + * @param none + * @return none + * + * Removes the exclusive lock which is created by ldrex. + */ +extern void __CLREX(void); + +/** + * @brief Return the Base Priority value + * + * @param none + * @return uint32_t BasePriority + * + * Return the content of the base priority register + */ +extern uint32_t __get_BASEPRI(void); + +/** + * @brief Set the Base Priority value + * + * @param uint32_t BasePriority + * @return none + * + * Set the base priority register + */ +extern void __set_BASEPRI(uint32_t basePri); + +/** + * @brief Return the Priority Mask value + * + * @param none + * @return uint32_t PriMask + * + * Return the state of the priority mask bit from the priority mask + * register + */ +extern uint32_t __get_PRIMASK(void); + +/** + * @brief Set the Priority Mask value + * + * @param uint32_t PriMask + * @return none + * + * Set the priority mask bit in the priority mask register + */ +extern void __set_PRIMASK(uint32_t priMask); + +/** + * @brief Return the Fault Mask value + * + * @param none + * @return uint32_t FaultMask + * + * Return the content of the fault mask register + */ +extern uint32_t __get_FAULTMASK(void); + +/** + * @brief Set the Fault Mask value + * + * @param uint32_t faultMask value + * @return none + * + * Set the fault mask register + */ +extern void __set_FAULTMASK(uint32_t faultMask); + +/** + * @brief Return the Control Register value + * + * @param none + * @return uint32_t Control value + * + * Return the content of the control register + */ +extern uint32_t __get_CONTROL(void); + +/** + * @brief Set the Control Register value + * + * @param uint32_t Control value + * @return none + * + * Set the control register + */ +extern void __set_CONTROL(uint32_t control); + +#else /* (__ARMCC_VERSION >= 400000) */ + + +/** + * @brief Remove the exclusive lock created by ldrex + * + * @param none + * @return none + * + * Removes the exclusive lock which is created by ldrex. + */ +#define __CLREX __clrex + +/** + * @brief Return the Base Priority value + * + * @param none + * @return uint32_t BasePriority + * + * Return the content of the base priority register + */ +static __INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + +/** + * @brief Set the Base Priority value + * + * @param uint32_t BasePriority + * @return none + * + * Set the base priority register + */ +static __INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0x1ff); +} + +/** + * @brief Return the Priority Mask value + * + * @param none + * @return uint32_t PriMask + * + * Return the state of the priority mask bit from the priority mask + * register + */ +static __INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + +/** + * @brief Set the Priority Mask value + * + * @param uint32_t PriMask + * @return none + * + * Set the priority mask bit in the priority mask register + */ +static __INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + +/** + * @brief Return the Fault Mask value + * + * @param none + * @return uint32_t FaultMask + * + * Return the content of the fault mask register + */ +static __INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + +/** + * @brief Set the Fault Mask value + * + * @param uint32_t faultMask value + * @return none + * + * Set the fault mask register + */ +static __INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & 1); +} + +/** + * @brief Return the Control Register value + * + * @param none + * @return uint32_t Control value + * + * Return the content of the control register + */ +static __INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + +/** + * @brief Set the Control Register value + * + * @param uint32_t Control value + * @return none + * + * Set the control register + */ +static __INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + +#endif /* __ARMCC_VERSION */ + + + +#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#define __enable_irq __enable_interrupt /*!< global Interrupt enable */ +#define __disable_irq __disable_interrupt /*!< global Interrupt disable */ + +static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); } +static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); } + +#define __NOP __no_operation() /*!< no operation intrinsic in IAR Compiler */ +static __INLINE void __WFI() { __ASM ("wfi"); } +static __INLINE void __WFE() { __ASM ("wfe"); } +static __INLINE void __SEV() { __ASM ("sev"); } +static __INLINE void __CLREX() { __ASM ("clrex"); } + +/* intrinsic void __ISB(void) */ +/* intrinsic void __DSB(void) */ +/* intrinsic void __DMB(void) */ +/* intrinsic void __set_PRIMASK(); */ +/* intrinsic void __get_PRIMASK(); */ +/* intrinsic void __set_FAULTMASK(); */ +/* intrinsic void __get_FAULTMASK(); */ +/* intrinsic uint32_t __REV(uint32_t value); */ +/* intrinsic uint32_t __REVSH(uint32_t value); */ +/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */ +/* intrinsic unsigned long __LDREX(unsigned long *); */ + + +/** + * @brief Return the Process Stack Pointer + * + * @param none + * @return uint32_t ProcessStackPointer + * + * Return the actual process stack pointer + */ +extern uint32_t __get_PSP(void); + +/** + * @brief Set the Process Stack Pointer + * + * @param uint32_t Process Stack Pointer + * @return none + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +extern void __set_PSP(uint32_t topOfProcStack); + +/** + * @brief Return the Main Stack Pointer + * + * @param none + * @return uint32_t Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +extern uint32_t __get_MSP(void); + +/** + * @brief Set the Main Stack Pointer + * + * @param uint32_t Main Stack Pointer + * @return none + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +extern void __set_MSP(uint32_t topOfMainStack); + +/** + * @brief Reverse byte order in unsigned short value + * + * @param uint16_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in unsigned short value + */ +extern uint32_t __REV16(uint16_t value); + +/** + * @brief Reverse bit order of value + * + * @param uint32_t value to reverse + * @return uint32_t reversed value + * + * Reverse bit order of value + */ +extern uint32_t __RBIT(uint32_t value); + +/** + * @brief LDR Exclusive + * + * @param uint8_t* address + * @return uint8_t value of (*address) + * + * Exclusive LDR command + */ +extern uint8_t __LDREXB(uint8_t *addr); + +/** + * @brief LDR Exclusive + * + * @param uint16_t* address + * @return uint16_t value of (*address) + * + * Exclusive LDR command + */ +extern uint16_t __LDREXH(uint16_t *addr); + +/** + * @brief LDR Exclusive + * + * @param uint32_t* address + * @return uint32_t value of (*address) + * + * Exclusive LDR command + */ +extern uint32_t __LDREXW(uint32_t *addr); + +/** + * @brief STR Exclusive + * + * @param uint8_t *address + * @param uint8_t value to store + * @return uint32_t successful / failed + * + * Exclusive STR command + */ +extern uint32_t __STREXB(uint8_t value, uint8_t *addr); + +/** + * @brief STR Exclusive + * + * @param uint16_t *address + * @param uint16_t value to store + * @return uint32_t successful / failed + * + * Exclusive STR command + */ +extern uint32_t __STREXH(uint16_t value, uint16_t *addr); + +/** + * @brief STR Exclusive + * + * @param uint32_t *address + * @param uint32_t value to store + * @return uint32_t successful / failed + * + * Exclusive STR command + */ +extern uint32_t __STREXW(uint32_t value, uint32_t *addr); + + + +#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); } +static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); } + +static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); } +static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); } + +static __INLINE void __NOP() { __ASM volatile ("nop"); } +static __INLINE void __WFI() { __ASM volatile ("wfi"); } +static __INLINE void __WFE() { __ASM volatile ("wfe"); } +static __INLINE void __SEV() { __ASM volatile ("sev"); } +static __INLINE void __ISB() { __ASM volatile ("isb"); } +static __INLINE void __DSB() { __ASM volatile ("dsb"); } +static __INLINE void __DMB() { __ASM volatile ("dmb"); } +static __INLINE void __CLREX() { __ASM volatile ("clrex"); } + + +/** + * @brief Return the Process Stack Pointer + * + * @param none + * @return uint32_t ProcessStackPointer + * + * Return the actual process stack pointer + */ +extern uint32_t __get_PSP(void); + +/** + * @brief Set the Process Stack Pointer + * + * @param uint32_t Process Stack Pointer + * @return none + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +extern void __set_PSP(uint32_t topOfProcStack); + +/** + * @brief Return the Main Stack Pointer + * + * @param none + * @return uint32_t Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +extern uint32_t __get_MSP(void); + +/** + * @brief Set the Main Stack Pointer + * + * @param uint32_t Main Stack Pointer + * @return none + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +extern void __set_MSP(uint32_t topOfMainStack); + +/** + * @brief Return the Base Priority value + * + * @param none + * @return uint32_t BasePriority + * + * Return the content of the base priority register + */ +extern uint32_t __get_BASEPRI(void); + +/** + * @brief Set the Base Priority value + * + * @param uint32_t BasePriority + * @return none + * + * Set the base priority register + */ +extern void __set_BASEPRI(uint32_t basePri); + +/** + * @brief Return the Priority Mask value + * + * @param none + * @return uint32_t PriMask + * + * Return the state of the priority mask bit from the priority mask + * register + */ +extern uint32_t __get_PRIMASK(void); + +/** + * @brief Set the Priority Mask value + * + * @param uint32_t PriMask + * @return none + * + * Set the priority mask bit in the priority mask register + */ +extern void __set_PRIMASK(uint32_t priMask); + +/** + * @brief Return the Fault Mask value + * + * @param none + * @return uint32_t FaultMask + * + * Return the content of the fault mask register + */ +extern uint32_t __get_FAULTMASK(void); + +/** + * @brief Set the Fault Mask value + * + * @param uint32_t faultMask value + * @return none + * + * Set the fault mask register + */ +extern void __set_FAULTMASK(uint32_t faultMask); + +/** + * @brief Return the Control Register value +* +* @param none +* @return uint32_t Control value + * + * Return the content of the control register + */ +extern uint32_t __get_CONTROL(void); + +/** + * @brief Set the Control Register value + * + * @param uint32_t Control value + * @return none + * + * Set the control register + */ +extern void __set_CONTROL(uint32_t control); + +/** + * @brief Reverse byte order in integer value + * + * @param uint32_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in integer value + */ +extern uint32_t __REV(uint32_t value); + +/** + * @brief Reverse byte order in unsigned short value + * + * @param uint16_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in unsigned short value + */ +extern uint32_t __REV16(uint16_t value); + +/* + * Reverse byte order in signed short value with sign extension to integer + * + * @param int16_t value to reverse + * @return int32_t reversed value + * + * @brief Reverse byte order in signed short value with sign extension to integer + */ +extern int32_t __REVSH(int16_t value); + +/** + * @brief Reverse bit order of value + * + * @param uint32_t value to reverse + * @return uint32_t reversed value + * + * Reverse bit order of value + */ +extern uint32_t __RBIT(uint32_t value); + +/** + * @brief LDR Exclusive + * + * @param uint8_t* address + * @return uint8_t value of (*address) + * + * Exclusive LDR command + */ +extern uint8_t __LDREXB(uint8_t *addr); + +/** + * @brief LDR Exclusive + * + * @param uint16_t* address + * @return uint16_t value of (*address) + * + * Exclusive LDR command + */ +extern uint16_t __LDREXH(uint16_t *addr); + +/** + * @brief LDR Exclusive + * + * @param uint32_t* address + * @return uint32_t value of (*address) + * + * Exclusive LDR command + */ +extern uint32_t __LDREXW(uint32_t *addr); + +/** + * @brief STR Exclusive + * + * @param uint8_t *address + * @param uint8_t value to store + * @return uint32_t successful / failed + * + * Exclusive STR command + */ +extern uint32_t __STREXB(uint8_t value, uint8_t *addr); + +/** + * @brief STR Exclusive + * + * @param uint16_t *address + * @param uint16_t value to store + * @return uint32_t successful / failed + * + * Exclusive STR command + */ +extern uint32_t __STREXH(uint16_t value, uint16_t *addr); + +/** + * @brief STR Exclusive + * + * @param uint32_t *address + * @param uint32_t value to store + * @return uint32_t successful / failed + * + * Exclusive STR command + */ +extern uint32_t __STREXW(uint32_t value, uint32_t *addr); + + +#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + + + +/* ########################## NVIC functions #################################### */ + + +/** + * @brief Set the Priority Grouping in NVIC Interrupt Controller + * + * @param uint32_t priority_grouping is priority grouping field + * @return none + * + * Set the priority grouping field using the required unlock sequence. + * The parameter priority_grouping is assigned to the field + * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + */ +static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((0xFFFFU << 16) | (0x0F << 8)); /* clear bits to change */ + reg_value = ((reg_value | NVIC_AIRCR_VECTKEY | (PriorityGroupTmp << 8))); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + +/** + * @brief Get the Priority Grouping from NVIC Interrupt Controller + * + * @param none + * @return uint32_t priority grouping field + * + * Get the priority grouping from NVIC Interrupt Controller. + * priority grouping is SCB->AIRCR [10:8] PRIGROUP field. + */ +static __INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR >> 8) & 0x07); /* read priority grouping field */ +} + +/** + * @brief Enable Interrupt in NVIC Interrupt Controller + * + * @param IRQn_Type IRQn specifies the interrupt number + * @return none + * + * Enable a device specific interupt in the NVIC interrupt controller. + * The interrupt number cannot be a negative value. + */ +static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + +/** + * @brief Disable the interrupt line for external interrupt specified + * + * @param IRQn_Type IRQn is the positive number of the external interrupt + * @return none + * + * Disable a device specific interupt in the NVIC interrupt controller. + * The interrupt number cannot be a negative value. + */ +static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + +/** + * @brief Read the interrupt pending bit for a device specific interrupt source + * + * @param IRQn_Type IRQn is the number of the device specifc interrupt + * @return uint32_t 1 if pending interrupt else 0 + * + * Read the pending register in NVIC and return 1 if its status is pending, + * otherwise it returns 0 + */ +static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + +/** + * @brief Set the pending bit for an external interrupt + * + * @param IRQn_Type IRQn is the Number of the interrupt + * @return none + * + * Set the pending bit for the specified interrupt. + * The interrupt number cannot be a negative value. + */ +static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + +/** + * @brief Clear the pending bit for an external interrupt + * + * @param IRQn_Type IRQn is the Number of the interrupt + * @return none + * + * Clear the pending bit for the specified interrupt. + * The interrupt number cannot be a negative value. + */ +static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + +/** + * @brief Read the active bit for an external interrupt + * + * @param IRQn_Type IRQn is the Number of the interrupt + * @return uint32_t 1 if active else 0 + * + * Read the active register in NVIC and returns 1 if its status is active, + * otherwise it returns 0. + */ +static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + +/** + * @brief Set the priority for an interrupt + * + * @param IRQn_Type IRQn is the Number of the interrupt + * @param priority is the priority for the interrupt + * @return none + * + * Set the priority for the specified interrupt. The interrupt + * number can be positive to specify an external (device specific) + * interrupt, or negative to specify an internal (core) interrupt. \n + * + * Note: The priority cannot be set for every core interrupt. + */ +static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + +/** + * @brief Read the priority for an interrupt + * + * @param IRQn_Type IRQn is the Number of the interrupt + * @return uint32_t priority is the priority for the interrupt + * + * Read the priority for the specified interrupt. The interrupt + * number can be positive to specify an external (device specific) + * interrupt, or negative to specify an internal (core) interrupt. + * + * The returned priority value is automatically aligned to the implemented + * priority bits of the microcontroller. + * + * Note: The priority cannot be set for every core interrupt. + */ +static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** + * @brief Encode the priority for an interrupt + * + * @param uint32_t PriorityGroup is the used priority group + * @param uint32_t PreemptPriority is the preemptive priority value (starting from 0) + * @param uint32_t SubPriority is the sub priority value (starting from 0) + * @return uint32_t the priority for the interrupt + * + * Encode the priority for an interrupt with the given priority group, + * preemptive priority value and sub priority value. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + * + * The returned priority value can be used for NVIC_SetPriority(...) function + */ +static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** + * @brief Decode the priority of an interrupt + * + * @param uint32_t Priority the priority for the interrupt + * @param uint32_t PrioGroup is the used priority group + * @param uint32_t* pPreemptPrio is the preemptive priority value (starting from 0) + * @param uint32_t* pSubPrio is the sub priority value (starting from 0) + * @return none + * + * Decode an interrupt priority value with the given priority group to + * preemptive priority value and sub priority value. + * In case of a conflict between priority grouping and available + * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + * + * The priority value can be retrieved with NVIC_GetPriority(...) function + */ +static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + + +/* ################################## SysTick function ############################################ */ + +#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0) + +/* SysTick constants */ +#define SYSTICK_ENABLE 0 /* Config-Bit to start or stop the SysTick Timer */ +#define SYSTICK_TICKINT 1 /* Config-Bit to enable or disable the SysTick interrupt */ +#define SYSTICK_CLKSOURCE 2 /* Clocksource has the offset 2 in SysTick Control and Status Register */ +#define SYSTICK_MAXCOUNT ((1<<24) -1) /* SysTick MaxCount */ + +/** + * @brief Initialize and start the SysTick counter and its interrupt. + * + * @param uint32_t ticks is the number of ticks between two interrupts + * @return none + * + * Initialise the system tick timer and its interrupt and start the + * system tick timer / counter in free running mode to generate + * periodical interrupts. + */ +static __INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ + SysTick->VAL = (0x00); /* Load the SysTick Counter Value */ + SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1<DEMCR & CoreDebug_DEMCR_TRCENA) && + (ITM->TCR & ITM_TCR_ITMENA) && + (ITM->TER & (1UL << 0)) ) + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __CM3_CORE_H__ */ + +/*lint -restore */ diff --git a/Demo/CORTEX_LPC1768_IAR/cstartup_M.s b/Demo/CORTEX_LPC1768_IAR/cstartup_M.s new file mode 100644 index 000000000..e8be5f6c4 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/cstartup_M.s @@ -0,0 +1,271 @@ +/************************************************** + * + * Part one of the system initialization code, contains low-level + * initialization, plain thumb variant. + * + * Copyright 2009 IAR Systems. All rights reserved. + * + * $Revision: 28532 $ + * + **************************************************/ + +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN xPortPendSVHandler + EXTERN xPortSysTickHandler + EXTERN vPortSVCHandler + EXTERN vEMAC_ISR + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + + DATA +__vector_table + DCD sfe(CSTACK) ; Top of Stack + DCD __iar_program_start ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler +__vector_table_0x1c + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD vPortSVCHandler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD xPortPendSVHandler ; PendSV Handler + DCD xPortSysTickHandler ; SysTick Handler + DCD WDT_IRQHandler ; Watchdog Handler + DCD TMR0_IRQHandler ; TIMER0 Handler + DCD TMR1_IRQHandler ; TIMER1 Handler + DCD TMR2_IRQHandler ; TIMER2 Handler + DCD TMR3_IRQHandler ; TIMER3 Handler + DCD UART0_IRQHandler ; UART0 Handler + DCD UART1_IRQHandler ; UART1 Handler + DCD UART2_IRQHandler ; UART2 Handler + DCD UART3_IRQHandler ; UART3 Handler + DCD PWM1_IRQHandler ; PWM1 Handler + DCD I2C0_IRQHandler ; I2C0 Handler + DCD I2C1_IRQHandler ; I2C1 Handler + DCD I2C2_IRQHandler ; I2C2 Handler + DCD SPI_IRQHandler ; SPI Handler + DCD SSP0_IRQHandler ; SSP0 Handler + DCD SSP1_IRQHandler ; SSP1 Handler + DCD PLL0_IRQHandler ; PLL0 Handler + DCD RTC_IRQHandler ; RTC Handler + DCD EINT0_IRQHandler ; EXT Interupt 0 Handler + DCD EINT1_IRQHandler ; EXT Interupt 1 Handler + DCD EINT2_IRQHandler ; EXT Interupt 2 Handler + DCD EINT3_IRQHandler ; EXT Interupt 3 Handler + DCD ADC_IRQHandler ; ADC Handler + DCD BOD_IRQHandler ; BOD Handler + DCD USB_IRQHandler ; USB Handler + DCD CAN_IRQHandler ; CAN Handler + DCD GPDMA_IRQHandler ; General Purpose DMA Handler + DCD I2S_IRQHandler ; I2S Handler + DCD vEMAC_ISR ; Ethernet Handler + DCD RIT_IRQHandler ; Repetitive Interrupt Timer Handler + DCD MotorControlPWM_IRQHandler ; Motor Control PWM Handler + DCD QE_IRQHandler ; Quadrature Encoder Handler + DCD PLL1_IRQHandler ; PLL1 Handler + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER(1) +NMI_Handler + B NMI_Handler + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER(1) +HardFault_Handler + B HardFault_Handler + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER(1) +MemManage_Handler + B MemManage_Handler + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER(1) +BusFault_Handler + B BusFault_Handler + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER(1) +SVC_Handler + B SVC_Handler + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER(1) +PendSV_Handler + B PendSV_Handler + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER(1) +SysTick_Handler + B SysTick_Handler + PUBWEAK WDT_IRQHandler + SECTION .text:CODE:REORDER(1) +WDT_IRQHandler + B WDT_IRQHandler + PUBWEAK TMR0_IRQHandler + SECTION .text:CODE:REORDER(1) +TMR0_IRQHandler + B TMR0_IRQHandler + PUBWEAK TMR1_IRQHandler + SECTION .text:CODE:REORDER(1) +TMR1_IRQHandler + B TMR1_IRQHandler + PUBWEAK TMR2_IRQHandler + SECTION .text:CODE:REORDER(1) +TMR2_IRQHandler + B TMR2_IRQHandler + PUBWEAK TMR3_IRQHandler + SECTION .text:CODE:REORDER(1) +TMR3_IRQHandler + B TMR3_IRQHandler + PUBWEAK UART0_IRQHandler + SECTION .text:CODE:REORDER(1) +UART0_IRQHandler + B UART0_IRQHandler + PUBWEAK UART1_IRQHandler + SECTION .text:CODE:REORDER(1) +UART1_IRQHandler + B UART1_IRQHandler + PUBWEAK UART2_IRQHandler + SECTION .text:CODE:REORDER(1) +UART2_IRQHandler + B UART2_IRQHandler + PUBWEAK UART3_IRQHandler + SECTION .text:CODE:REORDER(1) +UART3_IRQHandler + B UART3_IRQHandler + PUBWEAK PWM1_IRQHandler + SECTION .text:CODE:REORDER(1) +PWM1_IRQHandler + B PWM1_IRQHandler + PUBWEAK I2C0_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C0_IRQHandler + B I2C0_IRQHandler + PUBWEAK I2C1_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C1_IRQHandler + B I2C1_IRQHandler + PUBWEAK I2C2_IRQHandler + SECTION .text:CODE:REORDER(1) +I2C2_IRQHandler + B I2C2_IRQHandler + PUBWEAK SPI_IRQHandler + SECTION .text:CODE:REORDER(1) +SPI_IRQHandler + B SPI_IRQHandler + PUBWEAK SSP0_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP0_IRQHandler + B SSP0_IRQHandler + PUBWEAK SSP1_IRQHandler + SECTION .text:CODE:REORDER(1) +SSP1_IRQHandler + B SSP1_IRQHandler + PUBWEAK PLL0_IRQHandler + SECTION .text:CODE:REORDER(1) +PLL0_IRQHandler + B PLL0_IRQHandler + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + PUBWEAK EINT0_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT0_IRQHandler + B EINT0_IRQHandler + PUBWEAK EINT1_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT1_IRQHandler + B EINT1_IRQHandler + PUBWEAK EINT2_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT2_IRQHandler + B EINT2_IRQHandler + PUBWEAK EINT3_IRQHandler + SECTION .text:CODE:REORDER(1) +EINT3_IRQHandler + B EINT3_IRQHandler + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + PUBWEAK BOD_IRQHandler + SECTION .text:CODE:REORDER(1) +BOD_IRQHandler + B BOD_IRQHandler + PUBWEAK USB_IRQHandler + SECTION .text:CODE:REORDER(1) +USB_IRQHandler + B USB_IRQHandler + PUBWEAK CAN_IRQHandler + SECTION .text:CODE:REORDER(1) +CAN_IRQHandler + B CAN_IRQHandler + PUBWEAK GPDMA_IRQHandler + SECTION .text:CODE:REORDER(1) +GPDMA_IRQHandler + B GPDMA_IRQHandler + PUBWEAK I2S_IRQHandler + SECTION .text:CODE:REORDER(1) +I2S_IRQHandler + B I2S_IRQHandler + PUBWEAK Ethernet_IRQHandler + SECTION .text:CODE:REORDER(1) +Ethernet_IRQHandler + B Ethernet_IRQHandler + PUBWEAK RIT_IRQHandler + SECTION .text:CODE:REORDER(1) +RIT_IRQHandler + B RIT_IRQHandler + PUBWEAK MotorControlPWM_IRQHandler + SECTION .text:CODE:REORDER(1) +MotorControlPWM_IRQHandler + B MotorControlPWM_IRQHandler + PUBWEAK QE_IRQHandler + SECTION .text:CODE:REORDER(1) +QE_IRQHandler + B QE_IRQHandler + PUBWEAK PLL1_IRQHandler + SECTION .text:CODE:REORDER(1) +PLL1_IRQHandler + B PLL1_IRQHandler + + END diff --git a/Demo/CORTEX_LPC1768_IAR/main.c b/Demo/CORTEX_LPC1768_IAR/main.c new file mode 100644 index 000000000..6074eda47 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/main.c @@ -0,0 +1,369 @@ +/* + FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation and modified by the FreeRTOS exception. + **NOTE** The exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + Alternative commercial license and support terms are also available upon + request. See the licensing section of http://www.FreeRTOS.org for full + license details. + + 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 along + with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + + *************************************************************************** + * * + * Looking for a quick start? Then check out the FreeRTOS eBook! * + * See http://www.FreeRTOS.org/Documentation for details * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +/* + * Creates all the demo application tasks, then starts the scheduler. The WEB + * documentation provides more details of the standard demo application tasks + * (which just exist to test the kernel port and provide an example of how to use + * each FreeRTOS API function). + * + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * "Check" hook - This only executes fully every five seconds from the tick + * hook. Its main function is to check that all the standard demo tasks are + * still operational. The status can be viewed using on the Task Stats page + * served by the WEB server. + * + * "uIP" task - This is the task that handles the uIP stack. All TCP/IP + * processing is performed in this task. + * + * "USB" task - Enumerates the USB device as a CDC class, then echoes back all + * received characters with a configurable offset (for example, if the offset + * is 1 and 'A' is received then 'B' will be sent back). A dumb terminal such + * as Hyperterminal can be used to talk to the USB task. + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo app includes. */ +#include "BlockQ.h" +#include "integer.h" +#include "blocktim.h" +#include "flash.h" +#include "partest.h" +#include "semtest.h" +#include "PollQ.h" +#include "GenQTest.h" +#include "QPeek.h" +#include "recmutex.h" + +/*-----------------------------------------------------------*/ + +/* The time between cycles of the 'check' functionality (defined within the +tick hook). */ +#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS ) + +/* Task priorities. */ +#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) +#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/* The WEB server has a larger stack as it utilises stack hungry string +handling library calls. */ +#define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 ) + +/* The message displayed by the WEB server when all tasks are executing +without an error being reported. */ +#define mainPASS_STATUS_MESSAGE "All tasks are executing without error." + +/*-----------------------------------------------------------*/ + +/* + * Configure the hardware for the demo. + */ +static void prvSetupHardware( void ); + +/* + * The task that handles the uIP stack. All TCP/IP processing is performed in + * this task. + */ +extern void vuIP_Task( void *pvParameters ); + +/* + * The task that handles the USB stack. + */ +extern void vUSBTask( void *pvParameters ); + +/* + * Simply returns the current status message for display on served WEB pages. + */ +char *pcGetTaskStatusMessage( void ); + +/*-----------------------------------------------------------*/ + +/* Holds the status message displayed by the WEB server. */ +static char *pcStatusMessage = mainPASS_STATUS_MESSAGE; + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + /* Configure the hardware for use by this demo. */ + prvSetupHardware(); + + /* Start the standard demo tasks. These are just here to exercise the + kernel port and provide examples of how the FreeRTOS API can be used. */ + vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); + vCreateBlockTimeTasks(); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); + vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY ); + vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); + vStartQueuePeekTasks(); + vStartRecursiveMutexTasks(); + + /* Create the USB task. */ +// xTaskCreate( vUSBTask, ( signed char * ) "USB", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); + + /* Create the uIP task. The WEB server runs in this task. */ + xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL ); + + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* Will only get here if there was insufficient memory to create the idle + task. The idle task is created within vTaskStartScheduler(). */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ +static unsigned portLONG ulTicksSinceLastDisplay = 0; + + /* Called from every tick interrupt as described in the comments at the top + of this file. + + Have enough ticks passed to make it time to perform our health status + check again? */ + ulTicksSinceLastDisplay++; + if( ulTicksSinceLastDisplay >= mainCHECK_DELAY ) + { + /* Reset the counter so these checks run again in mainCHECK_DELAY + ticks time. */ + ulTicksSinceLastDisplay = 0; + + /* Has an error been found in any task? */ + if( xAreGenericQueueTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Generic Queue test/demo."; + } + else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Peek Queue test/demo."; + } + else if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Block Queue test/demo."; + } + else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Block Time test/demo."; + } + else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Semaphore test/demo."; + } + else if( xArePollingQueuesStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Poll Queue test/demo."; + } + else if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Int Math test/demo."; + } + else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "An error has been detected in the Mutex test/demo."; + } + + vParTestToggleLED( 0 ); + } +} +/*-----------------------------------------------------------*/ + +char *pcGetTaskStatusMessage( void ) +{ + /* Not bothered about a critical section here. */ + return pcStatusMessage; +} +/*-----------------------------------------------------------*/ + +void prvSetupHardware( void ) +{ + /* Disable peripherals power. */ + SC->PCONP = 0; + + /* Enable GPIO power. */ + SC->PCONP = PCONP_PCGPIO; + + /* Disable TPIU. */ + PINCON->PINSEL10 = 0; + + if ( SC->PLL0STAT & ( 1 << 25 ) ) + { + /* Enable PLL, disconnected. */ + SC->PLL0CON = 1; + SC->PLL0FEED = PLLFEED_FEED1; + SC->PLL0FEED = PLLFEED_FEED2; + } + + /* Disable PLL, disconnected. */ + SC->PLL0CON = 0; + SC->PLL0FEED = PLLFEED_FEED1; + SC->PLL0FEED = PLLFEED_FEED2; + + /* Enable main OSC. */ + SC->SCS |= 0x20; + while( !( SC->SCS & 0x40 ) ); + + /* select main OSC, 12MHz, as the PLL clock source. */ + SC->CLKSRCSEL = 0x1; + + SC->PLL0CFG = 0x0b; + SC->PLL0FEED = PLLFEED_FEED1; + SC->PLL0FEED = PLLFEED_FEED2; + + /* Enable PLL, disconnected. */ + SC->PLL0CON = 1; + SC->PLL0FEED = PLLFEED_FEED1; + SC->PLL0FEED = PLLFEED_FEED2; + + /* Set clock divider. */ + SC->CCLKCFG = 0x03; + + /* Configure flash accelerator. */ + SC->FLASHCFG = 0x303a; + + /* Check lock bit status. */ + while( ( ( SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) ); + + /* Enable and connect. */ + SC->PLL0CON = 3; + SC->PLL0FEED = PLLFEED_FEED1; + SC->PLL0FEED = PLLFEED_FEED2; + while( ( ( SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) ); + + + + + /* Configure the clock for the USB. */ + + if( SC->PLL1STAT & ( 1 << 9 ) ) + { + /* Enable PLL, disconnected. */ + SC->PLL1CON = 1; + SC->PLL1FEED = PLLFEED_FEED1; + SC->PLL1FEED = PLLFEED_FEED2; + } + + /* Disable PLL, disconnected. */ + SC->PLL1CON = 0; + SC->PLL1FEED = PLLFEED_FEED1; + SC->PLL1FEED = PLLFEED_FEED2; + + SC->PLL1CFG = 0x23; + SC->PLL1FEED = PLLFEED_FEED1; + SC->PLL1FEED = PLLFEED_FEED2; + + /* Enable PLL, disconnected. */ + SC->PLL1CON = 1; + SC->PLL1FEED = PLLFEED_FEED1; + SC->PLL1FEED = PLLFEED_FEED2; + while( ( ( SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) ); + + /* Enable and connect. */ + SC->PLL1CON = 3; + SC->PLL1FEED = PLLFEED_FEED1; + SC->PLL1FEED = PLLFEED_FEED2; + while( ( ( SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) ); + + /* Setup the peripheral bus to be the same as the PLL output (64 MHz). */ + SC->PCLKSEL0 = 0x05555555; + + /* Configure the LEDs. */ + vParTestInitialise(); +} +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName ) +{ + /* This function will get called if a task overflows its stack. */ + + ( void ) pxTask; + ( void ) pcTaskName; + + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vConfigureTimerForRunTimeStats( void ) +{ +const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01; + + /* This function configures a timer that is used as the time base when + collecting run time statistical information - basically the percentage + of CPU time that each task is utilising. It is called automatically when + the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set + to 1). */ + + /* Power up and feed the timer. */ + SC->PCONP |= 0x02UL; + SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2); + + /* Reset Timer 0 */ + TIM0->TCR = TCR_COUNT_RESET; + + /* Just count up. */ + TIM0->CTCR = CTCR_CTM_TIMER; + + /* Prescale to a frequency that is good enough to get a decent resolution, + but not too fast so as to overflow all the time. */ + TIM0->PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL; + + /* Start the counter. */ + TIM0->TCR = TCR_COUNT_ENABLE; +} +/*-----------------------------------------------------------*/ + diff --git a/Demo/CORTEX_LPC1768_IAR/printf-stdarg.c b/Demo/CORTEX_LPC1768_IAR/printf-stdarg.c new file mode 100644 index 000000000..b5ac41be7 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/printf-stdarg.c @@ -0,0 +1,293 @@ +/* + Copyright 2001, 2002 Georges Menie (www.menie.org) + stdarg version contributed by Christian Ettinger + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + putchar is the only external dependency for this file, + if you have a working putchar, leave it commented out. + If not, uncomment the define below and + replace outbyte(c) by your own function call. + +*/ + +#define putchar(c) c + +#include + +static void printchar(char **str, int c) +{ + //extern int putchar(int c); + + if (str) { + **str = (char)c; + ++(*str); + } + else + { + (void)putchar(c); + } +} + +#define PAD_RIGHT 1 +#define PAD_ZERO 2 + +static int prints(char **out, const char *string, int width, int pad) +{ + register int pc = 0, padchar = ' '; + + if (width > 0) { + register int len = 0; + register const char *ptr; + for (ptr = string; *ptr; ++ptr) ++len; + if (len >= width) width = 0; + else width -= len; + if (pad & PAD_ZERO) padchar = '0'; + } + if (!(pad & PAD_RIGHT)) { + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + } + for ( ; *string ; ++string) { + printchar (out, *string); + ++pc; + } + for ( ; width > 0; --width) { + printchar (out, padchar); + ++pc; + } + + return pc; +} + +/* the following should be enough for 32 bit int */ +#define PRINT_BUF_LEN 12 + +static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase) +{ + char print_buf[PRINT_BUF_LEN]; + register char *s; + register int t, neg = 0, pc = 0; + register unsigned int u = (unsigned int)i; + + if (i == 0) { + print_buf[0] = '0'; + print_buf[1] = '\0'; + return prints (out, print_buf, width, pad); + } + + if (sg && b == 10 && i < 0) { + neg = 1; + u = (unsigned int)-i; + } + + s = print_buf + PRINT_BUF_LEN-1; + *s = '\0'; + + while (u) { + t = (unsigned int)u % b; + if( t >= 10 ) + t += letbase - '0' - 10; + *--s = (char)(t + '0'); + u /= b; + } + + if (neg) { + if( width && (pad & PAD_ZERO) ) { + printchar (out, '-'); + ++pc; + --width; + } + else { + *--s = '-'; + } + } + + return pc + prints (out, s, width, pad); +} + +static int print( char **out, const char *format, va_list args ) +{ + register int width, pad; + register int pc = 0; + char scr[2]; + + for (; *format != 0; ++format) { + if (*format == '%') { + ++format; + width = pad = 0; + if (*format == '\0') break; + if (*format == '%') goto out; + if (*format == '-') { + ++format; + pad = PAD_RIGHT; + } + while (*format == '0') { + ++format; + pad |= PAD_ZERO; + } + for ( ; *format >= '0' && *format <= '9'; ++format) { + width *= 10; + width += *format - '0'; + } + if( *format == 's' ) { + register char *s = (char *)va_arg( args, int ); + pc += prints (out, s?s:"(null)", width, pad); + continue; + } + if( *format == 'd' ) { + pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a'); + continue; + } + if( *format == 'x' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a'); + continue; + } + if( *format == 'X' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A'); + continue; + } + if( *format == 'u' ) { + pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a'); + continue; + } + if( *format == 'c' ) { + /* char are converted to int then pushed on the stack */ + scr[0] = (char)va_arg( args, int ); + scr[1] = '\0'; + pc += prints (out, scr, width, pad); + continue; + } + } + else { + out: + printchar (out, *format); + ++pc; + } + } + if (out) **out = '\0'; + va_end( args ); + return pc; +} + +int printf(const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( 0, format, args ); +} + +int sprintf(char *out, const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( &out, format, args ); +} + + +int snprintf( char *buf, unsigned int count, const char *format, ... ) +{ + va_list args; + + ( void ) count; + + va_start( args, format ); + return print( &buf, format, args ); +} + + +#ifdef TEST_PRINTF +int main(void) +{ + char *ptr = "Hello world!"; + char *np = 0; + int i = 5; + unsigned int bs = sizeof(int)*8; + int mi; + char buf[80]; + + mi = (1 << (bs-1)) + 1; + printf("%s\n", ptr); + printf("printf test\n"); + printf("%s is null pointer\n", np); + printf("%d = 5\n", i); + printf("%d = - max int\n", mi); + printf("char %c = 'a'\n", 'a'); + printf("hex %x = ff\n", 0xff); + printf("hex %02x = 00\n", 0); + printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3); + printf("%d %s(s)%", 0, "message"); + printf("\n"); + printf("%d %s(s) with %%\n", 0, "message"); + sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf); + sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf); + sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf); + sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf); + sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf); + sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf); + sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf); + sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf); + + return 0; +} + +/* + * if you compile this file with + * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c + * you will get a normal warning: + * printf.c:214: warning: spurious trailing `%' in format + * this line is testing an invalid % at the end of the format string. + * + * this should display (on 32bit int machine) : + * + * Hello world! + * printf test + * (null) is null pointer + * 5 = 5 + * -2147483647 = - max int + * char a = 'a' + * hex ff = ff + * hex 00 = 00 + * signed -3 = unsigned 4294967293 = hex fffffffd + * 0 message(s) + * 0 message(s) with % + * justif: "left " + * justif: " right" + * 3: 0003 zero padded + * 3: 3 left justif. + * 3: 3 right justif. + * -3: -003 zero padded + * -3: -3 left justif. + * -3: -3 right justif. + */ + +#endif + + +/* To keep linker happy. */ +int write( int i, char* c, int n) +{ + (void)i; + (void)n; + (void)c; + return 0; +} + diff --git a/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.cspy.bat b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.cspy.bat new file mode 100644 index 000000000..c96471c07 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.cspy.bat @@ -0,0 +1,33 @@ +@REM This bat file has been generated by the IAR Embeddded Workbench +@REM C-SPY interactive debugger,as an aid to preparing a command +@REM line for running the cspybat command line utility with the +@REM appropriate settings. +@REM +@REM After making some adjustments to this file, you can launch cspybat +@REM by typing the name of this file followed by the name of the debug +@REM file (usually an ubrof file). Note that this file is generated +@REM every time a new debug session is initialized, so you may want to +@REM move or rename the file before making changes. +@REM +@REM Note: some command line arguments cannot be properly generated +@REM by this process. Specifically, the plugin which is responsible +@REM for the Terminal I/O window (and other C runtime functionality) +@REM comes in a special version for cspybat, and the name of that +@REM plugin dll is not known when generating this file. It resides in +@REM the $TOOLKIT_DIR$\bin folder and is usually called XXXbat.dll or +@REM XXXlibsupportbat.dll, where XXX is the name of the corresponding +@REM tool chain. Replace the '' parameter +@REM below with the appropriate file name. Other plugins loaded by +@REM C-SPY are usually not needed by, or will not work in, cspybat +@REM but they are listed at the end of this file for reference. + + +"C:\devtools\IAR Systems\Embedded Workbench 5.4\common\bin\cspybat" "C:\devtools\IAR Systems\Embedded Workbench 5.4\arm\bin\armproc.dll" "C:\devtools\IAR Systems\Embedded Workbench 5.4\arm\bin\armjlink.dll" %1 --plugin "C:\devtools\IAR Systems\Embedded Workbench 5.4\arm\bin\" --macro "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\Flash.mac" --backend -B "--endian=little" "--cpu=Cortex-M3" "--fpu=None" "-p" "C:\devtools\IAR Systems\Embedded Workbench 5.4\arm\CONFIG\debugger\NXP\iolpc1768.ddf" "--drv_verify_download" "--semihosting=none" "--device=LPC1768" "-d" "jlink" "--drv_communication=USB0" "--jlink_speed=auto" "--jlink_initial_speed=32" "--jlink_reset_strategy=0,0" + + +@REM Loaded plugins: +@REM C:\devtools\IAR Systems\Embedded Workbench 5.4\arm\bin\armlibsupport.dll +@REM C:\devtools\IAR Systems\Embedded Workbench 5.4\common\plugins\CodeCoverage\CodeCoverage.dll +@REM C:\devtools\IAR Systems\Embedded Workbench 5.4\common\plugins\Profiling\Profiling.dll +@REM C:\devtools\IAR Systems\Embedded Workbench 5.4\common\plugins\stack\stack.dll +@REM C:\devtools\IAR Systems\Embedded Workbench 5.4\common\plugins\SymList\SymList.dll diff --git a/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dbgdt b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dbgdt new file mode 100644 index 000000000..f2b037c02 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dbgdt @@ -0,0 +1,79 @@ + + + + + + + + + 201342 + + 20 + 1006 + 268 + 67 + + + + + + + + 124272727 + + + + + + 200100 + 200200100100100100 + + + + + + + + TabID-31842-26703 + Debug Log + Debug-Log + + + + TabID-31319-26713 + Build + Build + + + + + 0 + + + TabID-9822-26706 + Workspace + Workspace + + + RTOSDemoRTOSDemo/WEB Server + + + + 0 + + + + + + TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\main.c013851515151TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Source\portable\IAR\ARM_CM3\port.c014558215821TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\ParTest.c07634673467TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Source\queue.c010553478834788TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\webserver\emac.c0130527352734TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\webserver\EthDev_LPC17xx.h028217892179020100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1-2-2742198-2-2200200142857203252142857756098-2-21981402-2-214042001002857203252142857203252 + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dni b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dni new file mode 100644 index 000000000..23207c418 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.dni @@ -0,0 +1,48 @@ +[DebugChecksum] +Checksum=1859043743 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[InstructionProfiling] +Enabled=_ 0 +[CodeCoverage] +Enabled=_ 0 +[Profiling] +Enabled=0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[TraceHelper] +Enabled=0 +ShowSource=1 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[DriverProfiling] +Enabled=0 +Source=2 +Graph=0 +[Disassemble mode] +mode=0 +[Breakpoints] +Count=0 diff --git a/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.wsdt b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.wsdt new file mode 100644 index 000000000..ff734cf3c --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo.wsdt @@ -0,0 +1,67 @@ + + + + + + RTOSDemo/Debug + + + + + + + + + 315272727 + + + + + + + 20100626867 + + 48268826191343 + + + + + + + TabID-17246-25544 + Workspace + Workspace + + + RTOSDemo + + + + 0 + + + TabID-17664-26559 + Build + Build + + + TabID-11527-1227Find in FilesFind-in-FilesTabID-6216-4192Debug LogDebug-Log + + 0 + + + + + + TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\main.c013851515151TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Source\portable\IAR\ARM_CM3\port.c014558215821TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\ParTest.c07634673467TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Source\queue.c010553478834788TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\webserver\emac.c0130527352734TextEditorC:\E\Dev\FreeRTOS\WorkingCopy3\Demo\CORTEX_LPC1768_IAR\webserver\EthDev_LPC17xx.h028217892179020100000010000001 + + + + + + + iaridepm.enu1-2-2640389-2-2200200142857203252279286652439-2-23001402-2-214043021002857306911142857203252 + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo_Debug.jlink b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo_Debug.jlink new file mode 100644 index 000000000..e49918734 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/settings/RTOSDemo_Debug.jlink @@ -0,0 +1,14 @@ +[FLASH] +SkipProgOnCRCMatch = 1 +VerifyDownload = 1 +AllowCaching = 1 +EnableFlashDL = 2 +Override = 0 +Device="ADUC7020X62" +[BREAKPOINTS] +ShowInfoWin = 1 +EnableFlashBP = 2 +BPDuringExecution = 0 +[CPU] +OverrideMemMap = 0 +AllowSimulation = 1 diff --git a/Demo/CORTEX_LPC1768_IAR/system_LPC17xx.h b/Demo/CORTEX_LPC1768_IAR/system_LPC17xx.h new file mode 100644 index 000000000..a5c9727d4 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/system_LPC17xx.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * @file: system_LPC17xx.h + * @purpose: CMSIS Cortex-M3 Device Peripheral Access Layer Header File + * for the NXP LPC17xx Device Series + * @version: V1.0 + * @date: 25. Nov. 2008 + *---------------------------------------------------------------------------- + * + * Copyright (C) 2008 ARM Limited. All rights reserved. + * + * ARM Limited (ARM) is supplying this software for use with Cortex-M3 + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + + +#ifndef __SYSTEM_LPC17xx_H +#define __SYSTEM_LPC17xx_H + +extern uint32_t SystemFrequency; /*!< System Clock Frequency (Core Clock) */ + + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemFrequency variable. + */ +extern void SystemInit (void); +#endif diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/EthDev.h b/Demo/CORTEX_LPC1768_IAR/webserver/EthDev.h new file mode 100644 index 000000000..f67789f44 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/EthDev.h @@ -0,0 +1,111 @@ +/* + * @file: EthDev.h + * @purpose: Ethernet Device Definitions + * @version: V1.10 + * @date: 24. Feb. 2009 + *---------------------------------------------------------------------------- + * + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * ARM Limited (ARM) is supplying this software for use with Cortex-M3 + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + */ + +#ifndef _ETHDEV__H +#define _ETHDEV__H + +#ifndef NULL + #define NULL 0 +#endif + +/*---------------------------------------------------------------------------- + Ethernet Device Defines + *----------------------------------------------------------------------------*/ +#define EthDev_ADDR_SIZE 6 /*!< Ethernet Address size in bytes */ +#define EthDev_MTU_SIZE 1514 /*!< Maximum Transmission Unit */ + + +/*---------------------------------------------------------------------------- + Ethernet Device Configuration and Control Command Defines + *----------------------------------------------------------------------------*/ +typedef enum { + EthDev_LINK_DOWN = 0, /*!< Ethernet link not established */ + EthDev_LINK_UP = 1, /*!< Ethernet link established */ +} EthDev_LINK; + +typedef enum { + EthDev_SPEED_10M = 0, /*!< 10.0 Mbps link speed */ + EthDev_SPEED_100M = 1, /*!< 100.0 Mbps link speed */ + EthDev_SPEED_1000M = 2, /*!< 1.0 Gbps link speed */ +} EthDev_SPEED; + +typedef enum { + EthDev_DUPLEX_HALF = 0, /*!< Link half duplex */ + EthDev_DUPLEX_FULL = 1, /*!< Link full duplex */ +} EthDev_DUPLEX; + +typedef enum { + EthDev_MODE_AUTO = 0, + EthDev_MODE_10M_FULL = 1, + EthDev_MODE_10M_HALF = 2, + EthDev_MODE_100M_FULL = 3, + EthDev_MODE_100M_HALF = 4, + EthDev_MODE_1000M_FULL = 5, + EthDev_MODE_1000M_HALF = 6, +} EthDev_MODE; + +typedef struct { + EthDev_LINK Link : 1; + EthDev_DUPLEX Duplex : 1; + EthDev_SPEED Speed : 2; +} EthDev_STATUS; + + +/*---------------------------------------------------------------------------- + Ethernet Device IO Block Structure + *----------------------------------------------------------------------------*/ +typedef struct { + + /* Initialized by the user application before call to Init. */ + EthDev_MODE Mode; + unsigned char HwAddr[EthDev_ADDR_SIZE]; + void *(*RxFrame) (int size); + void (*RxFrameReady) (int size); + + /* Initialized by Ethernet driver. */ + int (*Init) (void); + int (*UnInit) (void); + int (*SetMCFilter)(int NumHwAddr, unsigned char *pHwAddr); + int (*TxFrame) (void *pData, int size); + void (*Lock) (void); + void (*UnLock) (void); + EthDev_STATUS (*LinkChk) (void); +} EthDev_IOB; + + +/* + * Look for received data. If data is found then uip_buf is assigned to the + * new data and the length of the data is returned. If no data is found then + * uip_buf is not updated and 0 is returned. + */ +unsigned long ulGetEMACRxData( void ); + +/* + * Send usTxDataLen bytes from uip_buf. + */ +void vSendEMACTxData( unsigned short usTxDataLen ); + +/* + * Prepare the Ethernet hardware ready for TCP/IP comms. + */ +long lEMACInit(void); + +#endif diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/EthDev_LPC17xx.h b/Demo/CORTEX_LPC1768_IAR/webserver/EthDev_LPC17xx.h new file mode 100644 index 000000000..03a875cb7 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/EthDev_LPC17xx.h @@ -0,0 +1,321 @@ +/* + * @file: EthDev_LPC17xx.h + * @purpose: Ethernet Device Definitions for NXP LPC17xx + * @version: V0.01 + * @date: 14. May 2009 + *---------------------------------------------------------------------------- + * + * Copyright (C) 2009 ARM Limited. All rights reserved. + * + * ARM Limited (ARM) is supplying this software for use with Cortex-M3 + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + */ + +#ifndef __ETHDEV_LPC17XX_H +#define __ETHDEV_LPC17XX_H + +#include + +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 3 /* Num.of RX Fragments. */ +#define NUM_TX_FRAG 2 /* Num.of TX Fragments. */ +#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ + +typedef struct { /* RX Descriptor struct */ + uint32_t Packet; + uint32_t Ctrl; +} RX_DESC_TypeDef; + +typedef struct { /* RX Status struct */ + uint32_t Info; + uint32_t HashCRC; +} RX_STAT_TypeDef; + +typedef struct { /* TX Descriptor struct */ + uint32_t Packet; + uint32_t Ctrl; +} TX_DESC_TypeDef; + +typedef struct { /* TX Status struct */ + uint32_t Info; +} TX_STAT_TypeDef; + + +/* EMAC variables located in AHB SRAM bank 1*/ +#define AHB_SRAM_BANK1_BASE 0x2007c000UL +#define RX_DESC_BASE (AHB_SRAM_BANK1_BASE ) +#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */ +#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */ +#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */ +#define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */ + +/* RX and TX descriptor and status definitions. */ +#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) +#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) +#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) +#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) +#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) +#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) +#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) +#define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i ) +#define ETH_NUM_BUFFERS ( NUM_TX_FRAG + NUM_RX_FRAG + 1 ) /* There are in fact 2 more buffers than descriptors as the two Tx descriptors use the same buffer to speed up the uip Tx. */ + + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ +#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | \ + RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* ENET Device Revision ID */ +#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */ + +/* KSZ8721BL PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_CTRLER 0x1f /* 100BASE-TX-PHY Controller */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ +#define PHY_AUTO_NEG_COMPLETE 0x0020 /* Auto negotiation have finished. */ + +#define KS8721_DEF_ADR 0x0100 /* Default PHY device address */ +#define KS8721_ID 0x00221619 /* PHY Identifier */ + +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/clock-arch.h b/Demo/CORTEX_LPC1768_IAR/webserver/clock-arch.h new file mode 100644 index 000000000..cde657b62 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/clock-arch.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $ + */ + +#ifndef __CLOCK_ARCH_H__ +#define __CLOCK_ARCH_H__ + +#include "FreeRTOS.h" + +typedef unsigned long clock_time_t; +#define CLOCK_CONF_SECOND configTICK_RATE_HZ + +#endif /* __CLOCK_ARCH_H__ */ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/emac.c b/Demo/CORTEX_LPC1768_IAR/webserver/emac.c new file mode 100644 index 000000000..104aba553 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/emac.c @@ -0,0 +1,600 @@ +/* + FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation and modified by the FreeRTOS exception. + **NOTE** The exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + Alternative commercial license and support terms are also available upon + request. See the licensing section of http://www.FreeRTOS.org for full + license details. + + 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 along + with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + + *************************************************************************** + * * + * Looking for a quick start? Then check out the FreeRTOS eBook! * + * See http://www.FreeRTOS.org/Documentation for details * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + 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. +*/ + +/* Originally adapted from file written by Andreas Dannenberg. Supplied with permission. */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Hardware specific includes. */ +#include "EthDev_LPC17xx.h" + +/* Time to wait between each inspection of the link status. */ +#define emacWAIT_FOR_LINK_TO_ESTABLISH ( 500 / portTICK_RATE_MS ) + +/* Short delay used in several places during the initialisation process. */ +#define emacSHORT_DELAY ( 2 ) + +/* Hardware specific bit definitions. */ +#define emacLINK_ESTABLISHED ( 0x0020) +#define emacFULL_DUPLEX_ENABLED ( 0x0010 ) +#define emac10BASE_T_MODE ( 0x0004 ) +#define emacPINSEL2_VALUE ( 0x50150105 ) +#define emacDIV_44 ( 0x28 ) + +/* If no buffers are available, then wait this long before looking again.... */ +#define emacBUFFER_WAIT_DELAY ( 3 / portTICK_RATE_MS ) + +/* ...and don't look more than this many times. */ +#define emacBUFFER_WAIT_ATTEMPTS ( 30 ) + +/* Index to the Tx descriptor that is always used first for every Tx. The second +descriptor is then used to re-send in order to speed up the uIP Tx process. */ +#define emacTX_DESC_INDEX ( 0 ) + +/*-----------------------------------------------------------*/ + +/* + * Configure both the Rx and Tx descriptors during the init process. + */ +static void prvInitDescriptors( void ); + +/* + * Setup the IO and peripherals required for Ethernet communication. + */ +static void prvSetupEMACHardware( void ); + +/* + * Control the auto negotiate process. + */ +static void prvConfigurePHY( void ); + +/* + * Wait for a link to be established, then setup the PHY according to the link + * parameters. + */ +static long prvSetupLinkStatus( void ); + +/* + * Search the pool of buffers to find one that is free. If a buffer is found + * mark it as in use before returning its address. + */ +static unsigned char *prvGetNextBuffer( void ); + +/* + * Return an allocated buffer to the pool of free buffers. + */ +static void prvReturnBuffer( unsigned char *pucBuffer ); + +/* + * Send lValue to the lPhyReg within the PHY. + */ +static long prvWritePHY( long lPhyReg, long lValue ); + +/* + * Read a value from ucPhyReg within the PHY. *plStatus will be set to + * pdFALSE if there is an error. + */ +static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus ); + +/*-----------------------------------------------------------*/ + +/* The semaphore used to wake the uIP task when data arrives. */ +extern xSemaphoreHandle xEMACSemaphore; + +/* Each ucBufferInUse index corresponds to a position in the pool of buffers. +If the index contains a 1 then the buffer within pool is in use, if it +contains a 0 then the buffer is free. */ +static unsigned char ucBufferInUse[ ETH_NUM_BUFFERS ] = { pdFALSE }; + +/* The uip_buffer is not a fixed array, but instead gets pointed to the buffers +allocated within this file. */ +unsigned char * uip_buf; + +/* Store the length of the data being sent so the data can be sent twice. The +value will be set back to 0 once the data has been sent twice. */ +static unsigned short usSendLen = 0; + +/*-----------------------------------------------------------*/ + +long lEMACInit( void ) +{ +long lReturn = pdPASS; +unsigned long ulID1, ulID2; + + /* Reset peripherals, configure port pins and registers. */ + prvSetupEMACHardware(); + + /* Check the PHY part number is as expected. */ + ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn ); + ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn ); + if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFFFUL ) ) == KS8721_ID ) + { + /* Set the Ethernet MAC Address registers */ + EMAC->SA0 = ( configMAC_ADDR0 << 8 ) | configMAC_ADDR1; + EMAC->SA1 = ( configMAC_ADDR2 << 8 ) | configMAC_ADDR3; + EMAC->SA2 = ( configMAC_ADDR4 << 8 ) | configMAC_ADDR5; + + /* Initialize Tx and Rx DMA Descriptors */ + prvInitDescriptors(); + + /* Receive broadcast and perfect match packets */ + EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; + + /* Setup the PHY. */ + prvConfigurePHY(); + } + else + { + lReturn = pdFAIL; + } + + /* Check the link status. */ + if( lReturn == pdPASS ) + { + lReturn = prvSetupLinkStatus(); + } + + if( lReturn == pdPASS ) + { + /* Initialise uip_buf to ensure it points somewhere valid. */ + uip_buf = prvGetNextBuffer(); + + /* Reset all interrupts */ + EMAC->IntClear = ( INT_RX_OVERRUN | INT_RX_ERR | INT_RX_FIN | INT_RX_DONE | INT_TX_UNDERRUN | INT_TX_ERR | INT_TX_FIN | INT_TX_DONE | INT_SOFT_INT | INT_WAKEUP ); + + /* Enable receive and transmit mode of MAC Ethernet core */ + EMAC->Command |= ( CR_RX_EN | CR_TX_EN ); + EMAC->MAC1 |= MAC1_REC_EN; + } + + return lReturn; +} +/*-----------------------------------------------------------*/ + +static unsigned char *prvGetNextBuffer( void ) +{ +long x; +unsigned char *pucReturn = NULL; +unsigned long ulAttempts = 0; + + while( pucReturn == NULL ) + { + /* Look through the buffers to find one that is not in use by + anything else. */ + for( x = 0; x < ETH_NUM_BUFFERS; x++ ) + { + if( ucBufferInUse[ x ] == pdFALSE ) + { + ucBufferInUse[ x ] = pdTRUE; + pucReturn = ( unsigned char * ) ETH_BUF( x ); + break; + } + } + + /* Was a buffer found? */ + if( pucReturn == NULL ) + { + ulAttempts++; + + if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS ) + { + break; + } + + /* Wait then look again. */ + vTaskDelay( emacBUFFER_WAIT_DELAY ); + } + } + + return pucReturn; +} +/*-----------------------------------------------------------*/ + +static void prvInitDescriptors( void ) +{ +long x, lNextBuffer = 0; + + for( x = 0; x < NUM_RX_FRAG; x++ ) + { + /* Allocate the next Ethernet buffer to this descriptor. */ + RX_DESC_PACKET( x ) = ETH_BUF( lNextBuffer ); + RX_DESC_CTRL( x ) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 ); + RX_STAT_INFO( x ) = 0; + RX_STAT_HASHCRC( x ) = 0; + + /* The Ethernet buffer is now in use. */ + ucBufferInUse[ lNextBuffer ] = pdTRUE; + lNextBuffer++; + } + + /* Set EMAC Receive Descriptor Registers. */ + EMAC->RxDescriptor = RX_DESC_BASE; + EMAC->RxStatus = RX_STAT_BASE; + EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1; + + /* Rx Descriptors Point to 0 */ + EMAC->RxConsumeIndex = 0; + + /* A buffer is not allocated to the Tx descriptors until they are actually + used. */ + for( x = 0; x < NUM_TX_FRAG; x++ ) + { + TX_DESC_PACKET( x ) = ( unsigned long ) NULL; + TX_DESC_CTRL( x ) = 0; + TX_STAT_INFO( x ) = 0; + } + + /* Set EMAC Transmit Descriptor Registers. */ + EMAC->TxDescriptor = TX_DESC_BASE; + EMAC->TxStatus = TX_STAT_BASE; + EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1; + + /* Tx Descriptors Point to 0 */ + EMAC->TxProduceIndex = 0; +} +/*-----------------------------------------------------------*/ + +static void prvSetupEMACHardware( void ) +{ +unsigned short us; +long x, lDummy; + + /* Enable P1 Ethernet Pins. */ + PINCON->PINSEL2 = emacPINSEL2_VALUE; + PINCON->PINSEL3 = ( PINCON->PINSEL3 & ~0x0000000F ) | 0x00000005; + + /* Power Up the EMAC controller. */ + SC->PCONP |= PCONP_PCENET; + vTaskDelay( emacSHORT_DELAY ); + + /* Reset all EMAC internal modules. */ + EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; + EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; + + /* A short delay after reset. */ + vTaskDelay( emacSHORT_DELAY ); + + /* Initialize MAC control registers. */ + EMAC->MAC1 = MAC1_PASS_ALL; + EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; + EMAC->MAXF = ETH_MAX_FLEN; + EMAC->CLRT = CLRT_DEF; + EMAC->IPGR = IPGR_DEF; + EMAC->MCFG = emacDIV_44; + + /* Enable Reduced MII interface. */ + EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; + + /* Reset Reduced MII Logic. */ + EMAC->SUPP = SUPP_RES_RMII; + vTaskDelay( emacSHORT_DELAY ); + EMAC->SUPP = 0; + + /* Put the PHY in reset mode */ + prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); + prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); + + /* Wait for hardware reset to end. */ + for( x = 0; x < 100; x++ ) + { + vTaskDelay( emacSHORT_DELAY * 5 ); + us = prvReadPHY( PHY_REG_BMCR, &lDummy ); + if( !( us & MCFG_RES_MII ) ) + { + /* Reset complete */ + break; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvConfigurePHY( void ) +{ +unsigned short us; +long x, lDummy; + + /* Auto negotiate the configuration. */ + if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) + { + vTaskDelay( emacSHORT_DELAY * 5 ); + + for( x = 0; x < 10; x++ ) + { + us = prvReadPHY( PHY_REG_BMSR, &lDummy ); + + if( us & PHY_AUTO_NEG_COMPLETE ) + { + break; + } + + vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH ); + } + } +} +/*-----------------------------------------------------------*/ + +static long prvSetupLinkStatus( void ) +{ +long lReturn = pdFAIL, x; +unsigned short usLinkStatus; + + /* Wait with timeout for the link to be established. */ + for( x = 0; x < 10; x++ ) + { + usLinkStatus = prvReadPHY( PHY_CTRLER, &lReturn ); + if( usLinkStatus != 0x00 ) + { + /* Link is established. */ + lReturn = pdPASS; + break; + } + + vTaskDelay( emacWAIT_FOR_LINK_TO_ESTABLISH ); + } + + if( lReturn == pdPASS ) + { + /* Configure Full/Half Duplex mode. */ + if( usLinkStatus & emacFULL_DUPLEX_ENABLED ) + { + /* Full duplex is enabled. */ + EMAC->MAC2 |= MAC2_FULL_DUP; + EMAC->Command |= CR_FULL_DUP; + EMAC->IPGT = IPGT_FULL_DUP; + } + else + { + /* Half duplex mode. */ + EMAC->IPGT = IPGT_HALF_DUP; + } + + /* Configure 100MBit/10MBit mode. */ + if( usLinkStatus & emac10BASE_T_MODE ) + { + /* 10MBit mode. */ + EMAC->SUPP = 0; + } + else + { + /* 100MBit mode. */ + EMAC->SUPP = SUPP_SPEED; + } + } + + return lReturn; +} +/*-----------------------------------------------------------*/ + +static void prvReturnBuffer( unsigned char *pucBuffer ) +{ +unsigned long ul; + + /* Return a buffer to the pool of free buffers. */ + for( ul = 0; ul < ETH_NUM_BUFFERS; ul++ ) + { + if( ETH_BUF( ul ) == ( unsigned long ) pucBuffer ) + { + ucBufferInUse[ ul ] = pdFALSE; + break; + } + } +} +/*-----------------------------------------------------------*/ + +unsigned long ulGetEMACRxData( void ) +{ +unsigned long ulLen = 0; +long lIndex; + + if( EMAC->RxProduceIndex != EMAC->RxConsumeIndex ) + { + /* Mark the current buffer as free as uip_buf is going to be set to + the buffer that contains the received data. */ + prvReturnBuffer( uip_buf ); + + ulLen = ( RX_STAT_INFO( EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3; + uip_buf = ( unsigned char * ) RX_DESC_PACKET( EMAC->RxConsumeIndex ); + + /* Allocate a new buffer to the descriptor. */ + RX_DESC_PACKET( EMAC->RxConsumeIndex ) = ( unsigned long ) prvGetNextBuffer(); + + /* Move the consume index onto the next position, ensuring it wraps to + the beginning at the appropriate place. */ + lIndex = EMAC->RxConsumeIndex; + + lIndex++; + if( lIndex >= NUM_RX_FRAG ) + { + lIndex = 0; + } + + EMAC->RxConsumeIndex = lIndex; + } + + return ulLen; +} +/*-----------------------------------------------------------*/ + +void vSendEMACTxData( unsigned short usTxDataLen ) +{ +unsigned long ulAttempts = 0UL; + + /* Check to see if the Tx descriptor is free, indicated by its buffer being + NULL. */ + while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL ) + { + /* Wait for the Tx descriptor to become available. */ + vTaskDelay( emacBUFFER_WAIT_DELAY ); + + ulAttempts++; + if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS ) + { + /* Something has gone wrong as the Tx descriptor is still in use. + Clear it down manually, the data it was sending will probably be + lost. */ + prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) ); + break; + } + } + + /* Setup the Tx descriptor for transmission. Remember the length of the + data being sent so the second descriptor can be used to send it again from + within the ISR. */ + usSendLen = usTxDataLen; + TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf; + TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT ); + EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 ); + + /* uip_buf is being sent by the Tx descriptor. Allocate a new buffer. */ + uip_buf = prvGetNextBuffer(); +} +/*-----------------------------------------------------------*/ + +static long prvWritePHY( long lPhyReg, long lValue ) +{ +const long lMaxTime = 10; +long x; + + EMAC->MADR = KS8721_DEF_ADR | lPhyReg; + EMAC->MWTD = lValue; + + x = 0; + for( x = 0; x < lMaxTime; x++ ) + { + if( ( EMAC->MIND & MIND_BUSY ) == 0 ) + { + /* Operation has finished. */ + break; + } + + vTaskDelay( emacSHORT_DELAY ); + } + + if( x < lMaxTime ) + { + return pdPASS; + } + else + { + return pdFAIL; + } +} +/*-----------------------------------------------------------*/ + +static unsigned short prvReadPHY( unsigned char ucPhyReg, long *plStatus ) +{ +long x; +const long lMaxTime = 10; + + EMAC->MADR = KS8721_DEF_ADR | ucPhyReg; + EMAC->MCMD = MCMD_READ; + + for( x = 0; x < lMaxTime; x++ ) + { + /* Operation has finished. */ + if( ( EMAC->MIND & MIND_BUSY ) == 0 ) + { + break; + } + + vTaskDelay( emacSHORT_DELAY ); + } + + EMAC->MCMD = 0; + + if( x >= lMaxTime ) + { + *plStatus = pdFAIL; + } + + return( EMAC->MRDD ); +} +/*-----------------------------------------------------------*/ + +void vEMAC_ISR( void ) +{ +unsigned long ulStatus; +long lHigherPriorityTaskWoken = pdFALSE; + + ulStatus = EMAC->IntStatus; + + /* Clear the interrupt. */ + EMAC->IntClear = ulStatus; + + if( ulStatus & INT_RX_DONE ) + { + /* Ensure the uIP task is not blocked as data has arrived. */ + xSemaphoreGiveFromISR( xEMACSemaphore, &lHigherPriorityTaskWoken ); + } + + if( ulStatus & INT_TX_DONE ) + { + if( usSendLen > 0 ) + { + /* Send the data again, using the second descriptor. As there are + only two descriptors the index is set back to 0. */ + TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX ); + TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT ); + EMAC->TxProduceIndex = ( emacTX_DESC_INDEX ); + + /* This is the second Tx so set usSendLen to 0 to indicate that the + Tx descriptors will be free again. */ + usSendLen = 0UL; + } + else + { + /* The Tx buffer is no longer required. */ + prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) ); + TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) NULL; + } + } + + portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); +} diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/http-strings b/Demo/CORTEX_LPC1768_IAR/webserver/http-strings new file mode 100644 index 000000000..0d3c30cdd --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/http-strings @@ -0,0 +1,35 @@ +http_http "http://" +http_200 "200 " +http_301 "301 " +http_302 "302 " +http_get "GET " +http_10 "HTTP/1.0" +http_11 "HTTP/1.1" +http_content_type "content-type: " +http_texthtml "text/html" +http_location "location: " +http_host "host: " +http_crnl "\r\n" +http_index_html "/index.html" +http_404_html "/404.html" +http_referer "Referer:" +http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" +http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" +http_content_type_plain "Content-type: text/plain\r\n\r\n" +http_content_type_html "Content-type: text/html\r\n\r\n" +http_content_type_css "Content-type: text/css\r\n\r\n" +http_content_type_text "Content-type: text/text\r\n\r\n" +http_content_type_png "Content-type: image/png\r\n\r\n" +http_content_type_gif "Content-type: image/gif\r\n\r\n" +http_content_type_jpg "Content-type: image/jpeg\r\n\r\n" +http_content_type_binary "Content-type: application/octet-stream\r\n\r\n" +http_html ".html" +http_shtml ".shtml" +http_htm ".htm" +http_css ".css" +http_png ".png" +http_gif ".gif" +http_jpg ".jpg" +http_text ".txt" +http_txt ".txt" + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/http-strings.c b/Demo/CORTEX_LPC1768_IAR/webserver/http-strings.c new file mode 100644 index 000000000..ef7a41c7d --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/http-strings.c @@ -0,0 +1,102 @@ +const char http_http[8] = +/* "http://" */ +{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_200[5] = +/* "200 " */ +{0x32, 0x30, 0x30, 0x20, }; +const char http_301[5] = +/* "301 " */ +{0x33, 0x30, 0x31, 0x20, }; +const char http_302[5] = +/* "302 " */ +{0x33, 0x30, 0x32, 0x20, }; +const char http_get[5] = +/* "GET " */ +{0x47, 0x45, 0x54, 0x20, }; +const char http_10[9] = +/* "HTTP/1.0" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, }; +const char http_11[9] = +/* "HTTP/1.1" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, }; +const char http_content_type[15] = +/* "content-type: " */ +{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, }; +const char http_texthtml[10] = +/* "text/html" */ +{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_location[11] = +/* "location: " */ +{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, }; +const char http_host[7] = +/* "host: " */ +{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, }; +const char http_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, }; +const char http_index_html[12] = +/* "/index.html" */ +{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_404_html[10] = +/* "/404.html" */ +{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_referer[9] = +/* "Referer:" */ +{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, }; +const char http_header_200[84] = +/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_header_404[91] = +/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_content_type_plain[29] = +/* "Content-type: text/plain\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_html[28] = +/* "Content-type: text/html\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_css [27] = +/* "Content-type: text/css\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_text[28] = +/* "Content-type: text/text\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_png [28] = +/* "Content-type: image/png\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_gif [28] = +/* "Content-type: image/gif\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_jpg [29] = +/* "Content-type: image/jpeg\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_binary[43] = +/* "Content-type: application/octet-stream\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, }; +const char http_html[6] = +/* ".html" */ +{0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_shtml[7] = +/* ".shtml" */ +{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_htm[5] = +/* ".htm" */ +{0x2e, 0x68, 0x74, 0x6d, }; +const char http_css[5] = +/* ".css" */ +{0x2e, 0x63, 0x73, 0x73, }; +const char http_png[5] = +/* ".png" */ +{0x2e, 0x70, 0x6e, 0x67, }; +const char http_gif[5] = +/* ".gif" */ +{0x2e, 0x67, 0x69, 0x66, }; +const char http_jpg[5] = +/* ".jpg" */ +{0x2e, 0x6a, 0x70, 0x67, }; +const char http_text[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, }; +const char http_txt[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, }; diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/http-strings.h b/Demo/CORTEX_LPC1768_IAR/webserver/http-strings.h new file mode 100644 index 000000000..acbe7e17f --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/http-strings.h @@ -0,0 +1,34 @@ +extern const char http_http[8]; +extern const char http_200[5]; +extern const char http_301[5]; +extern const char http_302[5]; +extern const char http_get[5]; +extern const char http_10[9]; +extern const char http_11[9]; +extern const char http_content_type[15]; +extern const char http_texthtml[10]; +extern const char http_location[11]; +extern const char http_host[7]; +extern const char http_crnl[3]; +extern const char http_index_html[12]; +extern const char http_404_html[10]; +extern const char http_referer[9]; +extern const char http_header_200[84]; +extern const char http_header_404[91]; +extern const char http_content_type_plain[29]; +extern const char http_content_type_html[28]; +extern const char http_content_type_css [27]; +extern const char http_content_type_text[28]; +extern const char http_content_type_png [28]; +extern const char http_content_type_gif [28]; +extern const char http_content_type_jpg [29]; +extern const char http_content_type_binary[43]; +extern const char http_html[6]; +extern const char http_shtml[7]; +extern const char http_htm[5]; +extern const char http_css[5]; +extern const char http_png[5]; +extern const char http_gif[5]; +extern const char http_jpg[5]; +extern const char http_text[5]; +extern const char http_txt[5]; diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.c b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.c new file mode 100644 index 000000000..dfcedb833 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.c @@ -0,0 +1,304 @@ +/** + * \addtogroup httpd + * @{ + */ + +/** + * \file + * Web server script interface + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2001-2006, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + * + */ + +#include "uip.h" +#include "psock.h" +#include "httpd.h" +#include "httpd-cgi.h" +#include "httpd-fs.h" + +#include +#include + +HTTPD_CGI_CALL(file, "file-stats", file_stats); +HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats); +HTTPD_CGI_CALL(net, "net-stats", net_stats); +HTTPD_CGI_CALL(rtos, "rtos-stats", rtos_stats ); +HTTPD_CGI_CALL(run, "run-time", run_time ); +HTTPD_CGI_CALL(io, "led-io", led_io ); + + +static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, &rtos, &run, &io, NULL }; + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + ( void ) ptr; + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_cgifunction +httpd_cgi(char *name) +{ + const struct httpd_cgi_call **f; + + /* Find the matching name in the table, return the function. */ + for(f = calls; *f != NULL; ++f) { + if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) { + return (*f)->function; + } + } + return nullfunction; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_file_stats(void *arg) +{ + char *f = (char *)arg; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f)); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static const char closed[] = /* "CLOSED",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; +static const char syn_rcvd[] = /* "SYN-RCVD",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, + 0x44, 0}; +static const char syn_sent[] = /* "SYN-SENT",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, + 0x54, 0}; +static const char established[] = /* "ESTABLISHED",*/ +{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, + 0x45, 0x44, 0}; +static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x31, 0}; +static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x32, 0}; +static const char closing[] = /* "CLOSING",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x49, + 0x4e, 0x47, 0}; +static const char time_wait[] = /* "TIME-WAIT,"*/ +{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, + 0x49, 0x54, 0}; +static const char last_ack[] = /* "LAST-ACK"*/ +{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, + 0x4b, 0}; + +static const char *states[] = { + closed, + syn_rcvd, + syn_sent, + established, + fin_wait_1, + fin_wait_2, + closing, + time_wait, + last_ack}; + + +static unsigned short +generate_tcp_stats(void *arg) +{ + struct uip_conn *conn; + struct httpd_state *s = (struct httpd_state *)arg; + + conn = &uip_conns[s->count]; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, + "%d%u.%u.%u.%u:%u%s%u%u%c %c\r\n", + htons(conn->lport), + htons(conn->ripaddr[0]) >> 8, + htons(conn->ripaddr[0]) & 0xff, + htons(conn->ripaddr[1]) >> 8, + htons(conn->ripaddr[1]) & 0xff, + htons(conn->rport), + states[conn->tcpstateflags & UIP_TS_MASK], + conn->nrtx, + conn->timer, + (uip_outstanding(conn))? '*':' ', + (uip_stopped(conn))? '!':' '); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) +{ + + PSOCK_BEGIN(&s->sout); + ( void ) ptr; + for(s->count = 0; s->count < UIP_CONNS; ++s->count) { + if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { + PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s); + } + } + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_net_stats(void *arg) +{ + struct httpd_state *s = (struct httpd_state *)arg; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, + "%5u\n", ((uip_stats_t *)&uip_stat)[s->count]); +} + +static +PT_THREAD(net_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + + ( void ) ptr; +#if UIP_STATISTICS + + for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); + ++s->count) { + PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s); + } + +#endif /* UIP_STATISTICS */ + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ + +extern void vTaskList( signed char *pcWriteBuffer ); +extern char *pcGetTaskStatusMessage( void ); +static char cCountBuf[ 128 ]; +long lRefreshCount = 0; +static unsigned short +generate_rtos_stats(void *arg) +{ + ( void ) arg; + lRefreshCount++; + sprintf( cCountBuf, "


Refresh count = %d


%s", (int)lRefreshCount, pcGetTaskStatusMessage() ); + vTaskList( uip_appdata ); + strcat( uip_appdata, cCountBuf ); + + return strlen( uip_appdata ); +} +/*---------------------------------------------------------------------------*/ + + +static +PT_THREAD(rtos_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + ( void ) ptr; + PSOCK_GENERATOR_SEND(&s->sout, generate_rtos_stats, NULL); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ + +char *pcStatus; +unsigned long ulString; + +static unsigned short generate_io_state( void *arg ) +{ +extern long lParTestGetLEDState( void ); + + ( void ) arg; + + /* Get the state of the LEDs that are on the FIO1 port. */ + if( lParTestGetLEDState() ) + { + pcStatus = ""; + } + else + { + pcStatus = "checked"; + } + + sprintf( uip_appdata, + "LED

", pcStatus ); + + return strlen( uip_appdata ); +} +/*---------------------------------------------------------------------------*/ + +extern void vTaskGetRunTimeStats( signed char *pcWriteBuffer ); +static unsigned short +generate_runtime_stats(void *arg) +{ + ( void ) arg; + lRefreshCount++; + sprintf( cCountBuf, "


Refresh count = %d", (int)lRefreshCount ); + vTaskGetRunTimeStats( uip_appdata ); + strcat( uip_appdata, cCountBuf ); + + return strlen( uip_appdata ); +} +/*---------------------------------------------------------------------------*/ + + +static +PT_THREAD(run_time(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + ( void ) ptr; + PSOCK_GENERATOR_SEND(&s->sout, generate_runtime_stats, NULL); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ + + +static PT_THREAD(led_io(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + ( void ) ptr; + PSOCK_GENERATOR_SEND(&s->sout, generate_io_state, NULL); + PSOCK_END(&s->sout); +} + +/** @} */ + + + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.h b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.h new file mode 100644 index 000000000..7ae928321 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-cgi.h @@ -0,0 +1,84 @@ +/** + * \addtogroup httpd + * @{ + */ + +/** + * \file + * Web server script interface header file + * \author + * Adam Dunkels + * + */ + + + +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cgi.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ + +#ifndef __HTTPD_CGI_H__ +#define __HTTPD_CGI_H__ + +#include "psock.h" +#include "httpd.h" + +typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *)); + +httpd_cgifunction httpd_cgi(char *name); + +struct httpd_cgi_call { + const char *name; + const httpd_cgifunction function; +}; + +/** + * \brief HTTPD CGI function declaration + * \param name The C variable name of the function + * \param str The string name of the function, used in the script file + * \param function A pointer to the function that implements it + * + * This macro is used for declaring a HTTPD CGI + * function. This function is then added to the list of + * HTTPD CGI functions with the httpd_cgi_add() function. + * + * \hideinitializer + */ +#define HTTPD_CGI_CALL(name, str, function) \ +static PT_THREAD(function(struct httpd_state *, char *)); \ +static const struct httpd_cgi_call name = {str, function} + +void httpd_cgi_init(void); +#endif /* __HTTPD_CGI_H__ */ + +/** @} */ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.c b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.c new file mode 100644 index 000000000..dc4aef011 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $ + */ + +#include "httpd.h" +#include "httpd-fs.h" +#include "httpd-fsdata.h" + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +#include "httpd-fsdata.c" + +#if HTTPD_FS_STATISTICS +static u16_t count[HTTPD_FS_NUMFILES]; +#endif /* HTTPD_FS_STATISTICS */ + +/*-----------------------------------------------------------------------------------*/ +static u8_t +httpd_fs_strcmp(const char *str1, const char *str2) +{ + u8_t i; + i = 0; + loop: + + if(str2[i] == 0 || + str1[i] == '\r' || + str1[i] == '\n') { + return 0; + } + + if(str1[i] != str2[i]) { + return 1; + } + + + ++i; + goto loop; +} +/*-----------------------------------------------------------------------------------*/ +int +httpd_fs_open(const char *name, struct httpd_fs_file *file) +{ +#if HTTPD_FS_STATISTICS + u16_t i = 0; +#endif /* HTTPD_FS_STATISTICS */ + struct httpd_fsdata_file_noconst *f; + + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)f->next) { + + if(httpd_fs_strcmp(name, f->name) == 0) { + file->data = f->data; + file->len = f->len; +#if HTTPD_FS_STATISTICS + ++count[i]; +#endif /* HTTPD_FS_STATISTICS */ + return 1; + } +#if HTTPD_FS_STATISTICS + ++i; +#endif /* HTTPD_FS_STATISTICS */ + + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +void +httpd_fs_init(void) +{ +#if HTTPD_FS_STATISTICS + u16_t i; + for(i = 0; i < HTTPD_FS_NUMFILES; i++) { + count[i] = 0; + } +#endif /* HTTPD_FS_STATISTICS */ +} +/*-----------------------------------------------------------------------------------*/ +#if HTTPD_FS_STATISTICS +u16_t httpd_fs_count +(char *name) +{ + struct httpd_fsdata_file_noconst *f; + u16_t i; + + i = 0; + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)f->next) { + + if(httpd_fs_strcmp(name, f->name) == 0) { + return count[i]; + } + ++i; + } + return 0; +} +#endif /* HTTPD_FS_STATISTICS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.h b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.h new file mode 100644 index 000000000..b594eea56 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $ + */ +#ifndef __HTTPD_FS_H__ +#define __HTTPD_FS_H__ + +#define HTTPD_FS_STATISTICS 1 + +struct httpd_fs_file { + char *data; + int len; +}; + +/* file must be allocated by caller and will be filled in + by the function. */ +int httpd_fs_open(const char *name, struct httpd_fs_file *file); + +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 +u16_t httpd_fs_count(char *name); +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ + +void httpd_fs_init(void); + +#endif /* __HTTPD_FS_H__ */ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/404.html b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/404.html new file mode 100644 index 000000000..43e7f4cad --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/404.html @@ -0,0 +1,8 @@ + + +

+

404 - file not found

+

Go here instead.

+
+ + \ No newline at end of file diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.html b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.html new file mode 100644 index 000000000..4937dc69a --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.html @@ -0,0 +1,13 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Loading index.shtml. Click here if not automatically redirected. + + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.shtml b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.shtml new file mode 100644 index 000000000..29d242c05 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/index.shtml @@ -0,0 +1,20 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS.org Homepage | IO +

+


+

+

Task statistics

+Page will refresh every 2 seconds.

+

Task          State  Priority  Stack	#
************************************************
+%! rtos-stats +
+
+ + + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/io.shtml b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/io.shtml new file mode 100644 index 000000000..fd0697d2a --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/io.shtml @@ -0,0 +1,28 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS.org Homepage | IO +

+


+LED and LCD IO
+ +

+ +Use the check box to turn on or off the LED, enter text to display on the OLED display, then click "Update IO". + + +

+

+%! led-io +

+ +

+

+ + + + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/runtime.shtml b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/runtime.shtml new file mode 100644 index 000000000..67cae4657 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/runtime.shtml @@ -0,0 +1,20 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS.org Homepage | IO +

+


+

+

Run-time statistics

+Page will refresh every 2 seconds.

+

Task            Abs Time      % Time
****************************************
+%! run-time +
+
+ + + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/stats.shtml b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/stats.shtml new file mode 100644 index 000000000..d95a69340 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/stats.shtml @@ -0,0 +1,41 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS.org Homepage | IO +

+


+

+

Network statistics

+ +
+IP           Packets dropped
+             Packets received
+             Packets sent
+IP errors    IP version/header length
+             IP length, high byte
+             IP length, low byte
+             IP fragments
+             Header checksum
+             Wrong protocol
+ICMP	     Packets dropped
+             Packets received
+             Packets sent
+             Type errors
+TCP          Packets dropped
+             Packets received
+             Packets sent
+             Checksum errors
+             Data packets without ACKs
+             Resets
+             Retransmissions
+	     No connection avaliable
+	     Connection attempts to closed ports
+
%! net-stats
+
+
+ + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/tcp.shtml b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/tcp.shtml new file mode 100644 index 000000000..41053679d --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fs/tcp.shtml @@ -0,0 +1,21 @@ + + + + FreeRTOS.org uIP WEB server demo + + + +Task Stats | Run Time Stats | TCP Stats | Connections | FreeRTOS.org Homepage | IO +

+


+
+

Network connections

+

+ + +%! tcp-connections + + + + + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.c b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.c new file mode 100644 index 000000000..c8b2a8026 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.c @@ -0,0 +1,557 @@ +static const char data_404_html[] = { + /* /404.html */ + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, + 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, + 0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, + 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, + 0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, +0}; + +static const char data_index_html[] = { + /* /index.html */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, + 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f, + 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x31, 0x30, 0x30, 0x29, 0x22, + 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, + 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, + 0x3e, 0xa, 0x4c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x2e, 0x20, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, 0x3c, 0x2f, 0x61, 0x3e, + 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x75, + 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, + 0x79, 0x20, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x2e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, + 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, + 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0}; + +static const char data_index_shtml[] = { + /* /index.shtml */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, + 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f, + 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x26, 0x71, + 0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x32, 0x30, 0x30, 0x30, 0x29, + 0x22, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, + 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, + 0x22, 0x3e, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, + 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, + 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, + 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, + 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, + 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, + 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, + 0x32, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, + 0x32, 0x3e, 0xa, 0x50, 0x61, 0x67, 0x65, 0x20, 0x77, 0x69, + 0x6c, 0x6c, 0x20, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x32, 0x20, 0x73, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x2e, 0x3c, 0x70, 0x3e, + 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, + 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, + 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x54, 0x61, 0x73, + 0x6b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x20, 0x50, 0x72, + 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x20, 0x53, 0x74, + 0x61, 0x63, 0x6b, 0x9, 0x23, 0x3c, 0x62, 0x72, 0x3e, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3c, 0x62, 0x72, + 0x3e, 0xa, 0x25, 0x21, 0x20, 0x72, 0x74, 0x6f, 0x73, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, + 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, + 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, + 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0}; + +static const char data_io_shtml[] = { + /* /io.shtml */ + 0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, + 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa, + 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, + 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, + 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65, + 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, + 0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, + 0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x3e, + 0x4c, 0x45, 0x44, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4c, 0x43, + 0x44, 0x20, 0x49, 0x4f, 0x3c, 0x2f, 0x62, 0x3e, 0x3c, 0x62, + 0x72, 0x3e, 0xa, 0xa, 0x3c, 0x70, 0x3e, 0xa, 0xa, 0x55, + 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x74, 0x6f, 0x20, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x72, + 0x20, 0x6f, 0x66, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4c, + 0x45, 0x44, 0x2c, 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, + 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x20, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x22, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x49, 0x4f, 0x22, 0x2e, + 0xa, 0xa, 0xa, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x66, 0x6f, + 0x72, 0x6d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, + 0x46, 0x6f, 0x72, 0x6d, 0x22, 0x20, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3d, 0x22, 0x2f, 0x69, 0x6f, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x3d, 0x22, 0x67, 0x65, 0x74, 0x22, 0x3e, 0xa, 0x25, + 0x21, 0x20, 0x6c, 0x65, 0x64, 0x2d, 0x69, 0x6f, 0xa, 0x3c, + 0x70, 0x3e, 0xa, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, + 0x69, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, + 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x49, 0x4f, + 0x22, 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, + 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, + 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0xa, 0xa, 0}; + +static const char data_runtime_shtml[] = { + /* /runtime.shtml */ + 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, + 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x20, 0x6f, + 0x6e, 0x4c, 0x6f, 0x61, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x28, 0x26, 0x71, 0x75, 0x6f, 0x74, + 0x3b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x27, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x27, + 0x26, 0x71, 0x75, 0x6f, 0x74, 0x3b, 0x2c, 0x32, 0x30, 0x30, + 0x30, 0x29, 0x22, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x6e, 0x74, + 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x61, 0x72, 0x69, + 0x61, 0x6c, 0x22, 0x3e, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x61, 0x73, + 0x6b, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x52, 0x75, 0x6e, 0x20, 0x54, + 0x69, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x54, 0x43, 0x50, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x66, 0x72, 0x65, 0x65, 0x72, 0x74, 0x6f, + 0x73, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x22, 0x3e, 0x46, 0x72, + 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, 0x72, 0x67, + 0x20, 0x48, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x69, 0x6f, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x49, 0x4f, 0x3c, 0x2f, 0x61, 0x3e, 0xa, 0x3c, + 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x72, + 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, 0x3e, 0xa, + 0x3c, 0x68, 0x32, 0x3e, 0x52, 0x75, 0x6e, 0x2d, 0x74, 0x69, + 0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, + 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0xa, 0x50, + 0x61, 0x67, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x72, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x20, 0x65, 0x76, 0x65, + 0x72, 0x79, 0x20, 0x32, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x2e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x66, 0x6f, + 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, + 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, + 0x72, 0x65, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, + 0x62, 0x73, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x25, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x3c, + 0x62, 0x72, 0x3e, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + 0x2a, 0x2a, 0x2a, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x25, 0x21, + 0x20, 0x72, 0x75, 0x6e, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0xa, + 0x3c, 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, + 0x6e, 0x74, 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, + 0x3e, 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0}; + +static const char data_stats_shtml[] = { + /* /stats.shtml */ + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, + 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa, + 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, + 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, + 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65, + 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, + 0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, + 0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x72, + 0x3e, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, + 0x32, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, 0x30, + 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x22, + 0x30, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, + 0x64, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, + 0x65, 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x66, 0x6f, 0x6e, 0x74, + 0x20, 0x66, 0x61, 0x63, 0x65, 0x3d, 0x22, 0x63, 0x6f, 0x75, + 0x72, 0x69, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x65, + 0x3e, 0xa, 0x49, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x49, 0x50, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x20, 0x20, 0x20, 0x20, + 0x49, 0x50, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, + 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68, + 0x69, 0x67, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74, + 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72, + 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0xa, 0x49, 0x43, 0x4d, 0x50, 0x9, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x54, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0xa, 0x54, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, + 0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, + 0x41, 0x43, 0x4b, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, + 0x73, 0x65, 0x74, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, 0x6c, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, + 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0x3c, + 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x70, + 0x72, 0x65, 0x3e, 0x25, 0x21, 0x20, 0x6e, 0x65, 0x74, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, + 0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, + 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, + 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0}; + +static const char data_tcp_shtml[] = { + /* /tcp.shtml */ + 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x2e, 0x6f, + 0x72, 0x67, 0x20, 0x75, 0x49, 0x50, 0x20, 0x57, 0x45, 0x42, + 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x64, 0x65, + 0x6d, 0x6f, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x42, 0x4f, 0x44, 0x59, 0x3e, 0xa, + 0x3c, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x66, 0x61, 0x63, 0x65, + 0x3d, 0x22, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x22, 0x3e, 0xa, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x54, 0x61, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, + 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x52, 0x75, 0x6e, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x54, 0x43, 0x50, 0x20, 0x53, 0x74, 0x61, 0x74, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x62, 0x3e, 0x7c, 0x3c, 0x2f, + 0x62, 0x3e, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x66, 0x72, + 0x65, 0x65, 0x72, 0x74, 0x6f, 0x73, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x65, 0x65, 0x52, 0x54, 0x4f, + 0x53, 0x2e, 0x6f, 0x72, 0x67, 0x20, 0x48, 0x6f, 0x6d, 0x65, + 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, + 0x62, 0x3e, 0x7c, 0x3c, 0x2f, 0x62, 0x3e, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x69, 0x6f, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x49, 0x4f, 0x3c, + 0x2f, 0x61, 0x3e, 0xa, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x70, + 0x3e, 0xa, 0x3c, 0x68, 0x72, 0x3e, 0xa, 0x3c, 0x62, 0x72, + 0x3e, 0xa, 0x3c, 0x68, 0x32, 0x3e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x68, 0x32, 0x3e, + 0xa, 0x3c, 0x70, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, + 0x3e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, + 0x3c, 0x74, 0x68, 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c, + 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, + 0x68, 0x3e, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21, + 0x20, 0x74, 0x63, 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa, 0x3c, 0x2f, 0x70, + 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, + 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x3e, 0xa, 0x3c, + 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, + 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0xa, 0}; + +const struct httpd_fsdata_file file_404_html[] = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10, 0}}; + +const struct httpd_fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12, 0}}; + +const struct httpd_fsdata_file file_index_shtml[] = {{file_index_html, data_index_shtml, data_index_shtml + 13, sizeof(data_index_shtml) - 13, 0}}; + +const struct httpd_fsdata_file file_io_shtml[] = {{file_index_shtml, data_io_shtml, data_io_shtml + 10, sizeof(data_io_shtml) - 10, 0}}; + +const struct httpd_fsdata_file file_runtime_shtml[] = {{file_io_shtml, data_runtime_shtml, data_runtime_shtml + 15, sizeof(data_runtime_shtml) - 15, 0}}; + +const struct httpd_fsdata_file file_stats_shtml[] = {{file_runtime_shtml, data_stats_shtml, data_stats_shtml + 13, sizeof(data_stats_shtml) - 13, 0}}; + +const struct httpd_fsdata_file file_tcp_shtml[] = {{file_stats_shtml, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11, 0}}; + +#define HTTPD_FS_ROOT file_tcp_shtml + +#define HTTPD_FS_NUMFILES 7 diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.h b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.h new file mode 100644 index 000000000..52d35c265 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd-fsdata.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $ + */ +#ifndef __HTTPD_FSDATA_H__ +#define __HTTPD_FSDATA_H__ + +#include "uip.h" + +struct httpd_fsdata_file { + const struct httpd_fsdata_file *next; + const char *name; + const char *data; + const int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +struct httpd_fsdata_file_noconst { + struct httpd_fsdata_file *next; + char *name; + char *data; + int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +#endif /* __HTTPD_FSDATA_H__ */ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd.c b/Demo/CORTEX_LPC1768_IAR/webserver/httpd.c new file mode 100644 index 000000000..c416cc1c8 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd.c @@ -0,0 +1,346 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup httpd Web server + * @{ + * The uIP web server is a very simplistic implementation of an HTTP + * server. It can serve web pages and files from a read-only ROM + * filesystem, and provides a very small scripting language. + + */ + +/** + * \file + * Web server + * \author + * Adam Dunkels + */ + + +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $ + */ + +#include "uip.h" +#include "httpd.h" +#include "httpd-fs.h" +#include "httpd-cgi.h" +#include "http-strings.h" + +#include + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_bang 0x21 +#define ISO_percent 0x25 +#define ISO_period 0x2e +#define ISO_slash 0x2f +#define ISO_colon 0x3a + + +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_part_of_file(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + memcpy(uip_appdata, s->file.data, s->len); + + return s->len; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + do { + PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s); + s->file.len -= s->len; + s->file.data += s->len; + } while(s->file.len > 0); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_part_of_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_SEND(&s->sout, s->file.data, s->len); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static void +next_scriptstate(struct httpd_state *s) +{ + char *p; + p = strchr(s->scriptptr, ISO_nl) + 1; + s->scriptlen -= (unsigned short)(p - s->scriptptr); + s->scriptptr = p; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_script(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->scriptpt); + + + while(s->file.len > 0) { + + /* Check if we should start executing a script. */ + if(*s->file.data == ISO_percent && + *(s->file.data + 1) == ISO_bang) { + s->scriptptr = s->file.data + 3; + s->scriptlen = s->file.len - 3; + if(*(s->scriptptr - 1) == ISO_colon) { + httpd_fs_open(s->scriptptr + 1, &s->file); + PT_WAIT_THREAD(&s->scriptpt, send_file(s)); + } else { + PT_WAIT_THREAD(&s->scriptpt, + httpd_cgi(s->scriptptr)(s, s->scriptptr)); + } + next_scriptstate(s); + + /* The script is over, so we reset the pointers and continue + sending the rest of the file. */ + s->file.data = s->scriptptr; + s->file.len = s->scriptlen; + } else { + /* See if we find the start of script marker in the block of HTML + to be sent. */ + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + + if(*s->file.data == ISO_percent) { + ptr = strchr(s->file.data + 1, ISO_percent); + } else { + ptr = strchr(s->file.data, ISO_percent); + } + if(ptr != NULL && + ptr != s->file.data) { + s->len = (int)(ptr - s->file.data); + if(s->len >= uip_mss()) { + s->len = uip_mss(); + } + } + PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); + s->file.data += s->len; + s->file.len -= s->len; + + } + } + + PT_END(&s->scriptpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + char *ptr; + + PSOCK_BEGIN(&s->sout); + + PSOCK_SEND_STR(&s->sout, statushdr); + + ptr = strrchr(s->filename, ISO_period); + if(ptr == NULL) { + PSOCK_SEND_STR(&s->sout, http_content_type_binary); + } else if(strncmp(http_html, ptr, 5) == 0 || + strncmp(http_shtml, ptr, 6) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_html); + } else if(strncmp(http_css, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_css); + } else if(strncmp(http_png, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_png); + } else if(strncmp(http_gif, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_gif); + } else if(strncmp(http_jpg, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_jpg); + } else { + PSOCK_SEND_STR(&s->sout, http_content_type_plain); + } + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->outputpt); + + if(!httpd_fs_open(s->filename, &s->file)) { + httpd_fs_open(http_404_html, &s->file); + strcpy(s->filename, http_404_html); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_200)); + ptr = strchr(s->filename, ISO_period); + if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) { + PT_INIT(&s->scriptpt); + PT_WAIT_THREAD(&s->outputpt, handle_script(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } + } + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + + /* Process any form input being sent to the server. */ + { + extern void vApplicationProcessFormInput( char *pcInputString ); + vApplicationProcessFormInput( s->inputbuf ); + } + + strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); + } + + /* httpd_log_file(uip_conn->ripaddr, s->filename);*/ + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + /* httpd_log(&s->inputbuf[9]);*/ + } + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void) +{ + struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate); + + if(uip_closed() || uip_aborted() || uip_timedout()) { + } else if(uip_connected()) { + PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->state = STATE_WAITING; + /* timer_set(&s->timer, CLOCK_SECOND * 100);*/ + s->timer = 0; + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + ++s->timer; + if(s->timer >= 20) { + uip_abort(); + } + } else { + s->timer = 0; + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the web server + * + * This function initializes the web server and should be + * called at system boot-up. + */ +void +httpd_init(void) +{ + uip_listen(HTONS(80)); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/httpd.h b/Demo/CORTEX_LPC1768_IAR/webserver/httpd.h new file mode 100644 index 000000000..7f7a6666e --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/httpd.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2001-2005, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ + +#ifndef __HTTPD_H__ +#define __HTTPD_H__ + +#include "psock.h" +#include "httpd-fs.h" + +struct httpd_state { + unsigned char timer; + struct psock sin, sout; + struct pt outputpt, scriptpt; + char inputbuf[50]; + char filename[20]; + char state; + struct httpd_fs_file file; + int len; + char *scriptptr; + int scriptlen; + + unsigned short count; +}; + +void httpd_init(void); +void httpd_appcall(void); + +void httpd_log(char *msg); +void httpd_log_file(u16_t *requester, char *file); + +#endif /* __HTTPD_H__ */ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/makefsdata b/Demo/CORTEX_LPC1768_IAR/webserver/makefsdata new file mode 100644 index 000000000..8d2715a8a --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/makefsdata @@ -0,0 +1,78 @@ +#!/usr/bin/perl + +open(OUTPUT, "> httpd-fsdata.c"); + +chdir("httpd-fs"); + +opendir(DIR, "."); +@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); +closedir(DIR); + +foreach $file (@files) { + + if(-d $file && $file !~ /^\./) { + print "Processing directory $file\n"; + opendir(DIR, $file); + @newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); + closedir(DIR); + printf "Adding files @newfiles\n"; + @files = (@files, map { $_ = "$file/$_" } @newfiles); + next; + } +} + +foreach $file (@files) { + if(-f $file) { + + print "Adding file $file\n"; + + open(FILE, $file) || die "Could not open file $file\n"; + + $file =~ s-^-/-; + $fvar = $file; + $fvar =~ s-/-_-g; + $fvar =~ s-\.-_-g; + # for AVR, add PROGMEM here + print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); + print(OUTPUT "\t/* $file */\n\t"); + for($j = 0; $j < length($file); $j++) { + printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); + } + printf(OUTPUT "0,\n"); + + + $i = 0; + while(read(FILE, $data, 1)) { + if($i == 0) { + print(OUTPUT "\t"); + } + printf(OUTPUT "%#02x, ", unpack("C", $data)); + $i++; + if($i == 10) { + print(OUTPUT "\n"); + $i = 0; + } + } + print(OUTPUT "0};\n\n"); + close(FILE); + push(@fvars, $fvar); + push(@pfiles, $file); + } +} + +for($i = 0; $i < @fvars; $i++) { + $file = $pfiles[$i]; + $fvar = $fvars[$i]; + + if($i == 0) { + $prevfile = "NULL"; + } else { + $prevfile = "file" . $fvars[$i - 1]; + } + print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); + print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); + print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); +} + +print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n"); +print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n"); diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/makestrings b/Demo/CORTEX_LPC1768_IAR/webserver/makestrings new file mode 100644 index 000000000..8a13c6d29 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/makestrings @@ -0,0 +1,40 @@ +#!/usr/bin/perl + + +sub stringify { + my $name = shift(@_); + open(OUTPUTC, "> $name.c"); + open(OUTPUTH, "> $name.h"); + + open(FILE, "$name"); + + while() { + if(/(.+) "(.+)"/) { + $var = $1; + $data = $2; + + $datan = $data; + $datan =~ s/\\r/\r/g; + $datan =~ s/\\n/\n/g; + $datan =~ s/\\01/\01/g; + $datan =~ s/\\0/\0/g; + + printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1); + printf(OUTPUTC "/* \"$data\" */\n"); + printf(OUTPUTC "{"); + for($j = 0; $j < length($datan); $j++) { + printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1))); + } + printf(OUTPUTC "};\n"); + + printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1); + + } + } + close(OUTPUTC); + close(OUTPUTH); +} +stringify("http-strings"); + +exit 0; + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/uIP_Task.c b/Demo/CORTEX_LPC1768_IAR/webserver/uIP_Task.c new file mode 100644 index 000000000..94f0cc11a --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/uIP_Task.c @@ -0,0 +1,264 @@ +/* + FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation and modified by the FreeRTOS exception. + **NOTE** The exception to the GPL is included to allow you to distribute a + combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + Alternative commercial license and support terms are also available upon + request. See the licensing section of http://www.FreeRTOS.org for full + license details. + + 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 along + with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + + *************************************************************************** + * * + * Looking for a quick start? Then check out the FreeRTOS eBook! * + * See http://www.FreeRTOS.org/Documentation for details * + * * + *************************************************************************** + + 1 tab == 4 spaces! + + Please ensure to read the configuration and relevant port sections of the + online documentation. + + 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. +*/ + +/* Standard includes. */ +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* uip includes. */ +#include "uip.h" +#include "uip_arp.h" +#include "httpd.h" +#include "timer.h" +#include "clock-arch.h" + +/* Demo includes. */ +#include "EthDev_LPC17xx.h" +#include "EthDev.h" +#include "ParTest.h" + +/*-----------------------------------------------------------*/ + +/* How long to wait before attempting to connect the MAC again. */ +#define uipINIT_WAIT ( 100 / portTICK_RATE_MS ) + +/* Shortcut to the header within the Rx buffer. */ +#define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ]) + +/* Standard constant. */ +#define uipTOTAL_FRAME_HEADER_SIZE 54 + +/*-----------------------------------------------------------*/ + +/* + * Setup the MAC address in the MAC itself, and in the uIP stack. + */ +static void prvSetMACAddress( void ); + +/* + * Port functions required by the uIP stack. + */ +void clock_init( void ); +clock_time_t clock_time( void ); + +/*-----------------------------------------------------------*/ + +/* The semaphore used by the ISR to wake the uIP task. */ +xSemaphoreHandle xEMACSemaphore = NULL; + +/*-----------------------------------------------------------*/ + +void clock_init(void) +{ + /* This is done when the scheduler starts. */ +} +/*-----------------------------------------------------------*/ + +clock_time_t clock_time( void ) +{ + return xTaskGetTickCount(); +} +/*-----------------------------------------------------------*/ + +void vuIP_Task( void *pvParameters ) +{ +portBASE_TYPE i; +uip_ipaddr_t xIPAddr; +struct timer periodic_timer, arp_timer; +extern void ( vEMAC_ISR_Wrapper )( void ); + + ( void ) pvParameters; + + /* Initialise the uIP stack. */ + timer_set( &periodic_timer, configTICK_RATE_HZ / 2 ); + timer_set( &arp_timer, configTICK_RATE_HZ * 10 ); + uip_init(); + uip_ipaddr( xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 ); + uip_sethostaddr( xIPAddr ); + uip_ipaddr( xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 ); + uip_setnetmask( xIPAddr ); + httpd_init(); + + /* Create the semaphore used to wake the uIP task. */ + vSemaphoreCreateBinary( xEMACSemaphore ); + + /* Initialise the MAC. */ + while( lEMACInit() != pdPASS ) + { + vTaskDelay( uipINIT_WAIT ); + } + + portENTER_CRITICAL(); + { + EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE ); + + /* Set the interrupt priority to the max permissible to cause some + interrupt nesting. */ + NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY ); + + /* Enable the interrupt. */ + NVIC_EnableIRQ( ENET_IRQn ); + prvSetMACAddress(); + } + portEXIT_CRITICAL(); + + + for( ;; ) + { + /* Is there received data ready to be processed? */ + uip_len = ulGetEMACRxData(); + + if( ( uip_len > 0 ) && ( uip_buf != NULL ) ) + { + /* Standard uIP loop taken from the uIP manual. */ + if( xHeader->type == htons( UIP_ETHTYPE_IP ) ) + { + uip_arp_ipin(); + uip_input(); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + uip_arp_out(); + vSendEMACTxData( uip_len ); + } + } + else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) ) + { + uip_arp_arpin(); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + vSendEMACTxData( uip_len ); + } + } + } + else + { + if( timer_expired( &periodic_timer ) && ( uip_buf != NULL ) ) + { + timer_reset( &periodic_timer ); + for( i = 0; i < UIP_CONNS; i++ ) + { + uip_periodic( i ); + + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if( uip_len > 0 ) + { + uip_arp_out(); + vSendEMACTxData( uip_len ); + } + } + + /* Call the ARP timer function every 10 seconds. */ + if( timer_expired( &arp_timer ) ) + { + timer_reset( &arp_timer ); + uip_arp_timer(); + } + } + else + { + /* We did not receive a packet, and there was no periodic + processing to perform. Block for a fixed period. If a packet + is received during this period we will be woken by the ISR + giving us the Semaphore. */ + xSemaphoreTake( xEMACSemaphore, configTICK_RATE_HZ / 2 ); + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSetMACAddress( void ) +{ +struct uip_eth_addr xAddr; + + /* Configure the MAC address in the uIP stack. */ + xAddr.addr[ 0 ] = configMAC_ADDR0; + xAddr.addr[ 1 ] = configMAC_ADDR1; + xAddr.addr[ 2 ] = configMAC_ADDR2; + xAddr.addr[ 3 ] = configMAC_ADDR3; + xAddr.addr[ 4 ] = configMAC_ADDR4; + xAddr.addr[ 5 ] = configMAC_ADDR5; + uip_setethaddr( xAddr ); +} +/*-----------------------------------------------------------*/ + +void vApplicationProcessFormInput( portCHAR *pcInputString ) +{ +char *c; +extern void vParTestSetLEDState( long lState ); + + /* Process the form input sent by the IO page of the served HTML. */ + + c = strstr( pcInputString, "?" ); + if( c ) + { + /* Turn the FIO1 LED's on or off in accordance with the check box status. */ + if( strstr( c, "LED0=1" ) != NULL ) + { + vParTestSetLEDState( pdTRUE ); + } + else + { + vParTestSetLEDState( pdFALSE ); + } + } +} + diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/uip-conf.h b/Demo/CORTEX_LPC1768_IAR/webserver/uip-conf.h new file mode 100644 index 000000000..b52b23fed --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/uip-conf.h @@ -0,0 +1,159 @@ +/** + * \addtogroup uipopt + * @{ + */ + +/** + * \name Project-specific configuration options + * @{ + * + * uIP has a number of configuration options that can be overridden + * for each project. These are kept in a project-specific uip-conf.h + * file and all configuration names have the prefix UIP_CONF. + */ + +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $ + */ + +/** + * \file + * An example uIP configuration file + * \author + * Adam Dunkels + */ + +#ifndef __UIP_CONF_H__ +#define __UIP_CONF_H__ + +#include + +#define UIP_CONF_EXTERNAL_BUFFER + +/** + * 8 bit datatype + * + * This typedef defines the 8-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint8_t u8_t; + +/** + * 16 bit datatype + * + * This typedef defines the 16-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint16_t u16_t; + +/** + * Statistics datatype + * + * This typedef defines the dataype used for keeping statistics in + * uIP. + * + * \hideinitializer + */ +typedef unsigned short uip_stats_t; + +/** + * Maximum number of TCP connections. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_CONNECTIONS 40 + +/** + * Maximum number of listening TCP ports. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_LISTENPORTS 40 + +/** + * uIP buffer size. + * + * \hideinitializer + */ +#define UIP_CONF_BUFFER_SIZE 1480 + +/** + * CPU byte order. + * + * \hideinitializer + */ +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN + +/** + * Logging on or off + * + * \hideinitializer + */ +#define UIP_CONF_LOGGING 0 + +/** + * UDP support on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP 0 + +/** + * UDP checksums on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP_CHECKSUMS 1 + +/** + * uIP statistics on or off + * + * \hideinitializer + */ +#define UIP_CONF_STATISTICS 1 + +/* Here we include the header file for the application(s) we use in + our project. */ +/*#include "smtp.h"*/ +/*#include "hello-world.h"*/ +/*#include "telnetd.h"*/ +#include "webserver.h" +/*#include "dhcpc.h"*/ +/*#include "resolv.h"*/ +/*#include "webclient.h"*/ + +#endif /* __UIP_CONF_H__ */ + +/** @} */ +/** @} */ diff --git a/Demo/CORTEX_LPC1768_IAR/webserver/webserver.h b/Demo/CORTEX_LPC1768_IAR/webserver/webserver.h new file mode 100644 index 000000000..1acb290b8 --- /dev/null +++ b/Demo/CORTEX_LPC1768_IAR/webserver/webserver.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ +#ifndef __WEBSERVER_H__ +#define __WEBSERVER_H__ + +#include "httpd.h" + +typedef struct httpd_state uip_tcp_appstate_t; +/* UIP_APPCALL: the name of the application function. This function + must return void and take no arguments (i.e., C type "void + appfunc(void)"). */ +#ifndef UIP_APPCALL +#define UIP_APPCALL httpd_appcall +#endif + + +#endif /* __WEBSERVER_H__ */ -- 2.39.5
LocalRemoteStateRetransmissionsTimerFlags