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,194 @@
/*
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
/*-----------------------------------------------------------
* 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 1
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( 96000000UL )
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 90 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 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 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
/* Run time stats gathering definitions. */
#ifdef __ICCARM__
/* The #ifdef just prevents this C specific syntax from being included in
assembly files. */
void vMainConfigureTimerForRunTimeStats( void );
unsigned long ulMainGetRunTimeCounterValue( void );
#endif
#define configGENERATE_RUN_TIME_STATS 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vMainConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() ulMainGetRunTimeCounterValue()
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /* 15 priority levels */
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
/******************************************************************************
* Network configuration constants follow from here.
*****************************************************************************/
/* MAC address configuration. */
#define configMAC_ADDR0 0x00
#define configMAC_ADDR1 0x12
#define configMAC_ADDR2 0x13
#define configMAC_ADDR3 0x10
#define configMAC_ADDR4 0x15
#define configMAC_ADDR5 0x11
/* IP address configuration. */
#define configIP_ADDR0 192
#define configIP_ADDR1 168
#define configIP_ADDR2 0
#define configIP_ADDR3 200
/* Netmask configuration. */
#define configNET_MASK0 255
#define configNET_MASK1 255
#define configNET_MASK2 255
#define configNET_MASK3 0
#define configPHY_ADDRESS 1
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,48 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x00080000;
define symbol __ICFEDIT_region_RAM_start__ = 0x1FFF0410;
define symbol __ICFEDIT_region_RAM_end__ = 0x20000000;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
define symbol __region_RAM2_start__ = 0x20000000;
define symbol __region_RAM2_end__ = 0x20010000;
define exported symbol __VECTOR_TABLE = 0x00000000;
define exported symbol __VECTOR_RAM = 0x1fff0000;
define exported symbol __BOOT_STACK_ADDRESS = __region_RAM2_end__ - 8; //0x2000FFF8;
define symbol __code_start__ = 0x00000410;
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__] | mem:[from __region_RAM2_start__ to __region_RAM2_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize manually { readwrite };
initialize manually { section .data};
initialize manually { section .textrw };
do not initialize { section .noinit };
define block CodeRelocate { section .textrw_init };
define block CodeRelocateRam { section .textrw };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:__code_start__ { readonly section .noinit };
place in ROM_region { readonly, block CodeRelocate};
place in RAM_region { readwrite, block CodeRelocateRam,
block CSTACK, block HEAP };

View file

@ -0,0 +1,25 @@
/*
* File: assert.h
* Purpose: Provide macro for software assertions
*
* Notes: assert_failed() defined in assert.c
*/
#ifndef _ASSERT_H_
#define _ASSERT_H_
/********************************************************************/
void assert_failed(char *, int);
#ifdef DEBUG_PRINT
#define ASSERT(expr) \
if (!(expr)) \
assert_failed(__FILE__, __LINE__)
#else
#define ASSERT(expr)
#endif
/********************************************************************/
#endif /* _ASSERT_H_ */

View file

@ -0,0 +1,76 @@
/*
* File: common.h
* Purpose: File to be included by all project files
*
* Notes:
*/
#ifndef _COMMON_H_
#define _COMMON_H_
/********************************************************************/
/*
* Debug prints ON (#define) or OFF (#undef)
*/
#define DEBUG
#define DEBUG_PRINT
/*
* Include the generic CPU header file
*/
#include "arm_cm4.h"
/*
* Include the platform specific header file
*/
#if (defined(TWR_K40X256))
#include "k40_tower.h"
#elif (defined(TWR_K53N512))
#include "k53_tower.h"
#elif (defined(TWR_K60N512))
#include "k60_tower.h"
#else
#error "No valid platform defined"
#endif
/*
* Include the cpu specific header file
*/
#if (defined(CPU_MK40N512VMD100))
#include <freescale/MK40N512VMD100.h>
#elif (defined(CPU_MK53N512VMD100))
#include <freescale/MK53N512CMD100.h>
#elif (defined(CPU_MK60N512VMD100))
#include <freescale/MK60N512VMD100.h>
#else
#error "No valid CPU defined"
#endif
/*
* Include any toolchain specfic header files
*/
#if (defined(CW))
#include "cw.h"
#elif (defined(IAR))
#include "iar.h"
#else
#warning "No toolchain specific header included"
#endif
/*
* Include common utilities
*/
#include "assert.h"
#include "io.h"
#include "startup.h"
#include "stdlib.h"
#if (defined(IAR))
#include "intrinsics.h"
#endif
/********************************************************************/
#endif /* _COMMON_H_ */

View file

@ -0,0 +1,16 @@
/*
* File: iar.h
* Purpose: Define constants used by IAR toolchain
*
* Notes:
*
*/
#ifndef _IAR_H_
#define _IAR_H_
/********************************************************************/
/********************************************************************/
#endif /* _IAR_H_ */

View file

@ -0,0 +1,29 @@
/*
* File: io.h
* Purpose: Serial Input/Output routines
*
*/
#ifndef _IO_H
#define _IO_H
/********************************************************************/
char
in_char(void);
void
out_char(char);
int
char_present(void);
int
printf(const char *, ... );
int
sprintf(char *, const char *, ... );
/********************************************************************/
#endif

View file

@ -0,0 +1,53 @@
/*
* File: queue.h
* Purpose: Implement a first in, first out linked list
*
* Notes:
*/
#ifndef _QUEUE_H_
#define _QUEUE_H_
/********************************************************************/
/*
* Individual queue node
*/
typedef struct NODE
{
struct NODE *next;
} QNODE;
/*
* Queue Struture - linked list of qentry items
*/
typedef struct
{
QNODE *head;
QNODE *tail;
} QUEUE;
/*
* Functions provided by queue.c
*/
void
queue_init(QUEUE *);
int
queue_isempty(QUEUE *);
void
queue_add(QUEUE *, QNODE *);
QNODE*
queue_remove(QUEUE *);
QNODE*
queue_peek(QUEUE *);
void
queue_move(QUEUE *, QUEUE *);
/********************************************************************/
#endif /* _QUEUE_H_ */

View file

@ -0,0 +1,93 @@
/*
* File: startup.c
* Purpose: Generic Kinetis startup code
*
* Notes:
*/
#include "common.h"
#if (defined(IAR))
#pragma section = ".data"
#pragma section = ".data_init"
#pragma section = ".bss"
#pragma section = "CodeRelocate"
#pragma section = "CodeRelocateRam"
#endif
/********************************************************************/
void
common_startup(void)
{
#if (defined(CW))
extern char __START_BSS[];
extern char __END_BSS[];
extern uint32 __DATA_ROM[];
extern uint32 __DATA_RAM[];
extern char __DATA_END[];
#endif
/* Declare a counter we'll use in all of the copy loops */
uint32 n;
/* Declare pointers for various data sections. These pointers
* are initialized using values pulled in from the linker file
*/
uint8 * data_ram, * data_rom, * data_rom_end;
uint8 * bss_start, * bss_end;
/* Get the addresses for the .data section (initialized data section) */
#if (defined(CW))
data_ram = (uint8 *)__DATA_RAM;
data_rom = (uint8 *)__DATA_ROM;
data_rom_end = (uint8 *)__DATA_END; /* This is actually a RAM address in CodeWarrior */
n = data_rom_end - data_ram;
#elif (defined(IAR))
data_ram = __section_begin(".data");
data_rom = __section_begin(".data_init");
data_rom_end = __section_end(".data_init");
n = data_rom_end - data_rom;
#endif
/* Copy initialized data from ROM to RAM */
while (n--)
*data_ram++ = *data_rom++;
/* Get the addresses for the .bss section (zero-initialized data) */
#if (defined(CW))
bss_start = (uint8 *)__START_BSS;
bss_end = (uint8 *)__END_BSS;
#elif (defined(IAR))
bss_start = __section_begin(".bss");
bss_end = __section_end(".bss");
#endif
/* Clear the zero-initialized data section */
n = bss_end - bss_start;
while(n--)
*bss_start++ = 0;
/* Get addresses for any code sections that need to be copied from ROM to RAM.
* The IAR tools have a predefined keyword that can be used to mark individual
* functions for execution from RAM. Add "__ramfunc" before the return type in
* the function prototype for any routines you need to execute from RAM instead
* of ROM. ex: __ramfunc void foo(void);
*/
#if (defined(IAR))
uint8* code_relocate_ram = __section_begin("CodeRelocateRam");
uint8* code_relocate = __section_begin("CodeRelocate");
uint8* code_relocate_end = __section_end("CodeRelocate");
/* Copy functions from ROM to RAM */
n = code_relocate_end - code_relocate;
while (n--)
*code_relocate_ram++ = *code_relocate++;
#endif
}
/********************************************************************/

View file

@ -0,0 +1,17 @@
/*
* File: startup.h
* Purpose: Determine cause of Reset and which processor is running
*
* Notes:
*/
#ifndef _STARTUP_H_
#define _STARTUP_H_
/********************************************************************/
void common_startup(void);
/********************************************************************/
#endif /* _STARTUP_H_ */

View file

@ -0,0 +1,156 @@
/*
* File: arm_cm4.c
* Purpose: Generic high-level routines for ARM Cortex M4 processors
*
* Notes:
*/
#include "common.h"
/***********************************************************************/
/*
* Configures the ARM system control register for STOP (deep sleep) mode
* and then executes the WFI instruction to enter the mode.
*
* Parameters:
* none
*
* Note: Might want to change this later to allow for passing in a parameter
* to optionally set the sleep on exit bit.
*/
void stop (void)
{
/* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */
SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;
/* WFI instruction will start entry into STOP mode */
asm("WFI");
}
/***********************************************************************/
/*
* Configures the ARM system control register for WAIT (sleep) mode
* and then executes the WFI instruction to enter the mode.
*
* Parameters:
* none
*
* Note: Might want to change this later to allow for passing in a parameter
* to optionally set the sleep on exit bit.
*/
void wait (void)
{
/* Clear the SLEEPDEEP bit to make sure we go into WAIT (sleep) mode instead
* of deep sleep.
*/
SCB_SCR &= ~SCB_SCR_SLEEPDEEP_MASK;
/* WFI instruction will start entry into WAIT mode */
asm("WFI");
}
/***********************************************************************/
/*
* Change the value of the vector table offset register to the specified value.
*
* Parameters:
* vtor new value to write to the VTOR
*/
void write_vtor (int vtor)
{
/* Write the VTOR with the new value */
SCB_VTOR = vtor;
}
/***********************************************************************/
/*
* Initialize the NVIC to enable the specified IRQ.
*
* NOTE: The function only initializes the NVIC to enable a single IRQ.
* Interrupts will also need to be enabled in the ARM core. This can be
* done using the EnableInterrupts macro.
*
* Parameters:
* irq irq number to be enabled (the irq number NOT the vector number)
*/
void enable_irq (int irq)
{
int div;
/* Determine which of the NVICISERs corresponds to the irq */
div = irq/32;
switch (div)
{
case 0x0:
NVICICPR0 = 1 << (irq%32);
NVICISER0 = 1 << (irq%32);
break;
case 0x1:
NVICICPR1 = 1 << (irq%32);
NVICISER1 = 1 << (irq%32);
break;
case 0x2:
NVICICPR2 = 1 << (irq%32);
NVICISER2 = 1 << (irq%32);
break;
}
}
/***********************************************************************/
/*
* Initialize the NVIC to disable the specified IRQ.
*
* NOTE: The function only initializes the NVIC to disable a single IRQ.
* If you want to disable all interrupts, then use the DisableInterrupts
* macro instead.
*
* Parameters:
* irq irq number to be disabled (the irq number NOT the vector number)
*/
void disable_irq (int irq)
{
int div;
/* Determine which of the NVICICERs corresponds to the irq */
div = irq/32;
switch (div)
{
case 0x0:
NVICICER0 = 1 << (irq%32);
break;
case 0x1:
NVICICER1 = 1 << (irq%32);
break;
case 0x2:
NVICICER2 = 1 << (irq%32);
break;
}
}
/***********************************************************************/
/*
* Initialize the NVIC to set specified IRQ priority.
*
* NOTE: The function only initializes the NVIC to set a single IRQ priority.
* Interrupts will also need to be enabled in the ARM core. This can be
* done using the EnableInterrupts macro.
*
* Parameters:
* irq irq number to be enabled (the irq number NOT the vector number)
* prio irq priority. 0-15 levels. 0 max priority
*/
void set_irq_priority (int irq, int prio)
{
/*irq priority pointer*/
uint8 *prio_reg;
/* Determine which of the NVICIPx corresponds to the irq */
prio_reg = (uint8 *)(((uint32)&NVICIP0) + irq);
/* Assign priority to IRQ */
*prio_reg = ( (prio&0xF) << (8 - ARM_INTERRUPT_LEVEL_BITS) );
}
/***********************************************************************/

View file

@ -0,0 +1,87 @@
/*
* File: arm_cm4.h
* Purpose: Definitions common to all ARM Cortex M4 processors
*
* Notes:
*/
#ifndef _CPU_ARM_CM4_H
#define _CPU_ARM_CM4_H
#include "common.h"
/*ARM Cortex M4 implementation for interrupt priority shift*/
#define ARM_INTERRUPT_LEVEL_BITS 4
/***********************************************************************/
// function prototypes for arm_cm4.c
void stop (void);
void wait (void);
void write_vtor (int);
void enable_irq (int);
void disable_irq (int);
void set_irq_priority (int, int);
/***********************************************************************/
/*!< Macro to enable all interrupts. */
#define EnableInterrupts asm(" CPSIE i");
/*!< Macro to disable all interrupts. */
#define DisableInterrupts asm(" CPSID i");
/***********************************************************************/
/*
* Misc. Defines
*/
#ifdef FALSE
#undef FALSE
#endif
#define FALSE (0)
#ifdef TRUE
#undef TRUE
#endif
#define TRUE (1)
#ifdef NULL
#undef NULL
#endif
#define NULL (0)
#ifdef ON
#undef ON
#endif
#define ON (1)
#ifdef OFF
#undef OFF
#endif
#define OFF (0)
/***********************************************************************/
/*
* The basic data types
*/
typedef unsigned char uint8; /* 8 bits */
typedef unsigned short int uint16; /* 16 bits */
typedef unsigned long int uint32; /* 32 bits */
typedef char int8; /* 8 bits */
typedef short int int16; /* 16 bits */
typedef int int32; /* 32 bits */
typedef volatile int8 vint8; /* 8 bits */
typedef volatile int16 vint16; /* 16 bits */
typedef volatile int32 vint32; /* 32 bits */
typedef volatile uint8 vuint8; /* 8 bits */
typedef volatile uint16 vuint16; /* 16 bits */
typedef volatile uint32 vuint32; /* 32 bits */
// function prototype for main function
void main(void);
/***********************************************************************/
#endif /* _CPU_ARM_CM4_H */

View file

@ -0,0 +1,36 @@
/*
* File: crt0.s
* Purpose: Lowest level routines for Kinetis.
*
* Notes:
*
*/
; AREA Crt0, CODE, READONLY ; name this block of code
SECTION .noinit : CODE
EXPORT __startup
__startup
MOV r0,#0 ; Initialize the GPRs
MOV r1,#0
MOV r2,#0
MOV r3,#0
MOV r4,#0
MOV r5,#0
MOV r6,#0
MOV r7,#0
MOV r8,#0
MOV r9,#0
MOV r10,#0
MOV r11,#0
MOV r12,#0
import start
BL start ; call the C code
__done
B __done
END

View file

@ -0,0 +1,121 @@
/*
* File: dma_channels.h
* Purpose: DMA request macros for use on Kinetis processors.
* This file gives default DMA channel assignments
* for all of the possible Kinetis module DMA requests.
*
*
* Notes: There are more DMA requests than DMA channels, so
* care should be taken to make sure that DMA channel
* assignments are unique for the modules that are
* being used at any time.
*/
#ifndef _DMA_CHANNELS_H
#define _DMA_CHANNELS_H
/********************************************************************/
/* NOTE: There are more DMA requests than DMA channels, so
* care should be taken to make sure that DMA channel
* assignments are unique for the modules that are
* being used at any time.
*
* It is recommended that you read the appropriate DMAMUX_CHCFGn
* register before updating it to verify it is 0x0. If the
* DMAMUX_CHCFGn register is not zero, then that indicates the
* selected DMA channel might already be in use by another peripheral
* (a more specific test would be to look for DMAMUX_CHCFGn[ENBL] set).
* The module's DMA configuration routine can return an error
* when this situation is detected.
*/
/* Default DMA channel assignments and module request macros */
/* UARTs */
#define DMA_UART0RX_CH 0
#define DMA_UART0TX_CH 1
#define DMA_UART1RX_CH 2
#define DMA_UART1TX_CH 3
#define DMA_UART2RX_CH 10
#define DMA_UART2TX_CH 11
#define DMA_UART3RX_CH 12
#define DMA_UART3TX_CH 13
#define DMA_UART4RX_CH 6
#define DMA_UART4TX_CH 7
#define DMA_UART5RX_CH 8
#define DMA_UART5TX_CH 9
/* SSI/SAI */
#define DMA_SSI0RX_CH 4
#define DMA_SSI0TX_CH 5
/* DSPIs */
#define DMA_DSPI0RX_CH 6
#define DMA_DSPI0TX_CH 7
#define DMA_DSPI1RX_CH 8
#define DMA_DSPI1TX_CH 9
#define DMA_DSPI2RX_CH 14
#define DMA_DSPI2TX_CH 15
/* I2Cs */
#define DMA_I2C0_CH 7
#define DMA_I2C1_CH 2
/* FTMs */
#define DMA_FTM0CH0_CH 5
#define DMA_FTM0CH1_CH 6
#define DMA_FTM0CH2_CH 3
#define DMA_FTM0CH3_CH 4
#define DMA_FTM0CH4_CH 12
#define DMA_FTM0CH5_CH 13
#define DMA_FTM0CH6_CH 14
#define DMA_FTM0CH7_CH 15
#define DMA_FTM1CH0_CH 10
#define DMA_FTM1CH1_CH 11
#define DMA_FTM2CH0_CH 0
#define DMA_FTM2CH1_CH 1
/* Ethernet timers */
#define DMA_ENETTMR0_CH 4
#define DMA_ENETTMR1_CH 8
#define DMA_ENETTMR2_CH 0
#define DMA_ENETTMR3_CH 15
/* ADCs */
#define DMA_ADC0_CH 12
#define DMA_ADC1_CH 3
/* HSCMPs */
#define DMA_HSCMP0_CH 13
#define DMA_HSCMP1_CH 2
#define DMA_HSCMP2_CH 9
/* 12-bit DAC */
#define DMA_12bDAC0_CH 14
/* CMT */
#define DMA_CMT_CH 5
/* PDB */
#define DMA_PDB_CH 10
/* GPIO Ports */
#define DMA_GPIOPORTA_CH 15
#define DMA_GPIOPORTB_CH 0
#define DMA_GPIOPORTC_CH 1
#define DMA_GPIOPORTD_CH 11
#define DMA_GPIOPORTE_CH 8
/********************************************************************/
#endif /* _DMA_CHANNELS_H */

View file

@ -0,0 +1,57 @@
/*
* File: k60_tower.h
* Purpose: Definitions for the Kinetis K60 tower card
*
* Notes:
*/
#ifndef __K60_TOWER_H__
#define __K60_TOWER_H__
#include "mcg.h"
/********************************************************************/
/* Global defines to use for all boards */
#define DEBUG_PRINT
/* Defines specific to the K60 tower board */
/* Define for the CPU on the K60 board */
#define CPU_MK60N512VMD100
/*
* System Bus Clock Info
*/
#define K60_CLK 1
#define REF_CLK XTAL8 /* value isn't used, but we still need something defined */
#define CORE_CLK_MHZ PLL96 /* 96MHz is only freq tested for a clock input*/
/*
* Serial Port Info
*/
/*
* Select the serial port that is being used below. Only one of the
* options should be uncommented at any time.
*/
//#define SERIAL_CARD // use this option for serial port on TWR-SER
#define OSJTAG // use this option for serial port over the OS-JTAG circuit
#if (defined(SERIAL_CARD))
#define TERM_PORT UART3_BASE_PTR
#define TERMINAL_BAUD 115200
#undef HW_FLOW_CONTROL
#elif (defined(OSJTAG))
#define TERM_PORT UART5_BASE_PTR
#define TERMINAL_BAUD 115200
#undef HW_FLOW_CONTROL
#else
#error "No valid serial port defined"
#endif
#endif /* __K60_TOWER_H__ */

View file

@ -0,0 +1,69 @@
/********************************************************************************/
/* FILENAME RegisterFile.h */
/* The current release of the documentation and header files does not include
* the system register file or the VBAT register file. This header file
* adds support for accessing both register files.
*
* Once the manual is updated to include the register files, this file
* will become obsolete.
*/
/********************************************************************************/
/* Register File - Peripheral instance base addresses */
/* Peripheral System Register File base pointer */
#define RFSYS_DATA_BASE_PTR ((RFDATA_MemMapPtr)0x40041000u)
/* Peripheral VBAT Register File base pointer */
#define RFVBAT_DATA_BASE_PTR ((RFDATA_MemMapPtr)0x4003E000u)
typedef struct RFDATA_MemMap {
uint32_t RFDATA [32]; /*!< Register file n, array offset: 0x0, array step: 0x4 */
} volatile *RFDATA_MemMapPtr;
/* ----------------------------------------------------------------------------
-- Register file - Register accessor macros
---------------------------------------------------------------------------- */
/* Register file - Register accessors */
#define RFSYS_DATA_REG(base,index) ((base)->RFDATA[index])
#define RFVBAT_DATA_REG(base,index) ((base)->RFDATA[index])
#define RFSYS_DATA0 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,0 )
#define RFSYS_DATA1 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,1 )
#define RFSYS_DATA2 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,2 )
#define RFSYS_DATA3 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,3 )
#define RFSYS_DATA4 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,4 )
#define RFSYS_DATA5 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,5 )
#define RFSYS_DATA6 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,6 )
#define RFSYS_DATA7 RFSYS_DATA_REG(RFSYS_DATA_BASE_PTR,7 )
#define RFVBAT_DATA0 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,0 )
#define RFVBAT_DATA1 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,1 )
#define RFVBAT_DATA2 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,2 )
#define RFVBAT_DATA3 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,3 )
#define RFVBAT_DATA4 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,4 )
#define RFVBAT_DATA5 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,5 )
#define RFVBAT_DATA6 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,6 )
#define RFVBAT_DATA7 RFVBAT_DATA_REG(RFVBAT_DATA_BASE_PTR,7 )
/* LL Bit Fields */
#define RF_DATA_LL_MASK 0x000000FFu
#define RF_DATA_LL_SHIFT 0
#define RF_DATA_LL(x) (((x)<<RF_DATA_LL_SHIFT)&RF_DATA_LL_MASK)
/* LH Bit Fields */
#define RF_DATA_LH_MASK 0x0000FF00u
#define RF_DATA_LH_SHIFT 8
#define RF_DATA_LH(x) (((x)<<RF_DATA_LH_SHIFT)&RF_DATA_LH_MASK)
/* HL Bit Fields */
#define RF_DATA_HL_MASK 0x00FF0000u
#define RF_DATA_HL_SHIFT 16
#define RF_DATA_HL(x) (((x)<<RF_DATA_HL_SHIFT)&RF_DATA_HL_MASK)
/* HH Bit Fields */
#define RF_DATA_HH_MASK 0xFF000000u
#define RF_DATA_HH_SHIFT 24
#define RF_DATA_HH(x) (((x)<<RF_DATA_HH_SHIFT)&RF_DATA_HH_MASK)
/*! \} */ /* end of group Register_File_Register_Accessor_Macros */

View file

@ -0,0 +1,86 @@
/*
* File: start.c
* Purpose: Kinetis start up routines.
*
* Notes:
*/
#include "start.h"
#include "common.h"
#include "wdog.h"
#include "sysinit.h"
/********************************************************************/
/*!
* \brief Kinetis Start
* \return None
*
* This function calls all of the needed starup routines and then
* branches to the main process.
*/
void start(void)
{
/* Disable the watchdog timer */
wdog_disable();
/* Copy any vector or data sections that need to be in RAM */
common_startup();
/* Perform processor initialization */
sysinit();
/* Determine the flash revision */
flash_identify();
/* Jump to main process */
main();
/* No actions to perform after this so wait forever */
while(1);
}
/********************************************************************/
/*!
* \brief flash Identify
* \return None
*
* This is primarly a reporting function that displays information
* about the specific flash parameters and flash version ID for
* the current device. These parameters are obtained using a special
* flash command call "read resource." The first four bytes returned
* are the flash parameter revision, and the second four bytes are
* the flash version ID.
*/
void flash_identify (void)
{
/* Get the flash parameter version */
/* Write the flash FCCOB registers with the values for a read resource command */
FTFL_FCCOB0 = 0x03;
FTFL_FCCOB1 = 0x00;
FTFL_FCCOB2 = 0x00;
FTFL_FCCOB3 = 0x00;
FTFL_FCCOB8 = 0x01;
/* All required FCCOBx registers are written, so launch the command */
FTFL_FSTAT = FTFL_FSTAT_CCIF_MASK;
/* Wait for the command to complete */
while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF_MASK));
/* Get the flash version ID */
/* Write the flash FCCOB registers with the values for a read resource command */
FTFL_FCCOB0 = 0x03;
FTFL_FCCOB1 = 0x00;
FTFL_FCCOB2 = 0x00;
FTFL_FCCOB3 = 0x04;
FTFL_FCCOB8 = 0x01;
/* All required FCCOBx registers are written, so launch the command */
FTFL_FSTAT = FTFL_FSTAT_CCIF_MASK;
/* Wait for the command to complete */
while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF_MASK));
}
/********************************************************************/

View file

@ -0,0 +1,12 @@
/*
* File: start.h
* Purpose: Kinetis start up routines.
*
* Notes:
*/
// Function prototypes
void _start(void);
void cpu_identify(void);
void flash_identify(void);

View file

@ -0,0 +1,132 @@
/*
* File: sysinit.c
* Purpose: Kinetis Configuration
* Initializes processor to a default state
*
* Notes:
*
*/
#include "common.h"
#include "sysinit.h"
#include "uart.h"
/********************************************************************/
/* Actual system clock frequency */
int core_clk_khz;
int core_clk_mhz;
int periph_clk_khz;
/********************************************************************/
void sysinit (void)
{
/*
* Enable all of the port clocks. These have to be enabled to configure
* pin muxing options, so most code will need all of these on anyway.
*/
SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK
| SIM_SCGC5_PORTB_MASK
| SIM_SCGC5_PORTC_MASK
| SIM_SCGC5_PORTD_MASK
| SIM_SCGC5_PORTE_MASK );
/* Ramp up the system clock */
core_clk_mhz = pll_init(CORE_CLK_MHZ, REF_CLK);
/*
* Use the value obtained from the pll_init function to define variables
* for the core clock in kHz and also the peripheral clock. These
* variables can be used by other functions that need awareness of the
* system frequency.
*/
core_clk_khz = core_clk_mhz * 1000;
periph_clk_khz = core_clk_khz / (((SIM_CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> 24)+ 1);
/* For debugging purposes, enable the trace clock and/or FB_CLK so that
* we'll be able to monitor clocks and know the PLL is at the frequency
* that we expect.
*/
trace_clk_init();
fb_clk_init();
/* Enable the pins for the selected UART */
if (TERM_PORT == UART0_BASE_PTR)
{
/* Enable the UART0_TXD function on PTD6 */
PORTD_PCR6 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
/* Enable the UART0_RXD function on PTD7 */
PORTD_PCR7 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
}
if (TERM_PORT == UART1_BASE_PTR)
{
/* Enable the UART1_TXD function on PTC4 */
PORTC_PCR4 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
/* Enable the UART1_RXD function on PTC3 */
PORTC_PCR3 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
}
if (TERM_PORT == UART2_BASE_PTR)
{
/* Enable the UART2_TXD function on PTD3 */
PORTD_PCR3 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
/* Enable the UART2_RXD function on PTD2 */
PORTD_PCR2 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
}
if (TERM_PORT == UART3_BASE_PTR)
{
/* Enable the UART3_TXD function on PTC17 */
PORTC_PCR17 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
/* Enable the UART3_RXD function on PTC16 */
PORTC_PCR16 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
}
if (TERM_PORT == UART4_BASE_PTR)
{
/* Enable the UART3_TXD function on PTC17 */
PORTE_PCR24 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
/* Enable the UART3_RXD function on PTC16 */
PORTE_PCR25 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
}
if (TERM_PORT == UART5_BASE_PTR)
{
/* Enable the UART3_TXD function on PTC17 */
PORTE_PCR8 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
/* Enable the UART3_RXD function on PTC16 */
PORTE_PCR9 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
}
/* UART0 and UART1 are clocked from the core clock, but all other UARTs are
* clocked from the peripheral clock. So we have to determine which clock
* to send to the uart_init function.
*/
if ((TERM_PORT == UART0_BASE_PTR) | (TERM_PORT == UART1_BASE_PTR))
uart_init (TERM_PORT, core_clk_khz, TERMINAL_BAUD);
else
uart_init (TERM_PORT, periph_clk_khz, TERMINAL_BAUD);
}
/********************************************************************/
void trace_clk_init(void)
{
/* Set the trace clock to the core clock frequency */
SIM_SOPT2 |= SIM_SOPT2_TRACECLKSEL_MASK;
/* Enable the TRACE_CLKOUT pin function on PTA6 (alt7 function) */
PORTA_PCR6 = ( PORT_PCR_MUX(0x7));
}
/********************************************************************/
void fb_clk_init(void)
{
/* Enable the clock to the FlexBus module */
SIM_SCGC7 |= SIM_SCGC7_FLEXBUS_MASK;
/* Enable the FB_CLKOUT function on PTC3 (alt5 function) */
PORTC_PCR3 = ( PORT_PCR_MUX(0x5));
}
/********************************************************************/

View file

@ -0,0 +1,17 @@
/*
* File: sysinit.h
* Purpose: Kinetis Configuration
* Initializes processor to a default state
*
* Notes:
*
*/
/********************************************************************/
// function prototypes
void sysinit (void);
void trace_clk_init(void);
void fb_clk_init(void);
void enable_abort_button(void);
/********************************************************************/

View file

@ -0,0 +1,306 @@
/******************************************************************************
* File: vectors.c
*
* Purpose: Configure interrupt vector table for Kinetis.
******************************************************************************/
#include "vectors.h"
#include "common.h"
/******************************************************************************
* Vector Table
******************************************************************************/
typedef void (*vector_entry)(void);
#if defined(IAR)
#pragma location = ".intvec"
const vector_entry __vector_table[] = //@ ".intvec" =
#elif defined(CW)
#pragma define_section vectortable ".vectortable" ".vectortable" ".vectortable" far_abs R
#define VECTOR __declspec(vectortable)
const VECTOR vector_entry __vector_table[] = //@ ".intvec" =
#endif
{
VECTOR_000, /* Initial SP */
VECTOR_001, /* Initial PC */
VECTOR_002,
VECTOR_003,
VECTOR_004,
VECTOR_005,
VECTOR_006,
VECTOR_007,
VECTOR_008,
VECTOR_009,
VECTOR_010,
VECTOR_011,
VECTOR_012,
VECTOR_013,
VECTOR_014,
VECTOR_015,
VECTOR_016,
VECTOR_017,
VECTOR_018,
VECTOR_019,
VECTOR_020,
VECTOR_021,
VECTOR_022,
VECTOR_023,
VECTOR_024,
VECTOR_025,
VECTOR_026,
VECTOR_027,
VECTOR_028,
VECTOR_029,
VECTOR_030,
VECTOR_031,
VECTOR_032,
VECTOR_033,
VECTOR_034,
VECTOR_035,
VECTOR_036,
VECTOR_037,
VECTOR_038,
VECTOR_039,
VECTOR_040,
VECTOR_041,
VECTOR_042,
VECTOR_043,
VECTOR_044,
VECTOR_045,
VECTOR_046,
VECTOR_047,
VECTOR_048,
VECTOR_049,
VECTOR_050,
VECTOR_051,
VECTOR_052,
VECTOR_053,
VECTOR_054,
VECTOR_055,
VECTOR_056,
VECTOR_057,
VECTOR_058,
VECTOR_059,
VECTOR_060,
VECTOR_061,
VECTOR_062,
VECTOR_063,
VECTOR_064,
VECTOR_065,
VECTOR_066,
VECTOR_067,
VECTOR_068,
VECTOR_069,
VECTOR_070,
VECTOR_071,
VECTOR_072,
VECTOR_073,
VECTOR_074,
VECTOR_075,
VECTOR_076,
VECTOR_077,
VECTOR_078,
VECTOR_079,
VECTOR_080,
VECTOR_081,
VECTOR_082,
VECTOR_083,
VECTOR_084,
VECTOR_085,
VECTOR_086,
VECTOR_087,
VECTOR_088,
VECTOR_089,
VECTOR_090,
VECTOR_091,
VECTOR_092,
VECTOR_093,
VECTOR_094,
VECTOR_095,
VECTOR_096,
VECTOR_097,
VECTOR_098,
VECTOR_099,
VECTOR_100,
VECTOR_101,
VECTOR_102,
VECTOR_103,
VECTOR_104,
VECTOR_105,
VECTOR_106,
VECTOR_107,
VECTOR_108,
VECTOR_109,
VECTOR_110,
VECTOR_111,
VECTOR_112,
VECTOR_113,
VECTOR_114,
VECTOR_115,
VECTOR_116,
VECTOR_117,
VECTOR_118,
VECTOR_119,
VECTOR_120,
VECTOR_121,
VECTOR_122,
VECTOR_123,
VECTOR_124,
VECTOR_125,
VECTOR_126,
VECTOR_127,
VECTOR_128,
VECTOR_129,
VECTOR_130,
VECTOR_131,
VECTOR_132,
VECTOR_133,
VECTOR_134,
VECTOR_135,
VECTOR_136,
VECTOR_137,
VECTOR_138,
VECTOR_139,
VECTOR_140,
VECTOR_141,
VECTOR_142,
VECTOR_143,
VECTOR_144,
VECTOR_145,
VECTOR_146,
VECTOR_147,
VECTOR_148,
VECTOR_149,
VECTOR_150,
VECTOR_151,
VECTOR_152,
VECTOR_153,
VECTOR_154,
VECTOR_155,
VECTOR_156,
VECTOR_157,
VECTOR_158,
VECTOR_159,
VECTOR_160,
VECTOR_161,
VECTOR_162,
VECTOR_163,
VECTOR_164,
VECTOR_165,
VECTOR_166,
VECTOR_167,
VECTOR_168,
VECTOR_169,
VECTOR_170,
VECTOR_171,
VECTOR_172,
VECTOR_173,
VECTOR_174,
VECTOR_175,
VECTOR_176,
VECTOR_177,
VECTOR_178,
VECTOR_179,
VECTOR_180,
VECTOR_181,
VECTOR_182,
VECTOR_183,
VECTOR_184,
VECTOR_185,
VECTOR_186,
VECTOR_187,
VECTOR_188,
VECTOR_189,
VECTOR_190,
VECTOR_191,
VECTOR_192,
VECTOR_193,
VECTOR_194,
VECTOR_195,
VECTOR_196,
VECTOR_197,
VECTOR_198,
VECTOR_199,
VECTOR_200,
VECTOR_201,
VECTOR_202,
VECTOR_203,
VECTOR_204,
VECTOR_205,
VECTOR_206,
VECTOR_207,
VECTOR_208,
VECTOR_209,
VECTOR_210,
VECTOR_211,
VECTOR_212,
VECTOR_213,
VECTOR_214,
VECTOR_215,
VECTOR_216,
VECTOR_217,
VECTOR_218,
VECTOR_219,
VECTOR_220,
VECTOR_221,
VECTOR_222,
VECTOR_223,
VECTOR_224,
VECTOR_225,
VECTOR_226,
VECTOR_227,
VECTOR_228,
VECTOR_229,
VECTOR_230,
VECTOR_231,
VECTOR_232,
VECTOR_233,
VECTOR_234,
VECTOR_235,
VECTOR_236,
VECTOR_237,
VECTOR_238,
VECTOR_239,
VECTOR_240,
VECTOR_241,
VECTOR_242,
VECTOR_243,
VECTOR_244,
VECTOR_245,
VECTOR_246,
VECTOR_247,
VECTOR_248,
VECTOR_249,
VECTOR_250,
VECTOR_251,
VECTOR_252,
VECTOR_253,
VECTOR_254,
VECTOR_255,
CONFIG_1,
CONFIG_2,
CONFIG_3,
CONFIG_4,
};
// VECTOR_TABLE end
/******************************************************************************
* default_isr(void)
*
* Default ISR definition.
*
* In: n/a
* Out: n/a
******************************************************************************/
//#if (defined(CW))
//__declspec(interrupt)
//#endif
void default_isr(void)
{
for( ;; );
}
/******************************************************************************/
/* End of "vectors.c" */

View file

@ -0,0 +1,304 @@
/******************************************************************************
* File: vectors.h
*
* Purpose: Provide custom interrupt service routines for Kinetis.
*
* NOTE: This vector table is a superset table, so interrupt sources might be
* listed that are not available on the specific Kinetis device you are
* using.
******************************************************************************/
#ifndef __VECTORS_H
#define __VECTORS_H 1
/* The kernel interrupts - in their CMSIS form. */
extern void SVC_Handler( void );
extern void PendSV_Handler( void );
extern void SysTick_Handler( void );
/* The button interrupt. */
extern void vPort_E_ISRHandler( void );
/* Ethernet interrupt handlers. */
void vEMAC_TxISRHandler( void );
void vEMAC_RxISRHandler( void );
void vEMAC_ErrorISRHandler( void );
// function prototype for default_isr in vectors.c
void default_isr(void);
void abort_isr(void);
void hard_fault_handler_c(unsigned int * hardfault_args);
/* Interrupt Vector Table Function Pointers */
typedef void pointer(void);
extern void __startup(void);
extern unsigned long __BOOT_STACK_ADDRESS[];
extern void __iar_program_start(void);
// Address Vector IRQ Source module Source description
#define VECTOR_000 (pointer*)__BOOT_STACK_ADDRESS // ARM core Initial Supervisor SP
#define VECTOR_001 __startup // 0x0000_0004 1 - ARM core Initial Program Counter
#define VECTOR_002 default_isr // 0x0000_0008 2 - ARM core Non-maskable Interrupt (NMI)
#define VECTOR_003 default_isr // 0x0000_000C 3 - ARM core Hard Fault
#define VECTOR_004 default_isr // 0x0000_0010 4 -
#define VECTOR_005 default_isr // 0x0000_0014 5 - ARM core Bus Fault
#define VECTOR_006 default_isr // 0x0000_0018 6 - ARM core Usage Fault
#define VECTOR_007 default_isr // 0x0000_001C 7 -
#define VECTOR_008 default_isr // 0x0000_0020 8 -
#define VECTOR_009 default_isr // 0x0000_0024 9 -
#define VECTOR_010 default_isr // 0x0000_0028 10 -
#define VECTOR_011 SVC_Handler // 0x0000_002C 11 - ARM core Supervisor call (SVCall)
#define VECTOR_012 default_isr // 0x0000_0030 12 - ARM core Debug Monitor
#define VECTOR_013 default_isr // 0x0000_0034 13 -
#define VECTOR_014 PendSV_Handler // 0x0000_0038 14 - ARM core Pendable request for system service (PendableSrvReq)
#define VECTOR_015 SysTick_Handler // 0x0000_003C 15 - ARM core System tick timer (SysTick)
#define VECTOR_016 default_isr // 0x0000_0040 16 0 DMA DMA Channel 0 transfer complete
#define VECTOR_017 default_isr // 0x0000_0044 17 1 DMA DMA Channel 1 transfer complete
#define VECTOR_018 default_isr // 0x0000_0048 18 2 DMA DMA Channel 2 transfer complete
#define VECTOR_019 default_isr // 0x0000_004C 19 3 DMA DMA Channel 3 transfer complete
#define VECTOR_020 default_isr // 0x0000_0050 20 4 DMA DMA Channel 4 transfer complete
#define VECTOR_021 default_isr // 0x0000_0054 21 5 DMA DMA Channel 5 transfer complete
#define VECTOR_022 default_isr // 0x0000_0058 22 6 DMA DMA Channel 6 transfer complete
#define VECTOR_023 default_isr // 0x0000_005C 23 7 DMA DMA Channel 7 transfer complete
#define VECTOR_024 default_isr // 0x0000_0060 24 8 DMA DMA Channel 8 transfer complete
#define VECTOR_025 default_isr // 0x0000_0064 25 9 DMA DMA Channel 9 transfer complete
#define VECTOR_026 default_isr // 0x0000_0068 26 10 DMA DMA Channel 10 transfer complete
#define VECTOR_027 default_isr // 0x0000_006C 27 11 DMA DMA Channel 11 transfer complete
#define VECTOR_028 default_isr // 0x0000_0070 28 12 DMA DMA Channel 12 transfer complete
#define VECTOR_029 default_isr // 0x0000_0074 29 13 DMA DMA Channel 13 transfer complete
#define VECTOR_030 default_isr // 0x0000_0078 30 14 DMA DMA Channel 14 transfer complete
#define VECTOR_031 default_isr // 0x0000_007C 31 15 DMA DMA Channel 15 transfer complete
#define VECTOR_032 default_isr // 0x0000_0080 32 16 DMA DMA Error Interrupt Channels 0-15
#define VECTOR_033 default_isr // 0x0000_0084 33 17 MCM Normal interrupt
#define VECTOR_034 default_isr // 0x0000_0088 34 18 Flash memory Command Complete
#define VECTOR_035 default_isr // 0x0000_008C 35 19 Flash memory Read Collision
#define VECTOR_036 default_isr // 0x0000_0090 36 20 Mode Controller Low Voltage Detect,Low Voltage Warning, Low Leakage Wakeup
#define VECTOR_037 default_isr // 0x0000_0094 37 21 LLWU
#define VECTOR_038 default_isr // 0x0000_0098 38 22 WDOG
#define VECTOR_039 default_isr // 0x0000_009C 39 23 RNGB
#define VECTOR_040 default_isr // 0x0000_00A0 40 24 I2C0
#define VECTOR_041 default_isr // 0x0000_00A4 41 25 I2C1
#define VECTOR_042 default_isr // 0x0000_00A8 42 26 SPI0 Single interrupt vector for all sources
#define VECTOR_043 default_isr // 0x0000_00AC 43 27 SPI1 Single interrupt vector for all sources
#define VECTOR_044 default_isr // 0x0000_00B0 44 28 SPI2 Single interrupt vector for all sources
#define VECTOR_045 default_isr // 0x0000_00B4 45 29 CAN0 OR'ed Message buffer (0-15)
#define VECTOR_046 default_isr // 0x0000_00B8 46 30 CAN0 Bus Off
#define VECTOR_047 default_isr // 0x0000_00BC 47 31 CAN0 Error
#define VECTOR_048 default_isr // 0x0000_00C0 48 32 CAN0 Transmit Warning
#define VECTOR_049 default_isr // 0x0000_00C4 49 33 CAN0 Receive Warning
#define VECTOR_050 default_isr // 0x0000_00C8 50 34 CAN0 Wake Up
#define VECTOR_051 default_isr // 0x0000_00CC 51 35 CAN0 Individual Matching Elements Update (IMEU)
#define VECTOR_052 default_isr // 0x0000_00D0 52 36 CAN0 Lost receive
#define VECTOR_053 default_isr // 0x0000_00D4 53 37 CAN1 OR'ed Message buffer (0-15)
#define VECTOR_054 default_isr // 0x0000_00D8 54 38 CAN1 Bus off
#define VECTOR_055 default_isr // 0x0000_00DC 55 39 CAN1 Error
#define VECTOR_056 default_isr // 0x0000_00E0 56 40 CAN1 Transmit Warning
#define VECTOR_057 default_isr // 0x0000_00E4 57 41 CAN1 Receive Warning
#define VECTOR_058 default_isr // 0x0000_00E8 58 42 CAN1 Wake Up
#define VECTOR_059 default_isr // 0x0000_00EC 59 43 CAN1 Individual Matching Elements Update (IMEU)
#define VECTOR_060 default_isr // 0x0000_00F0 60 44 CAN1 Lost receive
#define VECTOR_061 default_isr // 0x0000_00F4 61 45 UART0 Single interrupt vector for UART status sources
#define VECTOR_062 default_isr // 0x0000_00F8 62 46 UART0 Single interrupt vector for UART error sources
#define VECTOR_063 default_isr // 0x0000_00FC 63 47 UART1 Single interrupt vector for UART status sources
#define VECTOR_064 default_isr // 0x0000_0100 64 48 UART1 Single interrupt vector for UART error sources
#define VECTOR_065 default_isr // 0x0000_0104 65 49 UART2 Single interrupt vector for UART status sources
#define VECTOR_066 default_isr // 0x0000_0108 66 50 UART2 Single interrupt vector for UART error sources
#define VECTOR_067 default_isr // 0x0000_010C 67 51 UART3 Single interrupt vector for UART status sources
#define VECTOR_068 default_isr // 0x0000_0110 68 52 UART3 Single interrupt vector for UART error sources
#define VECTOR_069 default_isr // 0x0000_0114 69 53 UART4 Single interrupt vector for UART status sources
#define VECTOR_070 default_isr // 0x0000_0118 70 54 UART4 Single interrupt vector for UART error sources
#define VECTOR_071 default_isr // 0x0000_011C 71 55 UART5 Single interrupt vector for UART status sources
#define VECTOR_072 default_isr // 0x0000_0120 72 56 UART5 Single interrupt vector for UART error sources
#define VECTOR_073 default_isr // 0x0000_0124 73 57 ADC0
#define VECTOR_074 default_isr // 0x0000_0128 74 58 ADC1
#define VECTOR_075 default_isr // 0x0000_012C 75 59 CMP0 High-speed comparator
#define VECTOR_076 default_isr // 0x0000_0130 76 60 CMP1
#define VECTOR_077 default_isr // 0x0000_0134 77 61 CMP2
#define VECTOR_078 default_isr // 0x0000_0138 78 62 FTM0 Single interrupt vector for all sources
#define VECTOR_079 default_isr // 0x0000_013C 79 63 FTM1 Single interrupt vector for all sources
#define VECTOR_080 default_isr // 0x0000_0140 80 64 FTM2 Single interrupt vector for all sources
#define VECTOR_081 default_isr // 0x0000_0144 81 65 CMT
#define VECTOR_082 default_isr // 0x0000_0148 82 66 RTC Timer interrupt
#define VECTOR_083 default_isr // 0x0000_014C 83 67
#define VECTOR_084 default_isr // 0x0000_0150 84 68 PIT Channel 0
#define VECTOR_085 default_isr // 0x0000_0154 85 69 PIT Channel 1
#define VECTOR_086 default_isr // 0x0000_0158 86 70 PIT Channel 2
#define VECTOR_087 default_isr // 0x0000_015C 87 71 PIT Channel 3
#define VECTOR_088 default_isr // 0x0000_0160 88 72 PDB
#define VECTOR_089 default_isr // 0x0000_0164 89 73 USB OTG
#define VECTOR_090 default_isr // 0x0000_0168 90 74 USB Charger Detect
#define VECTOR_091 default_isr // 0x0000_016C 91 75 ENET IEEE 1588 Timer interrupt
#define VECTOR_092 vEMAC_TxISRHandler // 0x0000_0170 92 76 ENET Transmit interrupt
#define VECTOR_093 vEMAC_RxISRHandler // 0x0000_0174 93 77 ENET Receive interrupt
#define VECTOR_094 vEMAC_ErrorISRHandler // 0x0000_0178 94 78 ENET Error and miscellaneous interrupt
#define VECTOR_095 default_isr // 0x0000_017C 95 79 I2S
#define VECTOR_096 default_isr // 0x0000_0180 96 80 SDHC
#define VECTOR_097 default_isr // 0x0000_0184 97 81 DAC0
#define VECTOR_098 default_isr // 0x0000_0188 98 82 DAC1
#define VECTOR_099 default_isr // 0x0000_018C 99 83 TSI Single interrupt vector for all sources
#define VECTOR_100 default_isr // 0x0000_0190 100 84 MCG
#define VECTOR_101 default_isr // 0x0000_0194 101 85 Low Power Timer
#define VECTOR_102 default_isr // 0x0000_0198 102 86 Segment LCD Single interrupt vector for all sources
#define VECTOR_103 default_isr // 0x0000_019C 103 87 Port control module Pin Detect (Port A)
#define VECTOR_104 default_isr // 0x0000_01A0 104 88 Port control module Pin Detect (Port B)
#define VECTOR_105 default_isr // 0x0000_01A4 105 89 Port control module Pin Detect (Port C)
#define VECTOR_106 default_isr // 0x0000_01A8 106 90 Port control module Pin Detect (Port D)
#define VECTOR_107 vPort_E_ISRHandler // 0x0000_01AC 107 91 Port control module Pin Detect (Port E)
#define VECTOR_108 default_isr // 0x0000_01B0 108 92
#define VECTOR_109 default_isr // 0x0000_01B4 109 93
#define VECTOR_110 default_isr // 0x0000_01B8 110 94
#define VECTOR_111 default_isr // 0x0000_01BC 111 95
#define VECTOR_112 default_isr // 0x0000_01C0 112 96
#define VECTOR_113 default_isr // 0x0000_01C4 113 97
#define VECTOR_114 default_isr // 0x0000_01C8 114 98
#define VECTOR_115 default_isr // 0x0000_01CC 115 99
#define VECTOR_116 default_isr // 0x0000_01D0 116 100
#define VECTOR_117 default_isr // 0x0000_01D4 117 101
#define VECTOR_118 default_isr // 0x0000_01D8 118 102
#define VECTOR_119 default_isr // 0x0000_01DC 119 103
#define VECTOR_120 default_isr //
#define VECTOR_121 default_isr //
#define VECTOR_122 default_isr //
#define VECTOR_123 default_isr //
#define VECTOR_124 default_isr //
#define VECTOR_125 default_isr //
#define VECTOR_126 default_isr //
#define VECTOR_127 default_isr //
#define VECTOR_128 default_isr //
#define VECTOR_129 default_isr //
#define VECTOR_130 default_isr //
#define VECTOR_131 default_isr //
#define VECTOR_132 default_isr //
#define VECTOR_133 default_isr //
#define VECTOR_134 default_isr //
#define VECTOR_135 default_isr //
#define VECTOR_136 default_isr //
#define VECTOR_137 default_isr //
#define VECTOR_138 default_isr //
#define VECTOR_139 default_isr //
#define VECTOR_140 default_isr //
#define VECTOR_141 default_isr //
#define VECTOR_142 default_isr //
#define VECTOR_143 default_isr //
#define VECTOR_144 default_isr //
#define VECTOR_145 default_isr //
#define VECTOR_146 default_isr //
#define VECTOR_147 default_isr //
#define VECTOR_148 default_isr //
#define VECTOR_149 default_isr //
#define VECTOR_150 default_isr //
#define VECTOR_151 default_isr //
#define VECTOR_152 default_isr //
#define VECTOR_153 default_isr //
#define VECTOR_154 default_isr //
#define VECTOR_155 default_isr //
#define VECTOR_156 default_isr //
#define VECTOR_157 default_isr //
#define VECTOR_158 default_isr //
#define VECTOR_159 default_isr //
#define VECTOR_160 default_isr //
#define VECTOR_161 default_isr //
#define VECTOR_162 default_isr //
#define VECTOR_163 default_isr //
#define VECTOR_164 default_isr //
#define VECTOR_165 default_isr //
#define VECTOR_166 default_isr //
#define VECTOR_167 default_isr //
#define VECTOR_168 default_isr //
#define VECTOR_169 default_isr //
#define VECTOR_170 default_isr //
#define VECTOR_171 default_isr //
#define VECTOR_172 default_isr //
#define VECTOR_173 default_isr //
#define VECTOR_174 default_isr //
#define VECTOR_175 default_isr //
#define VECTOR_176 default_isr //
#define VECTOR_177 default_isr //
#define VECTOR_178 default_isr //
#define VECTOR_179 default_isr //
#define VECTOR_180 default_isr //
#define VECTOR_181 default_isr //
#define VECTOR_182 default_isr //
#define VECTOR_183 default_isr //
#define VECTOR_184 default_isr //
#define VECTOR_185 default_isr //
#define VECTOR_186 default_isr //
#define VECTOR_187 default_isr //
#define VECTOR_188 default_isr //
#define VECTOR_189 default_isr //
#define VECTOR_190 default_isr //
#define VECTOR_191 default_isr //
#define VECTOR_192 default_isr //
#define VECTOR_193 default_isr //
#define VECTOR_194 default_isr //
#define VECTOR_195 default_isr //
#define VECTOR_196 default_isr //
#define VECTOR_197 default_isr //
#define VECTOR_198 default_isr //
#define VECTOR_199 default_isr //
#define VECTOR_200 default_isr //
#define VECTOR_201 default_isr //
#define VECTOR_202 default_isr //
#define VECTOR_203 default_isr //
#define VECTOR_204 default_isr //
#define VECTOR_205 default_isr //
#define VECTOR_206 default_isr //
#define VECTOR_207 default_isr //
#define VECTOR_208 default_isr //
#define VECTOR_209 default_isr //
#define VECTOR_210 default_isr //
#define VECTOR_211 default_isr //
#define VECTOR_212 default_isr //
#define VECTOR_213 default_isr //
#define VECTOR_214 default_isr //
#define VECTOR_215 default_isr //
#define VECTOR_216 default_isr //
#define VECTOR_217 default_isr //
#define VECTOR_218 default_isr //
#define VECTOR_219 default_isr //
#define VECTOR_220 default_isr //
#define VECTOR_221 default_isr //
#define VECTOR_222 default_isr //
#define VECTOR_223 default_isr //
#define VECTOR_224 default_isr //
#define VECTOR_225 default_isr //
#define VECTOR_226 default_isr //
#define VECTOR_227 default_isr //
#define VECTOR_228 default_isr //
#define VECTOR_229 default_isr //
#define VECTOR_230 default_isr //
#define VECTOR_231 default_isr //
#define VECTOR_232 default_isr //
#define VECTOR_233 default_isr //
#define VECTOR_234 default_isr //
#define VECTOR_235 default_isr //
#define VECTOR_236 default_isr //
#define VECTOR_237 default_isr //
#define VECTOR_238 default_isr //
#define VECTOR_239 default_isr //
#define VECTOR_240 default_isr //
#define VECTOR_241 default_isr //
#define VECTOR_242 default_isr //
#define VECTOR_243 default_isr //
#define VECTOR_244 default_isr //
#define VECTOR_245 default_isr //
#define VECTOR_246 default_isr //
#define VECTOR_247 default_isr //
#define VECTOR_248 default_isr //
#define VECTOR_249 default_isr //
#define VECTOR_250 default_isr //
#define VECTOR_251 default_isr //
#define VECTOR_252 default_isr //
#define VECTOR_253 default_isr //
#define VECTOR_254 default_isr //
#define VECTOR_255 default_isr //
#define CONFIG_1 (pointer*)0xffffffff
#define CONFIG_2 (pointer*)0xffffffff
#define CONFIG_3 (pointer*)0xffffffff
#define CONFIG_4 (pointer*)0xfffffffe
#endif /*__VECTORS_H*/
/* End of "vectors.h" */

View file

@ -0,0 +1,243 @@
/*
* File: enet.c
* Purpose: Driver for the ENET controller
*
* Notes:
*/
#include "common.h"
#include "enet.h"
#include "nbuf.h"
#include "eth.h"
/********************************************************************/
/* Initialize the MIB counters
*
* Parameters:
* ch FEC channel
*/
void
enet_mib_init(int ch)
{
//To do
}
/********************************************************************/
/* Display the MIB counters
*
* Parameters:
* ch FEC channel
*/
void
enet_mib_dump(int ch)
{
//To do
}
/********************************************************************/
/*
* Set the duplex on the selected FEC controller
*
* Parameters:
* ch FEC channel
* duplex enet_MII_FULL_DUPLEX or enet_MII_HALF_DUPLEX
*/
void
enet_duplex (int ch, ENET_DUPLEX duplex)
{
switch (duplex)
{
case MII_HDX:
ENET_RCR/*(ch)*/ |= ENET_RCR_DRT_MASK;
ENET_TCR/*(ch)*/ &= (uint32_t)~ENET_TCR_FDEN_MASK;
break;
case MII_FDX:
default:
ENET_RCR/*(ch)*/ &= ~ENET_RCR_DRT_MASK;
ENET_TCR/*(ch)*/ |= ENET_TCR_FDEN_MASK;
break;
}
}
/********************************************************************/
/*
* Generate the hash table settings for the given address
*
* Parameters:
* addr 48-bit (6 byte) Address to generate the hash for
*
* Return Value:
* The 6 most significant bits of the 32-bit CRC result
*/
uint8_t
enet_hash_address(const uint8_t* addr)
{
uint32_t crc;
uint8_t byte;
int i, j;
crc = 0xFFFFFFFF;
for(i=0; i<6; ++i)
{
byte = addr[i];
for(j=0; j<8; ++j)
{
if((byte & 0x01)^(crc & 0x01))
{
crc >>= 1;
crc = crc ^ 0xEDB88320;
}
else
crc >>= 1;
byte >>= 1;
}
}
return (uint8_t)(crc >> 26);
}
/********************************************************************/
/*
* Set the Physical (Hardware) Address and the Individual Address
* Hash in the selected FEC
*
* Parameters:
* ch FEC channel
* pa Physical (Hardware) Address for the selected FEC
*/
void
enet_set_address (int ch, const uint8_t *pa)
{
uint8_t crc;
/*
* Set the Physical Address
*/
ENET_PALR/*(ch)*/ = (uint32_t)((pa[0]<<24) | (pa[1]<<16) | (pa[2]<<8) | pa[3]);
ENET_PAUR/*(ch)*/ = (uint32_t)((pa[4]<<24) | (pa[5]<<16));
/*
* Calculate and set the hash for given Physical Address
* in the Individual Address Hash registers
*/
crc = enet_hash_address(pa);
if(crc >= 32)
ENET_IAUR/*(ch)*/ |= (uint32_t)(1 << (crc - 32));
else
ENET_IALR/*(ch)*/ |= (uint32_t)(1 << crc);
}
/********************************************************************/
/*
* Reset the selected FEC controller
*
* Parameters:
* ch FEC channel
*/
void
enet_reset (int ch)
{
int i;
/* Set the Reset bit and clear the Enable bit */
ENET_ECR/*(ch)*/ = ENET_ECR_RESET_MASK;
/* Wait at least 8 clock cycles */
for (i=0; i<10; ++i)
asm( "NOP" );
}
/********************************************************************/
/*
* Initialize the selected FEC
*
* Parameters:
* config: ENET parameters
*
*
*/
void
enet_init (ENET_CONFIG *config)
{
/* Clear the Individual and Group Address Hash registers */
ENET_IALR/*(ch)*/ = 0;
ENET_IAUR/*(ch)*/ = 0;
ENET_GALR/*(ch)*/ = 0;
ENET_GAUR/*(ch)*/ = 0;
/* Set the Physical Address for the selected FEC */
enet_set_address(config->ch, config->mac);
/* Mask all FEC interrupts */
ENET_EIMR/*(ch)*/ = 0;//FSL:ENET_EIMR_MASK_ALL_MASK;
/* Clear all FEC interrupt events */
ENET_EIR/*(ch)*/ = 0xFFFFFFFF;//FSL:ENET_EIR_CLEAR_ALL_MASK;
/* Initialize the Receive Control Register */
ENET_RCR/*(ch)*/ = 0
| ENET_RCR_MAX_FL(ETH_MAX_FRM)
| ENET_RCR_MII_MODE_MASK /*always*/
| ENET_RCR_CRCFWD_MASK; /*no CRC pad required*/
if ( config->interface == mac_rmii )
{
ENET_RCR/*(ch)*/ |= ENET_RCR_RMII_MODE_MASK;
/*only set speed in RMII mode*/
if( config->speed == MII_10BASET )
{
ENET_RCR/*(ch)*/ |= ENET_RCR_RMII_10T_MASK;
}
}/*no need to configure MAC MII interface*/
ENET_TCR/*(ch)*/ = 0;
/* Set the duplex */
enet_duplex(config->ch, config->duplex);
if (config->prom)
{
ENET_RCR/*(ch)*/ |= ENET_RCR_PROM_MASK;
}
#ifdef ENHANCED_BD
ENET_ECR/*(ch)*/ = ENET_ECR_EN1588_MASK;
#else
ENET_ECR/*(ch)*/ = 0;//clear register
#endif
if(config->loopback == INTERNAL_LOOPBACK)
{
/*seems like RMII internal loopback works, even if it's not supported*/
ENET_RCR/*(0)*/ |= ENET_RCR_LOOP_MASK;
}
}
/********************************************************************/
void
enet_start (int ch)
{
// Enable FEC
ENET_ECR/*(ch)*/ |= ENET_ECR_ETHEREN_MASK;
}
/********************************************************************/
int
enet_wait_for_frame_receive(int ch, int timeout)
{
int i, return_val = 1;
for (i=0; i < timeout; i++)
{
if (ENET_EIR/*(ch)*/ & ENET_EIR_RXF_MASK)
{
ENET_EIR/*(ch)*/ = ENET_EIR_RXF_MASK;
break;
}
}
if(i == timeout)
{
return_val = 0;
}
return return_val;
}
/********************************************************************/

View file

@ -0,0 +1,95 @@
/*
* File: enet.h
* Purpose: Driver for the ENET controller
*
* Notes:
*/
#ifndef _ENET_H_
#define _ENET_H_
#include "nbuf.h"
/********INTERFACE**********/
typedef enum {
mac_mii,
mac_rmii,
} ENET_INTERFACE;
/********AUTONEG**********/
typedef enum {
autoneg_on,
autoneg_off
} ENET_AUTONEG;
/********SPEED**********/
typedef enum {
MII_10BASET,
MII_100BASET
} ENET_SPEED;
/********DUPLEX**********/
/* MII Duplex Settings */
typedef enum {
MII_HDX, /*!< half-duplex */
MII_FDX /*!< full-duplex */
} ENET_DUPLEX;
/********LOOPBACK**********/
typedef enum {
INTERNAL_LOOPBACK,
EXTERNAL_LOOPBACK,
NO_LOOPBACK
} ENET_LOOPBACK;
/********EXTERNAL**********/
typedef enum {
EXTERNAL_NONE,
EXTERNAL_YES
} ENET_EXTERNAL_CONN;
/*
* FEC Configuration Parameters
*/
typedef struct
{
uint8_t ch; /* FEC channel */
ENET_INTERFACE interface; /* Transceiver mode */
ENET_AUTONEG neg; /* FEC autoneg */
ENET_SPEED speed; /* Ethernet Speed */
ENET_DUPLEX duplex; /* Ethernet Duplex */
ENET_LOOPBACK loopback; /* Loopback Mode */
ENET_EXTERNAL_CONN external; /* outside test? */
uint8_t prom; /* Promiscuous Mode? */
uint8_t mac[6]; /* Ethernet Address */
} ENET_CONFIG;
void
enet_mib_init(int);
void
enet_mib_dump(int);
void
enet_reg_dump(int);
void
enet_duplex (int, ENET_DUPLEX);
uint8_t
enet_hash_address(const uint8_t*);
void
enet_set_address (int, const uint8_t*);
void
enet_reset (int);
void
enet_init (ENET_CONFIG *config);
void
enet_start (int ch);
int
enet_wait_for_frame_receive(int,int);
/********************************************************************/
#endif /* _ENET_H_ */

View file

@ -0,0 +1,58 @@
/*!
* \file eth.h
* \brief Definitinos for Ethernet Frames
* \version $Revision: 1.1 $
* \author Michael Norman
*/
#ifndef _ETH_H
#define _ETH_H
/*b06862*/
#include "common.h"
/*******************************************************************/
/* Ethernet standard lengths in bytes*/
#define ETH_ADDR_LEN (6)
#define ETH_TYPE_LEN (2)
#define ETH_CRC_LEN (4)
#define ETH_MAX_DATA (1500)
#define ETH_MIN_DATA (46)
#define ETH_HDR_LEN (ETH_ADDR_LEN * 2 + ETH_TYPE_LEN)
/* Defined Ethernet Frame Types */
#define ETH_FRM_IP (0x0800)
#define ETH_FRM_ARP (0x0806)
#define ETH_FRM_RARP (0x8035)
#define ETH_FRM_TEST (0xA5A5)
/* Maximum and Minimum Ethernet Frame Sizes */
#define ETH_MAX_FRM (ETH_HDR_LEN + ETH_MAX_DATA + ETH_CRC_LEN)
#define ETH_MIN_FRM (ETH_HDR_LEN + ETH_MIN_DATA + ETH_CRC_LEN)
#define ETH_MTU (ETH_HDR_LEN + ETH_MAX_DATA)
/* Ethernet Addresses */
typedef uint8_t ETH_ADDR[ETH_ADDR_LEN];
/* 16-bit Ethernet Frame Type, ie. Protocol */
typedef uint16_t ETH_FRM_TYPE;
/* Ethernet Frame Header definition */
typedef struct
{
ETH_ADDR dest;
ETH_ADDR src;
ETH_FRM_TYPE type;
} ETH_HDR;
/* Ethernet Frame definition */
typedef struct
{
ETH_HDR head;
uint8_t* data;
} ETH_FRAME;
/*******************************************************************/
#endif /* _ETH_H */

View file

@ -0,0 +1,406 @@
/*!
* \file eth_phy.c
* \brief Ethernet Physical Layer Interface Driver
* \version $Revision: 1.3 $
* \author Michael Norman
*
* This is a generic driver for all Ethernet PHYs with the basic MII registers
*/
#include "common.h"
#include "eth_phy.h"
#include "mii.h"
/* Variable to save off auto-negotiate settings */
int eth_phy_anar = 0
| PHY_ANAR_100BTX_FDX
| PHY_ANAR_100BTX
| PHY_ANAR_10BT_FDX
| PHY_ANAR_10BT;
int
eth_phy_reset(int ch, int phy_addr)
{
#if MII_CHECK_TIMEOUT
int timeout;
#endif
int settings;
/* Reset the PHY */
if (mii_write(ch, phy_addr, PHY_BMCR, PHY_BMCR_RESET))
return 1;
/* Wait for reset to complete */
#if MII_CHECK_TIMEOUT
for (timeout = 0; timeout < MII_LINK_TIMEOUT; ++timeout)
#endif
while(1)
{
/* Read back the contents of the CTRL register and verify
* that RESET is not set - this is a sanity check to ensure
* that we are talking to the PHY correctly. RESET should
* always be cleared. */
if (!(mii_read(ch, phy_addr, PHY_BMCR, &settings)) && !(settings & PHY_BMCR_RESET))
break;/*FSL: ready*/
}
#if MII_CHECK_TIMEOUT
if (timeout == MII_LINK_TIMEOUT || (settings & PHY_BMCR_RESET))
return 1;
else
#endif
return 0;
}
/********************************************************************/
/*!
* \brief Enable the Ethernet PHY in auto-negotiate mode
* \param phy_addr Address of the PHY
* \param speed Desired speed (MII_10BASE_T or MII_100BASE_TX)
* \param duplex Desired duplex (MII_FDX or MII_HDX)
* \return 0 if successful; non-zero otherwise
*/
int
eth_phy_autoneg(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex)
{
int timeout, settings;
/* Reset the PHY */
eth_phy_reset(ch, phy_addr);
/* Set the Auto-Negotiation Advertisement Register */
if (speed == MII_10BASET)
{
settings = (duplex == MII_FDX)
? PHY_ANAR_10BT_FDX | PHY_ANAR_10BT
: PHY_ANAR_10BT;
}
else /* (speed == MII_100BASET) */
{
settings = (duplex == MII_FDX)
? PHY_ANAR_100BTX_FDX |
PHY_ANAR_100BTX |
PHY_ANAR_10BT_FDX |
PHY_ANAR_10BT
: PHY_ANAR_10BT_FDX |
PHY_ANAR_10BT;
}
/* Save off the settings we just advertised */
eth_phy_anar = settings;
if (mii_write(ch, phy_addr, PHY_ANAR, settings))
return 1;
/* Enable Auto-Negotiation */
if (mii_write(ch, phy_addr, PHY_BMCR, PHY_BMCR_AN_ENABLE | PHY_BMCR_AN_RESTART))
return 1;
/* Wait for auto-negotiation to complete */
for (timeout = 0; timeout < MII_LINK_TIMEOUT; ++timeout)
{
if (mii_read(ch, phy_addr, PHY_BMSR, &settings))
return 1;
if (settings & PHY_BMSR_AN_COMPLETE)
break;
}
/* Read the BMSR one last time */
if (mii_read(ch, phy_addr, PHY_BMSR, &settings))
return 1;
if (timeout == MII_LINK_TIMEOUT || !(settings & PHY_BMSR_LINK))
return 1;
else
return 0;
}
/********************************************************************/
/*!
* \brief Enable the Ethernet PHY in manual mode
* \param phy_addr Address of the PHY
* \param speed Desired speed (MII_10BASE_T or MII_100BASE_TX)
* \param duplex Desired duplex (MII_FDX or MII_HDX)
* \param loop Put PHY in loopback mode?
* \return 0 if successful; non-zero otherwise
*/
int
eth_phy_manual(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex, int loop)
{
int timeout;
int settings = 0;
/* Reset the PHY */
/* Reset the PHY */
eth_phy_reset(ch, phy_addr);
if (loop)
settings |= PHY_BMCR_LOOP;
if (duplex == MII_FDX)
settings |= PHY_BMCR_FDX;
if (speed == MII_100BASET)
settings |= PHY_BMCR_SPEED;
if (mii_write(ch, phy_addr, PHY_BMCR, settings))
return 1;
/* Wait for link */
for (timeout = 0; timeout < MII_LINK_TIMEOUT; ++timeout)
{
if (mii_read(ch, phy_addr, PHY_BMSR, &settings))
return 1;
if (settings & PHY_BMSR_LINK)
break;
}
#if MII_CHECK_TIMEOUT
if (timeout == MII_LINK_TIMEOUT || !(settings & PHY_BMSR_LINK))
return 1;
else
#endif
return 0;
}
/********************************************************************/
/*!
* \brief Get the auto-negotiated speed
* \param phy_addr Address of the PHY
* \param speed Pointer where speed data is stored
* \return 0 if successful; non-zero otherwise
*/
int
eth_phy_get_speed(int ch, int phy_addr, int *speed)
{
#if MII_CHECK_TIMEOUT
int timeout;
#endif
int settings = 0;
/* Get Link Partner settings */
#if MII_CHECK_TIMEOUT
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
#endif
while(1)
{
if (mii_read(ch, phy_addr, PHY_ANLPAR, &settings))
return 1;
else
break;
}
#if MII_CHECK_TIMEOUT
if (timeout == MII_TIMEOUT)
return 1;
#endif
settings &= eth_phy_anar;
if (settings & PHY_ANLPAR_100BT4 ||
settings & PHY_ANLPAR_100BTX_FDX ||
settings & PHY_ANLPAR_100BTX)
*speed = MII_100BASET;
else
*speed = MII_10BASET;
return 0;
}
/********************************************************************/
/*!
* \brief Get the auto-negotiated duplex
* \param phy_addr Address of the PHY
* \param speed Pointer where speed data is stored
* \return 0 if successful; non-zero otherwise
*/
int
eth_phy_get_duplex(int ch, int phy_addr, int *speed)
{
#if MII_CHECK_TIMEOUT
int timeout;
#endif
int settings = 0;
/* Get Link Partner settings */
#if MII_CHECK_TIMEOUT
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
#endif
while(1)
{
if (mii_read(ch, phy_addr, PHY_ANLPAR, &settings))
return 1;
else
break;
}
#if MII_CHECK_TIMEOUT
if (timeout == MII_TIMEOUT)
return 1;
#endif
settings &= eth_phy_anar;
if (settings & PHY_ANLPAR_100BTX_FDX ||
settings & PHY_ANLPAR_10BTX_FDX)
*speed = MII_FDX;
else
*speed = MII_HDX;
return 0;
}
/********************************************************************/
/*!
* \brief Get the manual speed
* \param phy_addr Address of the PHY
* \param speed Pointer where speed data is stored
* \return 0 if successful; non-zero otherwise
*/
int
eth_phy_get_manual_speed(int ch, int phy_addr, int *speed)
{
#if MII_CHECK_TIMEOUT
int timeout;
#endif
int settings = 0;
/* Get Link Partner settings */
#if MII_CHECK_TIMEOUT
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
#endif
while(1)
{
#ifdef TWR_K60N512
if (mii_read(ch, phy_addr, PHY_PHYCTRL2, &settings))//Micrel
#else
if (mii_read(ch, phy_addr, PHY_PHYSTS, &settings))//National Semiconductors
#endif
return 1;
else
break;
}
#if MII_CHECK_TIMEOUT
if (timeout == MII_TIMEOUT)
return 1;
#endif
#ifdef TWR_K60N512
/*FSL: obtain speed/duplex*/
settings = (settings & PHY_PHYCTRL2_OP_MOD_MASK)>>PHY_PHYCTRL2_OP_MOD_SHIFT;
if (settings == PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_HD ||
settings == PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_FD)
*speed = MII_10BASET;
else
*speed = MII_100BASET;
#else
if (settings & PHY_PHYSTS_SPEEDSTATUS)
*speed = MII_10BASET;
else
*speed = MII_100BASET;
#endif
return 0;
}
/********************************************************************/
/*!
* \brief Get the manual duplex
* \param phy_addr Address of the PHY
* \param duplex Pointer where duplex data is stored
* \return 0 if successful; non-zero otherwise
*/
int
eth_phy_get_manual_duplex(int ch, int phy_addr, int *duplex)
{
#if MII_CHECK_TIMEOUT
int timeout;
#endif
int settings = 0;
/* Get Link Partner settings */
#if MII_CHECK_TIMEOUT
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
#endif
while(1)
{
#ifdef TWR_K60N512
if (mii_read(ch, phy_addr, PHY_PHYCTRL2, &settings))//Micrel
#else
if (mii_read(ch, phy_addr, PHY_PHYSTS, &settings))//National Semiconductors
#endif
return 1;
else
break;
}
#if MII_CHECK_TIMEOUT
if (timeout == MII_TIMEOUT)
return 1;
#endif
#ifdef TWR_K60N512
/*FSL: obtain speed/duplex*/
settings = (settings & PHY_PHYCTRL2_OP_MOD_MASK)>>PHY_PHYCTRL2_OP_MOD_SHIFT;
if (settings == PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_HD ||
settings == PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_HD)
*duplex = MII_HDX;
else
*duplex = MII_FDX;
#else
if (settings & PHY_PHYSTS_DUPLEXSTATUS)
*duplex = MII_FDX;
else
*duplex = MII_HDX;
#endif
return 0;
}
/********************************************************************/
/*!
* \brief Get the manual speed
* \param phy_addr Address of the PHY
* \param loop set if loopback is needed
* \return 0 if successful; non-zero otherwise
*/
int
eth_phy_set_remote_loopback(int ch, int phy_addr, int loop)
{
#if MII_CHECK_TIMEOUT
int timeout;
#endif
int settings = 0;
/* Get Link Partner settings */
#if MII_CHECK_TIMEOUT
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
#endif
while(1)
{
if (mii_read(ch, phy_addr, PHY_PHYCTRL1, &settings))
return 1;
else
break;
}
#if MII_CHECK_TIMEOUT
if (timeout == MII_TIMEOUT)
return 1;
#endif
/*set remote loopback flag*/
if(loop)
settings |= PHY_PHYCTRL1_REMOTE_LOOP; /*set bit*/
else
settings &= ~PHY_PHYCTRL1_REMOTE_LOOP; /*clear bit*/
if (mii_write(ch, phy_addr, PHY_PHYCTRL1, settings))
return 1;
return 0;
}
/********************************************************************/
/*!
* \brief Print all the MII registers (0x00-0x1F)
* \param phy_addr Address of the PHY
*/
int
eth_phy_reg_dump(int ch, int phy_addr)
{
int j, settings;
for (j = 0; j < 32; j++)
{
mii_read(ch, phy_addr, j, &settings);
}
return 0;
}

View file

@ -0,0 +1,175 @@
/*!
* \file eth.h
* \brief Definitions for Ethernet Physical Layer Interface
* \version $Revision: 1.3 $
* \author Michael Norman
* \modif b06862
*/
#ifndef _ETH_PHY_H
#define _ETH_PHY_H
#include "enet.h"
/*******************************************************************/
int
eth_phy_reset(int ch, int phy_addr);
int
eth_phy_autoneg(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex);
int
eth_phy_manual(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex, int loop);
int
eth_phy_get_speed(int, int, int*);
int
eth_phy_get_duplex(int, int, int*);
int
eth_phy_get_manual_speed(int, int, int*);
int
eth_phy_get_manual_duplex(int, int, int*);
int
eth_phy_set_remote_loopback(int, int, int);
int
eth_phy_reg_dump(int, int);
/*******************************************************************/
/* MII Register Addresses */
#define PHY_BMCR (0x00)
#define PHY_BMSR (0x01)
#define PHY_PHYIDR1 (0x02)
#define PHY_PHYIDR2 (0x03)
#define PHY_ANAR (0x04)
#define PHY_ANLPAR (0x05)
#define PHY_ANLPARNP (0x05)
#define PHY_ANER (0x06)
#define PHY_ANNPTR (0x07)
#define PHY_PHYSTS (0x10)
#define PHY_MICR (0x11)
#define PHY_MISR (0x12)
#define PHY_PAGESEL (0x13)
/*TSI-EVB definition: National Semiconductor*/
#define PHY_PHYCR2 (0x1C)
/*TWR definition: Micrel*/
#define PHY_PHYCTRL1 (0x1E)
#define PHY_PHYCTRL2 (0x1F)
/* Bit definitions and macros for PHY_BMCR */
#define PHY_BMCR_RESET (0x8000)
#define PHY_BMCR_LOOP (0x4000)
#define PHY_BMCR_SPEED (0x2000)
#define PHY_BMCR_AN_ENABLE (0x1000)
#define PHY_BMCR_POWERDOWN (0x0800)
#define PHY_BMCR_ISOLATE (0x0400)
#define PHY_BMCR_AN_RESTART (0x0200)
#define PHY_BMCR_FDX (0x0100)
#define PHY_BMCR_COL_TEST (0x0080)
/* Bit definitions and macros for PHY_BMSR */
#define PHY_BMSR_100BT4 (0x8000)
#define PHY_BMSR_100BTX_FDX (0x4000)
#define PHY_BMSR_100BTX (0x2000)
#define PHY_BMSR_10BT_FDX (0x1000)
#define PHY_BMSR_10BT (0x0800)
#define PHY_BMSR_NO_PREAMBLE (0x0040)
#define PHY_BMSR_AN_COMPLETE (0x0020)
#define PHY_BMSR_REMOTE_FAULT (0x0010)
#define PHY_BMSR_AN_ABILITY (0x0008)
#define PHY_BMSR_LINK (0x0004)
#define PHY_BMSR_JABBER (0x0002)
#define PHY_BMSR_EXTENDED (0x0001)
/* Bit definitions and macros for PHY_ANAR */
#define PHY_ANAR_NEXT_PAGE (0x8001)
#define PHY_ANAR_REM_FAULT (0x2001)
#define PHY_ANAR_PAUSE (0x0401)
#define PHY_ANAR_100BT4 (0x0201)
#define PHY_ANAR_100BTX_FDX (0x0101)
#define PHY_ANAR_100BTX (0x0081)
#define PHY_ANAR_10BT_FDX (0x0041)
#define PHY_ANAR_10BT (0x0021)
#define PHY_ANAR_802_3 (0x0001)
/* Bit definitions and macros for PHY_ANLPAR */
#define PHY_ANLPAR_NEXT_PAGE (0x8000)
#define PHY_ANLPAR_ACK (0x4000)
#define PHY_ANLPAR_REM_FAULT (0x2000)
#define PHY_ANLPAR_PAUSE (0x0400)
#define PHY_ANLPAR_100BT4 (0x0200)
#define PHY_ANLPAR_100BTX_FDX (0x0100)
#define PHY_ANLPAR_100BTX (0x0080)
#define PHY_ANLPAR_10BTX_FDX (0x0040)
#define PHY_ANLPAR_10BT (0x0020)
/* Bit definitions of PHY_PHYSTS: National */
#define PHY_PHYSTS_MDIXMODE (0x4000)
#define PHY_PHYSTS_RX_ERR_LATCH (0x2000)
#define PHY_PHYSTS_POL_STATUS (0x1000)
#define PHY_PHYSTS_FALSECARRSENSLAT (0x0800)
#define PHY_PHYSTS_SIGNALDETECT (0x0400)
#define PHY_PHYSTS_PAGERECEIVED (0x0100)
#define PHY_PHYSTS_MIIINTERRUPT (0x0080)
#define PHY_PHYSTS_REMOTEFAULT (0x0040)
#define PHY_PHYSTS_JABBERDETECT (0x0020)
#define PHY_PHYSTS_AUTONEGCOMPLETE (0x0010)
#define PHY_PHYSTS_LOOPBACKSTATUS (0x0008)
#define PHY_PHYSTS_DUPLEXSTATUS (0x0004)
#define PHY_PHYSTS_SPEEDSTATUS (0x0002)
#define PHY_PHYSTS_LINKSTATUS (0x0001)
/* Bit definitions of PHY_PHYCR2 */
#define PHY_PHYCR2_SYNC_ENET_EN (0x2000)
#define PHY_PHYCR2_CLK_OUT_RXCLK (0x1000)
#define PHY_PHYCR2_BC_WRITE (0x0800)
#define PHY_PHYCR2_PHYTER_COMP (0x0400)
#define PHY_PHYCR2_SOFT_RESET (0x0200)
#define PHY_PHYCR2_CLK_OUT_DIS (0x0001)
/* Bit definition and macros for PHY_PHYCTRL1 */
#define PHY_PHYCTRL1_LED_MASK (0xC000)
#define PHY_PHYCTRL1_POLARITY (0x2000)
#define PHY_PHYCTRL1_MDX_STATE (0x0800)
#define PHY_PHYCTRL1_REMOTE_LOOP (0x0080)
/* Bit definition and macros for PHY_PHYCTRL2 */
#define PHY_PHYCTRL2_HP_MDIX (0x8000)
#define PHY_PHYCTRL2_MDIX_SELECT (0x4000)
#define PHY_PHYCTRL2_PAIRSWAP_DIS (0x2000)
#define PHY_PHYCTRL2_ENERGY_DET (0x1000)
#define PHY_PHYCTRL2_FORCE_LINK (0x0800)
#define PHY_PHYCTRL2_POWER_SAVING (0x0400)
#define PHY_PHYCTRL2_INT_LEVEL (0x0200)
#define PHY_PHYCTRL2_EN_JABBER (0x0100)
#define PHY_PHYCTRL2_AUTONEG_CMPLT (0x0080)
#define PHY_PHYCTRL2_ENABLE_PAUSE (0x0040)
#define PHY_PHYCTRL2_PHY_ISOLATE (0x0020)
#define PHY_PHYCTRL2_OP_MOD_MASK (0x001C)
#define PHY_PHYCTRL2_EN_SQE_TEST (0x0002)
#define PHY_PHYCTRL2_DATA_SCRAM_DIS (0x0001)
/* Bit definitions of PHY_PHYCTRL2_OP_MOD_MASK */
#define PHY_PHYCTRL2_OP_MOD_SHIFT 2
#define PHY_PHYCTRL2_MODE_OP_MOD_STILL_NEG 0
#define PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_HD 1
#define PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_HD 2
#define PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_FD 5
#define PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_FD 6
/*******************************************************************/
#endif /* _ETH_PHY_H */

View file

@ -0,0 +1,130 @@
/*!
* \file mii.c
* \brief Media Independent Interface (MII) driver
* \version $Revision: 1.2 $
* \author Michael Norman
*
* \warning This driver assumes that FEC0 is used for all MII management
* communications. For dual PHYs, etc. Insure that FEC0_MDC and
* FEC0_MDIO are connected to the PHY's MDC and MDIO.
*/
#include "common.h"
#include "mii.h"
/********************************************************************/
/*
* \brief Initialize the MII interface controller
* \param System Clock Frequency (in MHz)
* \warning The system clock in this case is the clock that drives
* the FEC logic. This may be different from the speed at which
* the CPU is operating.
*
* Initialize the MII clock (EMDC) frequency. The desired MII clock is 2.5MHz:
*
* MII Speed Setting = System_Clock / (2.5MHz * 2)
* (plus 1 to round up)
*/
void
mii_init(int ch, int sys_clk_mhz)
{
ENET_MSCR/*(ch)*/ = 0
#ifdef TSIEVB/*TSI EVB requires a longer hold time than default 10 ns*/
| ENET_MSCR_HOLDTIME(2)
#endif
| ENET_MSCR_MII_SPEED((2*sys_clk_mhz/5)+1)
;
}
/********************************************************************/
/*!
* \brief Write a value to a PHY's MII register.
*
* \param phy_addr Address of the PHY
* \param reg_addr Address of the register in the PHY
* \param data Data to be written to the PHY register
* \return 0 if write is successful; 1 if write times out
*
* mii_write() polls for the FEC's MII interrupt event (which should
* be masked from the interrupt handler) and clears it. If after a
* suitable amount of time the event isn't triggered, a non-zero value
* is returned.
*/
int
mii_write(int ch, int phy_addr, int reg_addr, int data)
{
int timeout;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
/* Initiatate the MII Management write */
ENET_MMFR/*(ch)*/ = 0
| ENET_MMFR_ST(0x01)
| ENET_MMFR_OP(0x01)
| ENET_MMFR_PA(phy_addr)
| ENET_MMFR_RA(reg_addr)
| ENET_MMFR_TA(0x02)
| ENET_MMFR_DATA(data);
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
{
if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)
break;
}
if(timeout == MII_TIMEOUT)
return 1;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
return 0;
}
/********************************************************************/
/*!
* \brief Read a value from a PHY's MII register.
* \param phy_addr Address of the PHY
* \param reg_addr Address of the register in the PHY
* \param data Pointer to location were read data will be stored
* \return 0 if write is successful; 1 if write times out
*
* mii_read() polls for the FEC's MII interrupt event (which should
* be masked from the interrupt handler) and clears it. If after a
* suitable amount of time the event isn't triggered, a non-zero value
* is returned.
*/
int
mii_read(int ch, int phy_addr, int reg_addr, int *data)
{
int timeout;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
/* Initiatate the MII Management read */
ENET_MMFR/*(ch)*/ = 0
| ENET_MMFR_ST(0x01)
| ENET_MMFR_OP(0x2)
| ENET_MMFR_PA(phy_addr)
| ENET_MMFR_RA(reg_addr)
| ENET_MMFR_TA(0x02);
/* Poll for the MII interrupt (interrupt should be masked) */
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
{
if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)
break;
}
if(timeout == MII_TIMEOUT)
return 1;
/* Clear the MII interrupt bit */
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
*data = ENET_MMFR/*(ch)*/ & 0x0000FFFF;
return 0;
}
/********************************************************************/

View file

@ -0,0 +1,30 @@
/*!
* \file mii.h
* \brief Media Independent Interface (MII) driver
* \version $Revision: 1.2 $
* \author Michael Norman
*
* \warning
*
*/
#ifndef _MII_H_
#define _MII_H_
/*******************************************************************/
#define MII_TIMEOUT 0x1FFFF
#define MII_LINK_TIMEOUT 0x1FFFF
void
mii_init(int, int);
int
mii_write(int, int, int, int);
int
mii_read(int, int, int, int*);
/*******************************************************************/
#endif /* _MII_H_ */

View file

@ -0,0 +1,233 @@
// ----------------------------------------------------------------------
// File: nbuf.h
// Purpose: Definitions for Network Buffer Allocation.
//
// Notes:
//
// ----------------------------------------------------------------------
#ifndef _NBUF_H_
#define _NBUF_H_
// Define number of MACs
#define NUM_CHANNELS 1/*b06862*/
// Choose Enhanced Buffer Descriptor or Legacy
#define ENHANCED_BD
//b06862: define Endianess for Little Endian architectures like ARM.
//Motorola/Freescale uses Big Endian or Register-Endianess
#define NBUF_LITTLE_ENDIAN
// Transmit packet directly or copy to dedicated buffers. If packets
// are not alligned dedicated Tx buffers can be used
//#define USE_DEDICATED_TX_BUFFERS
// Buffer sizes in bytes (must be divisible by 16)
#define RX_BUFFER_SIZE 256
#define TX_BUFFER_SIZE 256
// Number of Receive and Transmit Buffers and Buffer Descriptors
#define NUM_RXBDS 20//10
#define NUM_TXBDS 20//10
// Buffer Descriptor Format
#ifdef ENHANCED_BD
typedef struct
{
uint16_t status; /* control and status */
uint16_t length; /* transfer length */
uint8_t *data; /* buffer address */
uint32_t ebd_status;
uint16_t length_proto_type;
uint16_t payload_checksum;
uint32_t bdu;
uint32_t timestamp;
uint32_t reserverd_word1;
uint32_t reserverd_word2;
} NBUF;
#else
typedef struct
{
uint16_t status; /* control and status */
uint16_t length; /* transfer length */
uint8_t *data; /* buffer address */
} NBUF;
#endif /* ENHANCED_BD */
// ----------------------------------------------------------------------
// Function Declarations
// ----------------------------------------------------------------------
void
nbuf_alloc(int ch);
void
nbuf_init(int);
void
nbuf_start_rx(int);
void
nbuf_flush(int);
//NM - return value
void
enet_get_received_packet(int, NBUF *);
//NM - return value
void
enet_fill_txbds(int, NBUF *);
void
enet_transmit_packet(int,NBUF *);
#ifdef NBUF_LITTLE_ENDIAN
//For Freescale ARM Architecture
// ----------------------------------------------------------------------
// TX Buffer Descriptor Bit Definitions
// ----------------------------------------------------------------------
#define TX_BD_R 0x0080
#define TX_BD_TO1 0x0040
#define TX_BD_W 0x0020
#define TX_BD_TO2 0x0010
#define TX_BD_L 0x0008
#define TX_BD_TC 0x0004
#define TX_BD_ABC 0x0002
// ----------------------------------------------------------------------
// TX Enhanced BD Bit Definitions
// ----------------------------------------------------------------------
#define TX_BD_INT 0x00000040
#define TX_BD_TS 0x00000020
#define TX_BD_PINS 0x00000010
#define TX_BD_IINS 0x00000008
#define TX_BD_TXE 0x00800000
#define TX_BD_UE 0x00200000
#define TX_BD_EE 0x00100000
#define TX_BD_FE 0x00080000
#define TX_BD_LCE 0x00040000
#define TX_BD_OE 0x00020000
#define TX_BD_TSE 0x00010000
#define TX_BD_BDU 0x00000080
// ----------------------------------------------------------------------
// RX Buffer Descriptor Bit Definitions
// ----------------------------------------------------------------------
// Offset 0 flags - status: Big Endian
#define RX_BD_E 0x0080
#define RX_BD_R01 0x0040
#define RX_BD_W 0x0020
#define RX_BD_R02 0x0010
#define RX_BD_L 0x0008
#define RX_BD_M 0x0001
#define RX_BD_BC 0x8000
#define RX_BD_MC 0x4000
#define RX_BD_LG 0x2000
#define RX_BD_NO 0x1000
#define RX_BD_CR 0x0400
#define RX_BD_OV 0x0200
#define RX_BD_TR 0x0100
// ----------------------------------------------------------------------
// RX Enhanced BD Bit Definitions
// ----------------------------------------------------------------------
#define RX_BD_ME 0x00000080
#define RX_BD_PE 0x00000004
#define RX_BD_CE 0x00000002
#define RX_BD_UC 0x00000001
#define RX_BD_INT 0x00008000
#define RX_BD_ICE 0x20000000
#define RX_BD_PCR 0x10000000
#define RX_BD_VLAN 0x04000000
#define RX_BD_IPV6 0x02000000
#define RX_BD_FRAG 0x01000000
#define RX_BD_BDU 0x00000080
#else
//For Freescale ColdFire Architecture
// ----------------------------------------------------------------------
// TX Buffer Descriptor Bit Definitions
// ----------------------------------------------------------------------
#define TX_BD_R 0x8000
#define TX_BD_TO1 0x4000
#define TX_BD_W 0x2000
#define TX_BD_TO2 0x1000
#define TX_BD_L 0x0800
#define TX_BD_TC 0x0400
#define TX_BD_ABC 0x0200
// ----------------------------------------------------------------------
// TX Enhanced BD Bit Definitions
// ----------------------------------------------------------------------
#define TX_BD_INT 0x40000000
#define TX_BD_TS 0x20000000
#define TX_BD_PINS 0x10000000
#define TX_BD_IINS 0x08000000
#define TX_BD_TXE 0x00008000
#define TX_BD_UE 0x00002000
#define TX_BD_EE 0x00001000
#define TX_BD_FE 0x00000800
#define TX_BD_LCE 0x00000400
#define TX_BD_OE 0x00000200
#define TX_BD_TSE 0x00000100
#define TX_BD_BDU 0x80000000
// ----------------------------------------------------------------------
// RX Buffer Descriptor Bit Definitions
// ----------------------------------------------------------------------
// Offset 0 flags - status
#define RX_BD_E 0x8000
#define RX_BD_R01 0x4000
#define RX_BD_W 0x2000
#define RX_BD_R02 0x1000
#define RX_BD_L 0x0800
#define RX_BD_M 0x0100
#define RX_BD_BC 0x0080
#define RX_BD_MC 0x0040
#define RX_BD_LG 0x0020
#define RX_BD_NO 0x0010
#define RX_BD_CR 0x0004
#define RX_BD_OV 0x0002
#define RX_BD_TR 0x0001
// ----------------------------------------------------------------------
// RX Enhanced BD Bit Definitions
// ----------------------------------------------------------------------
#define RX_BD_ME 0x80000000
#define RX_BD_PE 0x04000000
#define RX_BD_CE 0x02000000
#define RX_BD_UC 0x01000000
#define RX_BD_INT 0x00800000
#define RX_BD_ICE 0x00000020
#define RX_BD_PCR 0x00000010
#define RX_BD_VLAN 0x00000004
#define RX_BD_IPV6 0x00000002
#define RX_BD_FRAG 0x00000001
#define RX_BD_BDU 0x80000000
#endif
// ----------------------------------------------------------------------
// Defines for word offsets of various fields of RX Enhanced BDs
// ----------------------------------------------------------------------
//#define RX_EBD_HEADER_LENGTH_OFFSET 12
//#define RX_EBD_PROTOCOL_TYPE_OFFSET 12
//#define RX_EBD_PAYLOAD_CHKSM_OFFSET 14
//#define RX_EBD_BDU_OFFSET 16
//#define RX_EBD_TIMESTAMP_MSB_OFFSET 20
//#define RX_EBD_TIMESTAMP_LSB_OFFSET 22
#endif /* _NBUF_H_ */

View file

@ -0,0 +1,244 @@
/*
* File: mcg.c
* Purpose: Driver for enabling the PLL in 1 of 4 options
*
* Notes:
* Assumes the MCG mode is in the default FEI mode out of reset
* One of 4 clocking oprions can be selected.
* One of 16 crystal values can be used
*/
#include "common.h"
#include "mcg.h"
extern int core_clk_khz;
extern int core_clk_mhz;
extern int periph_clk_khz;
unsigned char pll_init(unsigned char clk_option, unsigned char crystal_val)
{
unsigned char pll_freq;
if (clk_option > 3) {return 0;} //return 0 if one of the available options is not selected
if (crystal_val > 15) {return 1;} // return 1 if one of the available crystal options is not available
//This assumes that the MCG is in default FEI mode out of reset.
// First move to FBE mode
#if (defined(K60_CLK) || defined(K53_CLK) || defined(ASB817))
MCG_C2 = 0;
#else
// Enable external oscillator, RANGE=2, HGO=1, EREFS=1, LP=0, IRCS=0
MCG_C2 = MCG_C2_RANGE(2) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK;
#endif
// after initialization of oscillator release latched state of oscillator and GPIO
SIM_SCGC4 |= SIM_SCGC4_LLWU_MASK;
LLWU_CS |= LLWU_CS_ACKISO_MASK;
// Select external oscilator and Reference Divider and clear IREFS to start ext osc
// CLKS=2, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
/* if we aren't using an osc input we don't need to wait for the osc to init */
#if (!defined(K60_CLK) && !defined(K53_CLK) && !defined(ASB817))
while (!(MCG_S & MCG_S_OSCINIT_MASK)){}; // wait for oscillator to initialize
#endif
while (MCG_S & MCG_S_IREFST_MASK){}; // wait for Reference clock Status bit to clear
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}; // Wait for clock status bits to show clock source is ext ref clk
// Now in FBE
#if (defined(K60_CLK) || defined(K53_CLK))
MCG_C5 = MCG_C5_PRDIV(0x18);
#else
// Configure PLL Ref Divider, PLLCLKEN=0, PLLSTEN=0, PRDIV=5
// The crystal frequency is used to select the PRDIV value. Only even frequency crystals are supported
// that will produce a 2MHz reference clock to the PLL.
MCG_C5 = MCG_C5_PRDIV(crystal_val); // Set PLL ref divider to match the crystal used
#endif
// Ensure MCG_C6 is at the reset default of 0. LOLIE disabled, PLL disabled, clk monitor disabled, PLL VCO divider is clear
MCG_C6 = 0x0;
// Select the PLL VCO divider and system clock dividers depending on clocking option
switch (clk_option) {
case 0:
// Set system options dividers
//MCG=PLL, core = MCG, bus = MCG, FlexBus = MCG, Flash clock= MCG/2
set_sys_dividers(0,0,0,1);
// Set the VCO divider and enable the PLL for 50MHz, LOLIE=0, PLLS=1, CME=0, VDIV=1
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(1); //VDIV = 1 (x25)
pll_freq = 50;
break;
case 1:
// Set system options dividers
//MCG=PLL, core = MCG, bus = MCG/2, FlexBus = MCG/2, Flash clock= MCG/4
set_sys_dividers(0,1,1,3);
// Set the VCO divider and enable the PLL for 100MHz, LOLIE=0, PLLS=1, CME=0, VDIV=26
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(26); //VDIV = 26 (x50)
pll_freq = 100;
break;
case 2:
// Set system options dividers
//MCG=PLL, core = MCG, bus = MCG/2, FlexBus = MCG/2, Flash clock= MCG/4
set_sys_dividers(0,1,1,3);
// Set the VCO divider and enable the PLL for 96MHz, LOLIE=0, PLLS=1, CME=0, VDIV=24
MCG_C6 = MCG_C6_PLLS_MASK | MCG_C6_VDIV(24); //VDIV = 24 (x48)
pll_freq = 96;
break;
case 3:
// Set system options dividers
//MCG=PLL, core = MCG, bus = MCG, FlexBus = MCG, Flash clock= MCG/2
set_sys_dividers(0,0,0,1);
// Set the VCO divider and enable the PLL for 48MHz, LOLIE=0, PLLS=1, CME=0, VDIV=0
MCG_C6 = MCG_C6_PLLS_MASK; //VDIV = 0 (x24)
pll_freq = 48;
break;
}
while (!(MCG_S & MCG_S_PLLST_MASK)){}; // wait for PLL status bit to set
while (!(MCG_S & MCG_S_LOCK_MASK)){}; // Wait for LOCK bit to set
// Now running PBE Mode
// Transition into PEE by setting CLKS to 0
// CLKS=0, FRDIV=3, IREFS=0, IRCLKEN=0, IREFSTEN=0
MCG_C1 &= ~MCG_C1_CLKS_MASK;
// Wait for clock status bits to update
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){};
// Now running PEE Mode
return pll_freq;
} //pll_init
/*
* This routine must be placed in RAM. It is a workaround for errata e2448.
* Flash prefetch must be disabled when the flash clock divider is changed.
* This cannot be performed while executing out of flash.
* There must be a short delay after the clock dividers are changed before prefetch
* can be re-enabled.
*/
#if (defined(IAR))
__ramfunc void set_sys_dividers(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4)
#elif (defined(CW))
__relocate_code__
void set_sys_dividers(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4)
#endif
{
uint32 temp_reg;
uint8 i;
temp_reg = FMC_PFAPR; // store present value of FMC_PFAPR
// set M0PFD through M7PFD to 1 to disable prefetch
FMC_PFAPR |= FMC_PFAPR_M7PFD_MASK | FMC_PFAPR_M6PFD_MASK | FMC_PFAPR_M5PFD_MASK
| FMC_PFAPR_M4PFD_MASK | FMC_PFAPR_M3PFD_MASK | FMC_PFAPR_M2PFD_MASK
| FMC_PFAPR_M1PFD_MASK | FMC_PFAPR_M0PFD_MASK;
// set clock dividers to desired value
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2)
| SIM_CLKDIV1_OUTDIV3(outdiv3) | SIM_CLKDIV1_OUTDIV4(outdiv4);
// wait for dividers to change
for (i = 0 ; i < outdiv4 ; i++)
{}
FMC_PFAPR = temp_reg; // re-store original value of FMC_PFAPR
return;
} // set_sys_dividers
/********************************************************************/
void mcg_pee_2_blpi(void)
{
uint8 temp_reg;
// Transition from PEE to BLPI: PEE -> PBE -> FBE -> FBI -> BLPI
// Step 1: PEE -> PBE
MCG_C1 |= MCG_C1_CLKS(2); // System clock from external reference OSC, not PLL.
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}; // Wait for clock status to update.
// Step 2: PBE -> FBE
MCG_C6 &= ~MCG_C6_PLLS_MASK; // Clear PLLS to select FLL, still running system from ext OSC.
while (MCG_S & MCG_S_PLLST_MASK){}; // Wait for PLL status flag to reflect FLL selected.
// Step 3: FBE -> FBI
MCG_C2 &= ~MCG_C2_LP_MASK; // FLL remains active in bypassed modes.
MCG_C2 |= MCG_C2_IRCS_MASK; // Select fast (1MHz) internal reference
temp_reg = MCG_C1;
temp_reg &= ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK);
temp_reg |= (MCG_C1_CLKS(1) | MCG_C1_IREFS_MASK); // Select internal reference (fast IREF clock @ 1MHz) as MCG clock source.
MCG_C1 = temp_reg;
while (MCG_S & MCG_S_IREFST_MASK){}; // Wait for Reference Status bit to update.
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x1){}; // Wait for clock status bits to update
// Step 4: FBI -> BLPI
MCG_C1 |= MCG_C1_IREFSTEN_MASK; // Keep internal reference clock running in STOP modes.
MCG_C2 |= MCG_C2_LP_MASK; // FLL remains disabled in bypassed modes.
while (!(MCG_S & MCG_S_IREFST_MASK)){}; // Wait for Reference Status bit to update.
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x1){}; // Wait for clock status bits to update.
} // end MCG PEE to BLPI
/********************************************************************/
void mcg_blpi_2_pee(void)
{
uint8 temp_reg;
// Transition from BLPI to PEE: BLPI -> FBI -> FEI -> FBE -> PBE -> PEE
// Step 1: BLPI -> FBI
MCG_C2 &= ~MCG_C2_LP_MASK; // FLL remains active in bypassed modes.
while (!(MCG_S & MCG_S_IREFST_MASK)){}; // Wait for Reference Status bit to update.
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x1){}; // Wait for clock status bits to update
// Step 2: FBI -> FEI
MCG_C2 &= ~MCG_C2_LP_MASK; // FLL remains active in bypassed modes.
temp_reg = MCG_C2; // assign temporary variable of MCG_C2 contents
temp_reg &= ~MCG_C2_RANGE_MASK; // set RANGE field location to zero
temp_reg |= (0x2 << 0x4); // OR in new values
MCG_C2 = temp_reg; // store new value in MCG_C2
MCG_C4 = 0x0E; // Low-range DCO output (~10MHz bus). FCTRIM=%0111.
MCG_C1 = 0x04; // Select internal clock as MCG source, FRDIV=%000, internal reference selected.
while (!(MCG_S & MCG_S_IREFST_MASK)){}; // Wait for Reference Status bit to update
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x0){}; // Wait for clock status bits to update
// Handle FEI to PEE transitions using standard clock initialization routine.
core_clk_mhz = pll_init(CORE_CLK_MHZ, REF_CLK);
/* Use the value obtained from the pll_init function to define variables
* for the core clock in kHz and also the peripheral clock. These
* variables can be used by other functions that need awareness of the
* system frequency.
*/
core_clk_khz = core_clk_mhz * 1000;
periph_clk_khz = core_clk_khz / (((SIM_CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> 24)+ 1);
} // end MCG BLPI to PEE
/********************************************************************/
void mcg_pbe_2_pee(void)
{
MCG_C1 &= ~MCG_C1_CLKS_MASK; // select PLL as MCG_OUT
// Wait for clock status bits to update
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){};
switch (CORE_CLK_MHZ) {
case PLL50:
core_clk_khz = 50000;
break;
case PLL100:
core_clk_khz = 100000;
break;
case PLL96:
core_clk_khz = 96000;
break;
case PLL48:
core_clk_khz = 48000;
break;
}
}

View file

@ -0,0 +1,61 @@
/*
* File: pll_init.h
* Purpose: pll_driver specific declarations
*
* Notes:
*/
#ifndef __MCG_H__
#define __MCG_H__
/********************************************************************/
/* For some reason CW needs to have cw.h explicitly included here for
* the code relocation of set_sys_dividers() to work correctly even
* though common.h should pull in cw.h.
*/
#if (defined(CW))
#include "cw.h"
#endif
unsigned char pll_init(unsigned char, unsigned char);
void mcg_pee_2_blpi(void);
void mcg_blpi_2_pee(void);
void mcg_pbe_2_pee(void);
#if (defined(IAR))
__ramfunc void set_sys_dividers(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4);
#elif (defined(CW))
__relocate_code__
void set_sys_dividers(uint32 outdiv1, uint32 outdiv2, uint32 outdiv3, uint32 outdiv4);
#endif
enum clk_option
{
PLL50,
PLL100,
PLL96,
PLL48
};
enum crystal_val
{
XTAL2,
XTAL4,
XTAL6,
XTAL8,
XTAL10,
XTAL12,
XTAL14,
XTAL16,
XTAL18,
XTAL20,
XTAL22,
XTAL24,
XTAL26,
XTAL28,
XTAL30,
XTAL32
};
/********************************************************************/
#endif /* __MCG_H__ */

View file

@ -0,0 +1,129 @@
/*
* File: uart.c
* Purpose: Provide common UART routines for serial IO
*
* Notes:
*
*/
#include "common.h"
#include "uart.h"
/********************************************************************/
/*
* Initialize the UART for 8N1 operation, interrupts disabled, and
* no hardware flow-control
*
* NOTE: Since the UARTs are pinned out in multiple locations on most
* Kinetis devices, this driver does not enable UART pin functions.
* The desired pins should be enabled before calling this init function.
*
* Parameters:
* uartch UART channel to initialize
* sysclk UART module Clock in kHz(used to calculate baud)
* baud UART baud rate
*/
void uart_init (UART_MemMapPtr uartch, int sysclk, int baud)
{
register uint16 sbr, brfa;
uint8 temp;
/* Enable the clock to the selected UART */
if(uartch == UART0_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
else
if (uartch == UART1_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART1_MASK;
else
if (uartch == UART2_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;
else
if(uartch == UART3_BASE_PTR)
SIM_SCGC4 |= SIM_SCGC4_UART3_MASK;
else
if(uartch == UART4_BASE_PTR)
SIM_SCGC1 |= SIM_SCGC1_UART4_MASK;
else
SIM_SCGC1 |= SIM_SCGC1_UART5_MASK;
/* Make sure that the transmitter and receiver are disabled while we
* change settings.
*/
UART_C2_REG(uartch) &= ~(UART_C2_TE_MASK
| UART_C2_RE_MASK );
/* Configure the UART for 8-bit mode, no parity */
UART_C1_REG(uartch) = 0; /* We need all default settings, so entire register is cleared */
/* Calculate baud settings */
sbr = (uint16)((sysclk*1000)/(baud * 16));
/* Save off the current value of the UARTx_BDH except for the SBR field */
temp = UART_BDH_REG(uartch) & ~(UART_BDH_SBR(0x1F));
UART_BDH_REG(uartch) = temp | UART_BDH_SBR(((sbr & 0x1F00) >> 8));
UART_BDL_REG(uartch) = (uint8)(sbr & UART_BDL_SBR_MASK);
/* Determine if a fractional divider is needed to get closer to the baud rate */
brfa = (((sysclk*32000)/(baud * 16)) - (sbr * 32));
/* Save off the current value of the UARTx_C4 register except for the BRFA field */
temp = UART_C4_REG(uartch) & ~(UART_C4_BRFA(0x1F));
UART_C4_REG(uartch) = temp | UART_C4_BRFA(brfa);
/* Enable receiver and transmitter */
UART_C2_REG(uartch) |= (UART_C2_TE_MASK
| UART_C2_RE_MASK );
}
/********************************************************************/
/*
* Wait for a character to be received on the specified UART
*
* Parameters:
* channel UART channel to read from
*
* Return Values:
* the received character
*/
char uart_getchar (UART_MemMapPtr channel)
{
/* Wait until character has been received */
while (!(UART_S1_REG(channel) & UART_S1_RDRF_MASK));
/* Return the 8-bit data from the receiver */
return UART_D_REG(channel);
}
/********************************************************************/
/*
* Wait for space in the UART Tx FIFO and then send a character
*
* Parameters:
* channel UART channel to send to
* ch character to send
*/
void uart_putchar (UART_MemMapPtr channel, char ch)
{
/* Wait until space is available in the FIFO */
while(!(UART_S1_REG(channel) & UART_S1_TDRE_MASK));
/* Send the character */
UART_D_REG(channel) = (uint8)ch;
}
/********************************************************************/
/*
* Check to see if a character has been received
*
* Parameters:
* channel UART channel to check for a character
*
* Return values:
* 0 No character received
* 1 Character has been received
*/
int uart_getchar_present (UART_MemMapPtr channel)
{
return (UART_S1_REG(channel) & UART_S1_RDRF_MASK);
}
/********************************************************************/

View file

@ -0,0 +1,20 @@
/*
* File: uart.h
* Purpose: Provide common ColdFire UART routines for polled serial IO
*
* Notes:
*/
#ifndef __UART_H__
#define __UART_H__
/********************************************************************/
void uart_init (UART_MemMapPtr, int, int);
char uart_getchar (UART_MemMapPtr);
void uart_putchar (UART_MemMapPtr, char);
int uart_getchar_present (UART_MemMapPtr);
/********************************************************************/
#endif /* __UART_H__ */

View file

@ -0,0 +1,59 @@
/*
* File: wdog.c
* Purpose: Provide common watchdog module routines
*
* Notes: Need to add more functionality. Right now it
* is just a disable routine since we know almost
* all projects will need that.
*
*/
#include "common.h"
#include "wdog.h"
/********************************************************************/
/*
* Watchdog timer disable routine
*
* Parameters:
* none
*/
void wdog_disable(void)
{
/* First unlock the watchdog so that we can write to registers */
wdog_unlock();
/* Clear the WDOGEN bit to disable the watchdog */
WDOG_STCTRLH &= ~WDOG_STCTRLH_WDOGEN_MASK;
}
/********************************************************************/
/*
* Watchdog timer unlock routine. Writing 0xC520 followed by 0xD928
* will unlock the write once registers in the WDOG so they are writable
* within the WCT period.
*
* Parameters:
* none
*/
void wdog_unlock(void)
{
/* NOTE: DO NOT SINGLE STEP THROUGH THIS FUNCTION!!! */
/* There are timing requirements for the execution of the unlock. If
* you single step through the code you will cause the CPU to reset.
*/
/* This sequence must execute within 20 clock cycles, so disable
* interrupts will keep the code atomic and ensure the timing.
*/
DisableInterrupts;
/* Write 0xC520 to the unlock register */
WDOG_UNLOCK = 0xC520;
/* Followed by 0xD928 to complete the unlock */
WDOG_UNLOCK = 0xD928;
/* Re-enable interrupts now that we are done */
EnableInterrupts;
}
/********************************************************************/

View file

@ -0,0 +1,18 @@
/*
* File: wdog.h
* Purpose: Provide common watchdog module routines
*
* Notes:
*/
#ifndef __WDOG_H__
#define __WDOG_H__
/********************************************************************/
// function prototypes
void wdog_disable(void);
void wdog_unlock(void);
/********************************************************************/
#endif /* __WDOG_H__ */

View file

@ -0,0 +1,150 @@
/*
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.
*/
/*-----------------------------------------------------------
* Simple GPIO (parallel port) IO routines.
*-----------------------------------------------------------*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Standard demo include. */
#include "partest.h"
/* Freescale includes. */
#include "common.h"
/* Only the LEDs on one of the two seven segment displays are used. */
#define partstMAX_LEDS 4
/* The bits used to control the LEDs on the TWR-K60N512. */
const unsigned long ulLEDs[ partstMAX_LEDS ] = { ( 1UL << 10UL ), ( 1UL << 29UL ), ( 1UL << 28UL ), ( 1UL << 11UL ) };
/*-----------------------------------------------------------*/
void vParTestInitialise( void )
{
/* Set PTA10, PTA11, PTA28, and PTA29 (connected to LED's) for GPIO
functionality. */
PORTA_PCR10 = ( 0 | PORT_PCR_MUX( 1 ) );
PORTA_PCR11 = ( 0 | PORT_PCR_MUX( 1 ) );
PORTA_PCR28 = ( 0 | PORT_PCR_MUX( 1 ) );
PORTA_PCR29 = ( 0 | PORT_PCR_MUX( 1 ) );
/* Change PTA10, PTA11, PTA28, PTA29 to outputs. */
GPIOA_PDDR=GPIO_PDDR_PDD( ulLEDs[ 0 ] | ulLEDs[ 1 ] | ulLEDs[ 2 ] | ulLEDs[ 3 ] );
/* Start with LEDs off. */
GPIOA_PTOR = ~0U;
}
/*-----------------------------------------------------------*/
void vParTestSetLED( unsigned long ulLED, signed portBASE_TYPE xValue )
{
if( ulLED < partstMAX_LEDS )
{
if( xValue == pdTRUE )
{
GPIOA_PCOR = ulLEDs[ ulLED ];
}
else
{
GPIOA_PSOR = ulLEDs[ ulLED ];
}
}
}
/*-----------------------------------------------------------*/
void vParTestToggleLED( unsigned long ulLED )
{
if( ulLED < partstMAX_LEDS )
{
GPIOA_PTOR = ulLEDs[ ulLED ];
}
}
/*-----------------------------------------------------------*/
long lParTestGetLEDState( unsigned long ulLED )
{
long lReturn = pdFALSE;
if( ulLED < partstMAX_LEDS )
{
lReturn = GPIOA_PDOR & ulLEDs[ ulLED ];
if( lReturn == 0 )
{
lReturn = pdTRUE;
}
else
{
lReturn = pdFALSE;
}
}
return lReturn;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\RTOSDemo.ewp</path>
</project>
<batchBuild>
<batchDefinition>
<name>All</name>
<member>
<project>gpio_k40_tower</project>
<configuration>FLASH_128KB_PFLASH</configuration>
</member>
<member>
<project>gpio_k40_tower</project>
<configuration>FLASH_64KB_PFLASH_64KB_DFLASH</configuration>
</member>
<member>
<project>gpio_k40_tower</project>
<configuration>RAM_128KB</configuration>
</member>
<member>
<project>RTOSDemo</project>
<configuration>FLASH_128KB_PFLASH</configuration>
</member>
<member>
<project>RTOSDemo</project>
<configuration>FLASH_64KB_PFLASH_64KB_DFLASH</configuration>
</member>
<member>
<project>RTOSDemo</project>
<configuration>RAM_128KB</configuration>
</member>
<member>
<project>gpio_k53_tower</project>
<configuration>FLASH_128KB_PFLASH</configuration>
</member>
<member>
<project>gpio_k53_tower</project>
<configuration>FLASH_64KB_PFLASH_64KB_DFLASH</configuration>
</member>
<member>
<project>gpio_k53_tower</project>
<configuration>RAM_128KB</configuration>
</member>
</batchDefinition>
</batchBuild>
</workspace>

View file

@ -0,0 +1,668 @@
/*
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.
*/
/*
* main-blinky.c is included when the "Blinky" build configuration is used.
* main-full.c is included when the "Full" build configuration is used.
*
* main-full.c (this file) defines a comprehensive demo that creates many
* tasks, queues, semaphores and timers. It also demonstrates how Cortex-M3
* interrupts can interact with FreeRTOS tasks/timers, a simple web server, and
* run time statistics gathering functionality. ***IF YOU ARE LOOKING FOR A
* SIMPLER STARTING POINT THEN USE THE "BLINKY" BUILD CONFIGURATION FIRST.***
*
* If the Ethernet functionality is excluded, then this demo will run 'stand
* alone' (without the rest of the tower system) on the TWR-K60N512 tower
* module. If the Ethernet functionality is included, then the full Freescale
* K60 tower kit, including both the TWR-K60N512 and TWR-SER modules, is
* required (as the Ethernet connector is on the TWR-SER). The TWR-K60N512 is
* populated with a K60N512 Cortex-M4 microcontroller.
*
* The main() Function:
* main() creates four demo specific software timers, and one demo specific
* task (the web server task). It also creates a whole host of 'standard
* demo' tasks/queues/semaphores/timers, before starting the scheduler. The
* demo specific tasks and timers are described in the comments here. The
* standard demo tasks are described on the FreeRTOS.org web site.
*
* The standard demo tasks provide no specific functionality. They are
* included to both test the FreeRTOS port, and provide examples of how the
* various FreeRTOS API functions can be used.
*
* This demo creates 37 persistent tasks, then dynamically creates and destroys
* another two tasks as the demo executes.
*
*
* The Demo Specific "LED" Timers and Callback Function:
* Two very simple LED timers are created. All they do is toggle an LED each
* when the timer callback function is executed. The two timers share a
* callback function, so the callback function parameter is used to determine
* which timer actually expired, and therefore, which LED to toggle. Both
* timers use a different frequency, one toggles the blue LED and the other the
* green LED.
*
* The LED/Button Software Timer and the Button Interrupt:
* The user button SW2 is configured to generate an interrupt each time it is
* pressed. The interrupt service routine switches the orange/yellow LED on,
* and resets the LED software timer. The LED timer has a 5000 millisecond (5
* second) period, and uses a callback function that is defined to just turn the
* LED off again. Therefore, pressing the user button will turn the LED on, and
* the LED will remain on until a full five seconds pass without the button
* being pressed.
*
* The Demo Specific "Check" Timer and Callback Function:
* The check timer period is initially set to three seconds. The check timer
* callback function checks that all the standard demo tasks are not only still
* executing, but are executing without reporting any errors. If the check
* timer discovers that a task has either stalled, or reported an error, then it
* changes its own period from the initial three seconds, to just 200ms. The
* check timer callback function also toggles the orange/red LED each time it is
* called. This provides a visual indication of the system status: If the LED
* toggles every three seconds, then no issues have been discovered. If the LED
* toggles every 200ms, then an issue has been discovered with at least one
* task. The last reported issue is latched into the pcStatusMessage variable,
* and displayed at the bottom of the "task stats" web page served by the
* embedded web server task.
*
* The web server task:
* The web server task implements a simple embedded web server that includes
* CGI scripting. Pages are provided that allow task statistics, network
* statistics and run time statistics to be viewed. In addition, an IO page is
* served that allows the orange/yellow LED to be turned on and off. Finally,
* a page is included that serves a large jpg file. See the documentation page
* for this demo on the http://www.FreeRTOS.org web site for web server
* configuration and usage instructions.
*
* The Demo Specific Idle Hook Function:
* The idle hook function demonstrates how to query the amount of FreeRTOS heap
* space that is remaining (see vApplicationIdleHook() defined in this file).
*
* The Demo Specific Tick Hook Function:
* The tick hook function is used to test the interrupt safe software timer
* functionality.
*
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
/* Freescale includes. */
#include "common.h"
/* Common demo includes. */
#include "partest.h"
#include "flash.h"
#include "BlockQ.h"
#include "death.h"
#include "blocktim.h"
#include "semtest.h"
#include "GenQTest.h"
#include "QPeek.h"
#include "recmutex.h"
#include "TimerDemo.h"
#include "PollQ.h"
#include "countsem.h"
#include "dynamic.h"
/* The LED toggled by the check timer callback function. */
#define mainCHECK_LED 3UL
/* The LED turned on by the button interrupt, and turned off by the LED timer. */
#define mainTIMER_CONTROLLED_LED 2UL
/* The LEDs toggled by the two simple flash LED timers. */
#define mainLED0 0UL
#define mainLED1 1UL
/* Constant used by the standard timer test functions. */
#define mainTIMER_TEST_PERIOD ( 50 )
/* Priorities used by the various different standard demo tasks. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The WEB server uses string handling functions, which in turn use a bit more
stack than most of the other tasks. */
#define mainuIP_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3 )
/* The period at which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_RATE_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS )
/* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_RATE_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS )
/* The LED that is turned on by pressing SW2 remains on until the button has not
been pushed for a full 5000ms. */
#define mainBUTTON_LED_TIMER_PERIOD_MS ( 5000UL / portTICK_RATE_MS )
/* The period at which the two simple LED flash timers will execute their
callback functions. */
#define mainLED1_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS )
#define mainLED2_TIMER_PERIOD_MS ( 600UL / portTICK_RATE_MS )
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL )
/* The vector used by the GPIO port E. Button SW2 is configured to generate
an interrupt on this port. */
#define mainGPIO_E_VECTOR ( 91 )
/*-----------------------------------------------------------*/
/*
* Setup the NVIC, LED outputs, and button inputs.
*/
static void prvSetupHardware( void );
/*
* Creates the timers that are specific to this demo - namely, the check timer
* the button LED timer, and the two simple LED flash timers.
*/
static void prvCreateDemoSpecificTimers( void );
/*
* The LED/button timer callback function. This does nothing but switch an LED
* off.
*/
static void prvButtonLEDTimerCallback( xTimerHandle xTimer );
/*
* The callback function used by both simple LED flash timers. Both timers use
* the same callback, so the function parameter is used to determine which LED
* should be flashed (effectively to determine which timer has expired).
*/
static void prvLEDTimerCallback( xTimerHandle xTimer );
/*
* The check timer callback function, as described at the top of this file.
*/
static void prvCheckTimerCallback( xTimerHandle xTimer );
/*
* Contains the implementation of the web server.
*/
extern void vuIP_Task( void *pvParameters );
/*-----------------------------------------------------------*/
/* The LED/Button software timer. This uses prvButtonLEDTimerCallback() as it's
callback function. */
static xTimerHandle xLEDButtonTimer = NULL;
/* The check timer. This uses prvCheckTimerCallback() as its callback
function. */
static xTimerHandle xCheckTimer = NULL;
/* LED timers - these simply flash LEDs, each using a different frequency. Both
use the same prvLEDTimerCallback() callback function. */
static xTimerHandle xLED1Timer = NULL, xLED2Timer = NULL;
/* If an error is detected in a standard demo task, then pcStatusMessage will
be set to point to a string that identifies the offending task. This is just
to make debugging easier. */
static const char *pcStatusMessage = NULL;
/* Used in the run time stats calculations. */
static unsigned long ulClocksPer10thOfAMilliSecond = 0UL;
/*-----------------------------------------------------------*/
void main( void )
{
/* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware();
/* Create the timers that are specific to this demo - other timers are
created as part of the standard demo within vStartTimerDemoTask. */
prvCreateDemoSpecificTimers();
/* Create a lot of 'standard demo' tasks. Nearly 40 tasks are created in
this demo. For a much simpler demo, select the 'blinky' build
configuration. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartQueuePeekTasks();
vStartRecursiveMutexTasks();
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks();
/* The web server task. */
xTaskCreate( vuIP_Task, "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL );
/* The suicide tasks must be created last, as they need to know how many
tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given
time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the tasks and timers running. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( xTimerHandle xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
/* Check the standard demo tasks are running without error. Latch the
latest reported error in the pcStatusMessage character pointer. The latched
string can be viewed using the embedded web server - it is displayed at
the bottom of the served "task stats" page. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: GenQueue";
}
if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: QueuePeek\n";
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: BlockQueue\n";
}
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: BlockTime\n";
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: SemTest\n";
}
if( xIsCreateTaskStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: Death\n";
}
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: RecMutex\n";
}
if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE )
{
pcStatusMessage = "Error: TimerDemo\n";
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: PollQueue\n";
}
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: CountSem\n";
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: DynamicPriority\n";
}
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latch in pcStatusMessage? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED
toggles. */
if( pcStatusMessage != NULL )
{
if( lChangedTimerPeriodAlready == pdFALSE )
{
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
}
/*-----------------------------------------------------------*/
static void prvButtonLEDTimerCallback( xTimerHandle xTimer )
{
/* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. */
vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE );
}
/*-----------------------------------------------------------*/
static void prvLEDTimerCallback( xTimerHandle xTimer )
{
unsigned long ulLED;
/* This callback is shared by two timers, so the parameter is used to
determine which LED to toggle. The LED number is stored in the ID of the
timer. */
ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer );
vParTestToggleLED( ulLED );
}
/*-----------------------------------------------------------*/
/* The ISR executed when the user button is pushed. */
void vPort_E_ISRHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */
vParTestSetLED( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is equal to or below the
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDButtonTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. */
PORTE_ISFR = 0xFFFFFFFFUL;
/* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* Enable the interrupt on SW1. */
taskDISABLE_INTERRUPTS();
PORTE_PCR26 = PORT_PCR_MUX( 1 ) | PORT_PCR_IRQC( 0xA ) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
enable_irq( mainGPIO_E_VECTOR );
/* The interrupt calls an interrupt safe API function - so its priority must
be equal to or lower than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. */
set_irq_priority( mainGPIO_E_VECTOR, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
/* Configure the LED outputs. */
vParTestInitialise();
}
/*-----------------------------------------------------------*/
static void prvCreateDemoSpecificTimers( void )
{
/* This function creates the timers, but does not start them. This is
because the standard demo timer test is started from main(), after this
function is called. The standard demo timer test will deliberately fill the
timer command queue - and will fail the test if the command queue already
holds start commands for the timers created here. Instead, the timers
created in this function are started from the idle task, at which time, the
timer service/daemon task will be running, and will have drained the timer
command queue. */
/* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of
this file. */
xLEDButtonTimer = xTimerCreate( ( const signed char * ) "ButtonLEDTimer", /* A text name, purely to help debugging. */
( mainBUTTON_LED_TIMER_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one shot timer, so xAutoReload is set to pdFALSE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */
prvButtonLEDTimerCallback /* The callback function that switches the LED off. */
);
/* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */
xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
);
/* Create the software timers used to simply flash LEDs. These two timers
share a callback function, so the callback parameter is used to pass in the
LED that should be toggled. */
xLED1Timer = xTimerCreate( ( const signed char * ) "LED1Timer",/* A text name, purely to help debugging. */
( mainLED1_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) mainLED0, /* The ID is used to pass in the number of the LED to be toggled. */
prvLEDTimerCallback /* The callback function simply toggles the LED specified by its parameter. */
);
xLED2Timer = xTimerCreate( ( const signed char * ) "LED2Timer",/* A text name, purely to help debugging. */
( mainLED2_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) mainLED1, /* The ID is used to pass in the number of the LED to be toggled. */
prvLEDTimerCallback /* The callback function simply toggles the LED specified by its parameter. */
);
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
static long lPrintedOut = pdFALSE;
volatile size_t xFreeHeapSpace;
if( lPrintedOut == pdFALSE )
{
lPrintedOut = pdTRUE;
/* The timer command queue will have been filled when the timer test
tasks were created in main() (this is part of the test they perform).
Therefore, while the check and LED timers can be created in main(), they
cannot be started from main(). Once the scheduler has started, the timer
service task will drain the command queue, and now the check and LED
timers can be started successfully. Normally the idle task must not
call a function that could cause it to block in case there are no tasks
that are able to run. In this case, however, it is ok as posting to the
timer command queue guarantees that at least the timer service/daemon
task will be able to execute. */
xTimerStart( xCheckTimer, portMAX_DELAY );
xTimerStart( xLED1Timer, portMAX_DELAY );
xTimerStart( xLED2Timer, portMAX_DELAY );
xFreeHeapSpace = xPortGetFreeHeapSize();
if( xFreeHeapSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
}
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */
vTimerPeriodicISRTests();
}
/*-----------------------------------------------------------*/
char *pcGetTaskStatusMessage( void )
{
/* A simple GET function used by a CGI script so it can display the
execution status at the bottom of the task stats web page served by the
embedded web server. */
if( pcStatusMessage == NULL )
{
return "All tasks running without error";
}
else
{
return ( char * ) pcStatusMessage;
}
}
/*-----------------------------------------------------------*/
void vMainConfigureTimerForRunTimeStats( void )
{
/* How many clocks are there per tenth of a millisecond? */
ulClocksPer10thOfAMilliSecond = configCPU_CLOCK_HZ / 10000UL;
}
/*-----------------------------------------------------------*/
unsigned long ulMainGetRunTimeCounterValue( void )
{
unsigned long ulSysTickCounts, ulTickCount, ulReturn;
const unsigned long ulSysTickReloadValue = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
volatile unsigned long * const pulCurrentSysTickCount = ( ( volatile unsigned long *) 0xe000e018 );
volatile unsigned long * const pulInterruptCTRLState = ( ( volatile unsigned long *) 0xe000ed04 );
const unsigned long ulSysTickPendingBit = 0x04000000UL;
/* NOTE: There are potentially race conditions here. However, it is used
anyway to keep the examples simple, and to avoid reliance on a separate
timer peripheral. */
/* The SysTick is a down counter. How many clocks have passed since it was
last reloaded? */
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;
/* How many times has it overflowed? */
ulTickCount = xTaskGetTickCountFromISR();
/* This is called from the context switch, so will be called from a
critical section. xTaskGetTickCountFromISR() contains its own critical
section, and the ISR safe critical sections are not designed to nest,
so reset the critical section. */
portSET_INTERRUPT_MASK_FROM_ISR();
/* Is there a SysTick interrupt pending? */
if( ( *pulInterruptCTRLState & ulSysTickPendingBit ) != 0UL )
{
/* There is a SysTick interrupt pending, so the SysTick has overflowed
but the tick count not yet incremented. */
ulTickCount++;
/* Read the SysTick again, as the overflow might have occurred since
it was read last. */
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;
}
/* Convert the tick count into tenths of a millisecond. THIS ASSUMES
configTICK_RATE_HZ is 1000! */
ulReturn = ( ulTickCount * 10UL ) ;
/* Add on the number of tenths of a millisecond that have passed since the
tick count last got updated. */
ulReturn += ( ulSysTickCounts / ulClocksPer10thOfAMilliSecond );
return ulReturn;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,402 @@
/*
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.
*/
/*
* main-blinky.c is included when the "Blinky" build configuration is used.
* main-full.c is included when the "Full" build configuration is used.
*
* main-blinky.c (this file) defines a very simple demo that creates two tasks,
* one queue, and one timer. It also demonstrates how Cortex-M3 interrupts can
* interact with FreeRTOS tasks/timers.
*
* This simple demo project runs 'stand alone' (without the rest of the tower
* system) on the TWR-K60N512 tower module, which is populated with a K60N512
* Cortex-M4 microcontroller.
*
* The idle hook function:
* The idle hook function demonstrates how to query the amount of FreeRTOS heap
* space that is remaining (see vApplicationIdleHook() defined in this file).
*
* The main() Function:
* main() creates one software timer, one queue, and two tasks. It then starts
* the scheduler.
*
* The Queue Send Task:
* The queue send task is implemented by the prvQueueSendTask() function in
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
* block for 200 milliseconds, before sending the value 100 to the queue that
* was created within main(). Once the value is sent, the task loops back
* around to block for another 200 milliseconds.
*
* The Queue Receive Task:
* The queue receive task is implemented by the prvQueueReceiveTask() function
* in this file. prvQueueReceiveTask() sits in a loop that causes it to
* repeatedly attempt to read data from the queue that was created within
* main(). When data is received, the task checks the value of the data, and
* if the value equals the expected 100, toggles the blue LED. The 'block
* time' parameter passed to the queue receive function specifies that the task
* should be held in the Blocked state indefinitely to wait for data to be
* available on the queue. The queue receive task will only leave the Blocked
* state when the queue send task writes to the queue. As the queue send task
* writes to the queue every 200 milliseconds, the queue receive task leaves the
* Blocked state every 200 milliseconds, and therefore toggles the blue LED
* every 200 milliseconds.
*
* The LED Software Timer and the Button Interrupt:
* The user button SW2 is configured to generate an interrupt each time it is
* pressed. The interrupt service routine switches the green LED on, and
* resets the LED software timer. The LED timer has a 5000 millisecond (5
* second) period, and uses a callback function that is defined to just turn the
* LED off again. Therefore, pressing the user button will turn the LED on, and
* the LED will remain on until a full five seconds pass without the button
* being pressed.
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
/* Freescale includes. */
#include "common.h"
/* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue, specified in milliseconds, and
converted to ticks using the portTICK_RATE_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS )
/* The LED will remain on until the button has not been pushed for a full
5000ms. */
#define mainBUTTON_LED_TIMER_PERIOD_MS ( 5000UL / portTICK_RATE_MS )
/* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find
the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* The LED toggle by the queue receive task (blue). */
#define mainTASK_CONTROLLED_LED ( 1UL << 10UL )
/* The LED turned on by the button interrupt, and turned off by the LED timer
(green). */
#define mainTIMER_CONTROLLED_LED ( 1UL << 29UL )
/* The vector used by the GPIO port E. Button SW2 is configured to generate
an interrupt on this port. */
#define mainGPIO_E_VECTOR ( 91 )
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL )
/*-----------------------------------------------------------*/
/*
* Setup the NVIC, LED outputs, and button inputs.
*/
static void prvSetupHardware( void );
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
/*
* The LED timer callback function. This does nothing but switch off the
* LED defined by the mainTIMER_CONTROLLED_LED constant.
*/
static void prvButtonLEDTimerCallback( xTimerHandle xTimer );
/*-----------------------------------------------------------*/
/* The queue used by both tasks. */
static xQueueHandle xQueue = NULL;
/* The LED software timer. This uses prvButtonLEDTimerCallback() as its callback
function. */
static xTimerHandle xButtonLEDTimer = NULL;
/*-----------------------------------------------------------*/
void main( void )
{
/* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware();
/* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of
this file. */
xButtonLEDTimer = xTimerCreate( ( const signed char * ) "ButtonLEDTimer", /* A text name, purely to help debugging. */
mainBUTTON_LED_TIMER_PERIOD_MS, /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one shot timer, so xAutoReload is set to pdFALSE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */
prvButtonLEDTimerCallback /* The callback function that switches the LED off. */
);
/* Start the tasks and timer running. */
vTaskStartScheduler();
}
/* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvButtonLEDTimerCallback( xTimerHandle xTimer )
{
/* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. */
GPIOA_PSOR = mainTIMER_CONTROLLED_LED;
}
/*-----------------------------------------------------------*/
/* The ISR executed when the user button is pushed. */
void vPort_E_ISRHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */
GPIOA_PCOR = mainTIMER_CONTROLLED_LED;
/* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xButtonLEDTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. */
PORTE_ISFR = 0xFFFFFFFFUL;
/* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
{
portTickType xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
{
/* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU
time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and
toggle an LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
{
unsigned long ulReceivedValue;
for( ;; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL )
{
GPIOA_PTOR = mainTASK_CONTROLLED_LED;
}
}
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* Enable the interrupt on SW1. */
PORTE_PCR26 = PORT_PCR_MUX( 1 ) | PORT_PCR_IRQC( 0xA ) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
enable_irq( mainGPIO_E_VECTOR );
/* The interrupt calls an interrupt safe API function - so its priority must
be equal to or lower than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. */
set_irq_priority( mainGPIO_E_VECTOR, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
/* Set PTA10, PTA11, PTA28, and PTA29 (connected to LED's) for GPIO
functionality. */
PORTA_PCR10 = ( 0 | PORT_PCR_MUX( 1 ) );
PORTA_PCR11 = ( 0 | PORT_PCR_MUX( 1 ) );
PORTA_PCR28 = ( 0 | PORT_PCR_MUX( 1 ) );
PORTA_PCR29 = ( 0 | PORT_PCR_MUX( 1 ) );
/* Change PTA10, PTA29 to outputs. */
GPIOA_PDDR=GPIO_PDDR_PDD( mainTASK_CONTROLLED_LED | mainTIMER_CONTROLLED_LED );
/* Start with LEDs off. */
GPIOA_PTOR = ~0U;
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
volatile size_t xFreeHeapSpace;
/* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */
xFreeHeapSpace = xPortGetFreeHeapSize();
if( xFreeHeapSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
}
}
/*-----------------------------------------------------------*/
/* The Blinky build configuration does not include Ethernet functionality,
however, the Full and Blinky build configurations share a vectors.h header file.
Therefore, dummy Ethernet interrupt handers need to be defined to keep the
linker happy. */
void vEMAC_TxISRHandler( void ) {}
void vEMAC_RxISRHandler( void ){}
void vEMAC_ErrorISRHandler( void ) {}
/* The Blinky build configuration does not include run time stats gathering,
however, the Full and Blinky build configurations share a FreeRTOSConfig.h
file. Therefore, dummy run time stats functions need to be defined to keep the
linker happy. */
void vMainConfigureTimerForRunTimeStats( void ) {}
unsigned long ulMainGetRunTimeCounterValue( void ) { return 0UL; }
/* A tick hook is used by the "Full" build configuration. The Full and blinky
build configurations share a FreeRTOSConfig.h header file, so this simple build
configuration also has to define a tick hook - even though it does not actually
use it for anything. */
void vApplicationTickHook( void ) {}

View file

@ -0,0 +1,358 @@
/*
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 <string.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
/* uip includes. */
#include "net/uip.h"
#include "net/uip_arp.h"
#include "apps/httpd/httpd.h"
#include "sys/timer.h"
#include "net/clock-arch.h"
#include "emac.h"
/* Demo includes. */
#include "ParTest.h"
/* The buffer used by the uIP stack to both receive and send. In this case,
because the Ethernet driver is implemented to be zero copy - the uip_buf
variable is just a pointer to an Ethernet buffer, and not a buffer in its own
right. */
extern unsigned char *uip_buf;
/* The ARP timer and the periodic timer share a callback function, so the
respective timer IDs are used to determine which timer actually expired. These
constants are assigned to the timer IDs. */
#define uipARP_TIMER 0
#define uipPERIODIC_TIMER 1
/* The length of the queue used to send events from timers or the Ethernet
driver to the uIP stack. */
#define uipEVENT_QUEUE_LENGTH 10
/* A block time of zero simply means "don't block". */
#define uipDONT_BLOCK 0UL
/* Shortcut to the header within the Rx buffer. */
#define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])
/*-----------------------------------------------------------*/
/*
* Setup the MAC address in the MAC itself, and in the uIP stack.
*/
static void prvSetMACAddress( void );
/*
* Perform any uIP initialisation required to ready the stack for http
* processing.
*/
static void prvInitialise_uIP( void );
/*
* The callback function that is assigned to both the periodic timer and the
* ARP timer.
*/
static void prvUIPTimerCallback( xTimerHandle xTimer );
/*
* Port functions required by the uIP stack.
*/
clock_time_t clock_time( void );
/*-----------------------------------------------------------*/
/* The queue used to send TCP/IP events to the uIP stack. */
xQueueHandle xEMACEventQueue = NULL;
/*-----------------------------------------------------------*/
clock_time_t clock_time( void )
{
return xTaskGetTickCount();
}
/*-----------------------------------------------------------*/
void vuIP_Task( void *pvParameters )
{
long i;
unsigned long ulNewEvent = 0UL, ulUIP_Events = 0UL;
unsigned short usPacketLength;
/* Just to prevent compiler warnings about the unused parameter. */
( void ) pvParameters;
/* Initialise the uIP stack, configuring for web server usage. */
prvInitialise_uIP();
/* Initialise the MAC and PHY. */
vEMACInit();
for( ;; )
{
/* Is there received data ready to be processed? */
usPacketLength = usEMACRead();
/* Statements to be executed if data has been received on the Ethernet. */
if( ( usPacketLength > 0U ) && ( uip_buf != NULL ) )
{
uip_len = usPacketLength;
if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
{
uip_arp_ipin();
uip_input();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if( uip_len > 0 )
{
uip_arp_out();
vEMACWrite();
}
}
else if( xHeader->type == htons( UIP_ETHTYPE_ARP ) )
{
uip_arp_arpin();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if( uip_len > 0 )
{
vEMACWrite();
}
}
}
else
{
/* Clear the RX event latched in ulUIP_Events - if one was latched. */
ulUIP_Events &= ~uipETHERNET_RX_EVENT;
}
/* Statements to be executed if the TCP/IP period timer has expired. */
if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL )
{
ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;
if( uip_buf != NULL )
{
for( i = 0; i < UIP_CONNS; i++ )
{
uip_periodic( i );
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if( uip_len > 0 )
{
uip_arp_out();
vEMACWrite();
}
}
}
}
/* Statements to be executed if the ARP timer has expired. */
if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
{
ulUIP_Events &= ~uipARP_TIMER_EVENT;
uip_arp_timer();
}
/* If all latched events have been cleared - block until another event
occurs. */
if( ulUIP_Events == pdFALSE )
{
xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );
ulUIP_Events |= ulNewEvent;
}
}
}
/*-----------------------------------------------------------*/
static void prvSetMACAddress( void )
{
struct uip_eth_addr xAddr;
/* Configure the MAC address in the uIP stack. */
xAddr.addr[ 0 ] = configMAC_ADDR0;
xAddr.addr[ 1 ] = configMAC_ADDR1;
xAddr.addr[ 2 ] = configMAC_ADDR2;
xAddr.addr[ 3 ] = configMAC_ADDR3;
xAddr.addr[ 4 ] = configMAC_ADDR4;
xAddr.addr[ 5 ] = configMAC_ADDR5;
uip_setethaddr( xAddr );
}
/*-----------------------------------------------------------*/
static void prvInitialise_uIP( void )
{
uip_ipaddr_t xIPAddr;
xTimerHandle xARPTimer, xPeriodicTimer;
uip_init();
uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
uip_sethostaddr( &xIPAddr );
uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );
uip_setnetmask( &xIPAddr );
prvSetMACAddress();
httpd_init();
/* Create the queue used to sent TCP/IP events to the uIP stack. */
xEMACEventQueue = xQueueCreate( uipEVENT_QUEUE_LENGTH, sizeof( unsigned long ) );
/* Create and start the uIP timers. */
xARPTimer = xTimerCreate( ( signed char * ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */
( 10000UL / portTICK_RATE_MS ), /* Timer period. */
pdTRUE, /* Autor-reload. */
( void * ) uipARP_TIMER,
prvUIPTimerCallback
);
xPeriodicTimer = xTimerCreate( ( signed char * ) "PeriodicTimer",
( 500UL / portTICK_RATE_MS ),
pdTRUE, /* Autor-reload. */
( void * ) uipPERIODIC_TIMER,
prvUIPTimerCallback
);
/* Sanity check that the timers were indeed created. */
configASSERT( xARPTimer );
configASSERT( xPeriodicTimer );
configASSERT( xEMACEventQueue );
/* These commands will block indefinitely until they succeed, so there is
no point in checking their return values. */
xTimerStart( xARPTimer, portMAX_DELAY );
xTimerStart( xPeriodicTimer, portMAX_DELAY );
}
/*-----------------------------------------------------------*/
static void prvUIPTimerCallback( xTimerHandle xTimer )
{
static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT;
static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT;
/* This is a time callback, so calls to xQueueSend() must not attempt to
block. As this callback is assigned to both the ARP and Periodic timers, the
first thing to do is ascertain which timer it was that actually expired. */
switch( ( int ) pvTimerGetTimerID( xTimer ) )
{
case uipARP_TIMER : xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK );
break;
case uipPERIODIC_TIMER : xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK );
break;
default : /* Should not get here. */
break;
}
}
/*-----------------------------------------------------------*/
void vApplicationProcessFormInput( char *pcInputString )
{
char *c;
const unsigned long ulYellowLED = 2UL;
/* Only interested in processing form input if this is the IO page. */
c = strstr( pcInputString, "io.shtml" );
if( c )
{
/* Is there a command in the string? */
c = strstr( pcInputString, "?" );
if( c )
{
/* Turn the LEDs on or off in accordance with the check box status. */
if( strstr( c, "LED0=1" ) != NULL )
{
/* Turn the LEDs on. */
vParTestSetLED( ulYellowLED, pdTRUE );
}
else
{
/* Turn the LEDs off. */
vParTestSetLED( ulYellowLED, pdFALSE );
}
}
else
{
/* Some browsers will only imply that a check box is off. */
vParTestSetLED( ulYellowLED, pdFALSE );
}
}
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,581 @@
/*
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.
*/
/* Freescale includes. */
#include "common.h"
#include "eth_phy.h"
#include "enet.h"
#include "mii.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* uIP includes. */
#include "net/uip.h"
/* The time to wait between attempts to obtain a free buffer. */
#define emacBUFFER_WAIT_DELAY_ms ( 3 / portTICK_RATE_MS )
/* The number of times emacBUFFER_WAIT_DELAY_ms should be waited before giving
up on attempting to obtain a free buffer all together. */
#define emacBUFFER_WAIT_ATTEMPTS ( 30 )
/* The number of Rx descriptors. */
#define emacNUM_RX_DESCRIPTORS 8
/* The number of Tx descriptors. When using uIP there is not point in having
more than two. */
#define emacNUM_TX_BUFFERS 2
/* The total number of EMAC buffers to allocate. */
#define emacNUM_BUFFERS ( emacNUM_RX_DESCRIPTORS + emacNUM_TX_BUFFERS )
/* The time to wait for the Tx descriptor to become free. */
#define emacTX_WAIT_DELAY_ms ( 10 / portTICK_RATE_MS )
/* The total number of times to wait emacTX_WAIT_DELAY_ms for the Tx descriptor to
become free. */
#define emacTX_WAIT_ATTEMPTS ( 50 )
/* Constants used for set up and initialisation. */
#define emacTX_INTERRUPT_NO ( 76 )
#define emacRX_INTERRUPT_NO ( 77 )
#define emacERROR_INTERRUPT_NO ( 78 )
#define emacLINK_DELAY ( 500 / portTICK_RATE_MS )
#define emacPHY_STATUS ( 0x1F )
#define emacPHY_DUPLEX_STATUS ( 4 << 2 )
#define emacPHY_SPEED_STATUS ( 1 << 2 )
/*-----------------------------------------------------------*/
/*
* Initialise both the Rx and Tx descriptors.
*/
static void prvInitialiseDescriptors( void );
/*
* Return a pointer to a free buffer within xEthernetBuffers.
*/
static unsigned char *prvGetNextBuffer( void );
/*
* Return a buffer to the list of free buffers.
*/
static void prvReturnBuffer( unsigned char *pucBuffer );
/*
* Examine the status of the next Rx descriptor to see if it contains new data.
*/
static unsigned short prvCheckRxStatus( void );
/*
* Something has gone wrong with the descriptor usage. Reset all the buffers
* and descriptors.
*/
static void prvResetEverything( void );
/*-----------------------------------------------------------*/
/* The buffers and descriptors themselves. */
#pragma data_alignment=16
volatile NBUF xRxDescriptors[ emacNUM_RX_DESCRIPTORS ];
#pragma data_alignment=16
volatile NBUF xTxDescriptors[ emacNUM_TX_BUFFERS ];
#pragma data_alignment=16
char xEthernetBuffers[ emacNUM_BUFFERS ][ UIP_BUFSIZE ];
/* Used to indicate which buffers are free and which are in use. If an index
contains 0 then the corresponding buffer in xEthernetBuffers is free, otherwise
the buffer is in use or about to be used. */
static unsigned char ucBufferInUse[ emacNUM_BUFFERS ];
/* Points to the Rx descriptor currently in use. */
static volatile NBUF *pxCurrentRxDesc = NULL;
/* pxCurrentRxDesc points to descriptor within the xRxDescriptors array that
has an index defined by ulRxDescriptorIndex. */
static unsigned long ulRxDescriptorIndex = 0UL;
/* The buffer used by the uIP stack to both receive and send. This points to
one of the Ethernet buffers when its actually in use. */
unsigned char *uip_buf = NULL;
/*-----------------------------------------------------------*/
void vEMACInit( void )
{
int iData;
extern int periph_clk_khz;
const unsigned portCHAR ucMACAddress[] =
{
configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5
};
/* Enable the ENET clock. */
SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;
/* Allow concurrent access to MPU controller to avoid bus errors. */
MPU_CESR = 0;
prvInitialiseDescriptors();
/* Reset and enable. */
ENET_ECR = ENET_ECR_RESET_MASK;
/* Wait at least 8 clock cycles */
vTaskDelay( 2 );
/* Start the MII interface*/
mii_init( 0, periph_clk_khz / 1000L );
/* Configure the transmit interrupt. */
set_irq_priority( emacTX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
enable_irq( emacTX_INTERRUPT_NO );
/* Configure the receive interrupt. */
set_irq_priority( emacRX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
enable_irq( emacRX_INTERRUPT_NO );
/* Configure the error interrupt. */
set_irq_priority( emacERROR_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
enable_irq( emacERROR_INTERRUPT_NO );
/* Configure the pins to the PHY - RMII mode used. */
PORTB_PCR0 = PORT_PCR_MUX( 4 ); /* RMII0_MDIO / MII0_MDIO. */
PORTB_PCR1 = PORT_PCR_MUX( 4 ); /* RMII0_MDC / MII0_MDC */
PORTA_PCR14 = PORT_PCR_MUX( 4 ); /* RMII0_CRS_DV / MII0_RXDV */
PORTA_PCR12 = PORT_PCR_MUX( 4 ); /* RMII0_RXD1 / MII0_RXD1 */
PORTA_PCR13 = PORT_PCR_MUX( 4 ); /* RMII0_RXD0/MII0_RXD0 */
PORTA_PCR15 = PORT_PCR_MUX( 4 ); /* RMII0_TXEN/MII0_TXEN */
PORTA_PCR16 = PORT_PCR_MUX( 4 ); /* RMII0_TXD0/MII0_TXD0 */
PORTA_PCR17 = PORT_PCR_MUX( 4 ); /* RMII0_TXD1/MII0_TXD1 */
/* Is there communication with the PHY? */
do
{
vTaskDelay( emacLINK_DELAY );
iData = 0xFFFF;
mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &iData );
} while( iData == 0xFFFF );
/* Start to auto negotiate. */
mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
/* Wait for auto negotiate to complete. */
do
{
vTaskDelay( emacLINK_DELAY );
mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &iData );
} while( !( iData & PHY_BMSR_AN_COMPLETE ) );
/* A link has been established. What was negotiated? */
iData = 0;
mii_read( 0, configPHY_ADDRESS, emacPHY_STATUS, &iData );
/* Clear the Individual and Group Address Hash registers */
ENET_IALR = 0;
ENET_IAUR = 0;
ENET_GALR = 0;
ENET_GAUR = 0;
/* Set the Physical Address for the selected ENET */
enet_set_address( 0, ucMACAddress );
ENET_RCR = ENET_RCR_MAX_FL( UIP_BUFSIZE ) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;
/* Clear the control registers. */
ENET_TCR = 0;
if( iData & emacPHY_DUPLEX_STATUS )
{
/* Full duplex */
ENET_RCR &= ( unsigned long )~ENET_RCR_DRT_MASK;
ENET_TCR |= ENET_TCR_FDEN_MASK;
}
else
{
/* Half duplex */
ENET_RCR |= ENET_RCR_DRT_MASK;
ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK;
}
if( iData & emacPHY_SPEED_STATUS )
{
/* 10Mbps */
ENET_RCR |= ENET_RCR_RMII_10T_MASK;
}
ENET_ECR = ENET_ECR_EN1588_MASK;
/* Store and forward checksum. */
ENET_TFWR = ENET_TFWR_STRFWD_MASK;
/* Set Rx Buffer Size */
ENET_MRBR = ( unsigned short ) UIP_BUFSIZE;
/* Point to the start of the circular Rx buffer descriptor queue */
ENET_RDSR = ( unsigned long ) &( xRxDescriptors[ 0 ] );
/* Point to the start of the circular Tx buffer descriptor queue */
ENET_TDSR = ( unsigned long ) &( xTxDescriptors[ 0 ] );
/* Clear all ENET interrupt events */
ENET_EIR = ( unsigned long ) -1;
/* Enable interrupts. */
ENET_EIMR = 0
/*rx irqs*/
| ENET_EIMR_RXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_RXB_MASK*/
/*xmit irqs*/
| ENET_EIMR_TXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_TXB_MASK*/
/*enet irqs*/
| ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK
;
/* Enable the MAC itself. */
ENET_ECR |= ENET_ECR_ETHEREN_MASK;
/* Indicate that there have been empty receive buffers produced */
ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
/*-----------------------------------------------------------*/
static void prvInitialiseDescriptors( void )
{
volatile NBUF *pxDescriptor;
long x;
for( x = 0; x < emacNUM_BUFFERS; x++ )
{
/* Ensure none of the buffers are shown as in use at the start. */
ucBufferInUse[ x ] = pdFALSE;
}
/* Initialise the Rx descriptors. */
for( x = 0; x < emacNUM_RX_DESCRIPTORS; x++ )
{
pxDescriptor = &( xRxDescriptors[ x ] );
pxDescriptor->data = ( uint8_t* ) &( xEthernetBuffers[ x ][ 0 ] );
pxDescriptor->data = ( uint8_t* ) __REV( ( unsigned long ) pxDescriptor->data );
pxDescriptor->length = 0;
pxDescriptor->status = RX_BD_E;
pxDescriptor->bdu = 0;
pxDescriptor->ebd_status = RX_BD_INT;
/* Mark this buffer as in use. */
ucBufferInUse[ x ] = pdTRUE;
}
/* The last descriptor points back to the start. */
pxDescriptor->status |= RX_BD_W;
/* Initialise the Tx descriptors. */
for( x = 0; x < emacNUM_TX_BUFFERS; x++ )
{
pxDescriptor = &( xTxDescriptors[ x ] );
/* A buffer is not allocated to the Tx descriptor until a send is
actually required. */
pxDescriptor->data = NULL;
pxDescriptor->length = 0;
pxDescriptor->status = TX_BD_TC;
pxDescriptor->ebd_status = TX_BD_INT;
}
/* The last descriptor points back to the start. */
pxDescriptor->status |= TX_BD_W;
/* Use the first Rx descriptor to start with. */
ulRxDescriptorIndex = 0UL;
pxCurrentRxDesc = &( xRxDescriptors[ 0 ] );
}
/*-----------------------------------------------------------*/
void vEMACWrite( void )
{
long x;
/* Wait until the second transmission of the last packet has completed. */
for( x = 0; x < emacTX_WAIT_ATTEMPTS; x++ )
{
if( ( xTxDescriptors[ 1 ].status & TX_BD_R ) != 0 )
{
/* Descriptor is still active. */
vTaskDelay( emacTX_WAIT_DELAY_ms );
}
else
{
break;
}
}
/* Is the descriptor free after waiting for it? */
if( ( xTxDescriptors[ 1 ].status & TX_BD_R ) != 0 )
{
/* Something has gone wrong. */
prvResetEverything();
}
/* Setup both descriptors to transmit the frame. */
xTxDescriptors[ 0 ].data = ( uint8_t * ) __REV( ( unsigned long ) uip_buf );
xTxDescriptors[ 0 ].length = __REVSH( uip_len );
xTxDescriptors[ 1 ].data = ( uint8_t * ) __REV( ( unsigned long ) uip_buf );
xTxDescriptors[ 1 ].length = __REVSH( uip_len );
/* uip_buf is being sent by the Tx descriptor. Allocate a new buffer
for use by the stack. */
uip_buf = prvGetNextBuffer();
/* Clear previous settings and go. */
xTxDescriptors[ 0 ].status |= ( TX_BD_R | TX_BD_L );
xTxDescriptors[ 1 ].status |= ( TX_BD_R | TX_BD_L );
/* Start the Tx. */
ENET_TDAR = ENET_TDAR_TDAR_MASK;
}
/*-----------------------------------------------------------*/
static unsigned char *prvGetNextBuffer( void )
{
long x;
unsigned char *pucReturn = NULL;
unsigned long ulAttempts = 0;
while( pucReturn == NULL )
{
/* Look through the buffers to find one that is not in use by
anything else. */
for( x = 0; x < emacNUM_BUFFERS; x++ )
{
if( ucBufferInUse[ x ] == pdFALSE )
{
ucBufferInUse[ x ] = pdTRUE;
pucReturn = ( unsigned char * ) &( xEthernetBuffers[ x ][ 0 ] );
break;
}
}
/* Was a buffer found? */
if( pucReturn == NULL )
{
ulAttempts++;
if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )
{
break;
}
/* Wait then look again. */
vTaskDelay( emacBUFFER_WAIT_DELAY_ms );
}
}
return pucReturn;
}
/*-----------------------------------------------------------*/
static void prvResetEverything( void )
{
/* Temporary code just to see if this gets called. This function has not
been implemented. */
portDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
unsigned short usEMACRead( void )
{
unsigned short usBytesReceived;
usBytesReceived = prvCheckRxStatus();
usBytesReceived = __REVSH( usBytesReceived );
if( usBytesReceived > 0 )
{
/* Mark the pxDescriptor buffer as free as uip_buf is going to be set to
the buffer that contains the received data. */
prvReturnBuffer( uip_buf );
/* Point uip_buf to the data about to be processed. */
uip_buf = ( void * ) pxCurrentRxDesc->data;
uip_buf = ( void * ) __REV( ( unsigned long ) uip_buf );
/* Allocate a new buffer to the descriptor, as uip_buf is now using it's
old descriptor. */
pxCurrentRxDesc->data = ( uint8_t * ) prvGetNextBuffer();
pxCurrentRxDesc->data = ( uint8_t* ) __REV( ( unsigned long ) pxCurrentRxDesc->data );
/* Prepare the descriptor to go again. */
pxCurrentRxDesc->status |= RX_BD_E;
/* Move onto the next buffer in the ring. */
ulRxDescriptorIndex++;
if( ulRxDescriptorIndex >= emacNUM_RX_DESCRIPTORS )
{
ulRxDescriptorIndex = 0UL;
}
pxCurrentRxDesc = &( xRxDescriptors[ ulRxDescriptorIndex ] );
/* Restart Ethernet if it has stopped */
ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
return usBytesReceived;
}
/*-----------------------------------------------------------*/
static void prvReturnBuffer( unsigned char *pucBuffer )
{
unsigned long ul;
/* Return a buffer to the pool of free buffers. */
for( ul = 0; ul < emacNUM_BUFFERS; ul++ )
{
if( &( xEthernetBuffers[ ul ][ 0 ] ) == ( void * ) pucBuffer )
{
ucBufferInUse[ ul ] = pdFALSE;
break;
}
}
}
/*-----------------------------------------------------------*/
static unsigned short prvCheckRxStatus( void )
{
unsigned long usReturn = 0;
if( ( pxCurrentRxDesc->status & RX_BD_E ) != 0 )
{
/* Current descriptor is still active. */
}
else
{
/* The descriptor contains a frame. Because of the size of the buffers
the frame should always be complete. */
usReturn = pxCurrentRxDesc->length;
}
return usReturn;
}
/*-----------------------------------------------------------*/
void vEMAC_TxISRHandler( void )
{
/* Clear the interrupt. */
ENET_EIR = ENET_EIR_TXF_MASK;
/* Check the buffers have not already been freed in the first of the
two Tx interrupts - which could potentially happen if the second Tx completed
during the interrupt for the first Tx. */
if( xTxDescriptors[ 0 ].data != NULL )
{
if( ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) && ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) )
{
configASSERT( xTxDescriptors[ 0 ].data == xTxDescriptors[ 1 ].data );
xTxDescriptors[ 0 ].data = ( uint8_t* ) __REV( ( unsigned long ) xTxDescriptors[ 0 ].data );
prvReturnBuffer( xTxDescriptors[ 0 ].data );
/* Just to mark the fact that the buffer has already been released. */
xTxDescriptors[ 0 ].data = NULL;
}
}
}
/*-----------------------------------------------------------*/
void vEMAC_RxISRHandler( void )
{
const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;
long lHigherPriorityTaskWoken = pdFALSE;
extern xQueueHandle xEMACEventQueue;
/* Clear the interrupt. */
ENET_EIR = ENET_EIR_RXF_MASK;
/* An Ethernet Rx event has occurred. */
xQueueSendFromISR( xEMACEventQueue, &ulRxEvent, &lHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
void vEMAC_ErrorISRHandler( void )
{
/* Clear the interrupt. */
ENET_EIR = ENET_EIR & ENET_EIMR;
/* Attempt recovery. Not very sophisticated. */
prvInitialiseDescriptors();
ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,85 @@
/*
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 FR_EMAC_H
#define FR_EMAC_H
/*
* Configure all the ethernet components (MAC, DMA, PHY) ready for communication.
*/
void vEMACInit( void );
/*
* Check the Rx status, and return the number of bytes received if any.
*/
unsigned short usEMACRead( void );
/*
* Send uip_len bytes from uip_buf to the Tx descriptors and initiate a Tx.
*/
void vEMACWrite( void );
#endif /* FR_EMAC_H */

View file

@ -0,0 +1,263 @@
/**
* \addtogroup httpd
* @{
*/
/**
* \file
* Web server script interface
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2001-2006, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $
*
*/
#include "net/uip.h"
#include "net/psock.h"
#include "apps/httpd/httpd.h"
#include "apps/httpd/httpd-cgi.h"
#include "apps/httpd/httpd-fs.h"
#include <stdio.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.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 );
HTTPD_CGI_CALL( rtos, "rtos-stats", rtos_stats );
HTTPD_CGI_CALL( run, "run-time", run_time );
HTTPD_CGI_CALL( io, "led-io", led_io );
static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, &rtos, &run, &io, NULL };
/*---------------------------------------------------------------------------*/
static PT_THREAD( nullfunction ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
( void ) ptr;
( void ) PT_YIELD_FLAG;
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
httpd_cgifunction httpd_cgi( char *name )
{
const struct httpd_cgi_call **f;
/* Find the matching name in the table, return the function. */
for( f = calls; *f != NULL; ++f )
{
if( strncmp((*f)->name, name, strlen((*f)->name)) == 0 )
{
return( *f )->function;
}
}
return nullfunction;
}
/*---------------------------------------------------------------------------*/
static unsigned short generate_file_stats( void *arg )
{
char *f = ( char * ) arg;
return sprintf( ( char * ) uip_appdata, "%5u", httpd_fs_count(f) );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( file_stats ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
( void ) PT_YIELD_FLAG;
PSOCK_GENERATOR_SEND( &s->sout, generate_file_stats, strchr(ptr, ' ') + 1 );
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static const char closed[] = /* "CLOSED",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0 };
static const char syn_rcvd[] = /* "SYN-RCVD",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, 0x44, 0 };
static const char syn_sent[] = /* "SYN-SENT",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, 0x54, 0 };
static const char established[] = /* "ESTABLISHED",*/ { 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0 };
static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x31, 0 };
static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x32, 0 };
static const char closing[] = /* "CLOSING",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x49, 0x4e, 0x47, 0 };
static const char time_wait[] = /* "TIME-WAIT,"*/ { 0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, 0x49, 0x54, 0 };
static const char last_ack[] = /* "LAST-ACK"*/ { 0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, 0x4b, 0 };
static const char *states[] = { closed, syn_rcvd, syn_sent, established, fin_wait_1, fin_wait_2, closing, time_wait, last_ack };
static unsigned short generate_tcp_stats( void *arg )
{
struct uip_conn *conn;
struct httpd_state *s = ( struct httpd_state * ) arg;
conn = &uip_conns[s->count];
return sprintf( ( char * ) uip_appdata,
"<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n", htons(conn->lport),
htons(conn->ripaddr.u16[0]) >> 8, htons(conn->ripaddr.u16[0]) & 0xff, htons(conn->ripaddr.u16[1]) >> 8,
htons(conn->ripaddr.u16[1]) & 0xff, htons(conn->rport), states[conn->tcpstateflags & UIP_TS_MASK], conn->nrtx, conn->timer,
(uip_outstanding(conn)) ? '*' : ' ', (uip_stopped(conn)) ? '!' : ' ' );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( tcp_stats ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
( void ) ptr;
( void ) PT_YIELD_FLAG;
for( s->count = 0; s->count < UIP_CONNS; ++s->count )
{
if( (uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED )
{
PSOCK_GENERATOR_SEND( &s->sout, generate_tcp_stats, s );
}
}
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static unsigned short generate_net_stats( void *arg )
{
struct httpd_state *s = ( struct httpd_state * ) arg;
return sprintf( ( char * ) uip_appdata, "%5u\n", (( uip_stats_t * ) &uip_stat)[s->count] );
}
static PT_THREAD( net_stats ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
( void ) ptr;
( void ) PT_YIELD_FLAG;
#if UIP_STATISTICS
for( s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); ++s->count )
{
PSOCK_GENERATOR_SEND( &s->sout, generate_net_stats, s );
}
#endif /* UIP_STATISTICS */
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
extern void vTaskList( signed char *pcWriteBuffer );
extern char *pcGetTaskStatusMessage( void );
static char cCountBuf[128];
long lRefreshCount = 0;
static unsigned short generate_rtos_stats( void *arg )
{
( void ) arg;
lRefreshCount++;
sprintf( cCountBuf, "<p><br>Refresh count = %d<p><br>%s", ( int ) lRefreshCount, pcGetTaskStatusMessage() );
vTaskList( uip_appdata );
strcat( uip_appdata, cCountBuf );
return strlen( uip_appdata );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( rtos_stats ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
( void ) ptr;
( void ) PT_YIELD_FLAG;
PSOCK_GENERATOR_SEND( &s->sout, generate_rtos_stats, NULL );
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
char *pcStatus;
unsigned long ulString;
static unsigned short generate_io_state( void *arg )
{
extern long lParTestGetLEDState( unsigned long ulLED );
( void ) arg;
const unsigned long ulYellowLED = 2UL;
/* Are the dynamically setable LEDs currently on or off? */
if( lParTestGetLEDState( ulYellowLED ) == pdTRUE )
{
pcStatus = "checked";
}
else
{
pcStatus = "";
}
sprintf( uip_appdata, "<input type=\"checkbox\" name=\"LED0\" value=\"1\" %s>LED<p><p>", pcStatus );
return strlen( uip_appdata );
}
/*---------------------------------------------------------------------------*/
extern void vTaskGetRunTimeStats( signed char *pcWriteBuffer );
static unsigned short generate_runtime_stats( void *arg )
{
( void ) arg;
lRefreshCount++;
sprintf( cCountBuf, "<p><br>Refresh count = %d", ( int ) lRefreshCount );
vTaskGetRunTimeStats( uip_appdata );
strcat( uip_appdata, cCountBuf );
return strlen( uip_appdata );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( run_time ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
( void ) ptr;
( void ) PT_YIELD_FLAG;
PSOCK_GENERATOR_SEND( &s->sout, generate_runtime_stats, NULL );
PSOCK_END( &s->sout );
}
/*---------------------------------------------------------------------------*/
static PT_THREAD( led_io ( struct httpd_state *s, char *ptr ) )
{
PSOCK_BEGIN( &s->sout );
( void ) ptr;
( void ) PT_YIELD_FLAG;
PSOCK_GENERATOR_SEND( &s->sout, generate_io_state, NULL );
PSOCK_END( &s->sout );
}
/** @} */

View file

@ -0,0 +1,8 @@
<html>
<body bgcolor="white">
<center>
<h1>404 - file not found</h1>
<h3>Go <a href="/">here</a> instead.</h3>
</center>
</body>
</html>

View file

@ -0,0 +1,13 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY onLoad="window.setTimeout(&quot;location.href='index.shtml'&quot;,100)">
<font face="arial">
Loading index.shtml. Click <a href="index.shtml">here</a> if not automatically redirected.
</font>
</font>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY onLoad="window.setTimeout(&quot;location.href='index.shtml'&quot;,2000)">
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
<br><p>
<hr>
<br><p>
<h2>Task statistics</h2>
Page will refresh every 2 seconds.<p>
<font face="courier"><pre>Task State Priority Stack #<br>************************************************<br>
%! rtos-stats
</pre></font>
</font>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY>
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
<br><p>
<hr>
<b>LED and LCD IO</b><br>
<p>
The check box and "Update IO" button can also be used to turn the yellow LED on and off.
<p>
<form name="aForm" action="/io.shtml" method="get">
%! led-io
<p>
<input type="submit" value="Update IO">
</form>
<br><p>
</font>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY onLoad="window.setTimeout(&quot;location.href='runtime.shtml'&quot;,2000)">
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
<br><p>
<hr>
<br><p>
<h2>Run-time statistics</h2>
Page will refresh every 2 seconds.<p>
<font face="courier"><pre>Task Abs Time % Time<br>****************************************<br>
%! run-time
</pre></font>
</font>
</body>
</html>

View file

@ -0,0 +1,47 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY>
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
<br><p>
<hr>
<br><p>
<h2>Network statistics</h2>
<table width="300" border="0">
<tr><td align="left"><font face="courier"><pre>
IP Packets received
Packets sent
Forwaded
Dropped
IP errors IP version/header length
IP length, high byte
IP length, low byte
IP fragments
Header checksum
Wrong protocol
ICMP Packets received
Packets sent
Packets dropped
Type errors
Checksum errors
TCP Packets received
Packets sent
Packets dropped
Checksum errors
Data packets without ACKs
Resets
Retransmissionsa
Syn to closed port
UDP Packets dropped
Packets received
Packets sent
Packets chkerr
No connection avaliable
</pre></font></td><td><font face="courier"><pre>%! net-stats
</pre></font></td></table>
</font>
</body>
</html>

View file

@ -0,0 +1,21 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeRTOS.org uIP WEB server demo</title>
</head>
<BODY>
<font face="arial">
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
<br><p>
<hr>
<br>
<h2>Network connections</h2>
<p>
<table>
<tr><th>Local</th><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Flags</th></tr>
%! tcp-connections
</pre></font>
</font>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,79 @@
#!/usr/bin/perl
open(OUTPUT, "> httpd-fsdata.c");
chdir("httpd-fs");
opendir(DIR, ".");
@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
foreach $file (@files) {
if(-d $file && $file !~ /^\./) {
print "Processing directory $file\n";
opendir(DIR, $file);
@newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
closedir(DIR);
printf "Adding files @newfiles\n";
@files = (@files, map { $_ = "$file/$_" } @newfiles);
next;
}
}
foreach $file (@files) {
if(-f $file) {
print "Adding file $file\n";
open(FILE, $file) || die "Could not open file $file\n";
binmode FILE;
$file =~ s-^-/-;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
# for AVR, add PROGMEM here
print(OUTPUT "static const char data".$fvar."[] = {\n");
print(OUTPUT "\t/* $file */\n\t");
for($j = 0; $j < length($file); $j++) {
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
}
printf(OUTPUT "0,\n");
$i = 0;
while(read(FILE, $data, 1)) {
if($i == 0) {
print(OUTPUT "\t");
}
printf(OUTPUT "%#02x, ", unpack("C", $data));
$i++;
if($i == 10) {
print(OUTPUT "\n");
$i = 0;
}
}
print(OUTPUT "0};\n\n");
close(FILE);
push(@fvars, $fvar);
push(@pfiles, $file);
}
}
for($i = 0; $i < @fvars; $i++) {
$file = $pfiles[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
} else {
$prevfile = "file" . $fvars[$i - 1];
}
print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
}
print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n");

View file

@ -0,0 +1,167 @@
/**
* \addtogroup uipopt
* @{
*/
/**
* \name Project-specific configuration options
* @{
*
* uIP has a number of configuration options that can be overridden
* for each project. These are kept in a project-specific uip-conf.h
* file and all configuration names have the prefix UIP_CONF.
*/
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
*/
/**
* \file
* An example uIP configuration file
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __UIP_CONF_H__
#define __UIP_CONF_H__
#define UIP_CONF_EXTERNAL_BUFFER
#define UIP_CONF_PROCESS_HTTPD_FORMS 1
/**
* 8 bit datatype
*
* This typedef defines the 8-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef unsigned char u8_t;
/**
* 16 bit datatype
*
* This typedef defines the 16-bit type used throughout uIP.
*
* \hideinitializer
*/
typedef unsigned short u16_t;
typedef unsigned long u32_t;
/**
* Statistics datatype
*
* This typedef defines the dataype used for keeping statistics in
* uIP.
*
* \hideinitializer
*/
typedef unsigned short uip_stats_t;
/**
* Maximum number of TCP connections.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_CONNECTIONS 40
/**
* Maximum number of listening TCP ports.
*
* \hideinitializer
*/
#define UIP_CONF_MAX_LISTENPORTS 40
/**
* uIP buffer size.
*
* \hideinitializer
*/
#define UIP_CONF_BUFFER_SIZE 1480
/**
* CPU byte order.
*
* \hideinitializer
*/
#if __LITTLE_ENDIAN__ == 1
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
#else
#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN
#endif
/**
* Logging on or off
*
* \hideinitializer
*/
#define UIP_CONF_LOGGING 0
/**
* UDP support on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP 0
/**
* UDP checksums on or off
*
* \hideinitializer
*/
#define UIP_CONF_UDP_CHECKSUMS 1
/**
* uIP statistics on or off
*
* \hideinitializer
*/
#define UIP_CONF_STATISTICS 1
/* Here we include the header file for the application(s) we use in
our project. */
/*#include "smtp.h"*/
/*#include "hello-world.h"*/
/*#include "telnetd.h"*/
#include "webserver.h"
/*#include "dhcpc.h"*/
/*#include "resolv.h"*/
/*#include "webclient.h"*/
#define CCIF
#define CC_REGISTER_ARG
#endif /* __UIP_CONF_H__ */
/** @} */
/** @} */

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2002, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack
*
* $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $
*
*/
#ifndef __WEBSERVER_H__
#define __WEBSERVER_H__
#include "apps/httpd/httpd.h"
typedef struct httpd_state uip_tcp_appstate_t;
/* UIP_APPCALL: the name of the application function. This function
must return void and take no arguments (i.e., C type "void
appfunc(void)"). */
#define UIP_APPCALL httpd_appcall
#endif /* __WEBSERVER_H__ */