mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-02 04:13:54 -04:00
Add FreeRTOS-Plus directory.
This commit is contained in:
parent
7bd5f21ad5
commit
f508a5f653
6798 changed files with 134949 additions and 19 deletions
194
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/FreeRTOSConfig.h
Normal file
194
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/FreeRTOSConfig.h
Normal 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 */
|
||||
|
|
@ -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 };
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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_ */
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* File: iar.h
|
||||
* Purpose: Define constants used by IAR toolchain
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IAR_H_
|
||||
#define _IAR_H_
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
#endif /* _IAR_H_ */
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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
|
||||
}
|
||||
/********************************************************************/
|
|
@ -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_ */
|
|
@ -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) );
|
||||
}
|
||||
/***********************************************************************/
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
|
@ -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 */
|
|
@ -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__ */
|
|
@ -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 */
|
|
@ -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));
|
||||
}
|
||||
/********************************************************************/
|
||||
|
|
@ -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);
|
|
@ -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));
|
||||
}
|
||||
/********************************************************************/
|
|
@ -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);
|
||||
/********************************************************************/
|
|
@ -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" */
|
|
@ -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" */
|
|
@ -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;
|
||||
}
|
||||
/********************************************************************/
|
||||
|
||||
|
||||
|
|
@ -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_ */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
/********************************************************************/
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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__ */
|
|
@ -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);
|
||||
}
|
||||
/********************************************************************/
|
||||
|
|
@ -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__ */
|
|
@ -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;
|
||||
}
|
||||
/********************************************************************/
|
|
@ -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__ */
|
150
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/ParTest.c
Normal file
150
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/ParTest.c
Normal 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;
|
||||
}
|
1785
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewd
Normal file
1785
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewd
Normal file
File diff suppressed because it is too large
Load diff
2016
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewp
Normal file
2016
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewp
Normal file
File diff suppressed because it is too large
Load diff
50
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.eww
Normal file
50
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.eww
Normal 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>
|
||||
|
||||
|
668
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/main-full.c
Normal file
668
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/main-full.c
Normal 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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
402
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/main_blinky.c
Normal file
402
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/main_blinky.c
Normal 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 ) {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
358
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/uIP_Task.c
Normal file
358
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/uIP_Task.c
Normal 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
581
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/EMAC.c
Normal file
581
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/EMAC.c
Normal 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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
85
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/EMAC.h
Normal file
85
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/EMAC.h
Normal 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 */
|
263
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/httpd-cgi.c
Normal file
263
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/httpd-cgi.c
Normal 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 );
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -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>
|
|
@ -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("location.href='index.shtml'",100)">
|
||||
<font face="arial">
|
||||
Loading index.shtml. Click <a href="index.shtml">here</a> if not automatically redirected.
|
||||
</font>
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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("location.href='index.shtml'",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>
|
||||
|
|
@ -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 |
|
@ -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("location.href='runtime.shtml'",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>
|
||||
|
|
@ -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>
|
|
@ -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>
|
||||
|
3873
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/httpd-fsdata.c
Normal file
3873
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/httpd-fsdata.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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");
|
167
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/uip-conf.h
Normal file
167
FreeRTOS/Demo/CORTEX_Kinetis_K60_Tower_IAR/webserver/uip-conf.h
Normal 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__ */
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -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__ */
|
Loading…
Add table
Add a link
Reference in a new issue