From 11a86f982291fb8f7e1c5d2902fb392f1663fa5b Mon Sep 17 00:00:00 2001 From: imi415 Date: Wed, 8 Jun 2022 13:55:50 +0000 Subject: [PATCH] Initial commit --- .clang-format | 11 + .gitignore | 6 + .gitmodules | 12 + CMakeLists.txt | 173 +++ MK60DN512xxx10.mex | 623 ++++++++++ MK60DN512xxx10_flash_sram.ld | 263 +++++ arm-none-eabi.cmake | 10 + board/board.c | 61 + board/board.h | 193 ++++ board/clock_config.c | 226 ++++ board/clock_config.h | 71 ++ board/peripherals.c | 212 ++++ board/peripherals.h | 49 + board/pin_mux.c | 306 +++++ board/pin_mux.h | 62 + include/FreeRTOSConfig.h | 132 +++ include/ethernetif.h | 146 +++ include/fsl_phy.h | 216 ++++ include/ip_stack_helpers.h | 6 + include/system_utilities.h | 7 + lib/.gitkeep | 0 lib/LwIP/CMakeLists.txt | 141 +++ lib/LwIP/port/include/arch/cc.h | 48 + lib/LwIP/port/include/arch/sys_arch.h | 95 ++ lib/LwIP/port/include/lwipopts.h | 336 ++++++ lib/LwIP/port/lwip_helpers.c | 15 + lib/LwIP/port/sys_arch.c | 607 ++++++++++ lib/MbedTLS/CMakeLists.txt | 6 + lib/MbedTLS/include/kinetis_mbedtls_config.h | 86 ++ src/ethernetif.c | 1077 ++++++++++++++++++ src/freertos_helpers.c | 4 + src/fsl_phy.c | 310 +++++ src/ip_stack_helpers.c | 116 ++ src/main.c | 77 ++ src/syscalls.c | 42 + src/system_utilities.c | 125 ++ 36 files changed, 5870 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 MK60DN512xxx10.mex create mode 100644 MK60DN512xxx10_flash_sram.ld create mode 100644 arm-none-eabi.cmake create mode 100644 board/board.c create mode 100644 board/board.h create mode 100644 board/clock_config.c create mode 100644 board/clock_config.h create mode 100644 board/peripherals.c create mode 100644 board/peripherals.h create mode 100644 board/pin_mux.c create mode 100644 board/pin_mux.h create mode 100644 include/FreeRTOSConfig.h create mode 100644 include/ethernetif.h create mode 100644 include/fsl_phy.h create mode 100644 include/ip_stack_helpers.h create mode 100644 include/system_utilities.h create mode 100644 lib/.gitkeep create mode 100644 lib/LwIP/CMakeLists.txt create mode 100644 lib/LwIP/port/include/arch/cc.h create mode 100644 lib/LwIP/port/include/arch/sys_arch.h create mode 100644 lib/LwIP/port/include/lwipopts.h create mode 100644 lib/LwIP/port/lwip_helpers.c create mode 100644 lib/LwIP/port/sys_arch.c create mode 100644 lib/MbedTLS/CMakeLists.txt create mode 100644 lib/MbedTLS/include/kinetis_mbedtls_config.h create mode 100644 src/ethernetif.c create mode 100644 src/freertos_helpers.c create mode 100644 src/fsl_phy.c create mode 100644 src/ip_stack_helpers.c create mode 100644 src/main.c create mode 100644 src/syscalls.c create mode 100644 src/system_utilities.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..1e81119 --- /dev/null +++ b/.clang-format @@ -0,0 +1,11 @@ +BasedOnStyle: Google +IndentWidth: 4 +AlignConsecutiveMacros: Consecutive +AlignConsecutiveDeclarations: true +AlignConsecutiveAssignments: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterEnum: false + AfterStruct: false + SplitEmptyFunction: false +ColumnLimit: 120 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee1fbdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/board/*.bak +/build +/cmake-build-* +/.vscode +/*.jdebug* +/*.jflash \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5e8c3e5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "SDK"] + path = SDK + url = https://git.minori.work/Embedded_SDK/MCUXpresso_MK60DN512xxx10.git +[submodule "lib/FreeRTOS"] + path = lib/FreeRTOS + url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git +[submodule "lib/LwIP"] + path = lib/LwIP/lwip + url = https://git.savannah.nongnu.org/git/lwip.git +[submodule "lib/MbedTLS"] + path = lib/MbedTLS/mbedtls + url = https://github.com/Mbed-TLS/mbedtls.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..86480db --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,173 @@ +cmake_minimum_required(VERSION 3.10) + +project(landzo_k60_lwip) + +enable_language(CXX) +enable_language(ASM) + +# Different linker scripts +set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/SDK/devices/MK60D10/gcc/MK60DN512xxx10_flash.ld") +set(TARGET_LDSCRIPT_FLASH_FB "${CMAKE_SOURCE_DIR}/MK60DN512xxx10_flash_sram.ld") +set(TARGET_LDSCRIPT_RAM "${CMAKE_SOURCE_DIR}/SDK/devices/MK60D10/gcc/MK60DN512xxx10_ram.ld") + +set(TARGET_SOURCES + "SDK/devices/MK60D10/drivers/fsl_adc16.c" + "SDK/devices/MK60D10/drivers/fsl_clock.c" + "SDK/devices/MK60D10/drivers/fsl_cmp.c" + "SDK/devices/MK60D10/drivers/fsl_cmt.c" + "SDK/devices/MK60D10/drivers/fsl_common.c" + "SDK/devices/MK60D10/drivers/fsl_crc.c" + "SDK/devices/MK60D10/drivers/fsl_dac.c" + "SDK/devices/MK60D10/drivers/fsl_dmamux.c" + "SDK/devices/MK60D10/drivers/fsl_dspi.c" + "SDK/devices/MK60D10/drivers/fsl_dspi_edma.c" + "SDK/devices/MK60D10/drivers/fsl_edma.c" + "SDK/devices/MK60D10/drivers/fsl_enet.c" + "SDK/devices/MK60D10/drivers/fsl_ewm.c" + "SDK/devices/MK60D10/drivers/fsl_flash.c" + "SDK/devices/MK60D10/drivers/fsl_flexbus.c" + "SDK/devices/MK60D10/drivers/fsl_flexcan.c" + "SDK/devices/MK60D10/drivers/fsl_ftm.c" + "SDK/devices/MK60D10/drivers/fsl_gpio.c" + "SDK/devices/MK60D10/drivers/fsl_i2c.c" + "SDK/devices/MK60D10/drivers/fsl_i2c_edma.c" + "SDK/devices/MK60D10/drivers/fsl_llwu.c" + "SDK/devices/MK60D10/drivers/fsl_lptmr.c" + "SDK/devices/MK60D10/drivers/fsl_pdb.c" + "SDK/devices/MK60D10/drivers/fsl_pit.c" + "SDK/devices/MK60D10/drivers/fsl_pmc.c" + "SDK/devices/MK60D10/drivers/fsl_rcm.c" + "SDK/devices/MK60D10/drivers/fsl_rnga.c" + "SDK/devices/MK60D10/drivers/fsl_rtc.c" + "SDK/devices/MK60D10/drivers/fsl_sai.c" + "SDK/devices/MK60D10/drivers/fsl_sai_edma.c" + "SDK/devices/MK60D10/drivers/fsl_sdhc.c" + "SDK/devices/MK60D10/drivers/fsl_sim.c" + "SDK/devices/MK60D10/drivers/fsl_smc.c" + "SDK/devices/MK60D10/drivers/fsl_sysmpu.c" + "SDK/devices/MK60D10/drivers/fsl_tsi_v2.c" + "SDK/devices/MK60D10/drivers/fsl_uart.c" + "SDK/devices/MK60D10/drivers/fsl_uart_edma.c" + "SDK/devices/MK60D10/drivers/fsl_vref.c" + "SDK/devices/MK60D10/drivers/fsl_wdog.c" + "SDK/devices/MK60D10/system_MK60D10.c" + "SDK/devices/MK60D10/utilities/fsl_debug_console.c" + "SDK/devices/MK60D10/utilities/fsl_notifier.c" + "SDK/devices/MK60D10/gcc/startup_MK60D10.S" + "SDK/devices/MK60D10/system_MK60D10.c" + "board/board.c" + "board/clock_config.c" + "board/peripherals.c" + "board/pin_mux.c" + "lib/LwIP/port/lwip_helpers.c" + "lib/LwIP/port/sys_arch.c" + "src/ethernetif.c" + "src/freertos_helpers.c" + "src/fsl_phy.c" + "src/ip_stack_helpers.c" + "src/main.c" + "src/syscalls.c" + "src/system_utilities.c" +) + +set(TARGET_C_DEFINES + "CPU_MK60DN512VLQ10" + "__STARTUP_CLEAR_BSS" + "USE_RTOS=1" + "FSL_RTOS_FREE_RTOS" +) + +set(TARGET_C_INCLUDES + "SDK/CMSIS/Include" + "SDK/devices/MK60D10" + "SDK/devices/MK60D10/drivers" + "SDK/devices/MK60D10/utilities" + "board" + "include" +) + +# Shared libraries linked with application +set(TARGET_LIBS + "freertos_kernel" + "lwip" + "mbedtls" +) + +# Shared library and linker script search paths +set(TARGET_LIB_DIRECTORIES + +) + +# Device specific settings, goes to CFLAGS and LDFLAGS +set(TARGET_CFLAGS_HARDWARE "-mcpu=cortex-m4 -mthumb -mfloat-abi=soft") + +# Conditional flags +# DEBUG +set(CMAKE_C_FLAGS_DEBUG "-DDEBUG -O0 -g") +set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -O0 -g") +set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG -O0 -g") + +# RELEASE +set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2 -flto") +set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O2 -flto") +set(CMAKE_ASM_FLAGS_RELEASE "-DNDEBUG -O2 -flto") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-flto") + +# Final compiler flags +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_CFLAGS_HARDWARE} -Wall -fno-common -fno-builtin -ffreestanding -fdata-sections -ffunction-sections") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TARGET_CFLAGS_HARDWARE} -Wall -fno-common -fno-builtin -ffreestanding -fdata-sections -ffunction-sections") +set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_C_FLAGS} -x assembler-with-cpp") +set(CMAKE_EXE_LINKER_FLAGS "-specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -Wl,--print-memory-usage -lc -lm -lnosys ") + +# Add subdirectories here. +set(FREERTOS_CONFIG_FILE_DIRECTORY "${CMAKE_SOURCE_DIR}/include" CACHE STRING "") +set(FREERTOS_PORT "GCC_ARM_CM3" CACHE STRING "") +add_subdirectory(lib/FreeRTOS) + +set(LWIP_CONFIG_FILE_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/LwIP/port/include" CACHE STRING "") +add_subdirectory(lib/LwIP) + +add_subdirectory(lib/MbedTLS) + +# Shared sources, includes and definitions +add_compile_definitions(${TARGET_C_DEFINES}) +include_directories(${TARGET_C_INCLUDES}) +link_directories(${TARGET_LIB_DIRECTORIES}) +link_libraries(${TARGET_LIBS}) + +# Main targets are added here + +# Create ELF +add_executable("${CMAKE_PROJECT_NAME}_FLASH.elf" ${TARGET_SOURCES}) +target_link_options("${CMAKE_PROJECT_NAME}_FLASH.elf" + PRIVATE "-T${TARGET_LDSCRIPT_FLASH}" +) +add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_FLASH.hex" + COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_FLASH.elf" "${CMAKE_PROJECT_NAME}_FLASH.hex" + DEPENDS "${CMAKE_PROJECT_NAME}_FLASH.elf" +) +add_custom_target("${CMAKE_PROJECT_NAME}_FLASH_HEX" DEPENDS "${CMAKE_PROJECT_NAME}_FLASH.hex") + +# Create ELF +add_executable("${CMAKE_PROJECT_NAME}_FLASH_FB.elf" ${TARGET_SOURCES}) +target_link_options("${CMAKE_PROJECT_NAME}_FLASH_FB.elf" + PRIVATE "-T${TARGET_LDSCRIPT_FLASH_FB}" + PRIVATE "-Wl,-Map=${CMAKE_PROJECT_NAME}_FLASH_FB.map" +) +add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_FLASH_FB.hex" + COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_FLASH_FB.elf" "${CMAKE_PROJECT_NAME}_FLASH_FB.hex" + DEPENDS "${CMAKE_PROJECT_NAME}_FLASH_FB.elf" +) +add_custom_target("${CMAKE_PROJECT_NAME}_FLASH_FB_HEX" DEPENDS "${CMAKE_PROJECT_NAME}_FLASH_FB.hex") + + +# Create ELF +add_executable("${CMAKE_PROJECT_NAME}_RAM.elf" ${TARGET_SOURCES}) +target_link_options("${CMAKE_PROJECT_NAME}_RAM.elf" + PRIVATE "-T${TARGET_LDSCRIPT_RAM}" +) +add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_RAM.hex" + COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_RAM.elf" "${CMAKE_PROJECT_NAME}_RAM.hex" + DEPENDS "${CMAKE_PROJECT_NAME}_RAM.elf" +) +add_custom_target("${CMAKE_PROJECT_NAME}_RAM_HEX" DEPENDS "${CMAKE_PROJECT_NAME}_RAM.hex") diff --git a/MK60DN512xxx10.mex b/MK60DN512xxx10.mex new file mode 100644 index 0000000..f9b2c59 --- /dev/null +++ b/MK60DN512xxx10.mex @@ -0,0 +1,623 @@ + + + + MK60DN512xxx10 + MK60DN512VLQ10 + ksdk2_0 + + + + + + + true + false + false + true + false + + + + + + + + + 11.0.1 + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.0.1 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + INPUT + + + + + true + + + + + OUTPUT + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + N/A + + + + + + + + true + + + + + 2.0.2 + + + + + + + + + 11.0.1 + + + + + + + + + 0 + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + checkSignals_FB_A + checkSignals_FB_AD + checkSignal_FB_OE + checkSignal_FB_RW + checkSignal_FB_CS0 + checkSignalGroup1 + checkSignalGroup2 + checkSignalGroup3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + N/A + + + + \ No newline at end of file diff --git a/MK60DN512xxx10_flash_sram.ld b/MK60DN512xxx10_flash_sram.ld new file mode 100644 index 0000000..58e9af1 --- /dev/null +++ b/MK60DN512xxx10_flash_sram.ld @@ -0,0 +1,263 @@ +/* +** ################################################################### +** Processors: MK60DN512VLL10 +** MK60DN512VLQ10 +** MK60DN512VMC10 +** MK60DN512VMD10 +** +** Compiler: GNU C Compiler +** Reference manual: K60P144M100SF2V2RM Rev. 2, Jun 2012 +** Version: rev. 1.7, 2015-07-29 +** Build: b170214 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x1000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; +M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0400 : 0x0; + +/* Specify the memory areas */ +MEMORY +{ + m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400 + m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010 + m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0 + m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000 + m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + m_fb_sram (RW) : ORIGIN = 0x60000000, LENGTH = 0x00080000 +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into internal flash */ + .interrupts : + { + __VECTOR_TABLE = .; + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + .flash_config : + { + . = ALIGN(4); + KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ + . = ALIGN(4); + } > m_flash_config + + /* The program code and other data goes into internal flash */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + .interrupts_ram : + { + . = ALIGN(4); + __VECTOR_RAM__ = .; + __interrupts_ram_start__ = .; /* Create a global symbol at data start */ + *(.m_interrupts_ram) /* This is a user defined section */ + . += M_VECTOR_RAM_SIZE; + . = ALIGN(4); + __interrupts_ram_end__ = .; /* Define a global symbol at data end */ + } > m_data + + __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); + __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .data_2 : + { + . = ALIGN(8); + *(.freertos_heap) + *(.freertos_heap*) + . = ALIGN(8); + } > m_data_2 + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_data_2 + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data_2 + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data_2) + LENGTH(m_data_2); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data_2 overflowed with stack and heap") + + .extmem (NOLOAD) : + { + . = ALIGN(8); + *(.lwip_pool) + *(.lwip_pool*) + . = ALIGN(8); + } > m_fb_sram + +} + diff --git a/arm-none-eabi.cmake b/arm-none-eabi.cmake new file mode 100644 index 0000000..ab16b40 --- /dev/null +++ b/arm-none-eabi.cmake @@ -0,0 +1,10 @@ +set(CMAKE_C_COMPILER arm-none-eabi-gcc) +set(CMAKE_CXX_COMPILER arm-none-eabi-g++) + +# Make CMake happy about those compilers +set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + +# Poor old Windows... +if(WIN32) + set(CMAKE_SYSTEM_NAME "Generic") +endif() \ No newline at end of file diff --git a/board/board.c b/board/board.c new file mode 100644 index 0000000..274ce3f --- /dev/null +++ b/board/board.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ + +#include +#include "fsl_common.h" +#include "fsl_rtc.h" +#include "fsl_debug_console.h" +#include "board.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/* Initialize debug console. */ +void BOARD_InitDebugConsole(void) +{ + uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ; + + DbgConsole_Init(BOARD_DEBUG_UART_BASEADDR, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq); +} + + +void BOARD_EnableRTC(void) { + rtc_config_t rtc_config; + + RTC_GetDefaultConfig(&rtc_config); + + RTC_Init(RTC, &rtc_config); + + RTC->SR |= RTC_SR_TCE_MASK; +} \ No newline at end of file diff --git a/board/board.h b/board/board.h new file mode 100644 index 0000000..2481a1b --- /dev/null +++ b/board/board.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include "clock_config.h" +#include "fsl_gpio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief The board name */ +#define BOARD_NAME "TWR-K60D100M" + +/*! @brief The UART to use for debug messages. */ +#define BOARD_USE_UART +#define BOARD_DEBUG_UART_TYPE DEBUG_CONSOLE_DEVICE_TYPE_UART +#define BOARD_DEBUG_UART_BASEADDR (uint32_t) UART0 +#define BOARD_DEBUG_UART_CLKSRC kCLOCK_CoreSysClk +#define BOARD_DEBUG_UART_CLK_FREQ CLOCK_GetCoreSysClkFreq() +#define BOARD_UART_IRQ UART0_RX_TX_IRQn +#define BOARD_UART_IRQ_HANDLER UART0_RX_TX_IRQHandler + +#ifndef BOARD_DEBUG_UART_BAUDRATE +#define BOARD_DEBUG_UART_BAUDRATE 115200 +#endif /* BOARD_DEBUG_UART_BAUDRATE */ + +/*! @brief The CAN instance used for board */ +#define BOARD_CAN_BASEADDR CAN1 + +/*! @brief The i2c instance used for i2c connection by default */ +#define BOARD_I2C_BASEADDR I2C0 + +/*! @brief The Enet instance used for board */ +#define BOARD_ENET_BASEADDR ENET + +/*! @brief The FlexBus instance used for board.*/ +#define BOARD_FLEXBUS_BASEADDR FB + +#define BOARD_TSI_ELECTRODE_CNT 4U + +/*! @brief Indexes of the TSI channels for on board electrodes */ +#define BOARD_TSI_ELECTRODE_1 5U +#define BOARD_TSI_ELECTRODE_2 8U +#define BOARD_TSI_ELECTRODE_3 7U +#define BOARD_TSI_ELECTRODE_4 9U + +#define BOARD_TSI_TWRPI_ELECTRODE_0 0U +#define BOARD_TSI_TWRPI_ELECTRODE_1 6U +#define BOARD_TSI_TWRPI_ELECTRODE_2 7U +#define BOARD_TSI_TWRPI_ELECTRODE_3 8U +#define BOARD_TSI_TWRPI_ELECTRODE_4 13U +#define BOARD_TSI_TWRPI_ELECTRODE_5 14U +#define BOARD_TSI_TWRPI_ELECTRODE_6 15U +#define BOARD_TSI_TWRPI_ELECTRODE_7 5U +#define BOARD_TSI_TWRPI_ELECTRODE_8 9U +#define BOARD_TSI_TWRPI_ELECTRODE_9 10U +#define BOARD_TSI_TWRPI_ELECTRODE_10 11U +#define BOARD_TSI_TWRPI_ELECTRODE_11 12U + +/*! @brief ADC TWRPI ID input channel */ +#define BOARD_ADC_TWRPIID0_CHANNEL 1U +#define BOARD_ADC_TWRPIID1_CHANNEL 16U +#define BOARD_ADC_TWRPI 1U + +/*! @brief The SDHC instance/channel used for board */ +#define BOARD_SDHC_BASEADDR SDHC +#define BOARD_SDHC_CD_GPIO_IRQ_HANDLER PORTE_IRQHandler + +/*! @brief The CMP instance/channel used for board. */ +#define BOARD_CMP_BASEADDR CMP0 +#define BOARD_CMP_CHANNEL 0U + +/*! @brief The i2c instance used for sai demo */ +#define BOARD_SAI_DEMO_I2C_BASEADDR I2C0 + +/*! @brief The rtc instance used for rtc_func */ +#define BOARD_RTC_FUNC_BASEADDR RTC + +/* Board led color mapping */ +#define LOGIC_LED_ON 0U +#define LOGIC_LED_OFF 1U +#define BOARD_LED_ORANGE_GPIO GPIOA +#define BOARD_LED_ORANGE_GPIO_PORT PORTA +#define BOARD_LED_ORANGE_GPIO_PIN 11U +#define BOARD_LED_YELLOW_GPIO GPIOA +#define BOARD_LED_YELLOW_GPIO_PORT PORTA +#define BOARD_LED_YELLOW_GPIO_PIN 28U +#define BOARD_LED_GREEN_GPIO GPIOA +#define BOARD_LED_GREEN_GPIO_PORT PORTA +#define BOARD_LED_GREEN_GPIO_PIN 29U +#define BOARD_LED_BLUE_GPIO GPIOA +#define BOARD_LED_BLUE_GPIO_PORT PORTA +#define BOARD_LED_BLUE_GPIO_PIN 10U + +#define LED_ORANGE_INIT(output) \ + GPIO_WritePinOutput(BOARD_LED_ORANGE_GPIO, BOARD_LED_ORANGE_GPIO_PIN, output);\ + BOARD_LED_ORANGE_GPIO->PDDR |= (1U << BOARD_LED_ORANGE_GPIO_PIN) /*!< Enable target LED_ORANGE */ +#define LED_ORANGE_ON() \ + GPIO_ClearPinsOutput(BOARD_LED_ORANGE_GPIO, 1U << BOARD_LED_ORANGE_GPIO_PIN) /*!< Turn on target LED_ORANGE */ +#define LED_ORANGE_OFF() \ + GPIO_SetPinsOutput(BOARD_LED_ORANGE_GPIO, 1U << BOARD_LED_ORANGE_GPIO_PIN) /*!< Turn off target LED_ORANGE */ +#define LED_ORANGE_TOGGLE() \ + GPIO_TogglePinsOutput(BOARD_LED_ORANGE_GPIO, 1U << BOARD_LED_ORANGE_GPIO_PIN) /*!< Toggle on target LED_ORANGE */ + +#define LED_YELLOW_INIT(output) \ + GPIO_WritePinOutput(BOARD_LED_YELLOW_GPIO, BOARD_LED_YELLOW_GPIO_PIN, output);\ + BOARD_LED_YELLOW_GPIO->PDDR |= (1U << BOARD_LED_YELLOW_GPIO_PIN) /*!< Enable target LED_YELLOW */ +#define LED_YELLOW_ON() \ + GPIO_ClearPinsOutput(BOARD_LED_YELLOW_GPIO, 1U << BOARD_LED_YELLOW_GPIO_PIN) /*!< Turn on target LED_YELLOW */ +#define LED_YELLOW_OFF() \ + GPIO_SetPinsOutput(BOARD_LED_YELLOW_GPIO, 1U << BOARD_LED_YELLOW_GPIO_PIN) /*!< Turn off target LED_YELLOW */ +#define LED_YELLOW_TOGGLE() \ + GPIO_TogglePinsOutput(BOARD_LED_YELLOW_GPIO, 1U << BOARD_LED_YELLOW_GPIO_PIN) /*!< Toggle on target LED_YELLOW */ + +#define LED_GREEN_INIT(output) \ + GPIO_WritePinOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN, output);\ + BOARD_LED_GREEN_GPIO->PDDR |= (1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Enable target LED_GREEN */ +#define LED_GREEN_ON() \ + GPIO_ClearPinsOutput(BOARD_LED_GREEN_GPIO, 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn on target LED_GREEN */ +#define LED_GREEN_OFF() \ + GPIO_SetPinsOutput(BOARD_LED_GREEN_GPIO, 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn off target LED_GREEN */ +#define LED_GREEN_TOGGLE() \ + GPIO_TogglePinsOutput(BOARD_LED_GREEN_GPIO, 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Toggle on target LED_GREEN */ + +#define LED_BLUE_INIT(output) \ + GPIO_WritePinOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PIN, output);\ + BOARD_LED_BLUE_GPIO->PDDR |= (1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Enable target LED_BLUE */ +#define LED_BLUE_ON() \ + GPIO_ClearPinsOutput(BOARD_LED_BLUE_GPIO, 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn on target LED_BLUE */ +#define LED_BLUE_OFF() \ + GPIO_SetPinsOutput(BOARD_LED_BLUE_GPIO, 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn off target LED_BLUE */ +#define LED_BLUE_TOGGLE() \ + GPIO_TogglePinsOutput(BOARD_LED_BLUE_GPIO, 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Toggle on target LED_BLUE */ + +/* SDHC base address, clock and card detection pin */ +#define BOARD_SDHC_BASEADDR SDHC +#define BOARD_SDHC_CLKSRC kCLOCK_CoreSysClk +#define BOARD_SDHC_CLK_FREQ CLOCK_GetFreq(kCLOCK_CoreSysClk) +#define BOARD_SDHC_IRQ SDHC_IRQn +#define BOARD_SDHC_CD_GPIO_BASE GPIOE +#define BOARD_SDHC_CD_GPIO_PIN 28U +#define BOARD_SDHC_CD_PORT_BASE PORTE +#define BOARD_SDHC_CD_PORT_IRQ PORTE_IRQn +#define BOARD_SDHC_CD_PORT_IRQ_HANDLER PORTE_IRQHandler + +#define BOARD_ACCEL_I2C_BASEADDR I2C0 + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* + * API + ******************************************************************************/ + +void BOARD_InitDebugConsole(void); + +void BOARD_EnableRTC(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _BOARD_H_ */ diff --git a/board/clock_config.c b/board/clock_config.c new file mode 100644 index 0000000..e6f39df --- /dev/null +++ b/board/clock_config.c @@ -0,0 +1,226 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and + * internal reference clock(MCGIRCLK). Follow the steps to setup: + * + * 1). Call CLOCK_BootToXxxMode to set MCG to target mode. + * + * 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured + * correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig + * explicitly to setup MCGIRCLK. + * + * 3). Don't need to configure FLL explicitly, because if target mode is FLL + * mode, then FLL has been configured by the function CLOCK_BootToXxxMode, + * if the target mode is not FLL mode, the FLL is disabled. + * + * 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been + * setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could + * be enabled independently, call CLOCK_EnablePll0 explicitly in this case. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v9.0 +processor: MK60DN512xxx10 +package_id: MK60DN512VLQ10 +mcu_data: ksdk2_0 +processor_version: 11.0.1 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_rtc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define MCG_IRCLK_DISABLE 0U /*!< MCGIRCLK disabled */ +#define MCG_PLL_DISABLE 0U /*!< MCGPLLCLK disabled */ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define RTC_OSC_CAP_LOAD_12PF 0x1800U /*!< RTC oscillator capacity load: 12pF */ +#define RTC_RTC32KCLK_PERIPHERALS_ENABLED 1U /*!< RTC32KCLK to other peripherals: enabled */ +#define SIM_ENET_RMII_CLK_SEL_EXTAL_CLK 0U /*!< SDHC clock select: Core/system clock */ +#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ +#define SIM_PLLFLLSEL_MCGFLLCLK_CLK 0U /*!< PLLFLL select: MCGFLLCLK clock */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetRtcClock + * Description : This function is used to configuring RTC clock including + * enabling RTC oscillator. + * Param capLoad : RTC oscillator capacity load + * Param enableOutPeriph : Enable (1U)/Disable (0U) clock to peripherals + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetRtcClock(uint32_t capLoad, uint8_t enableOutPeriph) +{ + /* RTC clock gate enable */ + CLOCK_EnableClock(kCLOCK_Rtc0); + if ((RTC->CR & RTC_CR_OSCE_MASK) == 0u) { /* Only if the Rtc oscillator is not already enabled */ + /* Set the specified capacitor configuration for the RTC oscillator */ + RTC_SetOscCapLoad(RTC, capLoad); + /* Enable the RTC 32KHz oscillator */ + RTC->CR |= RTC_CR_OSCE_MASK; + } + /* Output to other peripherals */ + if (enableOutPeriph) { + RTC->CR &= ~RTC_CR_CLKO_MASK; + } + else { + RTC->CR |= RTC_CR_CLKO_MASK; + } + /* Set the XTAL32/RTC_CLKIN frequency based on board setting. */ + CLOCK_SetXtal32Freq(BOARD_XTAL32K_CLK_HZ); + /* Set RTC_TSR if there is fault value in RTC */ + if (RTC->SR & RTC_SR_TIF_MASK) { + RTC -> TSR = RTC -> TSR; + } + /* RTC clock gate disable */ + CLOCK_DisableClock(kCLOCK_Rtc0); +} + +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetFllExtRefDiv + * Description : Configure FLL external reference divider (FRDIV). + * Param frdiv : The value to set FRDIV. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetFllExtRefDiv(uint8_t frdiv) +{ + MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Bus_clock.outFreq, value: 50 MHz} +- {id: Core_clock.outFreq, value: 100 MHz} +- {id: Flash_clock.outFreq, value: 25 MHz} +- {id: FlexBus_clock.outFreq, value: 50 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 39.0625 kHz} +- {id: OSCERCLK.outFreq, value: 50 MHz} +- {id: RMIICLK.outFreq, value: 50 MHz} +- {id: System_clock.outFreq, value: 100 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: MCG.FRDIV.scale, value: '1280'} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLL} +- {id: MCG.PRDIV.scale, value: '13', locked: true} +- {id: MCG.VDIV.scale, value: '26', locked: true} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: RMIISrcConfig, value: 'yes'} +- {id: RTC_CR_OSCE_CFG, value: Enabled} +- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC12PF} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV3.scale, value: '2'} +- {id: SIM.OUTDIV4.scale, value: '4'} +sources: +- {id: OSC.OSC.outFreq, value: 50 MHz, enabled: true} +- {id: RTC.RTC32kHz.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockRUN = + { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */ + .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ + .fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */ + .frdiv = 0x6U, /* FLL reference clock divider: divided by 1280 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0xcU, /* PLL Reference divider: divided by 13 */ + .vdiv = 0x2U, /* VCO divider: multiplied by 26 */ + }, + }; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = + { + .pllFllSel = SIM_PLLFLLSEL_MCGFLLCLK_CLK, /* PLLFLL select: MCGFLLCLK clock */ + .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x1130000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /2, OUTDIV4: /4 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 50000000U, /* Oscillator frequency: 50000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Configure RTC clock including enabling RTC oscillator. */ + CLOCK_CONFIG_SetRtcClock(RTC_OSC_CAP_LOAD_12PF, RTC_RTC32KCLK_PERIPHERALS_ENABLED); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, + kMCG_PllClkSelPll0, + &mcgConfig_BOARD_BootClockRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + /* Set RMII clock source. */ + CLOCK_SetRmii0Clock(SIM_ENET_RMII_CLK_SEL_EXTAL_CLK); +} + diff --git a/board/clock_config.h b/board/clock_config.h new file mode 100644 index 0000000..245fb30 --- /dev/null +++ b/board/clock_config.h @@ -0,0 +1,71 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 50000000U /*!< Board xtal0 frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board RTC xtal frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ + +/*! @brief MCG set for BOARD_BootClockRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ + diff --git a/board/peripherals.c b/board/peripherals.c new file mode 100644 index 0000000..b37c6d3 --- /dev/null +++ b/board/peripherals.c @@ -0,0 +1,212 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Peripherals v11.0 +processor: MK60DN512xxx10 +package_id: MK60DN512VLQ10 +mcu_data: ksdk2_0 +processor_version: 11.0.1 +functionalGroups: +- name: BOARD_InitPeripherals + UUID: ac647ac1-e799-4dfc-9b77-81b2d47bf6c6 + called_from_default_init: true + selectedCore: core0 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +component: +- type: 'system' +- type_id: 'system_54b53072540eeeb8f8e9343e71f28176' +- global_system_definitions: + - user_definitions: '' + - user_includes: '' + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +component: +- type: 'gpio_adapter_common' +- type_id: 'gpio_adapter_common_57579b9ac814fe26bf95df0a384c36b6' +- global_gpio_adapter_common: + - quick_selection: 'default' + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +component: +- type: 'uart_cmsis_common' +- type_id: 'uart_cmsis_common_9cb8e302497aa696fdbb5a4fd622c2a8' +- global_USART_CMSIS_common: + - quick_selection: 'default' + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/*********************************************************************************************************************** + * Included files + **********************************************************************************************************************/ +#include "peripherals.h" + +/*********************************************************************************************************************** + * BOARD_InitPeripherals functional group + **********************************************************************************************************************/ +/*********************************************************************************************************************** + * NVIC initialization code + **********************************************************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +instance: +- name: 'NVIC' +- type: 'nvic' +- mode: 'general' +- custom_name_enabled: 'false' +- type_id: 'nvic_57b5eef3774cc60acaede6f5b8bddc67' +- functional_group: 'BOARD_InitPeripherals' +- peripheral: 'NVIC' +- config_sets: + - nvic: + - interrupt_table: [] + - interrupts: [] + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/* Empty initialization function (commented out) +static void NVIC_init(void) { +} */ + +/*********************************************************************************************************************** + * FB initialization code + **********************************************************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +instance: +- name: 'FB' +- type: 'flexbus' +- mode: 'general' +- custom_name_enabled: 'false' +- type_id: 'flexbus_c0f98ce230f06c38b26b546b16ee96cc' +- functional_group: 'BOARD_InitPeripherals' +- peripheral: 'FB' +- config_sets: + - fsl_flexbus: + - clockSource: 'FunctionClock' + - clockSourceFreq: 'BOARD_BootClockRUN' + - flexbus_configs: + - 0: + - enableChipConfiguration: 'true' + - initChip: 'true' + - chip: 'FB_CS0' + - chipUserName: 'LCD' + - chipBaseAddress: '0x70000000' + - chipBaseAddressMask: 'mask_0x0FFF' + - byteEnableMode: 'false' + - autoAcknowledge: 'true' + - extendTransferAddress: 'false' + - byteLaneShift: 'kFLEXBUS_NotShifted' + - portSize: 'kFLEXBUS_1Byte' + - writeAddressHold: 'kFLEXBUS_Hold1Cycle' + - readAddressHold: 'kFLEXBUS_Hold1Or0Cycles' + - addressSetup: 'kFLEXBUS_FirstRisingEdge' + - waitStates: '0' + - burstWrite: 'false' + - burstRead: 'false' + - writeProtect: 'false' + - 1: + - enableChipConfiguration: 'true' + - initChip: 'true' + - chip: 'FB_CS1' + - chipUserName: 'SRAM' + - chipBaseAddress: '0x60000000' + - chipBaseAddressMask: 'mask_0x0007' + - byteEnableMode: 'true' + - autoAcknowledge: 'true' + - extendTransferAddress: 'false' + - byteLaneShift: 'kFLEXBUS_NotShifted' + - portSize: 'kFLEXBUS_2Bytes' + - writeAddressHold: 'kFLEXBUS_Hold1Cycle' + - readAddressHold: 'kFLEXBUS_Hold1Or0Cycles' + - addressSetup: 'kFLEXBUS_FirstRisingEdge' + - waitStates: '1' + - burstWrite: 'false' + - burstRead: 'false' + - writeProtect: 'false' + - groupsMultiplexControl: + - group1MultiplexControl: 'kFLEXBUS_MultiplexGroup1_FB_CS1' + - group2MultiplexControl: 'kFLEXBUS_MultiplexGroup2_FB_BE_31_24' + - group3MultiplexControl: 'kFLEXBUS_MultiplexGroup3_FB_BE_23_16' + - group4MultiplexControl: 'kFLEXBUS_MultiplexGroup4_FB_TBST' + - group5MultiplexControl: 'kFLEXBUS_MultiplexGroup5_FB_TA' + - checkSignalsPins: 'checkSignals_FB_A checkSignals_FB_AD checkSignal_FB_OE checkSignal_FB_RW checkSignal_FB_CS0 checkSignalGroup1 checkSignalGroup2 checkSignalGroup3' + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ +flexbus_config_t FB_LCD_config = { + .chip = 0, + .chipBaseAddress = 0x70000000UL, + .chipBaseAddressMask = 0x0FFFU, + .byteEnableMode = false, + .autoAcknowledge = true, + .extendTransferAddress = false, + .byteLaneShift = kFLEXBUS_NotShifted, + .portSize = kFLEXBUS_1Byte, + .writeAddressHold = kFLEXBUS_Hold1Cycle, + .readAddressHold = kFLEXBUS_Hold1Or0Cycles, + .addressSetup = kFLEXBUS_FirstRisingEdge, + .waitStates = 0U, + .secondaryWaitStates = false, + .burstWrite = false, + .burstRead = false, + .writeProtect = false, + .group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_CS1, + .group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_BE_31_24, + .group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_BE_23_16, + .group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST, + .group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA +}; +flexbus_config_t FB_SRAM_config = { + .chip = 1, + .chipBaseAddress = 0x60000000UL, + .chipBaseAddressMask = 0x0007U, + .byteEnableMode = true, + .autoAcknowledge = true, + .extendTransferAddress = false, + .byteLaneShift = kFLEXBUS_NotShifted, + .portSize = kFLEXBUS_2Bytes, + .writeAddressHold = kFLEXBUS_Hold1Cycle, + .readAddressHold = kFLEXBUS_Hold1Or0Cycles, + .addressSetup = kFLEXBUS_FirstRisingEdge, + .waitStates = 1U, + .secondaryWaitStates = false, + .burstWrite = false, + .burstRead = false, + .writeProtect = false, + .group1MultiplexControl = kFLEXBUS_MultiplexGroup1_FB_CS1, + .group2MultiplexControl = kFLEXBUS_MultiplexGroup2_FB_BE_31_24, + .group3MultiplexControl = kFLEXBUS_MultiplexGroup3_FB_BE_23_16, + .group4MultiplexControl = kFLEXBUS_MultiplexGroup4_FB_TBST, + .group5MultiplexControl = kFLEXBUS_MultiplexGroup5_FB_TA +}; + +static void FB_init(void) { + /* FlexBus initialization */ + FLEXBUS_Init(FB_PERIPHERAL, &FB_LCD_config); + FLEXBUS_Init(FB_PERIPHERAL, &FB_SRAM_config); +} + +/*********************************************************************************************************************** + * Initialization functions + **********************************************************************************************************************/ +void BOARD_InitPeripherals(void) +{ + /* Initialize components */ + FB_init(); +} + +/*********************************************************************************************************************** + * BOARD_InitBootPeripherals function + **********************************************************************************************************************/ +void BOARD_InitBootPeripherals(void) +{ + BOARD_InitPeripherals(); +} diff --git a/board/peripherals.h b/board/peripherals.h new file mode 100644 index 0000000..7778516 --- /dev/null +++ b/board/peripherals.h @@ -0,0 +1,49 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PERIPHERALS_H_ +#define _PERIPHERALS_H_ + +/*********************************************************************************************************************** + * Included files + **********************************************************************************************************************/ +#include "fsl_common.h" +#include "fsl_flexbus.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ +/* Definitions for BOARD_InitPeripherals functional group */ +/* Definition of peripheral ID */ +#define FB_PERIPHERAL FB + +/*********************************************************************************************************************** + * Global variables + **********************************************************************************************************************/ +/* FlexBus configuration structure for LCD */ +extern flexbus_config_t FB_LCD_config; +/* FlexBus configuration structure for SRAM */ +extern flexbus_config_t FB_SRAM_config; + +/*********************************************************************************************************************** + * Initialization functions + **********************************************************************************************************************/ + +void BOARD_InitPeripherals(void); + +/*********************************************************************************************************************** + * BOARD_InitBootPeripherals function + **********************************************************************************************************************/ +void BOARD_InitBootPeripherals(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* _PERIPHERALS_H_ */ diff --git a/board/pin_mux.c b/board/pin_mux.c new file mode 100644 index 0000000..811e34e --- /dev/null +++ b/board/pin_mux.c @@ -0,0 +1,306 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v11.0 +processor: MK60DN512xxx10 +package_id: MK60DN512VLQ10 +mcu_data: ksdk2_0 +processor_version: 11.0.1 +pin_labels: +- {pin_num: '58', pin_signal: PTA6/FTM0_CH3/TRACE_CLKOUT, label: BUZZER, identifier: BUZZER} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '136', peripheral: UART0, signal: TX, pin_signal: PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1} + - {pin_num: '133', peripheral: UART0, signal: RX, pin_signal: ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FB_AD0/FTM0_FLT0} + - {pin_num: '58', peripheral: GPIOA, signal: 'GPIO, 6', pin_signal: PTA6/FTM0_CH3/TRACE_CLKOUT, direction: OUTPUT} + - {pin_num: '132', peripheral: FB, signal: 'AD, 1', pin_signal: ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/UART0_COL_b/FTM0_CH5/FB_AD1/EWM_OUT_b} + - {pin_num: '131', peripheral: FB, signal: 'AD, 2', pin_signal: PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/FB_AD2/EWM_IN} + - {pin_num: '130', peripheral: FB, signal: 'AD, 3', pin_signal: PTD3/SPI0_SIN/UART2_TX/FB_AD3} + - {pin_num: '129', peripheral: FB, signal: 'AD, 4', pin_signal: PTD2/LLWU_P13/SPI0_SOUT/UART2_RX/FB_AD4} + - {pin_num: '115', peripheral: FB, signal: 'AD, 5', pin_signal: ADC1_SE6b/PTC10/I2C1_SCL/I2S0_RX_FS/FB_AD5} + - {pin_num: '114', peripheral: FB, signal: 'AD, 6', pin_signal: ADC1_SE5b/CMP0_IN3/PTC9/I2S0_RX_BCLK/FB_AD6/FTM2_FLT0} + - {pin_num: '113', peripheral: FB, signal: 'AD, 7', pin_signal: ADC1_SE4b/CMP0_IN2/PTC8/I2S0_MCLK/FB_AD7} + - {pin_num: '112', peripheral: FB, signal: 'AD, 8', pin_signal: CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS/FB_AD8} + - {pin_num: '111', peripheral: FB, signal: 'AD, 9', pin_signal: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK} + - {pin_num: '110', peripheral: FB, signal: 'AD, 10', pin_signal: PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FB_AD10/CMP0_OUT} + - {pin_num: '109', peripheral: FB, signal: 'AD, 11', pin_signal: PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FB_AD11/CMP1_OUT} + - {pin_num: '105', peripheral: FB, signal: 'AD, 12', pin_signal: ADC0_SE4b/CMP1_IN0/TSI0_CH15/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FB_AD12/I2S0_TX_FS} + - {pin_num: '104', peripheral: FB, signal: 'AD, 13', pin_signal: ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/FB_AD13/I2S0_TXD0} + - {pin_num: '103', peripheral: FB, signal: 'AD, 14', pin_signal: ADC0_SE14/TSI0_CH13/PTC0/SPI0_PCS4/PDB0_EXTRG/FB_AD14/I2S0_TXD1} + - {pin_num: '97', peripheral: FB, signal: 'AD, 15', pin_signal: TSI0_CH11/PTB18/CAN0_TX/FTM2_CH0/I2S0_TX_BCLK/FB_AD15/FTM2_QD_PHA} + - {pin_num: '137', peripheral: FB, signal: 'A, 16', pin_signal: PTD8/I2C0_SCL/UART5_RX/FB_A16} + - {pin_num: '138', peripheral: FB, signal: 'A, 17', pin_signal: PTD9/I2C0_SDA/UART5_TX/FB_A17} + - {pin_num: '139', peripheral: FB, signal: 'A, 18', pin_signal: PTD10/UART5_RTS_b/FB_A18} + - {pin_num: '96', peripheral: FB, signal: 'AD, 16', pin_signal: TSI0_CH10/PTB17/SPI1_SIN/UART0_TX/FB_AD16/EWM_OUT_b} + - {pin_num: '95', peripheral: FB, signal: 'AD, 17', pin_signal: TSI0_CH9/PTB16/SPI1_SOUT/UART0_RX/FB_AD17/EWM_IN} + - {pin_num: '92', peripheral: FB, signal: 'AD, 18', pin_signal: ADC1_SE15/PTB11/SPI1_SCK/UART3_TX/FB_AD18/FTM0_FLT2} + - {pin_num: '91', peripheral: FB, signal: 'AD, 19', pin_signal: ADC1_SE14/PTB10/SPI1_PCS0/UART3_RX/FB_AD19/FTM0_FLT1} + - {pin_num: '90', peripheral: FB, signal: 'AD, 20', pin_signal: PTB9/SPI1_PCS1/UART3_CTS_b/FB_AD20} + - {pin_num: '89', peripheral: FB, signal: 'AD, 21', pin_signal: PTB8/UART3_RTS_b/FB_AD21} + - {pin_num: '88', peripheral: FB, signal: 'AD, 22', pin_signal: ADC1_SE13/PTB7/FB_AD22} + - {pin_num: '87', peripheral: FB, signal: 'AD, 23', pin_signal: ADC1_SE12/PTB6/FB_AD23} + - {pin_num: '120', peripheral: FB, signal: 'AD, 24', pin_signal: PTC15/UART4_TX/FB_AD24} + - {pin_num: '119', peripheral: FB, signal: 'AD, 25', pin_signal: PTC14/UART4_RX/FB_AD25} + - {pin_num: '117', peripheral: FB, signal: 'AD, 27', pin_signal: PTC12/UART4_RTS_b/FB_AD27} + - {pin_num: '118', peripheral: FB, signal: 'AD, 26', pin_signal: PTC13/UART4_CTS_b/FB_AD26} + - {pin_num: '102', peripheral: FB, signal: 'AD, 28', pin_signal: PTB23/SPI2_SIN/SPI0_PCS5/FB_AD28} + - {pin_num: '101', peripheral: FB, signal: 'AD, 29', pin_signal: PTB22/SPI2_SOUT/FB_AD29/CMP2_OUT} + - {pin_num: '100', peripheral: FB, signal: 'AD, 30', pin_signal: PTB21/SPI2_SCK/FB_AD30/CMP1_OUT} + - {pin_num: '99', peripheral: FB, signal: 'AD, 31', pin_signal: PTB20/SPI2_PCS0/FB_AD31/CMP0_OUT} + - {pin_num: '127', peripheral: FB, signal: ALE_CS1_TS, pin_signal: PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b/FB_ALE/FB_CS1_b/FB_TS_b} + - {pin_num: '128', peripheral: FB, signal: CS0, pin_signal: ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b/FB_CS0_b} + - {pin_num: '116', peripheral: FB, signal: RW, pin_signal: ADC1_SE7b/PTC11/LLWU_P11/I2C1_SDA/I2S0_RXD1/FB_RW_b} + - {pin_num: '98', peripheral: FB, signal: OE, pin_signal: TSI0_CH12/PTB19/CAN0_RX/FTM2_CH1/I2S0_TX_FS/FB_OE_b/FTM2_QD_PHB} + - {pin_num: '77', peripheral: FB, signal: 'A, 27', pin_signal: PTA26/MII0_TXD3/FB_A27} + - {pin_num: '123', peripheral: FB, signal: CS5_TSIZ1_BE23_16_BLS15_8, pin_signal: PTC16/CAN1_RX/UART3_RX/ENET0_1588_TMR0/FB_CS5_b/FB_TSIZ1/FB_BE23_16_b} + - {pin_num: '124', peripheral: FB, signal: CS4_TSIZ0_BE31_24_BLS7_0, pin_signal: PTC17/CAN1_TX/UART3_TX/ENET0_1588_TMR1/FB_CS4_b/FB_TSIZ0/FB_BE31_24_b} + - {pin_num: '66', peripheral: ENET, signal: RMII_CRS_DV, pin_signal: PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2S0_RX_BCLK/I2S0_TXD1} + - {pin_num: '82', peripheral: ENET, signal: RMII_MDC, pin_signal: ADC0_SE9/ADC1_SE9/TSI0_CH6/PTB1/I2C0_SDA/FTM1_CH1/RMII0_MDC/MII0_MDC/FTM1_QD_PHB} + - {pin_num: '81', peripheral: ENET, signal: RMII_MDIO, pin_signal: ADC0_SE8/ADC1_SE8/TSI0_CH0/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/RMII0_MDIO/MII0_MDIO/FTM1_QD_PHA} + - {pin_num: '65', peripheral: ENET, signal: RMII_RXD0, pin_signal: CMP2_IN1/PTA13/LLWU_P4/CAN0_RX/FTM1_CH1/RMII0_RXD0/MII0_RXD0/I2S0_TX_FS/FTM1_QD_PHB} + - {pin_num: '64', peripheral: ENET, signal: RMII_RXD1, pin_signal: CMP2_IN0/PTA12/CAN0_TX/FTM1_CH0/RMII0_RXD1/MII0_RXD1/I2S0_TXD0/FTM1_QD_PHA} + - {pin_num: '55', peripheral: ENET, signal: RMII_RXER, pin_signal: PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b} + - {pin_num: '68', peripheral: ENET, signal: RMII_TXD0, pin_signal: PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1} + - {pin_num: '69', peripheral: ENET, signal: RMII_TXD1, pin_signal: ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK} + - {pin_num: '67', peripheral: ENET, signal: rmii_txen, pin_signal: PTA15/SPI0_SCK/UART0_RX/RMII0_TXEN/MII0_TXEN/I2S0_RXD0} + - {pin_num: '72', peripheral: ENET, signal: RMII_CLKIN, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + /* Port A Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortA); + /* Port B Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortB); + /* Port C Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortC); + /* Port D Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortD); + + gpio_pin_config_t BUZZER_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTA6 (pin 58) */ + GPIO_PinInit(BOARD_INITPINS_BUZZER_GPIO, BOARD_INITPINS_BUZZER_PIN, &BUZZER_config); + + /* PORTA12 (pin 64) is configured as RMII0_RXD1 */ + PORT_SetPinMux(PORTA, 12U, kPORT_MuxAlt4); + + /* PORTA13 (pin 65) is configured as RMII0_RXD0 */ + PORT_SetPinMux(PORTA, 13U, kPORT_MuxAlt4); + + /* PORTA14 (pin 66) is configured as RMII0_CRS_DV */ + PORT_SetPinMux(PORTA, 14U, kPORT_MuxAlt4); + + /* PORTA15 (pin 67) is configured as RMII0_TXEN */ + PORT_SetPinMux(PORTA, 15U, kPORT_MuxAlt4); + + /* PORTA16 (pin 68) is configured as RMII0_TXD0 */ + PORT_SetPinMux(PORTA, 16U, kPORT_MuxAlt4); + + /* PORTA17 (pin 69) is configured as RMII0_TXD1 */ + PORT_SetPinMux(PORTA, 17U, kPORT_MuxAlt4); + + /* PORTA18 (pin 72) is configured as EXTAL0 */ + PORT_SetPinMux(PORTA, 18U, kPORT_PinDisabledOrAnalog); + + /* PORTA26 (pin 77) is configured as FB_A27 */ + PORT_SetPinMux(PORTA, 26U, kPORT_MuxAlt6); + + /* PORTA5 (pin 55) is configured as RMII0_RXER */ + PORT_SetPinMux(PORTA, 5U, kPORT_MuxAlt4); + + /* PORTA6 (pin 58) is configured as PTA6 */ + PORT_SetPinMux(BOARD_INITPINS_BUZZER_PORT, BOARD_INITPINS_BUZZER_PIN, kPORT_MuxAsGpio); + + /* PORTB0 (pin 81) is configured as RMII0_MDIO */ + PORT_SetPinMux(PORTB, 0U, kPORT_MuxAlt4); + + /* PORTB1 (pin 82) is configured as RMII0_MDC */ + PORT_SetPinMux(PORTB, 1U, kPORT_MuxAlt4); + + /* PORTB10 (pin 91) is configured as FB_AD19 */ + PORT_SetPinMux(PORTB, 10U, kPORT_MuxAlt5); + + /* PORTB11 (pin 92) is configured as FB_AD18 */ + PORT_SetPinMux(PORTB, 11U, kPORT_MuxAlt5); + + /* PORTB16 (pin 95) is configured as FB_AD17 */ + PORT_SetPinMux(PORTB, 16U, kPORT_MuxAlt5); + + /* PORTB17 (pin 96) is configured as FB_AD16 */ + PORT_SetPinMux(PORTB, 17U, kPORT_MuxAlt5); + + /* PORTB18 (pin 97) is configured as FB_AD15 */ + PORT_SetPinMux(PORTB, 18U, kPORT_MuxAlt5); + + /* PORTB19 (pin 98) is configured as FB_OE_b */ + PORT_SetPinMux(PORTB, 19U, kPORT_MuxAlt5); + + /* PORTB20 (pin 99) is configured as FB_AD31 */ + PORT_SetPinMux(PORTB, 20U, kPORT_MuxAlt5); + + /* PORTB21 (pin 100) is configured as FB_AD30 */ + PORT_SetPinMux(PORTB, 21U, kPORT_MuxAlt5); + + /* PORTB22 (pin 101) is configured as FB_AD29 */ + PORT_SetPinMux(PORTB, 22U, kPORT_MuxAlt5); + + /* PORTB23 (pin 102) is configured as FB_AD28 */ + PORT_SetPinMux(PORTB, 23U, kPORT_MuxAlt5); + + /* PORTB6 (pin 87) is configured as FB_AD23 */ + PORT_SetPinMux(PORTB, 6U, kPORT_MuxAlt5); + + /* PORTB7 (pin 88) is configured as FB_AD22 */ + PORT_SetPinMux(PORTB, 7U, kPORT_MuxAlt5); + + /* PORTB8 (pin 89) is configured as FB_AD21 */ + PORT_SetPinMux(PORTB, 8U, kPORT_MuxAlt5); + + /* PORTB9 (pin 90) is configured as FB_AD20 */ + PORT_SetPinMux(PORTB, 9U, kPORT_MuxAlt5); + + /* PORTC0 (pin 103) is configured as FB_AD14 */ + PORT_SetPinMux(PORTC, 0U, kPORT_MuxAlt5); + + /* PORTC1 (pin 104) is configured as FB_AD13 */ + PORT_SetPinMux(PORTC, 1U, kPORT_MuxAlt5); + + /* PORTC10 (pin 115) is configured as FB_AD5 */ + PORT_SetPinMux(PORTC, 10U, kPORT_MuxAlt5); + + /* PORTC11 (pin 116) is configured as FB_RW_b */ + PORT_SetPinMux(PORTC, 11U, kPORT_MuxAlt5); + + /* PORTC12 (pin 117) is configured as FB_AD27 */ + PORT_SetPinMux(PORTC, 12U, kPORT_MuxAlt5); + + /* PORTC13 (pin 118) is configured as FB_AD26 */ + PORT_SetPinMux(PORTC, 13U, kPORT_MuxAlt5); + + /* PORTC14 (pin 119) is configured as FB_AD25 */ + PORT_SetPinMux(PORTC, 14U, kPORT_MuxAlt5); + + /* PORTC15 (pin 120) is configured as FB_AD24 */ + PORT_SetPinMux(PORTC, 15U, kPORT_MuxAlt5); + + /* PORTC16 (pin 123) is configured as FB_CS5_b */ + PORT_SetPinMux(PORTC, 16U, kPORT_MuxAlt5); + + /* PORTC17 (pin 124) is configured as FB_CS4_b */ + PORT_SetPinMux(PORTC, 17U, kPORT_MuxAlt5); + + /* PORTC2 (pin 105) is configured as FB_AD12 */ + PORT_SetPinMux(PORTC, 2U, kPORT_MuxAlt5); + + /* PORTC4 (pin 109) is configured as FB_AD11 */ + PORT_SetPinMux(PORTC, 4U, kPORT_MuxAlt5); + + /* PORTC5 (pin 110) is configured as FB_AD10 */ + PORT_SetPinMux(PORTC, 5U, kPORT_MuxAlt5); + + /* PORTC6 (pin 111) is configured as FB_AD9 */ + PORT_SetPinMux(PORTC, 6U, kPORT_MuxAlt5); + + /* PORTC7 (pin 112) is configured as FB_AD8 */ + PORT_SetPinMux(PORTC, 7U, kPORT_MuxAlt5); + + /* PORTC8 (pin 113) is configured as FB_AD7 */ + PORT_SetPinMux(PORTC, 8U, kPORT_MuxAlt5); + + /* PORTC9 (pin 114) is configured as FB_AD6 */ + PORT_SetPinMux(PORTC, 9U, kPORT_MuxAlt5); + + /* PORTD0 (pin 127) is configured as FB_CS1_b */ + PORT_SetPinMux(PORTD, 0U, kPORT_MuxAlt5); + + /* PORTD1 (pin 128) is configured as FB_CS0_b */ + PORT_SetPinMux(PORTD, 1U, kPORT_MuxAlt5); + + /* PORTD10 (pin 139) is configured as FB_A18 */ + PORT_SetPinMux(PORTD, 10U, kPORT_MuxAlt6); + + /* PORTD2 (pin 129) is configured as FB_AD4 */ + PORT_SetPinMux(PORTD, 2U, kPORT_MuxAlt5); + + /* PORTD3 (pin 130) is configured as FB_AD3 */ + PORT_SetPinMux(PORTD, 3U, kPORT_MuxAlt5); + + /* PORTD4 (pin 131) is configured as FB_AD2 */ + PORT_SetPinMux(PORTD, 4U, kPORT_MuxAlt5); + + /* PORTD5 (pin 132) is configured as FB_AD1 */ + PORT_SetPinMux(PORTD, 5U, kPORT_MuxAlt5); + + /* PORTD6 (pin 133) is configured as UART0_RX */ + PORT_SetPinMux(PORTD, 6U, kPORT_MuxAlt3); + + /* PORTD7 (pin 136) is configured as UART0_TX */ + PORT_SetPinMux(PORTD, 7U, kPORT_MuxAlt3); + + /* PORTD8 (pin 137) is configured as FB_A16 */ + PORT_SetPinMux(PORTD, 8U, kPORT_MuxAlt6); + + /* PORTD9 (pin 138) is configured as FB_A17 */ + PORT_SetPinMux(PORTD, 9U, kPORT_MuxAlt6); + + SIM->SOPT2 = ((SIM->SOPT2 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT2_RMIISRC_MASK))) + + /* RMII clock source select: EXTAL clock. */ + | SIM_SOPT2_RMIISRC(SOPT2_RMIISRC_EXTAL)); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_UART0TXSRC_MASK | SIM_SOPT5_UART0RXSRC_MASK))) + + /* UART 0 transmit data source select: UART0_TX pin. */ + | SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX) + + /* UART 0 receive data source select: UART0_RX pin. */ + | SIM_SOPT5_UART0RXSRC(SOPT5_UART0RXSRC_UART_RX)); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/board/pin_mux.h b/board/pin_mux.h new file mode 100644 index 0000000..c594838 --- /dev/null +++ b/board/pin_mux.h @@ -0,0 +1,62 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define SOPT2_RMIISRC_EXTAL 0x00u /*!<@brief RMII clock source select: EXTAL clock */ +#define SOPT5_UART0RXSRC_UART_RX 0x00u /*!<@brief UART 0 receive data source select: UART0_RX pin */ +#define SOPT5_UART0TXSRC_UART_TX 0x00u /*!<@brief UART 0 transmit data source select: UART0_TX pin */ + +/*! @name PORTA6 (number 58), BUZZER + @{ */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_BUZZER_GPIO GPIOA /*!<@brief GPIO peripheral base pointer */ +#define BOARD_INITPINS_BUZZER_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_INITPINS_BUZZER_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_INITPINS_BUZZER_PIN 6U /*!<@brief PORT pin number */ +#define BOARD_INITPINS_BUZZER_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h new file mode 100644 index 0000000..6e0409c --- /dev/null +++ b/include/FreeRTOSConfig.h @@ -0,0 +1,132 @@ +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + #include + extern uint32_t SystemCoreClock; +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 0 +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ 1000 +#define configMAX_PRIORITIES 64 +#define configMINIMAL_STACK_SIZE 128 +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE 10 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 1 +#define configENABLE_BACKWARD_COMPATIBILITY 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configSTACK_DEPTH_TYPE uint16_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE 57344 +#define configAPPLICATION_ALLOCATED_HEAP 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY 54 +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* =============================================================================================================== */ + +/* 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 +#endif +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 +/* 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) ) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#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. */ +/* USER CODE BEGIN 1 */ +#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} +/* USER CODE END 1 */ +/* 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 + +/* =============================================================================================================== */ + +/* FreeRTOS MPU specific definitions. */ +#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#define configTOTAL_MPU_REGIONS 8 /* Default value. */ +#define configTEX_S_C_B_FLASH 0x07UL /* Default value. */ +#define configTEX_S_C_B_SRAM 0x07UL /* Default value. */ +#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1 +#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 1 + +/* ARMv8-M secure side port related definitions. */ +#define secureconfigMAX_SECURE_CONTEXTS 5 + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetHandle 0 +#define INCLUDE_xTaskResumeFromISR 1 + +/* A header file that defines trace macro can be included here. */ + +#endif /* FREERTOS_CONFIG_H */ \ No newline at end of file diff --git a/include/ethernetif.h b/include/ethernetif.h new file mode 100644 index 0000000..a90369b --- /dev/null +++ b/include/ethernetif.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2001-2003 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. 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 lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 SDRVL THE COPYRIGHT HOLDER 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. + */ + +#ifndef ETHERNETIF_H +#define ETHERNETIF_H + +#include "lwip/err.h" +#include "fsl_enet.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#ifndef ENET_RXBD_NUM + #define ENET_RXBD_NUM (5) +#endif +#ifndef ENET_TXBD_NUM +#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) + #define ENET_TXBD_NUM (5) +#else + #define ENET_TXBD_NUM (3) +#endif +#endif +#ifndef ENET_RXBUFF_SIZE + #define ENET_RXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN) +#endif +#ifndef ENET_TXBUFF_SIZE + #define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN) +#endif + +/* MAC address configuration. */ +#ifndef configMAC_ADDR0 +#define configMAC_ADDR0 0x00 +#endif +#ifndef configMAC_ADDR1 +#define configMAC_ADDR1 0x12 +#endif +#ifndef configMAC_ADDR2 +#define configMAC_ADDR2 0x13 +#endif +#ifndef configMAC_ADDR3 +#define configMAC_ADDR3 0x10 +#endif +#ifndef configMAC_ADDR4 +#define configMAC_ADDR4 0x15 +#endif +#ifndef configMAC_ADDR5 +#define configMAC_ADDR5 0x11 +#endif + +#define ENET_OK (0U) +#define ENET_ERROR (0xFFU) +#define ENET_TIMEOUT (0xFFFU) + +/* ENET IRQ priority. Used in FreeRTOS. */ +#ifndef ENET_PRIORITY + #define ENET_PRIORITY (6U) +#endif +#ifndef ENET_1588_PRIORITY + #define ENET_1588_PRIORITY (5U) +#endif +/* The PHY address.*/ +#ifndef ENET_PHY_ADDRESS + #define ENET_PHY_ADDRESS (1) +#endif + +/* Defines Ethernet Autonegotiation Timeout during initialization. + * Set it to 0 to disable the waiting. */ +#ifndef ENET_ATONEGOTIATION_TIMEOUT + #define ENET_ATONEGOTIATION_TIMEOUT (0xFFFU) +#endif + +/** + * This function should be passed as a parameter to netif_add() + */ +err_t ethernetif_init(struct netif *netif); + +/** + * This function should be called when a packet is ready to be read + * from the interface. + * It is used by bare-metal applications. + * + * @param netif the lwip network interface structure for this ethernetif + */ +void ethernetif_input(struct netif *netif); + +#endif diff --git a/include/fsl_phy.h b/include/fsl_phy.h new file mode 100644 index 0000000..4ef4e36 --- /dev/null +++ b/include/fsl_phy.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +#ifndef _FSL_PHY_H_ +#define _FSL_PHY_H_ + +#include "fsl_enet.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ + +/*! @brief Defines the PHY registers. */ +#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */ +#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */ +#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */ +#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */ +#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */ +#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */ +#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */ + +#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/ + +/*! @brief Defines the mask flag in basic control register. */ +#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */ +#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */ +#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */ +#define PHY_BCTL_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */ +#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */ +#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */ + +/*!@brief Defines the mask flag of operation mode in control two register*/ +#define PHY_CTL1_REMOTELOOP_MASK 0x0008U /*!< The PHY remote loopback mask. */ +#define PHY_CTL2_10HALFDUPLEX_MASK 0x0004U /*!< The PHY 10M half duplex mask. */ +#define PHY_CTL2_100HALFDUPLEX_MASK 0x0008U /*!< The PHY 100M half duplex mask. */ +#define PHY_CTL2_10FULLDUPLEX_MASK 0x0014U /*!< The PHY 10M full duplex mask. */ +#define PHY_CTL2_100FULLDUPLEX_MASK 0x0018U /*!< The PHY 100M full duplex mask. */ + +/*! @brief Defines the mask flag in basic status register. */ +#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */ +#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */ +#define PHY_BSTATUS_SPEEDUPLX_MASK 0x001cU /*!< The PHY speed and duplex mask. */ +#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */ + +/*! @brief Defines the mask flag in PHY auto-negotiation advertise register. */ +#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */ +#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/ +#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/ + +/*! @brief Defines the PHY status. */ +enum _phy_status +{ + kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 0), /*!< ENET PHY SMI visit timeout. */ + kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 1) /*!< ENET PHY AutoNegotiate Fail. */ +}; + +/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */ +typedef enum _phy_speed +{ + kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */ + kPHY_Speed100M /*!< ENET PHY 100M speed. */ +} phy_speed_t; + +/*! @brief Defines the PHY link duplex. */ +typedef enum _phy_duplex +{ + kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */ + kPHY_FullDuplex /*!< ENET PHY full duplex. */ +} phy_duplex_t; + +/*! @brief Defines the PHY loopback mode. */ +typedef enum _phy_loop +{ + kPHY_LocalLoop = 0U, /*!< ENET PHY local loopback. */ + kPHY_RemoteLoop /*!< ENET PHY remote loopback. */ +} phy_loop_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize the SMI interface and initialize PHY. + * The SMI is the MII management interface between PHY and MAC, which should be + * firstly initialized before any other operation for PHY. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI. + * @retval kStatus_Success PHY initialize success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + * @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail + */ +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz); + +/*! + * @brief PHY Write function. This function write data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data); + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * the two loopback mode should not be both set. when one loopback mode is set + * the other one should be disabled. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY loopback success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, bool enable); + +/*! + * @brief Gets the PHY link status. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY get link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status); + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY get link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PHY_H_ */ diff --git a/include/ip_stack_helpers.h b/include/ip_stack_helpers.h new file mode 100644 index 0000000..3cee98d --- /dev/null +++ b/include/ip_stack_helpers.h @@ -0,0 +1,6 @@ +#ifndef IP_STACK_HELPERS_H +#define IP_STACK_HELPERS_H + +void ip_stack_setup(void); + +#endif \ No newline at end of file diff --git a/include/system_utilities.h b/include/system_utilities.h new file mode 100644 index 0000000..ecdcad3 --- /dev/null +++ b/include/system_utilities.h @@ -0,0 +1,7 @@ +#ifndef SYSTEM_UTILITIES_H +#define SYSTEM_UTILITIES_H + +void print_hardware(void); +void sram_test(void); + +#endif \ No newline at end of file diff --git a/lib/.gitkeep b/lib/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/lib/LwIP/CMakeLists.txt b/lib/LwIP/CMakeLists.txt new file mode 100644 index 0000000..9a14e2a --- /dev/null +++ b/lib/LwIP/CMakeLists.txt @@ -0,0 +1,141 @@ +cmake_minimum_required(VERSION 3.10) + +project(lwip) + +if(NOT LWIP_CONFIG_FILE_DIRECTORY) + message(FATAL_ERROR "Please specify LWIP_CONFIG_FILE_DIRECTORY for lwipopts.h") +endif() + +set(lwip_SRCS + "lwip/src/api/api_lib.c" + "lwip/src/api/api_msg.c" + "lwip/src/api/err.c" + "lwip/src/api/if_api.c" + "lwip/src/api/netbuf.c" + "lwip/src/api/netdb.c" + "lwip/src/api/netifapi.c" + "lwip/src/api/sockets.c" + "lwip/src/api/tcpip.c" + "lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c" + "lwip/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c" + "lwip/src/apps/http/altcp_proxyconnect.c" + "lwip/src/apps/http/fs.c" + "lwip/src/apps/http/fsdata.c" + "lwip/src/apps/http/http_client.c" + "lwip/src/apps/http/httpd.c" + "lwip/src/apps/lwiperf/lwiperf.c" + "lwip/src/apps/mdns/mdns.c" + "lwip/src/apps/mdns/mdns_domain.c" + "lwip/src/apps/mdns/mdns_out.c" + "lwip/src/apps/mqtt/mqtt.c" + "lwip/src/apps/netbiosns/netbiosns.c" + "lwip/src/apps/smtp/smtp.c" + "lwip/src/apps/snmp/snmp_asn1.c" + "lwip/src/apps/snmp/snmp_core.c" + "lwip/src/apps/snmp/snmp_mib2.c" + "lwip/src/apps/snmp/snmp_mib2_icmp.c" + "lwip/src/apps/snmp/snmp_mib2_interfaces.c" + "lwip/src/apps/snmp/snmp_mib2_ip.c" + "lwip/src/apps/snmp/snmp_mib2_snmp.c" + "lwip/src/apps/snmp/snmp_mib2_system.c" + "lwip/src/apps/snmp/snmp_mib2_tcp.c" + "lwip/src/apps/snmp/snmp_mib2_udp.c" + "lwip/src/apps/snmp/snmp_msg.c" + "lwip/src/apps/snmp/snmp_netconn.c" + "lwip/src/apps/snmp/snmp_pbuf_stream.c" + "lwip/src/apps/snmp/snmp_raw.c" + "lwip/src/apps/snmp/snmp_scalar.c" + "lwip/src/apps/snmp/snmp_snmpv2_framework.c" + "lwip/src/apps/snmp/snmp_snmpv2_usm.c" + "lwip/src/apps/snmp/snmp_table.c" + "lwip/src/apps/snmp/snmp_threadsync.c" + "lwip/src/apps/snmp/snmp_traps.c" + "lwip/src/apps/snmp/snmpv3.c" + "lwip/src/apps/snmp/snmpv3_mbedtls.c" + "lwip/src/apps/sntp/sntp.c" + "lwip/src/apps/tftp/tftp.c" + "lwip/src/core/altcp.c" + "lwip/src/core/altcp_alloc.c" + "lwip/src/core/altcp_tcp.c" + "lwip/src/core/def.c" + "lwip/src/core/dns.c" + "lwip/src/core/inet_chksum.c" + "lwip/src/core/init.c" + "lwip/src/core/ip.c" + "lwip/src/core/ipv4/acd.c" + "lwip/src/core/ipv4/autoip.c" + "lwip/src/core/ipv4/dhcp.c" + "lwip/src/core/ipv4/etharp.c" + "lwip/src/core/ipv4/icmp.c" + "lwip/src/core/ipv4/igmp.c" + "lwip/src/core/ipv4/ip4.c" + "lwip/src/core/ipv4/ip4_addr.c" + "lwip/src/core/ipv4/ip4_frag.c" + "lwip/src/core/ipv6/dhcp6.c" + "lwip/src/core/ipv6/ethip6.c" + "lwip/src/core/ipv6/icmp6.c" + "lwip/src/core/ipv6/inet6.c" + "lwip/src/core/ipv6/ip6.c" + "lwip/src/core/ipv6/ip6_addr.c" + "lwip/src/core/ipv6/ip6_frag.c" + "lwip/src/core/ipv6/mld6.c" + "lwip/src/core/ipv6/nd6.c" + "lwip/src/core/mem.c" + "lwip/src/core/memp.c" + "lwip/src/core/netif.c" + "lwip/src/core/pbuf.c" + "lwip/src/core/raw.c" + "lwip/src/core/stats.c" + "lwip/src/core/sys.c" + "lwip/src/core/tcp.c" + "lwip/src/core/tcp_in.c" + "lwip/src/core/tcp_out.c" + "lwip/src/core/timeouts.c" + "lwip/src/core/udp.c" + "lwip/src/netif/bridgeif.c" + "lwip/src/netif/bridgeif_fdb.c" + "lwip/src/netif/ethernet.c" + "lwip/src/netif/lowpan6.c" + "lwip/src/netif/lowpan6_ble.c" + "lwip/src/netif/lowpan6_common.c" + "lwip/src/netif/ppp/auth.c" + "lwip/src/netif/ppp/ccp.c" + "lwip/src/netif/ppp/chap-md5.c" + "lwip/src/netif/ppp/chap-new.c" + "lwip/src/netif/ppp/chap_ms.c" + "lwip/src/netif/ppp/demand.c" + "lwip/src/netif/ppp/eap.c" + "lwip/src/netif/ppp/ecp.c" + "lwip/src/netif/ppp/eui64.c" + "lwip/src/netif/ppp/fsm.c" + "lwip/src/netif/ppp/ipcp.c" + "lwip/src/netif/ppp/ipv6cp.c" + "lwip/src/netif/ppp/lcp.c" + "lwip/src/netif/ppp/magic.c" + "lwip/src/netif/ppp/mppe.c" + "lwip/src/netif/ppp/multilink.c" + "lwip/src/netif/ppp/polarssl/arc4.c" + "lwip/src/netif/ppp/polarssl/des.c" + "lwip/src/netif/ppp/polarssl/md4.c" + "lwip/src/netif/ppp/polarssl/md5.c" + "lwip/src/netif/ppp/polarssl/sha1.c" + "lwip/src/netif/ppp/ppp.c" + "lwip/src/netif/ppp/pppapi.c" + "lwip/src/netif/ppp/pppcrypt.c" + "lwip/src/netif/ppp/pppoe.c" + "lwip/src/netif/ppp/pppol2tp.c" + "lwip/src/netif/ppp/pppos.c" + "lwip/src/netif/ppp/upap.c" + "lwip/src/netif/ppp/utils.c" + "lwip/src/netif/ppp/vj.c" + "lwip/src/netif/slipif.c" + "lwip/src/netif/zepif.c" + +) + +set(lwip_INCS + "lwip/src/include" +) + +add_library(${PROJECT_NAME} ${lwip_SRCS}) +target_include_directories(${PROJECT_NAME} PUBLIC ${lwip_INCS} ${LWIP_CONFIG_FILE_DIRECTORY}) diff --git a/lib/LwIP/port/include/arch/cc.h b/lib/LwIP/port/include/arch/cc.h new file mode 100644 index 0000000..ab15eac --- /dev/null +++ b/lib/LwIP/port/include/arch/cc.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2001-2003 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. 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 lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_ARCH_CC_H +#define LWIP_ARCH_CC_H + +#define LWIP_ERRNO_INCLUDE +#define LWIP_ERRNO_STDINCLUDE 1 + +extern unsigned int lwip_platform_rand(void); +#define LWIP_RAND() (lwip_platform_rand()) + +#define LWIP_TIMEVAL_PRIVATE 0 + +#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t __attribute__((section(".lwip_pool"))) variable_name[LWIP_MEM_ALIGN_BUFFER(size)] + +int set_rtc_time(int sec); +#define SNTP_SET_SYSTEM_TIME set_rtc_time + +#endif /* LWIP_ARCH_CC_H */ diff --git a/lib/LwIP/port/include/arch/sys_arch.h b/lib/LwIP/port/include/arch/sys_arch.h new file mode 100644 index 0000000..0cfc889 --- /dev/null +++ b/lib/LwIP/port/include/arch/sys_arch.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017 Simon Goldschmidt + * 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 lwIP TCP/IP stack. + * + * Author: Simon Goldschmdit + * + */ +#ifndef LWIP_ARCH_SYS_ARCH_H +#define LWIP_ARCH_SYS_ARCH_H + +#include "lwip/opt.h" +#include "lwip/arch.h" + +/** This is returned by _fromisr() sys functions to tell the outermost function + * that a higher priority task was woken and the scheduler needs to be invoked. + */ +#define ERR_NEED_SCHED 123 + +/* This port includes FreeRTOS headers in sys_arch.c only. + * FreeRTOS uses pointers as object types. We use wrapper structs instead of + * void pointers directly to get a tiny bit of type safety. + */ + +void sys_arch_msleep(u32_t delay_ms); +#define sys_msleep(ms) sys_arch_msleep(ms) + +#if SYS_LIGHTWEIGHT_PROT +typedef u32_t sys_prot_t; +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#if !LWIP_COMPAT_MUTEX +struct _sys_mut { + void *mut; +}; +typedef struct _sys_mut sys_mutex_t; +#define sys_mutex_valid_val(mutex) ((mutex).mut != NULL) +#define sys_mutex_valid(mutex) (((mutex) != NULL) && sys_mutex_valid_val(*(mutex))) +#define sys_mutex_set_invalid(mutex) ((mutex)->mut = NULL) +#endif /* !LWIP_COMPAT_MUTEX */ + +struct _sys_sem { + void *sem; +}; +typedef struct _sys_sem sys_sem_t; +#define sys_sem_valid_val(sema) ((sema).sem != NULL) +#define sys_sem_valid(sema) (((sema) != NULL) && sys_sem_valid_val(*(sema))) +#define sys_sem_set_invalid(sema) ((sema)->sem = NULL) + +struct _sys_mbox { + void *mbx; +}; +typedef struct _sys_mbox sys_mbox_t; +#define sys_mbox_valid_val(mbox) ((mbox).mbx != NULL) +#define sys_mbox_valid(mbox) (((mbox) != NULL) && sys_mbox_valid_val(*(mbox))) +#define sys_mbox_set_invalid(mbox) ((mbox)->mbx = NULL) + +struct _sys_thread { + void *thread_handle; +}; +typedef struct _sys_thread sys_thread_t; + +#if LWIP_NETCONN_SEM_PER_THREAD +sys_sem_t* sys_arch_netconn_sem_get(void); +void sys_arch_netconn_sem_alloc(void); +void sys_arch_netconn_sem_free(void); +#define LWIP_NETCONN_THREAD_SEM_GET() sys_arch_netconn_sem_get() +#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc() +#define LWIP_NETCONN_THREAD_SEM_FREE() sys_arch_netconn_sem_free() +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + +#endif /* LWIP_ARCH_SYS_ARCH_H */ diff --git a/lib/LwIP/port/include/lwipopts.h b/lib/LwIP/port/include/lwipopts.h new file mode 100644 index 0000000..edbfa97 --- /dev/null +++ b/lib/LwIP/port/include/lwipopts.h @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2001-2003 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. 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 lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_LWIPOPTS_H +#define LWIP_LWIPOPTS_H + +#ifdef LWIP_OPTTEST_FILE +#include "lwipopts_test.h" +#else /* LWIP_OPTTEST_FILE */ + +#define LWIP_IPV4 1 +#define LWIP_IPV6 1 + +#define NO_SYS 0 +#define LWIP_SOCKET (NO_SYS==0) +#define LWIP_NETCONN (NO_SYS==0) +#define LWIP_NETIF_API (NO_SYS==0) + +#define LWIP_IGMP LWIP_IPV4 +#define LWIP_ICMP LWIP_IPV4 + +#define LWIP_SNMP LWIP_UDP +#define MIB2_STATS LWIP_SNMP +#ifdef LWIP_HAVE_MBEDTLS +#define LWIP_SNMP_V3 (LWIP_SNMP) +#endif + +#define LWIP_DNS LWIP_UDP +#define LWIP_MDNS_RESPONDER LWIP_UDP + +#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER) + +#define LWIP_HAVE_LOOPIF 1 +#define LWIP_NETIF_LOOPBACK 1 +#define LWIP_LOOPBACK_MAX_PBUFS 10 +#define LWIP_NETIF_HOSTNAME 1 + +#define TCP_LISTEN_BACKLOG 1 + +#define LWIP_COMPAT_SOCKETS 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_RCVBUF 1 + +#define LWIP_TCPIP_CORE_LOCKING 1 + +#define LWIP_NETIF_LINK_CALLBACK 1 +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_EXT_STATUS_CALLBACK 1 + +#define LWIP_DEBUG 1 + + +#ifdef LWIP_DEBUG + +#define LWIP_DBG_MIN_LEVEL 0 +#define PPP_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_OFF +#define AUTOIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_ON +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define IGMP_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT) + + +/* ---------- Memory options ---------- */ +/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which + lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 + byte alignment -> define MEM_ALIGNMENT to 2. */ +/* MSVC port: intel processors don't need 4-byte alignment, + but are faster that way! */ +#define MEM_ALIGNMENT 4U + +/* MEM_SIZE: the size of the heap memory. If the application will send +a lot of data that needs to be copied, this should be set high. */ +#define MEM_SIZE 20480 + +/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application + sends a lot of data out of ROM (or other static memory), this + should be set high. */ +#define MEMP_NUM_PBUF 16 +/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One + per active RAW "connection". */ +#define MEMP_NUM_RAW_PCB 3 +/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + per active UDP "connection". */ +#define MEMP_NUM_UDP_PCB 8 +/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP + connections. */ +#define MEMP_NUM_TCP_PCB 5 +/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP + connections. */ +#define MEMP_NUM_TCP_PCB_LISTEN 8 +/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP + segments. */ +#define MEMP_NUM_TCP_SEG 16 +/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active + timeouts. */ +#define MEMP_NUM_SYS_TIMEOUT 17 + +/* The following four are used only with the sequential API and can be + set to 0 if the application only will use the raw API. */ +/* MEMP_NUM_NETBUF: the number of struct netbufs. */ +#define MEMP_NUM_NETBUF 2 +/* MEMP_NUM_NETCONN: the number of struct netconns. */ +#define MEMP_NUM_NETCONN 12 +/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used + for sequential API communication and incoming packets. Used in + src/api/tcpip.c. */ +#define MEMP_NUM_TCPIP_MSG_API 16 +#define MEMP_NUM_TCPIP_MSG_INPKT 16 + + +/* ---------- Pbuf options ---------- */ +/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ +#define PBUF_POOL_SIZE 128 + +/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +#define PBUF_POOL_BUFSIZE 256 + +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0) + + +/* ---------- TCP options ---------- */ +#define LWIP_TCP 1 +#define TCP_TTL 255 + +#define LWIP_ALTCP (LWIP_TCP) +#ifdef LWIP_HAVE_MBEDTLS +#define LWIP_ALTCP_TLS (LWIP_TCP) +#define LWIP_ALTCP_TLS_MBEDTLS (LWIP_TCP) +#endif + + +/* Controls if TCP should queue segments that arrive out of + order. Define to 0 if your device is low on memory. */ +#define TCP_QUEUE_OOSEQ 1 + +/* TCP Maximum segment size. */ +#define TCP_MSS 1024 + +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF 4096 + +/* TCP sender buffer space (pbufs). This must be at least = 2 * + TCP_SND_BUF/TCP_MSS for things to work. */ +#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS) + +/* TCP writable space (bytes). This must be less than or equal + to TCP_SND_BUF. It is the amount of space which must be + available in the tcp snd_buf for select to return writable */ +#define TCP_SNDLOWAT (TCP_SND_BUF/2) + +/* TCP receive window. */ +#define TCP_WND (10 * 1024) + +/* Maximum number of retransmissions of data segments. */ +#define TCP_MAXRTX 12 + +/* Maximum number of retransmissions of SYN segments. */ +#define TCP_SYNMAXRTX 4 + + +/* ---------- ARP options ---------- */ +#define LWIP_ARP 1 +#define ARP_TABLE_SIZE 10 +#define ARP_QUEUEING 1 + + +/* ---------- IP options ---------- */ +/* Define IP_FORWARD to 1 if you wish to have the ability to forward + IP packets across network interfaces. If you are going to run lwIP + on a device with only one network interface, define this to 0. */ +#define IP_FORWARD 1 + +/* IP reassembly and segmentation.These are orthogonal even + * if they both deal with IP fragments */ +#define IP_REASSEMBLY 1 +#define IP_REASS_MAX_PBUFS (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE)) +#define MEMP_NUM_REASSDATA IP_REASS_MAX_PBUFS +#define IP_FRAG 1 +#define IPV6_FRAG_COPYHEADER 1 + +/* ---------- ICMP options ---------- */ +#define ICMP_TTL 255 + + +/* ---------- DHCP options ---------- */ +/* Define LWIP_DHCP to 1 if you want DHCP configuration of + interfaces. */ +#define LWIP_DHCP LWIP_UDP + +/* 1 if you want to do an ARP check on the offered address + (recommended). */ +#define DHCP_DOES_ARP_CHECK (LWIP_DHCP) + + +/* ---------- AUTOIP options ------- */ +#define LWIP_AUTOIP (LWIP_DHCP) +#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP) + + +/* ---------- UDP options ---------- */ +#define LWIP_UDP 1 +#define LWIP_UDPLITE LWIP_UDP +#define UDP_TTL 255 + + +/* ---------- RAW options ---------- */ +#define LWIP_RAW 1 + + +/* ---------- Statistics options ---------- */ + +#define LWIP_STATS 1 +#define LWIP_STATS_DISPLAY 1 + +#if LWIP_STATS +#define LINK_STATS 1 +#define IP_STATS 1 +#define ICMP_STATS 1 +#define IGMP_STATS 1 +#define IPFRAG_STATS 1 +#define UDP_STATS 1 +#define TCP_STATS 1 +#define MEM_STATS 1 +#define MEMP_STATS 1 +#define PBUF_STATS 1 +#define SYS_STATS 1 +#endif /* LWIP_STATS */ + +/* ---------- NETBIOS options ---------- */ +#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1 + +/* ---------- PPP options ---------- */ + +#define PPP_SUPPORT 1 /* Set > 0 for PPP */ + +#if PPP_SUPPORT + +#define NUM_PPP 1 /* Max PPP sessions. */ + + +/* Select modules to enable. Ideally these would be set in the makefile but + * we're limited by the command line length so you need to modify the settings + * in this file. + */ +#define PPPOE_SUPPORT 1 +#define PPPOS_SUPPORT 1 + +#define PAP_SUPPORT 1 /* Set > 0 for PAP. */ +#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */ +#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */ +#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */ +#define CCP_SUPPORT 0 /* Set > 0 for CCP */ +#define VJ_SUPPORT 0 /* Set > 0 for VJ header compression. */ +#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */ + +#endif /* PPP_SUPPORT */ + +#endif /* LWIP_OPTTEST_FILE */ + +/* The following defines must be done even in OPTTEST mode: */ + +#if !defined(NO_SYS) || !NO_SYS /* default is 0 */ +void sys_check_core_locking(void); +#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking() +#endif + +#ifndef LWIP_PLATFORM_ASSERT +/* Define LWIP_PLATFORM_ASSERT to something to catch missing stdio.h includes */ +void lwip_platform_assert(const char *msg, int line, const char *file); +#define LWIP_PLATFORM_ASSERT(x) lwip_platform_assert(x, __LINE__, __FILE__) +#endif + +/* FreeRTOS related settings */ +#define TCPIP_THREAD_PRIO 15 +#define TCPIP_MBOX_SIZE 32 +#define TCPIP_THREAD_STACKSIZE 1024 + + +#endif /* LWIP_LWIPOPTS_H */ diff --git a/lib/LwIP/port/lwip_helpers.c b/lib/LwIP/port/lwip_helpers.c new file mode 100644 index 0000000..d32a4b2 --- /dev/null +++ b/lib/LwIP/port/lwip_helpers.c @@ -0,0 +1,15 @@ +#include + +#include "fsl_debug_console.h" + +void lwip_platform_assert(const char *msg, int line, const char *file) { + PRINTF("Assertion \"%s\" failed at line %d in %s\r\n", msg, line, file); + for(;;) { + /**/ + } +} + +int lwip_platform_rand(void) { + /* TODO: Use RNG. */ + return rand(); +} diff --git a/lib/LwIP/port/sys_arch.c b/lib/LwIP/port/sys_arch.c new file mode 100644 index 0000000..a8f26f6 --- /dev/null +++ b/lib/LwIP/port/sys_arch.c @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2017 Simon Goldschmidt + * 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 lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "lwip/tcpip.h" +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +/** Set this to 1 if you want the stack size passed to sys_thread_new() to be + * interpreted as number of stack words (FreeRTOS-like). + * Default is that they are interpreted as byte count (lwIP-like). + */ +#ifndef LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS +#define LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS 0 +#endif + +/** Set this to 1 to use a mutex for SYS_ARCH_PROTECT() critical regions. + * Default is 0 and locks interrupts/scheduler for SYS_ARCH_PROTECT(). + */ +#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX +#define LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX 1 +#endif + +/** Set this to 1 to include a sanity check that SYS_ARCH_PROTECT() and + * SYS_ARCH_UNPROTECT() are called matching. + */ +#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK +#define LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK 0 +#endif + +/** Set this to 1 to let sys_mbox_free check that queues are empty when freed */ +#ifndef LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE +#define LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE 0 +#endif + +/** Set this to 1 to enable core locking check functions in this port. + * For this to work, you'll have to define LWIP_ASSERT_CORE_LOCKED() + * and LWIP_MARK_TCPIP_THREAD() correctly in your lwipopts.h! */ +#ifndef LWIP_FREERTOS_CHECK_CORE_LOCKING +#define LWIP_FREERTOS_CHECK_CORE_LOCKING 1 +#endif + +/** Set this to 0 to implement sys_now() yourself, e.g. using a hw timer. + * Default is 1, where FreeRTOS ticks are used to calculate back to ms. + */ +#ifndef LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS +#define LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS 1 +#endif + +#if !configSUPPORT_DYNAMIC_ALLOCATION +# error "lwIP FreeRTOS port requires configSUPPORT_DYNAMIC_ALLOCATION" +#endif +#if !INCLUDE_vTaskDelay +# error "lwIP FreeRTOS port requires INCLUDE_vTaskDelay" +#endif +#if !INCLUDE_vTaskSuspend +# error "lwIP FreeRTOS port requires INCLUDE_vTaskSuspend" +#endif +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX || !LWIP_COMPAT_MUTEX +#if !configUSE_MUTEXES +# error "lwIP FreeRTOS port requires configUSE_MUTEXES" +#endif +#endif + +#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX +static SemaphoreHandle_t sys_arch_protect_mutex; +#endif +#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK +static sys_prot_t sys_arch_protect_nesting; +#endif + +/* Initialize this module (see description in sys.h) */ +void +sys_init(void) +{ +#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + /* initialize sys_arch_protect global mutex */ + sys_arch_protect_mutex = xSemaphoreCreateRecursiveMutex(); + LWIP_ASSERT("failed to create sys_arch_protect mutex", + sys_arch_protect_mutex != NULL); +#endif /* SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ +} + +#if configUSE_16_BIT_TICKS == 1 +#error This port requires 32 bit ticks or timer overflow will fail +#endif + +#if LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS +u32_t +sys_now(void) +{ + return xTaskGetTickCount() * portTICK_PERIOD_MS; +} +#endif + +u32_t +sys_jiffies(void) +{ + return xTaskGetTickCount(); +} + +#if SYS_LIGHTWEIGHT_PROT + +sys_prot_t +sys_arch_protect(void) +{ +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + BaseType_t ret; + LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL); + + ret = xSemaphoreTakeRecursive(sys_arch_protect_mutex, portMAX_DELAY); + LWIP_ASSERT("sys_arch_protect failed to take the mutex", ret == pdTRUE); +#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ + taskENTER_CRITICAL(); +#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK + { + /* every nested call to sys_arch_protect() returns an increased number */ + sys_prot_t ret = sys_arch_protect_nesting; + sys_arch_protect_nesting++; + LWIP_ASSERT("sys_arch_protect overflow", sys_arch_protect_nesting > ret); + return ret; + } +#else + return 1; +#endif +} + +void +sys_arch_unprotect(sys_prot_t pval) +{ +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + BaseType_t ret; +#endif +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK + LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting > 0); + sys_arch_protect_nesting--; + LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting == pval); +#endif + +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL); + + ret = xSemaphoreGiveRecursive(sys_arch_protect_mutex); + LWIP_ASSERT("sys_arch_unprotect failed to give the mutex", ret == pdTRUE); +#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ + taskEXIT_CRITICAL(); +#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ + LWIP_UNUSED_ARG(pval); +} + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +void +sys_arch_msleep(u32_t delay_ms) +{ + TickType_t delay_ticks = pdMS_TO_TICKS(delay_ms); + vTaskDelay(delay_ticks); +} + +#if !LWIP_COMPAT_MUTEX + +/* Create a new mutex*/ +err_t +sys_mutex_new(sys_mutex_t *mutex) +{ + LWIP_ASSERT("mutex != NULL", mutex != NULL); + + mutex->mut = xSemaphoreCreateRecursiveMutex(); + if(mutex->mut == NULL) { + SYS_STATS_INC(mutex.err); + return ERR_MEM; + } + SYS_STATS_INC_USED(mutex); + return ERR_OK; +} + +void +sys_mutex_lock(sys_mutex_t *mutex) +{ + BaseType_t ret; + LWIP_ASSERT("mutex != NULL", mutex != NULL); + LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); + + ret = xSemaphoreTakeRecursive(mutex->mut, portMAX_DELAY); + LWIP_ASSERT("failed to take the mutex", ret == pdTRUE); +} + +void +sys_mutex_unlock(sys_mutex_t *mutex) +{ + BaseType_t ret; + LWIP_ASSERT("mutex != NULL", mutex != NULL); + LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); + + ret = xSemaphoreGiveRecursive(mutex->mut); + LWIP_ASSERT("failed to give the mutex", ret == pdTRUE); +} + +void +sys_mutex_free(sys_mutex_t *mutex) +{ + LWIP_ASSERT("mutex != NULL", mutex != NULL); + LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); + + SYS_STATS_DEC(mutex.used); + vSemaphoreDelete(mutex->mut); + mutex->mut = NULL; +} + +#endif /* !LWIP_COMPAT_MUTEX */ + +err_t +sys_sem_new(sys_sem_t *sem, u8_t initial_count) +{ + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("initial_count invalid (not 0 or 1)", + (initial_count == 0) || (initial_count == 1)); + + sem->sem = xSemaphoreCreateBinary(); + if(sem->sem == NULL) { + SYS_STATS_INC(sem.err); + return ERR_MEM; + } + SYS_STATS_INC_USED(sem); + + if(initial_count == 1) { + BaseType_t ret = xSemaphoreGive(sem->sem); + LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE); + } + return ERR_OK; +} + +void +sys_sem_signal(sys_sem_t *sem) +{ + BaseType_t ret; + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); + + ret = xSemaphoreGive(sem->sem); + /* queue full is OK, this is a signal only... */ + LWIP_ASSERT("sys_sem_signal: sane return value", + (ret == pdTRUE) || (ret == errQUEUE_FULL)); +} + +u32_t +sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms) +{ + BaseType_t ret; + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); + + if(!timeout_ms) { + /* wait infinite */ + ret = xSemaphoreTake(sem->sem, portMAX_DELAY); + LWIP_ASSERT("taking semaphore failed", ret == pdTRUE); + } else { + TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms); + ret = xSemaphoreTake(sem->sem, timeout_ticks); + if (ret == errQUEUE_EMPTY) { + /* timed out */ + return SYS_ARCH_TIMEOUT; + } + LWIP_ASSERT("taking semaphore failed", ret == pdTRUE); + } + + /* Old versions of lwIP required us to return the time waited. + This is not the case any more. Just returning != SYS_ARCH_TIMEOUT + here is enough. */ + return 1; +} + +void +sys_sem_free(sys_sem_t *sem) +{ + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); + + SYS_STATS_DEC(sem.used); + vSemaphoreDelete(sem->sem); + sem->sem = NULL; +} + +err_t +sys_mbox_new(sys_mbox_t *mbox, int size) +{ + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("size > 0", size > 0); + + mbox->mbx = xQueueCreate((UBaseType_t)size, sizeof(void *)); + if(mbox->mbx == NULL) { + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } + SYS_STATS_INC_USED(mbox); + return ERR_OK; +} + +void +sys_mbox_post(sys_mbox_t *mbox, void *msg) +{ + BaseType_t ret; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + ret = xQueueSendToBack(mbox->mbx, &msg, portMAX_DELAY); + LWIP_ASSERT("mbox post failed", ret == pdTRUE); +} + +err_t +sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + BaseType_t ret; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + ret = xQueueSendToBack(mbox->mbx, &msg, 0); + if (ret == pdTRUE) { + return ERR_OK; + } else { + LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL); + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } +} + +err_t +sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg) +{ + BaseType_t ret; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + ret = xQueueSendToBackFromISR(mbox->mbx, &msg, &xHigherPriorityTaskWoken); + if (ret == pdTRUE) { + if (xHigherPriorityTaskWoken == pdTRUE) { + return ERR_NEED_SCHED; + } + return ERR_OK; + } else { + LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL); + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } +} + +u32_t +sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout_ms) +{ + BaseType_t ret; + void *msg_dummy; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + if (!msg) { + msg = &msg_dummy; + } + + if (!timeout_ms) { + /* wait infinite */ + ret = xQueueReceive(mbox->mbx, &(*msg), portMAX_DELAY); + LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + } else { + TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms); + ret = xQueueReceive(mbox->mbx, &(*msg), timeout_ticks); + if (ret == errQUEUE_EMPTY) { + /* timed out */ + *msg = NULL; + return SYS_ARCH_TIMEOUT; + } + LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + } + + /* Old versions of lwIP required us to return the time waited. + This is not the case any more. Just returning != SYS_ARCH_TIMEOUT + here is enough. */ + return 1; +} + +u32_t +sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ + BaseType_t ret; + void *msg_dummy; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + if (!msg) { + msg = &msg_dummy; + } + + ret = xQueueReceive(mbox->mbx, &(*msg), 0); + if (ret == errQUEUE_EMPTY) { + *msg = NULL; + return SYS_MBOX_EMPTY; + } + LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + + return 0; +} + +void +sys_mbox_free(sys_mbox_t *mbox) +{ + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + +#if LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE + { + UBaseType_t msgs_waiting = uxQueueMessagesWaiting(mbox->mbx); + LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0); + + if (msgs_waiting != 0) { + SYS_STATS_INC(mbox.err); + } + } +#endif + + vQueueDelete(mbox->mbx); + + SYS_STATS_DEC(mbox.used); +} + +sys_thread_t +sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) +{ + TaskHandle_t rtos_task; + BaseType_t ret; + sys_thread_t lwip_thread; + size_t rtos_stacksize; + + LWIP_ASSERT("invalid stacksize", stacksize > 0); +#if LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS + rtos_stacksize = (size_t)stacksize; +#else + rtos_stacksize = (size_t)stacksize / sizeof(StackType_t); +#endif + + /* lwIP's lwip_thread_fn matches FreeRTOS' TaskFunction_t, so we can pass the + thread function without adaption here. */ + ret = xTaskCreate(thread, name, (configSTACK_DEPTH_TYPE)rtos_stacksize, arg, prio, &rtos_task); + LWIP_ASSERT("task creation failed", ret == pdTRUE); + + lwip_thread.thread_handle = rtos_task; + return lwip_thread; +} + +#if LWIP_NETCONN_SEM_PER_THREAD +#if configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 + +sys_sem_t * +sys_arch_netconn_sem_get(void) +{ + void* ret; + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + LWIP_ASSERT("task != NULL", task != NULL); + + ret = pvTaskGetThreadLocalStoragePointer(task, 0); + return ret; +} + +void +sys_arch_netconn_sem_alloc(void) +{ + void *ret; + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + LWIP_ASSERT("task != NULL", task != NULL); + + ret = pvTaskGetThreadLocalStoragePointer(task, 0); + if(ret == NULL) { + sys_sem_t *sem; + err_t err; + /* need to allocate the memory for this semaphore */ + sem = mem_malloc(sizeof(sys_sem_t)); + LWIP_ASSERT("sem != NULL", sem != NULL); + err = sys_sem_new(sem, 0); + LWIP_ASSERT("err == ERR_OK", err == ERR_OK); + LWIP_ASSERT("sem invalid", sys_sem_valid(sem)); + vTaskSetThreadLocalStoragePointer(task, 0, sem); + } +} + +void sys_arch_netconn_sem_free(void) +{ + void* ret; + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + LWIP_ASSERT("task != NULL", task != NULL); + + ret = pvTaskGetThreadLocalStoragePointer(task, 0); + if(ret != NULL) { + sys_sem_t *sem = ret; + sys_sem_free(sem); + mem_free(sem); + vTaskSetThreadLocalStoragePointer(task, 0, NULL); + } +} + +#else /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */ +#error LWIP_NETCONN_SEM_PER_THREAD needs configNUM_THREAD_LOCAL_STORAGE_POINTERS +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */ + +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + +#if LWIP_FREERTOS_CHECK_CORE_LOCKING +#if LWIP_TCPIP_CORE_LOCKING + +/** Flag the core lock held. A counter for recursive locks. */ +static u8_t lwip_core_lock_count; +static TaskHandle_t lwip_core_lock_holder_thread; + +void +sys_lock_tcpip_core(void) +{ + sys_mutex_lock(&lock_tcpip_core); + if (lwip_core_lock_count == 0) { + lwip_core_lock_holder_thread = xTaskGetCurrentTaskHandle(); + } + lwip_core_lock_count++; +} + +void +sys_unlock_tcpip_core(void) +{ + lwip_core_lock_count--; + if (lwip_core_lock_count == 0) { + lwip_core_lock_holder_thread = 0; + } + sys_mutex_unlock(&lock_tcpip_core); +} + +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +#if !NO_SYS +static TaskHandle_t lwip_tcpip_thread; +#endif + +void +sys_mark_tcpip_thread(void) +{ +#if !NO_SYS + lwip_tcpip_thread = xTaskGetCurrentTaskHandle(); +#endif +} + +void +sys_check_core_locking(void) +{ + /* Embedded systems should check we are NOT in an interrupt context here */ + /* E.g. core Cortex-M3/M4 ports: + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + + Instead, we use more generic FreeRTOS functions here, which should fail from ISR: */ + taskENTER_CRITICAL(); + taskEXIT_CRITICAL(); + +#if !NO_SYS + if (lwip_tcpip_thread != 0) { + TaskHandle_t current_thread = xTaskGetCurrentTaskHandle(); + +#if LWIP_TCPIP_CORE_LOCKING + LWIP_ASSERT("Function called without core lock", + current_thread == lwip_core_lock_holder_thread && lwip_core_lock_count > 0); +#else /* LWIP_TCPIP_CORE_LOCKING */ + LWIP_ASSERT("Function called from wrong thread", current_thread == lwip_tcpip_thread); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + } +#endif /* !NO_SYS */ +} + +#endif /* LWIP_FREERTOS_CHECK_CORE_LOCKING*/ diff --git a/lib/MbedTLS/CMakeLists.txt b/lib/MbedTLS/CMakeLists.txt new file mode 100644 index 0000000..0706a78 --- /dev/null +++ b/lib/MbedTLS/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) + +project(kinetis_mbedtls) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMBEDTLS_CONFIG_FILE='\"kinetis_mbedtls_config.h\"' -I${CMAKE_CURRENT_LIST_DIR}/include") +add_subdirectory(mbedtls) diff --git a/lib/MbedTLS/include/kinetis_mbedtls_config.h b/lib/MbedTLS/include/kinetis_mbedtls_config.h new file mode 100644 index 0000000..9dd8edf --- /dev/null +++ b/lib/MbedTLS/include/kinetis_mbedtls_config.h @@ -0,0 +1,86 @@ +/** + * \file kinetis_mbedtls_config.h + * + * \brief Minimal configuration of features for Kinetis K60 platform + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Minimal configuration of features that do not require an entropy source + * Distinguishing reatures: + * - no entropy module + * - no TLS protocol implementation available due to absence of an entropy + * source + * + * See README.txt for usage instructions. + */ + +/* System support */ +#define MBEDTLS_HAVE_ASM +#define MBEDTLS_HAVE_TIME + +/* mbed TLS feature support */ +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_PK_RSA_ALT_SUPPORT +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_PKCS1_V21 +#define MBEDTLS_SELF_TEST +#define MBEDTLS_VERSION_FEATURES + +/* mbed TLS modules */ +#define MBEDTLS_AES_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CCM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ERROR_C +#define MBEDTLS_GCM_C +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_MD_C +#define MBEDTLS_OID_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_RSA_C +/* The library does not currently support enabling SHA-224 without SHA-256. + * A future version of the library will have this option disabled + * by default. */ +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA224_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA384_C +#define MBEDTLS_SHA512_C +#define MBEDTLS_VERSION_C +#define MBEDTLS_X509_USE_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_CRL_PARSE_C +//#define MBEDTLS_CMAC_C + +/* Miscellaneous options */ +#define MBEDTLS_AES_ROM_TABLES diff --git a/src/ethernetif.c b/src/ethernetif.c new file mode 100644 index 0000000..dd21d2e --- /dev/null +++ b/src/ethernetif.c @@ -0,0 +1,1077 @@ +/* + * Copyright (c) 2001-2004 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. 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 lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 SDRVL THE COPYRIGHT HOLDER 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. + */ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/ethip6.h" +#include "netif/etharp.h" +#include "netif/ppp/pppoe.h" +#include "lwip/igmp.h" +#include "lwip/mld6.h" + +#define USE_RTOS 1 +#define FSL_RTOS_FREE_RTOS 1 + +#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 100000000 + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) +#include "FreeRTOS.h" +#include "event_groups.h" +#include "task.h" +#endif + +#include "ethernetif.h" + +#include "fsl_enet.h" +#include "fsl_phy.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +#define ENET_ALIGN(x) \ + ((unsigned int)((x) + ((ENET_BUFF_ALIGNMENT)-1)) & (unsigned int)(~(unsigned int)((ENET_BUFF_ALIGNMENT)-1))) + +#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) +#define kENET_RxEvent kENET_RxIntEvent +#define kENET_TxEvent kENET_TxIntEvent +#endif + +/** + * Helper struct to hold private data used to operate your ethernet interface. + */ +struct ethernetif +{ + ENET_Type *base; +#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)) || \ + (USE_RTOS && defined(FSL_RTOS_FREE_RTOS)) + enet_handle_t handle; +#endif + uint32_t phyAddr; +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + EventGroupHandle_t enetTransmitAccessEvent; + TaskHandle_t rxTaskHandle; + EventBits_t txFlag; +#endif + uint8_t RxBuffDescrip[ENET_RXBD_NUM * sizeof(enet_rx_bd_struct_t) + ENET_BUFF_ALIGNMENT]; + uint8_t TxBuffDescrip[ENET_TXBD_NUM * sizeof(enet_tx_bd_struct_t) + ENET_BUFF_ALIGNMENT]; + uint8_t RxDataBuff[ENET_RXBD_NUM * ENET_ALIGN(ENET_RXBUFF_SIZE) + ENET_BUFF_ALIGNMENT]; + uint8_t TxDataBuff[ENET_TXBD_NUM * ENET_ALIGN(ENET_TXBUFF_SIZE) + ENET_BUFF_ALIGNMENT]; +#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) + uint8_t txIdx; +#if !(USE_RTOS && defined(FSL_RTOS_FREE_RTOS)) + uint8_t rxIdx; +#endif +#endif +}; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +static struct ethernetif ethernetif_0; + +/******************************************************************************* + * Code + ******************************************************************************/ +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) +#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) +static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param) +#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) +static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, uint8_t channel, void *param) +#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ +{ + struct netif *netif = (struct netif *)param; + struct ethernetif *ethernetif = netif->state; + + BaseType_t xHigherPriorityTaskWoken = 0U; + + switch (event) + { + case kENET_RxEvent: + { + if(__get_IPSR()) + { + xTaskNotifyFromISR(ethernetif->rxTaskHandle, 0x1UL, eSetBits, &xHigherPriorityTaskWoken); + } + else + { + xTaskNotify(ethernetif->rxTaskHandle, 0x1UL, eSetBits); + } + break; + } + case kENET_TxEvent: + { + if (__get_IPSR()) + { + xEventGroupSetBitsFromISR(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, &xHigherPriorityTaskWoken); + } + else + { + xEventGroupSetBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag); + } + } + break; + default: + break; + } + if(__get_IPSR()) + { + if (pdTRUE == xHigherPriorityTaskWoken) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } +} +#endif + +#if LWIP_IPV4 && LWIP_IGMP +static err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, u8_t action) +{ + struct ethernetif *ethernetif = netif->state; + uint8_t multicastMacAddr[6]; + err_t result; + + multicastMacAddr[0] = 0x01U; + multicastMacAddr[1] = 0x00U; + multicastMacAddr[2] = 0x5EU; + multicastMacAddr[3] = (group->addr >> 8) & 0x7FU; + multicastMacAddr[4] = (group->addr >> 16) & 0xFFU; + multicastMacAddr[5] = (group->addr >> 24) & 0xFFU; + + switch (action) + { + case IGMP_ADD_MAC_FILTER: + /* Adds the ENET device to a multicast group.*/ + ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); + result = ERR_OK; + break; + case IGMP_DEL_MAC_FILTER: +/* Moves the ENET device from a multicast group.*/ +#if 0 + ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); +#endif + result = ERR_OK; + break; + default: + result = ERR_IF; + break; + } + + return result; +} +#endif + +#if LWIP_IPV6 && LWIP_IPV6_MLD +static err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group, enum netif_mac_filter_action action) +{ + struct ethernetif *ethernetif = netif->state; + uint8_t multicastMacAddr[6]; + err_t result; + + multicastMacAddr[0] = 0x33U; + multicastMacAddr[1] = 0x33U; + multicastMacAddr[2] = (group->addr[3]) & 0xFFU; + multicastMacAddr[3] = (group->addr[3] >> 8) & 0xFFU; + multicastMacAddr[4] = (group->addr[3] >> 16) & 0xFFU; + multicastMacAddr[5] = (group->addr[3] >> 24) & 0xFFU; + + switch (action) + { + case NETIF_ADD_MAC_FILTER: + /* Adds the ENET device to a multicast group.*/ + ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); + result = ERR_OK; + break; + case NETIF_DEL_MAC_FILTER: +/* Moves the ENET device from a multicast group.*/ +#if 0 + ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); +#endif + result = ERR_OK; + break; + default: + result = ERR_IF; + break; + } + + return result; +} +#endif + +#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) +static inline enet_rx_bd_struct_t *get_rx_desc(struct ethernetif *ethernetif, uint32_t index) +{ + return (enet_rx_bd_struct_t *)ENET_ALIGN(ðernetif->RxBuffDescrip[index * sizeof(enet_rx_bd_struct_t)]); +} + +static inline enet_tx_bd_struct_t *get_tx_desc(struct ethernetif *ethernetif, uint32_t index) +{ + return (enet_tx_bd_struct_t *)ENET_ALIGN(ðernetif->TxBuffDescrip[index * sizeof(enet_tx_bd_struct_t)]); +} +#endif + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) +static void enet_rx_task(void *params) { + struct netif *netif = params; + uint32_t ulNotifyValue = 0U; + + for(;;) { + xTaskNotifyWait(0UL, 0xFFFFFFFFUL, &ulNotifyValue, portMAX_DELAY); + ethernetif_input(netif); + } +} +#endif + +/** + * Initializes ENET driver. + */ +#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) +static void enet_init(struct netif *netif, struct ethernetif *ethernetif) +{ + enet_config_t config; + uint32_t sysClock; + bool link = false; + phy_speed_t speed; + phy_duplex_t duplex; + uint32_t count = 0; + enet_buffer_config_t buffCfg; + + /* prepare the buffer configuration. */ + buffCfg.rxBdNumber = ENET_RXBD_NUM; /* Receive buffer descriptor number. */ + buffCfg.txBdNumber = ENET_TXBD_NUM; /* Transmit buffer descriptor number. */ + buffCfg.rxBuffSizeAlign = ENET_ALIGN(ENET_RXBUFF_SIZE); /* Aligned receive data buffer size. */ + buffCfg.txBuffSizeAlign = ENET_ALIGN(ENET_TXBUFF_SIZE); /* Aligned transmit data buffer size. */ + buffCfg.rxBdStartAddrAlign = (enet_rx_bd_struct_t *)ENET_ALIGN( + ethernetif->RxBuffDescrip); /* Aligned receive buffer descriptor start address. */ + buffCfg.txBdStartAddrAlign = (enet_tx_bd_struct_t *)ENET_ALIGN( + ethernetif->TxBuffDescrip); /* Aligned transmit buffer descriptor start address. */ + buffCfg.rxBufferAlign = (uint8_t *)ENET_ALIGN(ethernetif->RxDataBuff); /* Receive data buffer start address. */ + buffCfg.txBufferAlign = (uint8_t *)ENET_ALIGN(ethernetif->TxDataBuff); /* Transmit data buffer start address. */ + + sysClock = CLOCK_GetFreq(kCLOCK_CoreSysClk); + + ENET_GetDefaultConfig(&config); + + PHY_Init(ethernetif->base, ethernetif->phyAddr, sysClock); + + while ((count < ENET_ATONEGOTIATION_TIMEOUT) && (!link)) + { + PHY_GetLinkStatus(ethernetif->base, ethernetif->phyAddr, &link); + + if (link) + { + /* Get the actual PHY link speed. */ + PHY_GetLinkSpeedDuplex(ethernetif->base, ethernetif->phyAddr, &speed, &duplex); + /* Change the MII speed and duplex for actual link status. */ + config.miiSpeed = (enet_mii_speed_t)speed; + config.miiDuplex = (enet_mii_duplex_t)duplex; + } + + count++; + } + +#if 0 /* Disable assert. If initial auto-negation is timeout, \ \ + the ENET set to default 100Mbs and full-duplex.*/ + if (count == ENET_ATONEGOTIATION_TIMEOUT) + { + LWIP_ASSERT("\r\nPHY Link down, please check the cable connection.\r\n", 0); + } +#endif + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + /* Create the Event for transmit busy release trigger. */ + ethernetif->enetTransmitAccessEvent = xEventGroupCreate(); + ethernetif->txFlag = 0x1; + + config.interrupt |= kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt; + + NVIC_SetPriority(ENET_Receive_IRQn, ENET_PRIORITY); + NVIC_SetPriority(ENET_Transmit_IRQn, ENET_PRIORITY); +#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE + NVIC_SetPriority(ENET_1588_Timer_IRQn, ENET_1588_PRIORITY); +#endif +#endif /* USE_RTOS */ + + /* Initialize the ENET module.*/ + ENET_Init(ethernetif->base, ðernetif->handle, &config, &buffCfg, netif->hwaddr, sysClock); + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + xTaskCreate(enet_rx_task, "enet_rx_task", 1024, netif, 16, ðernetif->rxTaskHandle); + + ENET_SetCallback(ðernetif->handle, ethernet_callback, netif); +#endif + + ENET_ActiveRead(ethernetif->base); +} +#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) +static void enet_init(struct netif *netif, struct ethernetif *ethernetif) +{ + enet_config_t config; + uint32_t sysClock; + bool link = false; + phy_speed_t speed; + phy_duplex_t duplex; + uint32_t count = 0; + enet_buffer_config_t buffCfg; + uint32_t rxBufferStartAddr[ENET_RXBD_NUM]; + uint32_t i; + + /* calculate start addresses of all rx buffers */ + for (i = 0; i < ENET_RXBD_NUM; i++) + { + rxBufferStartAddr[i] = ENET_ALIGN(ðernetif->RxDataBuff[i * ENET_ALIGN(ENET_RXBUFF_SIZE)]); + } + + /* prepare the buffer configuration. */ + buffCfg.rxRingLen = ENET_RXBD_NUM; /* The length of receive buffer descriptor ring. */ + buffCfg.txRingLen = ENET_TXBD_NUM; /* The length of transmit buffer descriptor ring. */ + buffCfg.txDescStartAddrAlign = get_tx_desc(ethernetif, 0U); /* Aligned transmit descriptor start address. */ + buffCfg.txDescTailAddrAlign = get_tx_desc(ethernetif, 0U); /* Aligned transmit descriptor tail address. */ + buffCfg.rxDescStartAddrAlign = get_rx_desc(ethernetif, 0U); /* Aligned receive descriptor start address. */ + buffCfg.rxDescTailAddrAlign = get_rx_desc(ethernetif, ENET_RXBD_NUM); /* Aligned receive descriptor tail address. */ + buffCfg.rxBufferStartAddr = rxBufferStartAddr; /* Start addresses of the rx buffers. */ + buffCfg.rxBuffSizeAlign = ENET_ALIGN(ENET_RXBUFF_SIZE); /* Aligned receive data buffer size. */ + + sysClock = CLOCK_GetFreq(kCLOCK_CoreSysClk); + + ENET_GetDefaultConfig(&config); + + PHY_Init(ethernetif->base, ethernetif->phyAddr, 0); + + while ((count < ENET_ATONEGOTIATION_TIMEOUT) && (!link)) + { + PHY_GetLinkStatus(ethernetif->base, ethernetif->phyAddr, &link); + if (link) + { + /* Get the actual PHY link speed. */ + PHY_GetLinkSpeedDuplex(ethernetif->base, ethernetif->phyAddr, &speed, &duplex); + /* Change the MII speed and duplex for actual link status. */ + config.miiSpeed = (enet_mii_speed_t)speed; + config.miiDuplex = (enet_mii_duplex_t)duplex; + } + + count++; + } + +#if 0 /* Disable assert. If initial auto-negation is timeout, \ \ + the ENET set to default 100Mbs and full-duplex.*/ + if (count == ENET_ATONEGOTIATION_TIMEOUT) + { + LWIP_ASSERT("\r\nPHY Link down, please check the cable connection.\r\n", 0); + } +#endif + +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + /* Create the Event for transmit busy release trigger. */ + ethernetif->enetTransmitAccessEvent = xEventGroupCreate(); + ethernetif->txFlag = 0x1; + + NVIC_SetPriority(ETHERNET_IRQn, ENET_PRIORITY); +#else + ethernetif->rxIdx = 0U; +#endif /* USE_RTOS */ + + ethernetif->txIdx = 0U; + + ENET_Init(ethernetif->base, &config, netif->hwaddr, sysClock); + +/* Create the handler. */ +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + ENET_EnableInterrupts(ethernetif->base, kENET_DmaTx | kENET_DmaRx); + ENET_CreateHandler(ethernetif->base, ðernetif->handle, &config, &buffCfg, ethernet_callback, netif); +#endif + + ENET_DescriptorInit(ethernetif->base, &config, &buffCfg); + + /* Active TX/RX. */ + ENET_StartRxTx(ethernetif->base, 1, 1); +} +#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void low_level_init(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = configMAC_ADDR0; + netif->hwaddr[1] = configMAC_ADDR1; + netif->hwaddr[2] = configMAC_ADDR2; + netif->hwaddr[3] = configMAC_ADDR3; + netif->hwaddr[4] = configMAC_ADDR4; + netif->hwaddr[5] = configMAC_ADDR5; + + /* maximum transfer unit */ + netif->mtu = 1500; /* TODO: define a config */ + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + /* ENET driver initialization.*/ + enet_init(netif, ethernetif); + +#if LWIP_IPV6 && LWIP_IPV6_MLD + /* + * For hardware/netifs that implement MAC filtering. + * All-nodes link-local is handled by default, so we must let the hardware know + * to allow multicast packets in. + * Should set mld_mac_filter previously. */ + if (netif->mld_mac_filter != NULL) + { + ip6_addr_t ip6_allnodes_ll; + ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); + netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); + } +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +} + +/** + * Returns next buffer for TX. + * Can wait if no buffer available. + */ +static unsigned char *enet_get_tx_buffer(struct ethernetif *ethernetif) +{ +#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) + { + static unsigned char ucBuffer[ENET_FRAME_MAX_FRAMELEN]; + return ucBuffer; + } +#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) + { + enet_tx_bd_struct_t *txBuffDesc = get_tx_desc(ethernetif, ethernetif->txIdx); +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + while (1) + { + if (ENET_IsTxDescriptorDmaOwn(txBuffDesc)) + { + xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false, + portMAX_DELAY); + } + else + { + break; + } + } +#else + { + uint32_t counter; + + for (counter = ENET_TIMEOUT; counter != 0U; counter--) + { + if (!ENET_IsTxDescriptorDmaOwn(txBuffDesc)) + { + break; + } + } + + if (counter == 0U) + { + return (unsigned char *)NULL; + } + } +#endif + return (unsigned char *)ENET_ALIGN(ethernetif->TxDataBuff + (ethernetif->txIdx * ENET_ALIGN(ENET_TXBUFF_SIZE))); + } +#endif +} + +/** + * Sends frame via ENET. + */ +static err_t enet_send_frame(struct ethernetif *ethernetif, unsigned char *data, const uint32_t length) +{ +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + { + status_t result; + + do + { + result = ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length); + + if (result == kStatus_ENET_TxFrameBusy) + { + xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false, + portMAX_DELAY); + } + + } while (result == kStatus_ENET_TxFrameBusy); + return ERR_OK; + } +#elif defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) + { + uint32_t counter; + + for (counter = ENET_TIMEOUT; counter != 0U; counter--) + { + if (ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length) != kStatus_ENET_TxFrameBusy) + { + return ERR_OK; + } + } + + return ERR_TIMEOUT; + } +#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) + { + uint32_t tail; + enet_tx_bd_struct_t *txBuffDesc = get_tx_desc(ethernetif, ethernetif->txIdx); + + ENET_SetupTxDescriptor(txBuffDesc, data, length, NULL, 0U, length, false, false, kENET_FirstLastFlag, 0U); + ethernetif->txIdx = (ethernetif->txIdx + 1U) % ENET_TXBD_NUM; + + /* Update the transmit tail address. */ + if (ethernetif->txIdx == 0U) + { + tail = (uint32_t)get_tx_desc(ethernetif, ENET_TXBD_NUM); + } + else + { + tail = (uint32_t)get_tx_desc(ethernetif, ethernetif->txIdx); + } + ENET_UpdateTxDescriptorTail(ethernetif->base, 0U, tail); + + return ERR_OK; + } +#endif +} + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + err_t result; + struct ethernetif *ethernetif = netif->state; + struct pbuf *q; + unsigned char *pucBuffer; + unsigned char *pucChar; + + LWIP_ASSERT("Output packet buffer empty", p); + + pucBuffer = enet_get_tx_buffer(ethernetif); + if (pucBuffer == NULL) + { + return ERR_BUF; + } + +/* Initiate transfer. */ + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + if (p->len == p->tot_len) + { +#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) + /* No pbuf chain, don't have to copy -> faster. */ + pucBuffer = (unsigned char *)p->payload; +#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) + /* No pbuf chain, still have to copy as pbuf could be reclaimed early. */ + memcpy(pucBuffer, p->payload, p->len); +#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ + } + else + { + /* pbuf chain, copy into contiguous ucBuffer. */ + if (p->tot_len >= ENET_FRAME_MAX_FRAMELEN) + { + return ERR_BUF; + } + else + { + pucChar = pucBuffer; + + for (q = p; q != NULL; q = q->next) + { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + /* send data from(q->payload, q->len); */ + if (q == p) + { + memcpy(pucChar, q->payload, q->len); + pucChar += q->len; + } + else + { + memcpy(pucChar, q->payload, q->len); + pucChar += q->len; + } + } + } + } + + /* Send frame. */ + result = enet_send_frame(ethernetif, pucBuffer, p->tot_len); + + MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); + if (((u8_t *)p->payload)[0] & 1) + { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); + } + else + { + /* unicast packet */ + MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); + } +/* increase ifoutdiscards or ifouterrors on error */ + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return result; +} + +/** + * Gets the length of received frame (if any). + */ +static status_t enet_get_rx_frame_size(struct ethernetif *ethernetif, uint32_t *length) +{ +#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) + { + return ENET_GetRxFrameSize(ðernetif->handle, length); + } +#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + { + return ENET_GetRxFrameSize(ethernetif->base, ðernetif->handle, length, 0U); + } +#else + { + uint8_t index = ethernetif->rxIdx; + enet_rx_bd_struct_t *rxDesc = get_rx_desc(ethernetif, index); + uint32_t rxControl = ENET_GetRxDescriptor(rxDesc); + + /* Reset the length to zero. */ + *length = 0; + + if (rxControl & ENET_RXDESCRIP_WR_OWN_MASK) + { + return kStatus_ENET_RxFrameEmpty; + } + else + { + do + { + /* Application owns the buffer descriptor, get the length. */ + if (rxControl & ENET_RXDESCRIP_WR_LD_MASK) + { + if (rxControl & ENET_RXDESCRIP_WR_ERRSUM_MASK) + { + return kStatus_ENET_RxFrameError; + } + else + { + *length = rxControl & ENET_RXDESCRIP_WR_PACKETLEN_MASK; + return kStatus_Success; + } + } + + index = (index + 1U) % ENET_RXBD_NUM; + rxDesc = get_rx_desc(ethernetif, index); + rxControl = ENET_GetRxDescriptor(rxDesc); + } while (index != ethernetif->rxIdx); + + return kStatus_ENET_RxFrameError; + } + } +#endif +#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ +} + +/** + * Reads frame from ENET. + */ +static void enet_read_frame(struct ethernetif *ethernetif, uint8_t *data, uint32_t length) +{ +#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) + { + ENET_ReadFrame(ethernetif->base, ðernetif->handle, data, length); + } +#elif defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) +#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) + { + ENET_ReadFrame(ethernetif->base, ðernetif->handle, data, length, 0U); + } +#else + { + enet_rx_bd_struct_t *rxDesc; + uint8_t index = ethernetif->rxIdx; + uint32_t rxControl; + bool isLastBuff = false; + uint32_t len = 0; + uint32_t offset = 0; + + if (!data) + { + do + { + rxDesc = get_rx_desc(ethernetif, ethernetif->rxIdx); + ethernetif->rxIdx = (ethernetif->rxIdx + 1U) % ENET_RXBD_NUM; + rxControl = ENET_GetRxDescriptor(rxDesc); + + /* Update the receive buffer descriptor. */ + ENET_UpdateRxDescriptor(rxDesc, NULL, NULL, false, false); + + /* Find the last buffer descriptor for the frame. */ + if (rxControl & ENET_RXDESCRIP_WR_LD_MASK) + { + break; + } + } while (ethernetif->rxIdx != index); + } + else + { + while (!isLastBuff) + { + rxDesc = get_rx_desc(ethernetif, ethernetif->rxIdx); + ethernetif->rxIdx = (ethernetif->rxIdx + 1U) % ENET_RXBD_NUM; + rxControl = ENET_GetRxDescriptor(rxDesc); + + if (rxControl & ENET_RXDESCRIP_WR_LD_MASK) + { + /* This is a valid frame. */ + isLastBuff = true; + if (length == (rxControl & ENET_RXDESCRIP_WR_PACKETLEN_MASK)) + { + /* Copy the frame to user's buffer. */ + len = (rxControl & ENET_RXDESCRIP_WR_PACKETLEN_MASK) - offset; + if (len > ENET_ALIGN(ENET_RXBUFF_SIZE)) + { + memcpy(data + offset, (void *)rxDesc->buff1Addr, ENET_ALIGN(ENET_RXBUFF_SIZE)); + offset += ENET_ALIGN(ENET_RXBUFF_SIZE); + memcpy(data + offset, (void *)rxDesc->buff2Addr, len - ENET_ALIGN(ENET_RXBUFF_SIZE)); + } + else + { + memcpy(data + offset, (void *)rxDesc->buff1Addr, len); + } + } + + /* Update the receive buffer descriptor. */ + ENET_UpdateRxDescriptor(rxDesc, NULL, NULL, false, false); + } + else + { + /* Store a frame on several buffer descriptors. */ + isLastBuff = false; + /* Length check. */ + if (offset >= length) + { + /* Updates the receive buffer descriptors. */ + ENET_UpdateRxDescriptor(rxDesc, NULL, NULL, false, false); + break; + } + + memcpy(data + offset, (void *)rxDesc->buff1Addr, ENET_ALIGN(ENET_RXBUFF_SIZE)); + offset += ENET_ALIGN(ENET_RXBUFF_SIZE); + + /* Update the receive buffer descriptor. */ + ENET_UpdateRxDescriptor(rxDesc, NULL, NULL, false, false); + } + } + } + + ENET_UpdateRxDescriptorTail(ethernetif->base, 0U, (uint32_t)get_rx_desc(ethernetif, ENET_RXBD_NUM)); + } +#endif /* USE_RTOS */ +#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf *low_level_input(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *p = NULL; + struct pbuf *q; + uint32_t len; + status_t status; + + /* Obtain the size of the packet and put it into the "len" + variable. */ + status = enet_get_rx_frame_size(ethernetif, &len); + + if (kStatus_ENET_RxFrameEmpty != status) + { + /* Call enet_read_frame when there is a received frame. */ + if (len != 0) + { +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) + { +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + if (p->next == 0) /* One-chain buffer.*/ + { + enet_read_frame(ethernetif, p->payload, p->len); + } + else /* Multi-chain buffer.*/ + { + uint8_t data_tmp[ENET_FRAME_MAX_FRAMELEN]; + uint32_t data_tmp_len = 0; + + enet_read_frame(ethernetif, data_tmp, p->tot_len); + + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. */ + for (q = p; (q != NULL) && ((data_tmp_len + q->len) <= sizeof(data_tmp)); q = q->next) + { + /* Read enough bytes to fill this pbuf in the chain. The + * available data in the pbuf is given by the q->len + * variable. */ + memcpy(q->payload, &data_tmp[data_tmp_len], q->len); + data_tmp_len += q->len; + } + } + + MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); + if (((u8_t *)p->payload)[0] & 1) + { + /* broadcast or multicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); + } + else + { + /* unicast packet*/ + MIB2_STATS_NETIF_INC(netif, ifinucastpkts); + } +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.recv); + } + else + { + /* drop packet*/ + enet_read_frame(ethernetif, NULL, 0U); + + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Fail to allocate new memory space\n")); + + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + MIB2_STATS_NETIF_INC(netif, ifindiscards); + } + } + else + { + /* Update the received buffer when error happened. */ + if (status == kStatus_ENET_RxFrameError) + { +#if 0 && defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) /* Error statisctics */ + enet_data_error_stats_t eErrStatic; + /* Get the error information of the received g_frame. */ + ENET_GetRxErrBeforeReadFrame(ðernetif->handle, &eErrStatic); +#endif + + /* Update the receive buffer. */ + enet_read_frame(ethernetif, NULL, 0U); + + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: RxFrameError\n")); + + LINK_STATS_INC(link.drop); + MIB2_STATS_NETIF_INC(netif, ifindiscards); + } + } + } + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +void ethernetif_input(struct netif *netif) +{ + struct pbuf *p; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + /* move received packet into a new pbuf */ + while ((p = low_level_input(netif)) != NULL) + { + /* pass all packets to ethernet_input, which decides what packets it supports */ + if (netif->input(p, netif) != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + } +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + netif->state = ðernetif_0; + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; +/* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ +#if LWIP_IPV4 + netif->output = etharp_output; +#endif +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif /* LWIP_IPV6 */ + netif->linkoutput = low_level_output; + +#if LWIP_IPV4 && LWIP_IGMP + netif_set_igmp_mac_filter(netif, ethernetif_igmp_mac_filter); + netif->flags |= NETIF_FLAG_IGMP; +#endif +#if LWIP_IPV6 && LWIP_IPV6_MLD + netif_set_mld_mac_filter(netif, ethernetif_mld_mac_filter); + netif->flags |= NETIF_FLAG_MLD6; +#endif + + /* Init ethernetif parameters.*/ + ethernetif_0.base = ENET; + ethernetif_0.phyAddr = ENET_PHY_ADDRESS; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} diff --git a/src/freertos_helpers.c b/src/freertos_helpers.c new file mode 100644 index 0000000..af0b2f8 --- /dev/null +++ b/src/freertos_helpers.c @@ -0,0 +1,4 @@ +#include "FreeRTOS.h" +#include "task.h" + +uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((section(".freertos_heap"))); \ No newline at end of file diff --git a/src/fsl_phy.c b/src/fsl_phy.c new file mode 100644 index 0000000..7a767b7 --- /dev/null +++ b/src/fsl_phy.c @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ + +#include "fsl_phy.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the timeout macro. */ +#define PHY_TIMEOUT_COUNT 0xFFFFFU + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the ENET instance from peripheral base address. + * + * @param base ENET peripheral base address. + * @return ENET instance. + */ +extern uint32_t ENET_GetInstance(ENET_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to enet clocks for each instance. */ +extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz) +{ + uint32_t bssReg; + uint32_t counter = PHY_TIMEOUT_COUNT; + uint32_t idReg = 0; + status_t result = kStatus_Success; + uint32_t instance = ENET_GetInstance(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Set SMI first. */ + CLOCK_EnableClock(s_enetClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + ENET_SetSMI(base, srcClock_Hz, false); + + /* Initialization after PHY stars to work. */ + while ((idReg != PHY_CONTROL_ID1) && (counter != 0)) + { + PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg); + counter --; + } + + if (!counter) + { + return kStatus_Fail; + } + + /* Reset PHY. */ + counter = PHY_TIMEOUT_COUNT; + result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + if (result == kStatus_Success) + { + /* Set the negotiation. */ + result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U)); + if (result == kStatus_Success) + { + result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, + (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); + if (result == kStatus_Success) + { + /* Check auto negotiation complete. */ + while (counter --) + { + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg); + if ( result == kStatus_Success) + { + if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0) + { + break; + } + } + + if (!counter) + { + return kStatus_PHY_AutoNegotiateFail; + } + } + } + } + } + + return result; +} + +status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) +{ + uint32_t counter; + + /* Clear the SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI write command. */ + ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data); + + /* Wait for SMI complete. */ + for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--) + { + if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) + { + break; + } + } + + /* Check for timeout. */ + if (!counter) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr) +{ + assert(dataPtr); + + uint32_t counter; + + /* Clear the MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI read command operation. */ + ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame); + + /* Wait for MII complete. */ + for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--) + { + if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) + { + break; + } + } + + /* Check for timeout. */ + if (!counter) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Get data from MII register. */ + *dataPtr = ENET_ReadSMIData(base); + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, bool enable) +{ + status_t result; + uint32_t data = 0; + + /* Set the loop mode. */ + if (enable) + { + if (mode == kPHY_LocalLoop) + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_LOOP_MASK)); + } + } + else + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL1_REG, (data | PHY_CTL1_REMOTELOOP_MASK)); + } + } + } + else + { + /* Disable the loop mode. */ + if (mode == kPHY_LocalLoop) + { + /* First read the current status in the basic control register. */ + result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data & ~PHY_BCTL_LOOP_MASK)); + } + } + else + { + /* First read the current status in control one register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL1_REG, (data & ~PHY_CTL1_REMOTELOOP_MASK)); + } + } + } + return result; +} + +status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status) +{ + assert(status); + + status_t result = kStatus_Success; + uint32_t data; + + /* Read the basic status register. */ + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data); + if (result == kStatus_Success) + { + if (!(PHY_BSTATUS_LINKSTATUS_MASK & data)) + { + /* link down. */ + *status = false; + } + else + { + /* link up. */ + *status = true; + } + } + return result; +} + +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex) +{ + assert(duplex); + + status_t result = kStatus_Success; + uint32_t data, ctlReg; + + /* Read the control two register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &ctlReg); + if (result == kStatus_Success) + { + data = ctlReg & PHY_BSTATUS_SPEEDUPLX_MASK; + if ((PHY_CTL2_10FULLDUPLEX_MASK == data) || (PHY_CTL2_100FULLDUPLEX_MASK == data)) + { + /* Full duplex. */ + *duplex = kPHY_FullDuplex; + } + else + { + /* Half duplex. */ + *duplex = kPHY_HalfDuplex; + } + + data = ctlReg & PHY_BSTATUS_SPEEDUPLX_MASK; + if ((PHY_CTL2_100HALFDUPLEX_MASK == data) || (PHY_CTL2_100FULLDUPLEX_MASK == data)) + { + /* 100M speed. */ + *speed = kPHY_Speed100M; + } + else + { /* 10M speed. */ + *speed = kPHY_Speed10M; + } + } + + return result; +} diff --git a/src/ip_stack_helpers.c b/src/ip_stack_helpers.c new file mode 100644 index 0000000..965b2b0 --- /dev/null +++ b/src/ip_stack_helpers.c @@ -0,0 +1,116 @@ +#include + +/* FreeRTOS */ +#include "FreeRTOS.h" +#include "task.h" + +/* LwIP */ +#include "lwip/apps/httpd.h" +#include "lwip/apps/lwiperf.h" +#include "lwip/apps/sntp.h" +#include "lwip/dhcp.h" +#include "lwip/dns.h" +#include "lwip/init.h" +#include "lwip/prot/dhcp.h" +#include "lwip/tcpip.h" + +/* ENET */ +#include "ethernetif.h" + +/* Debug Console */ +#include "fsl_debug_console.h" + +#define NTP_POOL_ADDR "cn.pool.ntp.org" +#define NETIF_HOSTNAME "k60_server" + +static char *s_netif_hostname = NETIF_HOSTNAME; +static struct netif fsl_netif0; + +/* Report state => string */ +static const char *report_type_str[] = { + "TCP_DONE_SERVER", /* LWIPERF_TCP_DONE_SERVER,*/ + "TCP_DONE_CLIENT", /* LWIPERF_TCP_DONE_CLIENT,*/ + "TCP_ABORTED_LOCAL", /* LWIPERF_TCP_ABORTED_LOCAL, */ + "TCP_ABORTED_LOCAL_DATAERROR", /* LWIPERF_TCP_ABORTED_LOCAL_DATAERROR, */ + "TCP_ABORTED_LOCAL_TXERROR", /* LWIPERF_TCP_ABORTED_LOCAL_TXERROR, */ + "TCP_ABORTED_REMOTE", /* LWIPERF_TCP_ABORTED_REMOTE, */ + "UDP_STARTED", /* LWIPERF_UDP_STARTED, */ + "UDP_DONE", /* LWIPERF_UDP_DONE, */ + "UDP_ABORTED_LOCAL", /* LWIPERF_UDP_ABORTED_LOCAL, */ + "UDP_ABORTED_REMOTE" /* LWIPERF_UDP_ABORTED_REMOTE */ +}; + +/** Prototype of a report function that is called when a session is finished. + This report function shows the test results. */ +static void ip_stack_lwiperf_report(void *arg, enum lwiperf_report_type report_type, const ip_addr_t *local_addr, + u16_t local_port, const ip_addr_t *remote_addr, u16_t remote_port, + u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec) { + printf("-------------------------------------------------\r\n"); + if ((report_type < sizeof(report_type_str)) && local_addr && remote_addr) { + printf(" %s \r\n", report_type_str[report_type]); + printf(" Local address : %u.%u.%u.%u ", ((u8_t *)local_addr)[0], ((u8_t *)local_addr)[1], + ((u8_t *)local_addr)[2], ((u8_t *)local_addr)[3]); + printf(" Port %d \r\n", local_port); + printf(" Remote address : %u.%u.%u.%u ", ((u8_t *)remote_addr)[0], ((u8_t *)remote_addr)[1], + ((u8_t *)remote_addr)[2], ((u8_t *)remote_addr)[3]); + printf(" Port %d \r\n", remote_port); + printf(" Bytes Transferred %ld \r\n", bytes_transferred); + printf(" Duration (ms) %ld \r\n", ms_duration); + printf(" Bandwidth (kbitpsec) %ld \r\n", bandwidth_kbitpsec); + } else { + printf(" IPERF Report error\r\n"); + } +} + +static void ip_stack_sntp_address_found(const char *name, const ip_addr_t *ipaddr, void *callback_arg) { + printf("Resolved IP: %s\r\n", ipaddr_ntoa(ipaddr)); + sntp_setserver(0, ipaddr); + sntp_init(); +} + +static void ip_stack_enable_sntp(void) { + /* We are not ESP32, we have to do the DNS resolution manually. */ + ip_addr_t ntp_addr; + + sntp_setoperatingmode(SNTP_OPMODE_POLL); + + if (dns_gethostbyname(NTP_POOL_ADDR, &ntp_addr, ip_stack_sntp_address_found, NULL) == ERR_OK) { + /* If ERR_OK is returned, the result is cached in DNS. */ + sntp_setserver(0, &ntp_addr); + sntp_init(); + } else { + printf("No cached DNS result found, wait for callback.\r\n"); + } +} + +void ip_stack_setup(void) { + ip4_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw; + + SYSMPU->CESR &= ~(SYSMPU_CESR_VLD_MASK); /* Disable MPU */ + + tcpip_init(NULL, NULL); + + /* Initialize netif interface */ + netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, NULL, ethernetif_init, tcpip_input); + netif_set_default(&fsl_netif0); + netif_set_up(&fsl_netif0); + + netif_set_hostname(&fsl_netif0, s_netif_hostname); + + /* Start DHCP, this configures both DNS and IP addresses. */ + dhcp_start(&fsl_netif0); + + /* Wait for a lease */ + while (dhcp_supplied_address(&fsl_netif0) == 0) { + vTaskDelay(pdMS_TO_TICKS(500)); + } + + printf("IP Address: %s\r\n", ipaddr_ntoa(&fsl_netif0.ip_addr)); + + ip_stack_enable_sntp(); + + /* Start IPerf server */ + lwiperf_start_tcp_server_default(ip_stack_lwiperf_report, NULL); + + httpd_init(); +} \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f4f7454 --- /dev/null +++ b/src/main.c @@ -0,0 +1,77 @@ +#include +#include + +/* HW Related */ +#include "board.h" +#include "clock_config.h" +#include "peripherals.h" +#include "pin_mux.h" + +/* Console */ +#include "fsl_debug_console.h" + +/* MISC */ +#include "ip_stack_helpers.h" +#include "system_utilities.h" + +/*FreeRTOS*/ +#include "FreeRTOS.h" +#include "task.h" + +/* MbedTLS */ +#include "mbedtls/aes.h" +#include "mbedtls/gcm.h" +#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" + +static void vTaskHello(void *pvParameters); +static void mtls_selftests(int verbose); + +int main(void) { + BOARD_InitBootPins(); + BOARD_BootClockRUN(); + BOARD_InitBootPeripherals(); + + BOARD_InitDebugConsole(); + BOARD_EnableRTC(); + + print_hardware(); + sram_test(); + + mtls_selftests(1); + + xTaskCreate(vTaskHello, "HELLO", 256, NULL, 32, NULL); + + vTaskStartScheduler(); + + for (;;) { + __WFI(); + } +} + +static void vTaskHello(void *pvParameters) { + ip_stack_setup(); + + time_t t; + struct tm *cur_tm; + for (;;) { + vTaskDelay(pdMS_TO_TICKS(1000)); + t = time(NULL); + cur_tm = localtime(&t); + + printf("Current time: %04d-%02d-%02d %02d:%02d:%02d\r\n", cur_tm->tm_year + 1900, cur_tm->tm_mon + 1, + cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec); + } +} + +static void mtls_selftests(int verbose) { + uint8_t failed_cases = 0; + if (mbedtls_aes_self_test(verbose) != 0) failed_cases++; + if (mbedtls_gcm_self_test(verbose) != 0) failed_cases++; + if (mbedtls_sha1_self_test(verbose) != 0) failed_cases++; + if (mbedtls_sha256_self_test(verbose) != 0) failed_cases++; + if (mbedtls_sha512_self_test(verbose) != 0) failed_cases++; + + printf("MbedTLS selftests completed, %d case(s) failed.\r\n", failed_cases); +} \ No newline at end of file diff --git a/src/syscalls.c b/src/syscalls.c new file mode 100644 index 0000000..eb7a265 --- /dev/null +++ b/src/syscalls.c @@ -0,0 +1,42 @@ +#include +#include + +#include "FreeRTOS.h" +#include "task.h" +#include "MK60D10.h" + + +int _gettimeofday(struct timeval *restrict tp, void *restrict tzp) { + tp->tv_sec = RTC->TSR; + tp->tv_usec = 0U; + + return 0; +} + +caddr_t _sbrk(int incr) +{ + extern char end __asm("end"); + extern char heap_limit __asm("__HeapLimit"); + static char *heap_end; + char *prev_heap_end; + + taskENTER_CRITICAL(); + + if (heap_end == NULL) + heap_end = &end; + + prev_heap_end = heap_end; + + if (heap_end + incr > &heap_limit) + { + errno = ENOMEM; + taskEXIT_CRITICAL(); + return (caddr_t)-1; + } + + heap_end += incr; + + taskEXIT_CRITICAL(); + + return (caddr_t)prev_heap_end; +} \ No newline at end of file diff --git a/src/system_utilities.c b/src/system_utilities.c new file mode 100644 index 0000000..cf14b54 --- /dev/null +++ b/src/system_utilities.c @@ -0,0 +1,125 @@ +#include + +#include "board.h" +#include "clock_config.h" +#include "peripherals.h" +#include "pin_mux.h" + +#define SRAM_BASE (0x60000000) +#define SRAM_SIZE (512 * 1024) + +void print_hardware(void) { + uint32_t kinetis_revid = (SIM->SDID & SIM_SDID_REVID_MASK) >> SIM_SDID_REVID_SHIFT; + uint32_t kinetis_family = (SIM->SDID & SIM_SDID_FAMID_MASK) >> SIM_SDID_FAMID_SHIFT; + uint32_t kinetis_pinid = (SIM->SDID & SIM_SDID_PINID_MASK) >> SIM_SDID_PINID_SHIFT; + + char *family_str = NULL; + + switch(kinetis_family) { + case 0: + family_str = "K10"; + break; + case 1: + family_str = "K20"; + break; + case 2: + family_str = "K30"; + break; + case 3: + family_str = "K40"; + break; + case 4: + family_str = "K60"; + break; + case 6: + family_str = "K50/K52"; + break; + case 7: + family_str = "K51/K53"; + break; + default: + family_str = "UNKNOWN"; + break; + } + + char *pin_str = NULL; + switch(kinetis_pinid) { + case 0x06: + pin_str = "80"; + break; + case 0x07: + pin_str = "81"; + break; + case 0x08: + pin_str = "100"; + break; + case 0x09: + pin_str = "121"; + break; + case 0x0A: + pin_str = "144"; + break; + default: + pin_str = "UNKNOWN"; + break; + } + + char *rev_str = NULL; + switch(kinetis_revid) { + case 0: + rev_str = "1.0 (0M33Z)"; + break; + case 1: + rev_str = "1.1 (0N30D)"; + break; + case 2: + rev_str = "1.2 (1N30D/2N30D)"; + break; + case 3: + rev_str = "1.4 (4N30D)"; + break; + case 7: + rev_str = "1.8 (8N30D)"; + break; + case 10: + rev_str = "2.2 (2N22D)"; + break; + case 12: + rev_str = "2.4 (4N22D)"; + break; + case 13: + rev_str = "2.5 (5N22D)"; + break; + default: + rev_str = "UNKNOWN"; + break; + } + + printf("This is %s with Rev. (Mask Set): %s, %s pins.\r\n", family_str, rev_str, pin_str); +} + +void sram_test(void) { + printf("SRAM write... "); + for(uint32_t i = SRAM_BASE; i < SRAM_BASE + SRAM_SIZE; i += 4) { + *(volatile uint32_t *)i = i; + } + + printf("done, SRAM read... "); + + for(uint32_t i = SRAM_BASE; i < SRAM_BASE + SRAM_SIZE; i += 4) { + if(*(volatile uint32_t *)i != i) { + printf("error.\r\n"); + return; + } + } + + printf("done.\r\n"); +} + +int set_rtc_time(int sec) { + RTC->SR &= ~(RTC_SR_TCE_MASK); + RTC->TSR = sec; + RTC->SR |= RTC_SR_TCE_MASK; + + return 0; +} \ No newline at end of file