add ota project function code from Wang_guozhu

it is OK
This commit is contained in:
xuedongliang 2023-05-10 10:12:16 +08:00
commit 9109db0d94
44 changed files with 6084 additions and 2591 deletions

View File

@ -5,4 +5,6 @@ source "$KERNEL_DIR/lib/Kconfig"
source "$KERNEL_DIR/fs/Kconfig"
source "$KERNEL_DIR/tool/Kconfig"
source "$KERNEL_DIR/../../APP_Framework/Kconfig"

View File

@ -62,6 +62,10 @@ PART += COMPILE_KERNEL
else ifeq ($(CONFIG_COMPILER_APP)_$(CONFIG_COMPILER_KERNEL),y_y)
PART := COMPILE_APP COMPILE_KERNEL
else ifeq ($(CONFIG_MCUBOOT_BOOTLOADER), y)
PART := COMPILE_BOOTLOADER
else ifeq ($(CONFIG_MCUBOOT_APPLICATION), y)
PART := COMPILE_APPLICATION
else
PART :=
@ -88,6 +92,22 @@ COMPILE_ALL:
@$(MAKE) -C build TARGET=XiZi-$(BOARD).elf LINK_FLAGS=LFLAGS
@rm build/Makefile build/make.obj
COMPILE_BOOTLOADER:
@for dir in $(SRC_DIR);do \
$(MAKE) -C $$dir; \
done
@cp link.mk build/Makefile
@$(MAKE) -C build COMPILE_TYPE="-boot" TARGET=XiZi-$(BOARD)-boot.elf LINK_FLAGS=LFLAGS
@rm build/Makefile build/make.obj
COMPILE_APPLICATION:
@for dir in $(SRC_DIR);do \
$(MAKE) -C $$dir; \
done
@cp link.mk build/Makefile
@$(MAKE) -C build COMPILE_TYPE="-app" TARGET=XiZi-$(BOARD)-app.elf LINK_FLAGS=LFLAGS
@rm build/Makefile build/make.obj
COMPILE_MUSL:
@for dir in $(MUSL_DIR);do \
$(MAKE) -C $$dir COMPILE_TYPE=$@ CONFIG_RESOURCES_LWIP=n; \

View File

@ -49,6 +49,61 @@ Modification:
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
#ifdef __BOOTLOADER /* BOOT */
cpsid i /* Mask interrupts */
.equ VTOR, 0xE000ED08
ldr r0, =VTOR
ldr r1, =__isr_vector
str r1, [r0]
ldr r2, [r1]
msr msp, r2
ldr r0,=SystemInit
blx r0
/* Loop to copy data from read only memory to RAM. The ranges
* of copy from/to are specified by following symbols evaluated in
* linker script.
* __bootloader_end: End of code section, i.e., begin of data sections to copy from.
* __data_start__/__data_end__: RAM address range that data should be
* __noncachedata_start__/__noncachedata_end__ : none cachable region
* copied to. Both must be aligned to 4 bytes boundary. */
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
/* Here are two copies of loop implemenations. First one favors code size
* and the second one favors performance. Default uses the first one.
* Change to "#if 0" to use the second one */
.LoopCopy0:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .LoopCopy0
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* Loop to zero out BSS section, which uses following symbols
* in linker script:
* __bss_start__: start of BSS section. Must align to 4
* __bss_end__: end of BSS section. Must align to 4
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.LoopCopy1:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .LoopCopy1
ldr r0,=ota_entry
blx r0
#else /* APP */
cpsid i /* Mask interrupts */
.equ VTOR, 0xE000ED08
ldr r0, =VTOR
@ -122,7 +177,7 @@ Reset_Handler:
blt .LC4
#endif /* __STARTUP_INITIALIZE_NONCACHEDATA */
#ifdef __STARTUP_CLEAR_BSS
#if 1
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
@ -144,5 +199,6 @@ Reset_Handler:
ldr r0,=entry
blx r0
#endif /* MCUBOOT_BOOTLOADER */
.size Reset_Handler, . - Reset_Handler

View File

@ -64,6 +64,10 @@ Modification:
#include <connect_wdt.h>
#endif
#ifdef TOOL_USING_OTA
#include <ota.h>
#endif
#ifdef BSP_USING_SEMC
extern status_t BOARD_InitSEMC(void);
#ifdef BSP_USING_EXTSRAM
@ -330,12 +334,12 @@ struct InitSequenceDesc _board_init[] =
#endif
#ifdef BSP_USING_SDIO
{ "sdio", Imxrt1052HwSdioInit },
{ "sdio", Imxrt1052HwSdioInit },
#endif
#ifdef BSP_USING_USB
#ifdef BSP_USING_NXP_USBH
{ "nxp hw usb", Imxrt1052HwUsbHostInit },
{ "nxp hw usb", Imxrt1052HwUsbHostInit },
#endif
#endif
@ -344,7 +348,7 @@ struct InitSequenceDesc _board_init[] =
#endif
#ifdef BSP_USING_LCD
{ "hw_lcd", Imxrt1052HwLcdInit },
{ "hw_lcd", Imxrt1052HwLcdInit },
#endif
#ifdef BSP_USING_TOUCH
@ -358,7 +362,7 @@ struct InitSequenceDesc _board_init[] =
#ifdef BSP_USING_WDT
{ "hw_wdt", Imxrt1052HwWdgInit },
#endif
{ " NONE ",NONE },
{ " NONE ",NONE },
};
/**
@ -367,7 +371,7 @@ struct InitSequenceDesc _board_init[] =
void InitBoardHardware()
{
int i = 0;
int ret = 0;
int ret = 0;
BOARD_ConfigMPU();
BOARD_InitPins();
@ -403,10 +407,14 @@ void InitBoardHardware()
KPrintf("board initialization......\n");
for(i = 0; _board_init[i].fn != NONE; i++) {
ret = _board_init[i].fn();
KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed");
}
ret = _board_init[i].fn();
KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed");
}
KPrintf("board init done.\n");
KPrintf("start kernel...\n");
}
KPrintf("start kernel...\n");
#ifdef TOOL_USING_OTA
//跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG
app_clear_jumpflag();
#endif
}

View File

@ -15,7 +15,11 @@ ifeq ($(CONFIG_RESOURCES_LWIP), y)
export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a
endif
ifeq ($(CONFIG_BSP_USING_USB),y)
ifeq ($(CONFIG_MCUBOOT_BOOTLOADER),y)
export LFLAGS += -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-xidatong-arm32-boot.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-bootloader.lds
else ifeq ($(CONFIG_MCUBOOT_APPLICATION),y)
export LFLAGS += -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-xidatong-arm32-app.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-application.lds
else ifeq ($(CONFIG_BSP_USING_USB),y)
export LFLAGS += -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-xidatong-arm32.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-usb.lds
else
export LFLAGS += -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-xidatong-arm32.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
@ -28,5 +32,9 @@ export APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections
export DEFINES := -DHAVE_CCONFIG_H -DCPU_MIMXRT1052CVL5B -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS
ifeq ($(CONFIG_MCUBOOT_BOOTLOADER),y)
export DEFINES += -D__BOOTLOADER
endif
export ARCH = arm
export MCU = cortex-m7

View File

@ -33,7 +33,7 @@ Modification:
#include "fsl_clock.h"
#include "fsl_enet.h"
#include "clock_config.h"
// #include <xizi.h>
#include <xizi.h>
#include <arch_interrupt.h>
extern int heap_start;

View File

@ -50,6 +50,53 @@ void BOARD_InitBootClocks(void);
******************************************************************************/
#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 600000000U /*!< Core clock frequency: 600000000Hz */
/* Clock outputs (values are in Hz): */
#define BOARD_BOOTCLOCKRUN_AHB_CLK_ROOT 600000000UL
#define BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT 40000000UL
#define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL
#define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL
#define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL
#define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL
#define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL
#define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 12000000UL
#define BOARD_BOOTCLOCKRUN_ENET1_TX_CLK 2400000UL
#define BOARD_BOOTCLOCKRUN_ENET_125M_CLK 2400000UL
#define BOARD_BOOTCLOCKRUN_ENET_25M_REF_CLK 1200000UL
#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL
#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 30000000UL
#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 160000000UL
#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 75000000UL
#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 75000000UL
#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 150000000UL
#define BOARD_BOOTCLOCKRUN_LCDIF_CLK_ROOT 9642857UL
#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL
#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL
#define BOARD_BOOTCLOCKRUN_LVDS1_CLK 1200000000UL
#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL
#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 75000000UL
#define BOARD_BOOTCLOCKRUN_PLL7_MAIN_CLK 24000000UL
#define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL
#define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL
#define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL
#define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL
#define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 63529411UL
#define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 63529411UL
#define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL
#define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 30000000UL
#define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL
#define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL
#define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL
#define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL
#define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 75000000UL
#define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL
#define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL
#define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 117333333UL
#define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL
#define BOARD_BOOTCLOCKRUN_USBPHY1_CLK 0UL
#define BOARD_BOOTCLOCKRUN_USBPHY2_CLK 0UL
#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 198000000UL
#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 198000000UL
/*! @brief Arm PLL set for BOARD_BootClockRUN configuration.
*/
extern const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN;

View File

@ -0,0 +1,264 @@
/*
** ###################################################################
** Processors: MIMXRT1052CVJ5B
** MIMXRT1052CVL5B
** MIMXRT1052DVJ6B
** MIMXRT1052DVL6B
**
** Compiler: GNU C Compiler
** Reference manual: IMXRT1050RM Rev.1, 03/2018
** Version: rev. 1.0, 2018-09-21
** Build: b180921
**
** Abstract:
** Linker file for the GNU C Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2018 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/**
* @file link.lds
* @brief xidatong-arm32 Linker script
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28
*/
/*************************************************
File name: link.lds
Description: xidatong-arm32 Linker script
Others: take MIMXRT1052xxxxx_flexspi_nor.ld for references
History:
1. Date: 2021-05-28
Author: AIIT XUOS Lab
Modification:
1. add shell cmd table and g_service_table
*************************************************/
/* Entry Point */
ENTRY(Reset_Handler)
STACK_SIZE = 0x4000;
/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x60100000, LENGTH = 0x00000400
m_text (RX) : ORIGIN = 0x60100400, LENGTH = 0x000FFC00
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000
m_sdram (RW) : ORIGIN = 0x80000000, LENGTH = 0x01E00000
m_nocache (RW) : ORIGIN = 0x81E00000, LENGTH = 0x00200000
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into internal RAM */
.interrupts :
{
__VECTOR_TABLE = .;
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_interrupts
__VECTOR_RAM = __VECTOR_TABLE;
__RAM_VECTOR_TABLE_SIZE_BYTES = 0x0;
/* The program code and other data goes into internal RAM */
.text :
{
. = ALIGN(4);
*(EXCLUDE_FILE(
/* Exclude flash and frequently executed functions from XIP */
*fsl_romapi.o
*flash.o
) .text) /* .text sections (code) */
*(EXCLUDE_FILE(
/* Exclude flash and frequently executed functions from XIP */
*fsl_romapi.o
*flash.o
) .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);
/* section information for shell */
. = ALIGN(4);
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
__isrtbl_idx_start = .;
KEEP(*(.isrtbl.idx))
__isrtbl_start = .;
KEEP(*(.isrtbl))
__isrtbl_end = .;
. = ALIGN(4);
PROVIDE(g_service_table_start = ABSOLUTE(.));
KEEP(*(.g_service_table))
PROVIDE(g_service_table_end = ABSOLUTE(.));
} > 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 */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
/* Explicit placement of flash and frequently executed functions in RAM */
*fsl_romapi.o
*flash.o
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
PROVIDE(_sramfuncs = ABSOLUTE(.));
KEEP(*(RamFunction))
PROVIDE(_eramfuncs = ABSOLUTE(.));
__data_end__ = .; /* define a global symbol at data end */
} > m_data
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
.ncache.init : AT(__NDATA_ROM)
{
__noncachedata_start__ = .; /* create a global symbol at ncache data start */
*(NonCacheable.init)
. = ALIGN(4);
__noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */
} > m_nocache
. = __noncachedata_init_end__;
.ncache :
{
*(NonCacheable)
. = ALIGN(4);
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
} > m_nocache
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_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
.stack :
{
. = ALIGN(8);
stack_start = .;
. += STACK_SIZE;
stack_end = .;
__StackTop = .;
heap_start = .;
} > m_data2
PROVIDE(heap_end = ORIGIN(m_data2) + LENGTH(m_data2));
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View File

@ -0,0 +1,280 @@
/*
** ###################################################################
** Processors: MIMXRT1052CVJ5B
** MIMXRT1052CVL5B
** MIMXRT1052DVJ6B
** MIMXRT1052DVL6B
**
** Compiler: GNU C Compiler
** Reference manual: IMXRT1050RM Rev.1, 03/2018
** Version: rev. 1.0, 2018-09-21
** Build: b180921
**
** Abstract:
** Linker file for the GNU C Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2018 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/**
* @file link.lds
* @brief xidatong-arm32 Linker script
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28
*/
/*************************************************
File name: link.lds
Description: xidatong-arm32 Linker script
Others: take MIMXRT1052xxxxx_flexspi_nor.ld for references
History:
1. Date: 2021-05-28
Author: AIIT XUOS Lab
Modification:
1. add shell cmd table and g_service_table
*************************************************/
/* Entry Point */
ENTRY(Reset_Handler)
STACK_SIZE = 0x8000;
/* Specify the memory areas */
MEMORY
{
m_boot_data (RX) : ORIGIN = 0x60000000, LENGTH = 0x00001000
m_image_vertor_table (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000
/*bootloader*/
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x0007DC00
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000
m_sdram (RW) : ORIGIN = 0x80000000, LENGTH = 0x01E00000
m_nocache (RW) : ORIGIN = 0x81E00000, LENGTH = 0x00200000
}
/* Define output sections */
SECTIONS
{
.boot_data :
{
KEEP(*(.boot_hdr.conf))
} > m_boot_data
.image_vertor_table :
{
KEEP(*(.boot_hdr.ivt))
KEEP(*(.boot_hdr.boot_data))
KEEP(*(.boot_hdr.dcd_data))
} > m_image_vertor_table
/* The startup code goes first into internal RAM */
.interrupts :
{
__VECTOR_TABLE = .;
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_interrupts
__VECTOR_RAM = __VECTOR_TABLE;
__RAM_VECTOR_TABLE_SIZE_BYTES = 0x0;
/* The program code and other data goes into internal RAM */
.text :
{
. = ALIGN(4);
*(EXCLUDE_FILE(
/* Exclude flash and frequently executed functions from XIP */
*fsl_romapi.o
*flash.o
) .text) /* .text sections (code) */
*(EXCLUDE_FILE(
/* Exclude flash and frequently executed functions from XIP */
*fsl_romapi.o
*flash.o
) .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);
/* section information for shell */
. = ALIGN(4);
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
__isrtbl_idx_start = .;
KEEP(*(.isrtbl.idx))
__isrtbl_start = .;
KEEP(*(.isrtbl))
__isrtbl_end = .;
. = ALIGN(4);
PROVIDE(g_service_table_start = ABSOLUTE(.));
KEEP(*(.g_service_table))
PROVIDE(g_service_table_end = ABSOLUTE(.));
} > 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 */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
/* Explicit placement of flash and frequently executed functions in RAM */
*fsl_romapi.o
*flash.o
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
PROVIDE(_sramfuncs = ABSOLUTE(.));
KEEP(*(RamFunction))
PROVIDE(_eramfuncs = ABSOLUTE(.));
__data_end__ = .; /* define a global symbol at data end */
} > m_data
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
.ncache.init : AT(__NDATA_ROM)
{
__noncachedata_start__ = .; /* create a global symbol at ncache data start */
*(NonCacheable.init)
. = ALIGN(4);
__noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */
} > m_nocache
. = __noncachedata_init_end__;
.ncache :
{
*(NonCacheable)
. = ALIGN(4);
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
} > m_nocache
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_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
.stack :
{
. = ALIGN(8);
stack_start = .;
. += STACK_SIZE;
stack_end = .;
__StackTop = .;
heap_start = .;
} > m_data
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View File

@ -260,5 +260,4 @@ SECTIONS
PROVIDE(heap_end = ORIGIN(m_data2) + LENGTH(m_data2));
.ARM.attributes 0 : { *(.ARM.attributes) }
}
}

View File

@ -4,4 +4,8 @@ ifeq ($(CONFIG_BSP_USING_SDIO),y)
SRC_FILES += fsl_usdhc.c
endif
ifeq ($(CONFIG_TOOL_USING_OTA),y)
SRC_FILES += fsl_romapi.c flash.c mcuboot.c common.c ymodem.c
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -78,11 +78,11 @@ outputs:
- {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz}
- {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz}
- {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz}
- {id: FLEXSPI_CLK_ROOT.outFreq, value: 2880/11 MHz}
- {id: FLEXSPI_CLK_ROOT.outFreq, value: 160 MHz}
- {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz}
- {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz}
- {id: IPG_CLK_ROOT.outFreq, value: 150 MHz}
- {id: LCDIF_CLK_ROOT.outFreq, value: 67.5/7 MHz}
- {id: LCDIF_CLK_ROOT.outFreq, value: 67.5 MHz}
- {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz}
- {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz}
- {id: LVDS1_CLK.outFreq, value: 1.2 GHz}
@ -108,10 +108,8 @@ outputs:
settings:
- {id: CCM.AHB_PODF.scale, value: '1', locked: true}
- {id: CCM.ARM_PODF.scale, value: '2', locked: true}
- {id: CCM.FLEXSPI_PODF.scale, value: '1', locked: true}
- {id: CCM.FLEXSPI_SEL.sel, value: CCM_ANALOG.PLL3_PFD0_CLK}
- {id: CCM.LCDIF_PODF.scale, value: '8', locked: true}
- {id: CCM.LCDIF_PRED.scale, value: '7', locked: true}
- {id: CCM.FLEXSPI_PODF.scale, value: '3', locked: true}
- {id: CCM.FLEXSPI_SEL.sel, value: CCM.PLL3_SW_CLK_SEL}
- {id: CCM.LPSPI_PODF.scale, value: '5', locked: true}
- {id: CCM.PERCLK_PODF.scale, value: '2', locked: true}
- {id: CCM.SEMC_PODF.scale, value: '8'}
@ -148,23 +146,20 @@ sources:
/*******************************************************************************
* Variables for BOARD_BootClockRUN configuration
******************************************************************************/
const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN =
{
.loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
};
const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN =
{
.loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */
.numerator = 0, /* 30 bit numerator of fractional loop divider */
.denominator = 1, /* 30 bit denominator of fractional loop divider */
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
};
const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN =
{
.loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
};
const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = {
.loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
};
const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = {
.loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */
.numerator = 0, /* 30 bit numerator of fractional loop divider */
.denominator = 1, /* 30 bit denominator of fractional loop divider */
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
};
const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = {
.loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */
.src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
};
/*******************************************************************************
* Code for BOARD_BootClockRUN configuration
******************************************************************************/
@ -229,9 +224,10 @@ void BOARD_BootClockRUN(void)
CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1);
/* Set Usdhc2 clock source. */
CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0);
/* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
* With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged.
* Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/
/* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
* With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left
* unchanged.
* Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/
#ifndef SKIP_SYSCLK_INIT
/* Disable Semc clock gate. */
CLOCK_DisableClock(kCLOCK_Semc);
@ -242,16 +238,17 @@ void BOARD_BootClockRUN(void)
/* Set Semc clock source. */
CLOCK_SetMux(kCLOCK_SemcMux, 0);
#endif
/* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
* With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged.
* Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
/* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
* With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left
* unchanged.
* Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
/* Disable Flexspi clock gate. */
CLOCK_DisableClock(kCLOCK_FlexSpi);
/* Set FLEXSPI_PODF. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0);
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2);
/* Set Flexspi clock source. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 3);
CLOCK_SetMux(kCLOCK_FlexspiMux, 1);
#endif
/* Disable CSI clock gate. */
CLOCK_DisableClock(kCLOCK_Csi);
@ -331,9 +328,9 @@ void BOARD_BootClockRUN(void)
/* Disable LCDIF clock gate. */
CLOCK_DisableClock(kCLOCK_LcdPixel);
/* Set LCDIF_PRED. */
CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 6);
CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1);
/* Set LCDIF_CLK_PODF. */
CLOCK_SetDiv(kCLOCK_LcdifDiv, 7);
CLOCK_SetDiv(kCLOCK_LcdifDiv, 3);
/* Set Lcdif pre clock source. */
CLOCK_SetMux(kCLOCK_LcdifPreMux, 5);
/* Disable SPDIF clock gate. */
@ -365,8 +362,9 @@ void BOARD_BootClockRUN(void)
/* Init ARM PLL. */
CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN);
/* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
* With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left unchanged.
* Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/
* With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left
* unchanged. Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as
* well.*/
#ifndef SKIP_SYSCLK_INIT
/* Init System PLL. */
CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN);
@ -382,8 +380,9 @@ void BOARD_BootClockRUN(void)
CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_PFD_OFFSET_EN_MASK;
#endif
/* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
* With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged.
* Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
* With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left
* unchanged. Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as
* well.*/
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
/* Init Usb1 PLL. */
CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN);
@ -420,7 +419,8 @@ void BOARD_BootClockRUN(void)
/* Bypass Enet PLL. */
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1);
/* Set Enet output divider. */
CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1);
CCM_ANALOG->PLL_ENET =
(CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1);
/* Enable Enet output. */
CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK;
/* Enable Enet25M output. */
@ -440,7 +440,8 @@ void BOARD_BootClockRUN(void)
/* Set per clock source. */
CLOCK_SetMux(kCLOCK_PerclkMux, 0);
/* Set lvds1 clock source. */
CCM_ANALOG->MISC1 = (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0);
CCM_ANALOG->MISC1 =
(CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0);
/* Set clock out1 divider. */
CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0);
/* Set clock out1 source. */
@ -466,7 +467,7 @@ void BOARD_BootClockRUN(void)
/* Set SAI3 MCLK3 clock source. */
IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0);
/* Set MQS configuration. */
IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0);
IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0);
/* Set ENET Tx clock source. */
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false);
/* Set GPT1 High frequency reference clock source. */
@ -476,4 +477,3 @@ void BOARD_BootClockRUN(void)
/* Set SystemCoreClock variable. */
SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
}

View File

@ -0,0 +1,301 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: common.c
* @brief: file common.c
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#include "common.h"
static uint32_t UartSrcFreq(void)
{
uint32_t freq;
if (CLOCK_GetMux(kCLOCK_UartMux) == 0){
freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
} else {
freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
}
return freq;
}
void UartConfig(void)
{
lpuart_config_t config;
LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = 115200u;
config.enableTx = true;
config.enableRx = true;
LPUART_Init(LPUART1, &config, UartSrcFreq());
}
/**
* @brief Convert an Integer to a string
* @param str: The string
* @param intnum: The intger to be converted
* @retval None
*/
void Int2Str(uint8_t* str, int32_t intnum)
{
uint32_t i, Div = 1000000000, j = 0, Status = 0;
for (i = 0; i < 10; i++)
{
str[j++] = (intnum / Div) + 48;
intnum = intnum % Div;
Div /= 10;
if ((str[j-1] == '0') & (Status == 0))
{
j = 0;
}
else
{
Status++;
}
}
}
/**
* @brief Convert a string to an integer
* @param inputstr: The string to be converted
* @param intnum: The intger value
* @retval 1: Correct
* 0: Error
*/
uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum)
{
uint32_t i = 0, res = 0;
uint32_t val = 0;
if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X'))
{
if (inputstr[2] == '\0')
{
return 0;
}
for (i = 2; i < 11; i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
/* return 1; */
res = 1;
break;
}
if (ISVALIDHEX(inputstr[i]))
{
val = (val << 4) + CONVERTHEX(inputstr[i]);
}
else
{
/* return 0, Invalid input */
res = 0;
break;
}
}
/* over 8 digit hex --invalid */
if (i >= 11)
{
res = 0;
}
}
else /* max 10-digit decimal input */
{
for (i = 0;i < 11;i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
/* return 1 */
res = 1;
break;
}
else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0))
{
val = val << 10;
*intnum = val;
res = 1;
break;
}
else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0))
{
val = val << 20;
*intnum = val;
res = 1;
break;
}
else if (ISVALIDDEC(inputstr[i]))
{
val = val * 10 + CONVERTDEC(inputstr[i]);
}
else
{
/* return 0, Invalid input */
res = 0;
break;
}
}
/* Over 10 digit decimal --invalid */
if (i >= 11)
{
res = 0;
}
}
return res;
}
/**
* @brief Get an integer from the HyperTerminal
* @param num: The inetger
* @retval 1: Correct
* 0: Error
*/
uint32_t GetIntegerInput(int32_t * num)
{
uint8_t inputstr[16];
while (1)
{
GetInputString(inputstr);
if (inputstr[0] == '\0') continue;
if ((inputstr[0] == 'a' || inputstr[0] == 'A') && inputstr[1] == '\0')
{
Serial_PutString("User Cancelled \r\n");
return 0;
}
if (Str2Int(inputstr, num) == 0)
{
Serial_PutString("Error, Input again: \r\n");
}
else
{
return 1;
}
}
}
/**
* @brief Test to see if a key has been pressed on the HyperTerminal
* @param key: The key pressed
* @retval 1: Correct
* 0: Error
*/
uint32_t SerialKeyPressed(uint8_t *key)
{
if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(LPUART1))
{
*key = LPUART_ReadByte(LPUART1);
return 1;
}
else
{
return 0;
}
}
/**
* @brief Get a key from the HyperTerminal
* @param None
* @retval The Key Pressed
*/
uint8_t GetKey(void)
{
uint8_t key = 0;
/* Waiting for user input */
while (1)
{
if (SerialKeyPressed((uint8_t*)&key)) break;
}
return key;
}
/**
* @brief Print a character on the HyperTerminal
* @param c: The character to be printed
* @retval None
*/
void SerialPutChar(uint8_t c)
{
LPUART_WriteByte(LPUART1,c);
while(!(kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)))
{
}
}
/**
* @brief Print a string on the HyperTerminal
* @param s: The string to be printed
* @retval None
*/
void Serial_PutString(uint8_t *s)
{
while (*s != '\0')
{
SerialPutChar(*s);
s++;
}
}
/**
* @brief Get Input string from the HyperTerminal
* @param buffP: The input string
* @retval None
*/
void GetInputString (uint8_t * buffP)
{
uint32_t bytes_read = 0;
uint8_t c = 0;
do
{
c = GetKey();
if (c == '\r')
break;
if (c == '\b') /* Backspace */
{
if (bytes_read > 0)
{
Serial_PutString("\b \b");
bytes_read --;
}
continue;
}
if (bytes_read >= CMD_STRING_SIZE )
{
Serial_PutString("Command string size overflow\r\n");
bytes_read = 0;
continue;
}
if (c >= 0x20 && c <= 0x7E)
{
buffP[bytes_read++] = c;
SerialPutChar(c);
}
}
while (1);
Serial_PutString(("\n\r"));
buffP[bytes_read] = '\0';
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 NXP
* Copyright 2017 - 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@ -26,7 +26,7 @@ achieve better performance, it is depend on the IDE Floating point settings, if
in IDE, clock_64b_t will switch to double type automatically. only support IAR and MDK here */
#if __FPU_USED
#if ((defined(__ICCARM__)) || (defined(__GNUC__)))
#if (defined(__ICCARM__))
#if (__ARMVFP__ >= __ARMFPV5__) && \
(__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
@ -35,6 +35,14 @@ typedef double clock_64b_t;
typedef uint64_t clock_64b_t;
#endif
#elif (defined(__GNUC__))
#if (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
typedef double clock_64b_t;
#else
typedef uint64_t clock_64b_t;
#endif
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
#if defined __TARGET_FPU_FPV5_D16
@ -71,6 +79,13 @@ volatile uint32_t g_rtcXtalFreq;
*/
static uint32_t CLOCK_GetPeriphClkFreq(void);
/*!
* @brief Get the frequency of PLL USB1 software clock.
*
* @return The frequency of PLL USB1 software clock.
*/
static uint32_t CLOCK_GetPllUsb1SWFreq(void);
/*******************************************************************************
* Code
******************************************************************************/
@ -80,7 +95,7 @@ static uint32_t CLOCK_GetPeriphClkFreq(void)
uint32_t freq;
/* Periph_clk2_clk ---> Periph_clk */
if (CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK)
if ((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK) != 0U)
{
switch (CCM->CBCMR & CCM_CBCMR_PERIPH_CLK2_SEL_MASK)
{
@ -141,6 +156,30 @@ static uint32_t CLOCK_GetPeriphClkFreq(void)
return freq;
}
static uint32_t CLOCK_GetPllUsb1SWFreq(void)
{
uint32_t freq;
switch ((CCM->CCSR & CCM_CCSR_PLL3_SW_CLK_SEL_MASK) >> CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT)
{
case 0:
{
freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
break;
}
case 1:
{
freq = 24000000UL;
break;
}
default:
freq = 0UL;
break;
}
return freq;
}
/*!
* brief Initialize the external 24MHz clock.
*
@ -161,11 +200,11 @@ void CLOCK_InitExternalClk(bool bypassXtalOsc)
assert(!bypassXtalOsc);
CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */
while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0)
while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0U)
{
}
CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */
while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0)
while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0UL)
{
}
CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK;
@ -194,9 +233,13 @@ void CLOCK_DeinitExternalClk(void)
void CLOCK_SwitchOsc(clock_osc_t osc)
{
if (osc == kCLOCK_RcOsc)
{
XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK;
}
else
{
XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK;
}
}
/*!
@ -235,10 +278,10 @@ uint32_t CLOCK_GetSemcFreq(void)
uint32_t freq;
/* SEMC alternative clock ---> SEMC Clock */
if (CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK)
if ((CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK) != 0U)
{
/* PLL3 PFD1 ---> SEMC alternative clock ---> SEMC Clock */
if (CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK)
if ((CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK) != 0U)
{
freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1);
}
@ -279,14 +322,14 @@ uint32_t CLOCK_GetPerClkFreq(void)
uint32_t freq;
/* Osc_clk ---> PER Clock*/
if (CCM->CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK)
if ((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK) != 0U)
{
freq = CLOCK_GetOscFreq();
}
/* Periph_clk ---> AHB Clock ---> IPG Clock ---> PER Clock */
else
{
freq = CLOCK_GetFreq(kCLOCK_IpgClk);
freq = CLOCK_GetIpgFreq();
}
freq /= (((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_PODF_MASK) >> CCM_CSCMR1_PERCLK_PODF_SHIFT) + 1U);
@ -350,6 +393,18 @@ uint32_t CLOCK_GetFreq(clock_name_t name)
case kCLOCK_Usb1PllPfd3Clk:
freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3);
break;
case kCLOCK_Usb1SwClk:
freq = CLOCK_GetPllUsb1SWFreq();
break;
case kCLOCK_Usb1Sw120MClk:
freq = CLOCK_GetPllUsb1SWFreq() / 4UL;
break;
case kCLOCK_Usb1Sw60MClk:
freq = CLOCK_GetPllUsb1SWFreq() / 8UL;
break;
case kCLOCK_Usb1Sw80MClk:
freq = CLOCK_GetPllUsb1SWFreq() / 6UL;
break;
case kCLOCK_Usb2PllClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllUsb2);
break;
@ -388,6 +443,45 @@ uint32_t CLOCK_GetFreq(clock_name_t name)
return freq;
}
/*!
* brief Gets the frequency of selected clock root.
*
* param clockRoot The clock root used to get the frequency, please refer to @ref clock_root_t.
* return The frequency of selected clock root.
*/
uint32_t CLOCK_GetClockRootFreq(clock_root_t clockRoot)
{
const clock_name_t clockRootSourceArray[][6] = CLOCK_ROOT_SOUCE;
const clock_mux_t clockRootMuxTupleArray[] = CLOCK_ROOT_MUX_TUPLE;
const clock_div_t clockRootDivTupleArray[][2] = CLOCK_ROOT_DIV_TUPLE;
uint32_t freq = 0UL;
clock_mux_t clockRootMuxTuple = clockRootMuxTupleArray[(uint8_t)clockRoot];
clock_div_t clockRootPreDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][0];
clock_div_t clockRootPostDivTuple = clockRootDivTupleArray[(uint8_t)clockRoot][1];
uint32_t clockRootMuxValue = (CCM_TUPLE_REG(CCM, clockRootMuxTuple) & CCM_TUPLE_MASK(clockRootMuxTuple)) >>
CCM_TUPLE_SHIFT(clockRootMuxTuple);
clock_name_t clockSourceName;
clockSourceName = clockRootSourceArray[(uint8_t)clockRoot][clockRootMuxValue];
assert(clockSourceName != kCLOCK_NoneName);
freq = CLOCK_GetFreq(clockSourceName);
if (clockRootPreDivTuple != kCLOCK_NonePreDiv)
{
freq /= ((CCM_TUPLE_REG(CCM, clockRootPreDivTuple) & CCM_TUPLE_MASK(clockRootPreDivTuple)) >>
CCM_TUPLE_SHIFT(clockRootPreDivTuple)) +
1UL;
}
freq /= ((CCM_TUPLE_REG(CCM, clockRootPostDivTuple) & CCM_TUPLE_MASK(clockRootPostDivTuple)) >>
CCM_TUPLE_SHIFT(clockRootPostDivTuple)) +
1UL;
return freq;
}
/*! brief Enable USB HS clock.
*
* This function only enables the access to USB HS prepheral, upper layer
@ -401,10 +495,12 @@ uint32_t CLOCK_GetFreq(clock_name_t name)
*/
bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq)
{
uint32_t i;
CCM->CCGR6 |= CCM_CCGR6_CG0_MASK;
USB1->USBCMD |= USBHS_USBCMD_RST_MASK;
for (volatile uint32_t i = 0; i < 400000;
i++) /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
/* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
for (i = 0; i < 400000U; i++)
{
__ASM("nop");
}
@ -426,10 +522,12 @@ bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq)
*/
bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq)
{
uint32_t i = 0;
CCM->CCGR6 |= CCM_CCGR6_CG0_MASK;
USB2->USBCMD |= USBHS_USBCMD_RST_MASK;
for (volatile uint32_t i = 0; i < 400000;
i++) /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
/* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
for (i = 0; i < 400000U; i++)
{
__ASM("nop");
}
@ -450,7 +548,7 @@ bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq)
bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
{
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
if (CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK)
if ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK) != 0U)
{
CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
}
@ -494,7 +592,7 @@ void CLOCK_InitArmPll(const clock_arm_pll_config_t *config)
(CCM_ANALOG->PLL_ARM & (~(CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK | CCM_ANALOG_PLL_ARM_POWERDOWN_MASK))) |
CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_DIV_SELECT(config->loopDivider);
while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0)
while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0UL)
{
}
@ -528,7 +626,7 @@ void CLOCK_InitSysPll(const clock_sys_pll_config_t *config)
CCM_ANALOG_PLL_SYS_ENABLE_MASK | CCM_ANALOG_PLL_SYS_DIV_SELECT(config->loopDivider);
/* Initialize the fractional mode */
CCM_ANALOG->PLL_SYS_NUM = CCM_ANALOG_PLL_SYS_NUM_A(config->numerator);
CCM_ANALOG->PLL_SYS_NUM = CCM_ANALOG_PLL_SYS_NUM_A(config->numerator);
CCM_ANALOG->PLL_SYS_DENOM = CCM_ANALOG_PLL_SYS_DENOM_B(config->denominator);
/* Initialize the spread spectrum mode */
@ -536,7 +634,7 @@ void CLOCK_InitSysPll(const clock_sys_pll_config_t *config)
CCM_ANALOG_PLL_SYS_SS_ENABLE(config->ss_enable) |
CCM_ANALOG_PLL_SYS_SS_STOP(config->ss_stop);
while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0)
while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0UL)
{
}
@ -569,7 +667,7 @@ void CLOCK_InitUsb1Pll(const clock_usb_pll_config_t *config)
CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK |
CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB1_DIV_SELECT(config->loopDivider);
while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0)
while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0UL)
{
}
@ -602,7 +700,7 @@ void CLOCK_InitUsb2Pll(const clock_usb_pll_config_t *config)
CCM_ANALOG_PLL_USB2_ENABLE_MASK | CCM_ANALOG_PLL_USB2_POWER_MASK |
CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB2_DIV_SELECT(config->loopDivider);
while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0)
while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0UL)
{
}
@ -634,7 +732,7 @@ void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
CCM_ANALOG->PLL_AUDIO = (CCM_ANALOG->PLL_AUDIO & (~CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC_MASK)) |
CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(config->src);
CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator);
CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator);
CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(config->denominator);
/*
@ -689,7 +787,7 @@ void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
CCM_ANALOG->PLL_AUDIO = pllAudio;
while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0)
while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0UL)
{
}
@ -702,7 +800,7 @@ void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
*/
void CLOCK_DeinitAudioPll(void)
{
CCM_ANALOG->PLL_AUDIO = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK;
CCM_ANALOG->PLL_AUDIO = (uint32_t)CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK;
}
/*!
@ -721,7 +819,7 @@ void CLOCK_InitVideoPll(const clock_video_pll_config_t *config)
CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) |
CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(config->src);
CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(config->numerator);
CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(config->numerator);
CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(config->denominator);
/*
@ -775,7 +873,7 @@ void CLOCK_InitVideoPll(const clock_video_pll_config_t *config)
CCM_ANALOG->PLL_VIDEO = pllVideo;
while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0)
while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0UL)
{
}
@ -820,7 +918,7 @@ void CLOCK_InitEnetPll(const clock_enet_pll_config_t *config)
enet_pll;
/* Wait for stable */
while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0)
while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0UL)
{
}
@ -883,10 +981,10 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
break;
case kCLOCK_PllSys:
/* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_SYS_NUM))) /
((clock_64b_t)(CCM_ANALOG->PLL_SYS_DENOM));
freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_SYS_NUM)));
freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_SYS_DENOM));
if (CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK)
if ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK) != 0U)
{
freq *= 22U;
}
@ -899,7 +997,7 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
break;
case kCLOCK_PllUsb1:
freq = (freq * ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) ? 22U : 20U));
freq = (freq * (((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) != 0UL) ? 22U : 20U));
break;
case kCLOCK_PllAudio:
@ -907,8 +1005,8 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
divSelect =
(CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_AUDIO_DIV_SELECT_SHIFT;
freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_NUM))) /
((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_DENOM));
freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_NUM)));
freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_DENOM));
freq = freq * divSelect + (uint32_t)freqTmp;
@ -938,7 +1036,12 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
freq = freq >> 1U;
break;
case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2U):
freq = freq >> 0U;
break;
default:
assert(false);
break;
}
@ -952,7 +1055,13 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
freq >>= 1U;
break;
case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0):
case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0):
freq >>= 0U;
break;
default:
assert(false);
break;
}
break;
@ -962,9 +1071,8 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
divSelect =
(CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_VIDEO_DIV_SELECT_SHIFT;
freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_NUM))) /
((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_DENOM));
freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_NUM)));
freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_DENOM));
freq = freq * divSelect + (uint32_t)freqTmp;
/* VIDEO PLL output = PLL output frequency / POSTDIV. */
@ -993,21 +1101,32 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
freq = freq >> 1U;
break;
case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2U):
freq = freq >> 0U;
break;
default:
assert(false);
break;
}
switch (CCM_ANALOG->MISC2 & CCM_ANALOG_MISC2_VIDEO_DIV_MASK)
{
case CCM_ANALOG_MISC2_VIDEO_DIV(3):
case CCM_ANALOG_MISC2_VIDEO_DIV(3U):
freq >>= 2U;
break;
case CCM_ANALOG_MISC2_VIDEO_DIV(1):
case CCM_ANALOG_MISC2_VIDEO_DIV(1U):
freq >>= 1U;
break;
case CCM_ANALOG_MISC2_VIDEO_DIV(0U):
case CCM_ANALOG_MISC2_VIDEO_DIV(2U):
freq >>= 0U;
break;
default:
assert(false);
break;
}
break;
@ -1023,7 +1142,7 @@ uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
break;
case kCLOCK_PllUsb2:
freq = (freq * ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) ? 22U : 20U));
freq = (freq * (((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0U) ? 22U : 20U));
break;
default:
freq = 0U;
@ -1049,13 +1168,14 @@ void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac)
uint32_t pfd528;
pfd528 = CCM_ANALOG->PFD_528 &
~((CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) << (8 * pfdIndex));
~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD0_FRAC_MASK)
<< (8UL * pfdIndex)));
/* Disable the clock output first. */
CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8 * pfdIndex));
CCM_ANALOG->PFD_528 = pfd528 | ((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
/* Set the new value and enable output. */
CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8 * pfdIndex));
CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex));
}
/*!
@ -1067,7 +1187,7 @@ void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac)
*/
void CLOCK_DeinitSysPfd(clock_pfd_t pfd)
{
CCM_ANALOG->PFD_528 |= CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8 * pfd);
CCM_ANALOG->PFD_528 |= (uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8U * (uint8_t)pfd);
}
/*!
@ -1086,13 +1206,14 @@ void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac)
uint32_t pfd480;
pfd480 = CCM_ANALOG->PFD_480 &
~((CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) << (8 * pfdIndex));
~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD0_FRAC_MASK)
<< (8UL * pfdIndex)));
/* Disable the clock output first. */
CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8 * pfdIndex));
CCM_ANALOG->PFD_480 = pfd480 | ((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
/* Set the new value and enable output. */
CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8 * pfdIndex));
CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex));
}
/*!
@ -1104,7 +1225,7 @@ void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac)
*/
void CLOCK_DeinitUsb1Pfd(clock_pfd_t pfd)
{
CCM_ANALOG->PFD_480 |= CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8 * pfd);
CCM_ANALOG->PFD_480 |= (uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * (uint8_t)pfd);
}
/*!
@ -1217,3 +1338,180 @@ void CLOCK_DisableUsbhs1PhyPllClock(void)
CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK;
USBPHY2->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
}
/*!
* brief Set the clock source and the divider of the clock output1.
*
* param selection The clock source to be output, please refer to clock_output1_selection_t.
* param divider The divider of the output clock signal, please refer to clock_output_divider_t.
*/
void CLOCK_SetClockOutput1(clock_output1_selection_t selection, clock_output_divider_t divider)
{
uint32_t tmp32;
tmp32 = CCM->CCOSR;
if (selection == kCLOCK_DisableClockOutput1)
{
tmp32 &= ~CCM_CCOSR_CLKO1_EN_MASK;
}
else
{
tmp32 |= CCM_CCOSR_CLKO1_EN_MASK;
tmp32 &= ~(CCM_CCOSR_CLKO1_SEL_MASK | CCM_CCOSR_CLKO1_DIV_MASK);
tmp32 |= CCM_CCOSR_CLKO1_SEL(selection) | CCM_CCOSR_CLKO1_DIV(divider);
}
CCM->CCOSR = tmp32;
}
/*!
* brief Set the clock source and the divider of the clock output2.
*
* param selection The clock source to be output, please refer to clock_output2_selection_t.
* param divider The divider of the output clock signal, please refer to clock_output_divider_t.
*/
void CLOCK_SetClockOutput2(clock_output2_selection_t selection, clock_output_divider_t divider)
{
uint32_t tmp32;
tmp32 = CCM->CCOSR;
if (selection == kCLOCK_DisableClockOutput2)
{
tmp32 &= CCM_CCOSR_CLKO2_EN_MASK;
}
else
{
tmp32 |= CCM_CCOSR_CLKO2_EN_MASK;
tmp32 &= ~(CCM_CCOSR_CLKO2_SEL_MASK | CCM_CCOSR_CLKO2_DIV_MASK);
tmp32 |= CCM_CCOSR_CLKO2_SEL(selection) | CCM_CCOSR_CLKO2_DIV(divider);
}
CCM->CCOSR = tmp32;
}
/*!
* brief Get the frequency of clock output1 clock signal.
*
* return The frequency of clock output1 clock signal.
*/
uint32_t CLOCK_GetClockOutCLKO1Freq(void)
{
uint32_t freq = 0U;
uint32_t tmp32;
tmp32 = CCM->CCOSR;
if ((tmp32 & CCM_CCOSR_CLKO1_EN_MASK) != 0UL)
{
switch ((tmp32 & CCM_CCOSR_CLKO1_SEL_MASK) >> CCM_CCOSR_CLKO1_SEL_SHIFT)
{
case (uint32_t)kCLOCK_OutputPllUsb1:
freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 2U;
break;
case (uint32_t)kCLOCK_OutputPllSys:
freq = CLOCK_GetPllFreq(kCLOCK_PllSys) / 2U;
break;
case (uint32_t)kCLOCK_OutputPllVideo:
freq = CLOCK_GetPllFreq(kCLOCK_PllVideo) / 2U;
break;
case (uint32_t)kCLOCK_OutputSemcClk:
freq = CLOCK_GetSemcFreq();
break;
case (uint32_t)kCLOCK_OutputLcdifPixClk:
freq = CLOCK_GetClockRootFreq(kCLOCK_LcdifClkRoot);
break;
case (uint32_t)kCLOCK_OutputAhbClk:
freq = CLOCK_GetAhbFreq();
break;
case (uint32_t)kCLOCK_OutputIpgClk:
freq = CLOCK_GetIpgFreq();
break;
case (uint32_t)kCLOCK_OutputPerClk:
freq = CLOCK_GetPerClkFreq();
break;
case (uint32_t)kCLOCK_OutputCkilSyncClk:
freq = CLOCK_GetRtcFreq();
break;
case (uint32_t)kCLOCK_OutputPll4MainClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllAudio);
break;
default:
/* This branch should never be hit. */
break;
}
freq /= (((tmp32 & CCM_CCOSR_CLKO1_DIV_MASK) >> CCM_CCOSR_CLKO1_DIV_SHIFT) + 1U);
}
else
{
freq = 0UL;
}
return freq;
}
/*!
* brief Get the frequency of clock output2 clock signal.
*
* return The frequency of clock output2 clock signal.
*/
uint32_t CLOCK_GetClockOutClkO2Freq(void)
{
uint32_t freq = 0U;
uint32_t tmp32;
tmp32 = CCM->CCOSR;
if ((tmp32 & CCM_CCOSR_CLKO2_EN_MASK) != 0UL)
{
switch ((tmp32 & CCM_CCOSR_CLKO2_SEL_MASK) >> CCM_CCOSR_CLKO2_SEL_SHIFT)
{
case (uint32_t)kCLOCK_OutputUsdhc1Clk:
freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc1ClkRoot);
break;
case (uint32_t)kCLOCK_OutputLpi2cClk:
freq = CLOCK_GetClockRootFreq(kCLOCK_Lpi2cClkRoot);
break;
case (uint32_t)kCLOCK_OutputCsiClk:
freq = CLOCK_GetClockRootFreq(kCLOCK_CsiClkRoot);
break;
case (uint32_t)kCLOCK_OutputOscClk:
freq = CLOCK_GetOscFreq();
break;
case (uint32_t)kCLOCK_OutputUsdhc2Clk:
freq = CLOCK_GetClockRootFreq(kCLOCK_Usdhc2ClkRoot);
break;
case (uint32_t)kCLOCK_OutputSai1Clk:
freq = CLOCK_GetClockRootFreq(kCLOCK_Sai1ClkRoot);
break;
case (uint32_t)kCLOCK_OutputSai2Clk:
freq = CLOCK_GetClockRootFreq(kCLOCK_Sai2ClkRoot);
break;
case (uint32_t)kCLOCK_OutputSai3Clk:
freq = CLOCK_GetClockRootFreq(kCLOCK_Sai3ClkRoot);
break;
case (uint32_t)kCLOCK_OutputCanClk:
freq = CLOCK_GetClockRootFreq(kCLOCK_CanClkRoot);
break;
case (uint32_t)kCLOCK_OutputFlexspiClk:
freq = CLOCK_GetClockRootFreq(kCLOCK_FlexspiClkRoot);
break;
case (uint32_t)kCLOCK_OutputUartClk:
freq = CLOCK_GetClockRootFreq(kCLOCK_UartClkRoot);
break;
case (uint32_t)kCLOCK_OutputSpdif0Clk:
freq = CLOCK_GetClockRootFreq(kCLOCK_SpdifClkRoot);
break;
default:
/* This branch should never be hit. */
break;
}
freq /= (((tmp32 & CCM_CCOSR_CLKO2_DIV_MASK) >> CCM_CCOSR_CLKO2_DIV_SHIFT) + 1U);
}
else
{
freq = 0UL;
}
return freq;
}

View File

@ -135,16 +135,16 @@ void *SDK_Malloc(size_t size, size_t alignbytes)
p_align_addr = (void *)SDK_SIZEALIGN((uint32_t)p_addr + sizeof(mem_align_cb_t), alignbytes);
p_cb = (mem_align_cb_t *)((uint32_t)p_align_addr - 4);
p_cb = (mem_align_cb_t *)((uint32_t)p_align_addr - 4U);
p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
p_cb->offset = (uint32_t)p_align_addr - (uint32_t)p_addr;
p_cb->offset = (uint32_t)p_align_addr - (uint32_t)p_addr;
return (void *)p_align_addr;
}
void SDK_Free(void *ptr)
{
mem_align_cb_t *p_cb = (mem_align_cb_t *)((uint32_t)ptr - 4);
mem_align_cb_t *p_cb = (mem_align_cb_t *)((uint32_t)ptr - 4U);
if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
{

View File

@ -0,0 +1,161 @@
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file fsl_romapi.c
* @brief support flexspi norflash function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#include "fsl_romapi.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Interface for the ROM FLEXSPI NOR flash driver.
*/
typedef struct
{
uint32_t version;
status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dst_addr, const uint32_t *src);
status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t lengthInBytes);
uint32_t reserved1;
void (*clear_cache)(uint32_t instance);
status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t seqNumber);
uint32_t reserved2;
} flexspi_nor_driver_interface_t;
/*!
* @brief Root of the bootloader api tree.
*
* An instance of this struct resides in read-only memory in the bootloader. It
* provides a user application access to APIs exported by the bootloader.
*
* @note The order of existing fields must not be changed.
*/
typedef struct
{
void (*runBootloader)(void *arg); /*!< Function to start the bootloader executing */
const uint32_t version; /*!< Bootloader version number */
const uint8_t *copyright; /*!< Bootloader Copyright */
const uint32_t reserved0;
flexspi_nor_driver_interface_t *flexSpiNorDriver; /*!< FLEXSPI NOR flash api */
} bootloader_api_entry_t;
/*******************************************************************************
* Variables
******************************************************************************/
#define g_bootloaderTree ((bootloader_api_entry_t *)*(uint32_t *)0x0020001cU)
#define api_flexspi_nor_erase_sector \
((status_t(*)(uint32_t instance, flexspi_nor_config_t * config, uint32_t address))0x002106E7U)
/*******************************************************************************
* Codes
******************************************************************************/
/*******************************************************************************
* ROM FLEXSPI NOR driver
******************************************************************************/
/*!
* @brief Initialize Serial NOR flash via FLEXSPI.
*
* @param instance storge the instance of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
*/
status_t ROM_FLEXSPI_NorFlash_Init(uint32_t instance, flexspi_nor_config_t *config)
{
return g_bootloaderTree->flexSpiNorDriver->init(instance, config);
}
/*!
* @brief Program data to Serial NOR via FLEXSPI.
*
* @param instance storge the instance of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
* @param dstAddr A pointer to the desired flash memory to be programmed.
* @param src A pointer to the source buffer of data that is to be programmed
* into the NOR flash.
*/
status_t ROM_FLEXSPI_NorFlash_ProgramPage(uint32_t instance,
flexspi_nor_config_t *config,
uint32_t dstAddr,
const uint32_t *src)
{
return g_bootloaderTree->flexSpiNorDriver->program(instance, config, dstAddr, src);
}
/*!
* @brief Erase Flash Region specified by address and length.
*
* @param instance storge the index of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
* @param start The start address of the desired NOR flash memory to be erased.
* @param length The length, given in bytes to be erased.
*/
status_t ROM_FLEXSPI_NorFlash_Erase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length)
{
return g_bootloaderTree->flexSpiNorDriver->erase(instance, config, start, length);
}
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR
/*!
* @brief Erase one sector specified by address.
*
* @param instance storge the index of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
* @param start The start address of the desired NOR flash memory to be erased.
*/
status_t ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t start)
{
return api_flexspi_nor_erase_sector(instance, config, start);
}
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR */
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL
/*! @brief Erase all the Serial NOR flash connected on FLEXSPI. */
status_t ROM_FLEXSPI_NorFlash_EraseAll(uint32_t instance, flexspi_nor_config_t *config)
{
return g_bootloaderTree->flexSpiNorDriver->erase_all(instance, config);
}
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL */
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER
/*! @brief FLEXSPI command */
status_t ROM_FLEXSPI_NorFlash_CommandXfer(uint32_t instance, flexspi_xfer_t *xfer)
{
return g_bootloaderTree->flexSpiNorDriver->xfer(instance, xfer);
}
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER */
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT
/*! @brief Configure FLEXSPI Lookup table. */
status_t ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance,
uint32_t seqIndex,
const uint32_t *lutBase,
uint32_t seqNumber)
{
return g_bootloaderTree->flexSpiNorDriver->update_lut(instance, seqIndex, lutBase, seqNumber);
}
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT */
/*! @brief Software reset for the FLEXSPI logic. */
void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance)
{
g_bootloaderTree->flexSpiNorDriver->clear_cache(instance);
}

View File

@ -0,0 +1,60 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file mucboot.c
* @brief support bootloader function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#include <stdint.h>
#include <xs_base.h>
#include "common.h"
#include "mcuboot.h"
#include "flash.h"
#ifdef TOOL_USING_OTA
void mcuboot_bord_init(void)
{
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
UartConfig();
SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
}
void mcuboot_reset(void)
{
__set_FAULTMASK(1);
NVIC_SystemReset();
}
void mcuboot_jump(void)
{
uint32_t addr = XIUOS_FLAH_ADDRESS;
SCB->VTOR = addr;
asm volatile("LDR R0, %0" : : "m"(addr));
asm volatile("LDR R0, [R0]");
asm volatile("MOV SP, R0");
addr += 4;
asm volatile("LDR R0, %0" : : "m"(addr));
asm volatile("LDR R0, [R0]");
asm volatile("BX R0");
}
extern void ImxrtMsDelay(uint32 ms);
void mcuboot_delay(uint32_t ms)
{
ImxrtMsDelay(ms);
}
#endif

View File

@ -0,0 +1,399 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: ymodem.c
* @brief: file ymodem.c
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#include <xs_base.h>
#include "ymodem.h"
#include "string.h"
#include "flash.h"
uint8_t tab_1024[1024] ={0};
uint8_t FileName[FILE_NAME_LENGTH];
/*******************************************************************************
* : Receive_Byte
* :
* : c:
timeout:
* : 0:,-1:
*******************************************************************************/
static int32_t Receive_Byte(uint8_t *c, uint32_t timeout)
{
while(timeout-- > 0)
{
if(SerialKeyPressed(c) == 1)
{
return 0;
}
}
return -1;
}
/*******************************************************************************
* : Send_Byte
* :
* : c:
* : 0
*******************************************************************************/
static uint32_t Send_Byte(uint8_t c)
{
SerialPutChar(c);
return 0;
}
/*******************************************************************************
* : UpdateCRC16
* : CRC16校验
* : crcIn:16crc数据
byte:8
* : crc数据
*******************************************************************************/
uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte)
{
uint32_t crc = crcIn;
uint32_t in = byte|0x100;
do
{
crc <<= 1;
in <<= 1;
if(in&0x100)
{
++crc;
}
if(crc&0x10000)
{
crc ^= 0x1021;
}
} while(!(in&0x10000));
return (crc&0xffffu);
}
/*******************************************************************************
* : Cal_CRC16
* : CRC16,YModem的数据包
* : data:buffer
size:
* : crc数据
*******************************************************************************/
uint16_t Cal_CRC16(const uint8_t* data, uint32_t size)
{
uint32_t crc = 0;
const uint8_t* dataEnd = data+size;
while(data<dataEnd)
{
crc = UpdateCRC16(crc,*data++);
}
crc = UpdateCRC16(crc,0);
crc = UpdateCRC16(crc,0);
return (crc&0xffffu);
}
/*******************************************************************************
* : CalChecksum
* : YModem数据包的总和
* : data:buffer
size:
* :
*******************************************************************************/
uint8_t CalChecksum(const uint8_t* data, uint32_t size)
{
uint32_t sum = 0;
const uint8_t* dataEnd = data+size;
while(data < dataEnd)
{
sum += *data++;
}
return (sum&0xffu);
}
/*******************************************************************************
* : Receive_Packet
* :
* : data:buffer
length:
timeout:
* : 0:,-1://,1:
*******************************************************************************/
static int32_t Receive_Packet(uint8_t *data, int32_t *length, uint32_t timeout)
{
uint16_t i, packet_size, computedcrc;
uint8_t c;
*length = 0;
if(Receive_Byte(&c, timeout) != 0)
{
return -1;
}
switch (c)
{
case SOH:
packet_size = PACKET_SIZE;
break;
case STX:
packet_size = PACKET_1K_SIZE;
break;
case EOT:
return 0;
case CA:
if((Receive_Byte(&c, timeout) == 0) && (c == CA))
{
*length = -1;
return 0;
}
else
{
return -1;
}
case ABORT1:
case ABORT2:
return 1;
default:
return -1;
}
*data = c;
for(i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)
{
if(Receive_Byte(data + i, timeout) != 0)
{
return -1;
}
}
if(data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff))
{
return -1;
}
/* Compute the CRC */
computedcrc = Cal_CRC16(&data[PACKET_HEADER], (uint32_t)packet_size);
/* Check that received CRC match the already computed CRC value
data[packet_size+3]<<8) | data[packet_size+4] contains the received CRC
computedcrc contains the computed CRC value */
if(computedcrc != (uint16_t)((data[packet_size+3]<<8) | data[packet_size+4]))
{
/* CRC error */
return -1;
}
*length = packet_size;
return 0;
}
/*******************************************************************************
* : Ymodem_Receive
* : 使ymodem协议接收文件
* : buf:buffer
addr:flash起始地址
timeout:
* :
*******************************************************************************/
int32_t Ymodem_Receive(uint8_t *buf, const uint32_t addr)
{
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;
uint32_t flashdestination;
/* Initialize flashdestination variable */
flashdestination = addr;
for(session_done = 0, errors = 0, session_begin = 0; ;)
{
for(packets_received = 0, file_done = 0, buf_ptr = buf; ;)
{
switch(Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))
{
case 0:
errors = 0;
switch(packet_length)
{
/* Abort by sender */
case - 1:
Send_Byte(ACK);
return 0;
/* End of transmission */
case 0:
Send_Byte(ACK);
file_done = 1;
break;
/* Normal packet */
default:
if((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
{
Send_Byte(NAK);
}
else
{
if(packets_received == 0)
{
/* Filename packet */
if(packet_data[PACKET_HEADER] != 0)
{
/* Filename packet has valid data */
for(i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
{
FileName[i++] = *file_ptr++;
}
FileName[i++] = '\0';
for(i = 0, file_ptr ++; (*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));)
{
file_size[i++] = *file_ptr++;
}
file_size[i++] = '\0';
Str2Int(file_size, &size);
/* Test the size of the image to be sent */
/* Image size is greater than Flash size */
if(size > APP_FLASH_SIZE)
{
/* End session */
Send_Byte(CA);
Send_Byte(CA);
return -1;
}
/* erase user application area */
NOR_FLASH_Erase(addr,size);
Send_Byte(ACK);
Send_Byte(CRC16);
}
/* Filename packet is empty, end session */
else
{
Send_Byte(ACK);
file_done = 1;
session_done = 1;
break;
}
}
/* Data packet */
else
{
memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
/* Write received data in Flash */
#ifndef USE_HIGHT_SPEED_TRANS
if(NOR_FLASH_Write(&flashdestination, buf, (uint16_t)packet_length) == 0)
#else
if(NOR_FLASH_Write(&flashdestination, buf, (uint16_t)packet_length, 0) == 0)
#endif
{
Send_Byte(ACK);
}
else /* An error occurred while writing to Flash memory */
{
/* End session */
Send_Byte(CA);
Send_Byte(CA);
return -2;
}
}
packets_received ++;
session_begin = 1;
}
}
break;
case 1:
Send_Byte(CA);
Send_Byte(CA);
return -3;
default:
if(session_begin > 0)
{
errors ++;
}
if(errors > MAX_ERRORS)
{
Send_Byte(CA);
Send_Byte(CA);
return 0;
}
Send_Byte(CRC16);
break;
}
if(file_done != 0)
{
break;
}
}
if(session_done != 0)
{
break;
}
}
#ifdef USE_HIGHT_SPEED_TRANS
NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length,1);
#endif
return (int32_t)size;
}
/*******************************************************************************
* : SerialDownload
* :
* : addr:flash起始地址
* :
*******************************************************************************/
int32_t SerialDownload(const uint32_t addr)
{
uint8_t Number[10] = {0};
int32_t Size = 0;
Serial_PutString("Waiting for the file to be sent ... (press 'a' to abort)\n\r");
Size = Ymodem_Receive(&tab_1024[0], addr);
if(Size > 0)
{
Serial_PutString("\n\n\r Programming Completed Successfully!\n\r--------------------------------\r\n Name: ");
Serial_PutString(FileName);
Int2Str(Number, Size);
Serial_PutString("\n\r Size: ");
Serial_PutString(Number);
Serial_PutString(" Bytes\r\n");
Serial_PutString("-------------------\n");
}
else if(Size == -1)
{
Serial_PutString("\n\n\rThe image size is higher than the allowed space memory!\n\r");
}
else if(Size == -2)
{
Serial_PutString("\n\n\rVerification failed!\n\r");
}
else if(Size == -3)
{
Serial_PutString("\r\n\nAborted by user.\n\r");
}
else
{
Serial_PutString("\n\rFailed to receive the file!\n\r");
}
return Size;
}

View File

@ -223,6 +223,12 @@
#define FSL_FEATURE_EDMA_HAS_ERROR_IRQ (1)
/* @brief Number of DMA channels with asynchronous request capability (register EARS). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT (32)
/* @brief Channel IRQ entry shared offset. */
#define FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET (16)
/* @brief If 8 bytes transfer supported. */
#define FSL_FEATURE_EDMA_SUPPORT_8_BYTES_TRANSFER (1)
/* @brief If 16 bytes transfer supported. */
#define FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER (0)
/* DMAMUX module features */
@ -279,6 +285,8 @@
#define FSL_FEATURE_FLEXIO_VERID_RESET_VALUE (0x1010001)
/* @brief Reset value of the FLEXIO_PARAM register */
#define FSL_FEATURE_FLEXIO_PARAM_RESET_VALUE (0x2200404)
/* @brief Flexio DMA request base channel */
#define FSL_FEATURE_FLEXIO_DMA_REQUEST_BASE_CHANNEL (0)
/* FLEXRAM module features */
@ -489,7 +497,10 @@
/* @brief Receive/transmit FIFO size in item count (register bit fields TCSR[FRDE], TCSR[FRIE], TCSR[FRF], TCR1[TFW], RCSR[FRDE], RCSR[FRIE], RCSR[FRF], RCR1[RFW], registers TFRn, RFRn). */
#define FSL_FEATURE_SAI_FIFO_COUNT (32)
/* @brief Receive/transmit channel number (register bit fields TCR3[TCE], RCR3[RCE], registers TDRn and RDRn). */
#define FSL_FEATURE_SAI_CHANNEL_COUNT (4)
#define FSL_FEATURE_SAI_CHANNEL_COUNTn(x) \
(((x) == SAI1) ? (4) : \
(((x) == SAI2) ? (1) : \
(((x) == SAI3) ? (1) : (-1))))
/* @brief Maximum words per frame (register bit fields TCR3[WDFL], TCR4[FRSZ], TMR[TWM], RCR3[WDFL], RCR4[FRSZ], RMR[RWM]). */
#define FSL_FEATURE_SAI_MAX_WORDS_PER_FRAME (32)
/* @brief Has support of combining multiple data channel FIFOs into single channel FIFO (register bit fields TCR3[CFR], TCR4[FCOMB], TFR0[WCP], TFR1[WCP], RCR3[CFR], RCR4[FCOMB], RFR0[RCP], RFR1[RCP]). */
@ -514,6 +525,10 @@
#define FSL_FEATURE_SAI_HAS_MDR (0)
/* @brief Has support the BCLK bypass mode when BCLK = MCLK. */
#define FSL_FEATURE_SAI_HAS_BCLK_BYPASS (0)
/* @brief Has DIV bit fields of MCR register (register bit fields MCR[DIV]. */
#define FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV (0)
/* @brief Support Channel Mode (register bit fields TCR4[CHMOD]). */
#define FSL_FEATURE_SAI_HAS_CHANNEL_MODE (1)
/* SEMC module features */
@ -623,5 +638,7 @@
/* @brief DMA_CH_MUX_REQ_95. */
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_95 (1)
#define FSL_FEATURE_XBARA_INTERRUPT_COUNT (4)
#endif /* _MIMXRT1052_FEATURES_H_ */

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: common.h
* @brief: file common.h
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#ifndef _COMMON_H
#define _COMMON_H
#include "fsl_common.h"
#include "fsl_lpuart.h"
#define CMD_STRING_SIZE 128
#define IS_AF(c) ((c >= 'A') && (c <= 'F'))
#define IS_af(c) ((c >= 'a') && (c <= 'f'))
#define IS_09(c) ((c >= '0') && (c <= '9'))
#define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c)
#define ISVALIDDEC(c) IS_09(c)
#define CONVERTDEC(c) (c - '0')
#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10))
#define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))
void UartConfig(void);
void Int2Str(uint8_t* str,int32_t intnum);
uint32_t Str2Int(uint8_t *inputstr,int32_t *intnum);
uint32_t GetIntegerInput(int32_t * num);
uint32_t SerialKeyPressed(uint8_t *key);
uint8_t GetKey(void);
void SerialPutChar(uint8_t c);
void Serial_PutString(uint8_t *s);
void GetInputString(uint8_t * buffP);
#endif

View File

@ -0,0 +1,84 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file flash.h
* @brief support flexspi norflash function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#ifndef __FLASH_H__
#define __FLASH_H__
#include <xs_base.h>
#include <stdint.h>
#include "fsl_romapi.h"
#define USE_HIGHT_SPEED_TRANS 1
#define SECTOR_SIZE 0x1000
#define FLASH_PAGE_SIZE 256
#define FLEXSPI_WAIT_TIMEOUT_NS (500000000UL) //FlexSPI timeout value, 500ms
#define FLEXSPI_FREQ_1GHz (1000000000UL)
#define FREQ_1MHz (1000000UL)
#define FLEXSPI_DLLCR_DEFAULT (0x100UL)
enum
{
kFlexSpiDelayCellUnit_Min = 75, // 75ps
kFlexSpiDelayCellUnit_Max = 225, // 225ps
};
typedef enum
{
kFlexSpiClock_CoreClock, //ARM Core Clock
kFlexSpiClock_AhbClock, //AHB clock
kFlexSpiClock_SerialRootClock, //Serial Root Clock
kFlexSpiClock_IpgClock, //IPG clock
} flexspi_clock_type_t;
typedef struct LookUpTable
{
uint32_t Read_Seq[4];
uint32_t ReadStatus_Seq[8];
uint32_t WriteEnable_Seq[8];
uint32_t EraseSector_Seq[16];
uint32_t PageProgram_Seq[8];
uint32_t ChipErase_Seq[8];
uint32_t ReadSfdp_Seq[4];
uint32_t Restore_NoCmd_Seq[4];
uint32_t Exit_NoCmd_Seq[4];
}lookuptable_t;
uint32_t FLASH_GetSectorSize(void);
uint32_t FLASH_GetProgramCmd(void);
void FLASH_Init(void);
void FLASH_DeInit(void);
uint8_t FLASH_EraseSector(uint32_t addr);
uint8_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len);
status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len);
status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt);
status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt);
status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len);
status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize);
status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize);
void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
#ifndef USE_HIGHT_SPEED_TRANS
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength);
#else
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength,uint8_t doneFlag);
#endif
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 - 2019 NXP
* Copyright 2017 - 2020, NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@ -47,8 +47,8 @@
/*! @name Driver version */
/*@{*/
/*! @brief CLOCK driver version 2.2.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*! @brief CLOCK driver version 2.4.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 4, 0))
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
@ -56,8 +56,8 @@
#endif
/* analog pll definition */
#define CCM_ANALOG_PLL_BYPASS_SHIFT (16U)
#define CCM_ANALOG_PLL_BYPASS_CLK_SRC_MASK (0xC000U)
#define CCM_ANALOG_PLL_BYPASS_SHIFT (16U)
#define CCM_ANALOG_PLL_BYPASS_CLK_SRC_MASK (0xC000U)
#define CCM_ANALOG_PLL_BYPASS_CLK_SRC_SHIFT (14U)
/*@}*/
@ -65,48 +65,56 @@
/*!
* @brief CCM registers offset.
*/
#define CCSR_OFFSET 0x0C
#define CBCDR_OFFSET 0x14
#define CBCMR_OFFSET 0x18
#define CCSR_OFFSET 0x0C
#define CBCDR_OFFSET 0x14
#define CBCMR_OFFSET 0x18
#define CSCMR1_OFFSET 0x1C
#define CSCMR2_OFFSET 0x20
#define CSCDR1_OFFSET 0x24
#define CDCDR_OFFSET 0x30
#define CDCDR_OFFSET 0x30
#define CSCDR2_OFFSET 0x38
#define CSCDR3_OFFSET 0x3C
#define CACRR_OFFSET 0x10
#define CACRR_OFFSET 0x10
#define CS1CDR_OFFSET 0x28
#define CS2CDR_OFFSET 0x2C
/*!
* @brief CCM Analog registers offset.
*/
#define PLL_ARM_OFFSET 0x00
#define PLL_SYS_OFFSET 0x30
#define PLL_USB1_OFFSET 0x10
#define PLL_ARM_OFFSET 0x00
#define PLL_SYS_OFFSET 0x30
#define PLL_USB1_OFFSET 0x10
#define PLL_AUDIO_OFFSET 0x70
#define PLL_VIDEO_OFFSET 0xA0
#define PLL_ENET_OFFSET 0xE0
#define PLL_USB2_OFFSET 0x20
#define PLL_ENET_OFFSET 0xE0
#define PLL_USB2_OFFSET 0x20
#define CCM_TUPLE(reg, shift, mask, busyShift) \
(int)((reg & 0xFFU) | ((shift) << 8U) | ((((mask) >> (shift)) & 0x1FFFU) << 13U) | ((busyShift) << 26U))
#define CCM_TUPLE_REG(base, tuple) (*((volatile uint32_t *)(((uint32_t)(base)) + ((tuple)&0xFFU))))
#define CCM_TUPLE_SHIFT(tuple) (((tuple) >> 8U) & 0x1FU)
#define CCM_TUPLE_MASK(tuple) ((uint32_t)((((tuple) >> 13U) & 0x1FFFU) << ((((tuple) >> 8U) & 0x1FU))))
#define CCM_TUPLE_BUSY_SHIFT(tuple) (((tuple) >> 26U) & 0x3FU)
(int)(((reg)&0xFFU) | ((shift) << 8U) | ((((mask) >> (shift)) & 0x1FFFU) << 13U) | ((busyShift) << 26U))
#define CCM_TUPLE_REG(base, tuple) (*((volatile uint32_t *)(((uint32_t)(base)) + ((uint32_t)(tuple)&0xFFU))))
#define CCM_TUPLE_SHIFT(tuple) ((((uint32_t)tuple) >> 8U) & 0x1FU)
#define CCM_TUPLE_MASK(tuple) \
((uint32_t)((((uint32_t)(tuple) >> 13U) & 0x1FFFU) << (((((uint32_t)tuple) >> 8U) & 0x1FU))))
#define CCM_TUPLE_BUSY_SHIFT(tuple) ((((uint32_t)tuple) >> 26U) & 0x3FU)
#define CCM_NO_BUSY_WAIT (0x20U)
/*!
* @brief CCM ANALOG tuple macros to map corresponding registers and bit fields.
*/
#define CCM_ANALOG_TUPLE(reg, shift) (((reg & 0xFFFU) << 16U) | (shift))
#define CCM_ANALOG_TUPLE(reg, shift) ((((reg)&0xFFFU) << 16U) | (shift))
#define CCM_ANALOG_TUPLE_SHIFT(tuple) (((uint32_t)tuple) & 0x1FU)
#define CCM_ANALOG_TUPLE_REG_OFF(base, tuple, off) \
(*((volatile uint32_t *)((uint32_t)base + (((uint32_t)tuple >> 16U) & 0xFFFU) + off)))
(*((volatile uint32_t *)((uint32_t)(base) + (((uint32_t)(tuple) >> 16U) & 0xFFFU) + (off))))
#define CCM_ANALOG_TUPLE_REG(base, tuple) CCM_ANALOG_TUPLE_REG_OFF(base, tuple, 0U)
/* Definition for ERRATA 50235 check */
#if (defined(FSL_FEATURE_CCM_HAS_ERRATA_50235) && FSL_FEATURE_CCM_HAS_ERRATA_50235)
#define CAN_CLOCK_CHECK_NO_AFFECTS \
((CCM_CSCMR2_CAN_CLK_SEL(2U) != (CCM->CSCMR2 & CCM_CSCMR2_CAN_CLK_SEL_MASK)) || \
(CCM_CCGR5_CG12(0) != (CCM->CCGR5 & CCM_CCGR5_CG12_MASK)))
#endif /* FSL_FEATURE_CCM_HAS_ERRATA_50235 */
/*!
* @brief clock1PN frequency.
*/
@ -118,8 +126,8 @@
* function CLOCK_SetXtalFreq to set the value in to clock driver. For example,
* if XTAL is 24MHz,
* @code
* CLOCK_InitExternalClk(false); // Setup the 24M OSC/SYSOSC
* CLOCK_SetXtalFreq(240000000); // Set the XTAL value to clock driver.
* CLOCK_InitExternalClk(false);
* CLOCK_SetXtalFreq(240000000);
* @endcode
*/
extern volatile uint32_t g_xtalFreq;
@ -132,7 +140,7 @@ extern volatile uint32_t g_xtalFreq;
extern volatile uint32_t g_rtcXtalFreq;
/* For compatible with other platforms */
#define CLOCK_SetXtal0Freq CLOCK_SetXtalFreq
#define CLOCK_SetXtal0Freq CLOCK_SetXtalFreq
#define CLOCK_SetXtal32Freq CLOCK_SetRtcXtalFreq
/*! @brief Clock ip name array for ADC. */
@ -400,6 +408,65 @@ extern volatile uint32_t g_rtcXtalFreq;
kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_Xbar2, kCLOCK_Xbar3 \
}
#define CLOCK_SOURCE_NONE (0xFFU)
#define CLOCK_ROOT_SOUCE \
{ \
{kCLOCK_SysPllPfd2Clk, kCLOCK_SysPllPfd0Clk, kCLOCK_NoneName, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* USDHC1 Clock Root. */ \
{kCLOCK_SysPllPfd2Clk, kCLOCK_SysPllPfd0Clk, kCLOCK_NoneName, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* USDHC2 Clock Root. */ \
{kCLOCK_SemcClk, kCLOCK_Usb1SwClk, kCLOCK_SysPllPfd2Clk, \
kCLOCK_Usb1PllPfd0Clk, kCLOCK_NoneName, kCLOCK_NoneName}, /* FLEXSPI Clock Root. */ \
{kCLOCK_OscClk, kCLOCK_SysPllPfd2Clk, kCLOCK_Usb1Sw120MClk, \
kCLOCK_Usb1PllPfd1Clk, kCLOCK_NoneName, kCLOCK_NoneName}, /* CSI Clock Root. */ \
{kCLOCK_Usb1PllPfd1Clk, kCLOCK_Usb1PllPfd0Clk, kCLOCK_SysPllClk, \
kCLOCK_SysPllPfd2Clk, kCLOCK_NoneName, kCLOCK_NoneName}, /* LPSPI Clock Root. */ \
{kCLOCK_SysPllClk, kCLOCK_SysPllPfd2Clk, kCLOCK_SysPllPfd0Clk, \
kCLOCK_SysPllPfd1Clk, kCLOCK_NoneName, kCLOCK_NoneName}, /* TRACE Clock Root */ \
{kCLOCK_Usb1PllPfd2Clk, kCLOCK_VideoPllClk, kCLOCK_AudioPllClk, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* SAI1 Clock Root */ \
{kCLOCK_Usb1PllPfd2Clk, kCLOCK_VideoPllClk, kCLOCK_AudioPllClk, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* SAI2 Clock Root */ \
{kCLOCK_Usb1PllPfd2Clk, kCLOCK_VideoPllClk, kCLOCK_AudioPllClk, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* SAI3 Clock Root */ \
{kCLOCK_Usb1Sw60MClk, kCLOCK_OscClk, kCLOCK_NoneName, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* LPI2C Clock Root */ \
{kCLOCK_Usb1Sw60MClk, kCLOCK_OscClk, kCLOCK_Usb1Sw80MClk, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* CAN Clock Root. */ \
{kCLOCK_Usb1Sw80MClk, kCLOCK_OscClk, kCLOCK_NoneName, \
kCLOCK_NoneName, kCLOCK_NoneName, kCLOCK_NoneName}, /* UART Clock Root */ \
{kCLOCK_SysPllClk, kCLOCK_Usb1PllPfd3Clk, kCLOCK_VideoPllClk, \
kCLOCK_SysPllPfd0Clk, kCLOCK_SysPllPfd1Clk, kCLOCK_Usb1PllPfd1Clk}, /* LCDIF Clock Root */ \
{kCLOCK_AudioPllClk, kCLOCK_Usb1PllPfd2Clk, kCLOCK_VideoPllClk, \
kCLOCK_Usb1SwClk, kCLOCK_NoneName, kCLOCK_NoneName}, /* SPDIF0 Clock Root */ \
{kCLOCK_AudioPllClk, kCLOCK_Usb1PllPfd2Clk, kCLOCK_VideoPllClk, \
kCLOCK_Usb1SwClk, kCLOCK_NoneName, kCLOCK_NoneName}, /* FLEXIO1 Clock Root */ \
{kCLOCK_AudioPllClk, kCLOCK_Usb1PllPfd2Clk, kCLOCK_VideoPllClk, \
kCLOCK_Usb1PllClk, kCLOCK_NoneName, kCLOCK_NoneName}, /* FLEXIO2 Clock ROOT */ \
}
#define CLOCK_ROOT_MUX_TUPLE \
{ \
kCLOCK_Usdhc1Mux, kCLOCK_Usdhc2Mux, kCLOCK_FlexspiMux, kCLOCK_CsiMux, kCLOCK_LpspiMux, kCLOCK_TraceMux, \
kCLOCK_Sai1Mux, kCLOCK_Sai2Mux, kCLOCK_Sai3Mux, kCLOCK_Lpi2cMux, kCLOCK_CanMux, kCLOCK_UartMux, \
kCLOCK_LcdifPreMux, kCLOCK_SpdifMux, kCLOCK_Flexio1Mux, kCLOCK_Flexio2Mux, \
}
#define CLOCK_ROOT_NONE_PRE_DIV 0UL
#define CLOCK_ROOT_DIV_TUPLE \
{ \
{kCLOCK_NonePreDiv, kCLOCK_Usdhc1Div}, {kCLOCK_NonePreDiv, kCLOCK_Usdhc2Div}, \
{kCLOCK_NonePreDiv, kCLOCK_FlexspiDiv}, {kCLOCK_NonePreDiv, kCLOCK_CsiDiv}, \
{kCLOCK_NonePreDiv, kCLOCK_LpspiDiv}, {kCLOCK_NonePreDiv, kCLOCK_TraceDiv}, \
{kCLOCK_Sai1PreDiv, kCLOCK_Sai1Div}, {kCLOCK_Sai2PreDiv, kCLOCK_Sai2Div}, \
{kCLOCK_Sai3PreDiv, kCLOCK_Sai3Div}, {kCLOCK_NonePreDiv, kCLOCK_Lpi2cDiv}, \
{kCLOCK_NonePreDiv, kCLOCK_CanDiv}, {kCLOCK_NonePreDiv, kCLOCK_UartDiv}, \
{kCLOCK_LcdifPreDiv, kCLOCK_LcdifDiv}, {kCLOCK_Spdif0PreDiv, kCLOCK_Spdif0Div}, \
{kCLOCK_Flexio1PreDiv, kCLOCK_Flexio1Div}, {kCLOCK_Flexio2PreDiv, kCLOCK_Flexio2Div}, \
}
/*! @brief Clock name used to get clock frequency. */
typedef enum _clock_name
{
@ -414,11 +481,15 @@ typedef enum _clock_name
kCLOCK_ArmPllClk = 0x7U, /*!< ARMPLLCLK. */
kCLOCK_Usb1PllClk = 0x8U, /*!< USB1PLLCLK. */
kCLOCK_Usb1PllPfd0Clk = 0x9U, /*!< USB1PLLPDF0CLK. */
kCLOCK_Usb1PllPfd1Clk = 0xAU, /*!< USB1PLLPFD1CLK. */
kCLOCK_Usb1PllPfd2Clk = 0xBU, /*!< USB1PLLPFD2CLK. */
kCLOCK_Usb1PllPfd3Clk = 0xCU, /*!< USB1PLLPFD3CLK. */
kCLOCK_Usb1PllClk = 0x8U, /*!< USB1PLLCLK. */
kCLOCK_Usb1PllPfd0Clk = 0x9U, /*!< USB1PLLPDF0CLK. */
kCLOCK_Usb1PllPfd1Clk = 0xAU, /*!< USB1PLLPFD1CLK. */
kCLOCK_Usb1PllPfd2Clk = 0xBU, /*!< USB1PLLPFD2CLK. */
kCLOCK_Usb1PllPfd3Clk = 0xCU, /*!< USB1PLLPFD3CLK. */
kCLOCK_Usb1SwClk = 0x17U, /*!< USB1PLLSWCLK */
kCLOCK_Usb1Sw120MClk = 0x18U, /*!< USB1PLLSw120MCLK */
kCLOCK_Usb1Sw60MClk = 0x19U, /*!< USB1PLLSw60MCLK */
kCLOCK_Usb1Sw80MClk = 0x1AU, /*!< USB1PLLSw80MCLK */
kCLOCK_Usb2PllClk = 0xDU, /*!< USB2PLLCLK. */
@ -431,11 +502,12 @@ typedef enum _clock_name
kCLOCK_EnetPll0Clk = 0x13U, /*!< Enet PLLCLK ref_enetpll0. */
kCLOCK_EnetPll1Clk = 0x14U, /*!< Enet PLLCLK ref_enetpll1. */
kCLOCK_AudioPllClk = 0x15U, /*!< Audio PLLCLK. */
kCLOCK_VideoPllClk = 0x16U, /*!< Video PLLCLK. */
kCLOCK_AudioPllClk = 0x15U, /*!< Audio PLLCLK. */
kCLOCK_VideoPllClk = 0x16U, /*!< Video PLLCLK. */
kCLOCK_NoneName = CLOCK_SOURCE_NONE, /*!< None Clock Name. */
} clock_name_t;
#define kCLOCK_CoreSysClk kCLOCK_CpuClk /*!< For compatible with other platforms without CCM. */
#define kCLOCK_CoreSysClk kCLOCK_CpuClk /*!< For compatible with other platforms without CCM. */
#define CLOCK_GetCoreSysClkFreq CLOCK_GetCpuClkFreq /*!< For compatible with other platforms without CCM. */
/*!
@ -835,6 +907,8 @@ typedef enum _clock_div
kCLOCK_CsiDiv = CCM_TUPLE(
CSCDR3_OFFSET, CCM_CSCDR3_CSI_PODF_SHIFT, CCM_CSCDR3_CSI_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< csi div name */
kCLOCK_NonePreDiv = CLOCK_ROOT_NONE_PRE_DIV, /*!< None Pre div. */
} clock_div_t;
/*! @brief USB clock source definition. */
@ -952,6 +1026,83 @@ typedef enum _clock_pfd
kCLOCK_Pfd3 = 3U, /*!< PLL PFD3 */
} clock_pfd_t;
/*!
* @brief The enumerater of clock output1's clock source, such as USB1 PLL, SYS PLL and so on.
*/
typedef enum _clock_output1_selection
{
kCLOCK_OutputPllUsb1 = 0U, /*!< Selects USB1 PLL clock(Divided by 2) output. */
kCLOCK_OutputPllSys = 1U, /*!< Selects SYS PLL clock(Divided by 2) output. */
kCLOCK_OutputPllVideo = 3U, /*!< Selects Video PLL clock(Divided by 2) output. */
kCLOCK_OutputSemcClk = 5U, /*!< Selects semc clock root output. */
kCLOCK_OutputLcdifPixClk = 0xAU, /*!< Selects Lcdif pix clock root output. */
kCLOCK_OutputAhbClk = 0xBU, /*!< Selects AHB clock root output. */
kCLOCK_OutputIpgClk = 0xCU, /*!< Selects IPG clock root output. */
kCLOCK_OutputPerClk = 0xDU, /*!< Selects PERCLK clock root output. */
kCLOCK_OutputCkilSyncClk = 0xEU, /*!< Selects Ckil clock root output. */
kCLOCK_OutputPll4MainClk = 0xFU, /*!< Selects PLL4 main clock output. */
kCLOCK_DisableClockOutput1 = 0x10U, /*!< Disables CLKO1. */
} clock_output1_selection_t;
/*!
* @brief The enumerater of clock output2's clock source, such as USDHC1 clock root, LPI2C clock root and so on.
*
*/
typedef enum _clock_output2_selection
{
kCLOCK_OutputUsdhc1Clk = 3U, /*!< Selects USDHC1 clock root output. */
kCLOCK_OutputLpi2cClk = 6U, /*!< Selects LPI2C clock root output. */
kCLOCK_OutputCsiClk = 0xBU, /*!< Selects CSI clock root output. */
kCLOCK_OutputOscClk = 0xEU, /*!< Selects OSC output. */
kCLOCK_OutputUsdhc2Clk = 0x11U, /*!< Selects USDHC2 clock root output. */
kCLOCK_OutputSai1Clk = 0x12U, /*!< Selects SAI1 clock root output. */
kCLOCK_OutputSai2Clk = 0x13U, /*!< Selects SAI2 clock root output. */
kCLOCK_OutputSai3Clk = 0x14U, /*!< Selects SAI3 clock root output. */
kCLOCK_OutputCanClk = 0x17U, /*!< Selects CAN clock root output. */
kCLOCK_OutputFlexspiClk = 0x1BU, /*!< Selects FLEXSPI clock root output. */
kCLOCK_OutputUartClk = 0x1CU, /*!< Selects UART clock root output. */
kCLOCK_OutputSpdif0Clk = 0x1DU, /*!< Selects SPDIF0 clock root output. */
kCLOCK_DisableClockOutput2 = 0x1FU, /*!< Disables CLKO2. */
} clock_output2_selection_t;
/*!
* @brief The enumerator of clock output's divider.
*/
typedef enum _clock_output_divider
{
kCLOCK_DivideBy1 = 0U, /*!< Output clock divided by 1. */
kCLOCK_DivideBy2, /*!< Output clock divided by 2. */
kCLOCK_DivideBy3, /*!< Output clock divided by 3. */
kCLOCK_DivideBy4, /*!< Output clock divided by 4. */
kCLOCK_DivideBy5, /*!< Output clock divided by 5. */
kCLOCK_DivideBy6, /*!< Output clock divided by 6. */
kCLOCK_DivideBy7, /*!< Output clock divided by 7. */
kCLOCK_DivideBy8, /*!< Output clock divided by 8. */
} clock_output_divider_t;
/*!
* @brief The enumerator of clock root.
*/
typedef enum _clock_root
{
kCLOCK_Usdhc1ClkRoot = 0U, /*!< USDHC1 clock root. */
kCLOCK_Usdhc2ClkRoot, /*!< USDHC2 clock root. */
kCLOCK_FlexspiClkRoot, /*!< FLEXSPI clock root. */
kCLOCK_CsiClkRoot, /*!< CSI clock root. */
kCLOCK_LpspiClkRoot, /*!< LPSPI clock root. */
kCLOCK_TraceClkRoot, /*!< Trace clock root. */
kCLOCK_Sai1ClkRoot, /*!< SAI1 clock root. */
kCLOCK_Sai2ClkRoot, /*!< SAI2 clock root. */
kCLOCK_Sai3ClkRoot, /*!< SAI3 clock root. */
kCLOCK_Lpi2cClkRoot, /*!< LPI2C clock root. */
kCLOCK_CanClkRoot, /*!< CAN clock root. */
kCLOCK_UartClkRoot, /*!< UART clock root. */
kCLOCK_LcdifClkRoot, /*!< LCD clock root. */
kCLOCK_SpdifClkRoot, /*!< SPDIF clock root. */
kCLOCK_Flexio1ClkRoot, /*!< FLEXIO1 clock root. */
kCLOCK_Flexio2ClkRoot, /*!< FLEXIO2 clock root. */
} clock_root_t;
/*******************************************************************************
* API
******************************************************************************/
@ -970,7 +1121,7 @@ static inline void CLOCK_SetMux(clock_mux_t mux, uint32_t value)
{
uint32_t busyShift;
busyShift = CCM_TUPLE_BUSY_SHIFT(mux);
busyShift = (uint32_t)CCM_TUPLE_BUSY_SHIFT(mux);
CCM_TUPLE_REG(CCM, mux) = (CCM_TUPLE_REG(CCM, mux) & (~CCM_TUPLE_MASK(mux))) |
(((uint32_t)((value) << CCM_TUPLE_SHIFT(mux))) & CCM_TUPLE_MASK(mux));
@ -980,7 +1131,7 @@ static inline void CLOCK_SetMux(clock_mux_t mux, uint32_t value)
if (CCM_NO_BUSY_WAIT != busyShift)
{
/* Wait until CCM internal handshake finish. */
while (CCM->CDHIPR & (1U << busyShift))
while ((CCM->CDHIPR & ((1UL << busyShift))) != 0UL)
{
}
}
@ -994,7 +1145,7 @@ static inline void CLOCK_SetMux(clock_mux_t mux, uint32_t value)
*/
static inline uint32_t CLOCK_GetMux(clock_mux_t mux)
{
return (CCM_TUPLE_REG(CCM, mux) & CCM_TUPLE_MASK(mux)) >> CCM_TUPLE_SHIFT(mux);
return (((uint32_t)(CCM_TUPLE_REG(CCM, mux) & CCM_TUPLE_MASK(mux))) >> CCM_TUPLE_SHIFT(mux));
}
/*!
@ -1017,7 +1168,7 @@ static inline void CLOCK_SetDiv(clock_div_t divider, uint32_t value)
if (CCM_NO_BUSY_WAIT != busyShift)
{
/* Wait until CCM internal handshake finish. */
while (CCM->CDHIPR & (1U << busyShift))
while ((CCM->CDHIPR & ((uint32_t)(1UL << busyShift))) != 0UL)
{
}
}
@ -1030,7 +1181,7 @@ static inline void CLOCK_SetDiv(clock_div_t divider, uint32_t value)
*/
static inline uint32_t CLOCK_GetDiv(clock_div_t divider)
{
return ((CCM_TUPLE_REG(CCM, divider) & CCM_TUPLE_MASK(divider)) >> CCM_TUPLE_SHIFT(divider));
return ((uint32_t)(CCM_TUPLE_REG(CCM, divider) & CCM_TUPLE_MASK(divider)) >> CCM_TUPLE_SHIFT(divider));
}
/*!
@ -1045,10 +1196,10 @@ static inline void CLOCK_ControlGate(clock_ip_name_t name, clock_gate_value_t va
uint32_t shift = ((uint32_t)name) & 0x1FU;
volatile uint32_t *reg;
assert(index <= 6);
assert(index <= 6UL);
reg = ((volatile uint32_t *)&CCM->CCGR0) + index;
*reg = ((*reg) & ~(3U << shift)) | (((uint32_t)value) << shift);
reg = (volatile uint32_t *)(&(((volatile uint32_t *)&CCM->CCGR0)[index]));
*reg = ((*reg) & ~((uint32_t)(3UL << shift))) | (((uint32_t)value) << shift);
}
/*!
@ -1087,13 +1238,11 @@ static inline void CLOCK_SetMode(clock_mode_t mode)
* This function will return the external XTAL OSC frequency if it is selected as the source of OSC,
* otherwise internal 24MHz RC OSC frequency will be returned.
*
* @param osc OSC type to get frequency.
*
* @return Clock frequency; If the clock is invalid, returns 0.
*/
static inline uint32_t CLOCK_GetOscFreq(void)
{
return (XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_OSC_SEL_MASK) ? 24000000UL : g_xtalFreq;
return ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_OSC_SEL_MASK) != 0UL) ? 24000000UL : g_xtalFreq;
}
/*!
@ -1130,7 +1279,7 @@ uint32_t CLOCK_GetPerClkFreq(void);
* This function checks the current clock configurations and then calculates
* the clock frequency for a specific clock name defined in clock_name_t.
*
* @param clockName Clock names defined in clock_name_t
* @param name Clock names defined in clock_name_t
* @return Clock frequency value in hertz
*/
uint32_t CLOCK_GetFreq(clock_name_t name);
@ -1145,6 +1294,14 @@ static inline uint32_t CLOCK_GetCpuClkFreq(void)
return CLOCK_GetFreq(kCLOCK_CpuClk);
}
/*!
* @brief Gets the frequency of selected clock root.
*
* @param clockRoot The clock root used to get the frequency, please refer to @ref clock_root_t.
* @return The frequency of selected clock root.
*/
uint32_t CLOCK_GetClockRootFreq(clock_root_t clockRoot);
/*!
* @name OSC operations
* @{
@ -1157,7 +1314,7 @@ static inline uint32_t CLOCK_GetCpuClkFreq(void)
* 1. Use external crystal oscillator.
* 2. Bypass the external crystal oscillator, using input source clock directly.
*
* After this function, please call @ref CLOCK_SetXtal0Freq to inform clock driver
* After this function, please call CLOCK_SetXtal0Freq to inform clock driver
* the external clock frequency.
*
* @param bypassXtalOsc Pass in true to bypass the external crystal oscillator.
@ -1171,7 +1328,7 @@ void CLOCK_InitExternalClk(bool bypassXtalOsc);
*
* This function disables the external 24MHz clock.
*
* After this function, please call @ref CLOCK_SetXtal0Freq to set external clock
* After this function, please call CLOCK_SetXtal0Freq to set external clock
* frequency to 0.
*/
void CLOCK_DeinitExternalClk(void);
@ -1229,7 +1386,7 @@ void CLOCK_DeinitRcOsc24M(void);
/*! @brief Enable USB HS clock.
*
* This function only enables the access to USB HS prepheral, upper layer
* should first call the @ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
* should first call the CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
* clock to use USB HS.
*
* @param src USB HS does not care about the clock source, here must be @ref kCLOCK_UsbSrcUnused.
@ -1242,7 +1399,7 @@ bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq);
/*! @brief Enable USB HS clock.
*
* This function only enables the access to USB HS prepheral, upper layer
* should first call the @ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
* should first call the CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
* clock to use USB HS.
*
* @param src USB HS does not care about the clock source, here must be @ref kCLOCK_UsbSrcUnused.
@ -1252,12 +1409,6 @@ bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq);
*/
bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq);
/*! @brief Disable USB HS PHY PLL clock.
*
* This function disables USB HS PHY PLL clock.
*/
void CLOCK_DisableUsbhs1PhyPllClock(void);
/* @} */
/*!
@ -1277,11 +1428,11 @@ static inline void CLOCK_SetPllBypass(CCM_ANALOG_Type *base, clock_pll_t pll, bo
{
if (bypass)
{
CCM_ANALOG_TUPLE_REG_OFF(base, pll, 4U) = 1U << CCM_ANALOG_PLL_BYPASS_SHIFT;
CCM_ANALOG_TUPLE_REG_OFF(base, pll, 4U) = 1UL << CCM_ANALOG_PLL_BYPASS_SHIFT;
}
else
{
CCM_ANALOG_TUPLE_REG_OFF(base, pll, 8U) = 1U << CCM_ANALOG_PLL_BYPASS_SHIFT;
CCM_ANALOG_TUPLE_REG_OFF(base, pll, 8U) = 1UL << CCM_ANALOG_PLL_BYPASS_SHIFT;
}
}
@ -1296,7 +1447,7 @@ static inline void CLOCK_SetPllBypass(CCM_ANALOG_Type *base, clock_pll_t pll, bo
*/
static inline bool CLOCK_IsPllBypassed(CCM_ANALOG_Type *base, clock_pll_t pll)
{
return (bool)(CCM_ANALOG_TUPLE_REG(base, pll) & (1U << CCM_ANALOG_PLL_BYPASS_SHIFT));
return (bool)(CCM_ANALOG_TUPLE_REG(base, pll) & (1UL << CCM_ANALOG_PLL_BYPASS_SHIFT));
}
/*!
@ -1310,7 +1461,7 @@ static inline bool CLOCK_IsPllBypassed(CCM_ANALOG_Type *base, clock_pll_t pll)
*/
static inline bool CLOCK_IsPllEnabled(CCM_ANALOG_Type *base, clock_pll_t pll)
{
return (bool)(CCM_ANALOG_TUPLE_REG(base, pll) & (1U << CCM_ANALOG_TUPLE_SHIFT(pll)));
return ((CCM_ANALOG_TUPLE_REG(base, pll) & (1UL << CCM_ANALOG_TUPLE_SHIFT(pll))) != 0U);
}
/*!
@ -1337,7 +1488,7 @@ static inline void CLOCK_SetPllBypassRefClkSrc(CCM_ANALOG_Type *base, clock_pll_
static inline uint32_t CLOCK_GetPllBypassRefClk(CCM_ANALOG_Type *base, clock_pll_t pll)
{
return (((CCM_ANALOG_TUPLE_REG(base, pll) & CCM_ANALOG_PLL_BYPASS_CLK_SRC_MASK) >>
CCM_ANALOG_PLL_BYPASS_CLK_SRC_SHIFT) == kCLOCK_PllClkSrc24M) ?
CCM_ANALOG_PLL_BYPASS_CLK_SRC_SHIFT) == (uint32_t)kCLOCK_PllClkSrc24M) ?
CLOCK_GetOscFreq() :
CLKPN_FREQ;
}
@ -1547,18 +1698,45 @@ bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq);
*/
void CLOCK_DisableUsbhs1PhyPllClock(void);
/*!
* @brief Use DWT to delay at least for some time.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
/* @} */
/*!
* @name Clock Output Inferfaces
* @{
*/
/*!
* @brief Set the clock source and the divider of the clock output1.
*
* @param selection The clock source to be output, please refer to @ref clock_output1_selection_t.
* @param divider The divider of the output clock signal, please refer to @ref clock_output_divider_t.
*/
void CLOCK_SetClockOutput1(clock_output1_selection_t selection, clock_output_divider_t divider);
/*!
* @brief Set the clock source and the divider of the clock output2.
*
* @param selection The clock source to be output, please refer to @ref clock_output2_selection_t.
* @param divider The divider of the output clock signal, please refer to @ref clock_output_divider_t.
*/
void CLOCK_SetClockOutput2(clock_output2_selection_t selection, clock_output_divider_t divider);
/*!
* @brief Get the frequency of clock output1 clock signal.
*
* @return The frequency of clock output1 clock signal.
*/
uint32_t CLOCK_GetClockOutCLKO1Freq(void);
/*!
* @brief Get the frequency of clock output2 clock signal.
*
* @return The frequency of clock output2 clock signal.
*/
uint32_t CLOCK_GetClockOutClkO2Freq(void);
/*! @} */
#if defined(__cplusplus)
}
#endif /* __cplusplus */

View File

@ -47,7 +47,7 @@
/*! @name Driver version */
/*@{*/
/*! @brief common driver version 2.0.1. */
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
/*@}*/
/* Debug console type definition. */
@ -131,6 +131,7 @@ enum _status_groups
kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */
kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */
kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */
kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */
kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
@ -157,6 +158,9 @@ enum _status_groups
kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */
kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */
kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */
kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */
kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/
kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */
};
/*! @brief Generic status return codes. */
@ -174,20 +178,6 @@ enum _generic_status
/*! @brief Type used for all status and error return values. */
typedef int32_t status_t;
/*
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
* defined in previous of this file.
*/
#include "fsl_clock.h"
/*
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
*/
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
#include "fsl_reset.h"
#endif
/*
* Macro guard for whether to use default weak IRQ implementation in drivers
*/
@ -198,11 +188,11 @@ typedef int32_t status_t;
/*! @name Min/max macros */
/* @{ */
#if !defined(MIN)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#if !defined(MAX)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
/* @} */
@ -394,6 +384,21 @@ _Pragma("diag_suppress=Pm120")
#error Toolchain not supported.
#endif /* defined(__ICCARM__) */
/* @} */
/*
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
* defined in previous of this file.
*/
#include "fsl_clock.h"
/*
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
*/
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
#include "fsl_reset.h"
#endif
/*******************************************************************************
* API
******************************************************************************/
@ -489,6 +494,9 @@ _Pragma("diag_suppress=Pm120")
*/
static inline uint32_t DisableGlobalIRQ(void)
{
#if defined (__XCC__)
return 0;
#else
#if defined(CPSR_I_Msk)
uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
@ -501,6 +509,7 @@ _Pragma("diag_suppress=Pm120")
__disable_irq();
return regPrimask;
#endif
#endif
}
@ -516,10 +525,13 @@ _Pragma("diag_suppress=Pm120")
*/
static inline void EnableGlobalIRQ(uint32_t primask)
{
#if defined (__XCC__)
#else
#if defined(CPSR_I_Msk)
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
#else
__set_PRIMASK(primask);
#endif
#endif
}

View File

@ -30,8 +30,8 @@
/*! @name Driver version */
/*@{*/
/*! @brief GPIO driver version 2.0.1. */
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*! @brief GPIO driver version 2.0.2. */
#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
/*@}*/
/*! @brief GPIO direction definition. */

View File

@ -30,8 +30,8 @@
/*! @name Driver version */
/*@{*/
/*! @brief LPUART driver version 2.2.6. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 6))
/*! @brief LPUART driver version 2.2.7. */
#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 7))
/*@}*/
/*! @brief Error codes for the LPUART driver. */
@ -166,9 +166,8 @@ enum _lpuart_flags
(LPUART_STAT_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */
kLPUART_ParityErrorFlag = (LPUART_STAT_PF_MASK), /*!< If parity enabled, sets upon parity error detection */
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
kLPUART_LinBreakFlag =
(int)(LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break char
detected and LIN circuit enabled */
kLPUART_LinBreakFlag = (int)(LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break
char detected and LIN circuit enabled */
#endif
kLPUART_RxActiveEdgeFlag =
(LPUART_STAT_RXEDGIF_MASK), /*!< Receive pin active edge interrupt flag, sets when active edge detected */
@ -624,7 +623,7 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
return base->DATA;
}
#else
return base->DATA;
return (uint8_t)(base->DATA);
#endif
}

View File

@ -0,0 +1,570 @@
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file fsl_romapi.h
* @brief support flexspi norflash function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#ifndef _FSL_ROMAPI_H_
#define _FSL_ROMAPI_H_
#include "fsl_common.h"
/*!
* @addtogroup romapi
* @{
*/
/*! @brief ROMAPI version 1.1.1. */
#define FSL_ROM_ROMAPI_VERSION (MAKE_VERSION(1U, 1U, 1U))
/*! @brief ROM FLEXSPI NOR driver version 1.4.0. */
#define FSL_ROM_FLEXSPINOR_DRIVER_VERSION (MAKE_VERSION(1U, 4U, 0U))
/*!
* @name Common ROMAPI fearures info defines
* @{
*/
/* @brief ROM has FLEXSPI NOR API. */
#define FSL_ROM_HAS_FLEXSPINOR_API (1)
/* @brief ROM has run bootloader API. */
#define FSL_ROM_HAS_RUNBOOTLOADER_API (0)
/* @brief ROM has FLEXSPI NOR get config API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_GET_CONFIG (0)
/* @brief ROM has flash init API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_FLASH_INIT (1)
/* @brief ROM has erase API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE (1)
/* @brief ROM has erase sector API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR (1)
/* @brief ROM has erase block API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_BLOCK (0)
/* @brief ROM has erase all API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL (1)
/* @brief ROM has page program API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_PAGE_PROGRAM (1)
/* @brief ROM has update lut API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT (1)
/* @brief ROM has FLEXSPI command API. */
#define FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER (1)
/*@}*/
#define kROM_StatusGroup_FLEXSPI 60U /*!< ROM FLEXSPI status group number.*/
#define kROM_StatusGroup_FLEXSPINOR 200U /*!< ROM FLEXSPI NOR status group number.*/
#define FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
(FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \
FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
/*! @brief Generate bit mask */
#define FSL_ROM_FLEXSPI_BITMASK(bit_offset) (1U << (bit_offset))
/*! @brief FLEXSPI memory config block related defintions */
#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) /*!< ascii "FCFB" Big Endian */
#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) /*!< V1.4.0 */
#define CMD_SDR 0x01U
#define CMD_DDR 0x21U
#define RADDR_SDR 0x02U
#define RADDR_DDR 0x22U
#define CADDR_SDR 0x03U
#define CADDR_DDR 0x23U
#define MODE1_SDR 0x04U
#define MODE1_DDR 0x24U
#define MODE2_SDR 0x05U
#define MODE2_DDR 0x25U
#define MODE4_SDR 0x06U
#define MODE4_DDR 0x26U
#define MODE8_SDR 0x07U
#define MODE8_DDR 0x27U
#define WRITE_SDR 0x08U
#define WRITE_DDR 0x28U
#define READ_SDR 0x09U
#define READ_DDR 0x29U
#define LEARN_SDR 0x0AU
#define LEARN_DDR 0x2AU
#define DATSZ_SDR 0x0BU
#define DATSZ_DDR 0x2BU
#define DUMMY_SDR 0x0CU
#define DUMMY_DDR 0x2CU
#define DUMMY_RWDS_SDR 0x0DU
#define DUMMY_RWDS_DDR 0x2DU
#define JMP_ON_CS 0x1FU
#define STOP 0U
#define FLEXSPI_1PAD 0U
#define FLEXSPI_2PAD 1U
#define FLEXSPI_4PAD 2U
#define FLEXSPI_8PAD 3U
/* Lookup table related defintions */
#define NOR_CMD_INDEX_READ 0U
#define NOR_CMD_INDEX_READSTATUS 1U
#define NOR_CMD_INDEX_WRITEENABLE 2U
#define NOR_CMD_INDEX_ERASESECTOR 3U
#define NOR_CMD_INDEX_PAGEPROGRAM 4U
#define NOR_CMD_INDEX_CHIPERASE 5U
#define NOR_CMD_INDEX_DUMMY 6U
#define NOR_CMD_INDEX_ERASEBLOCK 7U
/*!
* NOR LUT sequence index used for default LUT assignment
* NOTE:
* The will take effect if the lut sequences are not customized.
*/
#define NOR_CMD_LUT_SEQ_IDX_READ 0U /*!< READ LUT sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS 1U /*!< Read Status LUT sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \
2U /*!< Read status DPI/QPI/OPI sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3U /*!< Write Enable sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \
4U /*!< Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5U /*!< Erase Sector sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8U /*!< Erase Block sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9U /*!< Program sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11U /*!< Chip Erase sequence in lookupTable id stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13U /*!< Read SFDP sequence in lookupTable id stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \
14U /*!< Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \
15U /*!< Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk */
/*!
* @name Support for init FLEXSPI NOR configuration
* @{
*/
/*! @brief Flash Pad Definitions */
enum
{
kSerialFlash_1Pad = 1U,
kSerialFlash_2Pads = 2U,
kSerialFlash_4Pads = 4U,
kSerialFlash_8Pads = 8U,
};
/*! @brief FLEXSPI clock configuration type */
enum
{
kFLEXSPIClk_SDR, /*!< Clock configure for SDR mode */
kFLEXSPIClk_DDR, /*!< Clock configurat for DDR mode */
};
/*! @brief FLEXSPI Read Sample Clock Source definition */
enum _flexspi_read_sample_clk
{
kFLEXSPIReadSampleClk_LoopbackInternally = 0U,
kFLEXSPIReadSampleClk_LoopbackFromDqsPad = 1U,
kFLEXSPIReadSampleClk_LoopbackFromSckPad = 2U,
kFLEXSPIReadSampleClk_ExternalInputFromDqsPad = 3U,
};
/*! @brief Flash Type Definition */
enum
{
kFLEXSPIDeviceType_SerialNOR = 1U, /*!< Flash device is Serial NOR */
};
/*! @brief Flash Configuration Command Type */
enum
{
kDeviceConfigCmdType_Generic, /*!< Generic command, for example: configure dummy cycles, drive strength, etc */
kDeviceConfigCmdType_QuadEnable, /*!< Quad Enable command */
kDeviceConfigCmdType_Spi2Xpi, /*!< Switch from SPI to DPI/QPI/OPI mode */
kDeviceConfigCmdType_Xpi2Spi, /*!< Switch from DPI/QPI/OPI to SPI mode */
kDeviceConfigCmdType_Spi2NoCmd, /*!< Switch to 0-4-4/0-8-8 mode */
kDeviceConfigCmdType_Reset, /*!< Reset device command */
};
/*! @brief Defintions for FLEXSPI Serial Clock Frequency */
enum _flexspi_serial_clk_freq
{
kFLEXSPISerialClk_NoChange = 0U,
kFLEXSPISerialClk_30MHz = 1U,
kFLEXSPISerialClk_50MHz = 2U,
kFLEXSPISerialClk_60MHz = 3U,
kFLEXSPISerialClk_75MHz = 4U,
kFLEXSPISerialClk_80MHz = 5U,
kFLEXSPISerialClk_100MHz = 6U,
kFLEXSPISerialClk_133MHz = 7U,
kFLEXSPISerialClk_166MHz = 8U,
kFLEXSPISerialClk_200MHz = 9U,
};
/*! @brief Misc feature bit definitions */
enum
{
kFLEXSPIMiscOffset_DiffClkEnable = 0U, /*!< Bit for Differential clock enable */
kFLEXSPIMiscOffset_Ck2Enable = 1U, /*!< Bit for CK2 enable */
kFLEXSPIMiscOffset_ParallelEnable = 2U, /*!< Bit for Parallel mode enable */
kFLEXSPIMiscOffset_WordAddressableEnable = 3U, /*!< Bit for Word Addressable enable */
kFLEXSPIMiscOffset_SafeConfigFreqEnable = 4U, /*!< Bit for Safe Configuration Frequency enable */
kFLEXSPIMiscOffset_PadSettingOverrideEnable = 5U, /*!< Bit for Pad setting override enable */
kFLEXSPIMiscOffset_DdrModeEnable = 6U, /*!< Bit for DDR clock confiuration indication. */
kFLEXSPIMiscOffset_UseValidTimeForAllFreq = 7U, /*!< Bit for DLLCR settings under all modes */
};
enum
{
kSerialNorType_StandardSPI, /*!< Device that support Standard SPI and Extended SPI mode */
kSerialNorType_HyperBus, /*!< Device that supports HyperBus only */
kSerialNorType_XPI, /*!< Device that works under DPI, QPI or OPI mode */
kSerialNorType_NoCmd, /*!< Device that works under No command mode (XIP mode/Performance Enhance
mode/continous read mode) */
};
/*@}*/
/*!
* @name FLEXSPI NOR Configuration
* @{
*/
/*! @brief FLEXSPI LUT Sequence structure */
typedef struct _flexspi_lut_seq
{
uint8_t seqNum; /*!< Sequence Number, valid number: 1-16 */
uint8_t seqId; /*!< Sequence Index, valid number: 0-15 */
uint16_t reserved;
} flexspi_lut_seq_t;
typedef struct
{
uint8_t time_100ps; /*!< Data valid time, in terms of 100ps */
uint8_t delay_cells; /*!< Data valid time, in terms of delay cells */
} flexspi_dll_time_t;
/*! @brief FLEXSPI Memory Configuration Block */
typedef struct _flexspi_mem_config
{
uint32_t tag; /*!< [0x000-0x003] Tag, fixed value 0x42464346UL */
uint32_t version; /*!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix */
uint32_t reserved0; /*!< [0x008-0x00b] Reserved for future use */
uint8_t readSampleClkSrc; /*!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 */
uint8_t csHoldTime; /*!< [0x00d-0x00d] Data hold time, default value: 3 */
uint8_t csSetupTime; /*!< [0x00e-0x00e] Date setup time, default value: 3 */
uint8_t columnAddressWidth; /*!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For
Serial NAND, need to refer to datasheet */
uint8_t deviceModeCfgEnable; /*!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable */
uint8_t deviceModeType; /*!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch,
Generic configuration, etc. */
uint16_t waitTimeCfgCommands; /*!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for
DPI/QPI/OPI switch or reset command */
flexspi_lut_seq_t deviceModeSeq; /*!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt
sequence number, [31:16] Reserved */
uint32_t deviceModeArg; /*!< [0x018-0x01b] Argument/Parameter for device configuration */
uint8_t configCmdEnable; /*!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable */
uint8_t configModeType[3]; /*!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe */
flexspi_lut_seq_t
configCmdSeqs[3]; /*!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq */
uint32_t reserved1; /*!< [0x02c-0x02f] Reserved for future use */
uint32_t configCmdArgs[3]; /*!< [0x030-0x03b] Arguments/Parameters for device Configuration commands */
uint32_t reserved2; /*!< [0x03c-0x03f] Reserved for future use */
uint32_t controllerMiscOption; /*!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more
details */
uint8_t deviceType; /*!< [0x044-0x044] Device Type: See Flash Type Definition for more details */
uint8_t sflashPadType; /*!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal */
uint8_t serialClkFreq; /*!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot
Chapter for more details */
uint8_t
lutCustomSeqEnable; /*!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot
be done using 1 LUT sequence, currently, only applicable to HyperFLASH */
uint32_t reserved3[2]; /*!< [0x048-0x04f] Reserved for future use */
uint32_t sflashA1Size; /*!< [0x050-0x053] Size of Flash connected to A1 */
uint32_t sflashA2Size; /*!< [0x054-0x057] Size of Flash connected to A2 */
uint32_t sflashB1Size; /*!< [0x058-0x05b] Size of Flash connected to B1 */
uint32_t sflashB2Size; /*!< [0x05c-0x05f] Size of Flash connected to B2 */
uint32_t csPadSettingOverride; /*!< [0x060-0x063] CS pad setting override value */
uint32_t sclkPadSettingOverride; /*!< [0x064-0x067] SCK pad setting override value */
uint32_t dataPadSettingOverride; /*!< [0x068-0x06b] data pad setting override value */
uint32_t dqsPadSettingOverride; /*!< [0x06c-0x06f] DQS pad setting override value */
uint32_t timeoutInMs; /*!< [0x070-0x073] Timeout threshold for read status command */
uint32_t commandInterval; /*!< [0x074-0x077] CS deselect interval between two commands */
flexspi_dll_time_t dataValidTime[2]; /*!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B */
uint16_t busyOffset; /*!< [0x07c-0x07d] Busy offset, valid value: 0-31 */
uint16_t busyBitPolarity; /*!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 -
busy flag is 0 when flash device is busy */
uint32_t lookupTable[64]; /*!< [0x080-0x17f] Lookup table holds Flash command sequences */
flexspi_lut_seq_t lutCustomSeq[12]; /*!< [0x180-0x1af] Customizable LUT Sequences */
uint32_t reserved4[4]; /*!< [0x1b0-0x1bf] Reserved for future use */
} flexspi_mem_config_t;
/*! @brief Serial NOR configuration block */
typedef struct _flexspi_nor_config
{
flexspi_mem_config_t memConfig; /*!< Common memory configuration info via FLEXSPI */
uint32_t pageSize; /*!< Page size of Serial NOR */
uint32_t sectorSize; /*!< Sector size of Serial NOR */
uint8_t ipcmdSerialClkFreq; /*!< Clock frequency for IP command */
uint8_t isUniformBlockSize; /*!< Sector/Block size is the same */
uint8_t isDataOrderSwapped; /*!< Data order (D0, D1, D2, D3) is swapped (D1,D0, D3, D2) */
uint8_t reserved0[1]; /*!< Reserved for future use */
uint8_t serialNorType; /*!< Serial NOR Flash type: 0/1/2/3 */
uint8_t needExitNoCmdMode; /*!< Need to exit NoCmd mode before other IP command */
uint8_t halfClkForNonReadCmd; /*!< Half the Serial Clock for non-read command: true/false */
uint8_t needRestoreNoCmdMode; /*!< Need to Restore NoCmd mode after IP commmand execution */
uint32_t blockSize; /*!< Block size */
uint32_t reserve2[11]; /*!< Reserved for future use */
} flexspi_nor_config_t;
/*@}*/
/*! @brief Manufacturer ID */
enum
{
kSerialFlash_ISSI_ManufacturerID = 0x9DU, /*!< Manufacturer ID of the ISSI serial flash */
kSerialFlash_Adesto_ManufacturerID = 0x1F, /*!< Manufacturer ID of the Adesto Technologies serial flash*/
kSerialFlash_Winbond_ManufacturerID = 0xEFU, /*!< Manufacturer ID of the Winbond serial flash */
kSerialFlash_Cypress_ManufacturerID = 0x01U, /*!< Manufacturer ID for Cypress */
};
/*! @brief ROM FLEXSPI NOR flash status */
enum _flexspi_nor_status
{
kStatus_ROM_FLEXSPI_SequenceExecutionTimeout =
MAKE_STATUS(kROM_StatusGroup_FLEXSPI, 0), /*!< Status for Sequence Execution timeout */
kStatus_ROM_FLEXSPI_InvalidSequence = MAKE_STATUS(kROM_StatusGroup_FLEXSPI, 1), /*!< Status for Invalid Sequence */
kStatus_ROM_FLEXSPI_DeviceTimeout = MAKE_STATUS(kROM_StatusGroup_FLEXSPI, 2), /*!< Status for Device timeout */
kStatus_FLEXSPINOR_DTRRead_DummyProbeFailed =
MAKE_STATUS(kROM_StatusGroup_FLEXSPINOR, 10), /*!< Status for DDR Read dummy probe failure */
kStatus_ROM_FLEXSPINOR_SFDP_NotFound =
MAKE_STATUS(kROM_StatusGroup_FLEXSPINOR, 7), /*!< Status for SFDP read failure */
kStatus_ROM_FLEXSPINOR_Flash_NotFound =
MAKE_STATUS(kROM_StatusGroup_FLEXSPINOR, 9), /*!< Status for Flash detection failure */
};
typedef enum _flexspi_operation
{
kFLEXSPIOperation_Command, /*!< FLEXSPI operation: Only command, both TX and RX buffer are ignored. */
kFLEXSPIOperation_Config, /*!< FLEXSPI operation: Configure device mode, the TX FIFO size is fixed in LUT. */
kFLEXSPIOperation_Write, /*!< FLEXSPI operation: Write, only TX buffer is effective */
kFLEXSPIOperation_Read, /*!< FLEXSPI operation: Read, only Rx Buffer is effective. */
kFLEXSPIOperation_End = kFLEXSPIOperation_Read,
} flexspi_operation_t;
/*! @brief FLEXSPI Transfer Context */
typedef struct _flexspi_xfer
{
flexspi_operation_t operation; /*!< FLEXSPI operation */
uint32_t baseAddress; /*!< FLEXSPI operation base address */
uint32_t seqId; /*!< Sequence Id */
uint32_t seqNum; /*!< Sequence Number */
bool isParallelModeEnable; /*!< Is a parallel transfer */
uint32_t *txBuffer; /*!< Tx buffer */
uint32_t txSize; /*!< Tx size in bytes */
uint32_t *rxBuffer; /*!< Rx buffer */
uint32_t rxSize; /*!< Rx size in bytes */
} flexspi_xfer_t;
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @name Initialization
* @{
*/
/*!
* @brief Initialize Serial NOR flash via FLEXSPI
*
* This function checks and initializes the FLEXSPI module for the other FLEXSPI APIs.
*
* @param instance storge the instance of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
*
* @retval kStatus_Success Api was executed succesfuly.
* @retval kStatus_InvalidArgument A invalid argument is provided.
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout
*/
status_t ROM_FLEXSPI_NorFlash_Init(uint32_t instance, flexspi_nor_config_t *config);
/*@}*/
/*!
* @name Programming
* @{
*/
/*!
* @brief Program data to Serial NOR flash via FLEXSPI.
*
* This function programs the NOR flash memory with the dest address for a given
* flash area as determined by the dst address and the length.
*
* @param instance storge the instance of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
* @param dstAddr A pointer to the desired flash memory to be programmed.
* NOTE:
* It is recommended that use page aligned access;
* If the dstAddr is not aligned to page,the driver automatically
* aligns address down with the page address.
* @param src A pointer to the source buffer of data that is to be programmed
* into the NOR flash.
*
* @retval kStatus_Success Api was executed succesfuly.
* @retval kStatus_InvalidArgument A invalid argument is provided.
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout
*/
status_t ROM_FLEXSPI_NorFlash_ProgramPage(uint32_t instance,
flexspi_nor_config_t *config,
uint32_t dstAddr,
const uint32_t *src);
/*@}*/
/*!
* @name Erasing
* @{
*/
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR
/*!
* @brief Erase one sector specified by address
*
* This function erases one of NOR flash sectors based on the desired address.
*
* @param instance storge the index of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
* @param address The start address of the desired NOR flash memory to be erased.
* NOTE:
* It is recommended that use sector-aligned access nor device;
* If dstAddr is not aligned with the sector,The driver automatically
* aligns address down with the sector address.
*
* @retval kStatus_Success Api was executed succesfuly.
* @retval kStatus_InvalidArgument A invalid argument is provided.
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout
*/
status_t ROM_FLEXSPI_NorFlash_EraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_SECTOR */
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL
/*!
* @brief Erase all the Serial NOR flash connected on FLEXSPI.
*
* @param instance storge the instance of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
*
* @retval kStatus_Success Api was executed succesfuly.
* @retval kStatus_InvalidArgument A invalid argument is provided.
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout
*/
status_t ROM_FLEXSPI_NorFlash_EraseAll(uint32_t instance, flexspi_nor_config_t *config);
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_ERASE_ALL */
/*!
* @brief Erase Flash Region specified by address and length
*
* This function erases the appropriate number of flash sectors based on the
* desired start address and length.
*
* @param instance storge the index of FLEXSPI.
* @param config A pointer to the storage for the driver runtime state.
* @param start The start address of the desired NOR flash memory to be erased.
* NOTE:
* It is recommended that use sector-aligned access NOR flash;
* If dstAddr is not aligned with the sector,the driver automatically
* aligns address down with the sector address.
* @param length The length, given in bytes to be erased.
* NOTE:
* It is recommended that use sector-aligned access NOR flash;
* If length is not aligned with the sector,the driver automatically
* aligns up with the sector.
* @retval kStatus_Success Api was executed succesfuly.
* @retval kStatus_InvalidArgument A invalid argument is provided.
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
* @retval kStatus_ROM_FLEXSPI_DeviceTimeout the device timeout
*/
status_t ROM_FLEXSPI_NorFlash_Erase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
/*@}*/
/*!
* @name Command
* @{
*/
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER
/*!
* @brief FLEXSPI command
*
* This function is used to perform the command write sequence to the NOR flash.
*
* @param instance storge the index of FLEXSPI.
* @param xfer A pointer to the storage FLEXSPI Transfer Context.
*
* @retval kStatus_Success Api was executed succesfuly.
* @retval kStatus_InvalidArgument A invalid argument is provided.
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
*/
status_t ROM_FLEXSPI_NorFlash_CommandXfer(uint32_t instance, flexspi_xfer_t *xfer);
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_CMD_XFER */
/*@}*/
/*!
* @name UpdateLut
* @{
*/
#if defined(FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT) && FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT
/*!
* @brief Configure FLEXSPI Lookup table
*
* @param instance storge the index of FLEXSPI.
* @param seqIndex storge the sequence Id.
* @param lutBase A pointer to the look-up-table for command sequences.
* @param seqNumber storge sequence number.
*
* @retval kStatus_Success Api was executed succesfuly.
* @retval kStatus_InvalidArgument A invalid argument is provided.
* @retval kStatus_ROM_FLEXSPI_InvalidSequence A invalid Sequence is provided.
* @retval kStatus_ROM_FLEXSPI_SequenceExecutionTimeout Sequence Execution timeout.
*/
status_t ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t instance,
uint32_t seqIndex,
const uint32_t *lutBase,
uint32_t seqNumber);
#endif /* FSL_ROM_FLEXSPINOR_API_HAS_FEATURE_UPDATE_LUT */
/*@}*/
/*!
* @name ClearCache
* @{
*/
/*!
* @brief Software reset for the FLEXSPI logic.
*
* This function sets the software reset flags for both AHB and buffer domain and
* resets both AHB buffer and also IP FIFOs.
*
* @param instance storge the index of FLEXSPI.
*/
void ROM_FLEXSPI_NorFlash_ClearCache(uint32_t instance);
/*@}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* _FSL_ROMAPI_H_ */

View File

@ -0,0 +1,33 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file mcuboot.h
* @brief support bootloader function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#ifndef __MCUBOOT_H__
#define __MCUBOOT_H__
#include "fsl_common.h"
#include "board.h"
#include "pin_mux.h"
#include "fsl_iomuxc.h"
#include "fsl_gpio.h"
#include "fsl_lpuart.h"
#include "common.h"
void mcuboot_bord_init(void);
void mcuboot_reset(void);
void mcuboot_jump(void);
void mcuboot_delay(uint32_t ms);
#endif

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: ymodem.h
* @brief: file ymodem.h
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#ifndef _YMODEM_H_
#define _YMODEM_H_
#include <stdint.h>
#include "common.h"
#define PACKET_SEQNO_INDEX (1)
#define PACKET_SEQNO_COMP_INDEX (2)
#define PACKET_HEADER (3)
#define PACKET_TRAILER (2)
#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER)
#define PACKET_SIZE (128)
#define PACKET_1K_SIZE (1024)
#define FILE_NAME_LENGTH (256)
#define FILE_SIZE_LENGTH (16)
#define SOH (0x01) /* start of 128-byte data packet */
#define STX (0x02) /* start of 1024-byte data packet */
#define EOT (0x04) /* end of transmission */
#define ACK (0x06) /* acknowledge */
#define NAK (0x15) /* negative acknowledge */
#define CA (0x18) /* two of these in succession aborts transfer */
#define CRC16 (0x43) /* 'C' == 0x43, request 16-bit CRC */
#define ABORT1 (0x41) /* 'A' == 0x41, abort by user */
#define ABORT2 (0x61) /* 'a' == 0x61, abort by user */
#define NAK_TIMEOUT (0x100000)
#define MAX_ERRORS (5)
int32_t SerialDownload(const uint32_t addr);
int32_t Ymodem_Receive(uint8_t *buf, const uint32_t addr);
#endif

View File

@ -46,43 +46,64 @@
#pragma location=".boot_hdr.conf"
#endif
const flexspi_nor_config_t Qspiflash_config =
#if defined(HYPERFLASH_BOOT)
const flexspi_nor_config_t hyperflash_config =
{
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackInternally,
.readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
.csHoldTime = 3u,
.csSetupTime = 3u,
.deviceModeCfgEnable = true,
.deviceModeType = 1,//Quad Enable command
.deviceModeSeq.seqNum = 1,
.deviceModeSeq.seqId = 4,
.deviceModeArg = 0x000200,//Set QE
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_60MHz,//80MHz for Winbond, 100MHz for GD, 133MHz for ISSI
.sflashA1Size = 16u * 1024u * 1024u,//4MBytes
.columnAddressWidth = 3u,
.controllerMiscOption = (1u << kFlexSpiMiscOffset_DdrModeEnable) |
(1u << kFlexSpiMiscOffset_WordAddressableEnable) |
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) |
(1u << kFlexSpiMiscOffset_DiffClkEnable),
.sflashPadType = kSerialFlash_8Pads,
.serialClkFreq = kFlexSpiSerialClk_133MHz,
.sflashA1Size = 64u * 1024u * 1024u,
.dataValidTime = {16u, 16u},
.lookupTable =
{
// //Fast Read Sequence
// [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B, RADDR_SDR, FLEXSPI_1PAD, 0x18),
// [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 0x08, READ_SDR, FLEXSPI_1PAD, 0x08),
// [2] = FLEXSPI_LUT_SEQ(JMP_ON_CS, 0, 0, 0, 0, 0),
//Quad Input/output read sequence
[0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
[1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
[2] = FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
//Read Status
[1*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),
//Write Enable
[3*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, 0, 0),
//Write status
[4*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x2),
},
{
FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18),
FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_DDR, FLEXSPI_8PAD, 0x06),
FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.pageSize = 512u,
.sectorSize = 256u * 1024u,
.blockSize = 256u * 1024u,
.isUniformBlockSize = true,
};
#else
const flexspi_nor_config_t Qspiflash_config =
{
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
.csHoldTime = 3u,
.csSetupTime = 3u,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_100MHz,
.sflashA1Size = 8u * 1024u * 1024u,
.lookupTable =
{
// Read LUTs
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.blockSize = 64u * 1024u,
.isUniformBlockSize = false,
};
#endif

View File

@ -555,6 +555,11 @@ KERNELPATHS +=-I$(KERNEL_ROOT)/tool/shell/letter-shell \
-I$(KERNEL_ROOT)/tool/shell/letter-shell/file_ext #
endif
ifeq ($(CONFIG_TOOL_USING_OTA), y)
KERNELPATHS +=-I$(KERNEL_ROOT)/tool/bootloader/flash \
-I$(KERNEL_ROOT)/tool/bootloader/ota #
endif
ifeq ($(CONFIG_FS_LWEXT4),y)
KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/blockdev/xiuos #
KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/include #

View File

@ -0,0 +1,5 @@
menu "Tool feature"
source "$KERNEL_DIR/tool/bootloader/Kconfig"
endmenu

View File

@ -4,4 +4,8 @@ ifeq ($(CONFIG_TOOL_SHELL),y)
SRC_DIR += shell
endif
ifeq ($(CONFIG_TOOL_USING_OTA),y)
SRC_DIR += bootloader
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,48 @@
menu "OTA function"
menuconfig TOOL_USING_OTA
bool "Enable support OTA function"
default n
if TOOL_USING_OTA
choice
prompt "Compile bootloader bin or application bin."
default MCUBOOT_BOOTLOADER
config MCUBOOT_BOOTLOADER
bool "Config as bootloader."
config MCUBOOT_APPLICATION
bool "Config as application."
endchoice
menu "Flash area address and size configuration."
config CHIP_FLAH_BASE
hex "Flash base address of the chip."
default 0x60000000
config XIUOS_FLAH_ADDRESS
hex "Flash area address of the XiUOS system."
default 0x60100000
config BAKUP_FLAH_ADDRESS
hex "Flash area address of the backup firmware."
default 0x60300000
config DOWN_FLAH_ADDRESS
hex "Flash area address of the downloaded firmware."
default 0x60500000
config FLAG_FLAH_ADDRESS
hex "Flash area address of the OTA information."
default 0x60700000
config APP_FLASH_SIZE
hex "Application package size,the default size is limited to 1M."
default 0x00100000
endmenu
endif
endmenu

View File

@ -0,0 +1,4 @@
SRC_DIR :=
SRC_DIR += flash ota
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES := flash_ops.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,47 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file flash_ops.h
* @brief support flash function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#ifndef __FLASH_OPS_H__
#define __FLASH_OPS_H__
#include <flash.h>
typedef struct
{
/* board init function*/
void (*board_init)(void);
void (*serial_init)(void);
void (*print_string)(uint8_t *s);
/* flash Driver operation */
void (*flash_init)(void);
void (*flash_deinit)(void);
/* flash operation */
status_t (*op_flash_erase)(uint32_t start_addr, uint32_t byte_cnt);
status_t (*op_flash_write)(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt);
status_t (*op_flash_read)(uint32_t addr, uint8_t *buf, uint32_t len);
status_t (*op_flash_copy)(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize);
/* Burn the initialization version */
int32_t (*download_by_serial)(const uint32_t addr);
/* system operation */
void(*op_reset)(void);
void(*op_jump)(void);
void(*op_delay)(uint32_t ms);
}mcuboot_t;
#endif

View File

@ -0,0 +1,3 @@
SRC_FILES := ota.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,441 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file ota.c
* @brief file ota.c
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#include "shell.h"
#include "xsconfig.h"
#include "mcuboot.h"
#include "ymodem.h"
#include "ota.h"
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static uint32_t calculate_crc32(uint32_t addr, uint32_t len);
static void UpdateApplication(void);
static void InitialVersion(void);
static void BackupVersion(void);
static void BootLoaderJumpApp(void);
static status_t UpdateOTAFlag(ota_info_t *ptr);
#ifdef MCUBOOT_APPLICATION
static void app_ota(void);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static const mcuboot_t mcuboot =
{
mcuboot_bord_init,
UartConfig,
Serial_PutString,
FLASH_Init,
FLASH_DeInit,
flash_erase,
flash_write,
flash_read,
flash_copy,
SerialDownload,
mcuboot_reset,
mcuboot_jump,
mcuboot_delay
};
static const uint32_t crc32tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*******************************************************************************
* : calculate_crc32
* : Flash内存地址范围中数据的CRC32校验和
* : addr:Flash地址的起始位置
len:CRC32的数据长度
* : CRC32值
*******************************************************************************/
static uint32_t calculate_crc32(uint32_t addr, uint32_t len)
{
uint32_t crc = 0xFFFFFFFF;
uint8_t byte = 0xFF;
for(uint32_t i = 0; i < len; i++)
{
byte = *((volatile uint8_t *)(addr + i));
crc = crc32tab[(crc ^ byte) & 0xff] ^ (crc >> 8);
}
return crc^0xFFFFFFFF;
}
/*******************************************************************************
* : UpdateApplication
* : bootloader里进行调用,Flash中Flag分区中的信息决定是否进行版本更新
* :
* :
* : app分区
*******************************************************************************/
static void UpdateApplication(void)
{
status_t status;
ota_info_t ota_info; // 定义OTA信息结构体
// 从Flash中读取OTA信息
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
// 如果OTA升级状态为准备状态且APP分区与download分区版本不同,才可以进行升级
if((ota_info.status == OTA_STATUS_READY) && (ota_info.os.crc32 != ota_info.down.crc32))
{
mcuboot.print_string("\r\n------Start to update the app!------\r\n");
// 校验downlad分区固件CRC
if(calculate_crc32(DOWN_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32)
{
ota_info.status = OTA_STATUS_UPDATING;
UpdateOTAFlag(&ota_info);
// 1.如果CRC校验通过,开始升级,逐字节拷贝Flash,先备份当前XiUOS System分区内容
status = mcuboot.op_flash_copy(XIUOS_FLAH_ADDRESS, BAKUP_FLAH_ADDRESS, ota_info.os.size);
if((status == kStatus_Success) &&(calculate_crc32(BAKUP_FLAH_ADDRESS, ota_info.os.size) == ota_info.os.crc32))
{
mcuboot.print_string("\r\n------Backup app success!------\r\n");
ota_info.bak.size = ota_info.os.size;
ota_info.bak.crc32 = ota_info.os.crc32;
ota_info.bak.version = ota_info.os.version;
strncpy(ota_info.bak.description, ota_info.os.description, sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);;
}
else
{
mcuboot.print_string("\r\n------Backup app failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Backup app failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);;
goto finish;
}
// 2.拷贝download分区到XiUOS System分区
status = mcuboot.op_flash_copy(DOWN_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.down.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32))
{
mcuboot.print_string("\r\n------The download partition is copied successfully!------\r\n");
ota_info.os.size = ota_info.down.size;
ota_info.os.crc32 = ota_info.down.crc32;
ota_info.os.version = ota_info.down.version;
strncpy(ota_info.os.description, ota_info.down.description, sizeof(ota_info.down.description));
ota_info.status == OTA_STATUS_IDLE; // 拷贝download分区到XiUOS System分区成功,将OTA升级状态设置为IDLE
UpdateOTAFlag(&ota_info);;
}
else
{
mcuboot.print_string("\r\n------The download partition copy failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "The download partition copy failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);;
goto finish;
}
mcuboot.print_string("\r\n------Update completed!------\r\n");
goto finish;
}
else
{
// 如果download分区CRC校验失败升级失败
mcuboot.print_string("\r\n------Download Firmware CRC check failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Download Firmware CRC check failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);;
goto finish;
}
}
else
{
mcuboot.print_string("\r\n------No need to update the app!------\r\n");
goto finish;
}
finish:
return;
}
/*******************************************************************************
* : InitialVersion
* : APP分区的初始化版本,0x1
* :
* :
*******************************************************************************/
static void InitialVersion(void)
{
int32_t size;
ota_info_t ota_info;
memset(&ota_info, 0, sizeof(ota_info_t));
size = mcuboot.download_by_serial(XIUOS_FLAH_ADDRESS);
if(size > 0)
{
ota_info.os.size = size;
ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size);
ota_info.os.version = 0x1;
strncpy(ota_info.os.description, "This is the initial firmware for the device!", sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);
}
}
/*******************************************************************************
* : BackupVersion
* : 退,APP存在bug导致无法跳转需调用此函数进行版本回退
* :
* :
*******************************************************************************/
static void BackupVersion(void)
{
status_t status;
ota_info_t ota_info;
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.status = OTA_STATUS_BACKUP;
UpdateOTAFlag(&ota_info);
status = mcuboot.op_flash_copy(BAKUP_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.bak.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.bak.size) == ota_info.bak.crc32))
{
mcuboot.print_string("\r\n------Backup app version success!------\r\n");
ota_info.os.size = ota_info.bak.size;
ota_info.os.crc32 = ota_info.bak.crc32;
ota_info.os.version = ota_info.bak.version;
strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description));
UpdateOTAFlag(&ota_info);
}
else
{
mcuboot.print_string("\r\n------Backup app version failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Backup app version failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
}
/*******************************************************************************
* : BootLoaderJumpApp
* : ,BAKUP分区进行恢复
* :
* :
*******************************************************************************/
static void BootLoaderJumpApp(void)
{
ota_info_t ota_info;
mcuboot.flash_init();
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
if(ota_info.lastjumpflag == JUMP_FAILED_FLAG)
{
mcuboot.print_string("\r\n------Bootloader false, begin backup!------\r\n");
BackupVersion();
}
else
{
ota_info.lastjumpflag = JUMP_FAILED_FLAG;
UpdateOTAFlag(&ota_info);
}
mcuboot.flash_deinit();
mcuboot.op_jump();
}
/*******************************************************************************
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
*******************************************************************************/
static status_t UpdateOTAFlag(ota_info_t *ptr)
{
status_t status;
status = mcuboot.op_flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
if(status != kStatus_Success)
{
return status;
}
status = mcuboot.op_flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t));
return status;
}
/*******************************************************************************
* : app_ota
* : app中通过命令来进行ota升级,
* :
* :
*******************************************************************************/
static void app_ota(void)
{
int32_t size;
ota_info_t ota_info;
mcuboot.flash_init();
mcuboot.serial_init();
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.status = OTA_STATUS_DOWNLOADING;
UpdateOTAFlag(&ota_info);
size = mcuboot.download_by_serial(DOWN_FLAH_ADDRESS);
ota_info.status = OTA_STATUS_DOWNLOADED;
UpdateOTAFlag(&ota_info);
if(size > 0)
{
ota_info.down.size = size;
ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, size);
ota_info.down.version = ota_info.os.version + 1;
strncpy(ota_info.down.description, "OTA Test!",sizeof(ota_info.down.description));
ota_info.status = OTA_STATUS_READY;
strncpy(ota_info.error_message, "No error message!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
else
{
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Failed to download firmware to download partition!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
mcuboot.flash_deinit();
mcuboot.op_reset();
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota, ota function);
/*******************************************************************************
* : app_clear_jumpflag
* : app成功后,app中调用将lastjumpflag重置为0XCDCDCDCD
* :
* :
*******************************************************************************/
void app_clear_jumpflag(void)
{
mcuboot.flash_init();
//跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG
ota_info_t ota_info;
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.lastjumpflag = JUMP_SUCCESS_FLAG;
UpdateOTAFlag(&ota_info);
mcuboot.flash_deinit();
}
/*******************************************************************************
* : ota_entry
* : bootloader的入口函数
* :
* :
*******************************************************************************/
void ota_entry(void)
{
uint8_t ch1, ch2;
uint32_t ret;
ota_info_t ota_info;
uint32_t timeout = 1000;
mcuboot.board_init();
mcuboot.print_string("Please press 'space' key into menu in 10s !!!\r\n");
while(timeout)
{
ret = (SerialKeyPressed((uint8_t*)&ch1));
if(ret) break;
timeout--;
mcuboot.op_delay(10);
}
while(1)
{
if((ret)&&(ch1 == 0x20))
{
mcuboot.print_string("\r\nPlease slecet:");
mcuboot.print_string("\r\n 1:run app");
mcuboot.print_string("\r\n 2:update app");
mcuboot.print_string("\r\n 3:reboot \r\n");
ch2 = GetKey();
switch(ch2)
{
case 0x31:
BootLoaderJumpApp();
break;
case 0x32:
mcuboot.flash_init();
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
/* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */
if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32))
{
mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n");
InitialVersion();
}
else
{
UpdateApplication();
}
mcuboot.flash_deinit();
BootLoaderJumpApp();
break;
case 0x33:
mcuboot.op_reset();
default:
break;
}
}
else
{
BootLoaderJumpApp();
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file ota.h
* @brief file ota.h
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#ifndef __OTA_DEF_H__
#define __OTA_DEF_H__
#include "flash_ops.h"
#define JUMP_FAILED_FLAG 0XABABABAB
#define JUMP_SUCCESS_FLAG 0XCDCDCDCD
typedef enum {
OTA_STATUS_IDLE = 0, // 空闲状态,没有进行OTA升级
OTA_STATUS_READY, // 准备状态,可以进行OTA升级
OTA_STATUS_DOWNLOADING, // 正在下载固件
OTA_STATUS_DOWNLOADED, // 固件下载完成
OTA_STATUS_UPDATING, // 正在进行OTA升级
OTA_STATUS_BACKUP, // 正在版本回退
OTA_STATUS_ERROR, // 出现错误,升级失败
} ota_status_t;
/* Flash分区中保存固件的属性描述 */
typedef struct {
uint32_t size; // 应用程序大小,记录分区固件的大小
uint32_t crc32; // 应用程序CRC32校验值,记录分区固件的crc32值
uint32_t version; // 应用程序版本号,记录分区固件的版本号
uint32_t reserve; // 保留字段
uint8_t description[128]; // 固件的描述信息,最多128个字符
} firmware_t;
/* OTA升级过程中的信息结构体 */
typedef struct {
firmware_t os; // XiUOS System分区属性信息
firmware_t bak; // Bakup分区属性信息
firmware_t down; // Download分区属性信息
uint32_t status; // 升级状态,取值来自于ota_status_t类型
uint32_t lastjumpflag; // bootloaer跳转失败的标志,bootloader里置0xABABABAB,跳转成功后在应用里置0xCDCDCDCD
uint32_t reserve[2]; // 保留字段
uint8_t error_message[128]; // 错误信息,最多128个字符
} ota_info_t;
void app_clear_jumpflag(void);
void ota_entry(void);
#endif