Work in progress on the LPC1766 port.

pull/4/head
Richard Barry 16 years ago
parent a9a108a751
commit 6003973d5e

@ -393,10 +393,7 @@
<projectStorage>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&#13;
&lt;TargetConfig&gt;&#13;
&lt;Properties property_0="" property_1="" property_2="" property_3="NXP" property_4="LPC1766ENG" property_count="5" version="1"/&gt;&#13;
&lt;infoList vendor="NXP"&gt;&#13;
&lt;info chip="LPC1766ENG" match_id="0x00033f33" name="LPC1766ENG"&gt;&#13;
&lt;chip&gt;&#13;
&lt;name&gt;LPC1766ENG&lt;/name&gt;&#13;
&lt;infoList vendor="NXP"&gt;&lt;info chip="LPC1766ENG" match_id="0x00033f33" name="LPC1766ENG"&gt;&lt;chip&gt;&lt;name&gt;LPC1766ENG&lt;/name&gt;&#13;
&lt;family&gt;LPC17xx&lt;/family&gt;&#13;
&lt;vendor&gt;NXP (formerly Philips)&lt;/vendor&gt;&#13;
&lt;reset board="None" core="Real" sys="Real"/&gt;&#13;
@ -448,8 +445,7 @@
&lt;peripheralInstance derived_from="MPU" determined="infoFile" id="MPU" location="0xE000ED90"/&gt;&#13;
&lt;peripheralInstance derived_from="LPC1x_WDT" determined="infoFile" id="WDT" location="0x40000000"/&gt;&#13;
&lt;/chip&gt;&#13;
&lt;processor&gt;&#13;
&lt;name gcc_name="cortex-m3"&gt;Cortex-M3&lt;/name&gt;&#13;
&lt;processor&gt;&lt;name gcc_name="cortex-m3"&gt;Cortex-M3&lt;/name&gt;&#13;
&lt;family&gt;Cortex-M&lt;/family&gt;&#13;
&lt;/processor&gt;&#13;
&lt;link href="nxp_lpcxxxx_peripheral.xme" show="embed" type="simple"/&gt;&#13;

@ -1,55 +1,60 @@
/*
FreeRTOS.org V5.0.3 - Copyright (C) 2003-2008 Richard Barry.
FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FreeRTOS.org 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.
FreeRTOS.org 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.
FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License
along with FreeRTOS.org; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License along
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes FreeRTOS.org, without being obliged to provide
A special exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS.org without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details of how and when the exception
can be applied.
***************************************************************************
***************************************************************************
* *
* SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *
* and even write all or part of your application on your behalf. *
* See http://www.OpenRTOS.com for details of the services we provide to *
* expedite your project. *
* *
***************************************************************************
***************************************************************************
of http://www.FreeRTOS.org for full details.
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "LPC17xx.h"
#include "LPC17xx_defs.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
@ -62,10 +67,11 @@
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 72000000 )
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 70 )
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 80 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 19 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
@ -74,6 +80,8 @@
#define configUSE_CO_ROUTINES 0
#define configUSE_MUTEXES 1
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define configUSE_COUNTING_SEMAPHORES 0
#define configUSE_ALTERNATIVE_API 0
#define configCHECK_FOR_STACK_OVERFLOW 2
@ -81,9 +89,6 @@
#define configQUEUE_REGISTRY_SIZE 10
#define configGENERATE_RUN_TIME_STATS 1
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
@ -96,6 +101,9 @@ to exclude the API function. */
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
/*-----------------------------------------------------------
* Ethernet configuration.
*-----------------------------------------------------------*/
/* MAC address configuration. */
#define configMAC_ADDR0 0x00
@ -130,27 +138,21 @@ to exclude the API function. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) )
#define TMR0_BASE_ADDR 0x40004000
#define T0TCR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x04))
#define T0CTCR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x70))
#define T0PR (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x0C))
#define T0TC (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x08))
#define TCR_COUNT_RESET ( 0x02 )
#define TCR_COUNT_ENABLE ( 0x01 )
#define CTCR_CTM_TIMER ( 0x00 )
#define _PCLKSEL0 (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x1A8))
/*-----------------------------------------------------------
* Macros required to setup the timer for the run time stats.
*-----------------------------------------------------------*/
extern void vConfigureTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() T0TC
/* The structure that is passed on the xLCDQueue. Put here for convenience. */
typedef struct
{
long xColumn;
char *pcMessage;
} xLCDMessage;
#endif /* FREERTOS_CONFIG_H */

@ -0,0 +1,93 @@
/*
FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org 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.
FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
A special exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS.org without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details.
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#include "FreeRTOS.h"
#include "task.h"
void vToggleLED( unsigned long ulLED )
{
/* ulLED is a bit mask for the LED. */
taskENTER_CRITICAL();
{
if( FIO2PIN & ulLED )
{
FIO2CLR = ulLED;
}
else
{
FIO2SET = ulLED;
}
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
void vSetLEDState( unsigned long ulLED, long lState )
{
/* ulLED is a bit mask for the LED. */
if( lState == 0 )
{
FIO2CLR = ulLED;
}
else
{
FIO2SET = ulLED;
}
}
/*-----------------------------------------------------------*/
long lGetLEDState( unsigned long ulLED )
{
/* ulLED is a bit mask for the LED. */
return FIO2PIN & ulLED;
}
/*-----------------------------------------------------------*/

@ -0,0 +1,59 @@
/*
FreeRTOS.org V5.2.0 - Copyright (C) 2003-2009 Richard Barry.
This file is part of the FreeRTOS.org distribution.
FreeRTOS.org 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.
FreeRTOS.org is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with FreeRTOS.org; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA.
A special exception to the GPL is included to allow you to distribute a
combined work that includes FreeRTOS.org without being obliged to provide
the source code for any proprietary components. See the licensing section
of http://www.FreeRTOS.org for full details.
***************************************************************************
* *
* Get the FreeRTOS eBook! See http://www.FreeRTOS.org/Documentation *
* *
* This is a concise, step by step, 'hands on' guide that describes both *
* general multitasking concepts and FreeRTOS specifics. It presents and *
* explains numerous examples that are written using the FreeRTOS API. *
* Full source code for all the examples is provided in an accompanying *
* .zip file. *
* *
***************************************************************************
1 tab == 4 spaces!
Please ensure to read the configuration and relevant port sections of the
online documentation.
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef LED_HH
#define LED_HH
void vToggleLED( unsigned long ulLED );
void vSetLEDState( unsigned long ulLED, long lState );
long lGetLEDState( unsigned long ulLED );
#endif

@ -19,7 +19,9 @@
#define SRAM_BASE_AHB ((unsigned long)0x20000000) // 32 Kb
/* System Control Space memory map */
#define SCS_BASE ((unsigned long)0xE000E000)
#ifndef SCS_BASE
#define SCS_BASE ((unsigned long)0xE000E000)
#endif
#define SysTick_BASE (SCS_BASE + 0x0010)
#define NVIC_BASE (SCS_BASE + 0x0100)

@ -52,7 +52,7 @@
RM := rm -rf
# Set the optimisation level - this should be set to 0, 1, 2, 3 or s (s for size).
OPTIM=0
OPTIM=1
# Set the debug level
DEBUG=-g3
@ -118,6 +118,7 @@ Demo_OBJS= $(OUTPUT_DIR)/main.o \
$(OUTPUT_DIR)/blocktim.o \
$(OUTPUT_DIR)/printf-stdarg.o \
$(OUTPUT_DIR)/cr_startup_nxp_cm3.o \
$(OUTPUT_DIR)/LED.o \
$(OUTPUT_DIR)/syscalls.o # This is just a dummy.
# The TCP/IP and WEB server files.

@ -50,7 +50,39 @@
*/
/*
* Creates all the demo application tasks, then starts the scheduler. The WEB
* documentation provides more details of the standard demo application tasks
* (which just exist to test the kernel port and provide an example of how to use
* each FreeRTOS API function).
*
* In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file:
*
* "LCD" task - the LCD task is a 'gatekeeper' task. It is the only task that
* is permitted to access the display directly. Other tasks wishing to write a
* message to the LCD send the message on a queue to the LCD task instead of
* accessing the LCD themselves. The LCD task just blocks on the queue waiting
* for messages - waking and displaying the messages as they arrive. The use
* of a gatekeeper in this manner permits both tasks and interrupts to write to
* the LCD without worrying about mutual exclusion. This is demonstrated by the
* check hook (see below) which sends messages to the display even though it
* executes from an interrupt context.
*
* "Check" hook - This only executes fully every five seconds from the tick
* hook. Its main function is to check that all the standard demo tasks are
* still operational. Should any unexpected behaviour be discovered within a
* demo task then the tick hook will write an error to the LCD (via the LCD task).
* If all the demo tasks are executing with their expected behaviour then the
* check task writes PASS to the LCD (again via the LCD task), as described above.
*
* LED tasks - These just demonstrate how multiple instances of a single task
* definition can be created. Each LED task simply toggles an LED. The task
* parameter is used to pass the number of the LED to be toggled into the task.
*
* "uIP" task - This is the task that handles the uIP stack. All TCP/IP
* processing is performed in this task.
*/
/* Standard includes. */
#include <stdio.h>
@ -64,9 +96,6 @@
/* Hardware library includes. */
#include "LPC17xx_defs.h"
#define NUM_LEDS 8
/* Demo app includes. */
#include "BlockQ.h"
#include "integer.h"
@ -79,28 +108,33 @@
#include "QPeek.h"
#include "recmutex.h"
#include "lcd/portlcd.h"
#include "LED.h"
/*-----------------------------------------------------------*/
/* The number of LED tasks that will be created. */
#define mainNUM_LED_TASKS ( 6 )
/* The time between cycles of the 'check' functionality (defined within the
tick hook. */
#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS )
/* Task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The period of the system clock in nano seconds. This is used to calculate
the jitter time in nano seconds. */
#define mainNS_PER_CLOCK ( ( unsigned portLONG ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) )
/* The WEB server has a larger stack as it utilises stack hungry string
handling library calls. */
#define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )
/* The length of the queue used to send messages to the LCD task. */
#define mainQUEUE_SIZE ( 3 )
/*-----------------------------------------------------------*/
/*
@ -108,11 +142,6 @@ the jitter time in nano seconds. */
*/
static void prvSetupHardware( void );
/*
* Simply toggles the indicated LED.
*/
static void vToggleLED( unsigned portBASE_TYPE uxLED );
/*
* Very simple task that toggles an LED.
*/
@ -124,20 +153,29 @@ static void vLEDTask( void *pvParameters );
*/
extern void vuIP_Task( void *pvParameters );
/*
* The LCD gatekeeper task as described in the comments at the top of this file.
* */
static void vLCDTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* The queue used to send messages to the LCD task. */
xQueueHandle xLCDQueue;
/*-----------------------------------------------------------*/
int main( void )
{
long l;
/* Configure the hardware for use by this demo. */
prvSetupHardware();
/* Start the standard demo tasks. */
/* Start the standard demo tasks. These are just here to exercise the
kernel port and provide examples of how the FreeRTOS API can be used. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
@ -147,34 +185,36 @@ long l;
vStartQueuePeekTasks();
vStartRecursiveMutexTasks();
/* Start 8 tasks, each of which toggles a different LED at a different rate. */
for( l = 0; l < NUM_LEDS; l++ )
/* Start the tasks that toggle LEDs - the LED to toggle is passed in as the
task parameter. */
for( l = 0; l < mainNUM_LED_TASKS; l++ )
{
xTaskCreate( vLEDTask, (signed char *) "LED", configMINIMAL_STACK_SIZE, ( void * ) l, tskIDLE_PRIORITY+1, NULL );
xTaskCreate( vLEDTask, (signed char *) "LED", configMINIMAL_STACK_SIZE, ( void * ) l, tskIDLE_PRIORITY, NULL );
}
/* Create the uIP task. This uses the lwIP RTOS abstraction layer.*/
xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
/* Create the uIP task. The WEB server runs in this task. */
xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );
/* Create the queue used by the LCD task. Messages for display on the LCD
are received via this queue. */
xLCDQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( xLCDMessage ) );
/* Start the tasks defined within this file/specific to this demo. */
xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE * 2, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
/* Start the LCD gatekeeper task - as described in the comments at the top
of this file. */
xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE * 2, NULL, mainLCD_TASK_PRIORITY, NULL );
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. */
task. The idle task is created within vTaskStartScheduler(). */
for( ;; );
}
/*-----------------------------------------------------------*/
static void vLEDTask( void *pvParameters )
{
/* The LED to toggle is passed in as the task paramter. */
/* The LED to toggle is passed in as the task parameter. */
long lLED = ( long ) pvParameters;
unsigned long ulLEDToToggle = 1 << lLED;
@ -183,46 +223,149 @@ unsigned long ulDelayPeriod = 100 * ( lLED + 1 );
for( ;; )
{
/* Delay for the calculated time. */
vTaskDelay( ulDelayPeriod );
/* Toggle the LED before going back to delay again. */
vToggleLED( ulLEDToToggle );
}
}
/*-----------------------------------------------------------*/
static void vToggleLED( unsigned portBASE_TYPE uxLED )
void vLCDTask( void *pvParameters )
{
if( FIO2PIN & uxLED )
xLCDMessage xMessage;
unsigned long ulRow = 0;
char cIPAddr[ 17 ]; /* To fit max IP address length of xxx.xxx.xxx.xxx\0 */
( void ) pvParameters;
/* The LCD gatekeeper task as described in the comments at the top of this
file. */
/* Initialise the LCD and display a startup message that includes the
configured IP address. */
LCD_init();
LCD_cur_off();
LCD_cls();
LCD_gotoxy( 1, 1 );
LCD_puts( "www.FreeRTOS.org" );
LCD_gotoxy( 1, 2 );
sprintf( cIPAddr, "%d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
LCD_puts( cIPAddr );
for( ;; )
{
FIO2CLR = uxLED;
/* Wait for a message to arrive to be displayed. */
while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );
/* Clear the old message. */
LCD_cls();
/* Switch LCD rows, jut to make it obvious that messages are arriving. */
ulRow++;
LCD_gotoxy( 1, ( ulRow & 0x01 ) + 1 );
/* Display the received text. */
LCD_puts( xMessage.pcMessage );
}
else
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
static xLCDMessage xMessage = { "PASS" };
static unsigned portLONG ulTicksSinceLastDisplay = 0;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Called from every tick interrupt as described in the comments at the top
of this file.
Have enough ticks passed to make it time to perform our health status
check again? */
ulTicksSinceLastDisplay++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
FIO2SET = uxLED;
/* Reset the counter so these checks run again in mainCHECK_DELAY
ticks time. */
ulTicksSinceLastDisplay = 0;
/* Has an error been found in any task? */
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: GEN Q";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: PEEK Q";
}
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: BLOCK Q";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: BLOCK TIME";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: SEMAPHR";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: POLL Q";
}
else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: INT MATH";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR: REC MUTEX";
}
/* Send the message to the OLED gatekeeper for display. The
xHigherPriorityTaskWoken parameter is not actually used here
as this function is running in the tick interrupt anyway - but
it must still be supplied. */
xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );
}
}
/*-----------------------------------------------------------*/
void prvSetupHardware( void )
{
PCONP = 0; /* Disable peripherals power. */
PCONP = PCONP_PCGPIO; /* Enable GPIO power. */
PINSEL10 = 0; /* Disable TPIU. */
/* Disable peripherals power. */
PCONP = 0;
/* Enable GPIO power. */
PCONP = PCONP_PCGPIO;
PLL0CON &= ~PLLCON_PLLC; /* Disconnect the main PLL. */
/* Disable TPIU. */
PINSEL10 = 0;
/* Disconnect the main PLL. */
PLL0CON &= ~PLLCON_PLLC;
PLL0FEED = PLLFEED_FEED1;
PLL0FEED = PLLFEED_FEED2;
while ((PLL0STAT & PLLSTAT_PLLC) != 0);
PLL0CON &= ~PLLCON_PLLE; /* Turn off the main PLL. */
/* Turn off the main PLL. */
PLL0CON &= ~PLLCON_PLLE;
PLL0FEED = PLLFEED_FEED1;
PLL0FEED = PLLFEED_FEED2;
while ((PLL0STAT & PLLSTAT_PLLE) != 0);
CCLKCFG = 0; /* No CPU clock divider. */
SCS = 0x20; /* OSCEN. */
/* No CPU clock divider. */
CCLKCFG = 0;
/* OSCEN. */
SCS = 0x20;
while ((SCS & 0x40) == 0);
CLKSRCSEL = 1; /* Use main oscillator. */
/* Use main oscillator. */
CLKSRCSEL = 1;
PLL0CFG = (PLLCFG_MUL16 | PLLCFG_DIV1);
PLL0FEED = PLLFEED_FEED1;
@ -234,7 +377,8 @@ void prvSetupHardware( void )
PLL0FEED = PLLFEED_FEED1;
PLL0FEED = PLLFEED_FEED2;
CCLKCFG = 5; /* 6x CPU clock divider (72 MHz) */
/* 6x CPU clock divider (72 MHz) */
CCLKCFG = 5;
/* Wait for the PLL to lock. */
while ((PLL0STAT & PLLSTAT_PLOCK) == 0);
@ -256,6 +400,8 @@ void prvSetupHardware( void )
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName )
{
/* This function will get called if a task overflows its stack. */
( void ) pxTask;
( void ) pcTaskName;
@ -265,8 +411,17 @@ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTask
void vConfigureTimerForRunTimeStats( void )
{
const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
/* This function configures a timer that is used as the time base when
collecting run time statistical information - basically the percentage
of CPU time that each task is utilising. It is called automatically when
the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
to 1. */
/* Power up and feed the timer. */
PCONP |= 0x02UL;
_PCLKSEL0 = (_PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
/* Reset Timer 0 */
T0TCR = TCR_COUNT_RESET;
@ -283,32 +438,3 @@ void vConfigureTimerForRunTimeStats( void )
}
/*-----------------------------------------------------------*/
void vLCDTask( void *pvParameters )
{
xLCDMessage xMessage;
char cIPAddr[ 17 ]; /* To fit max IP address length of xxx.xxx.xxx.xxx\0 */
( void ) pvParameters;
/* Initialise the LCD and display a startup message. */
LCD_init();
LCD_cur_off();
LCD_cls();
LCD_gotoxy( 1, 1 );
LCD_puts( "www.FreeRTOS.org" );
LCD_gotoxy( 1, 2 );
sprintf( cIPAddr, "%d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
LCD_puts( cIPAddr );
for( ;; )
{
/* Wait for a message to arrive that requires displaying. */
while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );
/* Display the message. Print each message to a different position. */
LCD_cls();
LCD_gotoxy( ( xMessage.xColumn & 0x07 ) + 1, ( xMessage.xColumn & 0x01 ) + 1 );
LCD_puts( xMessage.pcMessage );
}
}
/*-----------------------------------------------------------*/

@ -1,6 +1,5 @@
/******************************************************************
***** *****
***** Name: cs8900.c *****
***** Ver.: 1.0 *****
***** Date: 07/05/2001 *****
***** Auth: Andreas Dannenberg *****
@ -16,416 +15,451 @@
******************************************************************/
/* Adapted from file originally written by Andreas Dannenberg. Supplied with permission. */
#include "FreeRTOS.h"
#include "semphr.h"
#include "semphr.h"
#include "task.h"
#include "emac.h"
#include "LPC17xx_defs.h"
#define configPINSEL2_VALUE 0x50150105
#define configPINSEL2_VALUE 0x50150105
/* The semaphore used to wake the uIP task when data arives. */
xSemaphoreHandle xEMACSemaphore = NULL;
static unsigned short *rptr;
static unsigned short *tptr;
xSemaphoreHandle xEMACSemaphore = NULL;
// easyWEB internal function
// help function to swap the byte order of a WORD
static unsigned short *rptr;
static unsigned short *tptr;
static unsigned short SwapBytes(unsigned short Data)
static unsigned short SwapBytes( unsigned short Data )
{
return (Data >> 8) | (Data << 8);
return( Data >> 8 ) | ( Data << 8 );
}
// Keil: function added to write PHY
void write_PHY (int PhyReg, int Value)
int write_PHY( int PhyReg, int Value )
{
unsigned int tout;
const unsigned int uiMaxTime = 10;
MAC_MADR = DP83848C_DEF_ADR | PhyReg;
MAC_MWTD = Value;
/* Wait utill operation completed */
tout = 0;
for (tout = 0; tout < uiMaxTime; tout++) {
if ((MAC_MIND & MIND_BUSY) == 0) {
break;
}
vTaskDelay( 2 );
}
unsigned int tout;
const unsigned int uiMaxTime = 10;
MAC_MADR = DP83848C_DEF_ADR | PhyReg;
MAC_MWTD = Value;
/* Wait utill operation completed */
tout = 0;
for( tout = 0; tout < uiMaxTime; tout++ )
{
if( (MAC_MIND & MIND_BUSY) == 0 )
{
break;
}
vTaskDelay( 2 );
}
if( tout < uiMaxTime )
{
return pdPASS;
}
else
{
return pdFAIL;
}
}
// Keil: function added to read PHY
unsigned short read_PHY (unsigned char PhyReg)
unsigned short read_PHY( unsigned char PhyReg, portBASE_TYPE *pxStatus )
{
unsigned int tout;
const unsigned int uiMaxTime = 10;
MAC_MADR = DP83848C_DEF_ADR | PhyReg;
MAC_MCMD = MCMD_READ;
/* Wait until operation completed */
tout = 0;
for (tout = 0; tout < uiMaxTime; tout++) {
if ((MAC_MIND & MIND_BUSY) == 0) {
break;
}
vTaskDelay( 2 );
}
MAC_MCMD = 0;
return (MAC_MRDD);
}
unsigned int tout;
const unsigned int uiMaxTime = 10;
MAC_MADR = DP83848C_DEF_ADR | PhyReg;
MAC_MCMD = MCMD_READ;
/* Wait until operation completed */
tout = 0;
for( tout = 0; tout < uiMaxTime; tout++ )
{
if( (MAC_MIND & MIND_BUSY) == 0 )
{
break;
}
vTaskDelay( 2 );
}
MAC_MCMD = 0;
if( tout >= uiMaxTime )
{
*pxStatus = pdFAIL;
}
return( MAC_MRDD );
}
// Keil: function added to initialize Rx Descriptors
void rx_descr_init (void)
void rx_descr_init( void )
{
unsigned int i;
for (i = 0; i < NUM_RX_FRAG; i++) {
RX_DESC_PACKET(i) = RX_BUF(i);
RX_DESC_CTRL(i) = RCTRL_INT | (ETH_FRAG_SIZE-1);
RX_STAT_INFO(i) = 0;
RX_STAT_HASHCRC(i) = 0;
}
/* Set EMAC Receive Descriptor Registers. */
MAC_RXDESCRIPTOR = RX_DESC_BASE;
MAC_RXSTATUS = RX_STAT_BASE;
MAC_RXDESCRIPTORNUM = NUM_RX_FRAG-1;
/* Rx Descriptors Point to 0 */
MAC_RXCONSUMEINDEX = 0;
unsigned int i;
for( i = 0; i < NUM_RX_FRAG; i++ )
{
RX_DESC_PACKET( i ) = RX_BUF( i );
RX_DESC_CTRL( i ) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );
RX_STAT_INFO( i ) = 0;
RX_STAT_HASHCRC( i ) = 0;
}
/* Set EMAC Receive Descriptor Registers. */
MAC_RXDESCRIPTOR = RX_DESC_BASE;
MAC_RXSTATUS = RX_STAT_BASE;
MAC_RXDESCRIPTORNUM = NUM_RX_FRAG - 1;
/* Rx Descriptors Point to 0 */
MAC_RXCONSUMEINDEX = 0;
}
// Keil: function added to initialize Tx Descriptors
void tx_descr_init (void) {
unsigned int i;
for (i = 0; i < NUM_TX_FRAG; i++) {
TX_DESC_PACKET(i) = TX_BUF(i);
TX_DESC_CTRL(i) = 0;
TX_STAT_INFO(i) = 0;
}
/* Set EMAC Transmit Descriptor Registers. */
MAC_TXDESCRIPTOR = TX_DESC_BASE;
MAC_TXSTATUS = TX_STAT_BASE;
MAC_TXDESCRIPTORNUM = NUM_TX_FRAG-1;
/* Tx Descriptors Point to 0 */
MAC_TXPRODUCEINDEX = 0;
void tx_descr_init( void )
{
unsigned int i;
for( i = 0; i < NUM_TX_FRAG; i++ )
{
TX_DESC_PACKET( i ) = TX_BUF( i );
TX_DESC_CTRL( i ) = 0;
TX_STAT_INFO( i ) = 0;
}
/* Set EMAC Transmit Descriptor Registers. */
MAC_TXDESCRIPTOR = TX_DESC_BASE;
MAC_TXSTATUS = TX_STAT_BASE;
MAC_TXDESCRIPTORNUM = NUM_TX_FRAG - 1;
/* Tx Descriptors Point to 0 */
MAC_TXPRODUCEINDEX = 0;
}
// configure port-pins for use with LAN-controller,
// reset it and send the configuration-sequence
portBASE_TYPE Init_EMAC(void)
portBASE_TYPE Init_EMAC( void )
{
portBASE_TYPE xReturn = pdPASS;
// Keil: function modified to access the EMAC
// Initializes the EMAC ethernet controller
volatile unsigned int regv,tout,id1,id2;
/* Enable P1 Ethernet Pins. */
PINSEL2 = configPINSEL2_VALUE;
PINSEL3 = (PINSEL3 & ~0x0000000F) | 0x00000005;
/* Power Up the EMAC controller. */
PCONP |= PCONP_PCENET;
vTaskDelay( 2 );
/* Reset all EMAC internal modules. */
MAC_MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
MAC_COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;
/* A short delay after reset. */
vTaskDelay( 2 );
/* Initialize MAC control registers. */
MAC_MAC1 = MAC1_PASS_ALL;
MAC_MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
MAC_MAXF = ETH_MAX_FLEN;
MAC_CLRT = CLRT_DEF;
MAC_IPGR = IPGR_DEF;
/* Enable Reduced MII interface. */
MAC_COMMAND = CR_RMII | CR_PASS_RUNT_FRM;
/* Reset Reduced MII Logic. */
MAC_SUPP = SUPP_RES_RMII;
vTaskDelay( 2 );
MAC_SUPP = 0;
/* Put the PHY in reset mode */
write_PHY (PHY_REG_BMCR, 0x8000);
write_PHY (PHY_REG_BMCR, 0x8000);
/* Wait for hardware reset to end. */
for (tout = 0; tout < 100; tout++) {
vTaskDelay( 10 );
regv = read_PHY (PHY_REG_BMCR);
if (!(regv & 0x8000)) {
/* Reset complete */
break;
}
}
/* Set the Ethernet MAC Address registers */
MAC_SA0 = (emacETHADDR0 << 8) | emacETHADDR1;
MAC_SA1 = (emacETHADDR2 << 8) | emacETHADDR3;
MAC_SA2 = (emacETHADDR4 << 8) | emacETHADDR5;
/* Initialize Tx and Rx DMA Descriptors */
rx_descr_init ();
tx_descr_init ();
/* Receive Broadcast and Perfect Match Packets */
MAC_RXFILTERCTRL = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
/* Create the semaphore used ot wake the uIP task. */
vSemaphoreCreateBinary( xEMACSemaphore );
/* Check if this is a DP83848C PHY. */
id1 = read_PHY (PHY_REG_IDR1);
id2 = read_PHY (PHY_REG_IDR2);
if (((id1 << 16) | (id2 & 0xFFF0)) == DP83848C_ID) {
/* Configure the PHY device */
/* Use autonegotiation about the link speed. */
write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
/* Wait to complete Auto_Negotiation. */
for (tout = 0; tout < 10; tout++) {
vTaskDelay( 100 );
regv = read_PHY (PHY_REG_BMSR);
if (regv & 0x0020) {
/* Autonegotiation Complete. */
break;
}
}
}
else
{
xReturn = pdFAIL;
}
/* Check the link status. */
if( xReturn == pdPASS )
{
xReturn = pdFAIL;
for (tout = 0; tout < 10; tout++) {
vTaskDelay( 100 );
regv = read_PHY (PHY_REG_STS);
if (regv & 0x0001) {
/* Link is on. */
xReturn = pdPASS;
break;
}
}
}
if( xReturn == pdPASS )
{
/* Configure Full/Half Duplex mode. */
if (regv & 0x0004) {
/* Full duplex is enabled. */
MAC_MAC2 |= MAC2_FULL_DUP;
MAC_COMMAND |= CR_FULL_DUP;
MAC_IPGT = IPGT_FULL_DUP;
}
else {
/* Half duplex mode. */
MAC_IPGT = IPGT_HALF_DUP;
}
/* Configure 100MBit/10MBit mode. */
if (regv & 0x0002) {
/* 10MBit mode. */
MAC_SUPP = 0;
}
else {
/* 100MBit mode. */
MAC_SUPP = SUPP_SPEED;
}
/* Reset all interrupts */
MAC_INTCLEAR = 0xFFFF;
/* Enable receive and transmit mode of MAC Ethernet core */
MAC_COMMAND |= (CR_RX_EN | CR_TX_EN);
MAC_MAC1 |= MAC1_REC_EN;
}
return xReturn;
portBASE_TYPE xReturn = pdPASS;
// Keil: function modified to access the EMAC
// Initializes the EMAC ethernet controller
volatile unsigned int regv, tout, id1, id2;
/* Enable P1 Ethernet Pins. */
PINSEL2 = configPINSEL2_VALUE;
PINSEL3 = ( PINSEL3 &~0x0000000F ) | 0x00000005;
/* Power Up the EMAC controller. */
PCONP |= PCONP_PCENET;
vTaskDelay( 2 );
/* Reset all EMAC internal modules. */
MAC_MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;
MAC_COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;
/* A short delay after reset. */
vTaskDelay( 2 );
/* Initialize MAC control registers. */
MAC_MAC1 = MAC1_PASS_ALL;
MAC_MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
MAC_MAXF = ETH_MAX_FLEN;
MAC_CLRT = CLRT_DEF;
MAC_IPGR = IPGR_DEF;
/* Enable Reduced MII interface. */
MAC_COMMAND = CR_RMII | CR_PASS_RUNT_FRM;
/* Reset Reduced MII Logic. */
MAC_SUPP = SUPP_RES_RMII;
vTaskDelay( 2 );
MAC_SUPP = 0;
/* Put the PHY in reset mode */
write_PHY( PHY_REG_BMCR, 0x8000 );
xReturn = write_PHY( PHY_REG_BMCR, 0x8000 );
/* Wait for hardware reset to end. */
for( tout = 0; tout < 100; tout++ )
{
vTaskDelay( 10 );
regv = read_PHY( PHY_REG_BMCR, &xReturn );
if( !(regv & 0x8000) )
{
/* Reset complete */
break;
}
}
/* Check if this is a DP83848C PHY. */
id1 = read_PHY( PHY_REG_IDR1, &xReturn );
id2 = read_PHY( PHY_REG_IDR2, &xReturn );
if( ((id1 << 16) | (id2 & 0xFFF0)) == DP83848C_ID )
{
/* Set the Ethernet MAC Address registers */
MAC_SA0 = ( emacETHADDR0 << 8 ) | emacETHADDR1;
MAC_SA1 = ( emacETHADDR2 << 8 ) | emacETHADDR3;
MAC_SA2 = ( emacETHADDR4 << 8 ) | emacETHADDR5;
/* Initialize Tx and Rx DMA Descriptors */
rx_descr_init();
tx_descr_init();
/* Receive Broadcast and Perfect Match Packets */
MAC_RXFILTERCTRL = RFC_UCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;
/* Create the semaphore used ot wake the uIP task. */
vSemaphoreCreateBinary( xEMACSemaphore );
/* Configure the PHY device */
/* Use autonegotiation about the link speed. */
if( write_PHY(PHY_REG_BMCR, PHY_AUTO_NEG) )
{
/* Wait to complete Auto_Negotiation. */
for( tout = 0; tout < 10; tout++ )
{
vTaskDelay( 100 );
regv = read_PHY( PHY_REG_BMSR, &xReturn );
if( regv & 0x0020 )
{
/* Autonegotiation Complete. */
break;
}
}
}
}
else
{
xReturn = pdFAIL;
}
/* Check the link status. */
if( xReturn == pdPASS )
{
xReturn = pdFAIL;
for( tout = 0; tout < 10; tout++ )
{
vTaskDelay( 100 );
regv = read_PHY( PHY_REG_STS, &xReturn );
if( regv & 0x0001 )
{
/* Link is on. */
xReturn = pdPASS;
break;
}
}
}
if( xReturn == pdPASS )
{
/* Configure Full/Half Duplex mode. */
if( regv & 0x0004 )
{
/* Full duplex is enabled. */
MAC_MAC2 |= MAC2_FULL_DUP;
MAC_COMMAND |= CR_FULL_DUP;
MAC_IPGT = IPGT_FULL_DUP;
}
else
{
/* Half duplex mode. */
MAC_IPGT = IPGT_HALF_DUP;
}
/* Configure 100MBit/10MBit mode. */
if( regv & 0x0002 )
{
/* 10MBit mode. */
MAC_SUPP = 0;
}
else
{
/* 100MBit mode. */
MAC_SUPP = SUPP_SPEED;
}
/* Reset all interrupts */
MAC_INTCLEAR = 0xFFFF;
/* Enable receive and transmit mode of MAC Ethernet core */
MAC_COMMAND |= ( CR_RX_EN | CR_TX_EN );
MAC_MAC1 |= MAC1_REC_EN;
}
return xReturn;
}
// reads a word in little-endian byte order from RX_BUFFER
unsigned short ReadFrame_EMAC(void)
unsigned short ReadFrame_EMAC( void )
{
return (*rptr++);
return( *rptr++ );
}
// reads a word in big-endian byte order from RX_FRAME_PORT
// (useful to avoid permanent byte-swapping while reading
// TCP/IP-data)
unsigned short ReadFrameBE_EMAC(void)
unsigned short ReadFrameBE_EMAC( void )
{
unsigned short ReturnValue;
unsigned short ReturnValue;
ReturnValue = SwapBytes (*rptr++);
return (ReturnValue);
ReturnValue = SwapBytes( *rptr++ );
return( ReturnValue );
}
// copies bytes from frame port to MCU-memory
// NOTES: * an odd number of byte may only be transfered
// if the frame is read to the end!
// * MCU-memory MUST start at word-boundary
void CopyFromFrame_EMAC(void *Dest, unsigned short Size)
void CopyFromFrame_EMAC( void *Dest, unsigned short Size )
{
unsigned short * piDest; // Keil: Pointer added to correct expression
piDest = Dest; // Keil: Line added
while (Size > 1) {
*piDest++ = ReadFrame_EMAC();
Size -= 2;
}
if (Size) { // check for leftover byte...
*(unsigned char *)piDest = (char)ReadFrame_EMAC();// the LAN-Controller will return 0
} // for the highbyte
unsigned short *piDest; // Keil: Pointer added to correct expression
piDest = Dest; // Keil: Line added
while( Size > 1 )
{
*piDest++ = ReadFrame_EMAC();
Size -= 2;
}
if( Size )
{ // check for leftover byte...
*( unsigned char * ) piDest = ( char ) ReadFrame_EMAC(); // the LAN-Controller will return 0
} // for the highbyte
}
// does a dummy read on frame-I/O-port
// NOTE: only an even number of bytes is read!
void DummyReadFrame_EMAC(unsigned short Size) // discards an EVEN number of bytes
{ // from RX-fifo
while (Size > 1) {
ReadFrame_EMAC();
Size -= 2;
}
void DummyReadFrame_EMAC( unsigned short Size ) // discards an EVEN number of bytes
{ // from RX-fifo
while( Size > 1 )
{
ReadFrame_EMAC();
Size -= 2;
}
}
// Reads the length of the received ethernet frame and checks if the
// Reads the length of the received ethernet frame and checks if the
// destination address is a broadcast message or not
// returns the frame length
unsigned short StartReadFrame(void) {
unsigned short RxLen;
unsigned int idx;
idx = MAC_RXCONSUMEINDEX;
RxLen = (RX_STAT_INFO(idx) & RINFO_SIZE) - 3;
rptr = (unsigned short *)RX_DESC_PACKET(idx);
return(RxLen);
unsigned short StartReadFrame( void )
{
unsigned short RxLen;
unsigned int idx;
idx = MAC_RXCONSUMEINDEX;
RxLen = ( RX_STAT_INFO(idx) & RINFO_SIZE ) - 3;
rptr = ( unsigned short * ) RX_DESC_PACKET( idx );
return( RxLen );
}
void EndReadFrame(void) {
unsigned int idx;
void EndReadFrame( void )
{
unsigned int idx;
/* DMA free packet. */
idx = MAC_RXCONSUMEINDEX;
/* DMA free packet. */
idx = MAC_RXCONSUMEINDEX;
if (++idx == NUM_RX_FRAG)
idx = 0;
if( ++idx == NUM_RX_FRAG )
{
idx = 0;
}
MAC_RXCONSUMEINDEX = idx;
MAC_RXCONSUMEINDEX = idx;
}
unsigned int CheckFrameReceived(void) { // Packet received ?
if (MAC_RXPRODUCEINDEX != MAC_RXCONSUMEINDEX) // more packets received ?
return(1);
else
return(0);
unsigned int CheckFrameReceived( void )
{
// Packet received ?
if( MAC_RXPRODUCEINDEX != MAC_RXCONSUMEINDEX )
{ // more packets received ?
return( 1 );
}
else
{
return( 0 );
}
}
unsigned int uiGetEMACRxData( unsigned char *ucBuffer )
{
unsigned int uiLen = 0;
unsigned int uiLen = 0;
if( MAC_RXPRODUCEINDEX != MAC_RXCONSUMEINDEX )
{
uiLen = StartReadFrame();
CopyFromFrame_EMAC( ucBuffer, uiLen );
EndReadFrame();
}
if( MAC_RXPRODUCEINDEX != MAC_RXCONSUMEINDEX )
{
uiLen = StartReadFrame();
CopyFromFrame_EMAC( ucBuffer, uiLen );
EndReadFrame();
}
return uiLen;
return uiLen;
}
// requests space in EMAC memory for storing an outgoing frame
void RequestSend(void)
void RequestSend( void )
{
unsigned int idx;
unsigned int idx;
idx = MAC_TXPRODUCEINDEX;
tptr = (unsigned short *)TX_DESC_PACKET(idx);
idx = MAC_TXPRODUCEINDEX;
tptr = ( unsigned short * ) TX_DESC_PACKET( idx );
}
// check if ethernet controller is ready to accept the
// frame we want to send
unsigned int Rdy4Tx(void)
unsigned int Rdy4Tx( void )
{
return (1); // the ethernet controller transmits much faster
} // than the CPU can load its buffers
return( 1 ); // the ethernet controller transmits much faster
} // than the CPU can load its buffers
// writes a word in little-endian byte order to TX_BUFFER
void WriteFrame_EMAC(unsigned short Data)
void WriteFrame_EMAC( unsigned short Data )
{
*tptr++ = Data;
*tptr++ = Data;
}
// copies bytes from MCU-memory to frame port
// NOTES: * an odd number of byte may only be transfered
// if the frame is written to the end!
// * MCU-memory MUST start at word-boundary
void CopyToFrame_EMAC(void *Source, unsigned int Size)
void CopyToFrame_EMAC( void *Source, unsigned int Size )
{
unsigned short * piSource;
piSource = Source;
Size = (Size + 1) & 0xFFFE; // round Size up to next even number
while (Size > 0) {
WriteFrame_EMAC(*piSource++);
Size -= 2;
}
unsigned short *piSource;
piSource = Source;
Size = ( Size + 1 ) & 0xFFFE; // round Size up to next even number
while( Size > 0 )
{
WriteFrame_EMAC( *piSource++ );
Size -= 2;
}
}
void DoSend_EMAC(unsigned short FrameSize)
void DoSend_EMAC( unsigned short FrameSize )
{
unsigned int idx;
unsigned int idx;
idx = MAC_TXPRODUCEINDEX;
TX_DESC_CTRL( idx ) = FrameSize | TCTRL_LAST;
if( ++idx == NUM_TX_FRAG )
{
idx = 0;
}
idx = MAC_TXPRODUCEINDEX;
TX_DESC_CTRL(idx) = FrameSize | TCTRL_LAST;
if (++idx == NUM_TX_FRAG) idx = 0;
MAC_TXPRODUCEINDEX = idx;
MAC_TXPRODUCEINDEX = idx;
}
void vEMAC_ISR( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */
MAC_INTCLEAR = 0xffff;
/* Clear the interrupt. */
MAC_INTCLEAR = 0xffff;
/* Ensure the uIP task is not blocked as data has arrived. */
xSemaphoreGiveFromISR( xEMACSemaphore, &xHigherPriorityTaskWoken );
/* Ensure the uIP task is not blocked as data has arrived. */
xSemaphoreGiveFromISR( xEMACSemaphore, &xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}

@ -54,6 +54,8 @@
#include <stdio.h>
#include <string.h>
#include "LED.h"
HTTPD_CGI_CALL(file, "file-stats", file_stats);
HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats);
HTTPD_CGI_CALL(net, "net-stats", net_stats);
@ -234,35 +236,27 @@ PT_THREAD(rtos_stats(struct httpd_state *s, char *ptr))
}
/*---------------------------------------------------------------------------*/
char *pcStatus[ 3 ];
char *pcStatus;
unsigned long ulString;
extern unsigned long uxParTextGetLED( unsigned long uxLED );
static unsigned short generate_io_state( void *arg )
{
( void ) arg;
// for( ulString = 0; ulString < 3; ulString++ )
// {
// if( uxParTextGetLED( ulString + 5 ) )
// {
// pcStatus[ ulString ] = "checked";
// }
// else
// {
// pcStatus[ ulString ] = "";
// }
// }
if( lGetLEDState( 1 << 7 ) == 0 )
{
pcStatus = "";
}
else
{
pcStatus = "checked";
}
sprintf( uip_appdata,
"<input type=\"checkbox\" name=\"LED0\" value=\"1\" %s>LED 2.5,"\
"<input type=\"checkbox\" name=\"LED1\" value=\"1\" %s>LED 2.6,"\
"<input type=\"checkbox\" name=\"LED2\" value=\"1\" %s>LED 2.7"\
"<input type=\"checkbox\" name=\"LED0\" value=\"1\" %s>LED 7"\
"<p>"\
"<input type=\"text\" name=\"LCD\" value=\"Enter LCD text\" size=\"16\">",
pcStatus[ 0 ],
pcStatus[ 1 ],
pcStatus[ 2 ] );
pcStatus );
return strlen( uip_appdata );
}

@ -270,8 +270,8 @@ PT_THREAD(handle_input(struct httpd_state *s))
/* Process any form input being sent to the server. */
{
extern void vApplicationProcessFormInput( char *pcInputString, long xInputLength );
vApplicationProcessFormInput( s->inputbuf, PSOCK_DATALEN(&s->sin) );
extern void vApplicationProcessFormInput( char *pcInputString );
vApplicationProcessFormInput( s->inputbuf );
}
strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));

@ -48,6 +48,7 @@
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
/* Standard includes. */
#include <string.h>
@ -65,9 +66,8 @@
/* Demo includes. */
#include "emac.h"
//#include "partest.h"
#include "LED.h"
//#include "LPC17xx_defs.h"
#include "LPC17xx.h"
#include "core_cm3.h"
/*-----------------------------------------------------------*/
@ -82,7 +82,6 @@
#define uipTOTAL_FRAME_HEADER_SIZE 54
#define MAC_INTENABLE (*(volatile unsigned long *)(EMAC_BASE + 0xFE4)) /* Interrupt enable reg */
/*-----------------------------------------------------------*/
/*
@ -275,12 +274,12 @@ struct uip_eth_addr xAddr;
}
/*-----------------------------------------------------------*/
void vApplicationProcessFormInput( portCHAR *pcInputString, portBASE_TYPE xInputLength )
void vApplicationProcessFormInput( portCHAR *pcInputString )
{
char *c, *pcText;
static portCHAR cMessageForDisplay[ 32 ];
extern xQueueHandle xLCDQueue;
//xLCDMessage xLCDMessage;
xLCDMessage xLCDMessage;
/* Process the form input sent by the IO page of the served HTML. */
@ -290,31 +289,15 @@ extern xQueueHandle xLCDQueue;
/* Turn LED's on or off in accordance with the check box status. */
if( strstr( c, "LED0=1" ) != NULL )
{
// vParTestSetLED( 5, 0 );
/* Set LED7. */
vSetLEDState( 1 << 7, 1 );
}
else
{
// vParTestSetLED( 5, 1 );
/* Clear LED7. */
vSetLEDState( 1 << 7, 0 );
}
if( strstr( c, "LED1=1" ) != NULL )
{
// vParTestSetLED( 6, 0 );
}
else
{
// vParTestSetLED( 6, 1 );
}
if( strstr( c, "LED2=1" ) != NULL )
{
// vParTestSetLED( 7, 0 );
}
else
{
// vParTestSetLED( 7, 1 );
}
/* Find the start of the text to be displayed on the LCD. */
pcText = strstr( c, "LCD=" );
pcText += strlen( "LCD=" );
@ -336,10 +319,9 @@ extern xQueueHandle xLCDQueue;
}
/* Write the message to the LCD. */
// strcpy( cMessageForDisplay, pcText );
// xLCDMessage.xColumn = 0;
// xLCDMessage.pcMessage = cMessageForDisplay;
// xQueueSend( xLCDQueue, &xLCDMessage, portMAX_DELAY );
strcpy( cMessageForDisplay, pcText );
xLCDMessage.pcMessage = cMessageForDisplay;
xQueueSend( xLCDQueue, &xLCDMessage, portMAX_DELAY );
}
}

Loading…
Cancel
Save