Add FreeRTOS-Plus directory.

This commit is contained in:
Richard Barry 2012-08-11 21:34:11 +00:00
parent 7bd5f21ad5
commit f508a5f653
6798 changed files with 134949 additions and 19 deletions

View file

@ -0,0 +1,117 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include <lpc210x.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.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 58982400 ) /* =14.7456MHz xtal multiplied by 4 using the PLL. */
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 23 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* 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
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,120 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
/* Application includes. */
#include "tcp.h"
/* Misc constants. */
#define tcpPOLL_DELAY ( ( portTickType ) 12 / portTICK_RATE_MS )
#define tcpCONNECTION_DELAY ( ( portTickType ) 8 / portTICK_RATE_MS )
/*-----------------------------------------------------------*/
/*
* This task initialises the hardware then processes one TCP connection at a
* time. When an HTTP client connects we just simply send a single page then
* disconnect - reset the socket data and wait for the next connection.
*/
void vHTTPServerTask( void *pvParameters )
{
/* Reset the network hardware. */
vTCPHardReset();
/* Loop, processing connections are they arrive. */
for( ;; )
{
/* Initialise the TCP interface.
The current minimal implementation does not check for buffer overflows
in the WIZnet hardware, so simply resets all the buffers for each
connection - and only processes one connection at a time. */
if( lTCPSoftReset() )
{
/* Create the socket that is going to accept incoming connections. */
if( lTCPCreateSocket() )
{
/* Wait for a connection. */
vTCPListen();
/* Process connections as they arrive. This function will only
return once the connection has been closed. */
lProcessConnection();
}
}
/* If we get here then the connection completed or failed. Wait a
while then try or start again. */
vTaskDelay( tcpCONNECTION_DELAY );
}
}

View file

@ -0,0 +1,72 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef HTTP_H
#define HTTP_H
void vHTTPServerTask( void *pvParameters );
#endif

View file

@ -0,0 +1,139 @@
#/*
# FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
#
#
# ***************************************************************************
# * *
# * FreeRTOS tutorial books are available in pdf and paperback. *
# * Complete, revised, and edited pdf reference manuals are also *
# * available. *
# * *
# * Purchasing FreeRTOS documentation will not only help you, by *
# * ensuring you get running as quickly as possible and with an *
# * in-depth knowledge of how to use FreeRTOS, it will also help *
# * the FreeRTOS project to continue with its mission of providing *
# * professional grade, cross platform, de facto standard solutions *
# * for microcontrollers - completely free of charge! *
# * *
# * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
# * *
# * Thank you for using FreeRTOS, and thank you for your support! *
# * *
# ***************************************************************************
#
#
# This file is part of the FreeRTOS distribution.
#
# FreeRTOS is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License (version 2) as published by the
# Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
# >>>NOTE<<< The modification to the GPL is included to allow you to
# distribute a combined work that includes FreeRTOS without being obliged to
# provide the source code for proprietary components outside of the FreeRTOS
# kernel. FreeRTOS is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. You should have received a copy of the GNU General Public
# License and the FreeRTOS license exception along with FreeRTOS; if not it
# can be viewed here: http://www.freertos.org/a00114.html and also obtained
# by writing to Richard Barry, contact details for whom are available on the
# FreeRTOS WEB site.
#
# 1 tab == 4 spaces!
#
# http://www.FreeRTOS.org - Documentation, latest information, license and
# contact details.
#
# http://www.SafeRTOS.com - A version that is certified for use in safety
# critical systems.
#
# http://www.OpenRTOS.com - Commercial support, development, porting,
# licensing and training services.
#*/
CC=arm-elf-gcc
OBJCOPY=arm-elf-objcopy
ARCH=arm-elf-ar
CRT0=boot.s
USE_THUMB_MODE=YES
DEBUG=-g
OPTIM=-Os
RUN_MODE=RUN_FROM_ROM
LDSCRIPT=lpc2106-rom.ld
#
# CFLAGS common to both the THUMB and ARM mode builds
#
CFLAGS=-Wall -D $(RUN_MODE) -D GCC_ARM7 -I. -I../../Source/include \
-I../Common/include $(DEBUG) -mcpu=arm7tdmi -T$(LDSCRIPT) \
-Wcast-align $(OPTIM) -fomit-frame-pointer
ifeq ($(USE_THUMB_MODE),YES)
CFLAGS += -mthumb-interwork -D THUMB_INTERWORK
THUMB_FLAGS=-mthumb
endif
LINKER_FLAGS=-Xlinker -oWebServeDemo.elf -Xlinker -M -Xlinker -Map=WebServeDemo.map
#
# Source files that can be built to THUMB mode.
#
THUMB_SRC = \
../../Source/tasks.c \
../../Source/queue.c \
../../Source/list.c \
../../Source/portable/MemMang/heap_2.c \
../../Source/portable/GCC/ARM7_LPC2000/port.c \
../Common/Minimal/flash.c \
../Common/Minimal/dynamic.c \
../Common/Minimal/semtest.c \
../Common/Minimal/PollQ.c \
../Common/Minimal/BlockQ.c \
../Common/Minimal/integer.c \
../ARM7_LPC2106_GCC/ParTest/ParTest.c \
main.c \
TCP.c \
HTTP_Serv.c \
i2c.c
#
# Source files that must be built to ARM mode.
#
ARM_SRC = \
../../Source/portable/GCC/ARM7_LPC2000/portISR.c \
i2cISR.c \
TCPISR.c
#
# Define all object files.
#
ARM_OBJ = $(ARM_SRC:.c=.o)
THUMB_OBJ = $(THUMB_SRC:.c=.o)
WebServeDemo.hex : WebServeDemo.elf
$(OBJCOPY) WebServeDemo.elf -O ihex WebServeDemo.hex
WebServeDemo.elf : $(ARM_OBJ) $(THUMB_OBJ) $(CRT0) Makefile
$(CC) $(CFLAGS) $(ARM_OBJ) $(THUMB_OBJ) -nostartfiles $(CRT0) $(LINKER_FLAGS)
$(THUMB_OBJ) : %.o : %.c $(LDSCRIPT) Makefile
$(CC) -c $(THUMB_FLAGS) $(CFLAGS) $< -o $@
$(ARM_OBJ) : %.o : %.c $(LDSCRIPT) Makefile
$(CC) -c $(CFLAGS) $< -o $@
clean :
touch makefile

View file

@ -0,0 +1,774 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/*
Changes from V3.2.3
+ Modified char* types to compile without warning when using GCC V4.0.1.
+ Corrected the address to which the MAC address is written. Thanks to
Bill Knight for this correction.
Changes from V3.2.4
+ Changed the default MAC address to something more realistic.
*/
/* Standard includes. */
#include <stdlib.h>
#include <string.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "tcp.h"
#include "serial.h"
/* Application includes. */
#include "i2c.h"
#include "html_pages.h"
/*-----------------------------------------------------------*/
/* Hardwired i2c address of the WIZNet device. */
#define tcpDEVICE_ADDRESS ( ( unsigned char ) 0x00 )
/* Constants used to configure the Tx and Rx buffer sizes within the WIZnet
device. */
#define tcp8K_RX ( ( unsigned char ) 0x03 )
#define tcp8K_TX ( ( unsigned char ) 0x03 )
/* Constants used to generate the WIZnet internal buffer addresses. */
#define tcpSINGLE_SOCKET_ADDR_MASK ( ( unsigned long ) 0x1fff )
#define tcpSINGLE_SOCKET_ADDR_OFFSET ( ( unsigned long ) 0x4000 )
/* Bit definitions of the commands that can be sent to the command register. */
#define tcpRESET_CMD ( ( unsigned char ) 0x80 )
#define tcpSYS_INIT_CMD ( ( unsigned char ) 0x01 )
#define tcpSOCK_STREAM ( ( unsigned char ) 0x01 )
#define tcpSOCK_INIT ( ( unsigned char ) 0x02 )
#define tcpLISTEN_CMD ( ( unsigned char ) 0x08 )
#define tcpRECEIVE_CMD ( ( unsigned char ) 0x40 )
#define tcpDISCONNECT_CMD ( ( unsigned char ) 0x10 )
#define tcpSEND_CMD ( ( unsigned char ) 0x20 )
/* Constants required to handle the interrupts. */
#define tcpCLEAR_EINT0 ( 1 )
#define i2cCLEAR_ALL_INTERRUPTS ( ( unsigned char ) 0xff )
#define i2cCHANNEL_0_ISR_ENABLE ( ( unsigned char ) 0x01 )
#define i2cCHANNEL_0_ISR_DISABLE ( ( unsigned char ) 0x00 )
#define tcpWAKE_ON_EINT0 ( 1 )
#define tcpENABLE_EINT0_FUNCTION ( ( unsigned long ) 0x01 )
#define tcpEINT0_VIC_CHANNEL_BIT ( ( unsigned long ) 0x4000 )
#define tcpEINT0_VIC_CHANNEL ( ( unsigned long ) 14 )
#define tcpEINT0_VIC_ENABLE ( ( unsigned long ) 0x0020 )
/* Various delays used in the driver. */
#define tcpRESET_DELAY ( ( portTickType ) 16 / portTICK_RATE_MS )
#define tcpINIT_DELAY ( ( portTickType ) 500 / portTICK_RATE_MS )
#define tcpLONG_DELAY ( ( portTickType ) 500 / portTICK_RATE_MS )
#define tcpSHORT_DELAY ( ( portTickType ) 5 / portTICK_RATE_MS )
#define tcpCONNECTION_WAIT_DELAY ( ( portTickType ) 100 / portTICK_RATE_MS )
#define tcpNO_DELAY ( ( portTickType ) 0 )
/* Length of the data to read for various register reads. */
#define tcpSTATUS_READ_LEN ( ( unsigned long ) 1 )
#define tcpSHADOW_READ_LEN ( ( unsigned long ) 1 )
/* Register addresses within the WIZnet device. */
#define tcpCOMMAND_REG ( ( unsigned short ) 0x0000 )
#define tcpGATEWAY_ADDR_REG ( ( unsigned short ) 0x0080 )
#define tcpSUBNET_MASK_REG ( ( unsigned short ) 0x0084 )
#define tcpSOURCE_HA_REG ( ( unsigned short ) 0x0088 )
#define tpcSOURCE_IP_REG ( ( unsigned short ) 0x008E )
#define tpcSOCKET_OPT_REG ( ( unsigned short ) 0x00A1 )
#define tcpSOURCE_PORT_REG ( ( unsigned short ) 0x00AE )
#define tcpTX_WRITE_POINTER_REG ( ( unsigned short ) 0x0040 )
#define tcpTX_READ_POINTER_REG ( ( unsigned short ) 0x0044 )
#define tcpTX_ACK_POINTER_REG ( ( unsigned short ) 0x0018 )
#define tcpTX_MEM_SIZE_REG ( ( unsigned short ) 0x0096 )
#define tcpRX_MEM_SIZE_REG ( ( unsigned short ) 0x0095 )
#define tcpINTERRUPT_STATUS_REG ( ( unsigned short ) 0x0004 )
#define tcpTX_WRITE_SHADOW_REG ( ( unsigned short ) 0x01F0 )
#define tcpTX_ACK_SHADOW_REG ( ( unsigned short ) 0x01E2 )
#define tcpISR_MASK_REG ( ( unsigned short ) 0x0009 )
#define tcpINTERRUPT_REG ( ( unsigned short ) 0x0008 )
#define tcpSOCKET_STATE_REG ( ( unsigned short ) 0x00a0 )
/* Constants required for hardware setup. */
#define tcpRESET_ACTIVE_LOW ( ( unsigned long ) 0x20 )
#define tcpRESET_ACTIVE_HIGH ( ( unsigned long ) 0x10 )
/* Constants defining the source of the WIZnet ISR. */
#define tcpISR_SYS_INIT ( ( unsigned char ) 0x01 )
#define tcpISR_SOCKET_INIT ( ( unsigned char ) 0x02 )
#define tcpISR_ESTABLISHED ( ( unsigned char ) 0x04 )
#define tcpISR_CLOSED ( ( unsigned char ) 0x08 )
#define tcpISR_TIMEOUT ( ( unsigned char ) 0x10 )
#define tcpISR_TX_COMPLETE ( ( unsigned char ) 0x20 )
#define tcpISR_RX_COMPLETE ( ( unsigned char ) 0x40 )
/* Constants defining the socket status bits. */
#define tcpSTATUS_ESTABLISHED ( ( unsigned char ) 0x06 )
#define tcpSTATUS_LISTEN ( ( unsigned char ) 0x02 )
/* Misc constants. */
#define tcpNO_STATUS_BITS ( ( unsigned char ) 0x00 )
#define i2cNO_ADDR_REQUIRED ( ( unsigned short ) 0x0000 )
#define i2cNO_DATA_REQUIRED ( 0x0000 )
#define tcpISR_QUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 10 )
#define tcpISR_QUEUE_ITEM_SIZE ( ( unsigned portBASE_TYPE ) 0 )
#define tcpBUFFER_LEN ( 4 * 1024 )
#define tcpMAX_REGISTER_LEN ( 4 )
#define tcpMAX_ATTEMPTS_TO_CHECK_BUFFER ( 6 )
#define tcpMAX_NON_LISTEN_STAUS_READS ( 5 )
/* Message definitions. The IP address, MAC address, gateway address, etc.
is set here! */
const unsigned char const ucDataGAR[] = { 172, 25, 218, 3 }; /* Gateway address. */
const unsigned char const ucDataMSR[] = { 255, 255, 255, 0 }; /* Subnet mask. */
const unsigned char const ucDataSIPR[] = { 172, 25, 218, 201 };/* IP address. */
const unsigned char const ucDataSHAR[] = { 00, 23, 30, 41, 15, 26 }; /* MAC address - DO NOT USE THIS ON A PUBLIC NETWORK! */
/* Other fixed messages. */
const unsigned char const ucDataReset[] = { tcpRESET_CMD };
const unsigned char const ucDataInit[] = { tcpSYS_INIT_CMD };
const unsigned char const ucDataProtocol[] = { tcpSOCK_STREAM };
const unsigned char const ucDataPort[] = { 0xBA, 0xCC };
const unsigned char const ucDataSockInit[] = { tcpSOCK_INIT };
const unsigned char const ucDataTxWritePointer[] = { 0x11, 0x22, 0x00, 0x00 };
const unsigned char const ucDataTxAckPointer[] = { 0x11, 0x22, 0x00, 0x00 };
const unsigned char const ucDataTxReadPointer[] = { 0x11, 0x22, 0x00, 0x00 };
const unsigned char const ucDataListen[] = { tcpLISTEN_CMD };
const unsigned char const ucDataReceiveCmd[] = { tcpRECEIVE_CMD };
const unsigned char const ucDataSetTxBufSize[] = { tcp8K_TX };
const unsigned char const ucDataSetRxBufSize[] = { tcp8K_RX };
const unsigned char const ucDataSend[] = { tcpSEND_CMD };
const unsigned char const ucDataDisconnect[] = { tcpDISCONNECT_CMD };
const unsigned char const ucDataEnableISR[] = { i2cCHANNEL_0_ISR_ENABLE };
const unsigned char const ucDataDisableISR[] = { i2cCHANNEL_0_ISR_DISABLE };
const unsigned char const ucDataClearInterrupt[] = { i2cCLEAR_ALL_INTERRUPTS };
static xSemaphoreHandle xMessageComplete = NULL;
xQueueHandle xTCPISRQueue = NULL;
/* Dynamically generate and send an html page. */
static void prvSendSamplePage( void );
/* Read a register from the WIZnet device via the i2c interface. */
static void prvReadRegister( unsigned char *pucDestination, unsigned short usAddress, unsigned long ulLength );
/* Send the entire Tx buffer (the Tx buffer within the WIZnet device). */
static void prvFlushBuffer( unsigned long ulTxAddress );
/* Write a string to the WIZnet Tx buffer. */
static void prvWriteString( const char * const pucTxBuffer, long lTxLen, unsigned long *pulTxAddress );
/* Convert a number to a string. */
void ultoa( unsigned long ulVal, char *pcBuffer, long lIgnore );
/*-----------------------------------------------------------*/
void ultoa( unsigned long ulVal, char *pcBuffer, long lIgnore )
{
unsigned long lNibble;
long lIndex;
/* Simple routine to convert an unsigned long value into a string in hex
format. */
/* For each nibble in the number we are converting. */
for( lIndex = 0; lIndex < ( sizeof( ulVal ) * 2 ); lIndex++ )
{
/* Take the top four bits of the number. */
lNibble = ( ulVal >> 28 );
/* We are converting it to a hex string, so is the number in the range
0-10 or A-F? */
if( lNibble < 10 )
{
pcBuffer[ lIndex ] = '0' + lNibble;
}
else
{
lNibble -= 10;
pcBuffer[ lIndex ] = 'A' + lNibble;
}
/* Shift off the top nibble so we use the next nibble next time around. */
ulVal <<= 4;
}
/* Mark the end of the string with a null terminator. */
pcBuffer[ lIndex ] = 0x00;
}
/*-----------------------------------------------------------*/
static void prvReadRegister( unsigned char *pucDestination, unsigned short usAddress, unsigned long ulLength )
{
unsigned char ucRxBuffer[ tcpMAX_REGISTER_LEN ];
/* Read a register value from the WIZnet device. */
/* First write out the address of the register we want to read. */
i2cMessage( ucRxBuffer, i2cNO_DATA_REQUIRED, tcpDEVICE_ADDRESS, usAddress, i2cWRITE, NULL, portMAX_DELAY );
/* Then read back from that address. */
i2cMessage( ( unsigned char * ) pucDestination, ulLength, tcpDEVICE_ADDRESS, i2cNO_ADDR_REQUIRED, i2cREAD, xMessageComplete, portMAX_DELAY );
/* I2C messages are queued so use the semaphore to wait for the read to
complete - otherwise we will leave this function before the I2C
transactions have completed. */
xSemaphoreTake( xMessageComplete, tcpLONG_DELAY );
}
/*-----------------------------------------------------------*/
void vTCPHardReset( void )
{
/* Physical reset of the WIZnet device by using the GPIO lines to hold the
WIZnet reset lines active for a few milliseconds. */
/* Make sure the interrupt from the WIZnet is disabled. */
VICIntEnClear |= tcpEINT0_VIC_CHANNEL_BIT;
/* If xMessageComplete is NULL then this is the first time that this
function has been called and the queue and semaphore used in this file
have not yet been created. */
if( xMessageComplete == NULL )
{
/* Create and obtain the semaphore used when we want to wait for an i2c
message to be completed. */
vSemaphoreCreateBinary( xMessageComplete );
xSemaphoreTake( xMessageComplete, tcpNO_DELAY );
/* Create the queue used to communicate between the WIZnet and TCP tasks. */
xTCPISRQueue = xQueueCreate( tcpISR_QUEUE_LENGTH, tcpISR_QUEUE_ITEM_SIZE );
}
/* Use the GPIO to reset the network hardware. */
GPIO_IOCLR = tcpRESET_ACTIVE_LOW;
GPIO_IOSET = tcpRESET_ACTIVE_HIGH;
/* Delay with the network hardware in reset for a short while. */
vTaskDelay( tcpRESET_DELAY );
GPIO_IOCLR = tcpRESET_ACTIVE_HIGH;
GPIO_IOSET = tcpRESET_ACTIVE_LOW;
vTaskDelay( tcpINIT_DELAY );
/* Setup the EINT0 to interrupt on required events from the WIZnet device.
First enable the EINT0 function of the pin. */
PCB_PINSEL1 |= tcpENABLE_EINT0_FUNCTION;
/* We want the TCP comms to wake us from power save. */
SCB_EXTWAKE = tcpWAKE_ON_EINT0;
/* Install the ISR into the VIC - but don't enable it yet! */
portENTER_CRITICAL();
{
extern void ( vEINT0_ISR_Wrapper )( void );
VICIntSelect &= ~( tcpEINT0_VIC_CHANNEL_BIT );
VICVectAddr3 = ( long ) vEINT0_ISR_Wrapper;
VICVectCntl3 = tcpEINT0_VIC_CHANNEL | tcpEINT0_VIC_ENABLE;
}
portEXIT_CRITICAL();
/* Enable interrupts in the WIZnet itself. */
i2cMessage( ucDataEnableISR, sizeof( ucDataEnableISR ), tcpDEVICE_ADDRESS, tcpISR_MASK_REG, i2cWRITE, NULL, portMAX_DELAY );
vTaskDelay( tcpLONG_DELAY );
}
/*-----------------------------------------------------------*/
long lTCPSoftReset( void )
{
unsigned char ucStatus;
extern volatile long lTransactionCompleted;
/* Send a message to the WIZnet device to tell it set all it's registers
back to their default states. Then setup the WIZnet device as required. */
/* Reset the internal WIZnet registers. */
i2cMessage( ucDataReset, sizeof( ucDataReset ), tcpDEVICE_ADDRESS, tcpCOMMAND_REG, i2cWRITE, NULL, portMAX_DELAY );
/* Now we can configure the protocol. Here the MAC address, gateway
address, subnet mask and IP address are configured. */
i2cMessage( ucDataSHAR, sizeof( ucDataSHAR ), tcpDEVICE_ADDRESS, tcpSOURCE_HA_REG, i2cWRITE, NULL, portMAX_DELAY );
i2cMessage( ucDataGAR, sizeof( ucDataGAR ), tcpDEVICE_ADDRESS, tcpGATEWAY_ADDR_REG, i2cWRITE, NULL, portMAX_DELAY );
i2cMessage( ucDataMSR, sizeof( ucDataMSR ), tcpDEVICE_ADDRESS, tcpSUBNET_MASK_REG, i2cWRITE, NULL, portMAX_DELAY );
i2cMessage( ucDataSIPR, sizeof( ucDataSIPR ), tcpDEVICE_ADDRESS, tpcSOURCE_IP_REG, i2cWRITE, NULL, portMAX_DELAY );
/* Next the memory buffers are configured to give all the WIZnet internal
memory over to a single socket. This gives the socket the maximum internal
Tx and Rx buffer space. */
i2cMessage( ucDataSetTxBufSize, sizeof( ucDataSetTxBufSize ), tcpDEVICE_ADDRESS, tcpTX_MEM_SIZE_REG, i2cWRITE, NULL, portMAX_DELAY );
i2cMessage( ucDataSetRxBufSize, sizeof( ucDataSetRxBufSize ), tcpDEVICE_ADDRESS, tcpRX_MEM_SIZE_REG, i2cWRITE, NULL, portMAX_DELAY );
/* Send the sys init command so the above parameters take effect. */
i2cMessage( ucDataInit, sizeof( ucDataInit ), tcpDEVICE_ADDRESS, tcpCOMMAND_REG, i2cWRITE, NULL, portMAX_DELAY );
/* Seems to like a little wait here. */
vTaskDelay( tcpINIT_DELAY );
/* Read back the status to ensure the system initialised ok. */
prvReadRegister( &ucStatus, tcpINTERRUPT_STATUS_REG, tcpSTATUS_READ_LEN );
/* We should find that the sys init was successful. */
if( ucStatus != tcpISR_SYS_INIT )
{
return ( long ) pdFAIL;
}
/* No i2c errors yet. */
portENTER_CRITICAL();
lTransactionCompleted = pdTRUE;
portEXIT_CRITICAL();
return ( long ) pdPASS;
}
/*-----------------------------------------------------------*/
long lTCPCreateSocket( void )
{
unsigned char ucStatus;
/* Create and configure a socket. */
/* Setup and init the socket. Here the port number is set and the socket
is initialised. */
i2cMessage( ucDataProtocol, sizeof( ucDataProtocol),tcpDEVICE_ADDRESS, tpcSOCKET_OPT_REG, i2cWRITE, NULL, portMAX_DELAY );
i2cMessage( ucDataPort, sizeof( ucDataPort), tcpDEVICE_ADDRESS, tcpSOURCE_PORT_REG, i2cWRITE, NULL, portMAX_DELAY );
i2cMessage( ucDataSockInit, sizeof( ucDataSockInit),tcpDEVICE_ADDRESS, tcpCOMMAND_REG, i2cWRITE, xMessageComplete, portMAX_DELAY );
/* Wait for the Init command to be sent. */
if( !xSemaphoreTake( xMessageComplete, tcpLONG_DELAY ) )
{
/* For some reason the message was not transmitted within our block
period. */
return ( long ) pdFAIL;
}
/* Allow the socket to initialise. */
vTaskDelay( tcpINIT_DELAY );
/* Read back the status to ensure the socket initialised ok. */
prvReadRegister( &ucStatus, tcpINTERRUPT_STATUS_REG, tcpSTATUS_READ_LEN );
/* We should find that the socket init was successful. */
if( ucStatus != tcpISR_SOCKET_INIT )
{
return ( long ) pdFAIL;
}
/* Setup the Tx pointer registers to indicate that the Tx buffer is empty. */
i2cMessage( ucDataTxReadPointer, sizeof( ucDataTxReadPointer ), tcpDEVICE_ADDRESS, tcpTX_READ_POINTER_REG, i2cWRITE, NULL, portMAX_DELAY );
vTaskDelay( tcpSHORT_DELAY );
i2cMessage( ucDataTxWritePointer, sizeof( ucDataTxWritePointer ), tcpDEVICE_ADDRESS, tcpTX_WRITE_POINTER_REG, i2cWRITE, NULL, portMAX_DELAY );
vTaskDelay( tcpSHORT_DELAY );
i2cMessage( ucDataTxAckPointer, sizeof( ucDataTxAckPointer ), tcpDEVICE_ADDRESS, tcpTX_ACK_POINTER_REG, i2cWRITE, NULL, portMAX_DELAY );
vTaskDelay( tcpSHORT_DELAY );
return ( long ) pdPASS;
}
/*-----------------------------------------------------------*/
void vTCPListen( void )
{
unsigned char ucISR;
/* Start a passive listen on the socket. */
/* Enable interrupts in the WizNet device after ensuring none are
currently pending. */
while( SCB_EXTINT & tcpCLEAR_EINT0 )
{
/* The WIZnet device is still asserting and interrupt so tell it to
clear. */
i2cMessage( ucDataClearInterrupt, sizeof( ucDataClearInterrupt ), tcpDEVICE_ADDRESS, tcpINTERRUPT_REG, i2cWRITE, xMessageComplete, portMAX_DELAY );
xSemaphoreTake( xMessageComplete, tcpLONG_DELAY );
vTaskDelay( 1 );
SCB_EXTINT = tcpCLEAR_EINT0;
}
while( xQueueReceive( xTCPISRQueue, &ucISR, tcpNO_DELAY ) )
{
/* Just clearing the queue used by the ISR routine to tell this task
that the WIZnet device needs attention. */
}
/* Now all the pending interrupts have been cleared we can enable the
processor interrupts. */
VICIntEnable |= tcpEINT0_VIC_CHANNEL_BIT;
/* Then start listening for incoming connections. */
i2cMessage( ucDataListen, sizeof( ucDataListen ), tcpDEVICE_ADDRESS, tcpCOMMAND_REG, i2cWRITE, NULL, portMAX_DELAY );
}
/*-----------------------------------------------------------*/
long lProcessConnection( void )
{
unsigned char ucISR, ucState, ucLastState = 2, ucShadow;
extern volatile long lTransactionCompleted;
long lSameStateCount = 0, lDataSent = pdFALSE;
unsigned long ulWritePointer, ulAckPointer;
/* No I2C errors can yet have occurred. */
portENTER_CRITICAL();
lTransactionCompleted = pdTRUE;
portEXIT_CRITICAL();
/* Keep looping - processing interrupts, until we have completed a
transaction. This uses the WIZnet in it's simplest form. The socket
accepts a connection - we process the connection - then close the socket.
We then go back to reinitialise everything and start again. */
while( lTransactionCompleted == pdTRUE )
{
/* Wait for a message on the queue from the WIZnet ISR. When the
WIZnet device asserts an interrupt the ISR simply posts a message
onto this queue to wake this task. */
if( xQueueReceive( xTCPISRQueue, &ucISR, tcpCONNECTION_WAIT_DELAY ) )
{
/* The ISR posted a message on this queue to tell us that the
WIZnet device asserted an interrupt. The ISR cannot process
an I2C message so cannot tell us what caused the interrupt so
we have to query the device here. This task is the highest
priority in the system so will run immediately following the ISR. */
prvReadRegister( &ucISR, tcpINTERRUPT_STATUS_REG, tcpSTATUS_READ_LEN );
/* Once we have read what caused the ISR we can clear the interrupt
in the WIZnet. */
i2cMessage( ucDataClearInterrupt, sizeof( ucDataClearInterrupt ), tcpDEVICE_ADDRESS, tcpINTERRUPT_REG, i2cWRITE, NULL, portMAX_DELAY );
/* Now we can clear the processor interrupt and re-enable ready for
the next. */
SCB_EXTINT = tcpCLEAR_EINT0;
VICIntEnable |= tcpEINT0_VIC_CHANNEL_BIT;
/* Process the interrupt ... */
if( ucISR & tcpISR_ESTABLISHED )
{
/* A connection has been established - respond by sending
a receive command. */
i2cMessage( ucDataReceiveCmd, sizeof( ucDataReceiveCmd ), tcpDEVICE_ADDRESS, tcpCOMMAND_REG, i2cWRITE, NULL, portMAX_DELAY );
}
if( ucISR & tcpISR_RX_COMPLETE )
{
/* We message has been received. This will be an HTTP get
command. We only have one page to send so just send it without
regard to what the actual requested page was. */
prvSendSamplePage();
}
if( ucISR & tcpISR_TX_COMPLETE )
{
/* We have a TX complete interrupt - which oddly does not
indicate that the message being sent is complete so we cannot
yet close the socket. Instead we read the position of the Tx
pointer within the WIZnet device so we know how much data it
has to send. Later we will read the ack pointer and compare
this to the Tx pointer to ascertain whether the transmission
has completed. */
/* First read the shadow register. */
prvReadRegister( &ucShadow, tcpTX_WRITE_SHADOW_REG, tcpSHADOW_READ_LEN );
/* Now a short delay is required. */
vTaskDelay( tcpSHORT_DELAY );
/* Then we can read the real register. */
prvReadRegister( ( unsigned char * ) &ulWritePointer, tcpTX_WRITE_POINTER_REG, sizeof( ulWritePointer ) );
/* We cannot do anything more here but need to remember that
this interrupt has occurred. */
lDataSent = pdTRUE;
}
if( ucISR & tcpISR_CLOSED )
{
/* The socket has been closed so we can leave this function. */
lTransactionCompleted = pdFALSE;
}
}
else
{
/* We have not received an interrupt from the WIZnet device for a
while. Read the socket status and check that everything is as
expected. */
prvReadRegister( &ucState, tcpSOCKET_STATE_REG, tcpSTATUS_READ_LEN );
if( ( ucState == tcpSTATUS_ESTABLISHED ) && ( lDataSent > 0 ) )
{
/* The socket is established and we have already received a Tx
end interrupt. We must therefore be waiting for the Tx buffer
inside the WIZnet device to be empty before we can close the
socket.
Read the Ack pointer register to see if it has caught up with
the Tx pointer register. First we have to read the shadow
register. */
prvReadRegister( &ucShadow, tcpTX_ACK_SHADOW_REG, tcpSHADOW_READ_LEN );
vTaskDelay( tcpSHORT_DELAY );
prvReadRegister( ( unsigned char * ) &ulAckPointer, tcpTX_ACK_POINTER_REG, sizeof( ulWritePointer ) );
if( ulAckPointer == ulWritePointer )
{
/* The Ack and write pointer are now equal and we can
safely close the socket. */
i2cMessage( ucDataDisconnect, sizeof( ucDataDisconnect ), tcpDEVICE_ADDRESS, tcpCOMMAND_REG, i2cWRITE, NULL, portMAX_DELAY );
}
else
{
/* Keep a count of how many times we encounter the Tx
buffer still containing data. */
lDataSent++;
if( lDataSent > tcpMAX_ATTEMPTS_TO_CHECK_BUFFER )
{
/* Assume we cannot complete sending the data and
therefore cannot safely close the socket. Start over. */
vTCPHardReset();
lTransactionCompleted = pdFALSE;
}
}
}
else if( ucState != tcpSTATUS_LISTEN )
{
/* If we have not yet received a Tx end interrupt we would only
ever expect to find the socket still listening for any
sustained period. */
if( ucState == ucLastState )
{
lSameStateCount++;
if( lSameStateCount > tcpMAX_NON_LISTEN_STAUS_READS )
{
/* We are persistently in an unexpected state. Assume
we cannot safely close the socket and start over. */
vTCPHardReset();
lTransactionCompleted = pdFALSE;
}
}
}
else
{
/* We are in the listen state so are happy that everything
is as expected. */
lSameStateCount = 0;
}
/* Remember what state we are in this time around so we can check
for a persistence on an unexpected state. */
ucLastState = ucState;
}
}
/* We are going to reinitialise the WIZnet device so do not want our
interrupts from the WIZnet to be processed. */
VICIntEnClear |= tcpEINT0_VIC_CHANNEL_BIT;
return lTransactionCompleted;
}
/*-----------------------------------------------------------*/
static void prvWriteString( const char * const pucTxBuffer, long lTxLen, unsigned long *pulTxAddress )
{
unsigned long ulSendAddress;
/* Send a string to the Tx buffer internal to the WIZnet device. */
/* Calculate the address to which we are going to write in the buffer. */
ulSendAddress = ( *pulTxAddress & tcpSINGLE_SOCKET_ADDR_MASK ) + tcpSINGLE_SOCKET_ADDR_OFFSET;
/* Send the buffer to the calculated address. Use the semaphore so we
can wait until the entire message has been transferred. */
i2cMessage( ( unsigned char * ) pucTxBuffer, lTxLen, tcpDEVICE_ADDRESS, ( unsigned short ) ulSendAddress, i2cWRITE, xMessageComplete, portMAX_DELAY );
/* Wait until the semaphore indicates that the message has been transferred. */
if( !xSemaphoreTake( xMessageComplete, tcpLONG_DELAY ) )
{
return;
}
/* Return the new address of the end of the buffer (within the WIZnet
device). */
*pulTxAddress += ( unsigned long ) lTxLen;
}
/*-----------------------------------------------------------*/
static void prvFlushBuffer( unsigned long ulTxAddress )
{
unsigned char ucTxBuffer[ tcpMAX_REGISTER_LEN ];
/* We have written some data to the Tx buffer internal to the WIZnet
device. Now we update the Tx pointer inside the WIZnet then send a
Send command - which causes the data up to the new Tx pointer to be
transmitted. */
/* Make sure endieness is correct for transmission. */
ulTxAddress = htonl( ulTxAddress );
/* Place the new Tx pointer in the string to be transmitted. */
ucTxBuffer[ 0 ] = ( unsigned char ) ( ulTxAddress & 0xff );
ulTxAddress >>= 8;
ucTxBuffer[ 1 ] = ( unsigned char ) ( ulTxAddress & 0xff );
ulTxAddress >>= 8;
ucTxBuffer[ 2 ] = ( unsigned char ) ( ulTxAddress & 0xff );
ulTxAddress >>= 8;
ucTxBuffer[ 3 ] = ( unsigned char ) ( ulTxAddress & 0xff );
ulTxAddress >>= 8;
/* And send it to the WIZnet device. */
i2cMessage( ucTxBuffer, sizeof( ulTxAddress ), tcpDEVICE_ADDRESS, tcpTX_WRITE_POINTER_REG, i2cWRITE, xMessageComplete, portMAX_DELAY );
if( !xSemaphoreTake( xMessageComplete, tcpLONG_DELAY ) )
{
return;
}
vTaskDelay( tcpSHORT_DELAY );
/* Transmit! */
i2cMessage( ucDataSend, sizeof( ucDataSend ), tcpDEVICE_ADDRESS, tcpCOMMAND_REG, i2cWRITE, xMessageComplete, portMAX_DELAY );
if( !xSemaphoreTake( xMessageComplete, tcpLONG_DELAY ) )
{
return;
}
}
/*-----------------------------------------------------------*/
static void prvSendSamplePage( void )
{
extern long lErrorInTask;
unsigned long ulTxAddress;
unsigned char ucShadow;
long lIndex;
static unsigned long ulRefreshCount = 0x00;
static char cPageBuffer[ tcpBUFFER_LEN ];
/* This function just generates a sample page of HTML which gets
sent each time a client attaches to the socket. The page is created
from two fixed strings (cSamplePageFirstPart and cSamplePageSecondPart)
with a bit of dynamically generated data in the middle. */
/* We need to know the address to which the html string should be sent
in the WIZnet Tx buffer. First read the shadow register. */
prvReadRegister( &ucShadow, tcpTX_WRITE_SHADOW_REG, tcpSHADOW_READ_LEN );
/* Now a short delay is required. */
vTaskDelay( tcpSHORT_DELAY );
/* Now we can read the real pointer value. */
prvReadRegister( ( unsigned char * ) &ulTxAddress, tcpTX_WRITE_POINTER_REG, sizeof( ulTxAddress ) );
/* Make sure endieness is correct. */
ulTxAddress = htonl( ulTxAddress );
/* Send the start of the page. */
prvWriteString( cSamplePageFirstPart, strlen( cSamplePageFirstPart ), &ulTxAddress );
/* Generate a bit of dynamic data and place it in the buffer ready to be
transmitted. */
strcpy( cPageBuffer, "<BR>Number of ticks since boot = 0x" );
lIndex = strlen( cPageBuffer );
ultoa( xTaskGetTickCount(), &( cPageBuffer[ lIndex ] ), 0 );
strcat( cPageBuffer, "<br>Number of tasks executing = ");
lIndex = strlen( cPageBuffer );
ultoa( ( unsigned long ) uxTaskGetNumberOfTasks(), &( cPageBuffer[ lIndex ] ), 0 );
strcat( cPageBuffer, "<br>IO port 0 state (used by flash tasks) = 0x" );
lIndex = strlen( cPageBuffer );
ultoa( ( unsigned long ) GPIO0_IOPIN, &( cPageBuffer[ lIndex ] ), 0 );
strcat( cPageBuffer, "<br>Refresh = 0x" );
lIndex = strlen( cPageBuffer );
ultoa( ( unsigned long ) ulRefreshCount, &( cPageBuffer[ lIndex ] ), 0 );
if( lErrorInTask )
{
strcat( cPageBuffer, "<p>An error has occurred in at least one task." );
}
else
{
strcat( cPageBuffer, "<p>All tasks executing without error." );
}
ulRefreshCount++;
/* Send the dynamically generated string. */
prvWriteString( cPageBuffer, strlen( cPageBuffer ), &ulTxAddress );
/* Finish the page. */
prvWriteString( cSamplePageSecondPart, strlen( cSamplePageSecondPart ), &ulTxAddress );
/* Tell the WIZnet to send the data we have just written to its Tx buffer. */
prvFlushBuffer( ulTxAddress );
}

View file

@ -0,0 +1,79 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef TCP_H
#define TCP_H
#define htonl(A) ((((A) & 0xff000000) >> 24) | (((A) & 0x00ff0000) >> 8) | (((A) & 0x0000ff00) << 8) | (((A) & 0x000000ff) << 24))
void vTCPHardReset( void );
long lTCPSoftReset( void );
long lTCPCreateSocket( void );
long lTCPListen( void );
long lProcessConnection( void );
void vTCPListen( void );
#endif

View file

@ -0,0 +1,129 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Constants required for interrupt management. */
#define tcpCLEAR_VIC_INTERRUPT ( 0 )
#define tcpEINT0_VIC_CHANNEL_BIT ( ( unsigned long ) 0x4000 )
/* EINT0 interrupt handler. This processes interrupts from the WIZnet device. */
void vEINT0_ISR_Wrapper( void ) __attribute__((naked));
/* The handler that goes with the EINT0 wrapper. */
void vEINT0_ISR_Handler( void );
/* Variable is required for its address, but does not otherwise get used. */
static long lDummyVariable;
/*
* When the WIZnet device asserts an interrupt we send an (empty) message to
* the TCP task. This wakes the task so the interrupt can be processed. The
* source of the interrupt has to be ascertained by the TCP task as this
* requires an I2C transaction which cannot be performed from this ISR.
* Note this code predates the introduction of semaphores, a semaphore should
* be used in place of the empty queue message.
*/
void vEINT0_ISR_Handler( void )
{
extern xQueueHandle xTCPISRQueue;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Just wake the TCP task so it knows an ISR has occurred. */
xQueueSendFromISR( xTCPISRQueue, ( void * ) &lDummyVariable, &xHigherPriorityTaskWoken );
/* We cannot carry on processing interrupts until the TCP task has
processed this one - so for now interrupts are disabled. The TCP task will
re-enable it. */
VICIntEnClear |= tcpEINT0_VIC_CHANNEL_BIT;
/* Clear the interrupt bit. */
VICVectAddr = tcpCLEAR_VIC_INTERRUPT;
if( xHigherPriorityTaskWoken )
{
portYIELD_FROM_ISR();
}
}
/*-----------------------------------------------------------*/
void vEINT0_ISR_Wrapper( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* The handler must be a separate function from the wrapper to
ensure the correct stack frame is set up. */
vEINT0_ISR_Handler();
/* Restore the context of whichever task is going to run next. */
portRESTORE_CONTEXT();
}

View file

@ -0,0 +1,157 @@
/* Sample initialization file */
.extern main
.extern exit
.text
.code 32
.align 0
.extern __bss_beg__
.extern __bss_end__
.extern __stack_end__
.extern __data_beg__
.extern __data_end__
.extern __data+beg_src__
.global start
.global endless_loop
/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000004
.set ABT_STACK_SIZE, 0x00000004
.set FIQ_STACK_SIZE, 0x00000004
.set IRQ_STACK_SIZE, 0X00000400
.set SVC_STACK_SIZE, 0x00000400
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
.set MODE_USR, 0x10 /* User Mode */
.set MODE_FIQ, 0x11 /* FIQ Mode */
.set MODE_IRQ, 0x12 /* IRQ Mode */
.set MODE_SVC, 0x13 /* Supervisor Mode */
.set MODE_ABT, 0x17 /* Abort Mode */
.set MODE_UND, 0x1B /* Undefined Mode */
.set MODE_SYS, 0x1F /* System Mode */
.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
start:
_start:
_mainCRTStartup:
/* Setup a stack for each mode - note that this only sets up a usable stack
for system/user, SWI and IRQ modes. Also each mode is setup with
interrupts initially disabled. */
ldr r0, .LC6
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */
mov sp, r0
/* We want to start in supervisor mode. Operation will switch to system
mode when the first task starts. */
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT
/* Clear BSS. */
mov a2, #0 /* Fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */
ldr r1, .LC1 /* Start of memory block */
ldr r3, .LC2 /* End of memory block */
subs r3, r3, r1 /* Length of block */
beq .end_clear_loop
mov r2, #0
.clear_loop:
strb r2, [r1], #1
subs r3, r3, #1
bgt .clear_loop
.end_clear_loop:
/* Initialise data. */
ldr r1, .LC3 /* Start of memory block */
ldr r2, .LC4 /* End of memory block */
ldr r3, .LC5
subs r3, r3, r1 /* Length of block */
beq .end_set_loop
.set_loop:
ldrb r4, [r2], #1
strb r4, [r1], #1
subs r3, r3, #1
bgt .set_loop
.end_set_loop:
mov r0, #0 /* no arguments */
mov r1, #0 /* no argv either */
bl main
endless_loop:
b endless_loop
.align 0
.LC1:
.word __bss_beg__
.LC2:
.word __bss_end__
.LC3:
.word __data_beg__
.LC4:
.word __data_beg_src__
.LC5:
.word __data_end__
.LC6:
.word __stack_end__
/* Setup vector table. Note that undf, pabt, dabt, fiq just execute
a null loop. */
.section .startup,"ax"
.code 32
.align 0
b _start /* reset - _start */
ldr pc, _undf /* undefined - _undf */
ldr pc, _swi /* SWI - _swi */
ldr pc, _pabt /* program abort - _pabt */
ldr pc, _dabt /* data abort - _dabt */
nop /* reserved */
ldr pc, [pc,#-0xFF0] /* IRQ - read the VIC */
ldr pc, _fiq /* FIQ - _fiq */
_undf: .word __undf /* undefined */
_swi: .word vPortYieldProcessor /* SWI */
_pabt: .word __pabt /* program abort */
_dabt: .word __dabt /* data abort */
_fiq: .word __fiq /* FIQ */
__undf: b . /* undefined */
__pabt: b . /* program abort */
__dabt: b . /* data abort */
__fiq: b . /* FIQ */

View file

@ -0,0 +1,100 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef HTML_PAGES_H
#define HTML_PAGES_H
/* Simply defines some strings that get sent as HTML pages. */
const char * const cSamplePageFirstPart =
"HTTP/1.0 200 OK\r\n"
"Content-type: text/html\r\n"
"\r\n"
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n"
"<html>\r\n"
"<head>\r\n"
"<title>FreeRTOS - Live embedded WEB server demo</title>\r\n"
"</head>\r\n"
"<body BGCOLOR=\"#CCCCFF\">\r\n"
"<font face=\"arial\">\r\n"
"<small><b><a href=\"http://www.freertos.org\" target=\"_top\">FreeRTOS Homepage</a></b></small><p>"
"<H1>Embedded WEB Server<br><small>On the FreeRTOS real time kernel</small></h1>\r\n"
"<p>\r\n"
"<b>This demo is now using FreeRTOS.org V4.x.x!</b><p>"
"This page is being served by the FreeRTOS embedded WEB server running on an ARM7 microcontroller.\r\n<pre>";
const char * const cSamplePageSecondPart =
"</pre>"
"If all is well you should see that 18 tasks are executing - 15 standard demo tasks, the embedded WEB server"
" task, the error check task and the idle task.<p>"
"</font>\r\n"
"</body>\r\n"
"</html>\r\n";
#endif

View file

@ -0,0 +1,243 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
/* Application includes. */
#include "i2c.h"
/*-----------------------------------------------------------*/
/* Constants to setup the microcontroller IO. */
#define mainSDA_ENABLE ( ( unsigned long ) 0x0040 )
#define mainSCL_ENABLE ( ( unsigned long ) 0x0010 )
/* Bit definitions within the I2CONCLR register. */
#define i2cSTA_BIT ( ( unsigned char ) 0x20 )
#define i2cSI_BIT ( ( unsigned char ) 0x08 )
#define i2cSTO_BIT ( ( unsigned char ) 0x10 )
/* Constants required to setup the VIC. */
#define i2cI2C_VIC_CHANNEL ( ( unsigned long ) 0x0009 )
#define i2cI2C_VIC_CHANNEL_BIT ( ( unsigned long ) 0x0200 )
#define i2cI2C_VIC_ENABLE ( ( unsigned long ) 0x0020 )
/* Misc constants. */
#define i2cNO_BLOCK ( ( portTickType ) 0 )
#define i2cQUEUE_LENGTH ( ( unsigned char ) 5 )
#define i2cEXTRA_MESSAGES ( ( unsigned char ) 2 )
#define i2cREAD_TX_LEN ( ( unsigned long ) 2 )
#define i2cACTIVE_MASTER_MODE ( ( unsigned char ) 0x40 )
#define i2cTIMERL ( 200 )
#define i2cTIMERH ( 200 )
/* Array of message definitions. See the header file for more information
on the structure members. There are two more places in the queue than as
defined by i2cQUEUE_LENGTH. This is to ensure that there is always a free
message available - one can be in the process of being transmitted and one
can be left free. */
static xI2CMessage xTxMessages[ i2cQUEUE_LENGTH + i2cEXTRA_MESSAGES ];
/* Function in the ARM part of the code used to create the queues. */
extern void vI2CISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxTxMessages, unsigned long **ppulBusFree );
/* Index to the next free message in the xTxMessages array. */
unsigned long ulNextFreeMessage = ( unsigned long ) 0;
/* Queue of messages that are waiting transmission. */
static xQueueHandle xMessagesForTx;
/* Flag to indicate the state of the I2C ISR state machine. */
static unsigned long *pulBusFree;
/*-----------------------------------------------------------*/
void i2cMessage( const unsigned char * const pucMessage, long lMessageLength, unsigned char ucSlaveAddress, unsigned short usBufferAddress, unsigned long ulDirection, xSemaphoreHandle xMessageCompleteSemaphore, portTickType xBlockTime )
{
extern volatile xI2CMessage *pxCurrentMessage;
xI2CMessage *pxNextFreeMessage;
signed portBASE_TYPE xReturn;
portENTER_CRITICAL();
{
/* This message is guaranteed to be free as there are two more messages
than spaces in the queue allowing for one message to be in process of
being transmitted and one to be left free. */
pxNextFreeMessage = &( xTxMessages[ ulNextFreeMessage ] );
/* Fill the message with the data to be sent. */
/* Pointer to the actual data. Only a pointer is stored (i.e. the
actual data is not copied, so the data being pointed to must still
be valid when the message eventually gets sent (it may be queued for
a while. */
pxNextFreeMessage->pucBuffer = ( unsigned char * ) pucMessage;
/* This is the address of the I2C device we are going to transmit this
message to. */
pxNextFreeMessage->ucSlaveAddress = ucSlaveAddress | ( unsigned char ) ulDirection;
/* A semaphore can be used to allow the I2C ISR to indicate that the
message has been sent. This can be NULL if you don't want to wait for
the message transmission to complete. */
pxNextFreeMessage->xMessageCompleteSemaphore = xMessageCompleteSemaphore;
/* How many bytes are to be sent? */
pxNextFreeMessage->lMessageLength = lMessageLength;
/* The address within the WIZnet device to which the data will be
written. This could be the address of a register, or alternatively
a location within the WIZnet Tx buffer. */
pxNextFreeMessage->ucBufferAddressLowByte = ( unsigned char ) ( usBufferAddress & 0xff );
/* Second byte of the address. */
usBufferAddress >>= 8;
pxNextFreeMessage->ucBufferAddressHighByte = ( unsigned char ) ( usBufferAddress & 0xff );
/* Increment to the next message in the array - with a wrap around check. */
ulNextFreeMessage++;
if( ulNextFreeMessage >= ( i2cQUEUE_LENGTH + i2cEXTRA_MESSAGES ) )
{
ulNextFreeMessage = ( unsigned long ) 0;
}
/* Is the I2C interrupt in the middle of transmitting a message? */
if( *pulBusFree == ( unsigned long ) pdTRUE )
{
/* No message is currently being sent or queued to be sent. We
can start the ISR sending this message immediately. */
pxCurrentMessage = pxNextFreeMessage;
I2C_I2CONCLR = i2cSI_BIT;
I2C_I2CONSET = i2cSTA_BIT;
*pulBusFree = ( unsigned long ) pdFALSE;
}
else
{
/* The I2C interrupt routine is mid sending a message. Queue
this message ready to be sent. */
xReturn = xQueueSend( xMessagesForTx, &pxNextFreeMessage, xBlockTime );
/* We may have blocked while trying to queue the message. If this
was the case then the interrupt would have been enabled and we may
now find that the I2C interrupt routine is no longer sending a
message. */
if( ( *pulBusFree == ( unsigned long ) pdTRUE ) && ( xReturn == pdPASS ) )
{
/* Get the next message in the queue (this should be the
message we just posted) and start off the transmission
again. */
xQueueReceive( xMessagesForTx, &pxNextFreeMessage, i2cNO_BLOCK );
pxCurrentMessage = pxNextFreeMessage;
I2C_I2CONCLR = i2cSI_BIT;
I2C_I2CONSET = i2cSTA_BIT;
*pulBusFree = ( unsigned long ) pdFALSE;
}
}
}
portEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
void i2cInit( void )
{
extern void ( vI2C_ISR_Wrapper )( void );
/* Create the queue used to send messages to the ISR. */
vI2CISRCreateQueues( i2cQUEUE_LENGTH, &xMessagesForTx, &pulBusFree );
/* Configure the I2C hardware. */
I2C_I2CONCLR = 0xff;
PCB_PINSEL0 |= mainSDA_ENABLE;
PCB_PINSEL0 |= mainSCL_ENABLE;
I2C_I2SCLL = i2cTIMERL;
I2C_I2SCLH = i2cTIMERH;
I2C_I2CONSET = i2cACTIVE_MASTER_MODE;
portENTER_CRITICAL();
{
/* Setup the VIC for the i2c interrupt. */
VICIntSelect &= ~( i2cI2C_VIC_CHANNEL_BIT );
VICIntEnable |= i2cI2C_VIC_CHANNEL_BIT;
VICVectAddr2 = ( long ) vI2C_ISR_Wrapper;
VICVectCntl2 = i2cI2C_VIC_CHANNEL | i2cI2C_VIC_ENABLE;
}
portEXIT_CRITICAL();
}

View file

@ -0,0 +1,120 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef I2C_H
#define I2C_H
/* Structure used to capture the I2C message details. The structure is then
* queued for processing by the I2C ISR.
*/
typedef struct AN_I2C_MESSAGE
{
long lMessageLength; /*< How many bytes of data to send or received - excluding the buffer address. */
unsigned char ucSlaveAddress; /*< The slave address of the WIZnet on the I2C bus. */
unsigned char ucBufferAddressLowByte; /*< The address within the WIZnet device to which data should be read from / written to. */
unsigned char ucBufferAddressHighByte; /*< As above, high byte. */
xSemaphoreHandle xMessageCompleteSemaphore; /*< Contains a reference to a semaphore if the application tasks wants notifying when the message has been transacted. */
unsigned char *pucBuffer; /*< Pointer to the buffer from where data will be read for transmission, or into which received data will be placed. */
} xI2CMessage;
/* Constants to use as the ulDirection parameter of i2cMessage(). */
#define i2cWRITE ( ( unsigned long ) 0 )
#define i2cREAD ( ( unsigned long ) 1 )
/**
* Must be called once before any calls to i2cMessage.
*/
void i2cInit( void );
/**
* Send or receive a message over the I2C bus.
*
* @param pucMessage The data to be transmitted or the buffer into which
* received data will be placed.
*
* @param lMessageLength The number of bytes to either transmit or receive.
*
* @param ucSlaveAddress The slave address of the WIZNet device on the I2C bus.
*
* @param usBufferAddress The address within the WIZNet device to which data is
* either written to or read from. The WIZnet has it's
* own Rx and Tx buffers.
*
* @param ulDirection Must be either i2cWRITE or i2cREAD as #defined above.
*
* @param xMessageCompleteSemaphore
* Can be used to pass a semaphore reference if the
* calling task want notification of when the message has
* completed. Otherwise NULL can be passed.
*
* @param xBlockTime The time to wait for a space in the message queue to
* become available should one not be available
* immediately.
*/
void i2cMessage( const unsigned char * const pucMessage, long lMessageLength, unsigned char ucSlaveAddress, unsigned short usBufferAddress, unsigned long ulDirection, xSemaphoreHandle xMessageCompleteSemaphore, portTickType xBlockTime );
#endif

View file

@ -0,0 +1,397 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Application includes. */
#include "i2c.h"
/*-----------------------------------------------------------*/
/* Bit definitions within the I2CONCLR register. */
#define i2cSTA_BIT ( ( unsigned char ) 0x20 )
#define i2cSI_BIT ( ( unsigned char ) 0x08 )
#define i2cSTO_BIT ( ( unsigned char ) 0x10 )
#define i2cAA_BIT ( ( unsigned char ) 0x04 )
/* Status codes for the I2STAT register. */
#define i2cSTATUS_START_TXED ( 0x08 )
#define i2cSTATUS_REP_START_TXED ( 0x10 )
#define i2cSTATUS_TX_ADDR_ACKED ( 0x18 )
#define i2cSTATUS_DATA_TXED ( 0x28 )
#define i2cSTATUS_RX_ADDR_ACKED ( 0x40 )
#define i2cSTATUS_DATA_RXED ( 0x50 )
#define i2cSTATUS_LAST_BYTE_RXED ( 0x58 )
/* Constants for operation of the VIC. */
#define i2cCLEAR_VIC_INTERRUPT ( 0 )
/* Misc constants. */
#define i2cJUST_ONE_BYTE_TO_RX ( 1 )
#define i2cBUFFER_ADDRESS_BYTES ( 2 )
/* End the current transmission and free the bus. */
#define i2cEND_TRANSMISSION( lStatus ) \
{ \
I2C_I2CONCLR = i2cAA_BIT; \
I2C_I2CONSET = i2cSTO_BIT; \
eCurrentState = eSentStart; \
lTransactionCompleted = lStatus; \
}
/*-----------------------------------------------------------*/
/* Valid i2c communication states. */
typedef enum
{
eSentStart, /*<< Last action was the transmission of a start bit. */
eSentAddressForWrite, /*<< Last action was the transmission of the slave address we are to write to. */
eSentAddressForRead, /*<< Last action was the transmission of the slave address we are to read from. */
eSentData, /*<< Last action was the transmission of a data byte. */
eReceiveData /*<< We expected data to be received. */
} I2C_STATE;
/*-----------------------------------------------------------*/
/* Points to the message currently being sent. */
volatile xI2CMessage *pxCurrentMessage = NULL;
/* The queue of messages waiting to be transmitted. */
static xQueueHandle xMessagesForTx;
/* Flag used to indicate whether or not the ISR is amid sending a message. */
unsigned long ulBusFree = ( unsigned long ) pdTRUE;
/* Setting this to true will cause the TCP task to think a message is
complete and thus restart. It can therefore be used under error states
to force a restart. */
volatile long lTransactionCompleted = pdTRUE;
/*-----------------------------------------------------------*/
void vI2CISRCreateQueues( unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxTxMessages, unsigned long **ppulBusFree )
{
/* Create the queues used to hold Rx and Tx characters. */
xMessagesForTx = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( xI2CMessage * ) );
/* Pass back a reference to the queue and bus free flag so the I2C API file
can post messages. */
*pxTxMessages = xMessagesForTx;
*ppulBusFree = &ulBusFree;
}
/*-----------------------------------------------------------*/
/* The ISR entry point. */
void vI2C_ISR_Wrapper( void ) __attribute__ (( naked ));
/* The ISR function to perform the actual work. This must be a separate
function from the wrapper to ensure the correct stack frame is set up. */
void vI2C_ISR_Handler( void );
/*-----------------------------------------------------------*/
void vI2C_ISR_Wrapper( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Call the handler to perform the actual work. This must be a
separate function to ensure the correct stack frame is set up. */
vI2C_ISR_Handler();
/* Restore the context of whichever task is going to run next. */
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
void vI2C_ISR_Handler( void )
{
/* Holds the current transmission state. */
static I2C_STATE eCurrentState = eSentStart;
static long lMessageIndex = -i2cBUFFER_ADDRESS_BYTES; /* There are two address bytes to send prior to the data. */
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
long lBytesLeft;
/* The action taken for this interrupt depends on our current state. */
switch( eCurrentState )
{
case eSentStart :
/* We sent a start bit, if it was successful we can
go on to send the slave address. */
if( ( I2C_I2STAT == i2cSTATUS_START_TXED ) || ( I2C_I2STAT == i2cSTATUS_REP_START_TXED ) )
{
/* Send the slave address. */
I2C_I2DAT = pxCurrentMessage->ucSlaveAddress;
if( pxCurrentMessage->ucSlaveAddress & i2cREAD )
{
/* We are then going to read bytes back from the
slave. */
eCurrentState = eSentAddressForRead;
/* Initialise the buffer index so the first byte goes
into the first buffer position. */
lMessageIndex = 0;
}
else
{
/* We are then going to write some data to the slave. */
eCurrentState = eSentAddressForWrite;
/* When writing bytes we first have to send the two
byte buffer address so lMessageIndex is set negative,
when it reaches 0 it is time to send the actual data. */
lMessageIndex = -i2cBUFFER_ADDRESS_BYTES;
}
}
else
{
/* Could not send the start bit so give up. */
i2cEND_TRANSMISSION( pdFAIL );
}
I2C_I2CONCLR = i2cSTA_BIT;
break;
case eSentAddressForWrite :
/* We sent the address of the slave we are going to write to.
If this was acknowledged we can go on to send the data. */
if( I2C_I2STAT == i2cSTATUS_TX_ADDR_ACKED )
{
/* Start the first byte transmitting which is the
first byte of the buffer address to which the data will
be sent. */
I2C_I2DAT = pxCurrentMessage->ucBufferAddressHighByte;
eCurrentState = eSentData;
}
else
{
/* Address was not acknowledged so give up. */
i2cEND_TRANSMISSION( pdFAIL );
}
break;
case eSentAddressForRead :
/* We sent the address of the slave we are going to read from.
If this was acknowledged we can go on to read the data. */
if( I2C_I2STAT == i2cSTATUS_RX_ADDR_ACKED )
{
eCurrentState = eReceiveData;
if( pxCurrentMessage->lMessageLength > i2cJUST_ONE_BYTE_TO_RX )
{
/* Don't ack the last byte of the message. */
I2C_I2CONSET = i2cAA_BIT;
}
}
else
{
/* Something unexpected happened - give up. */
i2cEND_TRANSMISSION( pdFAIL );
}
break;
case eReceiveData :
/* We have just received a byte from the slave. */
if( ( I2C_I2STAT == i2cSTATUS_DATA_RXED ) || ( I2C_I2STAT == i2cSTATUS_LAST_BYTE_RXED ) )
{
/* Buffer the byte just received then increment the index
so it points to the next free space. */
pxCurrentMessage->pucBuffer[ lMessageIndex ] = I2C_I2DAT;
lMessageIndex++;
/* How many more bytes are we expecting to receive? */
lBytesLeft = pxCurrentMessage->lMessageLength - lMessageIndex;
if( lBytesLeft == ( unsigned long ) 0 )
{
/* This was the last byte in the message. */
i2cEND_TRANSMISSION( pdPASS );
/* If xMessageCompleteSemaphore is not null then there
is a task waiting for this message to complete and we
must 'give' the semaphore so the task is woken.*/
if( pxCurrentMessage->xMessageCompleteSemaphore )
{
xSemaphoreGiveFromISR( pxCurrentMessage->xMessageCompleteSemaphore, &xHigherPriorityTaskWoken );
}
/* Are there any other messages to transact? */
if( xQueueReceiveFromISR( xMessagesForTx, &pxCurrentMessage, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* Start the next message - which was
retrieved from the queue. */
I2C_I2CONSET = i2cSTA_BIT;
}
else
{
/* No more messages were found to be waiting for
transaction so the bus is free. */
ulBusFree = ( unsigned long ) pdTRUE;
}
}
else
{
/* There are more bytes to receive but don't ack the
last byte. */
if( lBytesLeft <= i2cJUST_ONE_BYTE_TO_RX )
{
I2C_I2CONCLR = i2cAA_BIT;
}
}
}
else
{
/* Something unexpected happened - give up. */
i2cEND_TRANSMISSION( pdFAIL );
}
break;
case eSentData :
/* We sent a data byte, if successful send the next byte in
the message. */
if( I2C_I2STAT == i2cSTATUS_DATA_TXED )
{
/* Index to the next byte to send. */
lMessageIndex++;
if( lMessageIndex < 0 )
{
/* lMessage index is still negative so we have so far
only sent the first byte of the buffer address. Send
the second byte now, then initialise the buffer index
to zero so the next byte sent comes from the actual
data buffer. */
I2C_I2DAT = pxCurrentMessage->ucBufferAddressLowByte;
}
else if( lMessageIndex < pxCurrentMessage->lMessageLength )
{
/* Simply send the next byte in the tx buffer. */
I2C_I2DAT = pxCurrentMessage->pucBuffer[ lMessageIndex ];
}
else
{
/* No more bytes in this message to be send. Finished
sending message - send a stop bit. */
i2cEND_TRANSMISSION( pdPASS );
/* If xMessageCompleteSemaphore is not null then there
is a task waiting for this message to be sent and the
semaphore must be 'given' to wake the task. */
if( pxCurrentMessage->xMessageCompleteSemaphore )
{
xSemaphoreGiveFromISR( pxCurrentMessage->xMessageCompleteSemaphore, &xHigherPriorityTaskWoken );
}
/* Are there any other messages to transact? */
if( xQueueReceiveFromISR( xMessagesForTx, &pxCurrentMessage, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* Start the next message from the Tx queue. */
I2C_I2CONSET = i2cSTA_BIT;
}
else
{
/* No more message were queues for transaction so
the bus is free. */
ulBusFree = ( unsigned long ) pdTRUE;
}
}
}
else
{
/* Something unexpected happened, give up. */
i2cEND_TRANSMISSION( pdFAIL );
}
break;
default :
/* Should never get here. */
eCurrentState = eSentStart;
break;
}
/* Clear the interrupt. */
I2C_I2CONCLR = i2cSI_BIT;
VICVectAddr = i2cCLEAR_VIC_INTERRUPT;
if( xHigherPriorityTaskWoken )
{
portYIELD_FROM_ISR();
}
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,49 @@
MEMORY
{
flash : ORIGIN = 0, LENGTH = 120K
ram : ORIGIN = 0x40000000, LENGTH = 64K
}
__stack_end__ = 0x40000000 + 64K - 4;
SECTIONS
{
. = 0;
startup : { *(.startup)} >flash
prog :
{
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} >flash
__end_of_text__ = .;
.data :
{
__data_beg__ = .;
__data_beg_src__ = __end_of_text__;
*(.data)
__data_end__ = .;
} >ram AT>flash
.bss :
{
__bss_beg__ = .;
*(.bss)
} >ram
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_end = .;
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
PROVIDE (end = .);

View file

@ -0,0 +1,321 @@
#ifndef lpc210x_h
#define lpc210x_h
/*******************************************************************************
lpc210x.h - Register defs for Philips LPC210X: LPC2104, LPC2105 and LPC2106
THE SOFTWARE IS DELIVERED "AS IS" WITHOUT WARRANTY OR CONDITION OF ANY KIND,
EITHER EXPRESS, IMPLIED OR STATUTORY. THIS INCLUDES WITHOUT LIMITATION ANY
WARRANTY OR CONDITION WITH RESPECT TO MERCHANTABILITY OR FITNESS FOR ANY
PARTICULAR PURPOSE, OR AGAINST THE INFRINGEMENTS OF INTELLECTUAL PROPERTY RIGHTS
OF OTHERS.
This file may be freely used for commercial and non-commercial applications,
including being redistributed with any tools.
If you find a problem with the file, please report it so that it can be fixed.
Created by Sten Larsson (sten_larsson at yahoo com)
Edited by Richard Barry.
*******************************************************************************/
#define REG8 (volatile unsigned char*)
#define REG16 (volatile unsigned short*)
#define REG32 (volatile unsigned int*)
/*##############################################################################
## MISC
##############################################################################*/
/* Constants for data to put in IRQ/FIQ Exception Vectors */
#define VECTDATA_IRQ 0xE51FFFF0 /* LDR PC,[PC,#-0xFF0] */
#define VECTDATA_FIQ /* __TODO */
/*##############################################################################
## VECTORED INTERRUPT CONTROLLER
##############################################################################*/
#define VICIRQStatus (*(REG32 (0xFFFFF000)))
#define VICFIQStatus (*(REG32 (0xFFFFF004)))
#define VICRawIntr (*(REG32 (0xFFFFF008)))
#define VICIntSelect (*(REG32 (0xFFFFF00C)))
#define VICIntEnable (*(REG32 (0xFFFFF010)))
#define VICIntEnClear (*(REG32 (0xFFFFF014)))
#define VICSoftInt (*(REG32 (0xFFFFF018)))
#define VICSoftIntClear (*(REG32 (0xFFFFF01C)))
#define VICProtection (*(REG32 (0xFFFFF020)))
#define VICVectAddr (*(REG32 (0xFFFFF030)))
#define VICDefVectAddr (*(REG32 (0xFFFFF034)))
#define VICVectAddr0 (*(REG32 (0xFFFFF100)))
#define VICVectAddr1 (*(REG32 (0xFFFFF104)))
#define VICVectAddr2 (*(REG32 (0xFFFFF108)))
#define VICVectAddr3 (*(REG32 (0xFFFFF10C)))
#define VICVectAddr4 (*(REG32 (0xFFFFF110)))
#define VICVectAddr5 (*(REG32 (0xFFFFF114)))
#define VICVectAddr6 (*(REG32 (0xFFFFF118)))
#define VICVectAddr7 (*(REG32 (0xFFFFF11C)))
#define VICVectAddr8 (*(REG32 (0xFFFFF120)))
#define VICVectAddr9 (*(REG32 (0xFFFFF124)))
#define VICVectAddr10 (*(REG32 (0xFFFFF128)))
#define VICVectAddr11 (*(REG32 (0xFFFFF12C)))
#define VICVectAddr12 (*(REG32 (0xFFFFF130)))
#define VICVectAddr13 (*(REG32 (0xFFFFF134)))
#define VICVectAddr14 (*(REG32 (0xFFFFF138)))
#define VICVectAddr15 (*(REG32 (0xFFFFF13C)))
#define VICVectCntl0 (*(REG32 (0xFFFFF200)))
#define VICVectCntl1 (*(REG32 (0xFFFFF204)))
#define VICVectCntl2 (*(REG32 (0xFFFFF208)))
#define VICVectCntl3 (*(REG32 (0xFFFFF20C)))
#define VICVectCntl4 (*(REG32 (0xFFFFF210)))
#define VICVectCntl5 (*(REG32 (0xFFFFF214)))
#define VICVectCntl6 (*(REG32 (0xFFFFF218)))
#define VICVectCntl7 (*(REG32 (0xFFFFF21C)))
#define VICVectCntl8 (*(REG32 (0xFFFFF220)))
#define VICVectCntl9 (*(REG32 (0xFFFFF224)))
#define VICVectCntl10 (*(REG32 (0xFFFFF228)))
#define VICVectCntl11 (*(REG32 (0xFFFFF22C)))
#define VICVectCntl12 (*(REG32 (0xFFFFF230)))
#define VICVectCntl13 (*(REG32 (0xFFFFF234)))
#define VICVectCntl14 (*(REG32 (0xFFFFF238)))
#define VICVectCntl15 (*(REG32 (0xFFFFF23C)))
#define VICITCR (*(REG32 (0xFFFFF300)))
#define VICITIP1 (*(REG32 (0xFFFFF304)))
#define VICITIP2 (*(REG32 (0xFFFFF308)))
#define VICITOP1 (*(REG32 (0xFFFFF30C)))
#define VICITOP2 (*(REG32 (0xFFFFF310)))
#define VICPeriphID0 (*(REG32 (0xFFFFFFE0)))
#define VICPeriphID1 (*(REG32 (0xFFFFFFE4)))
#define VICPeriphID2 (*(REG32 (0xFFFFFFE8)))
#define VICPeriphID3 (*(REG32 (0xFFFFFFEC)))
#define VICIntEnClr VICIntEnClear
#define VICSoftIntClr VICSoftIntClear
/*##############################################################################
## PCB - Pin Connect Block
##############################################################################*/
#define PCB_PINSEL0 (*(REG32 (0xE002C000)))
#define PCB_PINSEL1 (*(REG32 (0xE002C004)))
/*##############################################################################
## GPIO - General Purpose I/O
##############################################################################*/
#define GPIO_IOPIN (*(REG32 (0xE0028000))) /* ALTERNATE NAME GPIO = GPIO0 */
#define GPIO_IOSET (*(REG32 (0xE0028004)))
#define GPIO_IODIR (*(REG32 (0xE0028008)))
#define GPIO_IOCLR (*(REG32 (0xE002800C)))
#define GPIO0_IOPIN (*(REG32 (0xE0028000))) /* ALTERNATE NAME GPIO = GPIO0 */
#define GPIO0_IOSET (*(REG32 (0xE0028004)))
#define GPIO0_IODIR (*(REG32 (0xE0028008)))
#define GPIO0_IOCLR (*(REG32 (0xE002800C)))
/*##############################################################################
## UART0 / UART1
##############################################################################*/
/* ---- UART 0 --------------------------------------------- */
#define UART0_RBR (*(REG32 (0xE000C000)))
#define UART0_THR (*(REG32 (0xE000C000)))
#define UART0_IER (*(REG32 (0xE000C004)))
#define UART0_IIR (*(REG32 (0xE000C008)))
#define UART0_FCR (*(REG32 (0xE000C008)))
#define UART0_LCR (*(REG32 (0xE000C00C)))
#define UART0_LSR (*(REG32 (0xE000C014)))
#define UART0_SCR (*(REG32 (0xE000C01C)))
#define UART0_DLL (*(REG32 (0xE000C000)))
#define UART0_DLM (*(REG32 (0xE000C004)))
/* ---- UART 1 --------------------------------------------- */
#define UART1_RBR (*(REG32 (0xE0010000)))
#define UART1_THR (*(REG32 (0xE0010000)))
#define UART1_IER (*(REG32 (0xE0010004)))
#define UART1_IIR (*(REG32 (0xE0010008)))
#define UART1_FCR (*(REG32 (0xE0010008)))
#define UART1_LCR (*(REG32 (0xE001000C)))
#define UART1_LSR (*(REG32 (0xE0010014)))
#define UART1_SCR (*(REG32 (0xE001001C)))
#define UART1_DLL (*(REG32 (0xE0010000)))
#define UART1_DLM (*(REG32 (0xE0010004)))
#define UART1_MCR (*(REG32 (0xE0010010)))
#define UART1_MSR (*(REG32 (0xE0010018)))
/*##############################################################################
## I2C
##############################################################################*/
#define I2C_I2CONSET (*(REG32 (0xE001C000)))
#define I2C_I2STAT (*(REG32 (0xE001C004)))
#define I2C_I2DAT (*(REG32 (0xE001C008)))
#define I2C_I2ADR (*(REG32 (0xE001C00C)))
#define I2C_I2SCLH (*(REG32 (0xE001C010)))
#define I2C_I2SCLL (*(REG32 (0xE001C014)))
#define I2C_I2CONCLR (*(REG32 (0xE001C018)))
/*##############################################################################
## SPI - Serial Peripheral Interface
##############################################################################*/
#define SPI_SPCR (*(REG32 (0xE0020000)))
#define SPI_SPSR (*(REG32 (0xE0020004)))
#define SPI_SPDR (*(REG32 (0xE0020008)))
#define SPI_SPCCR (*(REG32 (0xE002000C)))
#define SPI_SPTCR (*(REG32 (0xE0020010)))
#define SPI_SPTSR (*(REG32 (0xE0020014)))
#define SPI_SPTOR (*(REG32 (0xE0020018)))
#define SPI_SPINT (*(REG32 (0xE002001C)))
/*##############################################################################
## Timer 0 and Timer 1
##############################################################################*/
/* ---- Timer 0 -------------------------------------------- */
#define T0_IR (*(REG32 (0xE0004000)))
#define T0_TCR (*(REG32 (0xE0004004)))
#define T0_TC (*(REG32 (0xE0004008)))
#define T0_PR (*(REG32 (0xE000400C)))
#define T0_PC (*(REG32 (0xE0004010)))
#define T0_MCR (*(REG32 (0xE0004014)))
#define T0_MR0 (*(REG32 (0xE0004018)))
#define T0_MR1 (*(REG32 (0xE000401C)))
#define T0_MR2 (*(REG32 (0xE0004020)))
#define T0_MR3 (*(REG32 (0xE0004024)))
#define T0_CCR (*(REG32 (0xE0004028)))
#define T0_CR0 (*(REG32 (0xE000402C)))
#define T0_CR1 (*(REG32 (0xE0004030)))
#define T0_CR2 (*(REG32 (0xE0004034)))
#define T0_CR3 (*(REG32 (0xE0004038)))
#define T0_EMR (*(REG32 (0xE000403C)))
/* ---- Timer 1 -------------------------------------------- */
#define T1_IR (*(REG32 (0xE0008000)))
#define T1_TCR (*(REG32 (0xE0008004)))
#define T1_TC (*(REG32 (0xE0008008)))
#define T1_PR (*(REG32 (0xE000800C)))
#define T1_PC (*(REG32 (0xE0008010)))
#define T1_MCR (*(REG32 (0xE0008014)))
#define T1_MR0 (*(REG32 (0xE0008018)))
#define T1_MR1 (*(REG32 (0xE000801C)))
#define T1_MR2 (*(REG32 (0xE0008020)))
#define T1_MR3 (*(REG32 (0xE0008024)))
#define T1_CCR (*(REG32 (0xE0008028)))
#define T1_CR0 (*(REG32 (0xE000802C)))
#define T1_CR1 (*(REG32 (0xE0008030)))
#define T1_CR2 (*(REG32 (0xE0008034)))
#define T1_CR3 (*(REG32 (0xE0008038)))
#define T1_EMR (*(REG32 (0xE000803C)))
/*##############################################################################
## PWM
##############################################################################*/
#define PWM_IR (*(REG32 (0xE0014000)))
#define PWM_TCR (*(REG32 (0xE0014004)))
#define PWM_TC (*(REG32 (0xE0014008)))
#define PWM_PR (*(REG32 (0xE001400C)))
#define PWM_PC (*(REG32 (0xE0014010)))
#define PWM_MCR (*(REG32 (0xE0014014)))
#define PWM_MR0 (*(REG32 (0xE0014018)))
#define PWM_MR1 (*(REG32 (0xE001401C)))
#define PWM_MR2 (*(REG32 (0xE0014020)))
#define PWM_MR3 (*(REG32 (0xE0014024)))
#define PWM_MR4 (*(REG32 (0xE0014040)))
#define PWM_MR5 (*(REG32 (0xE0014044)))
#define PWM_MR6 (*(REG32 (0xE0014048)))
#define PWM_EMR (*(REG32 (0xE001403C)))
#define PWM_PCR (*(REG32 (0xE001404C)))
#define PWM_LER (*(REG32 (0xE0014050)))
#define PWM_CCR (*(REG32 (0xE0014028)))
#define PWM_CR0 (*(REG32 (0xE001402C)))
#define PWM_CR1 (*(REG32 (0xE0014030)))
#define PWM_CR2 (*(REG32 (0xE0014034)))
#define PWM_CR3 (*(REG32 (0xE0014038)))
/*##############################################################################
## RTC
##############################################################################*/
/* ---- RTC: Miscellaneous Register Group ------------------ */
#define RTC_ILR (*(REG32 (0xE0024000)))
#define RTC_CTC (*(REG32 (0xE0024004)))
#define RTC_CCR (*(REG32 (0xE0024008)))
#define RTC_CIIR (*(REG32 (0xE002400C)))
#define RTC_AMR (*(REG32 (0xE0024010)))
#define RTC_CTIME0 (*(REG32 (0xE0024014)))
#define RTC_CTIME1 (*(REG32 (0xE0024018)))
#define RTC_CTIME2 (*(REG32 (0xE002401C)))
/* ---- RTC: Timer Control Group --------------------------- */
#define RTC_SEC (*(REG32 (0xE0024020)))
#define RTC_MIN (*(REG32 (0xE0024024)))
#define RTC_HOUR (*(REG32 (0xE0024028)))
#define RTC_DOM (*(REG32 (0xE002402C)))
#define RTC_DOW (*(REG32 (0xE0024030)))
#define RTC_DOY (*(REG32 (0xE0024034)))
#define RTC_MONTH (*(REG32 (0xE0024038)))
#define RTC_YEAR (*(REG32 (0xE002403C)))
/* ---- RTC: Alarm Control Group --------------------------- */
#define RTC_ALSEC (*(REG32 (0xE0024060)))
#define RTC_ALMIN (*(REG32 (0xE0024064)))
#define RTC_ALHOUR (*(REG32 (0xE0024068)))
#define RTC_ALDOM (*(REG32 (0xE002406C)))
#define RTC_ALDOW (*(REG32 (0xE0024070)))
#define RTC_ALDOY (*(REG32 (0xE0024074)))
#define RTC_ALMON (*(REG32 (0xE0024078)))
#define RTC_ALYEAR (*(REG32 (0xE002407C)))
/* ---- RTC: Reference Clock Divider Group ----------------- */
#define RTC_PREINT (*(REG32 (0xE0024080)))
#define RTC_PREFRAC (*(REG32 (0xE0024084)))
/*##############################################################################
## WD - Watchdog
##############################################################################*/
#define WD_WDMOD (*(REG32 (0xE0000000)))
#define WD_WDTC (*(REG32 (0xE0000004)))
#define WD_WDFEED (*(REG32 (0xE0000008)))
#define WD_WDTV (*(REG32 (0xE000000C)))
/*##############################################################################
## System Control Block
##############################################################################*/
#define SCB_EXTINT (*(REG32 (0xE01FC140)))
#define SCB_EXTWAKE (*(REG32 (0xE01FC144)))
#define SCB_MEMMAP (*(REG32 (0xE01FC040)))
#define SCB_PLLCON (*(REG32 (0xE01FC080)))
#define SCB_PLLCFG (*(REG32 (0xE01FC084)))
#define SCB_PLLSTAT (*(REG32 (0xE01FC088)))
#define SCB_PLLFEED (*(REG32 (0xE01FC08C)))
#define SCB_PCON (*(REG32 (0xE01FC0C0)))
#define SCB_PCONP (*(REG32 (0xE01FC0C4)))
#define SCB_VPBDIV (*(REG32 (0xE01FC100)))
/*##############################################################################
## Memory Accelerator Module (MAM)
##############################################################################*/
#define MAM_TIM (*(REG32 (0xE01FC004)))
#define MAM_CR (*(REG32 (0xE01FC000)))
#endif /* lpc210x_h */

View file

@ -0,0 +1,332 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used.
*/
/*
* Program entry point.
*
* main() is responsible for setting up the microcontroller peripherals, then
* starting the demo application tasks. Once the tasks have been created the
* scheduler is started and main() should never complete.
*
* The demo creates the three standard 'flash' tasks to provide some visual
* feedback that the system and scheduler are still operating correctly.
*
* The HTTP server task operates at the highest priority so will always preempt
* the flash or idle task on TCP/IP events.
*/
/* Standard includes. */
#include <stdlib.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
/* Application includes. */
#include "i2c.h"
#include "HTTP_Serv.h"
#include "flash.h"
#include "partest.h"
#include "dynamic.h"
#include "semtest.h"
#include "PollQ.h"
#include "BlockQ.h"
#include "integer.h"
/*-----------------------------------------------------------*/
/* Constants to setup the PLL. */
#define mainPLL_MUL_4 ( ( unsigned char ) 0x0003 )
#define mainPLL_DIV_1 ( ( unsigned char ) 0x0000 )
#define mainPLL_ENABLE ( ( unsigned char ) 0x0001 )
#define mainPLL_CONNECT ( ( unsigned char ) 0x0003 )
#define mainPLL_FEED_BYTE1 ( ( unsigned char ) 0xaa )
#define mainPLL_FEED_BYTE2 ( ( unsigned char ) 0x55 )
#define mainPLL_LOCK ( ( unsigned long ) 0x0400 )
/* Constants to setup the MAM. */
#define mainMAM_TIM_3 ( ( unsigned char ) 0x03 )
#define mainMAM_MODE_FULL ( ( unsigned char ) 0x02 )
/* Constants to setup the peripheral bus. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
/* Constants to setup I/O and processor. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
#define mainLED_TO_OUTPUT ( ( unsigned long ) 0xff0000 )
#define mainJTAG_PORT ( ( unsigned long ) 0x3E0000UL )
/* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainHTTP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainERROR_CHECK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* Flash rates of the on board LED to indicate the health of the system. */
#define mainNO_ERROR_DELAY ( 3000 )
#define mainERROR_DELAY ( 500 )
#define mainON_BOARD_LED_BIT ( ( unsigned long ) 0x80 )
/*-----------------------------------------------------------*/
/*
* The Olimex demo board has a single built in LED. This function simply
* toggles its state.
*/
void prvToggleOnBoardLED( void );
/*
* Configure the processor for use with the Olimex demo board.
*/
static void prvSetupHardware( void );
/*
* Simply check for errors and toggle the onboard LED.
*/
static void prvErrorChecks( void *pvParameters );
/*
* Return true if the demo tasks are executing without error - otherwise
* return false.
*/
static void prvMainCheckOtherTasksAreStillRunning( void );
/*-----------------------------------------------------------*/
/* Flag set by prvMainCheckOtherTasksAreStillExecuting(). */
long lErrorInTask = pdFALSE;
/*
* Application entry point:
* Starts all the other tasks, then starts the scheduler.
*/
int main( void )
{
/* Setup the hardware for use with the Olimex demo board. */
prvSetupHardware();
/* Start the standard flash tasks so the WEB server is not the only thing
running. */
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartSemaphoreTasks( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks();
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartIntegerMathTasks( tskIDLE_PRIORITY );
/* Start the WEB server task and the error check task. */
xTaskCreate( vHTTPServerTask, ( signed char * ) "HTTP", configMINIMAL_STACK_SIZE, NULL, mainHTTP_TASK_PRIORITY, NULL );
xTaskCreate( prvErrorChecks, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainERROR_CHECK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler.
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. */
vTaskStartScheduler();
/* Should never reach here! */
return 0;
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
#ifdef RUN_FROM_RAM
/* Remap the interrupt vectors to RAM if we are are running from RAM. */
SCB_MEMMAP = 2;
#endif
/* Set all GPIO to output other than the P0.14 (BSL), and the JTAG pins.
The JTAG pins are left as input as I'm not sure what will happen if the
Wiggler is connected after powerup - not that it would be a good idea to
do that anyway. */
GPIO_IODIR = ~( mainJTAG_PORT );
/* Setup the PLL to multiply the XTAL input by 4. */
SCB_PLLCFG = ( mainPLL_MUL_4 | mainPLL_DIV_1 );
/* Activate the PLL by turning it on then feeding the correct sequence of
bytes. */
SCB_PLLCON = mainPLL_ENABLE;
SCB_PLLFEED = mainPLL_FEED_BYTE1;
SCB_PLLFEED = mainPLL_FEED_BYTE2;
/* Wait for the PLL to lock... */
while( !( SCB_PLLSTAT & mainPLL_LOCK ) );
/* ...before connecting it using the feed sequence again. */
SCB_PLLCON = mainPLL_CONNECT;
SCB_PLLFEED = mainPLL_FEED_BYTE1;
SCB_PLLFEED = mainPLL_FEED_BYTE2;
/* Setup and turn on the MAM. Three cycle access is used due to the fast
PLL used. It is possible faster overall performance could be obtained by
tuning the MAM and PLL settings. */
MAM_TIM = mainMAM_TIM_3;
MAM_CR = mainMAM_MODE_FULL;
/* Setup the peripheral bus to be the same as the PLL output. */
SCB_VPBDIV = mainBUS_CLK_FULL;
/* Initialise the i2c peripheral. */
i2cInit();
/* Initialise the LED's used by the flash tasks. */
vParTestInitialise();
}
/*-----------------------------------------------------------*/
static void prvMainCheckOtherTasksAreStillRunning( void )
{
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected
an error. */
/* This function is called from more than one task. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
lErrorInTask = pdTRUE;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
lErrorInTask = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
lErrorInTask = pdTRUE;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
lErrorInTask = pdTRUE;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
lErrorInTask = pdTRUE;
}
}
/*-----------------------------------------------------------*/
void prvToggleOnBoardLED( void )
{
unsigned long ulState;
ulState = GPIO0_IOPIN;
if( ulState & mainON_BOARD_LED_BIT )
{
GPIO_IOCLR = mainON_BOARD_LED_BIT;
}
else
{
GPIO_IOSET = mainON_BOARD_LED_BIT;
}
}
/*-----------------------------------------------------------*/
static void prvErrorChecks( void *pvParameters )
{
portTickType xDelay = mainNO_ERROR_DELAY;
/* The parameters are not used. */
( void ) pvParameters;
for( ;; )
{
/* How long we delay depends on whether an error has been detected
or not. Therefore the flash rate of the on board LED indicates
whether or not an error has occurred. */
vTaskDelay( xDelay );
/* Update the lErrorInTask flag. */
prvMainCheckOtherTasksAreStillRunning();
if( lErrorInTask )
{
/* An error has been found so reduce the delay period and in so
doing speed up the flash rate of the on board LED. */
xDelay = mainERROR_DELAY;
}
prvToggleOnBoardLED();
}
}