[1] 添加Andes N1068体系;

[2] 基于AE210P EVB板;
[3] 详细信息参阅bsp/AE210P/readme文件夹;
    《Andes工程创建和调试》文档;等。
This commit is contained in:
ArcherChang
2017-08-25 10:25:33 +08:00
parent 27c7ed3501
commit 921fbfbc21
100 changed files with 21301 additions and 6 deletions

76
.cproject Normal file
View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="nds.nds32le-elf-mculib-v3.base.58599081">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="nds.nds32le-elf-mculib-v3.base.58599081" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="com.andestech.ide.cdt.managedbuilder.core.CROSS_GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="nds.nds32le-elf-mculib-v3.base.58599081" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="nds.nds32le-elf-mculib-v3.base.58599081.1110402366" name="/" resourcePath="">
<toolChain id="nds.nds32le-elf-mculib-v3.base.1767351733" name="nds32le-elf-mculib-v3" superClass="nds.nds32le-elf-mculib-v3.base">
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_CPU.1896754197" name="CPU" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_CPU"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_LIST_CPU.895643889" name="LIST_CPU" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_LIST_CPU"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_CORE.1142664471" name="CORE" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_CORE"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_ARCH.1121945628" name="ARCH" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_ARCH"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_ISA_REDUCE_REGS.1293207534" name="ISA_REDUCE_REGS" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_ISA_REDUCE_REGS"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_TARGET.1070191715" name="TARGET" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_TARGET"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_ENDIAN.377724547" name="ENDIAN" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_ENDIAN"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_LIB_C_DEFAULT.464304688" name="LIB_C_DEFAULT" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_LIB_C_DEFAULT"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_LIB_CPP_DEFAULT.1439903022" name="LIB_CPP_DEFAULT" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.NDS32_LIB_CPP_DEFAULT"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.RSE_TARGET.1444389132" name="RSE_TARGET" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.RSE_TARGET"/>
<option id="nds32le-elf-mculib-v3.managedbuild.option.toolchain.RSE_CONNECT.1587775719" name="RSE_CONNECT" superClass="nds32le-elf-mculib-v3.managedbuild.option.toolchain.RSE_CONNECT"/>
<targetPlatform archList="all" binaryParser="com.andestech.ide.cdt.managedbuilder.core.CROSS_GNU_ELF" id="target.nds.platform.base.894202893" name="Debug Platform" osList="all" superClass="target.nds.platform.base"/>
<builder buildPath="${workspace_loc:/rtt_master/bsp/AE210P}" cleanBuildTarget="APP=rtthread AE210P=1 USING_CLI=1 DEBUG=1 clean" id="target.nds.builder.base.798580194" incrementalBuildTarget="APP=rtthread AE210P=1 USING_CLI=1 DEBUG=1 all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Andes Make Builder" superClass="target.nds.builder.base"/>
<tool id="tool.nds32le-elf-mculib-v3.archiver.base.541270770" name="Andes Archiver" superClass="tool.nds32le-elf-mculib-v3.archiver.base"/>
<tool id="tool.nds32le-elf-mculib-v3.cpp.compiler.base.798443763" name="Andes C++ Compiler" superClass="tool.nds32le-elf-mculib-v3.cpp.compiler.base"/>
<tool id="tool.nds32le-elf-mculib-v3.cpp.linker.base.1663125809" name="Andes C++ Linker" superClass="tool.nds32le-elf-mculib-v3.cpp.linker.base">
<option defaultValue="true" id="nds32le-elf-mculib-v3.cpp.link.option.noshared.base.889050287" name="No shared libraries (-static)" superClass="nds32le-elf-mculib-v3.cpp.link.option.noshared.base" valueType="boolean"/>
</tool>
<tool id="tool.nds32le-elf-mculib-v3.c.compiler.base.1446774168" name="Andes C Compiler" superClass="tool.nds32le-elf-mculib-v3.c.compiler.base">
<inputType id="tool.nds.c.compiler.input.624026089" superClass="tool.nds.c.compiler.input"/>
</tool>
<tool id="tool.nds32le-elf-mculib-v3.c.linker.base.84728931" name="Andes C Linker" superClass="tool.nds32le-elf-mculib-v3.c.linker.base">
<option defaultValue="true" id="nds32le-elf-mculib-v3.c.link.option.noshared.base.2119240931" name="No shared libraries (-static)" superClass="nds32le-elf-mculib-v3.c.link.option.noshared.base" valueType="boolean"/>
<inputType id="tool.nds.c.linker.input.775039577" superClass="tool.nds.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="tool.nds32le-elf-mculib-v3.assembler.base.1651903076" name="Andes Assembler" superClass="tool.nds32le-elf-mculib-v3.assembler.base">
<inputType id="tool.nds.assembler.input.639385268" superClass="tool.nds.assembler.input"/>
</tool>
<tool id="tool.nds32le-elf-mculib-v3.nm.base.1513872058" name="NM (symbol listing)" superClass="tool.nds32le-elf-mculib-v3.nm.base"/>
<tool id="tool.nds32le-elf-mculib-v3.readelf.base.839251283" name="Readelf (ELF info listing)" superClass="tool.nds32le-elf-mculib-v3.readelf.base"/>
<tool id="tool.nds32le-elf-mculib-v3.objdump.base.380287659" name="Objdump (disassembly)" superClass="tool.nds32le-elf-mculib-v3.objdump.base"/>
<tool id="tool.nds32le-elf-mculib-v3.objcopy.base.511281711" name="Objcopy (object content copy)" superClass="tool.nds32le-elf-mculib-v3.objcopy.base"/>
<tool id="tool.nds32le-elf-mculib-v3.size.base.191568706" name="Size (section size listing)" superClass="tool.nds32le-elf-mculib-v3.size.base"/>
<tool id="tool.nds32le-elf-mculib-v3.ldsag.base.682055329" name="LdSaG Tool" superClass="tool.nds32le-elf-mculib-v3.ldsag.base"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="rtt_master.null.750251984" name="rtt_master"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/rtt_master"/>
</configuration>
</storageModule>
</cproject>

26
.project Normal file
View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>rtt_master</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

2
bsp/AE210P/.PHONY.size Normal file
View File

@@ -0,0 +1,2 @@
text (code + rodata) data bss dec hex filename
54224 (45672 + 8552) 328 9820 64372 fb74 rtthread.elf

303
bsp/AE210P/Makefile Normal file
View File

@@ -0,0 +1,303 @@
#************************************************************
# RT-Thread RTOS makefile base on Andes N1068A core
#
# Mengxin Technology Co., Ltd.
# Archer Chang <archer.zhang@wh-mx.com>
# 2017.07.25 16:00
#
#************************************************************
CROSS_COMPILE ?= nds32le-elf-
SIZE_OUTPUTS = .PHONY.size
CC := $(CROSS_COMPILE)gcc
OBJCOPY := $(CROSS_COMPILE)objcopy
AR := $(CROSS_COMPILE)ar
AS := $(CROSS_COMPILE)as
ifeq ($(DEBUG),1)
OPTIM := -O0 -g2
else
OPTIM := -O2 -g0
endif
ROOT_PATH := .
RTOS_PATH := $(ROOT_PATH)/../..
ARCH_PATH := $(RTOS_PATH)/libcpu
KERNEL_PATH := $(RTOS_PATH)/src
COMPONENTS_PATH := $(RTOS_PATH)/components
COMPONENTS_INIT_PATH := $(COMPONENTS_PATH)/init
COMPONENTS_DRV_PATH := $(COMPONENTS_PATH)/drivers
COMPONENTS_DRVSRC_PATH := $(COMPONENTS_DRV_PATH)/src
COMPONENTS_DRVINC_PATH := $(COMPONENTS_DRV_PATH)/include
COMPONENTS_DRVINC_DRV_PATH := $(COMPONENTS_DRVINC_PATH)/drivers
BSP_PATH := $(RTOS_PATH)/bsp
CLI_PATH := $(COMPONENTS_PATH)/finsh
PLATFORM_PATH := $(BSP_PATH)/AE210P
ARCH_SEL_PATH := $(ARCH_PATH)/nds32
CONFIG_PATH := $(PLATFORM_PATH)
BOARD_PATH := $(PLATFORM_PATH)/board
LIBC_PATH := $(PLATFORM_PATH)/libc
LDSCRIPT := $(BOARD_PATH)/ae210p.ld
CONFIG_H := $(CONFIG_PATH)/config.h
PLATFORM_DEF := -DAE210P
ARCH_INCLUDE_PATH := $(ARCH_PATH)/nds32
HW_HAL_SRC := $(BOARD_PATH)/ae210p.c \
$(PLATFORM_PATH)/board.c \
$(ARCH_SEL_PATH)/cpuport.c \
$(PLATFORM_PATH)/startup.c \
$(PLATFORM_PATH)/application.c
DRIVERS_PATH := $(PLATFORM_PATH)/driver
OS_DEF := -DCONFIG_OS_RTTHREAD
INCLUDE_PATH := \
-I$(RTOS_PATH) \
-I$(ARCH_INCLUDE_PATH) \
-I$(RTOS_PATH)/include \
-I${KERNEL_PATH} \
-I$(CONFIG_PATH) \
-I$(PLATFORM_PATH) \
-I$(BOARD_PATH) \
-I$(DRIVERS_PATH) \
-I$(CLI_PATH) \
-I$(LIBC_PATH) \
-I${PLATFORM_PATH}/include \
-I$(COMPONENTS_DRVINC_PATH) \
-I$(COMPONENTS_DRVINC_DRV_PATH) \
-I$(COMPONENTS_INIT_PATH)
SMALL_HEAP_DEF :=
#Check GCC version
VERSION := $(shell $(CC) --version | grep ^$(CC) | sed 's/^.* //g')
GCC_VERSION := $(shell echo $(VERSION)| sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/' )
# GCC version before 4.8.2 doesn't support -mcmodel
ifneq ($(shell expr `echo $(GCC_VERSION)` \< 40802 ),1)
CMODEL := -mcmodel=large
endif
CFLAGS := \
$(INCLUDE_PATH) \
-Wall \
$(PLATFORM_DEF) \
$(OS_DEF) \
$(SMALL_HEAP_DEF) \
-fno-builtin -fomit-frame-pointer -funroll-loops -nostdlib \
-fno-strict-aliasing -ffunction-sections \
$(CMODEL) \
$(OPTIM) \
$(OSC_DEF) \
$(CFLAGS_EXT)
LD_FLAGS := $(OPTIM) -fno-builtin -nostartfiles -static -Wl,--gc-sections $(CMODEL)
AFLAGS := -fno-builtin
# Add `-fno-delete-null-pointer-checks` flag if the compiler supports it.
# GCC assumes that programs cannot safely dereference null pointers,
# and that no code or data element resides there.
# However, 0x0 is the vector table memory location, so the test must not be removed.
ifeq ($(shell $(CC) -fno-delete-null-pointer-checks -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
CFLAGS += -fno-delete-null-pointer-checks
LD_FLAGS += -fno-delete-null-pointer-checks
endif
# Maybe necessary
NO_IFC = y
NO_EX9 = y
ifeq ($(shell echo | $(CC) -E -dM - | grep __NDS32_EXT_IFC__ > /dev/null && echo IFC),IFC)
ifeq ($(NO_IFC),y)
CFLAGS += -mno-ifc -DCONFIG_NO_NDS32_EXT_IFC
LD_FLAGS += -Wl,--mno-ifc
endif
else
ifneq ($(NO_IFC),)
$(error this toolchain do not support IFC extension)
endif
endif
ifeq ($(shell echo | $(CC) -E -dM - | grep __NDS32_EXT_EX9__ > /dev/null && echo EX9),EX9)
ifeq ($(NO_EX9),y)
CFLAGS += -mno-ex9 -DCONFIG_NO_NDS32_EXT_EX9
LD_FLAGS += -Wl,--mno-ex9
endif
else
ifneq ($(NO_EX9),)
$(error this toolchain do not support EX9 extension)
endif
endif
ifeq ($(CACHE),1)
CFLAGS += -DCONFIG_CACHE_SUPPORT
endif
# add INTC check
ifeq ($(EXT_INTC),1)
CFLAGS += -DCONFIG_EXT_INTC
endif
# HWZOL check
ifeq ($(HWZOL),1)
ifeq ($(shell echo | $(CC) -E -dM -mext-zol - | grep '\<__NDS32_EXT_ZOL__\>' > /dev/null && echo "ZOL"), ZOL)
CFLAGS += -DCONFIG_HWZOL
LD_FLAGS += -mext-zol
else
$(error this toolchain do not support ZOL extension)
endif
endif
RTOS_SRC := \
$(KERNEL_PATH)/clock.c \
$(KERNEL_PATH)/device.c \
$(KERNEL_PATH)/idle.c \
$(KERNEL_PATH)/ipc.c \
$(KERNEL_PATH)/irq.c \
$(KERNEL_PATH)/kservice.c \
$(KERNEL_PATH)/mem.c \
$(KERNEL_PATH)/mempool.c \
$(KERNEL_PATH)/scheduler.c \
$(KERNEL_PATH)/thread.c \
$(KERNEL_PATH)/timer.c \
$(KERNEL_PATH)/object.c \
NDS32_SRC := \
$(PLATFORM_PATH)/reset.c \
$(PLATFORM_PATH)/cache.c \
$(HW_HAL_SRC) \
BOOT_SRC := \
$(PLATFORM_PATH)/start.S \
$(ARCH_SEL_PATH)/context_gcc.S
CLI_SRC :=
ifeq ($(USING_CLI),1)
CLI_SRC += $(KERNEL_PATH)/components.c \
$(COMPONENTS_DRVSRC_PATH)/ringbuffer.c \
$(COMPONENTS_DRVSRC_PATH)/completion.c \
$(COMPONENTS_DRVSRC_PATH)/dataqueue.c \
$(CLI_PATH)/cmd.c \
$(CLI_PATH)/finsh_compiler.c \
$(CLI_PATH)/finsh_error.c \
$(CLI_PATH)/finsh_heap.c \
$(CLI_PATH)/finsh_init.c \
$(CLI_PATH)/finsh_node.c \
$(CLI_PATH)/finsh_ops.c \
$(CLI_PATH)/finsh_parser.c \
$(CLI_PATH)/finsh_token.c \
$(CLI_PATH)/finsh_var.c \
$(CLI_PATH)/finsh_vm.c \
$(CLI_PATH)/msh.c \
$(CLI_PATH)/msh_cmd.c \
$(CLI_PATH)/shell.c \
$(CLI_PATH)/symbol.c
endif
#DRIVER_SRC := \
${UART_DRIVER_SRC} \
${LCD_DRIVER_SRC} \
${SD_DRIVER_SRC} \
${TOUCHSCREEN_DRIVER_SRC} \
${AC97_DRIVER_SRC} \
${DMA_DRIVER_SRC} \
${HAL_DRIVER_SRC} \
DRIVER_SRC := \
$(PLATFORM_PATH)/driver/uart/uart.c \
$(PLATFORM_PATH)/driver/gpio/gpio.c \
$(BOARD_PATH)/uart_dev.c \
$(COMPONENTS_DRV_PATH)/serial/serial.c
# $(PLATFORM_PATH)/driver/dma/dmad.c
LIBC_SRC := \
$(LIBC_PATH)/stdio/fgets.c \
$(LIBC_PATH)/stdio/fputs.c \
$(LIBC_PATH)/stdio/fprintf.c \
$(LIBC_PATH)/stdio/do_printf.c \
$(LIBC_PATH)/stdio/printf.c \
$(LIBC_PATH)/string/memcpy.c \
$(LIBC_PATH)/string/memmove.c \
$(LIBC_PATH)/string/memset.c \
$(LIBC_PATH)/string/strcat.c \
$(LIBC_PATH)/string/strcasecmp.c \
$(LIBC_PATH)/string/strcmp.c \
$(LIBC_PATH)/string/strcpy.c \
$(LIBC_PATH)/string/strdup.c \
$(LIBC_PATH)/string/strlen.c \
$(LIBC_PATH)/string/strstr.c \
$(LIBC_PATH)/string/strupr.c \
$(LIBC_PATH)/string/wchar.c \
$(LIBC_PATH)/stdlib/qsort.c
#LIBC_FILE_SRC := \
# $(LIBC_PATH)/stdio/file.c \
#********************************************
# Applications
#********************************************
APP_SRCS :=
#################################################################
# #
# Source code to each application #
# #
#################################################################
SRCS := \
${NDS32_SRC} \
${RTOS_SRC} \
${DRIVER_SRC} \
${CLI_SRC} \
${APP_SRCS} \
${LIBC_SRC}
ALL_C_SRCS := ${SRCS}
ALL_AS_SRCS += ${BOOT_SRC}
# % can match to all the strings
ALL_C_OBJS := $(patsubst %.S,%.o,$(patsubst %.c,%.o,${ALL_C_SRCS}))
ALL_AS_OBJS := $(patsubst %.S,%.o,${ALL_AS_SRCS})
OBJS = ${ALL_C_OBJS} ${ALL_AS_OBJS}
.PHONY: all clean distclean
all: ${APP}.elf ${APP}.bin $(SIZE_OUTPUTS)
if test ! -d ./build; then \
mkdir ./build; \
fi
mv ${APP}.elf ${APP}.bin ./build
clean:
$(RM) $(OBJS)
$(RM) ./build/${APP}.elf ./build/${APP}.bin
distclean: clean
$(RM) -rf build/
.SUFFIXES : .o .c .S
.c.o : $(CONFIG_H)
$(CC) -include $(CONFIG_H) -c $(CFLAGS) $< -o $@
.S.o : $(CONFIG_H)
$(CC) -include $(CONFIG_H) -c $(CFLAGS) $(AFLAGS) $< -o $@
${APP}.elf: $(CONFIG_H) ${KCONFIG_CONFIG} ${ALL_C_OBJS} ${ALL_AS_OBJS}
@echo ' '
$(CC) -T$(LDSCRIPT) ${ALL_C_OBJS} ${ALL_AS_OBJS} $(LD_FLAGS) $(LFLAGS_EXT) -o $@
@echo ' '
${APP}.bin: ${APP}.elf
# @echo ' '
$(OBJCOPY) ${APP}.elf -O binary ${APP}.bin
@echo ' '
.PHONY.size:
# @echo ' '
$(CROSS_COMPILE)size ${APP}.elf | tee .PHONY.size
@echo ' '
.PHONY: all clean distclean .PHONY.size

136
bsp/AE210P/application.c Normal file
View File

@@ -0,0 +1,136 @@
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard the first version
* 2013-07-12 aozima update for auto initial.
*/
/**
* @addtogroup STM32
*/
/*@{*/
#include <board.h>
#include <rtthread.h>
#include <rthw.h>
#ifdef RT_USING_COMPONENTS_INIT
#include <components.h>
#endif /* RT_USING_COMPONENTS_INIT */
#ifdef RT_USING_DFS
/* dfs filesystem:ELM filesystem init */
#include <dfs_elm.h>
/* dfs Filesystem APIs */
#include <dfs_fs.h>
#endif
#ifdef RT_USING_RTGUI
#include <rtgui/rtgui.h>
#include <rtgui/rtgui_server.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/driver.h>
#include <rtgui/calibration.h>
#endif
void rt_init_thread_entry(void* parameter)
{
#ifdef RT_USING_COMPONENTS_INIT
/* initialization RT-Thread Components */
rt_components_init();
#endif
/* Filesystem Initialization */
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
/* mount sd card fat partition 1 as root directory */
if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
{
rt_kprintf("File System initialized!\n");
}
else
rt_kprintf("File System initialzation failed!\n");
#endif /* RT_USING_DFS */
#ifdef RT_USING_RTGUI
{
extern void rt_hw_lcd_init();
extern void rtgui_touch_hw_init(void);
rt_device_t lcd;
/* init lcd */
rt_hw_lcd_init();
/* init touch panel */
rtgui_touch_hw_init();
/* find lcd device */
lcd = rt_device_find("lcd");
/* set lcd device as rtgui graphic driver */
rtgui_graphic_set_device(lcd);
#ifndef RT_USING_COMPONENTS_INIT
/* init rtgui system server */
rtgui_system_server_init();
#endif
calibration_set_restore(cali_setup);
calibration_set_after(cali_store);
calibration_init();
}
#endif /* #ifdef RT_USING_RTGUI */
}
#include "debug.h"
rt_thread_t test_thread[2];
void rt_test_thread_entry(void *parameter)
{
uint32_t num = (uint32_t)parameter;
uint32_t schedule_times = 0;
while (1)
{
DEBUG(1, 0, "%d:%d\r\n", num, schedule_times++);
rt_thread_delay(1);
}
}
int rt_application_init(void)
{
rt_thread_t init_thread;
#if (RT_THREAD_PRIORITY_MAX == 32)
init_thread = rt_thread_create("init",
rt_init_thread_entry, RT_NULL,
2048, 8, 20);
#else
init_thread = rt_thread_create("init",
rt_init_thread_entry, RT_NULL,
2048, 80, 20);
#endif
if (init_thread != RT_NULL)
rt_thread_startup(init_thread);
// test_thread[0] = rt_thread_create("t1", rt_test_thread_entry, (void *)1, 1024, 26, 5);
// test_thread[1] = rt_thread_create("t2", rt_test_thread_entry, (void *)2, 1024, 26, 5);
// if (test_thread[0] != RT_NULL)
// rt_thread_startup(test_thread[0]);
// if (test_thread[1] != RT_NULL)
// rt_thread_startup(test_thread[1]);
return 0;
}
/*@}*/

95
bsp/AE210P/board.c Normal file
View File

@@ -0,0 +1,95 @@
/*
* File : board.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009 RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first implementation
* 2013-07-12 aozima update for auto initial.
*/
#include <rthw.h>
#include <rtthread.h>
#include "nds32.h"
#include "bsp_hal.h"
#include "ae210p.h"
#include "debug.h"
//#include "uart/uart.h"
#include "uart_dev.h"
#include "board.h"
#include "rtconfig.h"
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* clean timer device pending*/
hal_timer_irq_clear(1);
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
/***********************************************************
* Set timer 1 as system tick by default
***********************************************************/
void BSP_Tmr_TickInit(uint32_t tmrId, uint32_t period, uint32_t vecId, void *isr)
{
/* set tick period */
hal_timer_set_period(tmrId, period);
/* enable timer1 interrupt */
hal_timer_irq_control(tmrId, 1);
/******************************
* tick ISR init
******************************/
/* init trigger mode */
/* Set edge trigger, falling edge */
hal_intc_irq_config(vecId, 1, 0);
/* clean pending */
hal_intc_irq_clean(vecId);
/* enable timer interrupt */
hal_intc_irq_enable(vecId);
if (isr)
OS_CPU_Vector_Table[vecId] = isr;
else
DEBUG(1, 1, "Invalid tick handler!!\r\n");
/* start timer */
hal_timer_start(tmrId);
}
/*
* Setup system tick for OS required.
*/
void bsp_init(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
// drv_uart_init();
rt_hw_usart_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
/* System tick init */
BSP_Tmr_TickInit(0x1, (MB_PCLK / RT_TICK_PER_SECOND), IRQ_SYS_TICK_VECTOR, SysTick_Handler);
}
/*@}*/

28
bsp/AE210P/board.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* File : board.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-09-22 Bernard add board.h to this bsp
*/
// <<< Use Configuration Wizard in Context Menu >>>
#ifndef __BOARD_H__
#define __BOARD_H__
#include "nds32.h"
/* board configuration */
//#define RT_USING_UART01 1
#define RT_USING_UART02 1
void rt_hw_board_init(void);
#endif /* __BOARD_H__ */

338
bsp/AE210P/board/ae210p.c Normal file
View File

@@ -0,0 +1,338 @@
#include <nds32_intrinsic.h>
#include "debug.h"
#include "nds32.h"
#include "cache.h"
#define CACHE_NONE 0
#define CACHE_WRITEBACK 2
#define CACHE_WRITETHROUGH 3
#if (defined(CONFIG_CPU_ICACHE_ENABLE) || defined(CONFIG_CPU_DCACHE_ENABLE))
/* Cacheable */
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
#define CACHE_MODE CACHE_WRITETHROUGH
#else
#define CACHE_MODE CACHE_WRITEBACK
#endif
#else
/* Uncacheable */
#define CACHE_MODE CACHE_NONE
#endif
#define MMU_CTL_MSK \
(MMU_CTL_mskD \
| MMU_CTL_mskNTC0 \
| MMU_CTL_mskNTC1 \
| MMU_CTL_mskNTC2 \
| MMU_CTL_mskNTC3 \
| MMU_CTL_mskTBALCK \
| MMU_CTL_mskMPZIU \
| MMU_CTL_mskNTM0 \
| MMU_CTL_mskNTM1 \
| MMU_CTL_mskNTM2 \
| MMU_CTL_mskNTM3)
/*
* NTC0: CACHE_MODE, NTC1~NTC3: Non-cacheable
* MSC_CFG.ADR24 = 0 : NTM0~NTM3 are mapped to partition 0/0/0/0
* MSC_CFG.ADR24 = 1 : NTM0~NTM3 are mapped to partition 0/1/2/3
*/
#define MMU_CTL_INIT \
(0x0UL << MMU_CTL_offD \
| (CACHE_MODE) << MMU_CTL_offNTC0 \
| 0x0UL << MMU_CTL_offNTC1 \
| 0x0UL << MMU_CTL_offNTC2 \
| 0x0UL << MMU_CTL_offNTC3 \
| 0x0UL << MMU_CTL_offTBALCK \
| 0x0UL << MMU_CTL_offMPZIU \
| 0x0UL << MMU_CTL_offNTM0 \
| 0x0UL << MMU_CTL_offNTM1 \
| 0x0UL << MMU_CTL_offNTM2 \
| 0x0UL << MMU_CTL_offNTM3)
#define MMU_CTL_INIT_ADR24 \
(MMU_CTL_INIT \
| 0x0UL << MMU_CTL_offNTM0 \
| 0x1UL << MMU_CTL_offNTM1 \
| 0x2UL << MMU_CTL_offNTM2 \
| 0x3UL << MMU_CTL_offNTM3)
#define CACHE_CTL_MSK \
(CACHE_CTL_mskIC_EN \
| CACHE_CTL_mskDC_EN \
| CACHE_CTL_mskICALCK \
| CACHE_CTL_mskDCALCK \
| CACHE_CTL_mskDCCWF \
| CACHE_CTL_mskDCPMW)
/* ICache/DCache enable */
#define CACHE_CTL_CACHE_ON \
(0x1UL << CACHE_CTL_offIC_EN \
| 0x1UL << CACHE_CTL_offDC_EN \
| 0x0UL << CACHE_CTL_offICALCK \
| 0x0UL << CACHE_CTL_offDCALCK \
| 0x1UL << CACHE_CTL_offDCCWF \
| 0x1UL << CACHE_CTL_offDCPMW)
/*
* Interrupt priority :
* PIT(IRQ #2): highest priority
* Others: lowest priority
*/
#define PRI1_DEFAULT 0xFFFFFFFF
#define PRI2_DEFAULT 0xFFFFFFFF
/* This must be a leaf function, no child function */
void _nds32_init_mem(void) __attribute__((naked, optimize("Os")));
void _nds32_init_mem(void)
{
/* Enable DLM */
__nds32__mtsr(EDLM_BASE | 0x1, NDS32_SR_DLMB);
__nds32__dsb();
}
/*
* Initialize MMU configure and cache ability.
*/
static void mmu_init(void)
{
//#ifndef __NDS32_ISA_V3M__
// unsigned int reg;
//
// /* MMU initialization: NTC0~NTC3, NTM0~NTM3 */
// reg = (__nds32__mfsr(NDS32_SR_MMU_CTL) & ~MMU_CTL_MSK) | MMU_CTL_INIT;
//
// if (__nds32__mfsr(NDS32_SR_MSC_CFG) & MSC_CFG_mskADR24)
// reg = (__nds32__mfsr(NDS32_SR_MMU_CTL) & ~MMU_CTL_MSK) | MMU_CTL_INIT_ADR24;
// else
// reg = (__nds32__mfsr(NDS32_SR_MMU_CTL) & ~MMU_CTL_MSK) | MMU_CTL_INIT;
//
// __nds32__mtsr(reg, NDS32_SR_MMU_CTL);
// __nds32__dsb();
//#endif
}
/*
* Platform specific initialization
*/
static void plf_init(void)
{
/* Set default Hardware interrupts priority */
__nds32__mtsr(PRI1_DEFAULT, NDS32_SR_INT_PRI);
__nds32__mtsr(PRI2_DEFAULT, NDS32_SR_INT_PRI2);
/* Mask all HW interrupts except SWI */
__nds32__mtsr((1 << IRQ_SYS_TICK_VECTOR) | (1 << IRQ_SWI_VECTOR), NDS32_SR_INT_MASK2);
/* Reset the PIT (timers) */
REG32(PIT_INT_EN) = 0; /* disable all timer interrupt */
REG32(PIT_CH_EN) = 0; /* disable all timer */
REG32(PIT_INT_ST) = -1; /* clear pending events */
REG32(PIT_CHNx_LOAD(0)) = 0; /* clean channel 0 reload */
REG32(PIT_CHNx_LOAD(1)) = 0; /* clean channel 1 reload */
REG32(PIT_CHNx_LOAD(2)) = 0; /* clean channel 2 reload */
REG32(PIT_CHNx_LOAD(3)) = 0; /* clean channel 3 reload */
}
/*
* All AE210P hardware initialization
*/
void hardware_init(void)
{
mmu_init(); /* mmu/cache */
plf_init(); /* Perform any platform specific initializations */
#if (defined(CONFIG_CPU_ICACHE_ENABLE) || defined(CONFIG_CPU_DCACHE_ENABLE))
unsigned int reg;
/* Invalid ICache */
nds32_icache_flush();
/* Invalid DCache */
nds32_dcache_invalidate();
/* Enable I/Dcache */
reg = (__nds32__mfsr(NDS32_SR_CACHE_CTL) & ~CACHE_CTL_MSK) | CACHE_CTL_CACHE_ON;
__nds32__mtsr(reg, NDS32_SR_CACHE_CTL);
#endif
}
/********************************
* HAL Level : Interrupt
********************************/
/* 32IVIC without SOC INTC */
/*
* mask/unmask priority >= _irqs_ interrupts
* used in ISR & gie diable
*/
uint32_t hal_intc_irq_mask(int _irqs_)
{
uint32_t prv_msk = __nds32__mfsr(NDS32_SR_INT_MASK2);
if (_irqs_ == -1 )
{
__nds32__mtsr(0, NDS32_SR_INT_MASK2);
}
else if (_irqs_ < 32 )
{
SR_CLRB32(NDS32_SR_INT_MASK2,_irqs_);
}
else
{
DEBUG(1,1,"_irqs_:%d, is invalid!\r\n",_irqs_);
return -1;
}
return prv_msk;
}
void hal_intc_irq_unmask(uint32_t _msk_)
{
__nds32__mtsr( _msk_ , NDS32_SR_INT_MASK2);
}
void hal_intc_irq_clean(int _irqs_)
{
if ( _irqs_ == IRQ_SWI_VECTOR )
{
SR_CLRB32(NDS32_SR_INT_PEND, INT_PEND_offSWI);
}
else
{
/* PEND2 is W1C */
SR_SETB32(NDS32_SR_INT_PEND2,_irqs_);
}
}
void hal_intc_irq_clean_all()
{
__nds32__mtsr(-1,NDS32_SR_INT_PEND2);
}
void hal_intc_irq_disable(int _irqs_)
{
SR_CLRB32(NDS32_SR_INT_MASK2,_irqs_);
}
void hal_intc_irq_disable_all()
{
__nds32__mtsr(0x0,NDS32_SR_INT_MASK2);
}
void hal_intc_irq_enable(int _irqs_)
{
SR_SETB32(NDS32_SR_INT_MASK2,_irqs_);
}
void hal_intc_irq_set_priority( uint32_t _prio1_, uint32_t _prio2_ )
{
__nds32__mtsr(_prio1_, NDS32_SR_INT_PRI);
__nds32__mtsr(_prio2_, NDS32_SR_INT_PRI2);
}
void hal_intc_irq_config(uint8_t _irq_, uint8_t _edge_, uint8_t _falling_){}
void hal_intc_swi_enable()
{
//SR_SETB32(NDS32_SR_INT_MASK,16);
SR_SETB32(NDS32_SR_INT_MASK2,IRQ_SWI_VECTOR);
}
void hal_intc_swi_disable()
{
SR_CLRB32(NDS32_SR_INT_MASK2,IRQ_SWI_VECTOR);
}
void hal_intc_swi_clean()
{
SR_CLRB32(NDS32_SR_INT_PEND, INT_PEND_offSWI);
}
void hal_intc_swi_trigger()
{
SR_SETB32(NDS32_SR_INT_PEND,INT_PEND_offSWI);
}
uint32_t hal_intc_get_all_pend()
{
return __nds32__mfsr(NDS32_SR_INT_PEND2);
}
/********************************
* TIMER HAL Function
********************************/
static const uint8_t timer_irq[4] = {IRQ_PIT_VECTOR, IRQ_PIT_VECTOR, IRQ_PIT_VECTOR, IRQ_PIT_VECTOR};
uint32_t hal_timer_irq_mask(uint32_t _tmr_ )
{
return hal_intc_irq_mask(timer_irq[_tmr_-1]);
}
void hal_timer_irq_unmask(uint32_t _msk_ )
{
hal_intc_irq_unmask(_msk_);
}
void hal_timer_irq_clear(uint32_t _tmr_ )
{
/* Clean IP pending, W1C */
#ifndef CONFIG_TX_DEMO
REG32(PIT_INT_ST) = (0x1 << (5*(_tmr_-1)));
#endif
hal_intc_irq_clean(timer_irq[_tmr_-1]);
}
void hal_timer_set_period(uint32_t _tmr_, uint32_t _period_ )
{
REG32(PIT_CHNx_LOAD(_tmr_-1)) = _period_;
//REG32(PIT_CHNx_COUNT(_tmr_-1))= _period_;
}
void hal_timer_irq_control(uint32_t _tmr_, uint32_t enable )
{
if (enable)
REG32(PIT_INT_EN) = REG32(PIT_INT_EN) | (0x1 << (5*(_tmr_-1)));
else
REG32(PIT_INT_EN) = REG32(PIT_INT_EN) & ~(0x1 << (5*(_tmr_-1)));
}
void hal_timer_set_upward(uint32_t _tmr_ ,uint32_t up)
{
if ( up )
DEBUG(1,1,"PIT Timer only support downward!\r\n");
}
void hal_timer_start(uint32_t _tmr_)
{
/* config channel mode */
/* 32 bits timer, APB clock */
REG32(PIT_CHNx_CTL(_tmr_-1)) = ( PIT_CH_CTL_APBCLK | PIT_CH_CTL_TMR32 );
/* enable channel */
REG32(PIT_CH_EN) = REG32(PIT_CH_EN) | (0x1 << (5*(_tmr_-1)));
}
void hal_timer_stop(uint32_t _tmr_ )
{
REG32(PIT_CH_EN) = REG32(PIT_CH_EN) & ~(0x1 << (5*(_tmr_-1)));
}
uint32_t hal_timer_read(uint32_t _tmr_ )
{
/* By default, timer would decrease from load value to 0 */
return REG32( PIT_CHNx_LOAD(_tmr_-1) ) - REG32( PIT_CHNx_COUNT(_tmr_-1) );
}
uint32_t hal_timer_count_read(uint32_t _tmr_ )
{
return REG32( PIT_CHNx_COUNT(_tmr_-1) );
}
uint32_t hal_timer_irq_status(uint32_t _tmr_)
{
/* return PIT int status */
/* PIT need #channel & #timer */
/* just return all int status */
return REG32(PIT_INT_ST);
}

74
bsp/AE210P/board/ae210p.h Normal file
View File

@@ -0,0 +1,74 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2014
* All Rights Reserved.
*
****************************************************************************/
#ifndef __AE210P_H__
#define __AE210P_H__
#ifndef __ASSEMBLER__
#include <inttypes.h>
#include <nds32_intrinsic.h>
#endif
/*****************************************************************************
* System clock
****************************************************************************/
#define KHz 1000
#define MHz 1000000
#define MB_OSCCLK (20 * MHz)
#define MB_CPUCLK (40 * MHz)
#define MB_HCLK (MB_CPUCLK)
#define MB_PCLK (MB_CPUCLK)
#define MB_UCLK (MB_OSCCLK)
/*****************************************************************************
* IRQ Vector
****************************************************************************/
#define IRQ_RTCPERIOD_VECTOR 0
#define IRQ_RTCALARM_VECTOR 1
#define IRQ_PIT_VECTOR 2
#define IRQ_SPI1_VECTOR 3
#define IRQ_SPI2_VECTOR 4
#define IRQ_I2C_VECTOR 5
#define IRQ_GPIO_VECTOR 6
#define IRQ_UART1_VECTOR 7
#define IRQ_UATR2_VECTOR 8
#define IRQ_DMA_VECTOR 9
#define IRQ_BMC_VECTOR 10
#define IRQ_SWI_VECTOR 11
/* EXT_INT_0~19 are reserved for vendor IPs */
#define IRQ_EXTINT0_VECTOR 12
#define IRQ_EXTINT1_VECTOR 13
#define IRQ_EXTINT2_VECTOR 14
#define IRQ_EXTINT3_VECTOR 15
#define IRQ_EXTINT4_VECTOR 16
#define IRQ_EXTINT5_VECTOR 17
#define IRQ_EXTINT6_VECTOR 18
#define IRQ_EXTINT7_VECTOR 19
#define IRQ_EXTINT8_VECTOR 20
#define IRQ_EXTINT9_VECTOR 21
#define IRQ_EXTINT10_VECTOR 22
#define IRQ_EXTINT11_VECTOR 23
#define IRQ_EXTINT12_VECTOR 24
#define IRQ_EXTINT13_VECTOR 25
#define IRQ_EXTINT14_VECTOR 26
#define IRQ_EXTINT15_VECTOR 27
#define IRQ_EXTINT16_VECTOR 28
#define IRQ_EXTINT17_VECTOR 29
#define IRQ_EXTINT18_VECTOR 30
#define IRQ_EXTINT19_VECTOR 31
/* The system tick IRQ for OS */
#define IRQ_SYS_TICK_VECTOR IRQ_PIT_VECTOR
#define IRQ_SYS_TICK2_VECTOR IRQ_PIT_VECTOR
/* Include ae210p memory mapping and register definition */
#include "ae210p_defs.h"
#include "ae210p_regs.h"
#endif /* __AE210P_H__ */

202
bsp/AE210P/board/ae210p.ld Normal file
View File

@@ -0,0 +1,202 @@
/* This file is generated by nds_ldsag (version (2017-01-11) ). */
ENTRY(_start)
SECTIONS
{
PROVIDE (__executable_start = 0x0);
NDS_SAG_LMA_FLASH1 = 0x0 ;
. = 0x0;
ROM_BEGIN = .;
.nds32_init : { KEEP(*(.nds32_init )) }
.interp : { *(.interp ) }
.hash : { *(.hash ) }
.dynsym : { *(.dynsym ) }
.dynstr : { *(.dynstr ) }
.gnu.version : { *(.gnu.version ) }
.gnu.version_d : { *(.gnu.version_d ) }
.gnu.version_r : { *(.gnu.version_r ) }
.rel.init : { *(.rel.init ) }
.rela.init : { *(.rela.init ) }
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.* ) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.* ) }
.rel.fini : { *(.rel.fini ) }
.rela.fini : { *(.rela.fini ) }
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.* ) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.* ) }
.rel.data.rel.ro : { *(.rel.data.rel.ro* ) }
.rela.data.rel.ro : { *(.rel.data.rel.ro* ) }
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.* ) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.* ) }
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.* ) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.* ) }
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.* ) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.* ) }
.rel.ctors : { *(.rel.ctors ) }
.rela.ctors : { *(.rela.ctors ) }
.rel.dtors : { *(.rel.dtors ) }
.rela.dtors : { *(.rela.dtors ) }
.rela.dyn : { *(rela.dyn ) *(.rela__libc_subfreeres ) *(.rela__libc_atexit ) *(.rela__libc_thread_subfreeres ) *(.rela.init_array ) *(.rela.fini_array ) }
.rel.got : { *(.rel.got ) }
.rela.got : { *(.rela.got ) }
.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.* ) }
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.* ) }
.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.* ) }
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.* ) }
.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.* ) }
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.* ) }
.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.* ) }
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.* ) }
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.* ) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.* ) }
.rel.plt : { *(.rel.plt ) }
.rela.plt : { *(.rela.plt ) }
.init : { KEEP(*(.init )) }
.plt : { *(.plt ) }
.text : { *(.text .stub .text.* .gnu.linkonce.t.* ) KEEP(*(.text.*personality* )) *(.gnu.warning ) . = ALIGN(4); }
.fini : { KEEP(*(.fini )) }
.ex9.itable : { *(.ex9.itable ) }
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.* ) }
.rodata1 : { *(.rodata1 ) }
.sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.* ) }
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.* ) }
.eh_frame_hdr : { *(.eh_frame_hdr ) }
. = ALIGN(4);
__fsymtab_start = .;
FSymTab : { KEEP(*(FSymTab )) }
. = ALIGN(4);
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
VSymTab : { KEEP(*(VSymTab )) }
. = ALIGN(4);
__vsymtab_end = .;
. = ALIGN(4);
__rt_init_start = .;
.rti_fn.0 : { KEEP(*(.rti_fn.0 )) }
.rti_fn.0.end : { KEEP(*(.rti_fn.0.end )) }
.rti_fn.1 : { KEEP(*(.rti_fn.1 )) }
.rti_fn.1.end : { KEEP(*(.rti_fn.1.end )) }
.rti_fn.2 : { KEEP(*(.rti_fn.2 )) }
.rti_fn.2.end : { KEEP(*(.rti_fn.2.end )) }
.rti_fn.3 : { KEEP(*(.rti_fn.3 )) }
.rti_fn.3.end : { KEEP(*(.rti_fn.3.end )) }
.rti_fn.4 : { KEEP(*(.rti_fn.4 )) }
.rti_fn.4.end : { KEEP(*(.rti_fn.4.end )) }
.rti_fn.5 : { KEEP(*(.rti_fn.5 )) }
.rti_fn.5.end : { KEEP(*(.rti_fn.5.end )) }
.rti_fn.6 : { KEEP(*(.rti_fn.6 )) }
.rti_fn.6.end : { KEEP(*(.rti_fn.6.end )) }
.rti_fn.7 : { KEEP(*(.rti_fn.7 )) }
.rti_fn.7.end : { KEEP(*(.rti_fn.7.end )) }
. = ALIGN(4);
__rt_init_end = .;
ROM_SIZE = . - ROM_BEGIN;
. = 0x200000;
RAM_BEGIN = .;
. = ALIGN(0x20);
__rw_lma_start = LOADADDR (.eh_frame);
__rw_vma_start = ADDR(.eh_frame);
.eh_frame : AT(ALIGN(LOADADDR (.rti_fn.7.end) + SIZEOF (.rti_fn.7.end), 32))
{ KEEP(*(.eh_frame )) }
.gcc_except_table : AT(ALIGN(LOADADDR (.eh_frame) + SIZEOF (.eh_frame), ALIGNOF(.gcc_except_table)))
{ KEEP(*(.gcc_except_table )) *(.gcc_except_table.* ) }
.tdata : AT(ALIGN(LOADADDR (.gcc_except_table) + SIZEOF (.gcc_except_table), ALIGNOF(.tdata)))
{ *(.tdata .tdata.* .gnu.linkonce.td.* ) }
. = ALIGN(4);
PROVIDE (__preinit_array_start = .);
.preinit_array : AT(ALIGN(ALIGN(LOADADDR (.tdata) + SIZEOF (.tdata), ALIGNOF(.preinit_array)), 4))
{ KEEP(*(.preinit_array )) }
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : AT(ALIGN(LOADADDR (.preinit_array) + SIZEOF (.preinit_array), ALIGNOF(.init_array)))
{ KEEP(*(.init_array )) }
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : AT(ALIGN(LOADADDR (.init_array) + SIZEOF (.init_array), ALIGNOF(.fini_array)))
{ KEEP(*(.fini_array )) }
PROVIDE (__fini_array_end = .);
.ctors : AT(ALIGN(LOADADDR (.fini_array) + SIZEOF (.fini_array), ALIGNOF(.ctors)))
{ KEEP(*crtbegin*.o(.ctors)) KEEP(*(EXCLUDE_FILE (*crtend*.o) .ctors)) KEEP(*(SORT(.ctors.* ))) KEEP(*(.ctors )) }
.dtors : AT(ALIGN(LOADADDR (.ctors) + SIZEOF (.ctors), ALIGNOF(.dtors)))
{ KEEP(*crtbegin*.o(.dtors)) KEEP(*(EXCLUDE_FILE (*crtend*.o) .dtors)) KEEP(*(SORT(.dtors.* ))) KEEP(*(.dtors )) }
.jcr : AT(ALIGN(LOADADDR (.dtors) + SIZEOF (.dtors), ALIGNOF(.jcr)))
{ KEEP(*(.jcr )) }
.data.rel.ro : AT(ALIGN(LOADADDR (.jcr) + SIZEOF (.jcr), ALIGNOF(.data.rel.ro)))
{ *(.data.rel.ro.local ) *(.data.rel.ro* ) }
.dynamic : AT(ALIGN(LOADADDR (.data.rel.ro) + SIZEOF (.data.rel.ro), ALIGNOF(.dynamic)))
{ *(.dynamic ) }
.data : AT(ALIGN(LOADADDR (.dynamic) + SIZEOF (.dynamic), ALIGNOF(.data)))
{ *(.data .data.* .gnu.linkonce.d.* ) KEEP(*(.gnu.linkonce.d.*personality* )) SORT(CONSTRUCTORS) . = ALIGN(8); }
.data1 : AT(ALIGN(LOADADDR (.data) + SIZEOF (.data), ALIGNOF(.data1)))
{ *(.data1 ) . = ALIGN(8); }
. = ALIGN(4);
.got : AT(ALIGN(ALIGN(LOADADDR (.data1) + SIZEOF (.data1), ALIGNOF(.got)), 4))
{ *(.got.plt ) *(.got ) }
.sdata_d : AT(ALIGN(LOADADDR (.got) + SIZEOF (.got), ALIGNOF(.sdata_d)))
{ *(.sdata_d .sdata_d.* ) }
.sdata_w : AT(ALIGN(LOADADDR (.sdata_d) + SIZEOF (.sdata_d), ALIGNOF(.sdata_w)))
{ *(.sdata_w .sdata_w.* ) }
.sdata_h : AT(ALIGN(LOADADDR (.sdata_w) + SIZEOF (.sdata_w), ALIGNOF(.sdata_h)))
{ *(.sdata_h .sdata_h.* ) }
.sdata_b : AT(ALIGN(LOADADDR (.sdata_h) + SIZEOF (.sdata_h), ALIGNOF(.sdata_b)))
{ *(.sdata_b .sdata_b.* ) }
.sdata_f : AT(ALIGN(LOADADDR (.sdata_b) + SIZEOF (.sdata_b), ALIGNOF(.sdata_f)))
{ *(.sdata_f .sdata_f.* ) }
. = ALIGN(4);
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
PROVIDE (__sbss_start = .);
PROVIDE (___sbss_start = .);
__rw_lma_end = LOADADDR (.tbss);
.tbss : AT(ALIGN(ALIGN(LOADADDR (.sdata_f) + SIZEOF (.sdata_f), ALIGNOF(.tbss)), 4))
{ *(.tbss .tbss.* .gnu.linkonce.tb.* ) *(.tcommon ) }
.sbss_f : AT(ALIGN(LOADADDR (.tbss) + SIZEOF (.tbss), ALIGNOF(.sbss_f)))
{ *(.sbss_f .sbss_f.* ) *(.scommon_f .scommon_f.* ) }
.sbss_b : AT(ALIGN(LOADADDR (.sbss_f) + SIZEOF (.sbss_f), ALIGNOF(.sbss_b)))
{ *(.sbss_b .sbss_b.* ) *(.scommon_b .scommon_b.* ) . = ALIGN(2); }
.sbss_h : AT(ALIGN(LOADADDR (.sbss_b) + SIZEOF (.sbss_b), ALIGNOF(.sbss_h)))
{ *(.sbss_h .sbss_h.* ) *(.scommon_h .scommon_h.* ) . = ALIGN(4); }
.sbss_w : AT(ALIGN(LOADADDR (.sbss_h) + SIZEOF (.sbss_h), ALIGNOF(.sbss_w)))
{ *(.sbss_w .sbss_w.* ) *(.scommon_w .scommon_w.* ) *(.dynsbss ) *(.scommon ) . = ALIGN(8); }
.sbss_d : AT(ALIGN(LOADADDR (.sbss_w) + SIZEOF (.sbss_w), ALIGNOF(.sbss_d)))
{ *(.sbss_d .sbss_d.* ) *(.scommon_d .scommon_d.* ) }
.bss : AT(ALIGN(LOADADDR (.sbss_d) + SIZEOF (.sbss_d), ALIGNOF(.bss)))
{ *(.dynbss ) *(.bss .bss.* .gnu.linkonce.b.* ) *(COMMON ) . = ALIGN(4); }
PROVIDE (__sbss_end = .);
PROVIDE (___sbss_end = .);
. = ALIGN(4);
_end = .;
PROVIDE (end = .);
PROVIDE (_stack = 0x24fff8);
RAM_SIZE = . - RAM_BEGIN;
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.note.nds32 0 : { *(.note.nds32) *(.note.nds32.*) }
.comment 0 : { *(.comment) }
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
ASSERT((DEFINED (_RELAX_END_) ? ROM_SIZE : 0x0)<= 0x80000, "ROM OVERFLOW");
ASSERT((DEFINED (_RELAX_END_) ? RAM_SIZE : 0x0)<= 0x50000, "RAM OVERFLOW");

View File

@@ -0,0 +1,68 @@
USER_SECTIONS FSymTab
USER_SECTIONS VSymTab
USER_SECTIONS .rti_fn.0
USER_SECTIONS .rti_fn.0.end
USER_SECTIONS .rti_fn.1
USER_SECTIONS .rti_fn.1.end
USER_SECTIONS .rti_fn.2
USER_SECTIONS .rti_fn.2.end
USER_SECTIONS .rti_fn.3
USER_SECTIONS .rti_fn.3.end
USER_SECTIONS .rti_fn.4
USER_SECTIONS .rti_fn.4.end
USER_SECTIONS .rti_fn.5
USER_SECTIONS .rti_fn.5.end
USER_SECTIONS .rti_fn.6
USER_SECTIONS .rti_fn.6.end
USER_SECTIONS .rti_fn.7
USER_SECTIONS .rti_fn.7.end
FLASH1 0x0
{
ROM 0x0 0x80000 ; EILM_SIZE <= 512KB
{
* (+RO)
. = ALIGN(4);
ADDR __fsymtab_start
* KEEP( FSymTab )
. = ALIGN(4);
ADDR __fsymtab_end
. = ALIGN(4);
ADDR __vsymtab_start
* KEEP( VSymTab )
. = ALIGN(4);
ADDR __vsymtab_end
. = ALIGN(4);
ADDR __rt_init_start
* KEEP( .rti_fn.0 )
* KEEP( .rti_fn.0.end )
* KEEP( .rti_fn.1 )
* KEEP( .rti_fn.1.end )
* KEEP( .rti_fn.2 )
* KEEP( .rti_fn.2.end )
* KEEP( .rti_fn.3 )
* KEEP( .rti_fn.3.end )
* KEEP( .rti_fn.4 )
* KEEP( .rti_fn.4.end )
* KEEP( .rti_fn.5 )
* KEEP( .rti_fn.5.end )
* KEEP( .rti_fn.6 )
* KEEP( .rti_fn.6.end )
* KEEP( .rti_fn.7 )
* KEEP( .rti_fn.7.end )
. = ALIGN(4);
ADDR __rt_init_end
}
; RAM 0x200000 0x80000 ; EDLM_SIZE <= 512KB
RAM 0x200000 0x50000 ; EDLM_SIZE <= 320KB
{
LOADADDR NEXT __rw_lma_start
ADDR NEXT __rw_vma_start
*(+RW)
LOADADDR NEXT __rw_lma_end
*(+ZI)
; STACK = 0x27fff8 ; 512KB
STACK = 0x24fff8 ; 320KB
}
}

View File

@@ -0,0 +1,306 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2014
* All Rights Reserved.
*
* Revision History:
*
* Jan.11.2014 Created.
****************************************************************************/
#ifndef __AE210_DEFS_H__
#define __AE210_DEFS_H__
/*****************************************************************************
* AHB_SLAVE_4_7 - AE210P AHB
****************************************************************************/
/*****************************************************************************
* BMC (APB Decoder)- AE210P AHB
****************************************************************************/
/*****************************************************************************
* OSC - AE210P OSC
****************************************************************************/
/* OSC control Register (+0x00) */
#define OSC_CTRL_OVL_SZ_SHIFT 24
#define OSC_CTRL_OVLVALID_SHIFT 31
#define OSC_CTRL_OVL_SZ_MASK 0x07000000
#define OSC_CTRL_OVLVALID_MASK 0x80000000
/* OSC Fixed Region Size Register (+0x04) */
#define OSC_OVLFS_OVL_FSZ_MASK 0x000FFFFF
/* OSC Overlay Region Base Register (+0x08) */
#define OSC_OVLBASE_OVL_BASE_MASK 0x000FFFFF
/* OSC Overlay Region End Register (+0x0C) */
#define OSC_OVLEND_OVL_END_MASK 0x001FFFFF
/*****************************************************************************
* DMAC - AE210P AHB
****************************************************************************/
/*****************************************************************************
* AHB_SLAVE_0_3 - AE210P AHB
****************************************************************************/
//TODO
//finish this table
/*****************************************************************************
* APBBR(N/A) - AE210P AHB to APB Bridge
****************************************************************************/
/*****************************************************************************
* SMU - AE210P Core APB
****************************************************************************/
/*****************************************************************************
* UARTx - AE210P Core APB
****************************************************************************/
/* Macros for specifying which UART to use. */
#define UARTC_NUM_DEVICES 2
/* IER Register (+0x04) */
#define UARTC_IER_RDR 0x01 /* Data Ready Enable */
#define UARTC_IER_THRE 0x02 /* THR Empty Enable */
#define UARTC_IER_RLS 0x04 /* Receive Line Status Enable */
#define UARTC_CIER_MS 0x08 /* Modem Staus Enable */
/* IIR Register (+0x08) */
#define UARTC_IIR_NONE 0x01 /* No interrupt pending */
#define UARTC_IIR_RLS 0x06 /* Receive Line Status */
#define UARTC_IIR_RDR 0x04 /* Receive Data Ready */
#define UARTC_IIR_RTO 0x0c /* Receive Time Out */
#define UARTC_IIR_THRE 0x02 /* THR Empty */
#define UARTC_IIR_MODEM 0x00 /* Modem Status */
#define UARTC_IIR_INT_MASK 0x0f /* Initerrupt Status Bits Mask */
#define UARTC_IIR_TFIFO_FULL 0x10 /* TX FIFO full */
#define UARTC_IIR_FIFO_EN 0xc0 /* FIFO mode is enabled, set when FCR[0] is 1 */
/* FCR Register (+0x08) */
#define UARTC_FCR_FIFO_EN 0x01 /* FIFO Enable */
#define UARTC_FCR_RFIFO_RESET 0x02 /* Rx FIFO Reset */
#define UARTC_FCR_TFIFO_RESET 0x04 /* Tx FIFO Reset */
#define UARTC_FCR_DMA_EN 0x08 /* Select UART DMA mode */
#define UARTC_FCR_TFIFO16_TRGL1 0x00 /* TX 16-byte FIFO int trigger level - 1 char */
#define UARTC_FCR_TFIFO16_TRGL3 0x10 /* TX 16-byte FIFO int trigger level - 3 char */
#define UARTC_FCR_TFIFO16_TRGL9 0x20 /* TX 16-byte FIFO int trigger level - 9 char */
#define UARTC_FCR_TFIFO16_TRGL13 0x30 /* TX 16-byte FIFO int trigger level - 13 char */
#define UARTC_FCR_RFIFO16_TRGL1 0x00 /* RX 16-byte FIFO int trigger level - 1 char */
#define UARTC_FCR_RFIFO16_TRGL4 0x40 /* RX 16-byte FIFO int trigger level - 4 char */
#define UARTC_FCR_RFIFO16_TRGL8 0x80 /* RX 16-byte FIFO int trigger level - 8 char */
#define UARTC_FCR_RFIFO16_TRGL14 0xc0 /* RX 16-byte FIFO int trigger level - 14 char */
/* FCR Register (+0x08) */
#define UARTC_FCR_FIFO_EN_MASK 0x01 /* FIFO Enable */
#define UARTC_FCR_FIFO_EN_BIT 0
#define UARTC_FCR_RFIFO_RESET_MASK 0x02 /* Rx FIFO Reset */
#define UARTC_FCR_RFIFO_RESET_BIT 1
#define UARTC_FCR_TFIFO_RESET_MASK 0x04 /* Tx FIFO Reset */
#define UARTC_FCR_TFIFO_RESET_BIT 2
#define UARTC_FCR_DMA_EN_MASK 0x08 /* Select UART DMA mode */
#define UARTC_FCR_DMA_EN_BIT 3
#define UARTC_FCR_TXFIFO_TRGL_MASK 0x30 /* TX FIFO int trigger level */
#define UARTC_FCR_TXFIFO_TRGL_SHIFT 4
#define UARTC_FCR_RXFIFO_TRGL_MASK 0xc0 /* RX FIFO int trigger level */
#define UARTC_FCR_RXFIFO_TRGL_SHIFT 6
/* LCR Register (+0x0c) */
#define UARTC_LCR_BITS5 0x00
#define UARTC_LCR_BITS6 0x01
#define UARTC_LCR_BITS7 0x02
#define UARTC_LCR_BITS8 0x03
#define UARTC_LCR_STOP1 0x00
#define UARTC_LCR_STOP2 0x04
#define UARTC_LCR_PARITY_EN 0x08 /* Parity Enable */
#define UARTC_LCR_PARITY_NONE 0x00 /* No Parity Check */
#define UARTC_LCR_PARITY_EVEN 0x18 /* Even Parity */
#define UARTC_LCR_PARITY_ODD 0x08 /* Odd Parity */
#if 0
#define UARTC_LCR_PARITY_1 0x21 /* 1 Parity Bit */
#define UARTC_LCR_PARITY_0 0x31 /* 0 Parity Bit */
#endif
#define UARTC_LCR_SETBREAK 0x40 /* Set Break condition */
#define UARTC_LCR_DLAB 0x80 /* Divisor Latch Access Bit */
/* MCR Register (+0x10) */
#define UARTC_MCR_DTR 0x01 /* Data Terminal Ready */
#define UARTC_MCR_RTS 0x02 /* Request to Send */
#define UARTC_MCR_OUT1 0x04 /* output1 */
#define UARTC_MCR_OUT2 0x08 /* output2 or global interrupt enable */
#define UARTC_MCR_LPBK 0x10 /* loopback mode */
#define UARTC_MCR_DMAMODE2 0x20 /* DMA mode2 */
#define UARTC_MCR_OUT3 0x40 /* output 3 */
/* LSR Register (+0x14) */
#define UARTC_LSR_RDR 0x1 /* Data Ready */
#define UARTC_LSR_OE 0x2 /* Overrun Error */
#define UARTC_LSR_PE 0x4 /* Parity Error */
#define UARTC_LSR_FE 0x8 /* Framing Error */
#define UARTC_LSR_BI 0x10 /* Break Interrupt */
#define UARTC_LSR_THRE 0x20 /* THR/FIFO Empty */
#define UARTC_LSR_TE 0x40 /* THR/FIFO and TFR Empty */
#define UARTC_LSR_DE 0x80 /* FIFO Data Error */
/* MSR Register (+0x18) */
#define UARTC_MSR_DELTACTS 0x1 /* Delta CTS */
#define UARTC_MSR_DELTADSR 0x2 /* Delta DSR */
#define UARTC_MSR_TERI 0x4 /* Trailing Edge RI */
#define UARTC_MSR_DELTACD 0x8 /* Delta CD */
#define UARTC_MSR_CTS 0x10 /* Clear To Send */
#define UARTC_MSR_DSR 0x20 /* Data Set Ready */
#define UARTC_MSR_RI 0x40 /* Ring Indicator */
#define UARTC_MSR_DCD 0x80 /* Data Carrier Detect */
/* MDR register (+0x20) */
#define UARTC_MDR_MODE_SEL_SHIFT 0
#define UARTC_MDR_SIP_BYCPU_BIT 2
#define UARTC_MDR_FMEND_MD_BIT 3
#define UARTC_MDR_DMA_EN_BIT 4
#define UARTC_MDR_FIR_INV_RX_BIT 5
#define UARTC_MDR_IR_INV_TX_BIT 6
#define UARTC_MDR_MODE_SEL_MASK 0x03
#define UARTC_MDR_SIP_BYCPU_MASK 0x04 /* 0: 1.6us end pulse; 1: depends on ACR[4] */
#define UARTC_MDR_FMEND_MD_MASK 0x08 /* 0: Frame length counter method; 1: Set end of transmission bit method */
#define UARTC_MDR_DMA_EN_MASK 0x10 /* Enable DMA mode. (PIO int should turn off) */
#define UARTC_MDR_FIR_INV_RX_MASK 0x20 /* (FIR only) Invert receiver input signal */
#define UARTC_MDR_IR_INV_TX_MASK 0x40 /* (FIR/SIR) Invert pulse during transmission */
#define UARTC_MDR_MODE_UART 0
#define UARTC_MDR_MODE_SIR 1
#define UARTC_MDR_MODE_FIR 2
/* ACR register (+0x24) */
#define UARTC_ACR_IR_TX_EN 0x01
#define UARTC_ACR_IR_RX_EN 0x02
#define UARTC_ACR_FIR_SETEOT 0x04
/*****************************************************************************
* PIT - AG101 Core APB
****************************************************************************/
/* Interrupt Enable Register */
#define PIT_CH_NUM_MASK 0x7
/* Channel & Interrupt Enable Reg */
#define PIT_C0_TMR0_EN 0x1
#define PIT_C0_TMR1_EN 0x2
#define PIT_C0_TMR2_EN 0x4
#define PIT_C0_TMR3_EN 0x8
#define PIT_C1_TMR0_EN 0x10
#define PIT_C1_TMR1_EN 0x20
#define PIT_C1_TMR2_EN 0x40
#define PIT_C1_TMR3_EN 0x80
#define PIT_C2_TMR0_EN 0x100
#define PIT_C2_TMR1_EN 0x200
#define PIT_C2_TMR2_EN 0x400
#define PIT_C2_TMR3_EN 0x800
#define PIT_C3_TMR0_EN 0x1000
#define PIT_C3_TMR1_EN 0x2000
#define PIT_C3_TMR2_EN 0x4000
#define PIT_C3_TMR3_EN 0x8000
/* Interrupt Status Register */
/* Clean Timer interrupt pending bit, write 1 clean */
#define PIT_C0_TMR0_PEND_W1C 0x1
#define PIT_C0_TMR1_PEND_W1C 0x2
#define PIT_C0_TMR2_PEND_W1C 0x4
#define PIT_C0_TMR3_PEND_W1C 0x8
#define PIT_C1_TMR0_PEND_W1C 0x10
#define PIT_C1_TMR1_PEND_W1C 0x20
#define PIT_C1_TMR2_PEND_W1C 0x40
#define PIT_C1_TMR3_PEND_W1C 0x80
#define PIT_C2_TMR0_PEND_W1C 0x100
#define PIT_C2_TMR1_PEND_W1C 0x200
#define PIT_C2_TMR2_PEND_W1C 0x400
#define PIT_C2_TMR3_PEND_W1C 0x800
#define PIT_C3_TMR0_PEND_W1C 0x1000
#define PIT_C3_TMR1_PEND_W1C 0x2000
#define PIT_C3_TMR2_PEND_W1C 0x4000
#define PIT_C3_TMR3_PEND_W1C 0x8000
/* channel 0~3 control register */
/* ChClk*/
#define PIT_CH_CTL_APBCLK 0x8
/* ChMode*/
#define PIT_CH_CTL_TMR32 0x1
#define PIT_CH_CTL_TMR16 0x2
#define PIT_CH_CTL_TMR8 0x3
#define PIT_CH_CTL_PWM 0x4
#define PIT_CH_CTL_MIX16 0x6
#define PIT_CH_CTL_MIX8 0x7
/*****************************************************************************
* WDT - AG101 Core APB
****************************************************************************/
//TODO
//finish this table
/*****************************************************************************
* RTC - AE210P APB
****************************************************************************/
//TODO
//Finish this table
/*****************************************************************************
* GPIO - AE210P APB
****************************************************************************/
/*****************************************************************************
* I2C - AG101 Core APB
****************************************************************************/
/*****************************************************************************
* SPI1 - AG101 Core APB
****************************************************************************/
/*****************************************************************************
* SPI2 - AG101 Core APB
****************************************************************************/
/*****************************************************************************
* APB_SLAVE_0_4 - AG101 Core APB
****************************************************************************/
/*****************************************************************************
* Interface & Definitions
****************************************************************************/
/* TODO: timer-polling method */
#if (defined(CONFIG_CPU_ICACHE_ENABLE) && defined(CONFIG_CPU_DCACHE_ENABLE))
#define _nds_kwait(count) \
do { \
volatile uint32_t i = 0; \
while (i++ < (uint32_t)(count)) \
; \
} while(0)
#else
#define _nds_kwait(count) \
do { \
volatile uint32_t i = 0; \
uint32_t c = (count > 0x10) ? count / 0x10 : 0x10; \
while (i++ < (uint32_t)(c)) \
; \
} while(0)
#endif
#endif /* __AE210P_DEFS_H__ */

View File

@@ -0,0 +1,315 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2014
* All Rights Reserved.
*
****************************************************************************/
#ifndef __AE210P_REGS_H__
#define __AE210P_REGS_H__
#ifndef __ASSEMBLER__
#include <inttypes.h>
#include <nds32_intrinsic.h>
#endif
#if (defined(CONFIG_CPU_ICACHE_ENABLE) || defined(CONFIG_CPU_DCACHE_ENABLE))
/*
* The NTC1 is set to noncache region and NTM1 is mapped to partition 0 (I/O region).
* Map the I/O address to NTC1 to be uncachable.
*/
#define UNCACHE_MAP(addr) ((addr) | 0x40000000)
#else
#define UNCACHE_MAP(addr) (addr)
#endif
#define _IO_(addr) UNCACHE_MAP(addr)
/*****************************************************************************
* ExLM - AE210P AHB
* **************************************************************************/
#define EILM_BASE 0x00000000
#ifdef CONFIG_OSC_SUPPORT
#define EDLM_BASE 0x00100000
#else
#define EDLM_BASE 0x00200000
#endif
#define SPIAHBMEM_BASE 0x00800000
/*****************************************************************************
* AHBC - AE210P AHB
****************************************************************************/
#define AHBC_BASE_4_7 _IO_(0x00400000) /* Vendor AHB Slave 8~9 */
#define AHBC_BASE_0_3 _IO_(0x00E20000) /* Vendor AHB Slave 0~7 */
/*****************************************************************************
* BMC - AE210P AHB
****************************************************************************/
#define BMC_BASE _IO_(0x00E00000) /* Device base address */
/*****************************************************************************
* OSC - AE210P OSC
****************************************************************************/
#define OSC_BASE _IO_(0x00E01000)
/* OSC register */
#define OSC_CTRL (OSC_BASE + 0x00)
#define OSC_OVLFS (OSC_BASE + 0x04)
#define OSC_OVLBASE (OSC_BASE + 0x08)
#define OSC_OVLEND (OSC_BASE + 0x0C)
#define OSC_DMAST (OSC_BASE + 0x10)
/*****************************************************************************
* DMAC - AE210P AHB
****************************************************************************/
#define DMAC_BASE _IO_(0x00E0E000) /* Device base address */
/*****************************************************************************
* APBBRG - AE210P APB
****************************************************************************/
#define APBBR_BASE _IO_(0x00F00000) /* Device base address */
/*****************************************************************************
* SMU - AE210P
****************************************************************************/
#define SMU_BASE _IO_(0x00F01000) /* Device base address */
/*****************************************************************************
* UARTx - AE210P
****************************************************************************/
#define UART1_BASE _IO_(0x00F02000) /* Device base address */
#define UART2_BASE _IO_(0x00F03000) /* Device base address */
#define STUARTC_BASE UART2_BASE /* standard/IR UART */
/* UART register offsets (4~8-bit width) */
/* SD_LCR_DLAB == 0 */
#define UARTC_RBR_OFFSET 0x20 /* receiver biffer register */
#define UARTC_THR_OFFSET 0x20 /* transmitter holding register */
#define UARTC_IER_OFFSET 0x24 /* interrupt enable register */
#define UARTC_IIR_OFFSET 0x28 /* interrupt identification register */
#define UARTC_FCR_OFFSET 0x28 /* FIFO control register */
#define UARTC_LCR_OFFSET 0x2c /* line control regitser */
#define UARTC_MCR_OFFSET 0x30 /* modem control register */
#define UARTC_LSR_OFFSET 0x34 /* line status register */
#define UARTC_TST_OFFSET 0x34 /* testing register */
#define UARTC_MSR_OFFSET 0x38 /* modem status register */
#define UARTC_SPR_OFFSET 0x3c /* scratch pad register */
/* SD_LCR_DLAB == 0 */
#define UARTC_DLL_OFFSET 0x20 /* baudrate divisor latch LSB */
#define UARTC_DLM_OFFSET 0x24 /* baudrate divisor latch MSB */
#define UARTC_PSR_OFFSET 0x28 /* prescaler register */
/*****************************************************************************
* PIT - AE210P
****************************************************************************/
#define PIT_BASE _IO_(0x00F04000) /* Device base address */
/* PIT register (32-bit width) */
#define PIT_ID_REV (PIT_BASE + 0x00 ) /* (ro) PIT ID and Revision Register */
#define PIT_CFG (PIT_BASE + 0x10 ) /* (ro) PIT Configuration Register */
#define PIT_INT_EN (PIT_BASE + 0x14 ) /* (rw) PIT Interrupt Enable Register*/
#define PIT_INT_ST (PIT_BASE + 0x18 ) /* (w1c) PIT Interrupt Status Register*/
#define PIT_CH_EN (PIT_BASE + 0x1C ) /* (rw) PIT Channel Enable Register */
/* _chn_ from 0 to 3*/
/* (rw) PIT Channel x Control Register (32-bit width) */
#define PIT_CHNx_CTL(_chn_) ( PIT_BASE + 0x20 + ( (_chn_)* 0x10) )
/* (rw) PIT Channel x Reload Register (32-bit width) */
#define PIT_CHNx_LOAD(_chn_) ( PIT_BASE + 0x24 + ( (_chn_)* 0x10) )
/* (ro) PIT Channel x Counter Register (32-bit width) */
#define PIT_CHNx_COUNT(_chn_) ( PIT_BASE + 0x28 + ( (_chn_)* 0x10) )
/*****************************************************************************
* WDT - AE210P
****************************************************************************/
#define WDTC_BASE _IO_(0x00F05000) /* Device base address */
/*****************************************************************************
* RTC - AE210P
****************************************************************************/
#define RTC_BASE _IO_(0x00F06000) /* Device base address */
/*****************************************************************************
* GPIO - AE210P
****************************************************************************/
#define GPIOC_BASE _IO_(0x00F07000) /* Device base address */
/*****************************************************************************
* I2C - AE210P
****************************************************************************/
#define I2C_BASE _IO_(0x00F0A000) /* Device base address */
/*****************************************************************************
* SPI1 - AE210P
****************************************************************************/
#define SPI1_BASE _IO_(0x00F0B000) /* Device base address */
/*****************************************************************************
* I2S/AC97 - AE210P (SSP2)
****************************************************************************/
#define SPI2_BASE _IO_(0x00F0F000) /* Device base address */
/*****************************************************************************
* APB_SLAVE - AE210P Vender APB Slave 0~4
****************************************************************************/
#define APB_SLAVE_BASE _IO_(0x00F19000) /* Device base address */
/*****************************************************************************
* Macros for Register Access
****************************************************************************/
#define REG32(reg) ( *( (volatile uint32_t *) (reg) ) )
#ifdef REG_IO_HACK
/* 8 bit access */
//#define IN8(reg) ( *( (volatile uint8_t *) (reg) ) )
#define OUT8(reg, data) ( (*( (volatile uint8_t *) (reg) ) ) = (uint8_t)(data) )
#define CLR8(reg) ( *( (volatile uint8_t *) (reg) ) = (uint8_t)0 )
#define MASK8(reg, mask) ( *( (volatile uint8_t *) (reg) ) & (uint8_t)(mask) )
#define UMSK8(reg, mask) ( *( (volatile uint8_t *) (reg) ) & ~( (uint8_t)(mask) ) )
#define SETR8SHL(reg, mask, shift, v) ( *( (volatile uint8_t *) (reg) ) = \
( ( *( (volatile uint8_t *) (reg) ) & ~( (uint8_t)(mask) ) ) | \
( ( (uint8_t)(v) << (shift) ) & (uint8_t)(mask) ) ) )
#define SETR8(reg, mask) ( *( (volatile uint8_t *) (reg) ) = \
( ( *( (volatile uint8_t *) (reg) ) & ~( (uint8_t)(mask) ) ) | (uint8_t)(mask) ) )
#define CLRR8(reg, mask) ( *( (volatile uint8_t *) (reg) ) &= ~( (uint8_t)(mask) ) )
#define SETB8(reg, bit) ( *( (volatile uint8_t *) (reg) ) |= (uint8_t)( (uint8_t)1 << (bit) ) )
#define CLRB8(reg, bit) ( *( (volatile uint8_t *) (reg) ) &= ( ~( (uint8_t) ( (uint8_t)1 << (bit) ) ) ) )
#define GETB8(reg, bit) ( *( (volatile uint8_t *) (reg) ) & (uint8_t) ( (uint8_t)1 << (bit) ) )
#define GETB8SHR(reg, bit) ( (*( (volatile uint8_t *) (reg) ) & (uint8_t) ( (uint8_t)1 << (bit) )) >> (bit) )
/* 16 bit access */
#define IN16(reg) ( *( (volatile uint16_t *) (reg) ) )
#define OUT16(reg, data) ( (*( (volatile uint16_t *) (reg) ) ) = (uint16_t)(data) )
#define CLR16(reg) ( *( (volatile uint16_t *) (reg) ) = (uint16_t)0 )
#define MASK16(reg, mask) ( *( (volatile uint16_t *) (reg) ) & (uint16_t)(mask) )
#define UMSK16(reg, mask) ( *( (volatile uint16_t *) (reg) ) & ~( (uint16_t)(mask) ) )
#define SETR16SHL(reg, mask, shift, v) ( *( (volatile uint16_t *) (reg) ) = \
( ( *( (volatile uint16_t *) (reg) ) & ~( (uint16_t)(mask) ) ) | \
( ( (uint16_t)(v) << (shift) ) & (uint16_t)(mask) ) ) )
#define SETR16(reg, mask) ( *( (volatile uint16_t *) (reg) ) = \
( ( *( (volatile uint16_t *) (reg) ) & ~( (uint16_t)(mask) ) ) | (uint16_t)(mask) ) )
#define CLRR16(reg, mask) ( *( (volatile uint16_t *) (reg) ) &= ~( (uint16_t)(mask) ) )
#define SETB16(reg, bit) ( *( (volatile uint16_t *) (reg) ) |= (uint16_t)( (uint16_t)1 << (bit) ) )
#define CLRB16(reg, bit) ( *( (volatile uint16_t *) (reg) ) &= ( ~( (uint16_t) ( (uint16_t)1 << (bit) ) ) ) )
#define GETB16(reg, bit) ( *( (volatile uint16_t *) (reg) ) & (uint16_t) ( (uint16_t)1 << (bit) ) )
#define GETB16SHR(reg, bit) ( (*( (volatile uint16_t *) (reg) ) & (uint16_t) ( (uint16_t)1 << (bit) )) >> (bit) )
/* 32 bit access */
#define IN32(reg) _IN32((uint32_t)(reg))
#define OUT32(reg, data) _OUT32((uint32_t)(reg), (uint32_t)(data))
#define CLR32(reg) _CLR32((uint32_t)(reg))
#define MASK32(reg, mask) _MASK32((uint32_t)(reg), (uint32_t)(mask))
#define UMSK32(reg, mask) _UMSK32((uint32_t)(reg), (uint32_t)(mask))
#define SETR32SHL(reg, mask, shift, v) _SETR32SHL((uint32_t)(reg), (uint32_t)(mask), (uint32_t)(shift), (uint32_t)(v))
#define SETR32(reg, mask) _SETR32((uint32_t)(reg), (uint32_t)(mask))
#define CLRR32(reg, mask) _CLRR32((uint32_t)(reg), (uint32_t)(mask))
#define SETB32(reg, bit) _SETB32((uint32_t)(reg), (uint32_t)(bit))
#define CLRB32(reg, bit) _CLRB32((uint32_t)(reg), (uint32_t)(bit))
#define GETB32(reg, bit) _GETB32((uint32_t)(reg), (uint32_t)(bit))
#define GETB32SHR(reg, bit) _GETB32SHR((uint32_t)(reg), (uint32_t)(bit))
#else /* REG_IO_HACK */
/* 8 bit access */
//#define IN8(reg) ( *( (volatile uint8_t *) (reg) ) )
#define OUT8(reg, data) ( (*( (volatile uint8_t *) (reg) ) ) = (uint8_t)(data) )
#define CLR8(reg) ( *( (volatile uint8_t *) (reg) ) = (uint8_t)0 )
#define MASK8(reg, mask) ( *( (volatile uint8_t *) (reg) ) & (uint8_t)(mask) )
#define UMSK8(reg, mask) ( *( (volatile uint8_t *) (reg) ) & ~( (uint8_t)(mask) ) )
#define SETR8SHL(reg, mask, shift, v) ( *( (volatile uint8_t *) (reg) ) = \
( ( *( (volatile uint8_t *) (reg) ) & ~( (uint8_t)(mask) ) ) | \
( ( (uint8_t)(v) << (shift) ) & (uint8_t)(mask) ) ) )
#define SETR8(reg, mask) ( *( (volatile uint8_t *) (reg) ) = \
( ( *( (volatile uint8_t *) (reg) ) & ~( (uint8_t)(mask) ) ) | (uint8_t)(mask) ) )
#define CLRR8(reg, mask) ( *( (volatile uint8_t *) (reg) ) &= ~( (uint8_t)(mask) ) )
#define SETB8(reg, bit) ( *( (volatile uint8_t *) (reg) ) |= (uint8_t)( (uint8_t)1 << (bit) ) )
#define CLRB8(reg, bit) ( *( (volatile uint8_t *) (reg) ) &= ( ~( (uint8_t) ( (uint8_t)1 << (bit) ) ) ) )
#define GETB8(reg, bit) ( *( (volatile uint8_t *) (reg) ) & (uint8_t) ( (uint8_t)1 << (bit) ) )
#define GETB8SHR(reg, bit) ( (*( (volatile uint8_t *) (reg) ) & (uint8_t) ( (uint8_t)1 << (bit) )) >> (bit) )
/* 16 bit access */
#define IN16(reg) ( *( (volatile uint16_t *) (reg) ) )
#define OUT16(reg, data) ( (*( (volatile uint16_t *) (reg) ) ) = (uint16_t)(data) )
#define CLR16(reg) ( *( (volatile uint16_t *) (reg) ) = (uint16_t)0 )
#define MASK16(reg, mask) ( *( (volatile uint16_t *) (reg) ) & (uint16_t)(mask) )
#define UMSK16(reg, mask) ( *( (volatile uint16_t *) (reg) ) & ~( (uint16_t)(mask) ) )
#define SETR16SHL(reg, mask, shift, v) ( *( (volatile uint16_t *) (reg) ) = \
( ( *( (volatile uint16_t *) (reg) ) & ~( (uint16_t)(mask) ) ) | \
( ( (uint16_t)(v) << (shift) ) & (uint16_t)(mask) ) ) )
#define SETR16(reg, mask) ( *( (volatile uint16_t *) (reg) ) = \
( ( *( (volatile uint16_t *) (reg) ) & ~( (uint16_t)(mask) ) ) | (uint16_t)(mask) ) )
#define CLRR16(reg, mask) ( *( (volatile uint16_t *) (reg) ) &= ~( (uint16_t)(mask) ) )
#define SETB16(reg, bit) ( *( (volatile uint16_t *) (reg) ) |= (uint16_t)( (uint16_t)1 << (bit) ) )
#define CLRB16(reg, bit) ( *( (volatile uint16_t *) (reg) ) &= ( ~( (uint16_t) ( (uint16_t)1 << (bit) ) ) ) )
#define GETB16(reg, bit) ( *( (volatile uint16_t *) (reg) ) & (uint16_t) ( (uint16_t)1 << (bit) ) )
#define GETB16SHR(reg, bit) ( (*( (volatile uint16_t *) (reg) ) & (uint16_t) ( (uint16_t)1 << (bit) )) >> (bit) )
/* 32 bit access */
#define IN32(reg) ( *( (volatile uint32_t *) (reg) ) )
#define OUT32(reg, data) ( (*( (volatile uint32_t *) (reg) ) ) = (uint32_t)(data) )
#define CLR32(reg) ( *( (volatile uint32_t *) (reg) ) = (uint32_t)0 )
#define MASK32(reg, mask) ( *( (volatile uint32_t *) (reg) ) & (uint32_t)(mask) )
#define UMSK32(reg, mask) ( *( (volatile uint32_t *) (reg) ) & ~( (uint32_t)(mask) ) )
#define SETR32SHL(reg, mask, shift, v) ( *( (volatile uint32_t *) (reg) ) = \
( ( *( (volatile uint32_t *) (reg) ) & ~( (uint32_t)(mask) ) ) | \
( ( (uint32_t)(v) << (shift) ) & (uint32_t)(mask) ) ) )
#define SETR32(reg, mask) ( *( (volatile uint32_t *) (reg) ) = \
( ( *( (volatile uint32_t *) (reg) ) & ~( (uint32_t)(mask) ) ) | (uint32_t)(mask) ) )
#define CLRR32(reg, mask) ( *( (volatile uint32_t *) (reg) ) &= ~( (uint32_t)(mask) ) )
#define SETB32(reg, bit) ( *( (volatile uint32_t *) (reg) ) |= (uint32_t)( (uint32_t)1 << (bit) ) )
#define CLRB32(reg, bit) ( *( (volatile uint32_t *) (reg) ) &= ( ~( (uint32_t) ( (uint32_t)1 << (bit) ) ) ) )
#define GETB32(reg, bit) ( *( (volatile uint32_t *) (reg) ) & (uint32_t) ( (uint32_t)1 << (bit) ) )
#define GETB32SHR(reg, bit) ( (*( (volatile uint32_t *) (reg) ) & (uint32_t) ( (uint32_t)1 << (bit) )) >> (bit) )
#endif /* REG_IO_HACK */
#define SR_CLRB32(reg, bit) \
{ \
int mask = __nds32__mfsr(reg)& ~(1<<bit);\
__nds32__mtsr(mask, reg); \
__nds32__dsb(); \
}
#define SR_SETB32(reg,bit)\
{\
int mask = __nds32__mfsr(reg)|(1<<bit);\
__nds32__mtsr(mask, reg); \
__nds32__dsb(); \
}
#endif /* __AE210P_REGS_H__ */

212
bsp/AE210P/board/uart_dev.c Normal file
View File

@@ -0,0 +1,212 @@
/*
* File : uart_dev.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006-2013, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard the first version
* 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode
* 2013-05-13 aozima update for kehong-lingtai.
*/
#include "uart/uart.h"
#include "uart_dev.h"
#include "ae210p.h"
#include "board.h"
#include "bsp_hal.h"
#include "rtdevice.h"
#include "serial.h"
#define UART_ENABLE_IRQ(n) hal_intc_irq_enable(n)
#define UART_DISABLE_IRQ(n) hal_intc_irq_disable(n)
struct uart_device
{
uint32_t uart_base;
uint32_t irq;
};
static rt_err_t __uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
struct uart_device *uartDev = RT_NULL;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uartDev = (struct uart_device *)serial->parent.user_data;
__drv_uart_init(uartDev->uart_base, cfg->baud_rate);
// todo : enable FIFO threshold, enable rx & rx timeout(threshold) interrupt
return RT_EOK;
}
static rt_err_t __uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
struct uart_device *uartDev = RT_NULL;
RT_ASSERT(serial != RT_NULL);
uartDev = (struct uart_device *)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT: /* disable rx irq */
UART_DISABLE_IRQ(uartDev->irq);
break;
case RT_DEVICE_CTRL_SET_INT: /* enable rx irq */
UART_ENABLE_IRQ(uartDev->irq);
break;
default:
break;
}
return RT_EOK;
}
static int __uart_putc(struct rt_serial_device *serial, char c)
{
struct uart_device *uartDev = RT_NULL;
RT_ASSERT(serial != RT_NULL);
uartDev = (struct uart_device *)serial->parent.user_data;
__drv_uart_put_char(uartDev->uart_base, c); // Transmit Data
return 1;
}
static int __uart_getc(struct rt_serial_device *serial)
{
int ch = -1;
struct uart_device *uartDev = RT_NULL;
RT_ASSERT(serial != RT_NULL);
uartDev = (struct uart_device *)serial->parent.user_data;
ch = -1;
if (__drv_uart_is_kbd_hit(uartDev->uart_base))
{
ch = __drv_uart_get_char(uartDev->uart_base) & 0x00FF;
}
return ch;
}
static const struct rt_uart_ops __uart_ops =
{
__uart_configure,
__uart_control,
__uart_putc,
__uart_getc,
RT_NULL
};
#if RT_USING_UART01
struct uart_device uartDev01 =
{ // UART01 device driver structure
UART1_BASE,
IRQ_UART1_VECTOR
};
struct rt_serial_device serial01;
void URT01_IRQHandler(void)
{
struct uart_device *uartDev = RT_NULL;
uartDev = &uartDev01;
rt_interrupt_enter(); /* enter interrupt */
// if (uart->uart_device->Interrupt & ((1 << bsUART_TIMEOUT_INTENAB) | (1 << bsUART_RECEIVE_INTENAB))) // RX
// {
// rt_hw_serial_isr(&serial01, RT_SERIAL_EVENT_RX_IND);
// }
//
// if (uart->uart_device->Interrupt & (1 << bsUART_TRANSMIT_INTENAB)) // TX
// {
// ;
// }
//
// /* clear all interrupt */
// uart->uart_device->IntClear = (1 << bsUART_RECEIVE_INTENAB)
// | (1 << bsUART_TRANSMIT_INTENAB)
// | (1 << bsUART_TIMEOUT_INTENAB);
rt_interrupt_leave(); /* leave interrupt */
}
#endif /* RT_USING_UART01 */
#if RT_USING_UART02
struct uart_device uartDev02 =
{ // UART02 device driver structure
UART2_BASE,
IRQ_UATR2_VECTOR
};
struct rt_serial_device serial02;
void URT02_IRQHandler(void)
{
struct uart_device *uartDev = RT_NULL;
uartDev = &uartDev02;
rt_interrupt_enter(); /* enter interrupt */
uartDev = uartDev;
rt_interrupt_leave(); /* leave interrupt */
}
#endif /* RT_USING_UART02 */
void rt_hw_usart_init(void)
{
struct uart_device *uartDev = RT_NULL;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#if RT_USING_UART01
uart = &uartDev01;
config.baud_rate = BAUD_RATE_38400;
serial01.ops = &__uart_ops;
serial01.config = config;
// set interrupt priority level
// disable interrupt
// register UART01 device
rt_hw_serial_register(&serial01, "uart01",
RT_DEVICE_FLAG_RDWR /*| RT_DEVICE_FLAG_INT_RX*/,
uartDev);
#endif /* RT_USING_UART01 */
#if RT_USING_UART02
uartDev = &uartDev02;
config.baud_rate = BAUD_RATE_38400;
serial02.ops = &__uart_ops;
serial02.config = config;
// set interrupt priority level
// disable interrupt
/* register UART02 device */
rt_hw_serial_register(&serial02, "uart02",
RT_DEVICE_FLAG_RDWR /*| RT_DEVICE_FLAG_INT_RX*/,
uartDev);
#endif /* RT_USING_UART02 */
}

View File

@@ -0,0 +1,23 @@
/*
* File : uart_dev.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard the first version
*/
#ifndef __UART_DEV_H__
#define __UART_DEV_H__
#include "rthw.h"
#include "rtthread.h"
void rt_hw_usart_init(void);
#endif // end of "__UART_DEV_H__"

77
bsp/AE210P/bsp_hal.h Normal file
View File

@@ -0,0 +1,77 @@
#ifndef __PLAT_HAL_H_
#define __PLAT_HAL_H_
#include "inttypes.h"
/********************************
* INTC HAL DEFINE
********************************/
#define IRQ_EDGE_TRIGGER 1
#define IRQ_LEVEL_TRIGGER 0
#define IRQ_ACTIVE_HIGH 1
#define IRQ_ACTIVE_LOW 0
void hal_intc_init();
void hal_intc_swi_enable();
void hal_intc_swi_disable();
void hal_intc_swi_clean();
void hal_intc_swi_trigger();
/* Call by HISR.
* Since our mask/unmask are not atomic.
* And HISR is task level ISR in RTOS, we need make sure it is atomic.
*
* TODO remove gie if atomic
*/
#define HAL_INTC_IRQ_ATOMIC_DISABLE(_irq_) \
do \
{ \
unsigned long _gie_; \
GIE_SAVE(&_gie_); \
hal_intc_irq_disable(_irq_); \
GIE_RESTORE(_gie_); \
} while(0)
#define HAL_INTC_IRQ_ATOMIC_ENABLE(_irq_) \
do \
{ \
unsigned long _gie_; \
GIE_SAVE(&_gie_); \
hal_intc_irq_enable(_irq_); \
GIE_RESTORE(_gie_); \
} while(0)
uint32_t hal_intc_irq_mask(int _irqs_);
void hal_intc_irq_unmask(int _irqs_);
void hal_intc_irq_clean(int _irqs_);
void hal_intc_irq_clean_all();
void hal_intc_irq_enable(uint32_t _irqs_);
void hal_intc_irq_disable(uint32_t _irqs_);
void hal_intc_irq_disable_all();
void hal_intc_irq_set_priority(uint32_t _prio_ );
void hal_intc_irq_config(uint32_t _irqs_, uint32_t _edge_, uint32_t _falling_);
uint32_t hal_intc_get_all_pend();
/********************************
* TIMER HAL DEFINE
********************************/
uint32_t hal_timer_irq_mask(uint32_t _tmr_ );
void hal_timer_irq_unmask(uint32_t _msk_ );
void hal_timer_irq_clear(uint32_t _tmr_ );
void hal_timer_start(uint32_t _tmr_);
void hal_timer_stop(uint32_t _tmr_ );
uint32_t hal_timer_read(uint32_t _tmr_ );
void hal_timer_set_period(uint32_t _tmr_, uint32_t _period_ );
void hal_timer_set_upward(uint32_t _tmr_ ,uint32_t up);
void hal_timer_init(uint32_t _tmr_ );
void hal_timer_irq_control(uint32_t _tmr_, uint32_t enable );
uint32_t hal_timer_irq_status(uint32_t _tmr_);
void hal_timer_set_match1(uint32_t _tmr_ , uint32_t match );
uint32_t hal_timer_count_read(uint32_t _tmr_);
#endif

273
bsp/AE210P/cache.c Normal file
View File

@@ -0,0 +1,273 @@
#include "nds32.h"
#include "cache.h"
#include "string.h"
void nds32_dcache_invalidate(void){
#ifdef CONFIG_CPU_DCACHE_ENABLE
__nds32__cctl_l1d_invalall();
__nds32__msync_store();
__nds32__dsb();
#endif
}
void nds32_dcache_flush(void){
#ifdef CONFIG_CPU_DCACHE_ENABLE
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
unsigned long saved_gie;
#endif
unsigned long end;
unsigned long cache_line;
cache_line = CACHE_LINE_SIZE(DCACHE);
end = CACHE_WAY(DCACHE) * CACHE_SET(DCACHE) * cache_line;
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
GIE_SAVE(&saved_gie);
/*
* Use CCTL L1D_IX_WB/L1D_IX_INVAL subtype instead of combined
* L1D_IX_WBINVAL. Because only N903 supports L1D_IX_WBINVAL.
*/
do {
end -= cache_line;
__nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, end);
__nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, end);
} while (end > 0);
GIE_RESTORE(saved_gie);
#else
while (end > 0){
end -= cache_line;
__nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, end);
}
#endif
__nds32__msync_store();
__nds32__dsb();
#endif
}
void nds32_icache_flush(void){
#ifdef CONFIG_CPU_ICACHE_ENABLE
unsigned long end;
unsigned long cache_line = CACHE_LINE_SIZE(ICACHE);
end = CACHE_WAY(ICACHE) * CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE);
do {
end -= cache_line;
__nds32__cctlidx_wbinval(NDS32_CCTL_L1I_IX_INVAL, end);
} while (end > 0);
__nds32__isb();
#endif
}
#ifdef CONFIG_CHECK_RANGE_ALIGNMENT
#define chk_range_alignment(start, end, line_size) do { \
\
BUG_ON((start) & ((line_size) - 1)); \
BUG_ON((end) & ((line_size) - 1)); \
BUG_ON((start) == (end)); \
\
} while (0);
#else
#define chk_range_alignment(start, end, line_size)
#endif
/* ================================ D-CACHE =============================== */
/*
* nds32_dcache_clean_range(start, end)
*
* For the specified virtual address range, ensure that all caches contain
* clean data, such that peripheral accesses to the physical RAM fetch
* correct data.
*/
void nds32_dcache_clean_range(unsigned long start, unsigned long end){
#ifdef CONFIG_CPU_DCACHE_ENABLE
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
chk_range_alignment(start, end, line_size);
while (end > start){
__nds32__cctlva_wbinval_one_lvl(NDS32_CCTL_L1D_VA_WB, (void *)start);
start += line_size;
}
__nds32__msync_store();
__nds32__dsb();
#endif
#endif
}
void nds32_dma_clean_range(unsigned long start, unsigned long end){
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
start = start & (~(line_size-1));
end = (end + line_size -1) & (~(line_size-1));
if (start == end)
return;
nds32_dcache_clean_range(start, end);
}
/*
* nds32_dcache_invalidate_range(start, end)
*
* throw away all D-cached data in specified region without an obligation
* to write them back. Note however that we must clean the D-cached entries
* around the boundaries if the start and/or end address are not cache
* aligned.
*/
void nds32_dcache_invalidate_range(unsigned long start, unsigned long end){
#ifdef CONFIG_CPU_DCACHE_ENABLE
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
chk_range_alignment(start, end, line_size);
while (end > start){
__nds32__cctlva_wbinval_one_lvl(NDS32_CCTL_L1D_VA_INVAL, (void *)start);
start += line_size;
}
#endif
}
void nds32_dcache_flush_range(unsigned long start, unsigned long end){
#ifdef CONFIG_CPU_DCACHE_ENABLE
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
while (end > start){
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
__nds32__cctlva_wbinval_one_lvl(NDS32_CCTL_L1D_VA_WB, (void *)start);
#endif
__nds32__cctlva_wbinval_one_lvl(NDS32_CCTL_L1D_VA_INVAL, (void *)start);
start += line_size;
}
#endif
}
void nds32_dcache_writeback_range(unsigned long start, unsigned long end){
#ifdef CONFIG_CPU_DCACHE_ENABLE
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
while (end > start){
__nds32__cctlva_wbinval_one_lvl(NDS32_CCTL_L1D_VA_WB, (void *)start);
start += line_size;
}
#endif
#endif
}
void unaligned_cache_line_move(unsigned char* src, unsigned char* dst, unsigned long len )
{
int i;
unsigned char* src_p = (unsigned char*)src;
unsigned char* dst_p = (unsigned char*)dst;
for( i = 0 ;i < len; ++i)
*(dst_p+i)=*(src_p+i);
}
void nds32_dma_inv_range(unsigned long start, unsigned long end){
unsigned long line_size;
unsigned long old_start=start;
unsigned long old_end=end;
line_size = CACHE_LINE_SIZE(DCACHE);
unsigned char h_buf[line_size];
unsigned char t_buf[line_size];
memset((void*)h_buf,0,line_size);
memset((void*)t_buf,0,line_size);
start = start & (~(line_size-1));
end = (end + line_size -1) & (~(line_size-1));
if (start == end)
return;
if (start != old_start)
{
//nds32_dcache_flush_range(start, start + line_size);
unaligned_cache_line_move((unsigned char*)start, h_buf, old_start - start);
}
if (end != old_end)
{
//nds32_dcache_flush_range(end - line_size ,end);
unaligned_cache_line_move((unsigned char*)old_end, t_buf, end - old_end);
}
nds32_dcache_invalidate_range(start, end);
//handle cache line unaligned problem
if(start != old_start)
unaligned_cache_line_move(h_buf,(unsigned char*)start, old_start - start);
if( end != old_end )
unaligned_cache_line_move(t_buf,(unsigned char*)old_end, end - old_end);
}
void nds32_dma_flush_range(unsigned long start, unsigned long end){
unsigned long line_size;
line_size = CACHE_LINE_SIZE(DCACHE);
start = start & (~(line_size-1));
end = (end + line_size -1 ) & (~(line_size-1));
if (start == end)
return;
nds32_dcache_flush_range(start, end);
}
/* ================================ I-CACHE =============================== */
/*
* nds32_icache_invalidate_range(start, end)
*
* invalidate a range of virtual addresses from the Icache
*
* This is a little misleading, it is not intended to clean out
* the i-cache but to make sure that any data written to the
* range is made consistant. This means that when we execute code
* in that region, everything works as we expect.
*
* This generally means writing back data in the Dcache and
* write buffer and flushing the Icache over that region
*
* start: virtual start address
* end: virtual end address
*/
void nds32_icache_invalidate_range(unsigned long start, unsigned long end){
#ifdef CONFIG_CPU_ICACHE_ENABLE
unsigned long line_size;
line_size = CACHE_LINE_SIZE(ICACHE);
//chk_range_alignment(start, end, line_size);
start &= (~(line_size-1));
end = ( end + line_size - 1 )&(~(line_size-1));
if (end == start)
end += line_size;
while (end > start){
end -= line_size;
__nds32__cctlva_wbinval_one_lvl(NDS32_CCTL_L1I_VA_INVAL, (void *)end);
}
#endif
}

45
bsp/AE210P/cache.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef __CACHE_H__
#define __CACHE_H__
#include "nds32_intrinsic.h"
#include "nds32.h"
enum cache_t{ICACHE, DCACHE};
static inline unsigned long CACHE_SET(enum cache_t cache){
if(cache == ICACHE)
return 64 << ((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskISET) >> ICM_CFG_offISET);
else
return 64 << ((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDSET) >> DCM_CFG_offDSET);
}
static inline unsigned long CACHE_WAY(enum cache_t cache){
if(cache == ICACHE)
return 1 + ((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskIWAY) >> ICM_CFG_offIWAY);
else
return 1 + ((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDWAY) >> DCM_CFG_offDWAY);
}
static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache){
if(cache == ICACHE)
return 8 << (((__nds32__mfsr(NDS32_SR_ICM_CFG) & ICM_CFG_mskISZ) >> ICM_CFG_offISZ) - 1);
else
return 8 << (((__nds32__mfsr(NDS32_SR_DCM_CFG) & DCM_CFG_mskDSZ) >> DCM_CFG_offDSZ) - 1);
}
extern void nds32_dcache_invalidate(void);
extern void nds32_dcache_flush(void);
extern void nds32_icache_flush(void);
extern void nds32_dcache_clean_range(unsigned long start, unsigned long end);
extern void nds32_dma_clean_range(unsigned long start, unsigned long end);
extern void nds32_dcache_invalidate_range(unsigned long start, unsigned long end);
extern void nds32_dcache_flush_range(unsigned long start, unsigned long end);
extern void nds32_dcache_writeback_range(unsigned long start, unsigned long end);
extern void nds32_dma_inv_range(unsigned long start, unsigned long end);
extern void nds32_dma_flush_range(unsigned long start, unsigned long end);
extern void nds32_icache_invalidate_range(unsigned long start, unsigned long end);
#endif /* __CACHE_H__ */

48
bsp/AE210P/config.h Normal file
View File

@@ -0,0 +1,48 @@
#define CONFIG_HEARTBEAT_LED 1
/*
* Select Platform
*/
#ifdef AE210P
#define CONFIG_PLAT_AE210P 1
#define IRQ_STACK_SIZE 5120 /* IRQ stack size */
#else
#error "No valid platform is defined!"
#endif
/*
* Platform Option
*/
#define VECTOR_BASE 0x00000000
#define VECTOR_NUMINTRS 32
#define NO_EXTERNAL_INT_CTL 1
#define XIP_MODE 1
#ifdef CONFIG_OSC_SUPPORT
#define OSC_EILM_SIZE 0x10000 // 64KB
#undef XIP_MODE
#endif
#undef CONFIG_HW_PRIO_SUPPORT
/*
* Cache Option
*/
#if (!defined(__NDS32_ISA_V3M__) && defined(CONFIG_CACHE_SUPPORT))
#define CONFIG_CPU_ICACHE_ENABLE 1
#define CONFIG_CPU_DCACHE_ENABLE 1
//#define CONFIG_CPU_DCACHE_WRITETHROUGH 1
#endif
#undef CONFIG_CHECK_RANGE_ALIGNMENT
#undef CONFIG_CACHE_L2
#undef CONFIG_FULL_ASSOC
/*
* Debugging Options
*/
#undef CONFIG_DEBUG
#undef CONFIG_WERROR
#include "ae210p.h"

View File

@@ -0,0 +1,2 @@
lib-y :=
lib-y += dmad.o

2513
bsp/AE210P/driver/dma/dmad.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,275 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2007-2008
* All Rights Reserved.
*
* Revision History:
*
* Aug.21.2007 Created.
****************************************************************************/
/*****************************************************************************
*
* FILE NAME VERSION
*
* dmad.h
*
* DESCRIPTION
*
* DMA controller driver internal supplement library.
*
* DATA STRUCTURES
*
* None
*
* DEPENDENCIES
*
* ag101regs.h
* ag101defs.h
*
****************************************************************************/
#ifndef __DMAD_H__
#define __DMAD_H__
#include <hal.h>
/*****************************************************************************
* Configuration section
****************************************************************************/
/* Code size control */
#define DMAD_SMALL_FOOTPRINT 0 /* non-zero to disable extra features for small footprint */
/* Debug trace enable switch */
#define DMAD_DEBUG_TRACE 0 /* non-zero to enable debug trace message */
/* DMAD globals section */
enum DMAD_DMAC_CORE { DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE };
/*
* AHB Channel Request
*
* Notes for developers:
* These should be channel-only properties. Controller-specific properties
* should be separated as other driver structure or driver buildin-hardcode.
* If controller properties are embeded in this union, request for a channel
* may unexpectedly override the controller setting of the request of other
* channels.
*/
typedef struct DMAD_AHBCH_REQUEST_STRUCT{
/* controller property (removed! should not exist in this struct) */
// uint8_t big_endian; /* (in) currently only M0 is designed, and transfer endian is default to little */
/* channel property */
uint32_t sync; /* (in) non-zero if src and dst have different clock domain */
uint32_t priority; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */
uint32_t hw_handshake; /* (in) non-zero to enable hardware handshake mode */
/* (required when need multiple bursts or in chain mode?) */
uint32_t burst_size; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */
/* source property */
uint32_t src_width; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
uint32_t src_addr_ctrl; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
uint32_t src_reqn; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
uint32_t src_index;
/* destination property */
uint32_t dst_width; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
uint32_t dst_addr_ctrl; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
uint32_t dst_reqn; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
uint32_t dst_index;
} DMAD_AHBCH_REQUEST;
/*
* APB Channel Request
*
* Notes for developers:
* These should be channel-only properties. Controller-specific properties
* should be separated as other driver structure or driver buildin-hardcode.
* If controller properties are embeded in this union, request for a channel
* may unexpectedly override the controller setting of the request of other
* channels.
*/
typedef struct DMAD_APBCH_REQUEST_STRUCT{
/* controller property (removed! should not exist in this struct) */
/* channel property */
uint32_t burst_mode; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */
uint32_t data_width; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */
/* source property */
uint32_t src_addr_ctrl; /* (in) APBBR_ADDRINC_xxx */
uint32_t src_reqn; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
uint32_t src_index;
/* destination property */
uint32_t dst_addr_ctrl; /* (in) APBBR_ADDRINC_xxx */
uint32_t dst_reqn; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
uint32_t dst_index;
} DMAD_APBCH_REQUEST;
/* Channel Request Descriptor */
typedef struct DMAD_CHANNEL_REQUEST_DESC_STRUCT{
uint32_t controller; /* (in) Use DMA controller in AHB or APB - one of the enum value of DMAD_DMAC_CORE */
uint32_t channel; /* (out) Allocated/granted channel */
void *drq; /* (out) Handle to DMA request queue (ptr to DMAD_DRQ, internal use) */
/*
* Properties for channel-alloc request
* Notes for developers:
* These should be channel-only properties. Controller-specific properties
* should be separated as other driver structure or driver buildin-hardcode.
* If controller properties are embeded in this union, request for a channel
* may unexpectedly override the controller setting of the request of other
* channels.
*/
union {
DMAD_AHBCH_REQUEST ahbch_req; /* (in) parameters for AHB DMAC channel request */
DMAD_APBCH_REQUEST apbch_req; /* (in) parameters for APB Bridge embeded DMA conteoller channel request */
};
} DMAD_CHANNEL_REQUEST_DESC;
enum DMAD_DRB_STATE{
DMAD_DRB_STATE_FREE = 0,
DMAD_DRB_STATE_READY,
DMAD_DRB_STATE_SUBMITTED,
DMAD_DRB_STATE_TRANSFERRING,
DMAD_DRB_STATE_COMPLETED,
DMAD_DRB_STATE_ERROR,
DMAD_DRB_STATE_ABORT,
};
/* DMA request block */
typedef struct DMAD_DRB_STRUCT{
uint32_t prev; /* (internal) Linked list previous node */
uint32_t next; /* (internal) Linked list next node */
uint32_t node; /* (internal) Linked list this node */
uint32_t state; /* (out) DRB's current state in the whole submission cycle. */
void *src_addr; /* (in) Source address in this request */
void *dst_addr; /* (in) Destination address in this submission request */
uint32_t req_size; /* (in) AHB DMA (12 bits): 0 ~ 4095, unit is number of "data width" */
/* APB DMA (24 bits): 0 ~ 16M-1, unit is number of "data width * burst size" */
uint32_t transfer_size; /* req_size * data_width*/
hal_semaphore_t *completion_sem;/* (in) Application supplied semaphore to signal completion of this */
/* DMA request block. Specify null to by-pass this mechanism. */
void (*psp)(void*); /* pre-submission programming */
void (*rcp)(void*); /* completion-of-submission programming */
void *data;
uint32_t src_index; /* to indicate it's device or memory */
uint32_t dst_index; /* to indicate it's device or memory */
// uint32_t src_reqn; /* to indicate it's device or memory */
// uint32_t dst_reqn; /* to indicate it's device or memory */
} DMAD_DRB;
enum DMAD_CHDIR
{
DMAD_DIR_A0_TO_A1 = 0,
DMAD_DIR_A1_TO_A0 = 1,
};
/* Debug Trace Mechanism */
#if (DMAD_DEBUG_TRACE)
#define DMAD_TRACE(x) printf x
#define DMAD_STRACE(x) printf x
#else /* DMAD_DEBUG_TRACE */
#define DMAD_TRACE(x)
#define DMAD_STRACE(x)
#endif /* DMAD_DEBUG_TRACE */
/*****************************************************************************
* DMAD Driver Interface
*
* [Structures]
*
* [Functions]
*
*
****************************************************************************/
extern uint32_t _dmad_channel_alloc(DMAD_CHANNEL_REQUEST_DESC *ch_req, uint8_t init);
extern uint32_t _dmad_channel_free(const DMAD_CHANNEL_REQUEST_DESC *ch_req);
extern uint32_t _dmad_channel_init(const DMAD_CHANNEL_REQUEST_DESC *ch_req);
extern uint32_t _dmad_channel_enable(const DMAD_CHANNEL_REQUEST_DESC *ch_req, uint8_t enable);
extern uint32_t _dmad_alloc_drb(DMAD_CHANNEL_REQUEST_DESC *ch_req, DMAD_DRB **drb);
extern uint32_t _dmad_free_drb(DMAD_CHANNEL_REQUEST_DESC *ch_req, DMAD_DRB *drb);
extern uint32_t _dmad_submit_request(DMAD_CHANNEL_REQUEST_DESC *ch_req, DMAD_DRB *drb);
extern uint32_t _dmad_cancel_request(DMAD_CHANNEL_REQUEST_DESC *ch_req, DMAD_DRB *drb);
extern uint32_t _dmad_wait(DMAD_CHANNEL_REQUEST_DESC *ch_req);
extern uint32_t _dmad_get_reqn(uint32_t dma_controller, uint32_t device);
enum ahp_reqn_index_t {
AHB_NONE,
AHB_CFC,
AHB_SSP,
AHB_UART1TX,
AHB_UART1RX,
AHB_I2SAC97,
AHB_USB,
AHB_EXT0,
AHB_EXT1,
AHB_SSP1TX,
AHB_SSP1RX,
AHB_UART2TX,
AHB_UART2RX,
AHB_UART4TX,
AHB_UART4RX,
AHB_SDC,
AHB_SSP2TX,
AHB_SSP2RX,
AHB_USB_2_0,
AHB_USB_1_1_EP1,
AHB_USB_1_1_EP2,
AHB_USB_1_1_EP3,
AHB_USB_1_1_EP4
};
enum apb_reqn_index_t {
APB_NONE,
APB_CFC,
APB_SSP,
APB_BTUART,
APB_I2SAC97,
APB_STUART,
APB_I2S,
APB_SSP2,
APB_EXT0,
APB_EXT1,
APB_SSP1TX,
APB_SSP1RX,
APB_UART2TX,
APB_UART2RX,
APB_UART4TX,
APB_UART4RX,
APB_SDC,
APB_SSP2TX,
APB_SSP2RX,
APB_USB_2_0,
APB_USB_1_1_EP1,
APB_USB_1_1_EP2,
APB_USB_1_1_EP3,
APB_USB_1_1_EP4,
APB_MAX
};
#endif /* __DMAD_H__ */

View File

@@ -0,0 +1,86 @@
#include "gpio.h"
//#include "hal.h"
#include "bsp_hal.h"
struct gpio_dev_t *gpio_p;
//static void _gpio_lisr(int vector)
//{
// DEBUG(0, 1, "Enter\n");
// if (vector != IRQ_GPIO_VECTOR)
// hal_system_error(HAL_ERR_UNHANDLED_INTERRUPT);
//
// /* Disable GPIO interrupt */
// uint32_t prv_msk = hal_intc_irq_mask(IRQ_GPIO_VECTOR);
//
// /* Get int state and then clear it */
// unsigned int int_sr = IN32(GPIOC_INT_RAW_STATE);
// gpio_p->int_data = int_sr;
// OUT32(GPIOC_INT_CLEAR, int_sr);
//
// /* Clean GPIO pending */
// hal_intc_irq_clean(IRQ_GPIO_VECTOR);
//
// /* Enable higher priority interrupt */
// /* comment it to disable nested interrupt */
// GIE_ENABLE();
// hal_raise_bh(&gpio_p->hisr);
//
// GIE_DISABLE();
// /* - Enable GPIO interrupt */
// hal_intc_irq_unmask(prv_msk);
//}
int gpio_init(struct gpio_dev_t *gpio)
{
// int status = HAL_SUCCESS;
// int core_intl;
//
// /* initialize global gpio pointer */
// gpio_p = gpio;
// core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
//
// /* INTC */
// // - Disable GPIO interrupt
// hal_intc_irq_disable(IRQ_GPIO_VECTOR);
// // - Clear GPIO interrupt status
// hal_intc_irq_clean(IRQ_GPIO_VECTOR);
// // - Setup #PENIRQ trigger mode - edge trigger
// // - Setup #PENIRQ trigger level - active high
// hal_intc_irq_config(IRQ_GPIO_VECTOR, IRQ_EDGE_TRIGGER, IRQ_ACTIVE_HIGH);
//
//
// /* GPIO */
// /* falling, interrupt when pressed */
// //OUT32(GPIOC_INT_RISE_NEG, 0xFFFFFFFF);
// /* rising, interrupt when released */
// OUT32(GPIOC_INT_RISE_NEG, 0x0);
// /* enable all gpio interrupt GPIO1-5*/
// OUT32(GPIOC_INT_ENABLE, 0x3E);
// /* set the max value to debounce */
// OUT32(GPIOC_INT_BOUNCE_PRESCALE, 0xFFFF);
// /* enable debounce */
// OUT32(GPIOC_INT_BOUNCE_ENABLE, 0x3E);
//
// status = hal_register_isr(IRQ_GPIO_VECTOR, _gpio_lisr, (void*)0);
//
// if (status != HAL_SUCCESS){
// DEBUG(1, 1, "Failed to register GPIO driver LISR!\n");
// return status;
// }
//
// status = hal_create_bh(&gpio->hisr);
// if (status != HAL_SUCCESS){
// DEBUG(1, 1, "Failed to create GPIO driver HISR!\n");
// return status;
// }
//
// // - Enable GPIO interrupt
// hal_intc_irq_enable(IRQ_GPIO_VECTOR);
//
// /* Restore CPU interrupt controller to previous level */
// hal_global_int_ctl(core_intl);
// return status;
return 0;
}

View File

@@ -0,0 +1,52 @@
#ifndef __AG101_GPIOC_INC__
#define __AG101_GPIOC_INC__
//#include "hal.h"
// GPIO port name definition
typedef enum GPIOD_PORTS
{
GPIO0 = 0x00000001,
GPIO1 = 0x00000002,
GPIO2 = 0x00000004,
GPIO3 = 0x00000008,
GPIO4 = 0x00000010,
GPIO5 = 0x00000020,
GPIO6 = 0x00000040,
GPIO7 = 0x00000080,
GPIO8 = 0x00000100,
GPIO9 = 0x00000200,
GPIO10 = 0x00000400,
GPIO11 = 0x00000800,
GPIO12 = 0x00001000,
GPIO13 = 0x00002000,
GPIO14 = 0x00004000,
GPIO15 = 0x00008000,
GPIO16 = 0x00010000,
GPIO17 = 0x00020000,
GPIO18 = 0x00040000,
GPIO19 = 0x00080000,
GPIO20 = 0x00100000,
GPIO21 = 0x00200000,
GPIO22 = 0x00400000,
GPIO23 = 0x00800000,
GPIO24 = 0x01000000,
GPIO25 = 0x02000000,
GPIO26 = 0x04000000,
GPIO27 = 0x08000000,
GPIO28 = 0x10000000,
GPIO29 = 0x20000000,
GPIO30 = 0x40000000,
GPIO31 = 0x80000000,
} GPIOD_PORTS;
struct gpio_dev_t
{
// hal_bh_t hisr;
unsigned int int_data;
};
#endif // __AG101_GPIOC_INC__

View File

@@ -0,0 +1 @@
lib-${CONFIG_FB_FTLCDC100} += font.o lcd.o

View File

@@ -0,0 +1,248 @@
#include "lcd/lcd.h"
/*
* Due to legal issue, this section is disabled and only available to the
* usage of internal developement and testing.
*
* Build-in OSD 12x16 font table (sizeof(UINT16) * 16 per font)
* LCDC maximum number of fonts = 256
*
* Font Name : Courier New (C) Microsoft
*
* ASCII Code Range : (0x20~0x7e, and 0x7f is a special symbol looks like 'v')
* " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~v"
*/
uint16_t drv_lcd_font_table[] __attribute__((aligned(4))) = {
/* ASCII 0x20 ~ 0x2F */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040,
0x0040, 0x0000, 0x0000, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01b0, 0x01b0, 0x0120, 0x0120, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0090, 0x0090, 0x0120, 0x03f0, 0x0120,
0x0120, 0x03f0, 0x0120, 0x0240, 0x0240, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0040, 0x00e0, 0x0120, 0x0100, 0x00c0,
0x0020, 0x0120, 0x01c0, 0x0040, 0x0040, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x00c0, 0x0120, 0x0120, 0x00c0, 0x01f0,
0x0060, 0x0090, 0x0090, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0040, 0x0040, 0x0040, 0x0040, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0020, 0x0020, 0x0040, 0x0040, 0x0040,
0x0040, 0x0040, 0x0040, 0x0040, 0x0020, 0x0020, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0100, 0x0100, 0x0100, 0x0080, 0x0080,
0x0080, 0x0080, 0x0080, 0x0100, 0x0100, 0x0100, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0080, 0x0080, 0x03e0, 0x0080, 0x0140,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0040, 0x0040, 0x0040, 0x03f8,
0x0040, 0x0040, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x00c0, 0x0080, 0x0180, 0x0100, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03f0,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x00c0, 0x00c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0010, 0x0010, 0x0020, 0x0020, 0x0040, 0x0040,
0x0080, 0x0080, 0x0100, 0x0100, 0x0200, 0x0000, 0x0000, 0x0000,
/* ASCII 0x30 ~ 0x3F */
0x0000, 0x0000, 0x0000, 0x01e0, 0x0210, 0x0210, 0x0210, 0x0210,
0x0210, 0x0210, 0x0210, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0040, 0x01c0, 0x0040, 0x0040, 0x0040,
0x0040, 0x0040, 0x0040, 0x01f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01c0, 0x0220, 0x0020, 0x0040, 0x0040,
0x0080, 0x0100, 0x0220, 0x03e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01c0, 0x0220, 0x0020, 0x0020, 0x00c0,
0x0020, 0x0020, 0x0220, 0x01c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0060, 0x00a0, 0x00a0, 0x0120, 0x0120,
0x03f0, 0x0020, 0x0020, 0x0070, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01f0, 0x0100, 0x0100, 0x01e0, 0x0010,
0x0010, 0x0010, 0x0210, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0070, 0x0080, 0x0100, 0x0100, 0x01e0,
0x0110, 0x0110, 0x0110, 0x00e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x03f0, 0x0210, 0x0010, 0x0020, 0x0020,
0x0020, 0x0040, 0x0040, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01c0, 0x0220, 0x0220, 0x0220, 0x01c0,
0x0220, 0x0220, 0x0220, 0x01c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01e0, 0x0210, 0x0210, 0x0210, 0x0210,
0x01f0, 0x0010, 0x0020, 0x03c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00c0, 0x00c0,
0x0000, 0x0000, 0x00c0, 0x00c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00c0, 0x00c0,
0x0000, 0x0000, 0x00c0, 0x0080, 0x0180, 0x0100, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0018, 0x0060, 0x0080,
0x0300, 0x0080, 0x0060, 0x0018, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07f0, 0x0000, 0x0000,
0x07f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0300, 0x00c0, 0x0020,
0x0018, 0x0020, 0x00c0, 0x0300, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x01c0, 0x0220, 0x0020, 0x0020,
0x0040, 0x0080, 0x0000, 0x00c0, 0x0000, 0x0000, 0x0000, 0x0000,
/* ASCII 0x40 ~ 0x4F */
0x0000, 0x0000, 0x0000, 0x00e0, 0x0110, 0x0210, 0x0270, 0x0290,
0x0290, 0x0270, 0x0200, 0x0110, 0x00e0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x01c0, 0x00c0, 0x00c0, 0x0120,
0x0120, 0x01e0, 0x0210, 0x0738, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03e0, 0x0110, 0x0110, 0x01e0,
0x0110, 0x0110, 0x0110, 0x03e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x00d0, 0x0130, 0x0200, 0x0200,
0x0200, 0x0200, 0x0110, 0x00e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03c0, 0x0120, 0x0110, 0x0110,
0x0110, 0x0110, 0x0120, 0x03c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, 0x0110, 0x0120, 0x01e0,
0x0120, 0x0100, 0x0110, 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, 0x0110, 0x0150, 0x01c0,
0x0140, 0x0100, 0x0100, 0x03c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x00d0, 0x0130, 0x0200, 0x0200,
0x0278, 0x0210, 0x0110, 0x00e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03b8, 0x0110, 0x0110, 0x01f0,
0x0110, 0x0110, 0x0110, 0x03b8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x01f0, 0x0040, 0x0040, 0x0040,
0x0040, 0x0040, 0x0040, 0x01f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x01f8, 0x0020, 0x0020, 0x0020,
0x0220, 0x0220, 0x0220, 0x01c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03b8, 0x0120, 0x0140, 0x0180,
0x01c0, 0x0120, 0x0110, 0x0398, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x07c0, 0x0100, 0x0100, 0x0100,
0x0110, 0x0110, 0x0110, 0x07f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0718, 0x0318, 0x02a8, 0x02a8,
0x02a8, 0x0248, 0x0208, 0x0718, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03b8, 0x0190, 0x0190, 0x0150,
0x0150, 0x0150, 0x0130, 0x03b0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x00e0, 0x0110, 0x0208, 0x0208,
0x0208, 0x0208, 0x0110, 0x00e0, 0x0000, 0x0000, 0x0000, 0x0000,
/* ASCII 0x50 ~ 0x5F */
0x0000, 0x0000, 0x0000, 0x0000, 0x03e0, 0x0110, 0x0110, 0x0110,
0x01e0, 0x0100, 0x0100, 0x03c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x00e0, 0x0110, 0x0208, 0x0208,
0x0208, 0x0208, 0x0110, 0x00e0, 0x00f8, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03e0, 0x0110, 0x0110, 0x0110,
0x01e0, 0x0120, 0x0110, 0x0388, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x01d0, 0x0230, 0x0200, 0x01e0,
0x0010, 0x0010, 0x0310, 0x02e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03f8, 0x0248, 0x0248, 0x0040,
0x0040, 0x0040, 0x0040, 0x01f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03b8, 0x0110, 0x0110, 0x0110,
0x0110, 0x0110, 0x0110, 0x00e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0738, 0x0210, 0x0120, 0x0120,
0x0120, 0x00c0, 0x00c0, 0x00c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0718, 0x0208, 0x0248, 0x0248,
0x02a8, 0x02a8, 0x02a8, 0x0110, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03b8, 0x0110, 0x00a0, 0x0040,
0x0040, 0x00a0, 0x0110, 0x03b8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03b8, 0x0110, 0x00a0, 0x00a0,
0x0040, 0x0040, 0x0040, 0x01f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x03f0, 0x0210, 0x0020, 0x0040,
0x0080, 0x0110, 0x0210, 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x00e0, 0x0080, 0x0080, 0x0080, 0x0080,
0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x00e0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0200, 0x0100, 0x0100, 0x0100, 0x0080, 0x0080,
0x0040, 0x0040, 0x0020, 0x0020, 0x0020, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01c0, 0x0040, 0x0040, 0x0040, 0x0040,
0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x01c0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0080, 0x0080, 0x0140, 0x0220, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07f8,
/* ASCII 0x60 ~ 0x6F */
0x0000, 0x0000, 0x0000, 0x0080, 0x0040, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01e0, 0x0210,
0x01f0, 0x0210, 0x0230, 0x01d8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0600, 0x0200, 0x0200, 0x02e0, 0x0310,
0x0210, 0x0210, 0x0310, 0x06e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01d0, 0x0230,
0x0200, 0x0200, 0x0210, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0030, 0x0010, 0x0010, 0x01d0, 0x0230,
0x0210, 0x0210, 0x0210, 0x01f8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01e0, 0x0210,
0x03f0, 0x0200, 0x0200, 0x01f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0070, 0x0080, 0x0080, 0x03f0, 0x0080,
0x0080, 0x0080, 0x0080, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01d8, 0x0230,
0x0210, 0x0210, 0x0230, 0x01d0, 0x0010, 0x0010, 0x01e0, 0x0000,
0x0000, 0x0000, 0x0000, 0x0300, 0x0100, 0x0100, 0x0160, 0x0190,
0x0110, 0x0110, 0x0110, 0x03b8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0040, 0x0000, 0x01c0, 0x0040,
0x0040, 0x0040, 0x0040, 0x03f8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0040, 0x0000, 0x03e0, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x03c0, 0x0000,
0x0000, 0x0000, 0x0000, 0x0300, 0x0100, 0x0100, 0x0170, 0x0140,
0x0180, 0x0140, 0x0120, 0x0338, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x00c0, 0x0040, 0x0040, 0x0040, 0x0040,
0x0040, 0x0040, 0x0040, 0x03f8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0690, 0x0368,
0x0248, 0x0248, 0x0248, 0x0768, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0360, 0x0190,
0x0110, 0x0110, 0x0110, 0x03b8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01e0, 0x0210,
0x0210, 0x0210, 0x0210, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000,
/* ASCII 0x70 ~ 0x7F */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0360, 0x0190,
0x0110, 0x0110, 0x0110, 0x01e0, 0x0100, 0x0100, 0x0380, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01d8, 0x0230,
0x0210, 0x0210, 0x0230, 0x01d0, 0x0010, 0x0010, 0x0038, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0370, 0x0180,
0x0100, 0x0100, 0x0100, 0x03e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01f0, 0x0210,
0x01e0, 0x0010, 0x0210, 0x03e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0100, 0x03f0, 0x0100,
0x0100, 0x0100, 0x0110, 0x00e0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0330, 0x0110,
0x0110, 0x0110, 0x0130, 0x00d8, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0738, 0x0210,
0x0120, 0x0120, 0x00c0, 0x00c0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0718, 0x0208,
0x0248, 0x02a8, 0x02a8, 0x0110, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0330, 0x0120,
0x00c0, 0x00c0, 0x0120, 0x0330, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03b8, 0x0110,
0x0110, 0x00a0, 0x00a0, 0x0040, 0x0040, 0x0080, 0x01c0, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01f0, 0x0120,
0x0040, 0x0080, 0x0110, 0x01f0, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0020, 0x0040, 0x0040, 0x0040, 0x0040,
0x0080, 0x0040, 0x0040, 0x0040, 0x0040, 0x0020, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040,
0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0100, 0x0080, 0x0080, 0x0080, 0x0080,
0x0040, 0x0080, 0x0080, 0x0080, 0x0080, 0x0100, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0190,
0x0260, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0010, 0x0010,
0x0320, 0x0120, 0x00c0, 0x0040, 0x0040, 0x0000, 0x0000, 0x0000,
};
int width = 12;
int height = 16;
void draw_font(int x, int y, int ascii)
{
uint16_t *idx;
int i, j;
if (ascii < 0 || ascii > (sizeof(drv_lcd_font_table) / sizeof(uint16_t)))
return;
idx = &drv_lcd_font_table[(ascii - ' ') * 16];
// drv_lcd_erase_rect(x, width, y, height);
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
if (*idx & (1 << i))
drv_lcd_draw_rect(x + width - i , 1, y + j, 1, 0xff, 0, 0xff);
}
idx++;
}
}

View File

@@ -0,0 +1,114 @@
#ifndef __LCD_INFO_H__
#define __LCD_INFO_H__
/*
* HBP : Horizontal Back Porch
* HFP : Horizontal Front Porch
* HSPW: Horizontal Sync. Pulse Width
* PPL : Pixels-per-line = 16(PPL+1)
*/
#define ENC_PARAM_TIME0(HBP, HFP, HSPW, PPL) \
((((HBP) - 1) << 24) | \
(((HFP) - 1) << 16) | \
(((HSPW) - 1) << 8 ) | \
((((PPL) >> 4) - 1) << 2 ))
/*
* HBP : Vertical Back Porch
* HFP : Vertical Front Porch
* HSPW: Vertical Sync. Pulse Width
* LPP : Lines-per-panel = LPP + 1
*/
#define ENC_PARAM_TIME1(VBP, VFP, VSPW, LPP) \
((((VBP) ) << 24) | \
(((VFP) ) << 16) | \
(((VSPW) - 1) << 10) | \
(((LPP) - 1) ))
/*
* PRA : Pixel Rate Adaptive
* IOE : Invert Panel Output Enable
* IPC : Invert Panel Clock (Test Chip Testing)
* IHS : Invert Horisontal Sync.
* IVS : Invert Versical Sync.
* PCD : Panel Clock Divisor
*/
#define ENC_PARAM_TIME2(PRA, IOE, IPC, IHS, IVS, PCD) \
(((PRA) << 15) | \
((IOE) << 14) | \
((IPC) << 13) | \
((IHS) << 12) | \
((IVS) << 11) | \
(((PCD) - 1) ))
/*
* Enable YCbCr
* Enable YCbCr422
* FIFO threadhold
* Panel type, 0-6bit, 1-8bit
* LcdVComp, when to generate interrupt, 1: start of back_porch
* Power Enable
* Big Endian Pixel/Byte Ordering
* BGR
* TFT
* LCD bits per pixel
* Controller Enable
*/
#define ENC_PARAM_CTRL(ENYUV, ENYUV422, FIFOTH, PTYPE, VCOMP, LCD_ON, ENDIAN, BGR, TFT, BPP, LCD_EN) \
((ENYUV << 18) | \
(ENYUV422 << 17) | \
(FIFOTH << 16) | \
(PTYPE << 15) | \
(VCOMP << 12) | \
(LCD_ON << 11) | \
(ENDIAN << 9) | \
(BGR << 8) | \
(TFT << 5) | \
(BPP << 1) | \
(LCD_EN))
#if defined(CONFIG_COLOR_DEPTH16)
#define LCD_COLOR_DEPTH 0x4
#define LCD_PANEL_BPP 16
#elif defined(CONFIG_COLOR_DEPTH24)
#define LCD_COLOR_DEPTH 0x5
#define LCD_PANEL_BPP 24
#else
#define LCD_COLOR_DEPTH 0x5
#define LCD_PANEL_BPP 24
#endif
#ifdef CONFIG_PANEL_AUA036QN01
#define LCD_PANEL_WIDTH 320
#define LCD_PANEL_HEIGHT 240
#define LCD_TIME0 ENC_PARAM_TIME0(7, 6, 1, 320) /* 0x0605004c */
#define LCD_TIME1 ENC_PARAM_TIME1(1, 1, 1, 240) /* 0x010100ef */
#define LCD_TIME2 ENC_PARAM_TIME2(0, 0, 1, 1, 1, 0x7) /* 0x00003806 */
#define LCD_CTRL ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, LCD_COLOR_DEPTH, 1) /* 0x0001b928 */
#endif
#ifdef CONFIG_PANEL_AUA070VW04
#define LCD_PANEL_WIDTH 800
#define LCD_PANEL_HEIGHT 480
#define LCD_TIME0 ENC_PARAM_TIME0(88, 40, 128, 800)
#define LCD_TIME1 ENC_PARAM_TIME1(21, 1, 3, 480)
#define LCD_TIME2 ENC_PARAM_TIME2(0, 1, 1, 1, 1, 0x7)
#define LCD_CTRL ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, LCD_COLOR_DEPTH, 1)
#endif
#ifdef CONFIG_PANEL_CH7013A
#define LCD_TIME0 ENC_PARAM_TIME0(42, 10, 96, 640)
#define LCD_TIME1 ENC_PARAM_TIME1(28, 5, 2, 480)
#define LCD_TIME2 ENC_PARAM_TIME2(0, 1, 1, 0, 0, 0x3)
#define LCD_CTRL ENC_PARAM_CTRL(0, 0, 1, 0, 0x3, 1, 0x0, 1, 1, LCD_COLOR_DEPTH, 1)
#endif /* CONFIG_CH7013A */
#endif /* __LCD_INFO_H__ */

142
bsp/AE210P/driver/lcd/lcd.c Normal file
View File

@@ -0,0 +1,142 @@
#include "hal.h"
#include "lcd/lcd.h"
#include "lcd-info.h"
#ifdef CONFIG_PLAT_AG101P_16MB
#define LCD_BASE 0x00e10000
#else
#define LCD_BASE 0x90600000
#endif
#define LCD_TIME0_OFFSET 0x00
#define LCD_TIME1_OFFSET 0x04
#define LCD_TIME2_OFFSET 0x08
#define LCD_BASE_OFFSET 0x10
#define LCD_INT_EN_OFFSET 0x18
#define LCD_CTRL_OFFSET 0x1C
#define LCD_INT_CLR_OFFSET 0x20
#define LCD_INT_MSK_OFFSET 0x24
static pixel_t _drv_lcd_fb[ LCD_PANEL_WIDTH * LCD_PANEL_HEIGHT] __attribute__((aligned (64)));
static pixel_t _drv_lcd_bg[ LCD_PANEL_WIDTH * LCD_PANEL_HEIGHT] __attribute__((aligned (64)));
static pixel_t *drv_lcd_fb = _drv_lcd_fb;
static pixel_t *drv_lcd_bg = _drv_lcd_bg;
extern void nds32_dcache_flush();
void drv_lcd_flip(void)
{
pixel_t *tmp = drv_lcd_fb;
drv_lcd_fb = drv_lcd_bg;
drv_lcd_bg = tmp;
OUT32(LCD_BASE + LCD_BASE_OFFSET, drv_lcd_fb);
}
pixel_t *drv_lcd_get_fb(void)
{
return drv_lcd_fb;
}
pixel_t *drv_lcd_get_bg(void)
{
return drv_lcd_bg;
}
void drv_lcd_get_param(int *width, int *height, int *bpp)
{
if (width)
*width = LCD_PANEL_WIDTH;
if (height)
*height = LCD_PANEL_HEIGHT;
if (bpp)
*bpp = LCD_PANEL_BPP;
}
void drv_lcd_fill_bg(void)
{
pixel_t *base = drv_lcd_bg;
int i, j;
for (i = j = 0; j < LCD_PANEL_HEIGHT; j++) {
for (i = 0; i < LCD_PANEL_WIDTH; i++) {
#if defined(CONFIG_COLOR_DEPTH16)
if (i == 0 || i == (LCD_PANEL_WIDTH - 1) || j == 0 || j == (LCD_PANEL_HEIGHT - 1))
*base++ = 0xFFFFu;
else
*base++ = 0x0000u;
#elif defined(CONFIG_COLOR_DEPTH24)
if (i == 0 || i == (LCD_PANEL_WIDTH - 1) || j == 0 || j == (LCD_PANEL_HEIGHT - 1))
*base++ = 0x00FFFFFFu;
else
*base++ = 0x00000000u;
#else
#error "COLOR DEPTH not supported!"
#endif
}
}
}
void drv_lcd_draw_bg(void)
{
pixel_t *src = drv_lcd_bg;
pixel_t *dst = drv_lcd_fb;
int i = 0;
while (i++ < LCD_PANEL_WIDTH * LCD_PANEL_HEIGHT)
*dst++ = *src++;
}
static void _drv_lcd_init(void)
{
OUT32(LCD_BASE + LCD_TIME0_OFFSET, LCD_TIME0);
OUT32(LCD_BASE + LCD_TIME1_OFFSET, LCD_TIME1);
OUT32(LCD_BASE + LCD_TIME2_OFFSET, LCD_TIME2);
OUT32(LCD_BASE + LCD_CTRL_OFFSET, LCD_CTRL);
OUT32(LCD_BASE + LCD_BASE_OFFSET, drv_lcd_fb);
}
void drv_lcd_draw_rect(int x, int w, int y, int h, int r, int g, int b)
{
pixel_t *base = drv_lcd_fb;
int i, j;
for (i = y; i < y + h; i++)
for (j = x; j < x + w; j++)
#if defined(CONFIG_COLOR_DEPTH16)
base[ i * LCD_PANEL_WIDTH + j] = (pixel_t)(((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0));
#elif defined(CONFIG_COLOR_DEPTH24)
base[ i * LCD_PANEL_WIDTH + j] = (pixel_t)((r << 16) | (g << 8) | b);
#endif
nds32_dcache_flush(); /* undefine CONFIG_CPU_DCACHE_WRITETHROUGH ,flush DCACHE for lcd screen */
}
void drv_lcd_erase_rect(int x, int w, int y, int h)
{
pixel_t *base = drv_lcd_fb;
int i, j;
for (i = y; i < y + h; i++)
for (j = x; j < x + w; j++)
base[ i * LCD_PANEL_WIDTH + j] = drv_lcd_bg[ i * LCD_PANEL_WIDTH + j];
}
void draw_blk(int x, int y, int sz, int border, int r, int g, int b)
{
drv_lcd_draw_rect(x, sz, y, sz, r, g, b);
drv_lcd_draw_rect(x + border, sz - 2 * border, y + border, sz - 2 * border, r ^ 0xff, g ^ 0xff, b ^ 0xff);
}
int drv_lcd_init(void)
{
_drv_lcd_init();
drv_lcd_fill_bg();
drv_lcd_draw_bg();
drv_lcd_flip();
return 0;
}

View File

@@ -0,0 +1,29 @@
#ifndef __LCD_H__
#define __LCD_H__
#include <inttypes.h>
#include "lcd-info.h"
#if defined(CONFIG_COLOR_DEPTH16)
typedef uint16_t pixel_t;
#elif defined(CONFIG_COLOR_DEPTH24)
typedef uint32_t pixel_t;
#else
#error "Unsupported COLOR_DEPTH!"
typedef int pixel_t;
#endif
extern void drv_lcd_flip(void);
extern pixel_t *drv_lcd_get_fb(void);
extern pixel_t *drv_lcd_get_bg(void);
extern void drv_lcd_get_param(int *width, int *height, int *bpp);
extern void drv_lcd_fill_bg(void);
extern void drv_lcd_draw_bg(void);
extern void drv_lcd_draw_rect(int x, int w, int y, int h, int r, int g, int b);
extern void drv_lcd_erase_rect(int x, int w, int y, int h);
extern void draw_blk(int x, int y, int sz, int border, int r, int g, int b);
extern int drv_lcd_init(void);
extern void draw_font(int x, int y, int ascii);
#endif /* __LCD_H__ */

View File

@@ -0,0 +1,74 @@
#include "hal.h"
#include "uart/uart.h"
#include "osc.h"
#include "os_except.h"
#define osc_hisr_TASK_PRIORITY 31 // osc_hisr must be the highest priority task of all tasks.
/*
*********************************************************************************************************
* Overlay SRAM Controller (OSC) initialize
*
* Description : This function is called to initialize overlay SRAM controller,
* including setting upfixed region size and overlay region base.
*
* Arguments :
*
* Notes :
*********************************************************************************************************
*/
void _osc_init(void)
{
register unsigned int ovly_region_szie;
register unsigned int fix_regiion_size;
register unsigned int ovly_region_base_addr;
/* Read the initial OSC overlay region size. */
ovly_region_szie = (REG32(OSC_CTRL) & OSC_CTRL_OVL_SZ_MASK) >> 12;
/* Initialize OSC fix region size */
fix_regiion_size = OSC_EILM_SIZE - ovly_region_szie;
REG32(OSC_OVLFS) = fix_regiion_size;
/* Initialize OSC overlay region to the end of all overlay text. */
ovly_region_base_addr = fix_regiion_size + ovly_region_szie * _novlys;
REG32(OSC_OVLBASE) = ovly_region_base_addr;
}
int _osc_drv_init(void (*handler)(unsigned int ipc),
void (*osc_hisr)(void *arg),
OSC_DRV_INFO *osc_info)
{
hal_queue_t *queue = &osc_info->queue;
hal_thread_t *th = &osc_info->th;
// Initial the Fixed/Overlap regions.
_osc_init();
// Register a user-define handler which is called from OSC exception handler.
register_exception_handler(GE_RESERVED_INST, handler);
// Register a user-define hisr which will be woken up by lisr sending msg to queue.
th->fn = osc_hisr;
th->name = "bh_osc";
th->stack_size = 0x400;
th->arg = queue;
th->prio = osc_hisr_TASK_PRIORITY;
th->task = NULL;
th->ptos = NULL;
// Create a bottom half.
// The bottom half is a thread task with a sync queue.
queue->size = 1;
if(hal_create_queue(queue) == HAL_FAILURE)
return HAL_FAILURE;
if(hal_create_thread(th) != HAL_SUCCESS)
return HAL_FAILURE;
puts("OSC driver init success!\n");
return HAL_SUCCESS;
}

View File

@@ -0,0 +1,77 @@
#ifndef __OSC_H__
#define __OSC_H__
#include "hal.h"
#define OVLY_SEG(NAME) __attribute__((section(#NAME)))
/*
TYPES OF GENERAL EXCEPTION
*/
#define GE_ALIGN_CHECK 0
#define GE_RESERVED_INST 1
#define GE_TRAP 2
#define GE_ARITHMETIC 3
#define GE_PRECISE_BUS_ERR 4
#define GE_INPRECISE_BUS_ERR 5
#define GE_COPROCESSOR 6
#define GE_PRIVILEGE_INST 7
#define GE_RESERVED_VALUE 8
#define GE_NON_EXIST_LOCAL_MEM 9
#define GE_MPZIU_CTRL 10
/*
structure of overlay control registers
Please define this structure based on your hardware design
*/
typedef struct
{
unsigned int reserved ;
unsigned int root_size ;
unsigned int base_addr ;
unsigned int end_addr ;
volatile unsigned int dma ;
} OVLY_REGS ;
typedef struct
{
unsigned long vma;
unsigned long size;
unsigned long lma;
unsigned long mapped;
} OVLY_TABLE ;
typedef struct
{
unsigned int ipc;
OVLY_REGS *povl;
} OVL_CTRL;
typedef struct {
hal_queue_t queue;
hal_thread_t th;
OVL_CTRL povl_ctrl;
} OSC_DRV_INFO;
/* _novlys from overlay table in linker script stands for number of overlay regions. */
extern int _novlys;
extern OVLY_TABLE _ovly_table[] ;
extern char __ovly_lmastart_OVL_RAM;
static volatile int overlay_busy = 0;
void __attribute__((no_prologue)) osc_init();
int _osc_drv_init(void (*handler)(unsigned int ipc),
void (*osc_hisr)(void *arg),
OSC_DRV_INFO *osc_info);
#ifdef CONFIG_OSC_DEBUG_SUPPORT
#define OVLY_DEBUG
#endif
#endif

View File

@@ -0,0 +1,3 @@
lib-y +=
lib-y += sdd.o
lib-y += sdd_sd.o

143
bsp/AE210P/driver/sd/sd.h Normal file
View File

@@ -0,0 +1,143 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2007-2008
* All Rights Reserved.
*
* Revision History:
*
* Aug.21.2007 Created.
****************************************************************************/
/*****************************************************************************
*
* FILE NAME VERSION
*
* sd.h
*
* DESCRIPTION
*
* SD controller driver interfaces for client applications.
* (Nucleus I/O Driver Architecture)
*
* DATA STRUCTURES
*
* None
*
* DEPENDENCIES
*
* ag101regs.h
* ag101defs.h
*
****************************************************************************/
#ifndef __SD_H__
#define __SD_H__
#include <inttypes.h>
/*
* SDD I/O control code, used for clients not using driver wrapper routines,
* i.e., when not using middle-ware interfaces. Driver implementation target
* is that almost every IOCTL should exist a corresponding wrapper routine.
*/
typedef enum SDD_IOCTL {
SDD_IOCTL_READ_SECTORS, /* Parameter: pointer to SDD_IOCTL_READ_SECTORS_PARAM struct */
SDD_IOCTL_WRITE_SECTORS, /* Parameter: pointer to SDD_IOCTL_WRITE_SECTORS_PARAM struct */
} SDD_IOCTL;
/* Parameter struct for SDD_IOCTL_ */
typedef struct _SDD_IOCTL_READ_SECTORS_PARAM {
uint32_t lba_sector; /* start sector number */
uint32_t sector_count; /* number of sectors included in this operation */
uint32_t sector_size; /* sector size in bytes */
void *io_buff; /* buffer pointer */
} SDD_IOCTL_READ_SECTORS_PARAM;
typedef struct _SDD_IOCTL_WRITE_SECTORS_PARAM {
uint32_t lba_sector; /* start sector number */
uint32_t sector_count; /* number of sectors included in this operation */
uint32_t sector_size; /* sector size in bytes */
void *io_buff; /* buffer pointer */
} SDD_IOCTL_WRITE_SECTORS_PARAM;
typedef enum SDD_EVENTS {
SDD_EVENT_CD = 0x00000001, /* Card-detection event. Event parameter: SDD_CD_EVENT */
} SDD_EVENTS;
typedef enum SDD_CD_EVENT_PARAM {
SDD_CD_CARD_INSERTED = 1,
SDD_CD_CARD_REMOVED = 0,
} SDD_CD_EVENT_PARAM;
typedef enum SDD_DMA_MODE {
SDD_DMA_NONE = 0, /* no dma, deivce i/o is through pio */
SDD_DMA_DCH = 1, /* dma channel is dynamically allocated on i/o request and get free after dma. */
SDD_DMA_SCH = 2, /* dma channel is allocated and occupied during device initialization. */
} SDD_DMA_MODE;
/* Define data structures for management of CF device. */
typedef struct SDD_DEVICE_STRUCT {
void *bdev_id; /* (reserved) The block device context. This field is reserved by the driver. */
uint8_t dma; /* (in) one of the enum value in SDD_DMA_MODE. */
uint8_t func; /* (in) (Reserved currently) Preferred SD card function mode (SD Memory, SD/IO, SPI) */
uint8_t padding[2]; /* stuff bytes */
} SDD_DEVICE;
/*****************************************************************************
* Note: Everything below is designed as an interface wrapper to access
* SD driver.
*
* [Structures]
*
* [Functions]
*
*
****************************************************************************/
/* driver generic error code for SDC */
#define SDD_SUCCESS 0x00
#define SDD_INVALID_INIT 0x01
#define SDD_INVALID_REQUEST 0x02
#define SDD_NOT_SUPPORTED 0x03
#define SDD_INVALID_FUNCTION 0x11
#define SDD_INVALID_PARAMETER 0x12
#define SDD_CARD_REMOVED 0x13
#define SDD_INVALID_MEDIA 0x14
#define SDD_INVALID_IOCTL 0x15
#define SDD_WRITE_DATA_ERROR 0x16
#define SDD_READ_DATA_ERROR 0x17
#define SDD_INVLAID_ADDRESS 0x18
#define SDD_INVLAID_ADDR_RANGE 0x19
#define SDD_CMD_TIMEOUT 0x21
#define SDD_CMD_ERROR 0x22
#define SDD_RSP_TIMEOUT 0x23
#define SDD_RSP_CRC_ERROR 0x24
#define SDD_NOT_SUPPORT_ACMD 0x25
#define SDD_CSR_ERROR 0x26
#define SDD_INVALID_STATE 0x27
#define SDD_WAIT_TIMEOUT 0x28
#define SDD_WRITE_PROTECTED 0x29
#define SDD_CARD_LOCKED 0x30
extern void _sdd_lisr(int vector);
extern void _sdd_hisr(void *param);
extern uint32_t NDS_SD_Init(SDD_DEVICE * sdd_dev);
extern void NDS_SD_Unload(void);
extern uint32_t NDS_SD_ReadSectors(SDD_DEVICE * sdd_dev, uint32_t sector,
uint32_t sector_count, uint32_t sector_size,
void *buffer);
extern uint32_t NDS_SD_WriteSectors(SDD_DEVICE * sdd_dev, uint32_t sector,
uint32_t sector_count, uint32_t sector_size,
void *buffer);
#endif /* __SD_H__ */

2951
bsp/AE210P/driver/sd/sdd.c Normal file

File diff suppressed because it is too large Load Diff

219
bsp/AE210P/driver/sd/sdd.h Normal file
View File

@@ -0,0 +1,219 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2007-2008
* All Rights Reserved.
*
* Revision History:
*
* Aug.21.2007 Created.
****************************************************************************/
/*****************************************************************************
*
* FILE NAME VERSION
*
* sdd.h
*
* DESCRIPTION
*
* SD driver implementation kernel mode header file.
* (Nucleus I/O Driver Architecture)
*
* DATA STRUCTURES
*
* None
*
* DEPENDENCIES
*
* sd.h SD driver interface exported to user applications
* ag101regs.h SoC register address header file
* ag101defs.h SoC register constant definition header file
*
****************************************************************************/
#ifndef __SDD_H__
#define __SDD_H__
#include <hal.h>
#include <dma/dmad.h>
#include "sd.h"
/* configuration section */
/* Note: SD clock -- please check "ag101defs.h". */
#define SDD_SMALL_FOOTPRINT 0 /* non-zero to disable extra features for small footprint */
#define SDD_SMALL_SD_FOOTPRINT 0 /* non-zero to skip compiling and linking of unsed SD command routines. */
#define SDD_DEBUG_TRACE 0 /* non-zero to enable debug trace message */
#define SDD_VFS_SUPPORT 1 /* non-zero to enable VFS support */
/* Define sector size that should be common for all file systems. */
/* Todo: Check if this the common case. */
#define SDD_SECTOR_SIZE 512
#define SDD_POWER_OF_SECTOR_SIZE 9
#define SDD_BYTES_TO_SECTORS(b) ((uint32_t)(b) >> 9)
/* SDD enums */
typedef enum _SDD_CARD_SPEC {
SDD_SPEC_1XX, /* the card is a spec 1.x implementation */
SDD_SPEC_200 /* the card is a spec 2.0 implementation */
} SDD_CARD_SPEC;
typedef enum _SDD_CARD_CCS {
SDD_CCS_SD, /* the card is a standard capacity card */
SDD_CCS_SDHC /* the card is a high capacity card */
} SDD_CARD_CCS;
typedef enum _SDD_VDD_WINDOW {
SDD_VDD_2_7 = 0x00008000, /* VDD 2.7 ~ 2.8 */
SDD_VDD_2_8 = 0x00010000, /* VDD 2.8 ~ 2.9 */
SDD_VDD_2_9 = 0x00020000, /* VDD 2.9 ~ 3.0 */
SDD_VDD_3_0 = 0x00040000, /* VDD 3.0 ~ 3.1 */
SDD_VDD_3_1 = 0x00080000, /* VDD 3.1 ~ 3.2 */
SDD_VDD_3_2 = 0x00100000, /* VDD 3.2 ~ 3.3 */
SDD_VDD_3_3 = 0x00200000, /* VDD 3.3 ~ 3.4 */
SDD_VDD_3_4 = 0x00400000, /* VDD 3.4 ~ 3.5 */
SDD_VDD_3_5 = 0x00800000, /* VDD 3.5 ~ 3.6 */
} SDD_VDD_WINDOW;
/*
* SD card device parameters
* Note:
* 1. This struct supports a single card.
* 2. Watch out 32-bit alignment after remarking unnecessary fields.
*/
typedef struct _SDD_CARD_DESC {
/* OCR (acmd41) */
uint8_t version; /* one of the enum value of SDD_CARD_SPEC */
uint8_t card_ccs; /* one of the enum value of SDD_CARD_CCS */
uint8_t padding1[2];
uint32_t vdd_window; /* one of the mask bits defined in SDD_VDD_WINDOW */
/* CID (cmd2) */
uint8_t mfg_id; /* Manufacturer ID */
char oem_id[3]; /* OEM/Application ID (2 char + 1 null-sz) */
char prod_name[6]; /* Product name (5 char + 1 null-sz) */
char prod_rev[4]; /* Product revision (x.y + 1 null-sz) */
uint8_t padding2[2];
uint32_t prod_sn; /* Product serial number */
uint16_t mfg_year; /* Manufacturing date */
uint16_t mfg_month;
/* RCA (cmd3) */
uint32_t rca; /* [31:16] RCA, [15:0] zero. */
/*
* Driver will check this before data transfer. */
/* CSD (cmd9) */
/* Todo: This is a tedious list and most fields are only for information purpose. */
/* Remove unnecessary fields after debugging. */
uint8_t csd_ver; /* CSD version */
uint8_t padding3[3];
uint32_t async_access_time; /* data read access time 1 (TAAC, x10, unit of ns) (2.0 is fixed value) */
uint32_t read_access_clks; /* data read access time 2 (NSAC, clock cycles) (2.0 is fixed value) */
uint32_t prog_factor; /* multiplication factor of time for typical block program (2.0 is fixed value) */
uint32_t max_dataline_rate; /* max data transfer rate (unit of kbps) (2.0 is fixed value) */
uint32_t cmd_class; /* card command classes */
uint16_t max_read_block_len; /* read block length in bytes (2.0 is fixed value) */
uint8_t partial_block_read; /* non-zero if the card supports small block size (minimum to 1 bytes) (2.0 is fixed value) */
uint8_t read_block_misalign; /* capability to read accross physical blocks (2.0 is fixed value) */
uint16_t max_write_block_len; /* write block length in bytes (2.0 is fixed value) */
uint8_t partial_block_write; /* non-zero if the card supports small block size (minimum to 1 bytes) (2.0 is fixed value) */
uint8_t write_block_misalign; /* capability to write accross physical blocks (2.0 is fixed value) */
uint8_t erase_single_block; /* non-zero if able to erase single block (2.0 is fixed value) */
uint8_t erase_sector_size; /* erase unit, number of write block size (not the meaning of disk sectors) (2.0 is fixed value) */
uint8_t file_format; /* enum of SDD_FILE_FORMAT (2.0 is fixed value) */
uint8_t padding4;
uint8_t wp_group_size; /* write protect group size, number of erase sector size. (2.0 is fixed value) */
uint8_t wp_group_enable; /* zero means no group write protection possible (2.0 is fixed value) */
uint8_t wp_permanent; /* card is permanently write protected */
uint8_t wp_temp; /* card is temporarily write protected */
uint8_t copy; /* indicates if the content is original (0) or copied (1 for OTP/MTP devices) */
uint8_t dsr_imp; /* non-zero if configurable driver stage register is supported */
uint32_t c_size; /* C_SIZE */
uint32_t c_size_mult; /* C_SIZE_MULT (2.0 is obsolete) */
#if 0
uint8_t max_c_read_at_vdd_min; /* max read current at vdd min (2.0 is obsolete) */
uint8_t max_c_read_at_vdd_max; /* max read current at vdd max (2.0 is obsolete) */
uint8_t max_c_write_at_vdd_min; /* max write current at vdd min (2.0 is obsolete) */
uint8_t max_c_write_at_vdd_max; /* max write current at vdd max (2.0 is obsolete) */
#endif
/* SCR (acmd51) */
uint8_t scr_ver; /* SCR version */
uint8_t spec_ver; /* SD memory card spec version */
uint8_t erase_val; /* data status after erase (0 or 1) */
uint8_t security_ver; /* security specification version */
uint8_t bus_width; /* data bus width, 1 or 4. */
/* derived fields */
uint32_t card_capacity; /* card size, in unit of 512-bytes */
uint32_t sdc_clk_div; /* clock division value to setup SDC SDC_CLK_DIV register */
uint32_t sdc_clk_freq; /* SDC clock frequency (info only) */
uint32_t read_timeout_clks; /* read timeout value to setup SDC DATA_TIMER register (fixed 100ms for SDHC) */
uint32_t write_timeout_clks; /* write timeout value to setup SDC DATA_TIMER register (fixed 250ms for SDHC) */
} SDD_CARD_DESC;
/* HISR definitions */
#define SDD_HISR_PRIORITY 0 /* 0: highest, 2: lowest */
#define SDD_HISR_STACK_SIZE 2048 /* Please align to 32-bit */
enum SDD_HISR_AS {
SDD_HISR_AS_CD = 0x00000001, /* Card Detect */
};
/* Driver data structure, one instance per system */
typedef struct SDD_DATA_STRUCT {
uint8_t valid; /* Indicates whether the device driver is instanciated or not */
uint8_t lisr_registered; /* SD cd LISR registeration status */
uint8_t hisr_registered; /* SD cd HISR registeration status */
uint8_t dma; /* One of the enum value in SDD_DMA_MODE for SD data transfer */
SDD_CARD_DESC card_desc; /* SD card parameters obtained from various card registers. */
hal_mutex_t semaphore; /* control exclusive access to driver */
hal_semaphore_t dma_sem; /* obtain dma completion notification from DMA hisr */
/* HISR resources */
hal_bh_t hisr; /* HISR kernel object, used to perform deffered tasks of LISR */
uint32_t hisr_as; /* HISR activation state (for the single HISR to identify why activated it) */
/* DMA resources */
DMAD_CHANNEL_REQUEST_DESC dma_ch; /* DMA channel descriptor initialized before data transfer */
} SDD_DATA;
/* Driver-occupied memory pool definitions */
#define SDD_MEM_POOL_BASE_SIZE 40960 /* base pool size for driver before counting size of ? */
#define SDD_MEM_ALLOC_GRANULARITY 8
/* Debug trace mechanism */
#if (SDD_DEBUG_TRACE)
#define SDD_TRACE(x) printf x
#define SDD_STRACE(x) printf x
#else /* SDD_DEBUG_TRACE */
#define SDD_TRACE(x)
#define SDD_STRACE(x)
#endif /* SDD_DEBUG_TRACE */
#endif /* __SDD_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,927 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2007-2008
* All Rights Reserved.
*
* Revision History:
*
* Sep.26.2007 Created.
****************************************************************************/
/*****************************************************************************
*
* FILE NAME VERSION
*
* sdd_sd.h
*
* DESCRIPTION
*
* Secure digital card specification 2.0 definition.
*
* Currently only Secure Digital Memory standards are well-defined.
* Remaining spec mostly are left for future developers.
*
* DATA STRUCTURES
*
* None
*
* DEPENDENCIES
*
* None
*
****************************************************************************/
#ifndef __SDD_SD_H__
#define __SDD_SD_H__
#include <hal.h>
/*****************************************************************************
* Secure Digital Memory Card Register Definitions
*
* Summary:
* read program
* ---- -------- ---------------------------------------------- ---------------------
* OCR 32 bits CMD8_SEND_IF_COND/R7 ACMD41_SD_SEND_OP_COND/R3
* CID 128 bits CMD2_ALL_SEND_CIS/R2 CMD10_SEND_CID/R2
* CSD 128 bits CMD9_SEND_CSD/R2 CMD27_PROGRAM_CSD/R1
* SCR 64 bits ACMD51_SEND_SCR/R1
* RCA 16 bits CMD3_SEND_RELATIVE_ADDR/R6
* DSR 16 bits CMD4_SET_DSR
* CSR 32 bits CMD13_SEND_STATUS/R1
* SSR 512 bits ACMD13_SD_STATUS/R1
*
* Responses:
* R1 48 bits (cmd) (normal response reg)
* [45:40] cmd_idx [39:08] CSR [7:1] CRC
* R1b 48 bits (cmd) busy signal (dat)
* [45:40] cmd_idx [39:08] CSR [7:1] CRC
* R2 136 bits (cmd) (CID, CSD reg)
* [127:1] CID/CSD (CRC included)
* R3 48 bits (cmd) (OCR reg))
* [39:8] OCR
* R6 48 bits (cmd) (RCA reg)
* [45:40] cmd_idx (0x03 CMD3) [39:24] New published RCA [23:8] CSR 23,22,19,12-0
* R7 48 bits (cmd) (card interface condition reg)
* [45:40] cmd_idx [19:16] voltage (0x01: 2.7~3.6V) [15:8] check-echo [7:1] CRC
*
****************************************************************************/
/* General Form 32-bit Response */
typedef struct _SD_R32 {
/*
* Note: The bitfields definition was not applied due to that the
* core architecture may be switched between big-endian
* and little endian. We don't want to define two structures
* to switch between the two endain architectures. Users
* could use following macros to extract the target member.
*/
union {
uint32_t r[1];
uint8_t b[4];
};
} SD_R32;
/* General Form 128-bit Response */
typedef struct _SD_R128 {
/*
* Note: The bitfields definition was not applied due to that the
* core architecture may be switched between big-endian
* and little endian. We don't want to define two structures
* to switch between the two endain architectures. Users
* could use following macros to extract the target member.
*/
union {
uint32_t r[4];
uint8_t b[16];
};
} SD_R128;
/* R6 Response Fields (Width: 32 bits) */
#define SD_R6_GET_RCA(r32) ((uint32_t)((r32).r[0]) & 0xffff0000)
#define SD_R6_GET_CSR(r32) ((uint32_t)((r32).r[0]) & 0x0000ffff)
#define SD_R6_GET_CSR_ERR(r32) ((uint32_t)((r32).r[0]) & 0x0000e000)
/* R7 Response Fields (Width: 32 bits) */
#define SD_R7_GET_VHS(r32) (((uint32_t)((r32).r[0]) >> 8) & 0x0f)
#define SD_R7_GET_PTN(r32) ((uint32_t)((r32).r[0]) & 0xff)
/* OCR - Operation Condition Register (Width: 32 bits */
/* Readback: ACMD41_SD_SEND_OP_COND/R3 */
typedef SD_R32 SD_OCR;
#define SD_OCR_VDD_MASK 0x00ffffff /* VDD voltage window */
#define SD_OCR_VDD_SHIFT 0
#define SD_OCR_VDD_2_7 0x00008000 /* VDD 2.7 ~ 2.8 */
#define SD_OCR_VDD_2_8 0x00010000 /* VDD 2.8 ~ 2.9 */
#define SD_OCR_VDD_2_9 0x00020000 /* VDD 2.9 ~ 3.0 */
#define SD_OCR_VDD_3_0 0x00040000 /* VDD 3.0 ~ 3.1 */
#define SD_OCR_VDD_3_1 0x00080000 /* VDD 3.1 ~ 3.2 */
#define SD_OCR_VDD_3_2 0x00100000 /* VDD 3.2 ~ 3.3 */
#define SD_OCR_VDD_3_3 0x00200000 /* VDD 3.3 ~ 3.4 */
#define SD_OCR_VDD_3_4 0x00400000 /* VDD 3.4 ~ 3.5 */
#define SD_OCR_VDD_3_5 0x00800000 /* VDD 3.5 ~ 3.6 */
#define SD_OCR_VDD_2_7V_3_6V (SD_OCR_VDD_2_7 | SD_OCR_VDD_2_8 | SD_OCR_VDD_2_9 | SD_OCR_VDD_3_0 | \
SD_OCR_VDD_3_1 | SD_OCR_VDD_3_2 | SD_OCR_VDD_3_3 | SD_OCR_VDD_3_4 | SD_OCR_VDD_3_5)
#define SD_OCR_CCS_MASK 0x40000000 /* Card capacity status */
#define SD_OCR_CCS_SHIFT 30
#define SD_CCS_SD 0
#define SD_CCS_SDHC 1
#define SD_OCR_BUSY_MASK 0x80000000 /* Card power up status bit */
#define SD_OCR_BUSY_SHIFT 31
#define SD_BUSY 0
#define SD_POWERUP 1
#define SD_OCR_GET_VDD(ocr) (((uint32_t)((ocr).r[0]) & SD_OCR_VDD_MASK) >> SD_OCR_VDD_SHIFT)
#define SD_OCR_GET_CCS(ocr) (((uint32_t)((ocr).r[0]) & SD_OCR_CCS_MASK) >> SD_OCR_CCS_SHIFT)
#define SD_OCR_GET_BUSY(ocr) (((uint32_t)((ocr).r[0]) & SD_OCR_BUSY_MASK) >> SD_OCR_BUSY_SHIFT)
/* CID - Card Identification Register (Width: 128 bits) */
/* Readback: CMD10_SEND_CID/R2 */
typedef SD_R128 SD_CID;
/* Manufacture ID */
#define SD_CID_GET_MID(cid) ((uint32_t)((cid).r[3]) >> 24)
#define SD_CID_GET_MID_FROM_R3(r) ((uint32_t)(r) >> 24)
/* OEM/Application ID */
#define SD_CID_GET_OID_PTR(cid) ((uint8_t*)&((cid).b[13]))
/* Product name */
#define SD_CID_GET_PNM_PTR(cid) ((uint8_t*)&((cid).b[8]))
/* Product revision (BCD coding) */
#define SD_CID_GET_PRV(cid) ((uint32_t)((cid).r[1]) >> 24)
#define SD_CID_GET_PRV_FROM_R1(r) ((uint32_t)(r) >> 24)
/* Product serial number */
#define SD_CID_GET_PSN(cid) (((uint32_t)((cid).r[1]) << 8) | ((uint32_t)((cid).r[0]) >> 24))
#define SD_CID_GET_PSN_FROM_R0R1(r0, r1) (((uint32_t)(r1) << 8) | ((uint32_t)(r0) >> 24))
/* Manufacturing date (0x0yym, year = 2000 + yy, month = m) */
#define SD_CID_GET_MDT(cid) (((uint32_t)((cid).r[0]) >> 8) & 0x0fff)
#define SD_CID_GET_MDT_FROM_R0(r) (((uint32_t)(r) >> 8) & 0x0fff)
/* CRC7 checksum */
#define SD_CID_GET_CRC(cid) (((uint32_t)((cid).r[0]) >> 1) & 0x007f)
#define SD_CID_GET_CRC_FROM_R0(r) (((uint32_t)(r) >> 1) & 0x007f)
/*
* CSD - Card-Specific Data Register (Width: 128 bits)
* Readback: CMD9_SEND_CSD/R2
* Program : CMD27_PROGRAM_CSD/R1
*/
typedef SD_R128 SD_CSD;
/* -------------------------- */
/* CSD v1.0 definitions */
/* CRC (R/W) */
#define SD_CSD_GET_CRC(csd) (((uint32_t)((csd).r[0]) >> 1) & 0x0000007f)
#define SD_CSD_GET_CRC_FROM_R0(r) (((uint32_t)(r) >> 1) & 0x0000007f)
#define SD_CSD_SET_CRC(csd,v) ((uint32_t)((csd).r[0]) |= (((uint32_t)(v) & 0x7f) << 1))
#define SD_CSD_SET_CRC_TO_R0(r,v) ((uint32_t)(r) |= (((uint32_t)(v) & 0x7f) << 1))
/* File format (R/W1, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_FILE_FORMAT(csd) (((uint32_t)((csd).r[0]) >> 10) & 0x00000003)
#define SD_CSD_GET_FILE_FORMAT_FROM_R0(r) (((uint32_t)(r) >> 10) & 0x00000003)
#define SD_CSD_SET_FILE_FORMAT(csd,v) ((uint32_t)((csd).r[0]) |= (((uint32_t)(v) & 0x03) << 10))
#define SD_CSD_SET_FILE_FORMAT_TO_R0(r,v) ((uint32_t)(r) |= (((uint32_t)(v) & 0x03) << 10))
#define SD_FILE_FORMAT_HDD 0 /* Hard disk like file system with partition table */
#define SD_FILE_FORMAT_FLOPPY 1 /* DOS FAT (floppy like) with boot sector only (no partition table) */
#define SD_FILE_FORMAT_UNIVERSAL 2 /* Universal file format */
#define SD_FILE_FORMAT_OTHERS 3 /* Others/Unknown */
/* Temporary write protection (R/W) */
#define SD_CSD_GET_TMP_WRITE_PROTECT(csd) (((uint32_t)((csd).r[0]) >> 12) & 0x00000001)
#define SD_CSD_GET_TMP_WRITE_PROTECT_FROM_R0(r) (((uint32_t)(r) >> 12) & 0x00000001)
#define SD_CSD_SET_TMP_WRITE_PROTECT(csd,v) ((uint32_t)((csd).r[0]) |= (((uint32_t)(v) & 0x01) << 12))
#define SD_CSD_SET_TMP_WRITE_PROTECT_TO_R0(r,v) ((uint32_t)(r) |= (((uint32_t)(v) & 0x01) << 12))
/* Permanent write protection (R/W1) */
#define SD_CSD_GET_PERM_WRITE_PROTECT(csd) (((uint32_t)((csd).r[0]) >> 13) & 0x00000001)
#define SD_CSD_GET_PERM_WRITE_PROTECT_FROM_R0(r) (((uint32_t)(r) >> 13) & 0x00000001)
#define SD_CSD_SET_PERM_WRITE_PROTECT(csd,v) ((uint32_t)((csd).r[0]) |= (((uint32_t)(v) & 0x01) << 13))
#define SD_CSD_SET_PERM_WRITE_PROTECT_TO_R0(r,v) ((uint32_t)(r) |= (((uint32_t)(v) & 0x01) << 13))
/* Copy flag (R/W1) */
#define SD_CSD_GET_COPY(csd) (((uint32_t)((csd).r[0]) >> 14) & 0x00000001)
#define SD_CSD_GET_COPY_FROM_R0(r) (((uint32_t)(r) >> 14) & 0x00000001)
#define SD_CSD_SET_COPY(csd,v) ((uint32_t)((csd).r[0]) |= (((uint32_t)(v) & 0x01) << 14))
#define SD_CSD_SET_COPY_TO_R0(r,v) ((uint32_t)(r) |= (((uint32_t)(v) & 0x01) << 14))
/* File format group (R/W1, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_FILE_FORMAT_GRP(csd) (((uint32_t)((csd).r[0]) >> 15) & 0x00000001)
#define SD_CSD_GET_FILE_FORMAT_GRP_FROM_R0(r) (((uint32_t)(r) >> 15) & 0x00000001)
#define SD_CSD_SET_FILE_FORMAT_GRP(csd,v) ((uint32_t)((csd).r[0]) |= (((uint32_t)(v) & 0x01) << 15))
#define SD_CSD_SET_FILE_FORMAT_GRP_TO_R0(r,v) ((uint32_t)(r) |= (((uint32_t)(v) & 0x01) << 15))
/* Partial blocks for write allowed (R, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_WRITE_BL_PARTIAL(csd) (((uint32_t)((csd).r[0]) >> 21) & 0x00000001)
#define SD_CSD_GET_WRITE_BL_PARTIAL_FROM_R0(r) (((uint32_t)(r) >> 21) & 0x00000001)
/* Max write data block length (R, fixed to 9 in 2.0) */
#define SD_CSD_GET_WRITE_BL_LEN(csd) (((uint32_t)((csd).r[0]) >> 22) & 0x0000000f)
#define SD_CSD_GET_WRITE_BL_LEN_FROM_R0(r) (((uint32_t)(r) >> 22) & 0x0000000f)
/* Write speed factor (R, fixed to 0x02 in 2.0) */
#define SD_CSD_GET_R2W_FACTOR(csd) (((uint32_t)((csd).r[0]) >> 26) & 0x00000007)
#define SD_CSD_GET_R2W_FACTOR_FROM_R0(r) (((uint32_t)(r) >> 26) & 0x00000007)
/* Write protect group enable (R, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_WP_GRP_ENABLE(csd) ((uint32_t)((csd).r[0]) >> 31)
#define SD_CSD_GET_WP_GRP_ENABLE_FROM_R0(r) ((uint32_t)(r) >> 31)
/* Write protect group size (R, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_WP_GRP_SIZE(csd) (((uint32_t)((csd).r[1]) >> 0) & 0x0000007f)
#define SD_CSD_GET_WP_GRP_SIZE_FROM_R1(r) (((uint32_t)(r) >> 0) & 0x0000007f)
/* Erase sector size (R, fixed to 0x7f in 2.0) */
#define SD_CSD_GET_SECTOR_SIZE(csd) (((uint32_t)((csd).r[1]) >> 7) & 0x0000007f)
#define SD_CSD_GET_SECTOR_SIZE_FROM_R1(r) (((uint32_t)(r) >> 7) & 0x0000007f)
/* Erase single block enable (R, fixed to 0x01 in 2.0) */
#define SD_CSD_GET_ERASE_BLK_EN(csd) (((uint32_t)((csd).r[1]) >> 14) & 0x00000001)
#define SD_CSD_GET_ERASE_BLK_EN_FROM_R1(r) (((uint32_t)(r) >> 14) & 0x00000001)
/* Device size multiplier (R, obsolete in 2.0) */
#define SD_CSD1_GET_C_SIZE_MULT(csd) (((uint32_t)((csd).r[1]) >> 15) & 0x00000007)
#define SD_CSD1_GET_C_SIZE_MULT_FROM_R1(r) (((uint32_t)(r) >> 15) & 0x00000007)
/* Max write current at VDD max (R, obsolete in 2.0) */
#define SD_CSD1_GET_VDD_W_CURR_MAX(csd) (((uint32_t)((csd).r[1]) >> 18) & 0x00000007)
#define SD_CSD1_GET_VDD_W_CURR_MAX_FROM_R1(r) (((uint32_t)(r) >> 18) & 0x00000007)
/* Max write current at VDD min (R, obsolete in 2.0) */
#define SD_CSD1_GET_VDD_W_CURR_MIN(csd) (((uint32_t)((csd).r[1]) >> 21) & 0x00000007)
#define SD_CSD1_GET_VDD_W_CURR_MIN_FROM_R1(r) (((uint32_t)(r) >> 21) & 0x00000007)
/* Max read current at VDD max (R, obsolete in 2.0) */
#define SD_CSD1_GET_VDD_R_CURR_MAX(csd) (((uint32_t)((csd).r[1]) >> 24) & 0x00000007)
#define SD_CSD1_GET_VDD_R_CURR_MAX_FROM_R1(r) (((uint32_t)(r) >> 24) & 0x00000007)
/* Max read current at VDD min (R, obsolete in 2.0) */
#define SD_CSD1_GET_VDD_R_CURR_MIN(csd) (((uint32_t)((csd).r[1]) >> 27) & 0x00000007)
#define SD_CSD1_GET_VDD_R_CURR_MIN_FROM_R1(r) (((uint32_t)(r) >> 27) & 0x00000007)
#define SD_VDD_CURR_MIN_0P5MA 0
#define SD_VDD_CURR_MIN_1MA 1
#define SD_VDD_CURR_MIN_5MA 2
#define SD_VDD_CURR_MIN_10MA 3
#define SD_VDD_CURR_MIN_25MA 4
#define SD_VDD_CURR_MIN_35MA 5
#define SD_VDD_CURR_MIN_60MA 6
#define SD_VDD_CURR_MIN_100MA 7
#define SD_VDD_CURR_MAX_1MA 0
#define SD_VDD_CURR_MAX_5MA 1
#define SD_VDD_CURR_MAX_10MA 2
#define SD_VDD_CURR_MAX_25MA 3
#define SD_VDD_CURR_MAX_35MA 4
#define SD_VDD_CURR_MAX_45MA 5
#define SD_VDD_CURR_MAX_80MA 6
#define SD_VDD_CURR_MAX_200MA 7
/* Device size (R) */
#define SD_CSD1_GET_C_SIZE(csd) ((((uint32_t)((csd).r[2]) << 2) & 0x00000fff) | (((uint32_t)((csd).r[1]) >> 30) & 0x00000003))
#define SD_CSD1_GET_C_SIZE_FROM_R1R2(r1, r2) ((((uint32_t)(r2) << 2) & 0x00000fff) | (((uint32_t)(r1) >> 30) & 0x00000003))
/* DSR implemented (R) */
#define SD_CSD_GET_DSR_IMP(csd) (((uint32_t)((csd).r[2]) >> 12) & 0x00000001)
#define SD_CSD_GET_DSR_IMP_FROM_R2(r) (((uint32_t)(r) >> 12) & 0x00000001)
/* Read block misaligned (R, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_READ_BLK_MISALIGN(csd) (((uint32_t)((csd).r[2]) >> 13) & 0x00000001)
#define SD_CSD_GET_READ_BLK_MISALIGN_FROM_R2(r) (((uint32_t)(r) >> 13) & 0x00000001)
/* Write block misaligned (R, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_WRITE_BLK_MISALIGN(csd) (((uint32_t)((csd).r[2]) >> 14) & 0x00000001)
#define SD_CSD_GET_WRITE_BLK_MISALIGN_FROM_R2(r) (((uint32_t)(r) >> 14) & 0x00000001)
/* Partial blocks for read allowed (R, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_READ_BL_PARTIAL(csd) (((uint32_t)((csd).r[2]) >> 15) & 0x00000001)
#define SD_CSD_GET_READ_BL_PARTIAL_FROM_R2(r) (((uint32_t)(r) >> 15) & 0x00000001)
/* Max read data block length (R, fixed to 9 in 2.0) */
#define SD_CSD_GET_READ_BL_LEN(csd) (((uint32_t)((csd).r[2]) >> 16) & 0x0000000f)
#define SD_CSD_GET_READ_BL_LEN_FROM_R2(r) (((uint32_t)(r) >> 16) & 0x0000000f)
#define SD_BL_LEN_512 9 /* 2^9 */
#define SD_BL_LEN_1024 10 /* 2^10 */
#define SD_BL_LEN_2048 11 /* 2^11 */
/* Card command classes (R) */
#define SD_CSD_GET_CCC(csd) (((uint32_t)((csd).r[2]) >> 20) & 0x00000fff)
#define SD_CSD_GET_CCC_FROM_R2(r) (((uint32_t)(r) >> 20) & 0x00000fff)
#define SD_CCC_CLASS0 0
#define SD_CCC_CLASS1 1
#define SD_CCC_CLASS2 2
#define SD_CCC_CLASS3 3
#define SD_CCC_CLASS4 4
#define SD_CCC_CLASS5 5
#define SD_CCC_CLASS6 6
#define SD_CCC_CLASS7 7
#define SD_CCC_CLASS8 8
#define SD_CCC_CLASS9 9
#define SD_CCC_CLASS10 10
#define SD_CCC_CLASS11 11
/* Max data transfer rate (R, fixed to 0x32 or 0x5a in 2.0) */
#define SD_CSD_GET_TRAN_SPEED(csd) ((uint32_t)((csd).r[3]) & 0x000000ff)
#define SD_CSD_GET_TRAN_SPEED_FROM_R3(r) ((uint32_t)(r) & 0x000000ff)
#define SD_TRAN_SPEED_TU(ts) ((uint32_t)(ts) & 0x07)
#define SD_TRAN_SPEED_TV(ts) (((uint32_t)(ts) >> 3) & 0x0f)
#define SD_TS_TU_100KBPS 0
#define SD_TS_TU_1MBPS 1
#define SD_TS_TU_10MBPS 2
#define SD_TS_TU_100MBPS 3
#define SD_TS_TV_1P0 1
#define SD_TS_TV_1P2 2
#define SD_TS_TV_1P3 3
#define SD_TS_TV_1P5 4
#define SD_TS_TV_2P0 5
#define SD_TS_TV_2P5 6
#define SD_TS_TV_3P0 7
#define SD_TS_TV_3P5 8
#define SD_TS_TV_4P0 9
#define SD_TS_TV_4P5 10
#define SD_TS_TV_5P0 11
#define SD_TS_TV_5P5 12
#define SD_TS_TV_6P0 13
#define SD_TS_TV_7P0 14
#define SD_TS_TV_8P0 15
/* Data read access-time-2 in CLK cycles (NSAC * 100) (R, fixed to 0x00 in 2.0) */
#define SD_CSD_GET_NSAC(csd) (((uint32_t)((csd).r[3]) >> 8) & 0x000000ff)
#define SD_CSD_GET_NSAC_FROM_R3(r) (((uint32_t)(r) >> 8) & 0x000000ff)
/* Data read access-time-1 (R, fixed to 0x0e in 2.0) */
#define SD_CSD_GET_TAAC(csd) (((uint32_t)((csd).r[3]) >> 16) & 0x0000ffff)
#define SD_CSD_GET_TAAC_FROM_R3(r) (((uint32_t)(r) >> 16) & 0x0000ffff)
#define SD_TAAC_TU(ac) ((uint32_t)(ac) & 0x07)
#define SD_TAAC_TV(ac) (((uint32_t)(ac) >> 3) & 0x0f)
#define SD_TAAC_TU_1NS 0
#define SD_TAAC_TU_10NS 1
#define SD_TAAC_TU_100NS 2
#define SD_TAAC_TU_1US 3
#define SD_TAAC_TU_10US 4
#define SD_TAAC_TU_100US 5
#define SD_TAAC_TU_1MS 6
#define SD_TAAC_TU_10MS 7
#define SD_TAAC_TV_1P0 1
#define SD_TAAC_TV_1P2 2
#define SD_TAAC_TV_1P3 3
#define SD_TAAC_TV_1P5 4
#define SD_TAAC_TV_2P0 5
#define SD_TAAC_TV_2P5 6
#define SD_TAAC_TV_3P0 7
#define SD_TAAC_TV_3P5 8
#define SD_TAAC_TV_4P0 9
#define SD_TAAC_TV_4P5 10
#define SD_TAAC_TV_5P0 11
#define SD_TAAC_TV_5P5 12
#define SD_TAAC_TV_6P0 13
#define SD_TAAC_TV_7P0 14
#define SD_TAAC_TV_8P0 15
/* CSD structure (R) */
#define SD_CSD_GET_CSD_STRUCTURE(csd) ((uint32_t)((csd).r[3]) >> 30)
#define SD_CSD_GET_CSD_STRUCTURE_FROM_R3(r) ((uint32_t)(r) >> 30)
/* Get user data size (card memory capacity, not include security protected area) */
#if 0
#define SD_CSD1_GET_CAPACITY(csd) (SD_CSD1_GET_C_SIZE(csd) + 1) * \
(1 << (SD_CSD1_GET_C_SIZE_MULT(csd) + 2)) * \
(1 << SD_CSD_GET_READ_BL_LEN(csd))
#define SD_CSD1_GET_CAPACITY_R1R2(r1,r2) (SD_CSD1_GET_C_SIZE_FROM_R1R2(r1,r2) + 1) * \
(1 << (SD_CSD1_GET_C_SIZE_MULT_FROM_R1(r1) + 2)) * \
(1 << SD_CSD_GET_READ_BL_LEN_FROM_R2(r2))
#endif
/* -------------------------- */
/* CSD v2.0 definitions */
/* */
/* Device size (R) */
#define SD_CSD2_GET_C_SIZE(csd) ((((uint32_t)((csd).r[2]) << 16) & 0x003f0000) | ((uint32_t)((csd).r[1]) >> 16))
#define SD_CSD2_GET_C_SIZE_FROM_R1R2(r1,r2) ((((uint32_t)(r2) << 16) & 0x003f0000) | ((uint32_t)(r1) >> 16))
/* Get user data size (card memory capacity, not include security protected area) */
// #define SD_CSD2_GET_CAPACITY_KB(csd) ((SD_CSD2_GET_C_SIZE(csd) + 1) * 512)
// #define SD_CSD2_GET_CAPACITY_KB_R1R2(r1,r2) ((SD_CSD2_GET_C_SIZE_FROM_R1R2(csd) + 1) * 512)
/*
* SCR - SD Card Configuration Register
* Width: 64 bits
* Readback: ACMD51_SEND_SCR/R1
*/
typedef struct _SD_SCR {
/* Note: The bitfields definition was not applied due to that the */
/* core architecture may be switched between big-endian */
/* and little endian. We don't want to define two structures */
/* to switch between the two endain architectures. Users */
/* could use following macros to extract the target member. */
union {
uint32_t r[2];
uint8_t b[8];
};
} SD_SCR;
/* DAT bus widths supported */
#define SD_SCR_GET_SD_BUS_WIDTHS(scr) (((uint32_t)((scr).r[1]) >> 16) & 0x0000000f)
#define SD_SCR_GET_SD_BUS_WIDTHS_FROM_R1(r) (((uint32_t)(r) >> 16) & 0x0000000f)
#define SD_BUS_WIDTH_1BIT 1 /* DAT0 */
#define SD_BUS_WIDTH_4BIT 4 /* DAT0 ~ DAT3 */
/* SD security support */
#define SD_SCR_GET_SD_SECURITY(scr) (((uint32_t)((scr).r[1]) >> 20) & 0x00000007)
#define SD_SCR_GET_SD_SECURITY_FROM_R1(r) (((uint32_t)(r) >> 20) & 0x00000007)
#define SD_SECURITY_NONE 0 /* no security */
#define SD_SECURITY_1_01 2 /* version 1.01 */
#define SD_SECURITY_2_0 3 /* version 2.00 */
/* Data status after erases */
#define SD_SCR_GET_DATA_STAT_AFTER_ERASE(scr) (((uint32_t)((scr).r[1]) >> 23) & 0x00000001)
#define SD_SCR_GET_DATA_STAT_AFTER_ERASE_FROM_R1(r) (((uint32_t)(r) >> 23) & 0x00000001)
/* SD memory card spec version */
#define SD_SCR_GET_SD_SPEC(scr) (((uint32_t)((scr).r[1]) >> 24) & 0x0000000f)
#define SD_SCR_GET_SD_SPEC_FROM_R1(r) (((uint32_t)(r) >> 24) & 0x0000000f)
#define SD_SPEC_1_0 0 /* version 1.0 ~ 1.01 */
#define SD_SPEC_1_1 1 /* version 1.10 */
#define SD_SPEC_2_0 2 /* version 2.00 */
/* SCR structure */
#define SD_SCR_GET_SCR_STRUCTURE(scr) (((uint32_t)((scr).r[1]) >> 28) & 0x0000000f)
#define SD_SCR_GET_SCR_STRUCTURE_FROM_R1(r) (((uint32_t)(r) >> 28) & 0x0000000f)
#define SD_SCR_VERSION_1_0 0
/*
* CSR - Card Status Register
* Width: 32 bits
* Readback: CMD13_SEND_STATUS/R1
*/
typedef SD_R32 SD_CSR;
/* Bit field defines of CSR */
#define SD_CSR_AKE_SEQ_ERROR 0x00000008 /* error in the sequence of authentication */
#define SD_CSR_APP_CMD 0x00000020 /* card expects ACMD or the command has been interpreted as ACMD */
#define SD_CSR_READY_FOR_DATA 0x00000100 /* buffer empty signaling on the bus */
#define SD_CSR_CURRENT_STATE_MASK 0x00001e00 /* the state of the card when receiving the command */
#define SD_CSR_CURRENT_STATE_SHIFT 9
#define SD_CSR_ERASE_RESET 0x00002000 /* a erase sequence was cleared before execution due to out of erase sequence commands */
#define SD_CSR_CARD_ECC_DISABLE 0x00004000 /* command was executed without using internal ECC */
#define SD_CSR_WP_ERASE_SKIP 0x00008000 /* attempt to partial erase of write protected blocks */
#define SD_CSR_CSD_OVERWRITE 0x00010000 /* attempt to 1) CSD ro fields mismatch, 2) reverse copy or perm wp bits */
#define SD_CSR_ERROR 0x00080000 /* general error */
#define SD_CSR_CC_ERROR 0x00100000 /* internal card controller error */
#define SD_CSR_CARD_ECC_FAILED 0x00200000 /* card internal ECC was applied but failed to correct the data */
#define SD_CSR_ILLEGAL_COMMAND 0x00400000 /* command illegal for the card state */
#define SD_CSR_COM_CRC_ERROR 0x00800000 /* command crc check failed */
#define SD_CSR_LOCK_UNLOCK_FAILED 0x01000000 /* password error in lock/unlock command */
#define SD_CSR_CARD_IS_LOCKED 0x02000000 /* card is locked by the host */
#define SD_CSR_WP_VIOLATION 0x04000000 /* attempts to write a protected block */
#define SD_CSR_ERASE_PARAM 0x08000000 /* invlaid selection of write blocks for erase */
#define SD_CSR_ERASE_SEQ_ERROR 0x10000000 /* error in erase command sequence */
#define SD_CSR_BLOCK_LEN_ERROR 0x20000000 /* transferred block length is not allowed or transferred bytes mismatch the block length */
#define SD_CSR_ADDRESS_ERROR 0x40000000 /* misaligned address which did not match the block length */
#define SD_CSR_OUT_OF_RANGE 0x80000000 /* command argument was out of allowed range */
/* Error in the sequence of the authentication process */
#define SD_CSR_GET_AKE_SEQ_ERROR(csr) (((uint32_t)((csr).r[0]) >> 3) & 0x00000001)
#define SD_CSR_GET_AKE_SEQ_ERROR_FROM_R(r) (((uint32_t)(r) >> 3) & 0x00000001)
/* Card is now expect ACMD, or the command has been interpreted as ACMD */
#define SD_CSR_GET_APP_CMD(csr) (((uint32_t)((csr).r[0]) >> 5) & 0x00000001)
#define SD_CSR_GET_APP_CMD_FROM_R(r) (((uint32_t)(r) >> 5) & 0x00000001)
/* Corresponds to buffer empty signaling on the bus */
#define SD_CSR_GET_READY_FOR_DATA(csr) (((uint32_t)((csr).r[0]) >> 8) & 0x00000001)
#define SD_CSR_GET_READY_FOR_DATA_FROM_R(r) (((uint32_t)(r) >> 8) & 0x00000001)
/*
* The state of the card when receiving the the command
* (visible in the response of the next command)
*/
#define SD_CSR_GET_CURRENT_STATE(csr) (((uint32_t)((csr).r[0]) >> 9) & 0x0000000f)
#define SD_CSR_GET_CURRENT_STATE_FROM_R(r) (((uint32_t)(r) >> 9) & 0x0000000f)
#define SD_STATE_IDLE 0
#define SD_STATE_READY 1
#define SD_STATE_IDENT 2
#define SD_STATE_STBY 3
#define SD_STATE_TRAN 4
#define SD_STATE_DATA 5
#define SD_STATE_RCV 6
#define SD_STATE_PRG 7
#define SD_STATE_DIS 8
/* An erase sequence was cleared due to out of erase sequence command */
#define SD_CSR_GET_ERASE_RESET(csr) (((uint32_t)((csr).r[0]) >> 13) & 0x00000001)
#define SD_CSR_GET_ERASE_RESET_FROM_R(r) (((uint32_t)(r) >> 13) & 0x00000001)
/* The command has been executed without using internal ECC */
#define SD_CSR_GET_CARD_ECC_DISABLED(csr) (((uint32_t)((csr).r[0]) >> 14) & 0x00000001)
#define SD_CSR_GET_CARD_ECC_DISABLED_FROM_R(r) (((uint32_t)(r) >> 14) & 0x00000001)
/* Set only when partial address erase was erased due to write protected (tmp/perm) blocks */
#define SD_CSR_GET_WP_ERASE_SKIP(csr) (((uint32_t)((csr).r[0]) >> 15) & 0x00000001)
#define SD_CSR_GET_WP_ERASE_SKIP_FROM_R(r) (((uint32_t)(r) >> 15) & 0x00000001)
/* Set when 1) read-only section of the CSD mismatch, 2) attempt to reverse copy or permanent WP bits */
#define SD_CSR_GET_CSD_OVERWRITE(csr) (((uint32_t)((csr).r[0]) >> 16) & 0x00000001)
#define SD_CSR_GET_CSD_OVERWRITE_FROM_R(r) (((uint32_t)(r) >> 16) & 0x00000001)
/* General error or unknown error */
#define SD_CSR_GET_ERROR(csr) (((uint32_t)((csr).r[0]) >> 19) & 0x00000001)
#define SD_CSR_GET_ERROR_FROM_R(r) (((uint32_t)(r) >> 19) & 0x00000001)
/* Internal card controller error */
#define SD_CSR_GET_CC_ERROR(csr) (((uint32_t)((csr).r[0]) >> 20) & 0x00000001)
#define SD_CSR_GET_CC_ERROR_FROM_R(r) (((uint32_t)(r) >> 20) & 0x00000001)
/* Card internal ECC was applied but failed to correct the data */
#define SD_CSR_GET_CARD_ECC_FAILED(csr) (((uint32_t)((csr).r[0]) >> 21) & 0x00000001)
#define SD_CSR_GET_CARD_ECC_FAILED_FROM_R(r) (((uint32_t)(r) >> 21) & 0x00000001)
/* Command not legalfor the card state */
#define SD_CSR_GET_ILLEGAL_COMMAND(csr) (((uint32_t)((csr).r[0]) >> 22) & 0x00000001)
#define SD_CSR_GET_ILLEGAL_COMMAND_FROM_R(r) (((uint32_t)(r) >> 22) & 0x00000001)
/* The CRC check of previous command failed */
#define SD_CSR_GET_COM_CRC_ERROR(csr) (((uint32_t)((csr).r[0]) >> 23) & 0x00000001)
#define SD_CSR_GET_COM_CRC_ERROR_FROM_R(r) (((uint32_t)(r) >> 23) & 0x00000001)
/* Set when a sequece or password error has been detected in lock/unlock card command */
#define SD_CSR_GET_LOCK_UNLOCK_FAILED(csr) (((uint32_t)((csr).r[0]) >> 24) & 0x00000001)
#define SD_CSR_GET_LOCK_UNLOCK_FAILED_FROM_R(r) (((uint32_t)(r) >> 24) & 0x00000001)
/* Signals that the card is locked by the host */
#define SD_CSR_GET_CARD_IS_LOCKED(csr) (((uint32_t)((csr).r[0]) >> 25) & 0x00000001)
#define SD_CSR_GET_CARD_IS_LOCKED_FROM_R(r) (((uint32_t)(r) >> 25) & 0x00000001)
/* Set when the host attempts to write protected block or tmp/perm protected card */
#define SD_CSR_GET_WP_VIOLATION(csr) (((uint32_t)((csr).r[0]) >> 26) & 0x00000001)
#define SD_CSR_GET_WP_VIOLATION_FROM_R(r) (((uint32_t)(r) >> 26) & 0x00000001)
/* An invalid selection of write-blocks for erase occured */
#define SD_CSR_GET_ERASE_PARAM(csr) (((uint32_t)((csr).r[0]) >> 27) & 0x00000001)
#define SD_CSR_GET_ERASE_PARAM_FROM_R(r) (((uint32_t)(r) >> 27) & 0x00000001)
/* An error in the sequence of erase commands occured */
#define SD_CSR_GET_ERASE_SEQ_ERROR(csr) (((uint32_t)((csr).r[0]) >> 28) & 0x00000001)
#define SD_CSR_GET_ERASE_SEQ_ERROR_FROM_R(r) (((uint32_t)(r) >> 28) & 0x00000001)
/* Transferred block length is not allowed or transferred length does not match block length */
#define SD_CSR_GET_BLOCK_LEN_ERROR(csr) (((uint32_t)((csr).r[0]) >> 29) & 0x00000001)
#define SD_CSR_GET_BLOCK_LEN_ERROR_FROM_R(r) (((uint32_t)(r) >> 29) & 0x00000001)
/* Misaligned address which did not match the block length was used in the command */
#define SD_CSR_GET_ADDRESS_ERROR(csr) (((uint32_t)((csr).r[0]) >> 30) & 0x00000001)
#define SD_CSR_GET_ADDRESS_ERROR_FROM_R(r) (((uint32_t)(r) >> 30) & 0x00000001)
/* Command argument out of range or this card */
#define SD_CSR_GET_OUT_OF_RANGE(csr) (((uint32_t)((csr).r[0]) >> 31) & 0x00000001)
#define SD_CSR_GET_OUT_OF_RANGE_FROM_R(r) (((uint32_t)(r) >> 31) & 0x00000001)
/* Check all data error bits at once */
#define SD_CSR_CHECK_ERROR_BITS(csr) ((uint32_t)((csr).r[0]) & (SD_CSR_AKE_SEQ_ERROR | SD_CSR_ERASE_RESET | \
SD_CSR_WP_ERASE_SKIP | SD_CSR_CSD_OVERWRITE | \
SD_CSR_ERROR | SD_CSR_CC_ERROR | SD_CSR_CARD_ECC_FAILED | \
/*SD_CSR_ILLEGAL_COMMAND |*/ SD_CSR_COM_CRC_ERROR | SD_CSR_LOCK_UNLOCK_FAILED | \
SD_CSR_CARD_IS_LOCKED | SD_CSR_WP_VIOLATION | SD_CSR_ERASE_PARAM | \
SD_CSR_ERASE_SEQ_ERROR | SD_CSR_BLOCK_LEN_ERROR | SD_CSR_ADDRESS_ERROR | \
SD_CSR_OUT_OF_RANGE))
/*
* SSR - SD Status Register
* Width: 512 bits
* Readback: ACMD13_SD_STATUS/DAT0
*/
#if 0
typedef struct _SD_SSR {
/*
* Note: The bitfields definition was not applied due to that the
* core architecture may be switched between big-endian
* and little endian. We don't want to define two structures
* to switch between the two endain architectures. Users
* could use following macros to extract the target member.
*/
union {
uint32_t r[16];
uint8_t b[64];
};
} SD_SSR;
#endif
/* Fixed offset value added to erase time */
#define SD_SSR_GET_ERASE_OFFSET(ssr) (((uint32_t)((csr).b[50]) >> 0) & 0x00000003)
/* Timeout value for erasing areas specified by UINT_OF_ERASE_AU */
#define SD_SSR_GET_ERASE_TIMEOUT(ssr) (((uint32_t)((csr).b[50]) >> 2) & 0x0000003f)
/* Number of AUs to be erased at a time */
#define SD_SSR_GET_ERASE_SIZE(ssr) (((uint32_t)((csr).b[52]) << 8) | (uint32_t)((csr).b[51]))
/* Size of AU */
#define SD_SSR_GET_AU_SIZE(ssr) ((uint32_t)((csr).b[53]) >> 4)
#define SD_AU_SIZE_NONE 0x00
#define SD_AU_SIZE_16KB 0x01
#define SD_AU_SIZE_32KB 0x02
#define SD_AU_SIZE_64KB 0x03
#define SD_AU_SIZE_128KB 0x04
#define SD_AU_SIZE_256KB 0x05
#define SD_AU_SIZE_512KB 0x06
#define SD_AU_SIZE_1MB 0x07
#define SD_AU_SIZE_2MB 0x08
#define SD_AU_SIZE_4MB 0x09
/* Performance of move indicated by 1 MB/s step */
#define SD_SSR_GET_PERFORMANCE_MOVE(ssr) ((uint32_t)((csr).b[54]))
/* Speed class of the card */
#define SD_SSR_GET_SPEED_CLASS(ssr) ((uint32_t)((csr).b[55]))
#define SD_SPEED_CLASS_0 0x00
#define SD_SPEED_CLASS_2 0x01
#define SD_SPEED_CLASS_4 0x02
#define SD_SPEED_CLASS_6 0x03
/* Size of protected area */
#define SD_SSR_GET_SIZE_OF_PROTECTED_AREA(ssr) ((uint32_t)((csr).r[14]))
/* SD memory card type */
#define SD_SSR_GET_SD_CARD_TYPE(ssr) (((uint32_t)((csr).r[15]) >> 0) & 0x0000ffff)
#define SD_CARD_TYPE_REGULAR 0x0000
#define SD_CARD_TYPE_ROM 0x0001
/* Card in secured mode operation */
#define SD_SSR_GET_SECURED_MODE(ssr) (((uint32_t)((csr).b[63]) >> 5) & 0x00000001)
/* Shows the current defined data bus width defined by ACMD6_SET_BUS_WIDTH */
#define SD_SSR_GET_DAT_BUS_WIDTH(ssr) (((uint32_t)((csr).b[63]) >> 6) & 0x00000003)
/*****************************************************************************
* Secure Digital Memory Card Command Definitions
*
****************************************************************************/
/*
* Class 0 - Basic Commands
* Responses:
* R1-R3, R6
* Registers:
* CID, CSD, DSR
*/
#define SD_CMD0_GO_IDLE_STATE 0 /* Resets all cards to idle state */
#define SD_CMD2_ALL_SEND_CID 2 /* Ask any card to send the CID numbers */
#define SD_CMD3_SEND_RELATIVE_ADDR 3 /* Ask the card to publish a new relative address */
#define SD_CMD4_SET_DSR 4 /* Programs the DSR of of all cards */
#define SD_CMD7_SELECT_DESELECT_CARD 7 /* Selected (its own relative address), deselected (other address) */
#define SD_CMD8_SEND_IF_COND 8 /* Sends SD Memory Card interface condition */
#define SD_CMD8_MAKE_ARG(vhs, ptn) ((((uint32_t)(vhs) & 0x0f) << 8) | ((uint32_t)(ptn) & 0xff))
#define SD_VHS_2_7V_3_6V 0x01
#define SD_VHS_LOW_VOLTAGE 0x02
#define SD_CMD8_DEFAULT_PTN 0xaa /* spec 20 suggested test pattern */
#define SD_CMD9_SEND_CSD 9 /* Addressed card sends its card-specific data (CSD) on the cmd line */
#define SD_CMD10_SEND_CID 10 /* Addressed card send its card-identification (CID) on the cmd line */
#define SD_CMD12_STOP_TRANSMISSION 12 /* Forces the card to stop transmission */
#define SD_CMD13_SEND_STATUS 13 /* Addressed card sends its status register */
#define SD_CMD15_GO_INACTIVE_STATE 15 /* Sends an addressed card into the inactive state */
/*
* Class 2 - Block-Oriented Read Commands
* Responses:
* R1
*/
#define SD_CMD16_SET_BLOCKLEN 16 /* Sets the block length for all following block commands (std cap.: read/write/lock, high cap.: lock) */
#define SD_CMD17_READ_SINGLE_BLOCK 17 /* Reads a block of size (std: SET_BLOCKLEN, high: 512) */
#define SD_CMD18_READ_MULTIPLE_BLOCK 18 /* Continuously transfers data from card to host until interrupted by a STOP_TRANSMISSION command */
/*
* Class 4 - Block-Oriented Write Commands
* Responses:
* R1
* Registers:
* CSD
*/
#define SD_CMD24_WRITE_BLOCK 24 /* Writes a block of the size (srd: SET_BLOCKLEN, high: 512) */
#define SD_CMD25_WRITE_MULTIPLE_BLOCK 25 /* Continuously writes block of data until interrupted by a STOP_TRANSMISSION command */
#define SD_CMD27_PROGRAM_CSD 27 /* Programming of the programmable bits of the CSD */
/*
* Class 6 - Block-Oriented Write Protection Commands
* Responses:
* R1
*/
#define SD_CMD28_SET_WRITE_PROT 28 /* Std: Sets the write protection bit of the addressed group, high: not supported */
#define SD_CMD29_CLR_WRITE_PROT 29 /* Std: clears the write protection bit of the addressed group, high: not supported */
#define SD_CMD30_SEND_WRITE_PROT 30 /* Std: ask the card to send the status of the write protection bits, high: not supported */
/*
* Class 5 - Erase Commands
* Responses:
* R1
*/
#define SD_CMD32_ERASE_WR_BLK_START 32 /* Sets the address of the first write block to be erased */
#define SD_CMD33_ERASE_WR_BLK_END 33 /* Sets the address of the last write block of the continuous range to be erased */
#define SD_CMD38_ERASE 38 /* Erase all previously selected write blocks */
/*
* Class 7 - Lock Card Commands
* Responses:
* R1
*/
#define SD_CMD42_LOCK_UNLOCK 42 /* To set/reset the password or lock/unlock the card (SET_BLOCKLEN) */
/*
* Class 8 - Application Specific Commands
* Responses:
* R1
* Registers:
* SCR
*/
#define SD_CMD55_APP_CMD 55 /* Indicates to the card that the next command is an application specific command */
#define SD_CMD56_GEN_CMD 56 /* Used to transfer/get a data block to/from the card for general purpose/application specific commands (SET_BLOCKLEN) */
#define SD_ACMD6_SET_BUS_WIDTH 6 /* Defines the data bus width to be used for data thransfer (allowed: SCR) */
#define SD_BUS_WIDTH_ARG_1BIT 0
#define SD_BUS_WIDTH_ARG_4BIT 2
#define SD_ACMD6_MAKE_ARG(bw) ((uint32_t)(bw) & 0x00000003)
#define SD_ACMD13_SD_STATUS 13 /* Send the SD status (table 4-37) */
#define SD_ACMD22_SEND_NUM_WR_BLOCKS 22 /* Send the number of the written write blocks */
#define SD_ACMD23_SET_WR_BLK_ERASE_COUNT 23 /* Set the number of write blocks to be preerased before writing */
#define SD_ACMD41_SD_SEND_OP_COND 41 /* Sends host capacity support information (HCS) and asks operating condition register (OCR) */
#define SD_ACMD41_MAKE_ARG(hcs) ((((uint32_t)(hcs) << SD_OCR_CCS_SHIFT) & SD_OCR_CCS_MASK) | SD_OCR_VDD_2_7V_3_6V)
#define SD_HCS_SD 0 /* (Host Capacity Support) Denotes not supporting SDHC */
#define SD_HCS_SDHC 1 /* (Host Capacity Support) Denotes SDHC support */
#define SD_ACMD42_SET_CLR_CARD_DETECT 42 /* Connect/Disconnect the 50KOhm pull-up resister on CD/DAT3 of the card */
#define SD_ACMD51_SEND_SCR 51 /* Reads the SD configuration register (SCR) */
/*
* Class 10 - Application Specific Commands
* Responses:
* R1
*/
#define SD_CMD6_SWITCH_FUNC 6 /* Checks switchable function (mode 0) and switch card function (mode 1) */
/*****************************************************************************
* SD Internal Programming Interfaces
*
****************************************************************************/
/* PIO SD command retry counts */
#define SD_CMD_MAX_RETRY_COUNT 0x10000
#define SD_ACMD41_MAX_RETRY_COUNT 0x100
#define SD_READ_MAX_RETRY_COUNT 0x1000
#define SD_WRITE_MAX_RETRY_COUNT 0x2000
#define SD_STATE_MAX_RETRY_COUNT 0x1000
#define SD_TRANSFER_MAX_RETRY_COUNT 0x1000
/* SD command predefined to be sent to the SDC */
/* Class 0 - Basic Commands */
#define SDC_CMD0_GO_IDLE_STATE \
((SD_CMD0_GO_IDLE_STATE & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK)
#define SDC_CMD2_ALL_SEND_CID \
((SD_CMD2_ALL_SEND_CID & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_LONG_RSP_MASK)
#define SDC_CMD3_SEND_RELATIVE_ADDR \
((SD_CMD3_SEND_RELATIVE_ADDR & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD4_SET_DSR \
((SD_CMD4_SET_DSR & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK)
#define SDC_CMD7_SELECT_DESELECT_CARD \
((SD_CMD7_SELECT_DESELECT_CARD & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD8_SEND_IF_COND \
((SD_CMD8_SEND_IF_COND & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD9_SEND_CSD \
((SD_CMD9_SEND_CSD & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_LONG_RSP_MASK)
#define SDC_CMD10_SEND_CID \
((SD_CMD10_SEND_CID & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_LONG_RSP_MASK)
#define SDC_CMD12_STOP_TRANSMISSION \
((SD_CMD12_STOP_TRANSMISSION & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD13_SEND_STATUS \
((SD_CMD13_SEND_STATUS & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD15_GO_INACTIVE_STATE \
((SD_CMD15_GO_INACTIVE_STATE & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK)
/* Class 2 - Block-Oriented Read Commands */
#define SDC_CMD16_SET_BLOCKLEN \
((SD_CMD16_SET_BLOCKLEN & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD17_READ_SINGLE_BLOCK \
((SD_CMD17_READ_SINGLE_BLOCK & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD18_READ_MULTIPLE_BLOCK \
((SD_CMD18_READ_MULTIPLE_BLOCK & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
/* Class 4 - Block-Oriented Write Commands */
#define SDC_CMD24_WRITE_BLOCK \
((SD_CMD24_WRITE_BLOCK & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD25_WRITE_MULTIPLE_BLOCK \
((SD_CMD25_WRITE_MULTIPLE_BLOCK & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD27_PROGRAM_CSD \
((SD_CMD27_PROGRAM_CSD & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
/* Class 6 - Block-Oriented Write Protection Commands */
#define SDC_CMD28_SET_WRITE_PROT \
((SD_CMD28_SET_WRITE_PROT & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD29_CLR_WRITE_PROT \
((SD_CMD29_CLR_WRITE_PROT & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD30_SEND_WRITE_PROT \
((SD_CMD30_SEND_WRITE_PROT & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
/* Class 5 - Erase Commands */
#define SDC_CMD32_ERASE_WR_BLK_START \
((SD_CMD32_ERASE_WR_BLK_START & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD33_ERASE_WR_BLK_END \
((SD_CMD33_ERASE_WR_BLK_END & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD38_ERASE \
((SD_CMD38_ERASE & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
/* Class 7 - Lock Card Commands */
#define SDC_CMD42_LOCK_UNLOCK \
((SD_CMD42_LOCK_UNLOCK & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
/* Class 8 - Application Specific Commands */
#define SDC_CMD55_APP_CMD \
((SD_CMD55_APP_CMD & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_CMD56_GEN_CMD \
((SD_CMD56_GEN_CMD & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
#define SDC_ACMD6_SET_BUS_WIDTH \
((SD_ACMD6_SET_BUS_WIDTH & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_APP_CMD_MASK)
#define SDC_ACMD13_SD_STATUS \
((SD_ACMD13_SD_STATUS & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_APP_CMD_MASK)
#define SDC_ACMD22_SEND_NUM_WR_BLOCKS \
((SD_ACMD22_SEND_NUM_WR_BLOCKS & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_APP_CMD_MASK)
#define SDC_ACMD23_SET_WR_BLK_ERASE_COUNT \
((SD_ACMD23_SET_WR_BLK_ERASE_COUNT & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_APP_CMD_MASK)
#define SDC_ACMD41_SD_SEND_OP_COND \
((SD_ACMD41_SD_SEND_OP_COND & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_APP_CMD_MASK)
#define SDC_ACMD42_SET_CLR_CARD_DETECT \
((SD_ACMD42_SET_CLR_CARD_DETECT & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_APP_CMD_MASK)
#define SDC_ACMD51_SEND_SCR \
((SD_ACMD51_SEND_SCR & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK | SDC_APP_CMD_MASK)
/* Class 10 - Application Specific Commands */
#define SDC_CMD6_SWITCH_FUNC \
((SD_CMD6_SWITCH_FUNC & SDC_CMD_IDX_MASK) | SDC_CMD_EN_MASK | SDC_NEED_RSP_MASK)
/* SD command interfaces */
#if (SDD_SMALL_SD_FOOTPRINT == 0)
extern uint32_t _sd_cmd0(void);
extern uint32_t _sd_cmd4(uint32_t dsr);
extern uint32_t _sd_cmd10(uint32_t rca, SD_CID * cid);
extern uint32_t _sd_cmd15(uint32_t rca);
extern uint32_t _sd_cmd17(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd24(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd27(SD_R32 * csr);
extern uint32_t _sd_cmd28(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd29(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd30(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd32(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd33(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd38(SD_R32 * csr);
extern uint32_t _sd_cmd42(SD_R32 * csr);
extern uint32_t _sd_cmd56(uint32_t rdwr, SD_R32 * csr);
extern uint32_t _sd_acmd22(SD_R32 * csr);
extern uint32_t _sd_acmd23(uint32_t blocks, SD_R32 * csr);
extern uint32_t _sd_acmd42(uint32_t conn, SD_R32 * csr);
extern uint32_t _sd_cmd6(uint32_t mode, SD_R32 * csr);
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
extern uint32_t _sd_cmd2(SD_CID * cid);
extern uint32_t _sd_cmd3(SD_R32 * rca);
extern uint32_t _sd_cmd7(uint32_t rca, SD_R32 * csr);
extern uint32_t _sd_cmd8(uint32_t vhs_arg, SD_R32 * vhs_rsp);
extern uint32_t _sd_cmd9(uint32_t rca, SD_CSD * csd);
extern uint32_t _sd_cmd12(SD_R32 * csr);
extern uint32_t _sd_cmd13(uint32_t rca, SD_R32 * csr);
extern uint32_t _sd_cmd16(uint32_t blk_len, SD_R32 * csr);
extern uint32_t _sd_cmd18(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd25(uint32_t addr, SD_R32 * csr);
extern uint32_t _sd_cmd55(uint32_t rca, SD_R32 * csr);
extern uint32_t _sd_acmd6(uint32_t bw, SD_R32 * csr);
extern uint32_t _sd_acmd13(SD_R32 * csr);
extern uint32_t _sd_acmd41(uint32_t hcs, SD_OCR * ocr);
extern uint32_t _sd_acmd51(SD_R32 * csr);
/* Data transfer mode state transition routines */
// extern uint32_t _sd_wait_sending_state(uint32_t rca);
// extern uint32_t _sd_wait_receiving_state(uint32_t rca);
extern uint32_t _sd_wait_programmed(uint32_t rca);
extern uint32_t _sd_wait_transferred(uint32_t rca);
extern uint32_t _sd_disconnect(uint32_t rca);
extern uint32_t _sd_connect(uint32_t rca);
extern uint32_t _sd_deselect_card(uint32_t rca);
extern uint32_t _sd_select_card(uint32_t rca);
extern uint32_t _sd_stop_transmission(uint32_t rca);
#endif /* __SDD_SD_H__ */

View File

@@ -0,0 +1 @@
lib-${CONFIG_FTSSP010} := sspd_ac97.o sspd_rts.o

View File

@@ -0,0 +1,300 @@
#include "hal.h"
#include "dma/dmad.h"
#include "sspd_ac97.h"
/* SSP FIFO properties */
#define SSPD_HW_TXFIFO_DEPTH 16 /* TX FIFO size, units of 32bit (todo: HW readback?) */
#define SSPD_HW_RXFIFO_DEPTH 16 /* RX FIFO size, units of 32bit (todo: HW readback?) */
/*****************************************************************************
* Data size for each each DMA request
*
* Adjust hint:
*
* AC97DMA_REQ_FRAMES sampling_rate effective data_size(2ch) data_size(6ch)
* ------------------------------------------------------------------------------
* 4096 48k (ac97-fix) 85.33 ms 32768 bytes 98304 bytes
* 8192 48k (ac97-fix) 170.66 ms 65536 bytes 196608 bytes
* 10240 48k (ac97-fix) 213.33 ms 81920 bytes 245760 bytes
* 12288 48k (ac97-fix) 256.00 ms 98304 bytes 294912 bytes
* 20480 48k (ac97-fix) 426.66 ms 163840 bytes 491520 bytes
****************************************************************************/
#define AC97DMA_REQ_FRAMES (20480) /* number of frames */
#define AC97_RESET_WAIT (0x600000) /* polling loop counter for waiting hw-reset */
enum SSPD_AC97_RESET {
SSPD_AC97_COLDRESET, /* All AC97 logic is initialized to its default state */
SSPD_AC97_WARMRESET, /* Contents of AC97 registers are left unaltered */
SSPD_AC97_REGRESET, /* Only Initialize the AC97 registers to their default states */
};
void sspd_ac97_sdata_out(uint32_t *txb, int cnt)
{
while (cnt > 0) {
uint32_t tfve;
/* Check room in TX FIFO */
tfve = MASK32(I2SAC97_SR, SSPC_SR_TFVE_MASK) >> SSPC_SR_TFVE_SHIFT;
/* Burst send to TX FIFO */
while (tfve++ < SSPD_HW_TXFIFO_DEPTH) {
/* Send one 32-bit word to TX FIFO */
OUT32(I2SAC97_DR, *txb++);
if (--cnt == 0)
break;
}
}
}
void sspd_ac97_cmd_out(int regidx, uint32_t data)
{
uint32_t txb[16];
/* Prepare AC97 write register address (slot1) and data (slot2) */
AC97_MAKE_WCMD(txb, regidx, data);
/* Clear SSP FIFO garbage */
SETR32(I2SAC97_CR2, SSPC_C2_RXFCLR_MASK | SSPC_C2_TXFCLR_MASK);
/* Set frame-tag slot-valid bits */
OUT32(I2SAC97_ACLINK, SSPC_AC97_WCMD_SLOTS_MASK | SSPC_AC97_MAKE_CODECID(0));
/* Feed data to TX FIFO -- AC97 CR-write contains 2 slots */
/*
* [??] According to AC97 2.1 spec, stuff bits with 0 has to be at their
* position during the slot's active time. SSP will smart enough to
* identify giving valid slots and auto stuffs 0s to empty slots in TX
* mode? And whot about the same question in RX mode?
*/
sspd_ac97_sdata_out(txb, SSPC_AC97_WCMD_SLOTS);
/* Enable SSP TX data out */
SETR32(I2SAC97_CR2, SSPC_C2_TXDOE_MASK | SSPC_C2_SSPEN_MASK);
while (MASK32(I2SAC97_SR, SSPC_SR_TFVE_MASK))
;
/* Disable SSP TX data out */
CLRR32(I2SAC97_CR2, SSPC_C2_TXDOE_MASK | SSPC_C2_SSPEN_MASK);
}
void sspd_ac97_reset(enum SSPD_AC97_RESET rest_type)
{
uint32_t core_intl;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
/* Disable SSP interrupts */
CLRR32(I2SAC97_INTCR, SSPC_INTCR_RFORIEN_MASK | SSPC_INTCR_TFURIEN_MASK |
SSPC_INTCR_RFTHIEN_MASK | SSPC_INTCR_TFTHIEN_MASK |
SSPC_INTCR_RFDMAEN_MASK | SSPC_INTCR_TFDMAEN_MASK |
SSPC_INTCR_AC97FCEN_MASK);
/* Disable SSP data out */
CLRR32(I2SAC97_CR2, SSPC_C2_SSPEN_MASK | SSPC_C2_TXDOE_MASK);
/* Disable DMA request FIFO trigger */
CLRR32(I2SAC97_INTCR, SSPC_INTCR_TFDMAEN_MASK | SSPC_INTCR_RFDMAEN_MASK);
/* Clear FIFO garbage */
SETR32(I2SAC97_CR2, SSPC_C2_RXFCLR_MASK | SSPC_C2_TXFCLR_MASK);
/* Set SSP frame format as AC97 */
SETR32SHL(I2SAC97_CR0, SSPC_C0_FFMT_MASK, SSPC_C0_FFMT_SHIFT, SSPC_INTEL_ACLINK);
switch (rest_type) {
case SSPD_AC97_COLDRESET: /* All AC97 logic is initialized to its default state */
/* (reset time: SSPCLK * SCLK_DIV) */
DEBUG(1, 1, "SSPD_AC97_COLDRESET\n");
SETB32(I2SAC97_CR2, SSPC_C2_ACCRST_BIT);
while (GETB32(I2SAC97_CR2, SSPC_C2_ACCRST_BIT))
;
_nds_kwait(AC97_RESET_WAIT);
break;
case SSPD_AC97_WARMRESET: /* Contents of AC97 registers are left unaltered */
/* (reset time: SSPCLK * SCLK_DIV, or wait ACWRST cleared) */
DEBUG(1, 1, "SSPD_AC97_WARMRESET\n");
SETB32(I2SAC97_CR2, SSPC_C2_ACWRST_BIT);
while (GETB32(I2SAC97_CR2, SSPC_C2_ACWRST_BIT))
;
break;
case SSPD_AC97_REGRESET: /* Only Initialize the AC97 registers to their default states */
DEBUG(1, 1, "SSPD_AC97_REGRESET\n");
/* Write AC97 reset register to do codec register reset */
sspd_ac97_cmd_out(AC97_CRIDX_RESET, 0);
_nds_kwait(AC97_RESET_WAIT);
break;
default:
DEBUG(1, 1, "Invalid reset method!\n");
}
hal_global_int_ctl(core_intl);
}
void sspd_ac97_init(void)
{
uint32_t core_intl;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
/*
* Change AC97 codec & SSP clock source
*
* PMU_AC97PINSEL: MFPSR[3]
* 0: X_I2Ssclkout/I2SCLK
* 1: X_ac97_resetn/50MHz in AG101
* PMU_AC97CLKSEL: MFPSR[4]
* 0: AC97CLK (Set AC97 XTL_IN source is from internal PLL. BIT_CLK is XTL_IN / 2)
* 1: GPIO22
* PMU_SSPCLKSEL: MFPSR[6]
* 0: SSPCLK
* 1: GPIO25
* PMU_AC97CLKOUTSEL: MFPSR[13]
* 0: GPIO
* 1: AC97CLK out
*/
// SETR32(PMU_MFPSR, PMU_AC97PINSEL_MASK | PMU_AC97CLKSEL_MASK | PMU_SSPCLKSEL_MASK | PMU_AC97CLKOUTSEL_MASK);
// SETR32(PMU_MFPSR, PMU_AC97PINSEL_MASK | PMU_AC97CLKOUTSEL_MASK);
// SETB32(PMU_MFPSR, PMU_AC97CLKSEL_BIT);
#if (MB_AC97_EXT_CLK)
DEBUG(1, 1, "AC97CLK: GPIO22\n");
SETR32(PMU_MFPSR, PMU_AC97PINSEL_MASK | PMU_AC97CLKSEL_MASK | PMU_AC97CLKOUTSEL_MASK);
#else /* MB_AC97_EXT_CLK */
DEBUG(1, 1, "AC97CLK: PLL\n");
SETR32(PMU_MFPSR, PMU_AC97PINSEL_MASK | PMU_AC97CLKOUTSEL_MASK);
CLRB32(PMU_MFPSR, PMU_AC97CLKSEL_BIT);
#endif /* MB_AC97_EXT_CLK */
sspd_ac97_reset(SSPD_AC97_COLDRESET);
/* Setup DMA FIFO trigger threshold */
SETR32SHL(I2SAC97_INTCR, SSPC_INTCR_TFTHOD_MASK, SSPC_INTCR_TFTHOD_SHIFT, 0);
SETR32SHL(I2SAC97_INTCR, SSPC_INTCR_RFTHOD_MASK, SSPC_INTCR_RFTHOD_SHIFT, 0);
/* SSP AC97 codec initialization */
/*
* Default master volume?
* Default mixer-in gain?
* Default record input selection?
*/
//sspd_ac97_cmd_out(AC97_CRIDX_MASTER_VOLUME, 0);
hal_global_int_ctl(core_intl);
}
void sspd_ac97_terminate(void)
{
uint32_t core_intl;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
/* Disable SSP interrupts */
CLRR32(I2SAC97_INTCR, SSPC_INTCR_RFORIEN_MASK | SSPC_INTCR_TFURIEN_MASK |
SSPC_INTCR_RFTHIEN_MASK | SSPC_INTCR_TFTHIEN_MASK |
SSPC_INTCR_RFDMAEN_MASK | SSPC_INTCR_TFDMAEN_MASK |
SSPC_INTCR_AC97FCEN_MASK);
/* Disable SSP data out */
CLRR32(I2SAC97_CR2, SSPC_C2_SSPEN_MASK | SSPC_C2_TXDOE_MASK);
/* Cold reset AC97 codec */
SETB32(I2SAC97_CR2, SSPC_C2_ACCRST_BIT);
while (GETB32(I2SAC97_CR2, SSPC_C2_ACCRST_BIT))
;
/* Clear FIFO garbage */
SETR32(I2SAC97_CR2, SSPC_C2_RXFCLR_MASK | SSPC_C2_TXFCLR_MASK);
hal_global_int_ctl(core_intl);
}
void ac97_init(void)
{
sspd_ac97_init();
sspd_ac97_cmd_out(AC97_CRIDX_RESET, 0);
_nds_kwait(AC97_RESET_WAIT);
sspd_ac97_cmd_out(AC97_CRIDX_PCMOUT_GAIN,
AC97_MIXER_GAIN(AC97_MIXER_MAX, AC97_MIXER_MAX));
sspd_ac97_cmd_out(AC97_CRIDX_MASTER_VOLUME,
AC97_STEREO_VOLUME(AC97_VOLUME_MAX - 0x30, AC97_VOLUME_MAX - 0x30));
SETR32SHL(I2SAC97_INTCR, SSPC_INTCR_TFTHOD_MASK, SSPC_INTCR_TFTHOD_SHIFT, 4);
SETR32SHL(I2SAC97_INTCR, SSPC_INTCR_RFTHOD_MASK, SSPC_INTCR_RFTHOD_SHIFT, 4);
OUT32(I2SAC97_ACLINK, SSPC_AC97_PCM_SLOTS_MASK | SSPC_AC97_MAKE_CODECID(0));
SETR32(I2SAC97_INTCR, SSPC_INTCR_TFDMAEN_MASK);
SETR32(I2SAC97_CR2, SSPC_C2_TXDOE_MASK | SSPC_C2_SSPEN_MASK);
SETR32(I2SAC97_CR2, SSPC_C2_RXFCLR_MASK | SSPC_C2_TXFCLR_MASK);
}
volatile int g_buffered_frames;
/* No use and marked by KCLin */
/*
static void psp(void *data)
{
g_buffered_frames -= *(int*)data;
free(data);
}
*/
static void rcp(void *data)
{
g_buffered_frames -= *(int*)data;
free(data);
}
extern int ring_idx;
void ac97_play(int frames, uint32_t *pcm_data, void *ac97_data)
{
DMAD_CHANNEL_REQUEST_DESC *ch_req = ac97_data;
while (frames > 0){
int f;
int *data;
DMAD_DRB *drb;
f = (frames < AC97DMA_REQ_FRAMES) ? frames : AC97DMA_REQ_FRAMES;
data = malloc(sizeof(int));
KASSERT(data);
*data = f;
_dmad_alloc_drb(ch_req, &drb);
drb->src_addr = pcm_data;
drb->dst_addr = (void *)I2SAC97_DR;
drb->req_size = (f << 1); /* units of data width (32bit for AC97) */
drb->rcp = rcp;
drb->data = data;
pcm_data += (f << 1);
g_buffered_frames += f;
// DEBUG(1, 1, "FRAME: %d,%d\n", g_buffered_frames,ring_idx);
_dmad_submit_request(ch_req, drb);
frames -= f;
}
}

View File

@@ -0,0 +1,444 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2007-2008
* All Rights Reserved.
*
* Revision History:
*
* Aug.21.2007 Created.
****************************************************************************/
/*****************************************************************************
*
* FILE NAME VERSION
*
* sspd_ac97.c
*
* DESCRIPTION
*
* AC97 codec digital serial interface protocol implementation.
* A SSP AC-link & AC97 controller driver supplement.
*
* DATA STRUCTURES
*
* None
*
* DEPENDENCIES
*
* None
*
****************************************************************************/
#ifndef __SSPD_AC97_H__
#define __SSPD_AC97_H__
/*****************************************************************************
* AC97 Audio Frame Definitions
*
****************************************************************************/
/*****************************************************************************
* Definitions for SDATA_OUT frame slots
****************************************************************************/
/* Command address port (slot1) */
#define AC97_CMDADDR_RW_MASK 0x00080000 /* AC97 read/write command */
#define AC97_CMDADDR_RW_BIT 19
#define AC97_CMD_WRITE 0
#define AC97_CMD_READ 1
#define AC97_CMDADDR_CRIDX_MASK 0x0007f000 /* AC97 control register index (even addressed) */
#define AC97_CMDADDR_CRIDX_SHIFT 12
/* Command data port (slot2) */
#define AC97_CMDDATA_MASK 0x000ffff0 /* AC97 command data (16 bits) */
#define AC97_CMDDATA_SHIFT 4
/*****************************************************************************
* Definitions for SDATA_IN frame slots
****************************************************************************/
/* Status address port (slot1) */
#define AC97_STADDR_CRIDX_MASK 0x0007f000 /* Echo of AC97 control register index */
#define AC97_STADDR_CRIDX_SHIFT 12
#define AC97_STADDR_SLOTREQ_MASK 0x00000ffc /* AC97 2.0 Appendex A SLOTREQ bit definitions */
#define AC97_STADDR_SLOTREQ_SHIFT 2
/* Command data port (slot2) */
#define AC97_STDATA_MASK 0x000ffff0
#define AC97_STDATA_SHIFT 4
/*****************************************************************************
* Definitions for PCM sampling data
****************************************************************************/
/* PCM sampling resolution */
#define AC97_PCM_SR16_MASK 0x000ffff0 /* 16-bit sampling resolution */
#define AC97_PCM_SR16_SHIFT 4
#define AC97_PCM_SR18_MASK 0x000ffffc /* 18-bit sampling resolution */
#define AC97_PCM_SR18_SHIFT 2
#define AC97_PCM_SR20_MASK 0x000fffff /* 20-bit sampling resolution */
#define AC97_PCM_SR20_SHIFT 0
/*****************************************************************************
* AC97 Control Register Definitions
****************************************************************************/
/* Reset register (index 0x00) */
#define AC97_CRIDX_RESET 0x00 /* Write any value to do register rest, */
/* read will return feature implementation id. */
/* Reset register definitions */
#define AC97_ID0_DEDICATED_MIC_MASK 0x0001 /* Dedicated mic PCM in channel */
#define AC97_ID0_DEDICATED_MIC_BIT 0
#define AC97_ID1_RESERVED_MASK 0x0002 /* Reserved (was modem line codec support) */
#define AC97_ID1_RESERVED_BIT 1
#define AC97_ID2_BASE_TREBLE_CTRL_MASK 0x0004 /* Bass and Treble control */
#define AC97_ID2_BASE_TREBLE_CTRL_BIT 2
#define AC97_ID3_SIMULATED_STEREO_MASK 0x0008 /* Simulated stereo */
#define AC97_ID3_SIMULATED_STEREO_BIT 3
#define AC97_ID4_HEADPHONE_OUT_MASK 0x0010 /* Headphone out support */
#define AC97_ID4_HEADPHONE_OUT_BIT 4
#define AC97_ID5_LAUDNESS_MASK 0x0020 /* Loudness (bass boost) support */
#define AC97_ID5_LAUDNESS_BIT 5
#define AC97_ID6_18BIT_DAC_MASK 0x0040 /* 18 bit DAC resolution */
#define AC97_ID6_18BIT_DAC_BIT 6
#define AC97_ID7_20BIT_DAC_MASK 0x0080 /* 20 bit DAC resolution */
#define AC97_ID7_20BIT_DAC_BIT 7
#define AC97_ID8_18BIT_ADC_MASK 0x0100 /* 18 bit ADC resolution */
#define AC97_ID8_18BIT_ADC_BIT 8
#define AC97_ID9_20BIT_ADC_MASK 0x0200 /* 20 bit ADC resolution */
#define AC97_ID9_20BIT_ADC_BIT 9
#define AC97_SE_MASK 0x7c /* 3D Stereo Enhancement Technique */
#define AC97_SE_SHIFT 10
#define AC97_SE_NONE 0
#define AC97_SE_PHAT 1
#define AC97_SE_CREATIVE 2
#define AC97_SE_NS3D 3
#define AC97_SE_YMERSION 4
#define AC97_SE_BBE3D 5
#define AC97_SE_CRYSTAL3D 6
#define AC97_SE_QXPANDER 7
#define AC97_SE_SPATIALIZER3D 8
#define AC97_SE_SRS3D 9
#define AC97_SE_PLATFORMTECH3D 10
#define AC97_SE_AKM3D 11
#define AC97_SE_AUREAL 12
#define AC97_SE_AZTECH3D 13
#define AC97_SE_BINAURA3D 14
#define AC97_SE_ESS 15
#define AC97_SE_VMAX 16
#define AC97_SE_NVIDEA3D 17
#define AC97_SE_INCREDIBLE 18
#define AC97_SE_TI3D 19
#define AC97_SE_VLSI3D 20
#define AC97_SE_TRITECH3D 21
#define AC97_SE_REALTECH3D 22
#define AC97_SE_SAMSUNG3D 23
#define AC97_SE_WOLFSON3D 24
#define AC97_SE_DELTA3D 25
#define AC97_SE_SIGMATEL3D 26
#define AC97_SE_ROCKWELL3D 28
/* Play master volume registers (index 0x02, 0x04, 0x06) */
#define AC97_CRIDX_MASTER_VOLUME 0x02 /* Stereo master volume register (ML, MR) */
#define AC97_CRIDX_HEADPHONE_VOLUME 0x04 /* Headphone volume register (ML, MR) */
#define AC97_CRIDX_MASTER_VOLUME_MONO 0x06 /* Mono master volume register (MM/MR) */
/* Play master volume register definitions */
#define AC97_MR_MASK 0x003f /* Right channel level (1.5dB step) */
#define AC97_MR_SHIFT 0
#define AC97_ML_MASK 0x3f00 /* Left channel level */
#define AC97_ML_SHIFT 8
#define AC97_MUTE_MASK 0x8000 /* Mute bit (able to keep original level value) */
#define AC97_MUTE_BIT 15
#define AC97_VOLUME_INCSTEP (-1) /* 1.5dB increase step */
#define AC97_VOLUME_DECSTEP (+1) /* 1.5dB decrease step */
#define AC97_VOLUME_0DB_ATTEN 0x00 /* 0 dB attenuation (max) (required) */
#define AC97_VOLUME_46P5DB_ATTEN 0x1f /* 46.5dB attenuation (required) */
#define AC97_VOLUME_94P5DB_ATTEN 0x3f /* 94.5dB attenuation (min) (optional) */
#define AC97_VOLUME_MAX 0x00 /* 0 dB attenuation (max) (required) */
#define AC97_VOLUME_MIDDLE 0x1f /* 46.5dB attenuation (required) */
#define AC97_VOLUME_MIN 0x3f /* 94.5dB attenuation (min) (optional) */
/* Master tone control register (index 0x08) */
#define AC97_CRIDX_MASTER_TONE 0x08 /* Master tone (bass & treble) control register */
/* Master tone control register definitions */
#define AC97_TREBLE_MASK 0x000f /* Tremble level (10kHz center, 1.5dB step) */
#define AC97_TREBLE_SHIFT 0
#define AC97_BASS_MASK 0x0f00 /* Base level (100Hz center, 1.5dB step) */
#define AC97_BASS_SHIFT 8
#define AC97_TONE_INCSTEP (-1) /* +1.5dB increase step */
#define AC97_TONE_DECSTEP (+1) /* -1.5dB decrease step */
#define AC97_TONE_MAX 0x00 /* +10.5dB gain */
#define AC97_TONE_CENTER 0x07 /* 0 dB gain */
#define AC97_TONE_MIN 0x0e /* -10.5dB gain */
#define AC97_TONE_BYPASS 0x0f /* Bypass */
/* PC beep register (index 0x0a) */
#define AC97_CRIDX_PCBEEP 0x0a /* PC beep input level control register */
/* PC beep register definitions */
#define AC97_PCBEEP_MASK 0x001e /* Beep level (3dB step) */
#define AC97_PCBEEP_SHIFT 1
#define AC97_PCBEEP_MUTE_MASK 0x8000 /* Mute bit (able to keep original level value) */
#define AC97_PCBEEP_MUTE_BIT 15
#define AC97_PCBEEP_INCSTEP (+1) /* 3dB increase step */
#define AC97_PCBEEP_DECSTEP (-1) /* 3dB decrease step */
#define AC97_PCBEEP_0DB 0 /* 0dB */
#define AC97_PCBEEP_45DB 15 /* 45dB */
/* Analog mixer input gain registers (index 0x0c ~ 0x18) */
#define AC97_CRIDX_PHONE_GAIN 0x0c /* Phone volume input gain control register (GR, M) */
#define AC97_CRIDX_MIC_GAIN 0x0e /* Microphone volume input gain control register (BOOST, GR, M) */
#define AC97_CRIDX_LINEIN_GAIN 0x10 /* Line in volume input gain control register (GL, GR, M) */
#define AC97_CRIDX_CD_GAIN 0x12 /* CD volume input gain control register (GL, GR, M) */
#define AC97_CRIDX_VIDEO_GAIN 0x14 /* Video volume input gain control register (GL, GR, M) */
#define AC97_CRIDX_AUX_GAIN 0x16 /* AUX volume input gain control register (GL, GR, M) */
#define AC97_CRIDX_PCMOUT_GAIN 0x18 /* PCM out from AC97 volume input gain control register (GL, GR, M) */
/*
* Phone volume input gain register definitions
* Microphone volume input gain control register definitions
* Line in volume input gain control register definitions
* CD volume input gain control register definitions
* Video volume input gain control register definitions
* AUX volume input gain control register definitions
* PCM out from AC97 volume input gain control register definitions
*/
#define AC97_MIXER_GR_MASK 0x001f /* Mixer input gain right channel (1.5dB step) */
#define AC97_MIXER_GR_SHIFT 0
#define AC97_MIXER_GN_MASK AC97_GR_MASK
#define AC97_MIXER_GN_SHIFT AC97_GR_SHIFT
#define AC97_MIXER_GL_MASK 0x1f00 /* Mixer input gain left channel (1.5dB step) */
#define AC97_MIXER_GL_SHIFT 0
#define AC97_MIXER_MUTE_MASK 0x8000 /* Mute bit (able to keep original level value) */
#define AC97_MIXER_MUTE_BIT 15
#define AC97_MIXER_INCSTEP (-1) /* 1.5dB increase step */
#define AC97_MIXER_DECSTEP (+1) /* 1.5dB decrease step */
#define AC97_MIXER_MAX 0x00 /* +12.0dB gain */
#define AC97_MIXER_CENTER 0x08 /* 0 dB gain */
#define AC97_MIXER_MIN 0x1f /* -34.5dB gain */
/* Microphone volume input gain control register specific definitions */
#define AC97_MIC_VOLUME_BOOST_MASK 0x0040 /* 20dB boost bit */
#define AC97_MIC_VOLUME_BOOST_BIT 0
/* ------------------------------------------------ */
/* Record select control register (index 0x1a) */
/* */
#define AC97_CRIDX_RECORD_SELECT 0x1a /* Record select control register */
/* Record select control register definitions */
#define AC97_RECORD_SR_MASK 0x0007 /* Record select right channel */
#define AC97_RECORD_SR_SHIFT 0
#define AC97_RECORD_SL_MASK 0x0700 /* Record select left channel */
#define AC97_RECORD_SL_SHIFT 8
#define AC97_RECORD_SELECT_MIC 0
#define AC97_RECORD_SELECT_CD 1
#define AC97_RECORD_SELECT_VIDEO 2
#define AC97_RECORD_SELECT_AUX 3
#define AC97_RECORD_SELECT_LINEIN 4
#define AC97_RECORD_SELECT_STEREOMIX 5
#define AC97_RECORD_SELECT_MONOMIX 6
#define AC97_RECORD_SELECT_PHONE 7
/* ------------------------------------------------ */
/* Record gain registers (index 0x1c, 0x1e) */
/* */
#define AC97_CRIDX_RECORD_GAIN 0x1c /* Record gain (stereo input) register (GL, GR, M) */
#define AC97_CRIDX_RECORD_GAIN_MIC 0x1e /* Record gain mic (optional ch3 mic) register (GR, M) */
/* Record gain (stereo input) register definitions */
/* Record gain mic (optional ch3 mic) register definitions */
#define AC97_RECORD_GR_MASK 0x000f /* Record gain right channel (1.5dB step) */
#define AC97_RECORD_GR_SHIFT 0
#define AC97_RECORD_GL_MASK 0x0f00 /* Record gain left channel (1.5dB step) */
#define AC97_RECORD_GL_SHIFT 8
#define AC97_RECORD_MUTE_MASK 0x8000 /* Mute bit (able to keep original level value) */
#define AC97_RECORD_MUTE_BIT 15
#define AC97_RECORD_INCSTEP (+1) /* 1.5dB increase step */
#define AC97_RECORD_DECSTEP (-1) /* 1.5dB decrease step */
#define AC97_RECORD_0DB 0x00 /* 0.0dB gain */
#define AC97_RECORD_22P5DB 0x0f /* +22.5dB gain */
/* ------------------------------------------------ */
/* General purpose register (index 0x20) */
/* */
#define AC97_CRIDX_GPR 0x20 /* General purpose register */
/* General purpose register definitions */
#define AC97_GPR_LPBK_MASK 0x0080 /* ADC/DAC loopback mode (system performance measurement) */
#define AC97_GPR_LPBK_BIT 7
#define AC97_GPR_MS_MASK 0x0100 /* Mic select (0: mic1, 1: mic2) */
#define AC97_GPR_MS_BIT 8
#define AC97_GPR_MIX_MASK 0x0200 /* Mono output select (0: mix, 1: mic) */
#define AC97_GPR_MIX_BIT 9
#define AC97_GPR_LD_MASK 0x1000 /* Loudness/bass_boost (0: off, 1: on) */
#define AC97_GPR_LD_BIT 12
#define AC97_GPR_3D_MASK 0x2000 /* 3D stereo enhancement (0: off, 1: on) */
#define AC97_GPR_3D_BIT 13
#define AC97_GPR_ST_MASK 0x4000 /* Simulated stereo enhancement (0: off, 1: on) */
#define AC97_GPR_ST_BIT 14
#define AC97_GPR_POP_MASK 0x8000 /* PCM out path & mute (0: pre 3D, 1: post 3D) */
#define AC97_GPR_POP_BIT 15
/* ------------------------------------------------ */
/* 3D control register (index 0x22) */
/* */
#define AC97_CRIDX_3D_CONTROL 0x22 /* 3D control register */
/* 3D control register definitions */
#define AC97_3D_CONTROL_DP_MASK 0x000f /* Depth */
#define AC97_3D_CONTROL_DP_SHIFT 0
#define AC97_3D_CONTROL_CR_MASK 0x0f00 /* Center */
#define AC97_3D_CONTROL_CR_SHIFT 8
/* ------------------------------------------------ */
/* Powerdown control/status register (index 0x20) */
/* */
#define AC97_CRIDX_POWER 0x26 /* Powerdown control/status register */
/* Powerdown control/status register definitions */
#define AC97_POWER_ADC_MASK 0x0001 /* ADC selction ready to transmit data */
#define AC97_POWER_ADC_BIT 0
#define AC97_POWER_DAC_MASK 0x0002 /* DAC selection ready to accept data */
#define AC97_POWER_DAC_BIT 1
#define AC97_POWER_ANL_MASK 0x0004 /* Analog mixer, etc. ready */
#define AC97_POWER_ANL_BIT 2
#define AC97_POWER_REF_MASK 0x0008 /* Vref's up to nominal level */
#define AC97_POWER_REF_BIT 3
#define AC97_POWER_PR0_MASK 0x0100 /* PCM in ADC's & input mux powerdown */
#define AC97_POWER_PR0_BIT 8
#define AC97_POWER_PR1_MASK 0x0200 /* PCM out DACs powerdown */
#define AC97_POWER_PR1_BIT 9
#define AC97_POWER_PR2_MASK 0x0400 /* Analog mixer power down (Vref still on) */
#define AC97_POWER_PR2_BIT 10
#define AC97_POWER_PR3_MASK 0x0800 /* Analog mixer power down (Vref off) */
#define AC97_POWER_PR3_BIT 11
#define AC97_POWER_PR4_MASK 0x1000 /* Digital interface (AC-link) powerdown (external clk off) */
#define AC97_POWER_PR4_BIT 12
#define AC97_POWER_PR5_MASK 0x2000 /* Internal clk disable */
#define AC97_POWER_PR5_BIT 13
#define AC97_POWER_PR6_MASK 0x4000 /* HP amp powerdown */
#define AC97_POWER_PR6_BIT 14
#define AC97_POWER_EAPD_MASK 0x8000 /* External amplifier power down */
#define AC97_POWER_EAPD_BIT 15
/* ------------------------------------------------ */
/* Vendor ID registers (index 0x20) */
/* */
#define AC97_CRIDX_VENDOR_ID1 0x7c /* Vendor ID register 1 */
#define AC97_CRIDX_VENDOR_ID2 0x7e /* Vendor ID register 2 */
/* Vendor ID 1 register definitions */
#define AC97_VENDOR_CHAR2_MASK 0x00ff /* Second ascii char of vendor id */
#define AC97_VENDOR_CHAR2_SHIFT 0
#define AC97_VENDOR_CHAR1_MASK 0xff00 /* First ascii char of vendor id */
#define AC97_VENDOR_CHAR1_SHIFT 8
/* Vendor ID 2 register definitions */
#define AC97_VENDOR_REV_MASK 0x00ff /* Vendor revision number */
#define AC97_VENDOR_REV_SHIFT 0
#define AC97_VENDOR_CHAR3_MASK 0xff00 /* Third ascii char of vendor id */
#define AC97_VENDOR_CHAR3_SHIFT 8
/*
* Todo:
* Appendix A - AC97 2.0 Variable Sample Rate Extension
* Appendix B - AC97 2.0 Modem AFE Extension
* Appendix C - AC97 2.0 Multiple Codec Extension
*/
/*****************************************************************************
* AC97 Driver-Supplement Helper Macros
****************************************************************************/
/* Make frame slot1 value to write AC97 codec register */
#define AC97_MAKE_WCMD_ADDR(idx) \
(((AC97_CMD_WRITE << AC97_CMDADDR_RW_BIT) & AC97_CMDADDR_RW_MASK) | \
(((uint32_t)(idx) << AC97_CMDADDR_CRIDX_SHIFT) & AC97_CMDADDR_CRIDX_MASK))
/* Make frame slot1 value to read AC97 codec register */
#define AC97_MAKE_RCMD_ADDR(idx) \
(((AC97_CMD_READ << AC97_CMDADDR_RW_BIT) & AC97_CMDADDR_RW_MASK) | \
(((uint32_t)(idx) << AC97_CMDADDR_CRIDX_SHIFT) & AC97_CMDADDR_CRIDX_MASK))
/* Make frame slot2 value to write AC97 codec register */
#define AC97_MAKE_CMD_DATA(data) \
(((uint32_t)(data) << AC97_CMDDATA_SHIFT) & AC97_CMDDATA_MASK)
/* Make frame slot1 and slot2 value to tx buffer for AC97 codec register write */
#define AC97_MAKE_WCMD(txb, idx, data) \
((uint32_t *)(txb))[0] = AC97_MAKE_WCMD_ADDR(idx); \
((uint32_t *)(txb))[1] = AC97_MAKE_CMD_DATA(data);
/* Make frame slot1 and slot2 value to tx buffer for AC97 codec register read */
#define AC97_MAKE_RCMD(txb, idx, data) \
((uint32_t *)(txb))[0] = AC97_MAKE_RCMD_ADDR(idx); \
/*((uint32_t *)(txb))[1] = AC97_MAKE_CMD_DATA(data); */
/*******************************************************************************
* Following helper functions imply non-20-bit msb-aligned sdata_out format
******************************************************************************/
/* Make codec stereo volume */
#define AC97_STEREO_VOLUME(l, r) \
((((uint32_t)(l) << AC97_ML_SHIFT) & AC97_ML_MASK) | \
(((uint32_t)(r) << AC97_MR_SHIFT) & AC97_MR_MASK))
/* Make codec mono volume */
#define AC97_MONO_VOLUME(m) \
((((uint32_t)(m) << AC97_MR_SHIFT) & AC97_MR_MASK))
/* Make tone (bass, treble) gain value */
#define AC97_TONE_GAIN(b, t) \
((((uint32_t)(b) << AC97_BASS_SHIFT) & AC97_BASS_MASK) | \
(((uint32_t)(t) << AC97_TREBLE_SHIFT) & AC97_TREBLE_MASK))
/* Make pc-beep gain value */
#define AC97_PCBEEP_GAIN(g) \
((((uint32_t)(g) << AC97_MIXER_GR_SHIFT) & AC97_MIXER_GR_MASK))
/* Make mixer phone gain value */
#define AC97_PHONE_GAIN(m) \
((((uint32_t)(m) << AC97_PCBEEP_SHIFT) & AC97_PCBEEP_MASK))
/* Make mixer mic gain value */
#define AC97_MIC_GAIN(b, m) \
((((uint32_t)(m) << AC97_MIXER_GR_SHIFT) & AC97_MIXER_GR_MASK) | \
(((uint32_t)(b) << AC97_MIC_VOLUME_BOOST_BIT) & AC97_MIC_VOLUME_BOOST_MASK))
/* Make mixer gain value */
#define AC97_MIXER_GAIN(l, r) \
((((uint32_t)(l) << AC97_MIXER_GL_SHIFT) & AC97_MIXER_GL_MASK) | \
(((uint32_t)(r) << AC97_MIXER_GR_SHIFT) & AC97_MIXER_GR_MASK))
/* Make record select value */
#define AC97_RECORD_SELECT(l, r) \
((((uint32_t)(l) << AC97_RECORD_SL_SHIFT) & AC97_RECORD_SL_MASK) | \
(((uint32_t)(r) << AC97_RECORD_SR_SHIFT) & AC97_RECORD_SR_MASK))
/* Make record gain value */
#define AC97_RECORD_GAIN(l, r) \
((((uint32_t)(l) << AC97_RECORD_GL_SHIFT) & AC97_RECORD_GL_MASK) | \
(((uint32_t)(r) << AC97_RECORD_GR_SHIFT) & AC97_RECORD_GR_MASK))
/* Make record mic gain value */
#define AC97_RECORD_MIC_GAIN(m) \
(((uint32_t)(m) << AC97_RECORD_GR_SHIFT) & AC97_RECORD_GR_MASK)
void ac97_init(void);
#endif /* __SSPD_AC97_H__ */

View File

@@ -0,0 +1,456 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2007-2008
* All Rights Reserved.
*
* Revision History:
*
* Mar.16.2008 Created.
****************************************************************************/
#include "hal.h"
#include "sspd_rts.h"
#include "bsp_hal.h"
#define RTS_PRESSED_Z1_MIN 0x10
#define RTS_PRESSED_Z2_MAX 0xfe0
typedef struct _SSPD_RTS_CONTEXT{
hal_bh_t hisr;
hal_semaphore_t *usr_ievent;
struct ts_data *usr_idata;
} SSPD_RTS_CONTEXT;
SSPD_RTS_CONTEXT rts_ctxt;
#define SSPD_HISR_STACK_SIZE 1024
static uint32_t sspd_rts_hisr_stack[SSPD_HISR_STACK_SIZE];
static void _sspd_rts_lisr(int vector){
int x = 0, y = 0, z1 = 0, z2 = 0, p = 0;
DEBUG(0, 1, "Enter\n");
if (vector != RTS_LISR_VECTOR)
hal_system_error(HAL_ERR_UNHANDLED_INTERRUPT);
/* Disable #PENIRQ interrupt */
uint32_t prv_msk = hal_intc_irq_mask(RTS_LISR_VECTOR);
/* Clear #PENIRQ interrupt status */
hal_intc_irq_clean(RTS_LISR_VECTOR);
/* Enable higher priority interrupt */
GIE_ENABLE();
//FIXME
#if 0
#if(NO_EXTERNAL_INT_CTL==0)
/* Disable #PENIRQ interrupt temporarily */
CLRB32(INTC_HW1_ER, RTS_LISR_VECTOR);
/* Clear #PENIRQ interrupt status */
SETB32(INTC_HW1_CLR, RTS_LISR_VECTOR);
#else
/* FIXME add clear ts interrupt */
#endif
#endif
_sspd_rts_probe(&x, &y, &z1, &z2, &p);
_sspd_rts_probe(&x, &y, &z1, &z2, &p);
_sspd_rts_probe(&x, &y, &z1, &z2, &p);
rts_ctxt.usr_idata->x = x;
rts_ctxt.usr_idata->y = y;
rts_ctxt.usr_idata->z1 = z1;
rts_ctxt.usr_idata->z2 = z2;
DEBUG(0, 1, "%4d, %4d, %4d, %4d\n", x, y, z1, z2);
if (z1 < 100) {
/* Disable GIE to prevent nested self */
GIE_DISABLE();
/*
* Clear #PENIRQ interrupt status again because _sspd_rts_probe would trigger #PENIRQ interrupt
* Please reference ADS7846 Spec.
*/
hal_intc_irq_clean(RTS_LISR_VECTOR);
/* Re-enable touch interrupt */
hal_intc_irq_unmask(prv_msk);
return;
}
hal_raise_bh(&rts_ctxt.hisr);
// TODO
// It is a walk around since interrupt priority
// we should change the hisr
hal_intc_irq_unmask(prv_msk);
hal_intc_irq_disable(RTS_LISR_VECTOR);
}
static inline void ts_hisr(void *param){
hal_bh_t *bh = param;
while (1){
DEBUG(0, 1, "before\n");
hal_pend_semaphore(&bh->sem, HAL_SUSPEND);
DEBUG(0, 1, "after\n");
hal_post_semaphore(rts_ctxt.usr_ievent);
#ifndef CONFIG_PLAT_QEMU
hal_sleep(300);
#endif
hal_intc_irq_clean(RTS_LISR_VECTOR);
HAL_INTC_IRQ_ATOMIC_ENABLE(RTS_LISR_VECTOR);
// SETB32(INTC_HW1_ER, RTS_LISR_VECTOR);
// SETB32(INTC_HW1_CLR, RTS_LISR_VECTOR);
}
}
static void _sspd_rts_set_sclk(int sclk){
int sclk_div; /* serial clock rate divisor */
if (sclk > RTS_ADS7846_DCLK_MAX){
DEBUG(1, 1, "Warning : SCLK exceed allowable range! Truncation is performed.\n");
sclk = RTS_ADS7846_DCLK_MAX;
}
/*
* sclk source:
* PLL3 (SSPCLK = PLL3/6) AG101 internal clk
* GPIO25 (SSPCLK = GPIO25) AG101 external clk
* OSCCLK (SSPCLK = OSCCLK * 6 / 6) Leopard
*
* calculate sclk_div from internal PLL3
*
* sclk_div = (SSPCLK / sclk / 2) - 1
* = ((PLL3 / 6) / sclk / 2) - 1
* = ((OSCCLK * 30 / 6) / sclk / 2) - 1
*/
/*
* setup PMU SSP clock source
*
* PMU_SSPCLKSEL: MFPSR[6]
* 0: SSPCLK
* 1: GPIO25
*
* PMU_AC97CLKOUTSEL: MFPSR[13]
* 0: GPIO
* 1: AC97CLK out
*/
/* [2008-03-20] SSP1 only works with internal clock source on AG101 and Leopard EVBs. */
#if 0 /*(MB_SSP_EXT_CLK) */
sclk_div = (24768000 / (sclk << 1)) - 1;
SSPD_TRACE(("\nSSPCLK: GPIO25\n"));
SETB32(PMU_MFPSR, PMU_SSPCLKSEL_BIT);
#else
sclk_div = (MB_OSCCLK / (2 * sclk)) - 1;
DEBUG(1, 1, "SSPCLK: PLL\n");
CLRB32(PMU_MFPSR, PMU_SSPCLKSEL_BIT);
#endif
DEBUG(1, 1, "sclk : %d, sclk_div : 0x%04x\n", sclk, sclk_div);
/*
* setup SSP SCLKDIV
* PDL : (padding data length) not used
* SDL : (serial data length) 8-1 (8 bits)
* SCLKDIV : sclk_div
*/
#ifndef CONFIG_PLAT_QEMU
OUT32(SSPC_CR1, ((7 << SSPC_C1_SDL_SHIFT) & SSPC_C1_SDL_MASK) | /* bit data length */
((sclk_div << SSPC_C1_SCLKDIV_SHIFT) & SSPC_C1_SCLKDIV_MASK)); /* sclkdiv */
#else
OUT32(SSPC_CR1, ((23 << SSPC_C1_SDL_SHIFT) & SSPC_C1_SDL_MASK) | /* bit data length */
((sclk_div << SSPC_C1_SCLKDIV_SHIFT) & SSPC_C1_SCLKDIV_MASK)); /* sclkdiv */
#endif
}
int _sspd_rts_init(struct ts_dev *ts){
int status = HAL_SUCCESS;
int core_intl;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
/* SSP controler initialization - SPI */
/* Disable all SSP interrupts, and set DMA trigger FIFO threshold to 0. */
OUT32(SSPC_INTCR, 0);
/* check ts interrupt vector*/
if (ts->penirq){
status = hal_register_isr(RTS_LISR_VECTOR, _sspd_rts_lisr, (void*)0);
if (status != HAL_SUCCESS){
DEBUG(1, 1, "Failed to register SSPD driver LISR!\n");
return status;
}
rts_ctxt.usr_ievent = ts->event_obj;
rts_ctxt.usr_idata = ts->event_data;
rts_ctxt.hisr.th.fn = ts_hisr;
rts_ctxt.hisr.th.ptos = &sspd_rts_hisr_stack[SSPD_HISR_STACK_SIZE];
rts_ctxt.hisr.th.stack_size = sizeof(sspd_rts_hisr_stack);
rts_ctxt.hisr.th.prio = CONFIG_TSD_HISR_PRIORITY;
rts_ctxt.hisr.th.name = "TS BH";
rts_ctxt.hisr.th.arg = &rts_ctxt.hisr;
status = hal_create_bh(&rts_ctxt.hisr);
if (status != HAL_SUCCESS){
DEBUG(1, 1, "Failed to create SSPD-RTS driver HISR!\n");
return status;
}
/* INTC */
/* - Disable #PENIRQ interrupt */
hal_intc_irq_disable(RTS_LISR_VECTOR);
/* - Clear #PENIRQ interrupt status */
hal_intc_irq_clean(RTS_LISR_VECTOR);
/* - Setup #PENIRQ interrupt trigger mode - edge trigger */
/* - Setup #PENIRQ interrupt trigger level - assert low */
hal_intc_irq_config(RTS_LISR_VECTOR, IRQ_EDGE_TRIGGER, IRQ_ACTIVE_LOW);
if (ts->penirq_en){
/* - Enable #PENIRQ interrupt */
hal_intc_irq_enable(RTS_LISR_VECTOR);
}
}
/* Reset SSP controller */
SETB32(SSPC_CR2, SSPC_C2_SSPRST_BIT);
/* Disable SSP data out */
CLRR32(SSPC_CR2, SSPC_C2_SSPEN_MASK | SSPC_C2_TXDOE_MASK);
/* setup sspc clock */
_sspd_rts_set_sclk(RTS_ADS7846_DCLK_DEFAULT);
_nds_kwait(RTS_RESET_WAIT);
/* Set SSP frame format to SPI */
OUT32(SSPC_CR0, ((0 << SSPC_C0_SCLKPH_BIT) & SSPC_C0_SCLKPH_MASK) | /* phase (1 not working for 16clk mode) */
((0 << SSPC_C0_SCLKPO_BIT) & SSPC_C0_SCLKPO_MASK) | /* polarity */
((SSPC_SSP_MASTER << SSPC_C0_OPM_SHIFT) & SSPC_C0_OPM_MASK) | /* operation mode */
((0 << SSPC_C0_LBM_BIT) & SSPC_C0_LBM_MASK) | /* loopback */
((SSPC_MOTO_SPI << SSPC_C0_FFMT_SHIFT) & SSPC_C0_FFMT_MASK)); /* frame format */
/* Clear FIFO garbage */
SETR32(SSPC_CR2, SSPC_C2_RXFCLR_MASK | SSPC_C2_TXFCLR_MASK);
/* Restore CPU interrupt controller to previous level */
hal_global_int_ctl(core_intl);
return status;
}
int _sspd_rts_probe(int *x, int *y, int *z1, int *z2, int *pressed){
uint32_t data[12];
int t, i;
/* Clear FIFO garbage */
SETR32(SSPC_CR2, SSPC_C2_RXFCLR_MASK | SSPC_C2_TXFCLR_MASK);
/* Enable SSP */
SETB32(SSPC_CR2, SSPC_C2_SSPEN_BIT);
/* Disable SSP data out temporarily */
CLRB32(SSPC_CR2, SSPC_C2_TXDOE_BIT);
/* [hw-limit] Wait until the ssp controller get ready */
// _nds_kwait(RTS_DIN_WAIT);
t = 0;
while (((IN32(SSPC_SR) & SSPC_SR_BUSY_MASK) != 0) && (t++ < RTS_DIN_TIMEOUT))
;
DEBUG(0, 1, "[RTS] SR : 0x%08lx\n", IN32(SSPC_SR));
/*
* ------------------------------------------------------------------------
* Timing of 16-clock-cycle per conversion
*
* power-up read y read x power down (full cycle)
* --------- --------- --------- ---------------
* dout (bytes) ctrl 0 ctrl 0 ctrl 0 ctrl 0 0 ____
* din (bytes) 0 msb lsb msb lsb msb lsb msb lsb ____
* ^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^
* don't care x1 or y1 x2 or y2 don't care
*
* x = (x1 + x2) / 2 (if averaging was expected)
* y = (y1 + y2) / 2 (if averaging was expected)
*
* Note: Watch out SSP FIFO depth (12 for AG101/Leopard)
* ------------------------------------------------------------------------
*/
/* SPI dout ... */
#ifndef CONFIG_PLAT_QEMU
/* power up */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RY);
OUT32(SSPC_DR, 0);
/* read y */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RY);
OUT32(SSPC_DR, 0);
/* read x */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RX);
OUT32(SSPC_DR, 0);
/* read z1 */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RZ1);
OUT32(SSPC_DR, 0);
/* read z2 && power down */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RZ2_PD);
OUT32(SSPC_DR, 0);
OUT32(SSPC_DR, 0);
#else
/* power up */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RY << 16);
OUT32(SSPC_DR, 0);
/* read y */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RY << 16);
OUT32(SSPC_DR, 0);
/* read x */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RX << 16);
OUT32(SSPC_DR, 0);
/* read z1 */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RZ1 << 16);
OUT32(SSPC_DR, 0);
/* read z2 && power down */
OUT32(SSPC_DR, RTS_ADS7846_CTL_RZ2_PD << 16);
OUT32(SSPC_DR, 0);
OUT32(SSPC_DR, 0);
#endif
/* Enable SSP-TX out */
SETB32(SSPC_CR2, SSPC_C2_TXDOE_BIT);
/* SPI din ... */
for (i = 0; i < 11; ++i){
/* Wait until data ready */
t = 0;
while ((IN32(SSPC_SR) & SSPC_SR_RFVE_MASK) == 0){
if ( ++t > RTS_DIN_TIMEOUT){
DEBUG(1, 1, "rts spi timeout at data[%d]\n", i);
goto _timeout;
}
}
/* Read data byte */
data[i] = IN32(SSPC_DR);
DEBUG(0, 1, "[RTS] data[%d] %d, 0x%x\n", i, data[i], data[i]);
}
/* Disable SSP data out */
CLRR32(SSPC_CR2, SSPC_C2_SSPEN_MASK | SSPC_C2_TXDOE_MASK);
/* Compose final data (12-bits or 8-bits) */
#if ((RTS_ADS7846_RY & RTS_ADS7846_MODE_MASK) == (RTS_ADS7846_8_BITS << RTS_ADS7846_MODE_SHIFT))
*y = RTS_ADS7846_8BITS_DATA(data[3], data[4]);
*x = RTS_ADS7846_8BITS_DATA(data[5], data[6]);
*z1 = RTS_ADS7846_8BITS_DATA(data[7], data[8]);
*z2 = RTS_ADS7846_8BITS_DATA(data[9], data[10]);
#else
*y = RTS_ADS7846_12BITS_DATA(data[3], data[4]);
*x = RTS_ADS7846_12BITS_DATA(data[5], data[6]);
*z1 = RTS_ADS7846_12BITS_DATA(data[7], data[8]);
*z2 = RTS_ADS7846_12BITS_DATA(data[9], data[10]);
#endif
#ifndef CONFIG_PLAT_QEMU
DEBUG(0, 1, "[RTS] y - %04d, msb(0x%02lx) lsb(0x%02lx)\n", *y, (data[3] & 0xff), (data[4] & 0xff));
DEBUG(0, 1, "[RTS] x - %04d, msb(0x%02lx) lsb(0x%02lx)\n", *x, (data[5] & 0xff), (data[6] & 0xff));
DEBUG(0, 1, "[RTS] z1 - %04d, msb(0x%02lx) lsb(0x%02lx)\n", *z1, (data[7] & 0xff), (data[8] & 0xff));
DEBUG(0, 1, "[RTS] z2 - %04d, msb(0x%02lx) lsb(0x%02lx)\n", *z2, (data[9] & 0xff), (data[10] & 0xff));
#else
DEBUG(0, 1, "[RTS] y - %d, msb(0x%x)%d, lsb(0x%x)%d\n", *y, data[3],data[3], data[4], data[4]);
DEBUG(0, 1, "[RTS] x - %d, msb(0x%x)%d, lsb(0x%x)%d\n", *x, data[5],data[5], data[6], data[6]);
DEBUG(0, 1, "[RTS] z1 - %d, msb(0x%x)%d, lsb(0x%x)%d\n", *z1, data[7],data[7], data[8], data[8]);
DEBUG(0, 1, "[RTS] z2 - %d, msb(0x%x)%d, lsb(0x%x)%d\n", *z2, data[9],data[9], data[10], data[10]);
#endif
if ((*z1 < RTS_PRESSED_Z1_MIN) && (*z2 >= RTS_PRESSED_Z2_MAX))
*pressed = 0;
else
*pressed = 1;
return HAL_SUCCESS;
_timeout:
return HAL_FAILURE;
}
void ts_adjust(struct ts_dev *ts, int ts_x, int ts_y, int *x, int *y)
{
*x = (ts->lcd_width * (ts_x - ts->left)) / (ts->right - ts->left);
*y = (ts->lcd_height * (ts_y - ts->top)) / (ts->bottom - ts->top);
DEBUG(0, 0, "adj (x, y) = (%4d, %4d)\n", *x, *y);
}
void ts_raw_value(struct ts_dev *ts, int *x, int *y)
{
hal_pend_semaphore(&ts->sem, HAL_SUSPEND);
*x = ts->data.x;
*y = ts->data.y;
DEBUG(0, 0, "raw (x, y) = (%4d, %4d)\n", *x, *y);
}
void ts_value(struct ts_dev *ts, int *x, int *y)
{
int raw_x, raw_y;
ts_raw_value(ts, &raw_x, &raw_y);
ts_adjust(ts, raw_x, raw_y, x, y);
}
void ts_calibrate(struct ts_dev *ts,
void (*draw_cross)(void *param, int x, int y),
int count)
{
int i = 0;
int left = 0, right = 0, top = 0, bottom = 0;
for (i = 0; i < count; i++) {
int raw_x = 0, raw_y = 0;
DEBUG(0, 0, "(left, top) = ");
draw_cross(NULL, ts->lcd_width * 1 / 5, ts->lcd_height * 1 / 5);
ts_raw_value(ts, &raw_x, &raw_y);
left = ((left * i) + raw_x) / (i + 1);
top = ((top * i) + raw_y) / (i + 1);
DEBUG(0, 0, "(%4d, %4d) || (x, y) = (%4d, %4d)\n", left, top, raw_x, raw_y);
DEBUG(0, 0, "(right, bottom) = ");
draw_cross(NULL, ts->lcd_width * 4 / 5, ts->lcd_height * 4 / 5);
ts_raw_value(ts, &raw_x, &raw_y);
right = ((right * i) + raw_x) / (i + 1);
bottom = ((bottom * i) + raw_y) / (i + 1);
DEBUG(0, 0, "(%4d, %4d) || (x, y) = (%4d, %4d)\n", right, bottom, raw_x, raw_y);
}
ts->left = left - (right - left) / 3;
ts->right = right + (right - left) / 3;
ts->top = top - (bottom - top) / 3;
ts->bottom = bottom + (bottom - top) / 3;
}

View File

@@ -0,0 +1,199 @@
/*****************************************************************************
*
* Copyright Andes Technology Corporation 2007-2008
* All Rights Reserved.
*
* Revision History:
*
* Mar.16.2008 Created.
****************************************************************************/
/*****************************************************************************
*
* FILE NAME VERSION
*
* sspd_rts.h
*
* DESCRIPTION
*
* SPI digital serial interface protocol header for resistive
* touch screen controller.
*
* DATA STRUCTURES
*
* None
*
* DEPENDENCIES
*
* None
*
****************************************************************************/
#ifndef __SSPD_RTS_H__
#define __SSPD_RTS_H__
/*****************************************************************************
* Configuration Options
****************************************************************************/
/* Non-zero to enable 16-clock per conversion mode, otherwise 24-clock cycle is applied. */
#define RTS_16CLK_CONV_CYCLE 1
#define RTS_LISR_VECTOR INTC_HW0_BIT /* AG101 connects #PENIRQ to hw0 vector */
/* polling loop counter for waiting hw-reset */
#define RTS_RESET_WAIT (0x300000)
/* CPU polling counter to avoid bouncing signals of previous RTS operation */
#define RTS_DEBOUNCE_WAIT (0x30000)
/* polling counter for serial data in */
#define RTS_DIN_TIMEOUT (0x30000)
/* HISR definitions */
#define RTS_HISR_PRIORITY 0 /* 0: highest, 2: lowest */
#define RTS_HISR_STACK_SIZE 2048 /* Please align to 32-bit */
#define RTS_HISR_AS_TOUCHED 0x00000001 /* Activate HISR for touched interrupt */
/*****************************************************************************
* Resistive Touch Screen Digital Interface Definitions
****************************************************************************/
/* Definitions for ADS7846 */
/* Control Byte Bits */
#define RTS_ADS7846_PD_MASK 0x03 /* Start Bit (MSB) */
#define RTS_ADS7846_PD_SHIFT 0
#define RTS_ADS7846_PD 0x00 /* power down between conversion, #penirq enabled */
#define RTS_ADS7846_ADC 0x01 /* ref off, adc on, #penirq disabled */
#define RTS_ADS7846_REF 0x02 /* ref on, adc off, #penirq enabled */
#define RTS_ADS7846_PW 0x03 /* power on, ref on, adc on, #penirq disabled */
#define RTS_ADS7846_SER_MASK 0x04 /* Single-Ended/#Differential-Reference Register */
#define RTS_ADS7846_SER_SHIFT 2
#define RTS_ADS7846_DF 0x00 /* differential */
#define RTS_ADS7846_SE 0x01 /* single-ended */
#define RTS_ADS7846_MODE_MASK 0x08 /* Conversion Selection Bit */
#define RTS_ADS7846_MODE_SHIFT 3
#define RTS_ADS7846_12_BITS 0x00 /* 12 bits conversion */
#define RTS_ADS7846_8_BITS 0x01 /* 8 bits conversion */
#define RTS_ADS7846_MUX_MASK 0x70 /* (A2 ~ A0) Control the setting of multiplexer input */
#define RTS_ADS7846_MUX_SHIFT 4
#define RTS_ADS7846_DF_X 0x05 /* [A2:A0] 101b, Driver: X+ X-, Measure Y+ */
#define RTS_ADS7846_DF_Y 0x01 /* [A2:A0] 001b, Driver: Y+ Y-, Measure X+ */
#define RTS_ADS7846_DF_Z1 0x03 /* [A2:A0] 011b, Driver: Y+ X-, Measure X+ */
#define RTS_ADS7846_DF_Z2 0x04 /* [A2:A0] 100b, Driver: Y+ X-, Measure Y- */
#define RTS_ADS7846_SE_X 0x05 /* [A2:A0] 101b */
#define RTS_ADS7846_SE_Y 0x01 /* [A2:A0] 001b */
#define RTS_ADS7846_SE_Z1 0x03 /* [A2:A0] 011b */
#define RTS_ADS7846_SE_Z2 0x04 /* [A2:A0] 100b */
#define RTS_ADS7846_SE_BAT 0x02 /* [A2:A0] 010b */
#define RTS_ADS7846_SE_AUX 0x06 /* [A2:A0] 110b */
#define RTS_ADS7846_SE_TEMP0 0x00 /* [A2:A0] 000b */
#define RTS_ADS7846_SE_TEMP1 0x07 /* [A2:A0] 111b */
#define RTS_ADS7846_START_MASK 0x80 /* Start Bit (MSB) */
#define RTS_ADS7846_START_BIT 7
#define RTS_ADS7846_START 1
/* Supplimental Macros */
#define RTS_ADS7846_PADDING_BYTE 0 /* Padding byte feed after the command byte to continue serial clocking */
#define RTS_ADS7846_CTRL_BYTE(mux, mode, ser, pd) \
((((uint32_t)(mux) << RTS_ADS7846_MUX_SHIFT) & RTS_ADS7846_MUX_MASK) | \
(((uint32_t)(mode) << RTS_ADS7846_MODE_SHIFT) & RTS_ADS7846_MODE_MASK) | \
(((uint32_t)(ser) << RTS_ADS7846_SER_SHIFT) & RTS_ADS7846_SER_MASK) | \
(((uint32_t)(pd) << RTS_ADS7846_PD_SHIFT) & RTS_ADS7846_PD_MASK) | \
(uint32_t)RTS_ADS7846_START_MASK)
/* this is correct */
#define RTS_ADS7846_8BITS_DATA(msb, lsb) ((((uint32_t)(msb) & 0x07) << 5) | (((uint32_t)(lsb) & 0xff) >> 3))
#ifndef CONFIG_PLAT_QEMU
#define RTS_ADS7846_12BITS_DATA(msb, lsb) ((((uint32_t)(msb) & 0x7f) << 5) | (((uint32_t)(lsb) & 0xff) >> 3))
#else
#define RTS_ADS7846_12BITS_DATA(msb, lsb) msb
//#define RTS_ADS7846_12BITS_DATA(msb, lsb) ((msb >> 19) & 0xfff)
#endif
/* Pre-defined Control-Byte Constants */
#define RTS_ADS7846_CTL_RY RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_Y, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PW)
#define RTS_ADS7846_CTL_RX RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_X, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PW)
#define RTS_ADS7846_CTL_RZ1 RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_Z1, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PW)
#define RTS_ADS7846_CTL_RZ2 RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_Z2, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PW)
#define RTS_ADS7846_CTL_RY_PD RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_Y, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PD)
#define RTS_ADS7846_CTL_RX_PD RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_X, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PD)
#define RTS_ADS7846_CTL_RZ1_PD RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_Z1, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PD)
#define RTS_ADS7846_CTL_RZ2_PD RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_Z2, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PD)
#define RTS_ADS7846_CTL_PD RTS_ADS7846_CTRL_BYTE(RTS_ADS7846_DF_Y, RTS_ADS7846_12_BITS, \
RTS_ADS7846_DF, RTS_ADS7846_PD)
/*
* DCLK
* ---------------
* From pp3:
* 125 kHz max throughput rate, so ...
* DCLK_max = 125k * 16(16-clock-per-conversion mode) = 2.0MHz
*
* From table VI (p.p.14):
* (tch + tcl) = 400ns minimum, so ...
* DCLK_max = 1/400ns = 2.5MHz ?
*/
#define RTS_ADS7846_DCLK_MAX 2000000 /* adopt 2.0MHz for safe */
#define RTS_ADS7846_DCLK_DEFAULT 125000 /* 7812 data per second (3906 x-y/sec, or 1953 x-y-z1-z2/sec) */
/*****************************************************************************
* SSP Controller Resistive Touch Screen Driver-Supplement Interfaces
****************************************************************************/
struct ts_data {
int x;
int y;
int z1;
int z2;
int pressed;
};
struct ts_dev {
int left;
int right;
int top;
int bottom;
int lcd_width;
int lcd_height;
int penirq; /* initialize touch screen driver in #penirq mode or polling mode */
int penirq_en; /* enable #penirq after initialization if penirq is non-zero */
void *event_obj; /* (in) Event object to notify app about the interrupt. */
struct ts_data *event_data; /* Client specified struct pointer to receive {x,y,touched} states */
hal_semaphore_t sem;
struct ts_data data;
};
extern int _sspd_rts_init(struct ts_dev *ts);
extern int _sspd_rts_probe(int *x, int *y, int *z1, int *z2, int *pressed);
extern void ts_adjust(struct ts_dev *ts, int ts_x, int ts_y, int *x, int *y);
extern void ts_raw_value(struct ts_dev *ts, int *x, int *y);
extern void ts_value(struct ts_dev *ts, int *x, int *y);
extern void ts_init(struct ts_dev *ts);
extern void ts_calibrate(struct ts_dev *ts, void (*draw_cross)(void *param, int x, int y), int count);
#endif /* __SSPD_RTS_H__ */

View File

@@ -0,0 +1,2 @@
lib-y :=
lib-y += uart.o

View File

@@ -0,0 +1,143 @@
#include <nds32_intrinsic.h>
#define DEFAULT_BAUDRATE 115200 /* 8n1 */
#define IN8(reg) (uint8_t)((*(volatile unsigned long *)(reg)) & 0x000000FF)
#define READ_CLR(reg) (*(volatile unsigned long *)(reg))
int drv_uart_set_baudrate(int baudrate)
{
unsigned long baud_div; /* baud rate divisor */
unsigned long temp_word;
baud_div = (MB_UCLK / (16 * baudrate));
/* Save LCR temporary */
temp_word = IN8(STUARTC_BASE + UARTC_LCR_OFFSET);
/* Setup dlab bit for baud rate setting */
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, (temp_word | UARTC_LCR_DLAB));
/* Apply baud rate */
OUT8(STUARTC_BASE + UARTC_DLM_OFFSET, (unsigned char)(baud_div >> 8));
OUT8(STUARTC_BASE + UARTC_DLL_OFFSET, (unsigned char)baud_div);
OUT8(STUARTC_BASE + UARTC_PSR_OFFSET, (unsigned char)1);
/* Restore LCR */
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, temp_word);
return 0;
}
int drv_uart_is_kbd_hit(void)
{
return IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_RDR;
}
int drv_uart_get_char(void)
{
while (!(IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_RDR))
;
return IN8(STUARTC_BASE + UARTC_RBR_OFFSET);
}
void drv_uart_put_char(int ch)
{
while (!(IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_THRE))
;
OUT8(STUARTC_BASE + UARTC_THR_OFFSET, ch);
}
int drv_uart_init(void)
{
/* Clear everything */
OUT8(STUARTC_BASE + UARTC_IER_OFFSET, 0x0);
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, 0x0);
/* Setup baud rate */
drv_uart_set_baudrate(DEFAULT_BAUDRATE);
/* Setup parity, data bits, and stop bits */
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, \
(UARTC_LCR_PARITY_NONE | UARTC_LCR_BITS8 | UARTC_LCR_STOP1));
return 0;
}
/**********************************************
*
* Archer Chang
*
* driver API with reg base
*
***********************************************/
int __drv_uart_set_baudrate(unsigned int regbase, int baudrate)
{
unsigned long baud_div; /* baud rate divisor */
unsigned long temp_word;
baud_div = (MB_UCLK / (16 * baudrate));
/* Save LCR temporary */
temp_word = IN8(regbase + UARTC_LCR_OFFSET);
/* Setup dlab bit for baud rate setting */
OUT8(regbase + UARTC_LCR_OFFSET, (temp_word | UARTC_LCR_DLAB));
/* Apply baud rate */
OUT8(regbase + UARTC_DLM_OFFSET, (unsigned char)(baud_div >> 8));
OUT8(regbase + UARTC_DLL_OFFSET, (unsigned char)baud_div);
OUT8(regbase + UARTC_PSR_OFFSET, (unsigned char)1);
/* Restore LCR */
OUT8(regbase + UARTC_LCR_OFFSET, temp_word);
return 0;
}
int __drv_uart_is_kbd_hit(unsigned int regbase)
{
return IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_RDR;
}
int __drv_uart_get_char(unsigned int regbase)
{
while (!(IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_RDR))
;
return IN8(regbase + UARTC_RBR_OFFSET);
}
void __drv_uart_put_char(unsigned int regbase, int ch)
{
while (!(IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_THRE))
;
OUT8(regbase + UARTC_THR_OFFSET, ch);
}
int __drv_uart_put_char_nowait(unsigned int regbase, int ch)
{
OUT8(regbase + UARTC_THR_OFFSET, ch);
return 1;
}
int __drv_uart_init(unsigned int regbase, int baudrate)
{
/* Clear everything */
OUT8(regbase + UARTC_IER_OFFSET, 0x0);
OUT8(regbase + UARTC_LCR_OFFSET, 0x0);
/* Setup baud rate */
__drv_uart_set_baudrate(regbase, baudrate);
/* Setup parity, data bits, and stop bits */
OUT8(regbase + UARTC_LCR_OFFSET, \
(UARTC_LCR_PARITY_NONE | UARTC_LCR_BITS8 | UARTC_LCR_STOP1));
return 0;
}

View File

@@ -0,0 +1,17 @@
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
extern int drv_uart_init(void);
extern int drv_uart_set_baudrate(int baudrate);
extern int drv_uart_is_kbd_hit(void);
extern int drv_uart_get_char(void);
extern void drv_uart_put_char(int ch);
extern int __drv_uart_init (unsigned int regbase, int baudrate);
extern int __drv_uart_set_baudrate (unsigned int regbase, int baudrate);
extern int __drv_uart_is_kbd_hit (unsigned int regbase);
extern int __drv_uart_get_char (unsigned int regbase);
extern void __drv_uart_put_char (unsigned int regbase, int ch);
extern void __drv_uart_put_char_nowait(unsigned int regbase, int ch);
#endif /* __DRV_UART_H__ */

View File

@@ -0,0 +1,51 @@
#ifndef __CTYPE_H__
#define __CTYPE_H__
static inline int islower(int c)
{
return c >= 'a' && c <= 'z';
}
static inline int isupper(int c)
{
return c >= 'A' && c <= 'Z';
}
static inline int isalpha(int c)
{
return islower(c) || isupper(c);
}
static inline int isdigit(int c)
{
return c >= '0' && c <= '9';
}
static inline int isalnum(int c)
{
return isalpha(c) || isdigit(c);
}
static inline int isblank(int c)
{
return c == ' ' || c == '\t';
}
static inline int isspace(int c)
{
return c == ' ';
}
static inline int isxdigit(int c)
{
return (c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z');
}
// static inline int isascii(int c)
// static inline int iscntrl(int c)
// static inline int isgraph(int c)
// static inline int isprint(int c)
// static inline int ispunct(int c)
#endif /* __CTYPE_H__ */

View File

@@ -0,0 +1,78 @@
#ifndef __DEBUG_H__
#define __DEBUG_H__
#include <stdio.h>
#define DEBUG(enable, tagged, ...) \
do \
{ \
if (enable) \
{ \
if (tagged) \
fprintf(stderr, "[ %25s() ] ", __func__); \
fprintf(stderr, __VA_ARGS__); \
} \
} while( 0)
#define ERROR(...) DEBUG(1, 1, "ERROR:"__VA_ARGS__)
#define KASSERT(cond) \
{ \
if (!(cond)) \
{ \
ERROR("Failed assertion in %s:\n" \
"%s at %s\n" \
"line %d\n" \
"RA=%lx\n", \
__func__, \
#cond, \
__FILE__, \
__LINE__, \
(unsigned long)__builtin_return_address(0)); \
\
while (1) \
; \
} \
}
#define KPANIC(args, ...) \
{ \
ERROR(args, __VA_ARGS__); \
while (1) ; \
}
static inline void dump_mem(const void *mem, int count)
{
const unsigned char *p = mem;
int i = 0;
for(i = 0; i < count; i++)
{
if( i % 16 == 0)
DEBUG(1, 0, "\n");
DEBUG(1, 0, "%02x ", p[i]);
}
}
/* help to trace back */
static inline void dump_stack(void)
{
unsigned long *stack;
unsigned long addr;
__asm__ __volatile__ ("\tori\t%0, $sp, #0\n" : "=r" (stack));
printf("Call Trace:\n");
addr = *stack;
while (addr)
{
addr = *stack++;
printf("[<%08lx>] ", addr);
}
printf("\n");
return;
}
#endif /* __DEBUG_H__ */

View File

@@ -0,0 +1,20 @@
#include "../library/ndsvfs/include/ndsvfs.h"
struct dirent {
int d_cnt;
int d_ino;
int d_off;
char d_name[256];
};
struct dir {
int d_cnt;
int d_off;
NDSVFS_FILE *d_file;
struct dirent *d_dirent;
NDSVFS_DENTRY *vde_list;
NDSVFS_DENTRY *vde_head;
};

View File

@@ -0,0 +1,18 @@
#ifndef _STDINT_H
#include <stdint.h>
#if 0
#ifndef __INTTYPES_H__
#define __INTTYPES_H__
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
#endif
#endif
#endif /* __INTTYPES_H__ */

View File

@@ -0,0 +1,324 @@
#ifndef __LIST_H__
#define __LIST_H__
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
#define LIST_POISON1 ((void*) 0x00100100)
#define LIST_POISON2 ((void*) 0x00200200)
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)
#endif
#define container_of(ptr, type, member) ( { \
const typeof(((type*)0)->member ) *__mptr = (ptr); \
(type*)((char*)__mptr - offsetof(type,member) );})
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry) {
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_empty_careful - tests whether a list is
* empty _and_ checks that no other CPU might be
* in the process of still modifying either member
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*
* @head: the list to test.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
static inline int list_swap(struct list_head *a, struct list_head *b, struct list_head *list)
{
if (a->next == list || b->prev == list)
return -1;
list_del(a);
list_add(a, b);
return 0;
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_prepare_entry - prepare a pos entry for use as a start point in
* list_for_each_entry_continue
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
/**
* list_for_each_entry_continue - iterate over list of given type
* continuing after existing point
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_reverse_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse_safe(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
#endif /* __LIST_H__ */

130
bsp/AE210P/include/stdarg.h Normal file
View File

@@ -0,0 +1,130 @@
/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/*
* ISO C Standard: 7.15 Variable arguments <stdarg.h>
*/
#ifndef _STDARG_H
#ifndef _ANSI_STDARG_H_
#ifndef __need___va_list
#define _STDARG_H
#define _ANSI_STDARG_H_
#endif /* not __need___va_list */
#undef __need___va_list
/* Define __gnuc_va_list. */
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
#endif
/* Define the standard macros for the user,
if this invocation was from the user program. */
#ifdef _STDARG_H
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#define va_copy(d,s) __builtin_va_copy(d,s)
#endif
#define __va_copy(d,s) __builtin_va_copy(d,s)
/* Define va_list, if desired, from __gnuc_va_list. */
/* We deliberately do not define va_list when called from
stdio.h, because ANSI C says that stdio.h is not supposed to define
va_list. stdio.h needs to have access to that data type,
but must not use that name. It should use the name __gnuc_va_list,
which is safe because it is reserved for the implementation. */
#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */
#undef _VA_LIST
#endif
#ifdef _BSD_VA_LIST
#undef _BSD_VA_LIST
#endif
#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST))
/* SVR4.2 uses _VA_LIST for an internal alias for va_list,
so we must avoid testing it and setting it here.
SVR4 uses _VA_LIST as a flag in stdarg.h, but we should
have no conflict with that. */
#ifndef _VA_LIST_
#define _VA_LIST_
#ifdef __i860__
#ifndef _VA_LIST
#define _VA_LIST va_list
#endif
#endif /* __i860__ */
typedef __gnuc_va_list va_list;
#ifdef _SCO_DS
#define __VA_LIST
#endif
#endif /* _VA_LIST_ */
#else /* not __svr4__ || _SCO_DS */
/* The macro _VA_LIST_ is the same thing used by this file in Ultrix.
But on BSD NET2 we must not test or define or undef it.
(Note that the comments in NET 2's ansi.h
are incorrect for _VA_LIST_--see stdio.h!) */
#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT)
/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */
#ifndef _VA_LIST_DEFINED
/* The macro _VA_LIST is used in SCO Unix 3.2. */
#ifndef _VA_LIST
/* The macro _VA_LIST_T_H is used in the Bull dpx2 */
#ifndef _VA_LIST_T_H
/* The macro __va_list__ is used by BeOS. */
#ifndef __va_list__
typedef __gnuc_va_list va_list;
#endif /* not __va_list__ */
#endif /* not _VA_LIST_T_H */
#endif /* not _VA_LIST */
#endif /* not _VA_LIST_DEFINED */
#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__))
#define _VA_LIST_
#endif
#ifndef _VA_LIST
#define _VA_LIST
#endif
#ifndef _VA_LIST_DEFINED
#define _VA_LIST_DEFINED
#endif
#ifndef _VA_LIST_T_H
#define _VA_LIST_T_H
#endif
#ifndef __va_list__
#define __va_list__
#endif
#endif /* not _VA_LIST_, except on certain systems */
#endif /* not __svr4__ */
#endif /* _STDARG_H */
#endif /* not _ANSI_STDARG_H_ */
#endif /* not _STDARG_H */

View File

@@ -0,0 +1,5 @@
#ifndef __STDDEF_H__
#define __STDDEF_H__
typedef unsigned long size_t;
#endif /* __STDDEF_H__ */

View File

@@ -0,0 +1,64 @@
#ifndef __STDIO_H__
#define __STDIO_H__
#include <stdarg.h> /* va_list, va_arg() */
#include <stddef.h> /* size_t */
#include <stdlib.h>
//#include <dirent.h>
// FIXME: find a right place to define the following things
// constants
typedef int fpos_t;
#define FSEEK_SET 0 // origin is beginning of the file
#define FSEEK_CUR 1 // origin is current position
#define FSEEK_END 2 // origin is end of the file
typedef unsigned long FILE;
typedef int time_t;
struct stat {
int st_dev; /* ID of device containing file */
int st_ino; /* inode number */
int st_mode; /* protection */
int st_size; /* total size, in bytes */
int st_blksize; /* blocksize for file system I/O */
int st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
#define stdin ((void*)0)
#define stdout ((void*)0)
#define stderr ((void*)0)
#define EOF (-1)
int vsprintf(char *buffer, const char *fmt, va_list args);
int sprintf(char *buffer, const char *fmt, ...);
int vprintf(const char *fmt, va_list args);
int printf(const char *fmt, ...);
int fprintf(FILE *stream, const char *format, ...);
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int getc(FILE *stream);
int getchar(void);
char *gets(char *s);
int ungetc(int c, FILE *stream);
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);
int fclose(FILE *fp);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
struct dir *opendir(const char *path);
struct dirent *readdir(struct dir *dirp);
int closedir(struct dir *dirp);
int fstat(FILE* fd, struct stat *buf);
#endif /* __STDIO_H__ */

View File

@@ -0,0 +1,70 @@
#ifndef __STDLIB_H__
#define __STDLIB_H__
#include <stddef.h>
#include <string.h>
#ifndef NULL
#define NULL ((void*)0)
#endif
#if defined(CONFIG_OS_UCOS_II) || defined(CONFIG_OS_UCOS_III)
#include "kmem.h"
static inline void *malloc(size_t size)
{
return kmalloc(size);
}
static inline void free(void *ptr)
{
return kfree(ptr);
}
#elif defined(CONFIG_OS_FREERTOS)
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
#define malloc pvPortMalloc
#define free vPortFree
#elif defined(CONFIG_OS_THREADX)
#include "kmem.h"
static inline void *malloc(size_t size)
{
return kmalloc(size);
}
static inline void free(void *ptr)
{
return kfree(ptr);
}
#elif defined(CONFIG_OS_RTTHREAD)
#include "rtdef.h"
#include "rtthread.h"
#define malloc rt_malloc
#define free rt_Free
#else
# error "No valid OS is defined!"
#endif
static inline void *calloc(size_t nmemb, size_t size)
{
int i = nmemb * size;
unsigned char *ret = malloc(i);
while (i >= 0)
ret[--i] = '\0';
return ret;
}
static inline void *realloc(void *ptr, size_t size)
{
return NULL;
}
static inline void exit(int status)
{
}
static inline void abort(void)
{
}
void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));
extern int atoi(const char *__nptr);
#endif /* __STDLIB_H__ */

View File

@@ -0,0 +1,51 @@
#ifndef __STRING_H__
#define __STRING_H__
#include <stddef.h>
extern void *memcpy(void *dest, const void *src, size_t n);
extern void *memmove(void *dest, const void *src, size_t n);
extern void *memset(void *s, int c, size_t n);
extern void bzero(void *, size_t);
extern char *strcat(char *dest, const char *src);
extern char *strncat(char *dest, const char *src, size_t n);
extern int strcasecmp(const char *s1, const char *s2);
extern int strncasecmp(const char *s1, const char *s2, size_t n);
extern int strcmp(const char *s1, const char *s2);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern char *strcpy(char *dest, const void *src);
extern char *strncpy(char *dest, const void *src, size_t n);
extern char *strdup(const char *s);
extern char *strndup(const char *s, size_t n);
extern size_t strlen(const char *s);
extern size_t strnlen(const char *s, size_t maxlen);
extern char *strstr(const char *haystack, const char *needle);
extern unsigned long int strtoul(const char *nptr, char **endptr, int base);
extern char *strupr(char *str);
/* wchar_t */
#ifndef WCHAR
typedef unsigned short WCHAR;
#endif // WCHAR
#ifndef wchar_t
typedef unsigned short wchar_t;
#endif // wchar
extern wchar_t *wcscat(wchar_t *str_dst, const wchar_t *str_src);
extern int wcscmp(const wchar_t *string1, const wchar_t *string2);
extern int wcsncmp(const wchar_t *string1, const wchar_t *string2, int count);
extern wchar_t *wcscpy(wchar_t *str_dst, const wchar_t *str_src);
extern wchar_t *wcsncpy(wchar_t *str_dst, const wchar_t *str_src, int count);
extern int wcslen(const wchar_t *str);
extern wchar_t *wcsupr(wchar_t *str);
extern wchar_t *wcslwr(wchar_t *str);
#endif /* __STRING_H__ */

220
bsp/AE210P/kmem/kmem.c Normal file
View File

@@ -0,0 +1,220 @@
#include "kmem.h"
#include "slab.h"
#include "debug.h"
#include "hal.h"
static struct page_struct mem_map[MEM_LIMIT >> PG_SHIFT];
static intptr_t kmem_start;
static intptr_t kmem_end;
static intptr_t kmem_size;
static intptr_t kmem_total_pages;
static intptr_t kmem_free_pages;
static inline int pg_is_free(struct page_struct *page)
{
return page->flag & PG_FLAG_FREE;
}
static inline void *pf_to_addr(intptr_t pg_idx)
{
return (void*)(kmem_start + (pg_idx << PG_SHIFT));
}
static inline intptr_t addr_to_pf(void *addr)
{
return (intptr_t)(addr - kmem_start) >> PG_SHIFT;
}
static inline void pg_flag_set(intptr_t start, intptr_t count, uint32_t flag)
{
while (count-- > 0)
mem_map[start + count].flag |= flag;
}
static inline void pg_flag_clr(intptr_t start, intptr_t count, uint32_t flag)
{
while (count-- > 0)
mem_map[start + count].flag &= ~flag;
}
struct page_struct *addr_to_pf_des(void *addr)
{
return &mem_map[addr_to_pf(addr)];
}
int init_kmem(intptr_t start, intptr_t end)
{
extern char *_end;
if((unsigned int)start < (unsigned int)&_end)
KPANIC("start and _end are overlap. start:%08x, _end=%08x\n", start, &_end);
kmem_start = start & PG_MASK;
kmem_end = end & PG_MASK;
kmem_size = kmem_end - kmem_start;
kmem_total_pages = kmem_size >> PG_SHIFT;
kmem_free_pages = kmem_total_pages;
pg_flag_set(0, kmem_total_pages, PG_FLAG_FREE);
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 0, "* Initializeing MM *\n");
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 1, "Start:0x%08x End:0x%08x, Size:0x%08x(%dK), Pages:%d\n",
kmem_start, kmem_end, kmem_size,
kmem_size >> 10, kmem_total_pages);
#ifdef CONFIG_KMEM_SLAB
init_cache();
#endif
return 0;
}
void *alloc_pages(intptr_t pg_req_nr)
{
intptr_t pg_begin_idx = -1;
intptr_t pg_found_nr = 0;
intptr_t i = 0;
DEBUG(0, 1, "Requesting for %d/%d/%d pages\n",
pg_req_nr, kmem_free_pages, kmem_total_pages);
if (kmem_free_pages < pg_req_nr)
return (void*)0;
for (i = 0; i < kmem_total_pages; i++) {
if (!pg_is_free(&mem_map[i])) {
pg_begin_idx = -1;
continue;
}
if (pg_begin_idx < 0) {
pg_begin_idx = i;
pg_found_nr = 1;
}
else {
pg_found_nr++;
}
if (pg_found_nr == pg_req_nr) {
pg_flag_clr(pg_begin_idx, pg_req_nr, PG_FLAG_FREE);
mem_map[pg_begin_idx].alloc_nr = pg_req_nr;
kmem_free_pages -= pg_req_nr;
DEBUG(0, 1, "return mem_map %d pages at [%d]:0x%08x\n",
pg_req_nr, pg_begin_idx, (intptr_t)pf_to_addr(pg_begin_idx));
return pf_to_addr(pg_begin_idx);
}
}
return (void*)0;
}
void *alloc_page(void)
{
return alloc_pages(1);
}
void free_pages(void *addr)
{
intptr_t idx = addr_to_pf(addr);
KASSERT(!pg_is_free(&mem_map[idx]))
pg_flag_set(idx, mem_map[idx].alloc_nr, PG_FLAG_FREE);
DEBUG(0, 1, "0x:%08x, idx:%d, pages:%d, phy_addr:%08x\n",
(intptr_t)addr, idx, mem_map[idx].alloc_nr,
(intptr_t)pf_to_addr(idx));
kmem_free_pages += mem_map[idx].alloc_nr;
mem_map[idx].alloc_nr = 0;
}
void *kmalloc(intptr_t size)
{
void *addr = 0;
intptr_t pg_req_nr = 0;
int core_intl = 0;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
DEBUG(0, 1, "%d bytes at:", size);
#ifdef CONFIG_KMEM_USING_SLAB
addr = kmem_cache_alloc_gen(size);
if (addr) {
DEBUG(0, 0, " 0x%08x\n", (intptr_t)addr);
hal_global_int_ctl(core_intl);
return addr;
}
#endif
size = (size + (PG_SIZE - 1)) & PG_MASK;
pg_req_nr = size >> PG_SHIFT;
if (pg_req_nr <= kmem_free_pages) {
addr = alloc_pages(pg_req_nr);
DEBUG(0, 0, " 0x%08x\n", (intptr_t)addr);
}
else {
DEBUG(0, 0, "FAIL:(req:%d, free:%d)\n", pg_req_nr, kmem_free_pages);
}
hal_global_int_ctl(core_intl);
return addr;
}
void kfree(void *addr)
{
int core_intl = 0;
core_intl = hal_global_int_ctl(HAL_DISABLE_INTERRUPTS);
#ifdef CONFIG_KMEM_USING_SLAB
struct page_struct *pg = addr_to_pf_des(addr);
struct cache_struct *cp = GET_PAGE_CACHE(pg);
if (cp) {
DEBUG(0, 1, "0x%08x\n", (intptr_t)addr);
kmem_cache_free(cp, addr);
hal_global_int_ctl(core_intl);
return;
}
#endif
DEBUG(0, 1, "0x%08x\n", (intptr_t)addr);
free_pages(addr);
hal_global_int_ctl(core_intl);
}
void mem_dump_map(void)
{
intptr_t i;
DEBUG(1, 1, "*:free +: begin of allocated chunk, -:allocated\n");
for (i = 0; i < kmem_total_pages; i++) {
if (i%32 == 0)
DEBUG(1, 0, "\n0x%08x\t: ", kmem_start + i * PG_SIZE);
else if (i%8 == 0)
DEBUG(1, 0, " ");
if (pg_is_free(&mem_map[i]))
DEBUG(1, 0, "*");
else if (mem_map[i].alloc_nr)
DEBUG(1, 0, "+");
else
DEBUG(1, 0, "-");
}
DEBUG(1, 0, "\n");
}

74
bsp/AE210P/kmem/kmem.h Normal file
View File

@@ -0,0 +1,74 @@
#ifndef __KMEM_H__
#define __KMEM_H__
#include <inttypes.h>
#include "list.h"
#define PG_FLAG_FREE 0x00000001
#ifdef CONFIG_PLAT_AE210P
#include "ae210p_regs.h"
#define PG_MASK 0xFFFFFF00
#define PG_SHIFT 8
#define PG_SIZE (1 << PG_SHIFT) //256Byte per page
/* 48MB ~ 112MB */
#define MEM_START 0x00208000 //EDLM_BASEi+32K
#define MEM_END 0x00210000 //EDLM_BASE+64K
#elif defined( CONFIG_LATENCY_HEAP )
#define PG_MASK 0xFFFFFFC0
#define PG_SHIFT 6
#define PG_SIZE (1 << PG_SHIFT)
#define MEM_START 0x0C000
#define MEM_END 0x10000
#else
#ifdef CONFIG_PLAT_AG101P_16MB
#define PG_MASK 0xFFFFFF00
#define PG_SHIFT 8
#define PG_SIZE (1 << PG_SHIFT)
#ifdef CONFIG_SMALL_HEAP
/* 6MB ~ 7MB*/
#define MEM_START 0x00600000
#else
/* 3MB ~ 7MB*/
#define MEM_START 0x00300000
#endif
#define MEM_END 0x00700000
#else
#define PG_MASK 0xFFFFF000
#define PG_SHIFT 12
#define PG_SIZE (1 << PG_SHIFT)
/* 48MB ~ 112MB */
#define MEM_START 0x03000000
#define MEM_END 0x07000000
#endif
#endif
#define MEM_LIMIT ((MEM_END) - (MEM_START))
struct page_struct {
struct list_head lru;
uint32_t flag;
intptr_t alloc_nr;
};
extern int init_kmem(intptr_t start, intptr_t end);
extern void *alloc_pages(intptr_t pg_req_nr);
extern void *alloc_page(void);
extern void free_pages(void *addr);
extern void *kmalloc(intptr_t size);
extern void kfree(void *addr);
extern struct page_struct *addr_to_pf_des(void *addr);
extern void mem_dump_map(void);
#endif /* __KMEM_H__ */

324
bsp/AE210P/kmem/list.h Normal file
View File

@@ -0,0 +1,324 @@
#ifndef __LIST_H__
#define __LIST_H__
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
#define LIST_POISON1 ((void*) 0x00100100)
#define LIST_POISON2 ((void*) 0x00200200)
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)
#endif
#define container_of(ptr, type, member) ( { \
const typeof(((type*)0)->member ) *__mptr = (ptr); \
(type*)((char*)__mptr - offsetof(type,member) );})
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry) {
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list, struct list_head *head) {
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_empty_careful - tests whether a list is
* empty _and_ checks that no other CPU might be
* in the process of still modifying either member
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*
* @head: the list to test.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
static inline int list_swap(struct list_head *a, struct list_head *b, struct list_head *list)
{
if (a->next == list || b->prev == list)
return -1;
list_del(a);
list_add(a, b);
return 0;
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/**
* list_prepare_entry - prepare a pos entry for use as a start point in
* list_for_each_entry_continue
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
/**
* list_for_each_entry_continue - iterate over list of given type
* continuing after existing point
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_for_each_entry_reverse_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse_safe(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
#endif /* __LIST_H__ */

318
bsp/AE210P/kmem/slab.c Normal file
View File

@@ -0,0 +1,318 @@
#include "list.h"
#include "slab.h"
#include "kmem.h"
#include "debug.h"
#include <string.h>
LIST_HEAD(cache_list);
struct cache_struct *cachep;
struct cache_struct *slabp;
struct cache_struct *kmem_cache_create(const char *name, intptr_t obj_size, handler_t ctor, handler_t dtor)
{
struct cache_struct *cp;
cp = kmem_cache_alloc(cachep);
KASSERT(cp);
strncpy(cp->name, name, CACHE_NAME_BUF_SIZE-1);
cp->obj_size = obj_size;
cp->page_nr = obj_size * 8 / PG_SIZE + 1;
cp->ctor = ctor;
cp->dtor = dtor;
cp->free_objs = 0;
if (cp->obj_size < (PG_SIZE >> 3))
cp->num = (PG_SIZE - sizeof(struct slab_struct)) / (sizeof(bufctl_t) + cp->obj_size);
else
cp->num = PG_SIZE / cp->obj_size;
cp->total_objs = 0;
INIT_LIST_HEAD(&cp->slab_full);
INIT_LIST_HEAD(&cp->slab_partial);
INIT_LIST_HEAD(&cp->slab_free);
INIT_LIST_HEAD(&cp->next);
list_add_tail(&cp->next, &cache_list);
DEBUG(0, 1, "Cache \"%s\" (size:%d) created\n", name, obj_size);
return cp;
}
static inline bufctl_t *slab_bufctl(struct slab_struct *sp)
{
return (bufctl_t*)(sp+1);
}
static void cache_init_objs(struct cache_struct *cp, struct slab_struct *sp, unsigned long ctor_flags)
{
intptr_t i;
DEBUG(0, 1, " %s:cp->num =%d\n", cp->name, cp->num);
for (i = 0; i < cp->num; i++) {
void *objp = (void*)(sp->s_mem + cp->obj_size*i);
if (cp->ctor)
cp->ctor(objp, cp, ctor_flags);
slab_bufctl(sp)[i] = (bufctl_t)(i+1);
}
slab_bufctl(sp)[i-1] = (bufctl_t)BUFCTL_END;
sp->next_free = 0;
}
static void kmem_cache_grow(struct cache_struct *cp)
{
void *addr;
struct slab_struct *sp;
struct page_struct *pg_des;
int i;
addr = alloc_pages(cp->page_nr);
KASSERT(addr);
if (cp->obj_size < (PG_SIZE >> 3)) {
sp = (struct slab_struct*)addr;
sp->s_mem = (void*)sp + sizeof(struct slab_struct) + sizeof(bufctl_t)*cp->num;
}
else {
sp = (struct slab_struct*)kmem_cache_alloc(slabp);
KASSERT(sp);
sp->s_mem = addr;
}
pg_des = addr_to_pf_des(addr);
i = cp->page_nr;
while (i--) {
SET_PAGE_CACHE(pg_des, cp);
SET_PAGE_SLAB(pg_des, sp);
pg_des++;
}
sp->cache = cp;
sp->ref_cnt = 0;
cache_init_objs(cp, sp, 0);
cp->free_objs += cp->num;
cp->total_objs += cp->num;
INIT_LIST_HEAD(&sp->list);
list_add_tail(&sp->list, &cp->slab_free);
DEBUG(0, 1, " %s:grow up, get %d more free object\n", cp->name, cp->free_objs);
}
static void *kmem_slab_refill(struct slab_struct *sp)
{
void *buf_addr;
intptr_t idx;
idx = sp->next_free;
sp->next_free = (intptr_t)(slab_bufctl(sp)[idx]);
slab_bufctl(sp)[idx] = BUFCTL_END;
DEBUG(0, 1, " %s:allocating %uth obj in a slab of Cache \n", sp->cache->name, idx);
if (sp->next_free == (intptr_t)BUFCTL_END) {
DEBUG(0, 1, " %s:move from slab_partial to slab_full\n", sp->cache->name);
list_move(&sp->list, &sp->cache->slab_full);
}
else if (sp->ref_cnt == 0) {
DEBUG(0, 1, " %s:move from slab_free to slab_partial\n", sp->cache->name);
list_move(&sp->list, &sp->cache->slab_partial);
}
sp->ref_cnt++;
sp->cache->free_objs--;
buf_addr = sp->s_mem + idx*sp->cache->obj_size;
return buf_addr;
}
static void slab_print_list(struct cache_struct *cp)
{
DEBUG(0, 1, " %s:partial[%c], free[%c], full[%c] %3d/%3d (%3d)\n",
cp->name,
list_empty(&cp->slab_partial)?' ':'*',
list_empty(&cp->slab_free)?' ':'*',
list_empty(&cp->slab_full)?' ':'*',
cp->free_objs,
cp->total_objs,
cp->num);
}
void *kmem_cache_alloc(struct cache_struct *cp)
{
struct slab_struct *sp;
slab_print_list(cp);
DEBUG(0, 1, " %s:free_objs = %d/%d\n", cp->name, cp->free_objs, cp->num);
while (!cp->free_objs)
kmem_cache_grow(cp);
list_for_each_entry(sp, &cp->slab_partial, list) {
DEBUG(0, 1, " %s:get a free obj from slab_partial list\n", cp->name);
return kmem_slab_refill(sp);
}
list_for_each_entry(sp, &cp->slab_free, list) {
DEBUG(0, 1, " %s:get a free obj from slab_free list\n", cp->name);
return kmem_slab_refill(sp);
}
KPANIC("%s:failed to alloc a free slab\n", cp->name);
}
void kmem_cache_free(struct cache_struct *cp, void *buf_addr)
{
struct page_struct *pg;
struct slab_struct *sp;
intptr_t idx;
pg = addr_to_pf_des(buf_addr);
sp = GET_PAGE_SLAB(pg);
idx = ((intptr_t)(buf_addr - sp->s_mem)) / cp->obj_size;
slab_bufctl(sp)[idx] = (bufctl_t)sp->next_free;
sp->next_free = idx;
DEBUG(0, 1, " %s:freeing %uth obj in a slab\n", cp->name, idx);
if (sp->ref_cnt == cp->num) {
DEBUG(0, 1, " %s:move from slab_full to slab_partial\n", cp->name);
list_move(&sp->list, &sp->cache->slab_partial);
}
else if (sp->ref_cnt == 1) {
DEBUG(0, 1, " %s:move from slab_partial to slab_free\n", cp->name);
list_move(&sp->list, &sp->cache->slab_free);
}
cp->free_objs++;
sp->ref_cnt--;
}
void kmem_cache_destory(struct cache_struct *cp)
{
if (!cp)
return;
}
void kmem_cache_reap(struct cache_struct *cp)
{
struct slab_struct *sp, *tmp;
slab_print_list(cp);
list_for_each_entry_safe(sp, tmp, &cp->slab_free, list) {
list_del(&sp->list);
if (cp->obj_size < (PG_SIZE >> 3))
free_pages(sp);
else
free_pages(sp->s_mem);
cp->free_objs -= cp->num;
DEBUG(0, 1, " %s:cache shrink, free_objs = %d\n", cp->name, cp->free_objs);
}
}
void init_cache(void)
{
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 0, "* Initializeing SLAB *\n");
DEBUG(1, 0, "*************************************************\n");
/* Initialize the cachep statically */
cachep = (struct cache_struct*)alloc_page();
KASSERT(cachep);
strncpy(cachep->name, "cachep", CACHE_NAME_BUF_SIZE-1);
cachep->obj_size = sizeof(struct cache_struct);
cachep->page_nr = sizeof(struct cache_struct) * 8 / PG_SIZE + 1;
cachep->ctor = (void*)0;
cachep->dtor = (void*)0;
cachep->num = (PG_SIZE - sizeof(struct slab_struct)) / (sizeof(bufctl_t) + cachep->obj_size);
cachep->free_objs = 0;
cachep->total_objs = 0;
INIT_LIST_HEAD(&cachep->slab_full);
INIT_LIST_HEAD(&cachep->slab_partial);
INIT_LIST_HEAD(&cachep->slab_free);
INIT_LIST_HEAD(&cachep->next);
list_add_tail(&cachep->next, &cache_list);
slabp = kmem_cache_create("slabp", sizeof(struct cache_struct), (void*)0, (void*)0);
#ifdef CONFIG_KMEM_USING_SLAB
init_general_caches();
#endif
}
#define TBL_SIZE 10
#define MIN_OBJ_SIZE 8
struct cache_tbl_entry {
struct cache_struct *cp;
intptr_t size;
};
struct cache_tbl_entry cache_tbl[TBL_SIZE];
void init_general_caches(void)
{
char name_buf[CACHE_NAME_BUF_SIZE];
intptr_t size;
intptr_t i;
size = MIN_OBJ_SIZE;
DEBUG(1, 0, "*************************************************\n");
DEBUG(1, 0, "* Initializeing SLAB(General Object Caches) *\n");
DEBUG(1, 0, "*************************************************\n");
for (i = 0; i < TBL_SIZE; i++) {
sprintf(name_buf, "gen_cache_%d", size);
cache_tbl[i].cp = kmem_cache_create(name_buf, size, (void*)0, (void*)0);
cache_tbl[i].size = size;
size *= 2;
}
}
void *kmem_cache_alloc_gen(intptr_t size)
{
int i;
for (i = 0; i < TBL_SIZE; i++) {
if (cache_tbl[i].size > size)
return kmem_cache_alloc(cache_tbl[i].cp);
}
return (void*)0;
}

59
bsp/AE210P/kmem/slab.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef __SLAB_H__
#define __SLAB_H__
#include <inttypes.h>
#include "list.h"
#define BUFCTL_END (((bufctl_t)(~0U))-0)
#define BUFCTL_FREE (((bufctl_t)(~0U))-1)
#define SLAB_LIMIT (((bufctl_t)(~0U))-2)
#define CACHE_NAME_BUF_SIZE 20
struct cache_struct;
typedef void (*handler_t)(void *, struct cache_struct*, intptr_t);
struct cache_struct {
struct list_head slab_full;
struct list_head slab_partial;
struct list_head slab_free;
struct list_head next;
char name[CACHE_NAME_BUF_SIZE];
intptr_t obj_size;
intptr_t page_nr;
intptr_t num;
intptr_t free_objs;
intptr_t total_objs;
handler_t ctor;
handler_t dtor;
};
struct slab_struct {
struct cache_struct *cache;
struct list_head list;
void *s_mem;
int ref_cnt;
intptr_t next_free;
};
typedef intptr_t *bufctl_t;
extern struct cache_struct *kmem_cache_create(const char *name, intptr_t obj_size, handler_t ctor, handler_t dtor);
extern void *kmem_cache_alloc(struct cache_struct *cp);
extern void kmem_cache_free(struct cache_struct *cp, void *buf_addr);
extern void *kmem_cache_alloc_gen(intptr_t size);
extern void kmem_cache_destory(struct cache_struct *cp);
extern void kmem_cache_reap(struct cache_struct *cp);
extern void init_cache(void);
extern void init_general_caches(void);
#define SET_PAGE_CACHE(pg,x) ((pg)->lru.next = (struct list_head*)(x))
#define GET_PAGE_CACHE(pg) ((struct cache_struct*)(pg)->lru.next)
#define SET_PAGE_SLAB(pg,x) ((pg)->lru.prev = (struct list_head*)(x))
#define GET_PAGE_SLAB(pg) ((struct slab_struct*)(pg)->lru.prev)
#endif /* __SLAB_H__ */

View File

@@ -0,0 +1,6 @@
lib-y += do_printf.o
lib-y += fgets.o
lib-y += file.o
lib-y += fprintf.o
lib-y += fputs.o
lib-y += printf.o

View File

@@ -0,0 +1,280 @@
#include <string.h> /* strlen() */
#include "do_printf.h"
/*****************************************************************************
Revised Jan 28, 2002
- changes to make characters 0x80-0xFF display properly
Revised June 10, 2001
- changes to make vsprintf() terminate string with '\0'
Revised May 12, 2000
- math in DO_NUM is now unsigned, as it should be
- %0 flag (pad left with zeroes) now works
- actually did some TESTING, maybe fixed some other bugs
name: do_printf
action: minimal subfunction for ?printf, calls function
'fn' with arg 'ptr' for each character to be output
returns:total number of characters output
%[flag][width][.prec][mod][conv]
flag: - left justify, pad right w/ blanks DONE
0 pad left w/ 0 for numerics DONE
+ always print sign, + or - no
' ' (blank) no
# (???) no
width: (field width) DONE
prec: (precision) no
conv: d,i decimal int DONE
u decimal unsigned DONE
o octal DONE
x,X hex DONE
f,e,g,E,G float no
c char DONE
s string DONE
p ptr DONE
mod: N near ptr DONE
F far ptr no
h short (16-bit) int DONE
l long (32-bit) int DONE
L long long (64-bit) int no
*****************************************************************************/
/* flags used in processing format string */
#define PR_LJ 0x01 /* left justify */
#define PR_CA 0x02 /* use A-F instead of a-f for hex */
#define PR_SG 0x04 /* signed numeric conversion (%d vs. %u) */
#define PR_32 0x08 /* long (32-bit) numeric conversion */
#define PR_16 0x10 /* short (16-bit) numeric conversion */
#define PR_WS 0x20 /* PR_SG set and num was < 0 */
#define PR_LZ 0x40 /* pad left with '0' instead of ' ' */
#define PR_FP 0x80 /* pointers are far */
/* largest number handled is 2^32-1, lowest radix handled is 8.
2^32-1 in base 8 has 11 digits (add 5 for trailing NUL and for slop) */
#define PR_BUFLEN 16
int do_printf(const char *fmt, va_list args, fnptr_t fn, void *ptr)
{
unsigned state, flags, radix, actual_wd, count, given_wd;
unsigned char *where, buf[PR_BUFLEN];
long num;
state = flags = count = given_wd = 0;
/* begin scanning format specifier list */
for(; *fmt; fmt++)
{
switch(state)
{
/* STATE 0: AWAITING % */
case 0:
if(*fmt != '%') /* not %... */
{
fn(*fmt, &ptr); /* ...just echo it */
count++;
break;
}
/* found %, get next char and advance state to check if next char is a flag */
state++;
fmt++;
/* FALL THROUGH */
/* STATE 1: AWAITING FLAGS (%-0) */
case 1:
if(*fmt == '%') /* %% */
{
fn(*fmt, &ptr);
count++;
state = flags = given_wd = 0;
break;
}
if(*fmt == '-')
{
if(flags & PR_LJ)/* %-- is illegal */
state = flags = given_wd = 0;
else
flags |= PR_LJ;
break;
}
/* not a flag char: advance state to check if it's field width */
state++;
/* check now for '%0...' */
if(*fmt == '0')
{
flags |= PR_LZ;
fmt++;
}
/* FALL THROUGH */
/* STATE 2: AWAITING (NUMERIC) FIELD WIDTH */
case 2:
if(*fmt >= '0' && *fmt <= '9')
{
given_wd = 10 * given_wd +
(*fmt - '0');
break;
}
/* not field width: advance state to check if it's a modifier */
state++;
/* FALL THROUGH */
/* STATE 3: AWAITING MODIFIER CHARS (FNlh) */
case 3:
if(*fmt == 'F')
{
flags |= PR_FP;
break;
}
if(*fmt == 'N')
break;
if(*fmt == 'l')
{
flags |= PR_32;
break;
}
if(*fmt == 'h')
{
flags |= PR_16;
break;
}
/* not modifier: advance state to check if it's a conversion char */
state++;
/* FALL THROUGH */
/* STATE 4: AWAITING CONVERSION CHARS (Xxpndiuocs) */
case 4:
where = buf + PR_BUFLEN - 1;
*where = '\0';
switch(*fmt)
{
case 'X':
flags |= PR_CA;
/* FALL THROUGH */
/* xxx - far pointers (%Fp, %Fn) not yet supported */
case 'x':
case 'p':
case 'n':
radix = 16;
goto DO_NUM;
case 'd':
case 'i':
flags |= PR_SG;
/* FALL THROUGH */
case 'u':
radix = 10;
goto DO_NUM;
case 'o':
radix = 8;
/* load the value to be printed. l=long=32 bits: */
DO_NUM: if(flags & PR_32)
num = va_arg(args, unsigned long);
/* h=short=16 bits (signed or unsigned) */
else if(flags & PR_16)
{
if(flags & PR_SG)
num = va_arg(args, unsigned long);
else
num = va_arg(args, unsigned long);
}
/* no h nor l: sizeof(int) bits (signed or unsigned) */
else
{
if(flags & PR_SG)
num = va_arg(args, unsigned long);
else
num = va_arg(args, unsigned long);
}
/* take care of sign */
if(flags & PR_SG)
{
if(num < 0)
{
flags |= PR_WS;
num = -num;
}
}
/* convert binary to octal/decimal/hex ASCII
OK, I found my mistake. The math here is _always_ unsigned */
do
{
unsigned long temp;
temp = (unsigned long)num % radix;
where--;
if(temp < 10)
*where = temp + '0';
else if(flags & PR_CA)
*where = temp - 10 + 'A';
else
*where = temp - 10 + 'a';
num = (unsigned long)num / radix;
}
while(num != 0);
goto EMIT;
case 'c':
/* disallow pad-left-with-zeroes for %c */
flags &= ~PR_LZ;
where--;
*where = (unsigned char)va_arg(args,
unsigned int);
actual_wd = 1;
goto EMIT2;
case 's':
/* disallow pad-left-with-zeroes for %s */
flags &= ~PR_LZ;
where = (unsigned char *)va_arg(args, unsigned int);
EMIT:
actual_wd = strlen((const char *)where);
if(flags & PR_WS)
actual_wd++;
/* if we pad left with ZEROES, do the sign now */
if((flags & (PR_WS | PR_LZ)) ==
(PR_WS | PR_LZ))
{
fn('-', &ptr);
count++;
}
/* pad on left with spaces or zeroes (for right justify) */
EMIT2: if((flags & PR_LJ) == 0)
{
while(given_wd > actual_wd)
{
fn(flags & PR_LZ ? '0' :
' ', &ptr);
count++;
given_wd--;
}
}
/* if we pad left with SPACES, do the sign now */
if((flags & (PR_WS | PR_LZ)) == PR_WS)
{
fn('-', &ptr);
count++;
}
/* emit string/char/converted number */
while(*where != '\0')
{
fn(*where++, &ptr);
count++;
}
/* pad on right with spaces (for left justify) */
if(given_wd < actual_wd)
given_wd = 0;
else given_wd -= actual_wd;
for(; given_wd; given_wd--)
{
fn(' ', &ptr);
count++;
}
break;
default:
break;
}
default:
state = flags = given_wd = 0;
break;
}
}
return count;
}

View File

@@ -0,0 +1,8 @@
#ifndef __DO_PRINTF_H__
#define __DO_PRINTF_H__
#include <stdarg.h> /* va_list, va_arg() */
typedef int (*fnptr_t)(unsigned c, void **helper);
int do_printf(const char *fmt, va_list args, fnptr_t fn, void *ptr);
#endif /* __DO_PRINTF_H__ */

View File

@@ -0,0 +1,73 @@
#include "uart/uart.h"
#include "rtdef.h"
#include "rtthread.h"
#include <stdio.h>
__attribute__((used))
int fgetc(FILE *stream)
{
int c;
while (!drv_uart_is_kbd_hit()) {
rt_thread_delay(1);
}
c = drv_uart_get_char();
if (c == '\r')
c = '\n';
fputc(c, stream);
return c;
}
__attribute__((used))
char *fgets(char *s, int size, FILE *stream)
{
char *p = s;
int i = 0;
for (i = 0; i < size - 1; i++){
int c = fgetc(stream);
if(c == '\n'){
*p++ = '\n';
break;
}
else if(c == '\0'){
break;
}
else if(c < 0){
return (void*)0;
}
else{
*p++ = c;
}
}
*p = '\0';
return s;
}
__attribute__((used))
int getc(FILE *stream)
{
return fgetc(stream);
}
__attribute__((used))
int getchar(void)
{
return fgetc((void*)0);
}
__attribute__((used))
int ungetc(int c, FILE *stream);

View File

@@ -0,0 +1,520 @@
#include <stdio.h>
#include "ndsvfs.h"
#include "dirent.h"
__attribute__((used))
FILE *fopen(const char *path_name, const char *mode)
{
NDSVFS_DENTRY *vde = HAL_NULL;
NDSVFS_FILE *file = HAL_NULL;
UINT32 mode_len;
UINT32 fmode = 0;
UINT32 i;
if (HAL_SUCCESS != _ndsvfs_lock())
return HAL_NULL;
// alloc file object
file = _ndsvfs_alloc_file();
if (file == HAL_NULL)
goto _safe_exit;
// open flags
if (mode == HAL_NULL)
mode_len = 0;
else
mode_len = (UINT32)strlen(mode);
for (i = 0; i < mode_len; ++i)
{
switch (mode[i])
{
case 'r':
fmode |= NDSVFS_FOPEN_READ;
break;
case 'w':
fmode |= NDSVFS_FOPEN_WRITE;
break;
case 'a':
fmode |= NDSVFS_FOPEN_APPEND;
break;
case '+':
fmode |= NDSVFS_FOPEN_PLUS;
break;
}
}
if (fmode == 0)
goto _safe_exit;
#if 0
// (todo) current imp should be read only
if (fmode & ~NDSVFS_FOPEN_READ)
goto _safe_exit;
if (!(fmode & NDSVFS_FOPEN_READ))
goto _safe_exit;
// ~(todo)
#endif
// lookup file entry
if (path_name == HAL_NULL)
goto _safe_exit;
if ((INT)strlen(path_name) == 0)
goto _safe_exit;
vde = _ndsvfs_path_lookup((const char *)path_name);
if (!vde)
{
// (todo) create the file if not exist and flag is not read only
goto _safe_exit;
}
// current imp allows only regular file
// we can open dir now, so I comments the codes
#if 0
if (vde->inode->mode & NDSVFS_INM_ATTR_MASK)
goto _safe_exit;
#endif
// notify file system to open the file
// (todo) call this only when user mode reference to the file is 0.
if (HAL_SUCCESS != vde->sb->open_file(vde, fmode))
goto _safe_exit;
file->flags = fmode;
file->vde = vde;
//file->pos = 0;
//DEBUG(0, 1,"fopen() 0x%08lx\r\n", (UINT32)file);
_ndsvfs_unlock();
// todo
return (FILE *)file;
_safe_exit:
if (vde)
NDSVFS_DEREF(vde);
file->vde = HAL_NULL;
if (file)
NDSVFS_DEREF(file);
_ndsvfs_unlock();
return HAL_NULL;
}
__attribute__((used))
int fclose(FILE *stream)
{
if (stream == HAL_NULL)
return (int)-NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
//DEBUG(0, 1,"fclose() 0x%08lx\r\n", (UINT32)stream);
// (todo) flush the file contents if ever been modified
// notify file system to close the file
// (todo) call this only when user mode reference to the file decreased to 0.
((NDSVFS_FILE *)stream)->vde->sb->close_file(((NDSVFS_FILE *)stream)->vde);
// release file references
if (stream)
NDSVFS_DEREF(stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
size_t fread(void *ptr, size_t size, size_t count, FILE *stream)
{
STATUS status;
UINT32 d_size = (UINT32)size * (UINT32)count;
UINT32 r_size; // size actually been read
#if 1
DEBUG(0, 1,"fread() 0x%08lx ptr(0x%08lx) size(0x%08lx) count(0x%08lx)\r\n",
(UINT32)stream, (UINT32)ptr, (UINT32)size, (UINT32)count);
#endif
if (stream == HAL_NULL)
{
((NDSVFS_FILE *)stream)->err = NDS_VFSD_INVALID_PARAMETER;
return 0;
}
if (HAL_SUCCESS != _ndsvfs_lock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
return 0;
}
DEBUG(0, 1,"fread() 0x%08lx >>\r\n", (UINT32)stream);
if (((NDSVFS_FILE *)stream)->pos < 0)
{
DEBUG(0, 1,"fread() 0x%08lx <<\r\n", (UINT32)stream);
_ndsvfs_unlock();
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_START;
return 0;
}
status = ((NDSVFS_FILE *)stream)->vde->sb->read_file(((NDSVFS_FILE *)stream)->vde,
ptr, (UINT32)((NDSVFS_FILE *)stream)->pos, d_size, &r_size);
if (status == NDS_VFSD_END_OF_FILE)
{
((NDSVFS_FILE *)stream)->eof = HAL_TRUE;
status = HAL_SUCCESS;
}
if (status == HAL_SUCCESS)
((NDSVFS_FILE *)stream)->pos += (INT32)r_size;
else
r_size = 0;
DEBUG(0, 1,"fread() 0x%08lx <<\r\n", (UINT32)stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
DEBUG(0, 1,"fread() 0x%08lx << unlock fail\r\n", (UINT32)stream);
return 0;
}
return (int)((size_t)r_size / size);
}
__attribute__((used))
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream)
{
STATUS status;
UINT32 d_size = (UINT32)size * (UINT32)count;
UINT32 w_size; // size actually been write
#if 1
DEBUG(0, 1,"fwrite() 0x%08lx ptr(0x%08lx) size(0x%08lx) count(0x%08lx)\r\n",
(UINT32)stream, (UINT32)ptr, (UINT32)size, (UINT32)count);
#endif
if (stream == HAL_NULL)
{
((NDSVFS_FILE *)stream)->err = NDS_VFSD_INVALID_PARAMETER;
return 0;
}
if (HAL_SUCCESS != _ndsvfs_lock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
return 0;
}
DEBUG(0, 1,"fwrite() 0x%08lx >>\r\n", (UINT32)stream);
if (((NDSVFS_FILE *)stream)->pos < 0)
{
DEBUG(0, 1,"fwrite() 0x%08lx <<\r\n", (UINT32)stream);
_ndsvfs_unlock();
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_START;
return 0;
}
status = ((NDSVFS_FILE *)stream)->vde->sb->write_file(((NDSVFS_FILE *)stream)->vde,
ptr, (UINT32)((NDSVFS_FILE *)stream)->pos, d_size, &w_size);
if (status == NDS_VFSD_END_OF_FILE)
{
((NDSVFS_FILE *)stream)->eof = HAL_TRUE;
status = HAL_SUCCESS;
}
if (status == HAL_SUCCESS)
((NDSVFS_FILE *)stream)->pos += (INT32)w_size;
else
w_size = 0;
DEBUG(0, 1,"fwrite() 0x%08lx <<\r\n", (UINT32)stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
{
((NDSVFS_FILE *)stream)->err = HAL_ERR_INVALID_OPERATION;
DEBUG(0, 1,"fwrite() 0x%08lx << unlock fail\r\n", (UINT32)stream);
return 0;
}
return (int)((size_t)w_size / size);
}
__attribute__((used))
int fflush(FILE *stream)
{
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
// todo
return (int)HAL_SUCCESS;
}
__attribute__((used))
int fseek(FILE *stream, int offset, int origin)
{
INT32 pos;
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
pos = ((NDSVFS_FILE *)stream)->pos;
//DEBUG(0, 1,"fseek() 0x%08lx >>\r\n", (UINT32)stream);
//DEBUG(0, 1,"pos (cur) : 0x%08lx\r\n", pos);
//DEBUG(0, 1,"offset : 0x%08lx\r\n", offset);
switch (origin)
{
case FSEEK_CUR:
pos += offset;
break;
case FSEEK_END:
pos = (INT32)((NDSVFS_FILE *)stream)->vde->inode->size + offset;
break;
case FSEEK_SET:
pos = offset;
break;
default:
//DEBUG(0, 1,"fseek() 0x%08lx <<\r\n", (UINT32)stream);
_ndsvfs_unlock();
return (int)NDS_VFSD_INVALID_PARAMETER;
}
//DEBUG(0, 1,"pos (new) : 0x%08lx\r\n", pos);
/*
if (pos > ((NDSVFS_FILE *)stream)->vde->inode->size)
{
_ndsvfs_unlock();
return (int)NDS_VFSD_INVALID_PARAMETER; // todo: might be a valid condition for write-mode
}*/
((NDSVFS_FILE *)stream)->pos = pos;
//DEBUG(0, 1,"fseek() 0x%08lx <<\r\n", (UINT32)stream);
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
long ftell(FILE *stream)
{
long pos;
if (stream == HAL_NULL)
return (int)HAL_ERR_INVALID_OPERATION;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
pos = (long)((NDSVFS_FILE *)stream)->pos;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return pos;
}
void frewind(FILE *stream)
{
if (stream == HAL_NULL)
return;
if (HAL_SUCCESS != _ndsvfs_lock())
return;
((NDSVFS_FILE *)stream)->pos = 0;
((NDSVFS_FILE *)stream)->err = 0;
((NDSVFS_FILE *)stream)->eof = 0;
if (HAL_SUCCESS != _ndsvfs_unlock())
return;
}
__attribute__((used))
int fgetpos(FILE *stream, fpos_t *position)
{
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (position == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
*position = ((NDSVFS_FILE *)stream)->pos;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
int fsetpos(FILE *stream, const fpos_t *position)
{
if (stream == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (position == HAL_NULL)
return (int)NDS_VFSD_INVALID_PARAMETER;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
if (*position > (INT32)((NDSVFS_FILE *)stream)->vde->inode->size)
{
_ndsvfs_unlock();
return (int)NDS_VFSD_INVALID_PARAMETER; // todo: might be a valid condition for write-mode
}
((NDSVFS_FILE *)stream)->pos = *position;
((NDSVFS_FILE *)stream)->eof = 0; // ?? todo: signal eof if position reaches end of file?
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return (int)HAL_SUCCESS;
}
__attribute__((used))
int feof(FILE *stream)
{
UINT32 eof;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
eof = ((NDSVFS_FILE *)stream)->eof > 0 ? HAL_TRUE : HAL_FALSE;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return eof;
}
__attribute__((used))
int ferror(FILE *stream)
{
UINT32 err;
if (HAL_SUCCESS != _ndsvfs_lock())
return (int)HAL_ERR_INVALID_OPERATION;
err = ((NDSVFS_FILE *)stream)->err > 0 ? 1 : 0;
if (HAL_SUCCESS != _ndsvfs_unlock())
return (int)HAL_ERR_INVALID_OPERATION;
return err;
}
void fclearerr(FILE *stream)
{
if (HAL_SUCCESS != _ndsvfs_lock())
return;
((NDSVFS_FILE *)stream)->err = 0;
((NDSVFS_FILE *)stream)->eof = 0;
if (HAL_SUCCESS != _ndsvfs_unlock())
return;
}
extern STATUS _ndsvfs_read_dirs(NDSVFS_DENTRY *vde_parent, NDSVFS_DENTRY **vde_list);
__attribute__((used))
struct dir *opendir(const char *path)
{
NDSVFS_FILE *file = NULL;
struct dir *dirp = NULL;
int status;
file = (NDSVFS_FILE *)fopen(path, "rb");
if (file == NULL) {
// ERROR("fopen path=%s\n",path);
return (void*)0;
}
if (!S_ISDIR(file->vde->inode)){
fclose((FILE *)file);
// ERROR("Not a dir path=%s\n",path);
return (void*)0;
}
if (!file->dirp){
file->dirp = malloc(sizeof(struct dir));
KASSERT(file->dirp);
dirp = (struct dir*)file->dirp;
dirp->d_dirent = malloc(sizeof(struct dirent));
KASSERT(dirp->d_dirent);
dirp->d_file = file;
dirp->d_off = 0;
}
status = _ndsvfs_read_dirs(file->vde, &(dirp->vde_list));
dirp->vde_head = dirp->vde_list;
dirp->vde_list = NULL;
if(status == HAL_FAILURE)
return HAL_NULL;
return dirp;
}
__attribute__((used))
int closedir(struct dir *dirp)
{
NDSVFS_FILE *file = dirp->d_file;
if (dirp == NULL)
return -1;
if (file == NULL)
return -1;
if (dirp->d_dirent != NULL)
free(dirp->d_dirent);
free(dirp);
return fclose((FILE *)file);
}
__attribute__((used))
struct dirent *readdir(struct dir *dirp)
{
/* this is the first time, becasue the vde_list is pointed to null */
if (dirp->vde_list == NULL && dirp->vde_head != NULL) {
strcpy(dirp->d_dirent->d_name, dirp->vde_head->name.utf_name);
dirp->vde_list = NDS_LIST_ENTITY(dirp->vde_head->c_chain.next, NDSVFS_DENTRY, c_chain);
return dirp->d_dirent;
}
/* this is not the first time. */
else if (dirp->vde_list != dirp->vde_head) {
strcpy(dirp->d_dirent->d_name, dirp->vde_list->name.utf_name);
dirp->vde_list = NDS_LIST_ENTITY(dirp->vde_list->c_chain.next, NDSVFS_DENTRY, c_chain);
return dirp->d_dirent;
}
else
return NULL;
}
__attribute__((used))
int fstat(FILE* fd, struct stat *buf)
{
NDSVFS_FILE *file = (NDSVFS_FILE *)fd;
if (file == HAL_NULL)
return -1;
return file->vde->sb->stat_file(file->vde, buf);
}

View File

@@ -0,0 +1,14 @@
#include <stdio.h>
__attribute__((used))
int fprintf(FILE *stream, const char *fmt, ...)
{
va_list args;
int ret_val;
va_start(args, fmt);
ret_val = vprintf(fmt, args);
va_end(args);
return ret_val;
}

View File

@@ -0,0 +1,41 @@
#include "uart/uart.h"
#include <stdio.h>
__attribute__((used))
int fputc(int c, FILE *stream)
{
if (c == '\n')
drv_uart_put_char('\r');
drv_uart_put_char(c);
return c;
}
__attribute__((used))
int fputs(const char *s, FILE *stream)
{
while (fputc(*s++, stream))
;
return 0;
}
__attribute__((used))
int putc(int c, FILE *stream)
{
return fputc(c, stream);
}
__attribute__((used))
int putchar(int c)
{
return fputc(c, (void*)0x10);
}
__attribute__((used))
int puts(const char *s)
{
return fputs(s, (void*)0x10);
}

View File

@@ -0,0 +1,65 @@
#include <stdarg.h> /* va_list, va_arg() */
#include <stdio.h>
#include "do_printf.h"
/*****************************************************************************
* PRINTF You must write your own putchar()
*****************************************************************************/
static int vprintf_help(unsigned c, void **ptr){
ptr = ptr; /* to avoid unused varible warning */
putchar(c);
return 0;
}
static int vsprintf_help(unsigned int c, void **ptr){
char *dst = *ptr;
*dst++ = c;
*ptr = dst;
return 0 ;
}
__attribute__((used))
int vsprintf(char *buffer, const char *fmt, va_list args){
int ret_val = do_printf(fmt, args, vsprintf_help, (void *)buffer);
buffer[ret_val] = '\0';
return ret_val;
}
__attribute__((used))
int sprintf(char *buffer, const char *fmt, ...){
va_list args;
int ret_val;
va_start(args, fmt);
ret_val = vsprintf(buffer, fmt, args);
va_end(args);
return ret_val;
}
__attribute__((used))
int vprintf(const char *fmt, va_list args){
return do_printf(fmt, args, vprintf_help, (void *)0);
}
__attribute__((used))
int printf(const char *fmt, ...){
va_list args;
int ret_val;
va_start(args, fmt);
ret_val = vprintf(fmt, args);
va_end(args);
return ret_val;
}

View File

@@ -0,0 +1 @@
lib-y += qsort.o

View File

@@ -0,0 +1,149 @@
//
// qsort.c
//
// Quick sort
//
// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
#define CUTOFF 8
static void shortsort(char *lo, char *hi, unsigned width, int (*comp)(const void *, const void *));
static void swap(char *p, char *q, unsigned int width);
__attribute__((used))
void qsort(void *base, unsigned num, unsigned width, int (*comp)(const void *, const void *))
{
char *lo, *hi;
char *mid;
char *loguy, *higuy;
unsigned size;
char *lostk[30], *histk[30];
int stkptr;
if (num < 2 || width == 0) return;
stkptr = 0;
lo = base;
hi = (char *) base + width * (num - 1);
recurse:
size = (hi - lo) / width + 1;
if (size <= CUTOFF)
{
shortsort(lo, hi, width, comp);
}
else
{
mid = lo + (size / 2) * width;
swap(mid, lo, width);
loguy = lo;
higuy = hi + width;
for (;;)
{
do { loguy += width; } while (loguy <= hi && comp(loguy, lo) <= 0);
do { higuy -= width; } while (higuy > lo && comp(higuy, lo) >= 0);
if (higuy < loguy) break;
swap(loguy, higuy, width);
}
swap(lo, higuy, width);
if (higuy - 1 - lo >= hi - loguy)
{
if (lo + width < higuy)
{
lostk[stkptr] = lo;
histk[stkptr] = higuy - width;
++stkptr;
}
if (loguy < hi)
{
lo = loguy;
goto recurse;
}
}
else
{
if (loguy < hi)
{
lostk[stkptr] = loguy;
histk[stkptr] = hi;
++stkptr;
}
if (lo + width < higuy)
{
hi = higuy - width;
goto recurse;
}
}
}
--stkptr;
if (stkptr >= 0)
{
lo = lostk[stkptr];
hi = histk[stkptr];
goto recurse;
}
else
return;
}
static void shortsort(char *lo, char *hi, unsigned width, int (*comp)(const void *, const void *))
{
char *p, *max;
while (hi > lo)
{
max = lo;
for (p = lo+width; p <= hi; p += width) if (comp(p, max) > 0) max = p;
swap(max, hi, width);
hi -= width;
}
}
static void swap(char *a, char *b, unsigned width)
{
char tmp;
if (a != b)
{
while (width--)
{
tmp = *a;
*a++ = *b;
*b++ = tmp;
}
}
}

View File

@@ -0,0 +1,12 @@
lib-y += memcpy.o
lib-y += memmove.o
lib-y += memset.o
lib-y += strcat.o
lib-y += strcasecmp.o
lib-y += strcmp.o
lib-y += strdup.o
lib-y += strlen.o
lib-y += strstr.o
lib-y += strtoul.o
lib-y += strupr.o
lib-y += wchar.o

View File

@@ -0,0 +1,10 @@
#include <string.h>
__attribute__((used))
void *memcpy(void *dest, const void *src, size_t n)
{
while (n--)
*(unsigned char *)dest++ = *(const unsigned char *)src++;
return dest;
}

View File

@@ -0,0 +1,17 @@
#include <string.h>
__attribute__((used))
void *memmove(void *dest, const void *src, size_t n)
{
char *destp = dest;
const char *srcp = src;
if (srcp < destp)
while (n--)
destp[n] = srcp[n];
else
while (n--)
*destp++ = *srcp++;
return dest;
}

View File

@@ -0,0 +1,10 @@
#include <string.h>
__attribute__((used))
void *memset(void *s, int c, size_t n)
{
while (n--)
*(unsigned char *)s++ = c;
return s;
}

View File

@@ -0,0 +1,30 @@
#include <string.h>
__attribute__((used))
int strcasecmp(const char *s1, const char *s2)
{
while (*s1 == *s2 || (*s1 ^ 0x20) == *s2) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
__attribute__((used))
int strncasecmp(const char *s1, const char *s2, size_t n)
{
while ((*s1 == *s2 || (*s1 ^ 0x20) == *s2) && --n) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}

View File

@@ -0,0 +1,33 @@
#include <string.h>
__attribute__((used))
char *strcat(char *dest, const char *src)
{
char *destp = dest;
while (*destp)
destp++;
while (*src)
*destp++ = *src++;
*destp = '\0';
return dest;
}
__attribute__((used))
char *strncat(char *dest, const char *src, size_t n)
{
char *destp = dest;
while (*destp)
destp++;
while (*src && n--)
*destp++ = *src++;
*destp = '\0';
return dest;
}

View File

@@ -0,0 +1,30 @@
#include <string.h>
__attribute__((used))
int strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
__attribute__((used))
int strncmp(const char *s1, const char *s2, size_t n)
{
while (*s1 == *s2 && --n) {
if (!*s1)
return 0;
++s1;
++s2;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}

View File

@@ -0,0 +1,30 @@
#include <string.h>
__attribute__((used))
char *strcpy(char *dest, const void *src)
{
char *destp = dest;
char *srcp = (char *)src;
while (*srcp)
*destp++ = *srcp++;
*destp = '\0';
return dest;
}
__attribute__((used))
char *strncpy(char *dest, const void *src, size_t n)
{
char *destp = dest;
char *srcp = (char *)src;
while (*srcp && n--)
*destp++ = *srcp++;
if (n)
*destp = '\0';
return dest;
}

View File

@@ -0,0 +1,32 @@
#include <string.h>
#include <stdlib.h>
__attribute__((used))
char *strdup(const char *s)
{
int len = strlen(s);
char *buf = malloc(len + 1);
if (buf) {
strncpy(buf, s, len);
buf[len] = '\0';
}
return buf;
}
__attribute__((used))
char *strndup(const char *s, size_t n)
{
int len = strnlen(s, n);
char *buf = malloc(len + 1);
if (buf) {
strncpy(buf, s, len);
buf[len] = '\0';
}
return buf;
}

View File

@@ -0,0 +1,23 @@
#include <string.h>
__attribute__((used))
size_t strlen(const char *s)
{
size_t n = 0;
while (*s++)
n++;
return n;
}
__attribute__((used))
size_t strnlen(const char *s, size_t maxlen)
{
size_t n = 0;
while (*s++ && maxlen--)
n++;
return n;
}

View File

@@ -0,0 +1,45 @@
#include <string.h>
/* FIXME: LICENSE */
__attribute__((used))
char *strstr(const char *haystack, const char *needle)
{
const char *start_s1 = (void *)0;
const char *in_s2 = (void *)0;
for (; *haystack != '\0'; haystack++) {
if (!start_s1) {
/* first char of match */
if (*haystack == *needle) {
/* remember start of matching substring in haystack */
start_s1 = haystack;
in_s2 = needle + 1;
/* done already? */
if (*in_s2 == '\0')
return (char*)start_s1;
}
/* continued mis-match
else
nothing ; */
}
else {
/* continued match */
if (*haystack == *in_s2) {
in_s2++;
/* done */
if (*in_s2 == '\0')
return (char*)start_s1;
}
else
/* first char of mis-match */
start_s1 = (void *)0;
}
}
return (void *)0;
}

View File

@@ -0,0 +1,82 @@
#include <string.h>
#include <ctype.h>
/* FIXME: LICENSE */
__attribute__((used))
unsigned long int strtoul(const char *nptr, char **endptr, int base)
{
const char *s;
unsigned long acc, cutoff;
int c;
int neg, any, cutlim;
s = nptr;
do
c = *s++;
while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
}
else {
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
#ifndef ULONG_MAX
#define ULONG_MAX (unsigned long) -1
#endif
cutoff = ULONG_MAX / (unsigned long)base;
cutlim = ULONG_MAX % (unsigned long)base;
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0)
continue;
// FIXME
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1;
acc = ULONG_MAX;
}
else {
any = 1;
acc *= (unsigned long)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != 0)
*endptr = (char *)(any ? s - 1 : nptr);
return acc;
}

View File

@@ -0,0 +1,16 @@
#include <string.h>
__attribute__((used))
char *strupr(char *str)
{
char *str_iter = str;
while (*str_iter != 0)
{
if ((*str_iter >= 'a') && (*str_iter <= 'z'))
*str_iter -= 0x20;
++str_iter;
}
return str;
}

View File

@@ -0,0 +1,147 @@
#include <string.h>
__attribute__((used))
wchar_t *wcscat(wchar_t *str_dst, const wchar_t *str_src)
{
wchar_t *dst_iter = str_dst;
int i = 0;
while (*dst_iter != 0)
++dst_iter;
while (str_src[i] != 0)
{
dst_iter[i] = str_src[i];
++i;
}
dst_iter[i] = 0;
return str_dst;
}
__attribute__((used))
int wcscmp(const wchar_t *string1, const wchar_t *string2)
{
int i = 0;
register wchar_t c1, c2;
while (1)
{
c1 = string1[i];
c2 = string2[i];
if (c1 < c2)
{
return -1;
}
else if (c1 > c2)
{
return 1;
}
if ((c1 == 0) || (c2 == 0))
break;
++i;
}
return 0;
}
__attribute__((used))
int wcsncmp(const wchar_t *string1, const wchar_t *string2, int count)
{
int i = 0;
while (i < count)
{
if (string1[i] < string2[i])
{
return -1;
}
else if (string1[i] > string2[i])
{
return 1;
}
if ((string1[i] == 0) || (string2[i] == 0))
break;
++i;
}
return 0;
}
__attribute__((used))
wchar_t *wcscpy(wchar_t *str_dst, const wchar_t *str_src)
{
int i = 0;
while (str_src[i] != 0)
{
str_dst[i] = str_src[i];
++i;
}
str_dst[i] = 0;
return str_dst;
}
__attribute__((used))
wchar_t *wcsncpy(wchar_t *str_dst, const wchar_t *str_src, int count)
{
int i = 0;
while ((str_src[i] != 0) && (i < count))
{
str_dst[i] = str_src[i];
++i;
}
str_dst[i] = 0;
return str_dst;
}
__attribute__((used))
int wcslen(const wchar_t *str)
{
int i = 0;
while (str[i] != 0)
++i;
return i;
}
__attribute__((used))
wchar_t *wcsupr(wchar_t *str)
{
wchar_t *str_iter = str;
while (*str_iter != 0)
{
if ((*str_iter >= (wchar_t)'a') && (*str_iter <= (wchar_t)'z'))
*str_iter -= 0x0020;
++str_iter;
}
return str;
}
__attribute__((used))
wchar_t *wcslwr(wchar_t *str)
{
wchar_t *str_iter = str;
while (*str_iter != 0)
{
if ((*str_iter <= (wchar_t)'Z') && (*str_iter >= (wchar_t)'A'))
*str_iter += 0x0020;
++str_iter;
}
return str;
}

80
bsp/AE210P/nds32.h Normal file
View File

@@ -0,0 +1,80 @@
#ifndef __NDS32_H__
#define __NDS32_H__
#include "nds32_defs.h"
/* Support FPU */
#if defined(__NDS32_EXT_FPU_DP__) || defined(__NDS32_EXT_FPU_SP__)
#define __TARGET_FPU_EXT
#if defined(__NDS32_EXT_FPU_CONFIG_0__)
#define FPU_REGS 8
#elif defined(__NDS32_EXT_FPU_CONFIG_1__)
#define FPU_REGS 16
#elif defined(__NDS32_EXT_FPU_CONFIG_2__)
#define FPU_REGS 32
#elif defined(__NDS32_EXT_FPU_CONFIG_3__)
#define FPU_REGS 64
#else
#error FPU register numbers no defined
#endif
#endif
/* Support IFC */
#ifdef __NDS32_EXT_IFC__
#ifndef CONFIG_NO_NDS32_EXT_IFC
#define __TARGET_IFC_EXT
#endif
#endif
/* Support ZOL */
#ifdef CONFIG_HWZOL
#define __TARGET_ZOL_EXT
#endif
#ifndef __ASSEMBLER__
#include "nds32_intrinsic.h"
#define GIE_ENABLE() __nds32__gie_en()
#define GIE_DISABLE() __nds32__gie_dis()
#ifdef CONFIG_CPU_DCACHE_ENABLE
#define NDS_DCache_Flush nds32_dcache_flush
#define NDS_DCache_Invalidate_Flush nds32_dcache_invalidate
#define NDS_DCache_Writeback nds32_dcache_flush_range
#else
#define NDS_DCache_Flush() ((void)0)
#define NDS_DCache_Invalidate_Flush() ((void)0)
#define NDS_DCache_Writeback() ((void)0)
#endif
static inline void GIE_SAVE(unsigned long *var)
{
*var = __nds32__mfsr(NDS32_SR_PSW);
GIE_DISABLE();
}
static inline void GIE_RESTORE(unsigned long var)
{
if (var & PSW_mskGIE)
GIE_ENABLE();
}
extern void *OS_CPU_Vector_Table[32];
typedef void (*isr_t)(int vector);
static inline void register_isr(int vector, isr_t isr, isr_t *old)
{
if (old)
*old = OS_CPU_Vector_Table[vector];
OS_CPU_Vector_Table[vector] = isr;
}
#endif /* __ASSEMBLER__ */
#endif /* __NDS32_H__ */

1362
bsp/AE210P/nds32_defs.h Normal file

File diff suppressed because it is too large Load Diff

426
bsp/AE210P/os_cpu_common.h Normal file
View File

@@ -0,0 +1,426 @@
#include "nds32.h"
.set regno, 0
#ifdef __TARGET_IFC_EXT
.set regno, regno+1
#endif
#ifdef __TARGET_ZOL_EXT
.set regno, regno+3
#endif
/* Descend PSW.INTL and enable PSW.AEN */
.macro IntlDescend
mfsr $r1, $PSW
#ifdef __TARGET_ZOL_EXT
/* Also enable ZOL (PSW.AEN) */
xori $r1, $r1, #((1 << 13) | (1 << 1))
#else
addi $r1, $r1, #-2
#endif
mtsr $r1, $PSW
.endm
/* FPU registers */
.macro SAVE_FPU_REGS_00
fsdi.bi $fd3, [$sp], -8
fsdi.bi $fd2, [$sp], -8
fsdi.bi $fd1, [$sp], -8
fsdi $fd0, [$sp+0]
.endm
.macro SAVE_FPU_REGS_01
fsdi.bi $fd7, [$sp], -8
fsdi.bi $fd6, [$sp], -8
fsdi.bi $fd5, [$sp], -8
fsdi.bi $fd4, [$sp], -8
SAVE_FPU_REGS_00
.endm
.macro SAVE_FPU_REGS_02
fsdi.bi $fd15, [$sp], -8
fsdi.bi $fd14, [$sp], -8
fsdi.bi $fd13, [$sp], -8
fsdi.bi $fd12, [$sp], -8
fsdi.bi $fd11, [$sp], -8
fsdi.bi $fd10, [$sp], -8
fsdi.bi $fd9, [$sp], -8
fsdi.bi $fd8, [$sp], -8
SAVE_FPU_REGS_01
.endm
.macro SAVE_FPU_REGS_03
fsdi.bi $fd31, [$sp], -8
fsdi.bi $fd30, [$sp], -8
fsdi.bi $fd29, [$sp], -8
fsdi.bi $fd28, [$sp], -8
fsdi.bi $fd27, [$sp], -8
fsdi.bi $fd26, [$sp], -8
fsdi.bi $fd25, [$sp], -8
fsdi.bi $fd24, [$sp], -8
fsdi.bi $fd23, [$sp], -8
fsdi.bi $fd22, [$sp], -8
fsdi.bi $fd21, [$sp], -8
fsdi.bi $fd20, [$sp], -8
fsdi.bi $fd19, [$sp], -8
fsdi.bi $fd18, [$sp], -8
fsdi.bi $fd17, [$sp], -8
fsdi.bi $fd16, [$sp], -8
SAVE_FPU_REGS_02
.endm
.macro push_fpu
#if defined(__NDS32_EXT_FPU_CONFIG_0__)
addi $sp, $sp, -8
SAVE_FPU_REGS_00
#elif defined(__NDS32_EXT_FPU_CONFIG_1__)
addi $sp, $sp, -8
SAVE_FPU_REGS_01
#elif defined(__NDS32_EXT_FPU_CONFIG_2__)
addi $sp, $sp, -8
SAVE_FPU_REGS_02
#elif defined(__NDS32_EXT_FPU_CONFIG_3__)
addi $sp, $sp, -8
SAVE_FPU_REGS_03
#else
#endif
.endm
.macro RESTORE_FPU_REGS_00
fldi.bi $fd0, [$sp], 8
fldi.bi $fd1, [$sp], 8
fldi.bi $fd2, [$sp], 8
fldi.bi $fd3, [$sp], 8
.endm
.macro RESTORE_FPU_REGS_01
RESTORE_FPU_REGS_00
fldi.bi $fd4, [$sp], 8
fldi.bi $fd5, [$sp], 8
fldi.bi $fd6, [$sp], 8
fldi.bi $fd7, [$sp], 8
.endm
.macro RESTORE_FPU_REGS_02
RESTORE_FPU_REGS_01
fldi.bi $fd8, [$sp], 8
fldi.bi $fd9, [$sp], 8
fldi.bi $fd10, [$sp], 8
fldi.bi $fd11, [$sp], 8
fldi.bi $fd12, [$sp], 8
fldi.bi $fd13, [$sp], 8
fldi.bi $fd14, [$sp], 8
fldi.bi $fd15, [$sp], 8
.endm
.macro RESTORE_FPU_REGS_03
RESTORE_FPU_REGS_02
fldi.bi $fd16, [$sp], 8
fldi.bi $fd17, [$sp], 8
fldi.bi $fd18, [$sp], 8
fldi.bi $fd19, [$sp], 8
fldi.bi $fd20, [$sp], 8
fldi.bi $fd21, [$sp], 8
fldi.bi $fd22, [$sp], 8
fldi.bi $fd23, [$sp], 8
fldi.bi $fd24, [$sp], 8
fldi.bi $fd25, [$sp], 8
fldi.bi $fd26, [$sp], 8
fldi.bi $fd27, [$sp], 8
fldi.bi $fd28, [$sp], 8
fldi.bi $fd29, [$sp], 8
fldi.bi $fd30, [$sp], 8
fldi.bi $fd31, [$sp], 8
.endm
.macro pop_fpu
#if defined(__NDS32_EXT_FPU_CONFIG_0__)
RESTORE_FPU_REGS_00
#elif defined(__NDS32_EXT_FPU_CONFIG_1__)
RESTORE_FPU_REGS_01
#elif defined(__NDS32_EXT_FPU_CONFIG_2__)
RESTORE_FPU_REGS_02
#elif defined(__NDS32_EXT_FPU_CONFIG_3__)
RESTORE_FPU_REGS_03
#else
#endif
.endm
/* FPU Caller registers */
.macro SAVE_FPU_CALLER_REGS_00
addi $sp, $sp, -8
fsdi.bi $fd2, [$sp], -8
fsdi.bi $fd1, [$sp], -8
fsdi $fd0, [$sp+0]
.endm
.macro SAVE_FPU_CALLER_REGS_01
SAVE_FPU_CALLER_REGS_00
.endm
.macro SAVE_FPU_CALLER_REGS_02
addi $sp, $sp, -8
fsdi.bi $fd15, [$sp], -8
fsdi.bi $fd14, [$sp], -8
fsdi.bi $fd13, [$sp], -8
fsdi.bi $fd12, [$sp], -8
fsdi.bi $fd11, [$sp], -8
fsdi.bi $fd2, [$sp], -8
fsdi.bi $fd1, [$sp], -8
fsdi $fd0, [$sp+0]
.endm
.macro SAVE_FPU_CALLER_REGS_03
addi $sp, $sp, -8
fsdi.bi $fd23, [$sp], -8
fsdi.bi $fd22, [$sp], -8
fsdi.bi $fd21, [$sp], -8
fsdi.bi $fd20, [$sp], -8
fsdi.bi $fd19, [$sp], -8
fsdi.bi $fd18, [$sp], -8
fsdi.bi $fd17, [$sp], -8
fsdi.bi $fd16, [$sp], -8
fsdi.bi $fd15, [$sp], -8
fsdi.bi $fd14, [$sp], -8
fsdi.bi $fd13, [$sp], -8
fsdi.bi $fd12, [$sp], -8
fsdi.bi $fd11, [$sp], -8
fsdi.bi $fd2, [$sp], -8
fsdi.bi $fd1, [$sp], -8
fsdi $fd0, [$sp+0]
.endm
.macro push_fpu_caller
#if defined(__NDS32_EXT_FPU_CONFIG_0__)
SAVE_FPU_CALLER_REGS_00
#elif defined(__NDS32_EXT_FPU_CONFIG_1__)
SAVE_FPU_CALLER_REGS_01
#elif defined(__NDS32_EXT_FPU_CONFIG_2__)
SAVE_FPU_CALLER_REGS_02
#elif defined(__NDS32_EXT_FPU_CONFIG_3__)
SAVE_FPU_CALLER_REGS_03
#else
#endif
.endm
.macro RESTORE_FPU_CALLER_REGS_00
fldi.bi $fd0, [$sp], 8
fldi.bi $fd1, [$sp], 8
fldi.bi $fd2, [$sp], 8
.endm
.macro RESTORE_FPU_CALLER_REGS_01
RESTORE_FPU_CALLER_REGS_00
.endm
.macro RESTORE_FPU_CALLER_REGS_02
fldi.bi $fd0, [$sp], 8
fldi.bi $fd1, [$sp], 8
fldi.bi $fd2, [$sp], 8
fldi.bi $fd11, [$sp], 8
fldi.bi $fd12, [$sp], 8
fldi.bi $fd13, [$sp], 8
fldi.bi $fd14, [$sp], 8
fldi.bi $fd15, [$sp], 8
.endm
.macro RESTORE_FPU_CALLER_REGS_03
fldi.bi $fd0, [$sp], 8
fldi.bi $fd1, [$sp], 8
fldi.bi $fd2, [$sp], 8
fldi.bi $fd11, [$sp], 8
fldi.bi $fd12, [$sp], 8
fldi.bi $fd13, [$sp], 8
fldi.bi $fd14, [$sp], 8
fldi.bi $fd15, [$sp], 8
fldi.bi $fd16, [$sp], 8
fldi.bi $fd17, [$sp], 8
fldi.bi $fd18, [$sp], 8
fldi.bi $fd19, [$sp], 8
fldi.bi $fd20, [$sp], 8
fldi.bi $fd21, [$sp], 8
fldi.bi $fd22, [$sp], 8
fldi.bi $fd23, [$sp], 8
.endm
.macro pop_fpu_caller
#if defined(__NDS32_EXT_FPU_CONFIG_0__)
RESTORE_FPU_CALLER_REGS_00
#elif defined(__NDS32_EXT_FPU_CONFIG_1__)
RESTORE_FPU_CALLER_REGS_01
#elif defined(__NDS32_EXT_FPU_CONFIG_2__)
RESTORE_FPU_CALLER_REGS_02
#elif defined(__NDS32_EXT_FPU_CONFIG_3__)
RESTORE_FPU_CALLER_REGS_03
#else
#endif
.endm
/* IFC system register */
.macro MFUSR_IFC R0="$r1"
mfusr \R0, $IFC_LP
.endm
.macro MTUSR_IFC R0="$r1"
mtusr \R0, $IFC_LP
.endm
/* ZOL system registers */
.macro MFUSR_ZOL R0="$r1", R1="$r2", R2="$r3"
mfusr \R0, $LB
mfusr \R1, $LE
mfusr \R2, $LC
.endm
.macro MTUSR_ZOL R0="$r1", R1="$r2", R2="$r3"
mtusr \R0, $LB
mtusr \R1, $LE
mtusr \R2, $LC
.endm
/* Context-switch save and restore routines */
.macro SAVE_ALL
pushm $r6, $r30
mfsr $r1, $IPC
mfsr $r2, $IPSW
.if (regno == 4)
MFUSR_ZOL "$r3","$r4","$r5"
MFUSR_IFC "$r6"
pushm $r0, $r6 /* $0 is dummy */
.else
.if (regno == 3)
MFUSR_ZOL "$r3","$r4","$r5"
pushm $r1, $r5
.else
.if (regno == 1)
MFUSR_IFC "$r3"
pushm $r1, $r3
.else
pushm $r1, $r2
.endif
.endif
.endif
push_fpu
.endm
.macro RESTORE_ALL
pop_fpu
setgie.d
dsb
.if (regno == 4)
popm $r0, $r6 /* $0 is dummy */
MTUSR_ZOL "$r3","$r4","$r5"
MTUSR_IFC "$r6"
.else
.if (regno == 3)
popm $r1, $r5
MTUSR_ZOL "$r3","$r4","$r5"
.else
.if (regno == 1)
popm $r1, $r3
MTUSR_IFC "$r3"
.else
popm $r1, $r2
.endif
.endif
.endif
mtsr $r1, $IPC
mtsr $r2, $IPSW
popm $r6, $r30
popm $r0, $r5
.endm
/* Nested IRQ save and restore routines*/
.macro SAVE_CALLER
pushm $r15,$r30 /* full: 16 gpr, reduce: 4 gpr */
.if (regno == 4)
MFUSR_ZOL "$r1","$r2","$r3"
MFUSR_IFC "$r4"
pushm $r1, $r4
mfsr $r1, $IPC
mfsr $r2, $IPSW
pushm $r1, $r2
.else
mfsr $r1, $IPC
mfsr $r2, $IPSW
.if (regno == 3)
MFUSR_ZOL "$r3","$r4","$r5"
pushm $r0, $r5 /* $0 is dummy */
.else
.if (regno == 1)
MFUSR_IFC "$r3"
pushm $r0, $r3 /* $r0 is dummy */
.else
pushm $r1, $r2
.endif
.endif
.endif
push_fpu_caller
.endm
.macro RESTORE_CALLER
pop_fpu_caller
setgie.d
dsb
.if (regno == 4)
popm $r1, $r2
mtsr $r1, $IPC
mtsr $r2, $IPSW
popm $r1, $r4
MTUSR_ZOL "$r1","$r2","$r3"
MTUSR_IFC "$r4"
.else
.if (regno == 3)
popm $r0, $r5 /* $0 is dummy */
MTUSR_ZOL "$r3","$r4","$r5"
.else
.if (regno == 1)
popm $r0, $r3 /* $0 is dummy */
MTUSR_IFC "$r3"
.else
popm $r1, $r2
.endif
.endif
mtsr $r1, $IPC
mtsr $r2, $IPSW
.endif
popm $r15,$r30 /* full: 16 gpr, reduce: 4 gpr*/
popm $r0, $r5
.endm
/* Non-Nested IRQ save and restore routines */
.macro SAVE_CALLER_UNNESTED
pushm $r15,$r30 /* full: 16 gpr, reduce: 4 gpr */
.if (regno == 1)
MFUSR_IFC "$r1"
pushm $r0, $r1 /* $r0 is dummy */
.endif
push_fpu_caller
.endm
.macro RESTORE_CALLER_UNNESTED
pop_fpu_caller
.if (regno == 1)
setgie.d
dsb
popm $r0, $r1 /* $0 is dummy */
MTUSR_IFC "$r1"
.endif
popm $r15,$r30 /* full: 16 gpr, reduce: 4 gpr*/
popm $r0, $r5
.endm

54
bsp/AE210P/os_except.c Normal file
View File

@@ -0,0 +1,54 @@
#include "hal.h"
#include "uart/uart.h"
#include "osc/osc.h"
#include "os_except.h"
/*
*********************************************************************************************************
* Register Exception Handlers
*
* Description : This function is called to register general exception handler.
* The total number of general exception is 16.
*
* Arguments : ipc
*
* Notes :
*********************************************************************************************************
*/
inline void register_exception_handler(int genneral_except_num, void (*handler)(unsigned int ipc))
{
if (genneral_except_num >= 16)
{
puts("Non-exist general exception number.\n");
while (1);
}
General_Exception_Handler_Table[genneral_except_num] = handler;
}
/*
*********************************************************************************************************
* Exception Dispatcher
*
* Description : This function is called from exception handler to dispatch different
* exception handler according to register itype.
*
* Arguments : ipc
*
* Notes :
*********************************************************************************************************
*/
void OS_CPU_EXCEPTION_Dispatcher(unsigned int ipc)
{
/* Interrupt is still disabled at this point */
/* get all needed system registers' values before re-enable interrupt */
unsigned int itype = __nds32__mfsr (NDS32_SR_ITYPE);
unsigned int exception_num;
void (*pHandler)(unsigned int ipc);
exception_num = itype & 0xf;
pHandler = General_Exception_Handler_Table[exception_num];
pHandler(ipc);
}

23
bsp/AE210P/os_except.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef __OS_EXCEPT_H__
#define __OS_EXCEPT_H__
/***********************************
TYPES OF GENERAL EXCEPTION
***********************************/
#define GE_ALIGN_CHECK 0
#define GE_RESERVED_INST 1
#define GE_TRAP 2
#define GE_ARITHMETIC 3
#define GE_PRECISE_BUS_ERR 4
#define GE_INPRECISE_BUS_ERR 5
#define GE_COPROCESSOR 6
#define GE_PRIVILEGE_INST 7
#define GE_RESERVED_VALUE 8
#define GE_NON_EXIST_LOCAL_MEM 9
#define GE_MPZIU_CTRL 10
void *General_Exception_Handler_Table[16];
inline void register_exception_handler(int genneral_except_num, void (*handler)(unsigned int ipc));
#endif

Binary file not shown.

View File

@@ -0,0 +1,49 @@
E-Mail : Archer Zhang <archer.zhang@wh-mx.com>
******************************
<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӻ<EFBFBD><EFBFBD>޸<EFBFBD>
******************************
[1] <20><>bspĿ¼<C4BF>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD>AE210PĿ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Andes AE210P EVB<56><42>N1068A<38><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC>
[2] <20><>libcpuĿ¼<C4BF>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD>nds32Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Andes N10ϵ<30><CFB5>Core<72><65><EFBFBD><EFBFBD>ϵĿ¼<C4BF><C2BC>
[3] <20><><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Libc<62><63>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>Libcλ<63><CEBB>AE210P/libc<62><63><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><DEB8><EFBFBD>finsh.h<>ļ<EFBFBD><C4BC><EFBFBD>Line<6E><65>74<37><34>75<37><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#if !(defined(__GNUC__) && defined(__x86_64__))
//typedef unsigned int size_t; // ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>typedef
#include <stddef.h> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
#include <string.h>
#else
[4] <20><><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD>δʹ<CEB4><CAB9><EFBFBD>жϽ<D0B6><CFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>˲<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><DEB8><EFBFBD>shell.c<>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
a. Line<6E><65>316<31><36>317
//rt_device_set_rx_indicate(shell->device, finsh_rx_ind);
//rt_device_open(shell->device, (RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX));
rt_device_open(shell->device, (RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM));
b. Line<6E><65>326<32><36>ע<EFBFBD>͸<EFBFBD><CDB8><EFBFBD>
// if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;
c. Line<6E><65>553<35><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CPUռ<55>õ<EFBFBD><C3B5>ͷ<EFBFBD>
rt_thread_delay(1); // <20><><EFBFBD><EFBFBD>rt-schedule();
******************************
<EFBFBD><EFBFBD><EFBFBD>̹<EFBFBD><EFBFBD><EFBFBD>
******************************
[1] <20>ù<EFBFBD><C3B9><EFBFBD>ʹ<EFBFBD><CAB9>Makefile<6C><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Makefile<6C><65><EFBFBD>ļ<EFBFBD>AE210P/Makefile<6C><65>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
make APP=rtthread AE210P=1 USING_CLI=1 DEBUG=1 all
make APP=rtthread AE210P=1 USING_CLI=1 DEBUG=1 clean
******************************
Tool Chain/IDE
******************************
[1] IDE<44><45>AndeSight_V300_STD
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Eclipse<EFBFBD><EFBFBD>GNU<EFBFBD><EFBFBD>GDB<EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>׼<EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD>ɡ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺͵<EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD>Andes<EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>.docx<63><78><EFBFBD><EFBFBD>
******************************
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD>壨PCBA<EFBFBD><EFBFBD>
******************************
[1] AE210P EVB

138
bsp/AE210P/reset.c Normal file
View File

@@ -0,0 +1,138 @@
#include "nds32_intrinsic.h"
#include "nds32.h"
#ifndef VECTOR_BASE
#define VECTOR_BASE 0x00000000
#endif
#define PSW_MSK \
(PSW_mskGIE | PSW_mskINTL | PSW_mskPOM | PSW_mskIFCON | PSW_mskCPL)
#define PSW_INIT \
(0x0UL << PSW_offGIE \
| 0x0UL << PSW_offINTL \
| 0x1UL << PSW_offPOM \
| 0x0UL << PSW_offIFCON \
| 0x7UL << PSW_offCPL)
#define IVB_MSK \
(IVB_mskEVIC | IVB_mskESZ | IVB_mskIVBASE)
#define IVB_INIT \
((VECTOR_BASE >> IVB_offIVBASE) << IVB_offIVBASE\
| 0x1UL << IVB_offESZ \
| 0x0UL << IVB_offEVIC)
#pragma weak c_startup = c_startup_common
void c_startup(void);
/*
* Default c_startup() function which used for those relocation from LMA to VMA.
*/
static void c_startup_common(void)
{
#ifdef XIP_MODE
/* Data section initialization */
#define MEMCPY(des, src, n) __builtin_memcpy ((des), (src), (n))
extern char __rw_lma_start, __rw_lma_end, __rw_vma_start;
unsigned int size = &__rw_lma_end - &__rw_lma_start;
/* Copy data section from LMA to VMA */
MEMCPY(&__rw_vma_start, &__rw_lma_start, size);
#else
/* We do nothing for those LMA equal to VMA */
#endif
}
static void cpu_init(void)
{
unsigned int reg;
/* Set PSW GIE/INTL to 0, superuser & CPL to 7 */
reg = (__nds32__mfsr(NDS32_SR_PSW) & ~PSW_MSK) | PSW_INIT;
__nds32__mtsr(reg, NDS32_SR_PSW);
__nds32__isb();
/* Set vector size: 16 byte, base: VECTOR_BASE, mode: IVIC */
reg = (__nds32__mfsr(NDS32_SR_IVB) & ~IVB_MSK) | IVB_INIT;
__nds32__mtsr(reg, NDS32_SR_IVB);
/*
* Check interrupt priority programmable (IVB.PROG_PRI_LVL)
* 0: Fixed priority, 1: Programmable priority
*/
if (reg & IVB_mskPROG_PRI_LVL)
{
/* Set PPL2FIX_EN to 0 to enable Programmable Priority Level */
__nds32__mtsr(0x0, NDS32_SR_INT_CTRL);
}
/* Mask and clear hardware interrupts */
if (reg & IVB_mskIVIC_VER)
{
/* IVB.IVIC_VER >= 1*/
__nds32__mtsr(0x0, NDS32_SR_INT_MASK2);
__nds32__mtsr(-1, NDS32_SR_INT_PEND2);
}
else
{
__nds32__mtsr(__nds32__mfsr(NDS32_SR_INT_MASK) & ~0xFFFF, NDS32_SR_INT_MASK);
}
}
/*
* Vectors initialization. This means to copy exception handler code to
* vector entry base address.
*/
static void vector_init(void)
{
extern unsigned int OS_Int_Vectors, OS_Int_Vectors_End;
if ((unsigned int)&OS_Int_Vectors != VECTOR_BASE)
{
volatile unsigned int *vector_srcptr = &OS_Int_Vectors;
volatile unsigned int *vector_dstptr = (unsigned int *)VECTOR_BASE;
/* copy vector table to VECTOR_BASE */
while (vector_srcptr != &OS_Int_Vectors_End)
*vector_dstptr++ = *vector_srcptr++;
}
}
/*
* NDS32 reset handler to reset all devices sequentially and call application
* entry function.
*/
void reset(void)
{
extern void hardware_init(void);
extern void bsp_init(void);
extern void rtthread_startup(void);
/*
* Initialize CPU to a post-reset state, ensuring the ground doesn't
* shift under us while we try to set things up.
*/
cpu_init();
/*
* Initialize LMA/VMA sections.
* Relocation for any sections that need to be copied from LMA to VMA.
*/
c_startup();
/* Copy vector table to vector base address */
vector_init();
/* Call platform specific hardware initialization */
hardware_init();
/* Setup the OS system required initialization */
bsp_init();
/* Application enrty function */
rtthread_startup();
/* Never go back here! */
while(1);
}

199
bsp/AE210P/rtconfig.h Normal file
View File

@@ -0,0 +1,199 @@
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
/* RT_NAME_MAX*/
#define RT_NAME_MAX 8
/* RT_ALIGN_SIZE*/
#define RT_ALIGN_SIZE 4
/* PRIORITY_MAX */
#define RT_THREAD_PRIORITY_MAX 32
/* Tick per Second */
#define RT_TICK_PER_SECOND (100)
/* SECTION: RT_DEBUG */
/* Thread Debug */
#define RT_DEBUG
#define RT_THREAD_DEBUG
#define RT_USING_OVERFLOW_CHECK
/* Using Hook */
#define RT_USING_HOOK
/* Using Software Timer */
/* #define RT_USING_TIMER_SOFT */
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 512
#define RT_TIMER_TICK_PER_SECOND 10
//#define RT_PRINTF_LONGLONG
/* SECTION: IPC */
/* Using Semaphore*/
#define RT_USING_SEMAPHORE
/* Using Mutex */
#define RT_USING_MUTEX
/* Using Event */
#define RT_USING_EVENT
/* Using MailBox */
#define RT_USING_MAILBOX
/* Using Message Queue */
#define RT_USING_MESSAGEQUEUE
/* SECTION: Memory Management */
/* Using Memory Pool Management*/
//#define RT_USING_MEMPOOL
/* Using Dynamic Heap Management */
#define RT_USING_HEAP
/* Using Small MM */
#define RT_USING_SMALL_MEM
// <bool name="RT_USING_COMPONENTS_INIT" description="Using RT-Thread components initialization" default="true" />
#define RT_USING_COMPONENTS_INIT
/* SECTION: Device System */
/* Using Device System */
#define RT_USING_DEVICE
// <bool name="RT_USING_DEVICE_IPC" description="Using device communication" default="true" />
#define RT_USING_DEVICE_IPC
// <bool name="RT_USING_SERIAL" description="Using Serial" default="true" />
#define RT_USING_SERIAL
/* SECTION: Console options */
#define RT_USING_CONSOLE
//#define RT_KPRINTF
/* the buffer size of console*/
#define RT_CONSOLEBUF_SIZE 260
// <string name="RT_CONSOLE_DEVICE_NAME" description="The device name for console" default="uart1" />
#define RT_CONSOLE_DEVICE_NAME "uart02"
/* SECTION: finsh, a C-Express shell */
#define RT_USING_FINSH
/* Using symbol table */
#define FINSH_USING_SYMTAB
#define FINSH_USING_DESCRIPTION
/* SECTION: MSH, a bash shell */
#define FINSH_USING_MSH
#define FINSH_USING_MSH_DEFAULT
/* SECTION: MXCLI, modified base-on MSH */
//#define FINSH_USING_MXCLI
/* SECTION: device filesystem */
//#define RT_USING_DFS
//#define DFS_USING_WORKDIR
//#define RT_USING_DFS_DEVFS
//#define RT_USING_DFS_JFFS2
/* Reentrancy (thread safe) of the FatFs module. */
#define RT_DFS_ELM_REENTRANT
/* Number of volumes (logical drives) to be used. */
#define RT_DFS_ELM_DRIVES 2
/* #define RT_DFS_ELM_USE_LFN 1 */
/* #define RT_DFS_ELM_CODE_PAGE 936 */
#define RT_DFS_ELM_MAX_LFN 255
/* Maximum sector size to be handled. */
#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
/* the max number of mounted filesystem */
#define DFS_FILESYSTEMS_MAX 2
/* the max number of opened files */
#define DFS_FD_MAX 4
/* SECTION: lwip, a lighwight TCP/IP protocol stack */
/* #define RT_USING_LWIP */
/* LwIP uses RT-Thread Memory Management */
#define RT_LWIP_USING_RT_MEM
/* Enable ICMP protocol*/
#define RT_LWIP_ICMP
/* Enable UDP protocol*/
#define RT_LWIP_UDP
/* Enable TCP protocol*/
#define RT_LWIP_TCP
/* Enable DNS */
#define RT_LWIP_DNS
/* the number of simulatenously active TCP connections*/
#define RT_LWIP_TCP_PCB_NUM 5
/* Using DHCP */
/* #define RT_LWIP_DHCP */
/* ip address of target*/
#define RT_LWIP_IPADDR0 192
#define RT_LWIP_IPADDR1 168
#define RT_LWIP_IPADDR2 1
#define RT_LWIP_IPADDR3 30
/* gateway address of target*/
#define RT_LWIP_GWADDR0 192
#define RT_LWIP_GWADDR1 168
#define RT_LWIP_GWADDR2 1
#define RT_LWIP_GWADDR3 1
/* mask address of target*/
#define RT_LWIP_MSKADDR0 255
#define RT_LWIP_MSKADDR1 255
#define RT_LWIP_MSKADDR2 255
#define RT_LWIP_MSKADDR3 0
/* tcp thread options */
#define RT_LWIP_TCPTHREAD_PRIORITY 12
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 10
#define RT_LWIP_TCPTHREAD_STACKSIZE 1024
/* ethernet if thread options */
#define RT_LWIP_ETHTHREAD_PRIORITY 15
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 10
#define RT_LWIP_ETHTHREAD_STACKSIZE 512
/* TCP sender buffer space */
#define RT_LWIP_TCP_SND_BUF 8192
/* TCP receive window. */
#define RT_LWIP_TCP_WND 8192
/* SECTION: RT-Thread/GUI */
/* #define RT_USING_RTGUI */
/* name length of RTGUI object */
#define RTGUI_NAME_MAX 12
/* support 16 weight font */
#define RTGUI_USING_FONT16
/* support Chinese font */
#define RTGUI_USING_FONTHZ
/* use DFS as file interface */
#define RTGUI_USING_DFS_FILERW
/* use font file as Chinese font */
#define RTGUI_USING_HZ_FILE
/* use Chinese bitmap font */
#define RTGUI_USING_HZ_BMP
/* use small size in RTGUI */
#define RTGUI_USING_SMALL_SIZE
/* use mouse cursor */
/* #define RTGUI_USING_MOUSE_CURSOR */
/* default font size in RTGUI */
#define RTGUI_DEFAULT_FONT_SIZE 16
/* image support */
/* #define RTGUI_IMAGE_XPM */
/* #define RTGUI_IMAGE_BMP */
// <bool name="RT_USING_CMSIS_OS" description="Using CMSIS OS API" default="true" />
// #define RT_USING_CMSIS_OS
// <bool name="RT_USING_RTT_CMSIS" description="Using CMSIS in RTT" default="true" />
#define RT_USING_RTT_CMSIS
// <bool name="RT_USING_BSP_CMSIS" description="Using CMSIS in BSP" default="true" />
// #define RT_USING_BSP_CMSIS
#endif

197
bsp/AE210P/start.S Normal file
View File

@@ -0,0 +1,197 @@
!********************************************************************************************************
!
! (c) Copyright 2005-2014, Andes Techonology
! All Rights Reserved
!
! NDS32 Generic Port
! GNU C Compiler
!
!********************************************************************************************************
!********************************************************************************************************
! INCLUDE ASSEMBLY CONSTANTS
!********************************************************************************************************
#include <nds32_init.inc>
#include "nds32_defs.h"
#include "os_cpu_common.h"
#ifndef VECTOR_NUMINTRS
#define VECTOR_NUMINTRS 32
#endif
.global OS_Init_Nds32
.global OS_Int_Vectors
.global OS_Int_Vectors_End
.macro WEAK_DEFAULT weak_sym, default_handler
.weak \weak_sym
.set \weak_sym ,\default_handler
.endm
! Define standard NDS32 vector table entry point of
! exception/interruption vectors
.macro VECTOR handler
WEAK_DEFAULT \handler, OS_Default_Exception
.align 4
__\handler:
#ifdef MPU_SUPPORT
la $p0, \handler
jr5 $p0
#else
pushm $r0, $r5
la $r0, \handler
jr5 $r0
#endif
.endm
.macro INTERRUPT_VECTOR num
WEAK_DEFAULT OS_Trap_Interrupt_HW\num, OS_Default_Interrupt
.align 4
__OS_Trap_Interrupt_HW\num:
#ifdef MPU_SUPPORT
la $p1, OS_Trap_Interrupt_HW\num
li $p0, \num
jr5 $p1
#else
pushm $r0, $r5
la $r1, OS_Trap_Interrupt_HW\num
li $r0, \num
jr5 $r1
#endif
.endm
!********************************************************************************************************
! Vector Entry Table
!********************************************************************************************************
.section .nds32_init, "ax"
OS_Int_Vectors:
b OS_Init_Nds32 ! (0) Trap Reset/NMI
VECTOR OS_Trap_TLB_Fill ! (1) Trap TLB fill
VECTOR OS_Trap_PTE_Not_Present ! (2) Trap PTE not present
VECTOR OS_Trap_TLB_Misc ! (3) Trap TLB misc
VECTOR OS_Trap_TLB_VLPT_Miss ! (4) Trap TLB VLPT miss
VECTOR OS_Trap_Machine_Error ! (5) Trap Machine error
VECTOR OS_Trap_Debug_Related ! (6) Trap Debug related
VECTOR OS_Trap_General_Exception ! (7) Trap General exception
VECTOR OS_Trap_Syscall ! (8) Syscall
! Interrupt vectors
.altmacro
.set irqno, 0
.rept VECTOR_NUMINTRS
INTERRUPT_VECTOR %irqno
.set irqno, irqno+1
.endr
.align 4
OS_Int_Vectors_End:
!******************************************************************************************************
! Start Entry
!******************************************************************************************************
.section .text
.global _start
OS_Init_Nds32:
_start:
!************************** Begin of do-not-modify **************************
! Please don't modify this code
! Initialize the registers used by the compiler
nds32_init ! NDS32 startup initial macro in <nds32_init.inc>
!*************************** End of do-not-modify ***************************
#ifdef CONFIG_HWZOL
! enable AEN
mfsr $r0, $PSW
ori $r0, $r0, (1 << PSW_offAEN)
mtsr $r0, $PSW
#endif
#if (defined(CONFIG_CPU_ICACHE_ENABLE) || defined(CONFIG_CPU_DCACHE_ENABLE))
! disable cache
mfsr $r0, $CACHE_CTL
li $r1, ~(CACHE_CTL_mskIC_EN | CACHE_CTL_mskDC_EN)
and $r0, $r0, $r1
mtsr $r0, $CACHE_CTL
#endif
! Do system low level setup. It must be a leaf function.
bal _nds32_init_mem
#if 1 /* Speed prefer */
! We do this on a word basis.
! Currently, the default linker script guarantee
! the __bss_start/_end boundary word-aligned.
! Clear bss
la $r0, __bss_start
la $r1, _end
sub $r2, $r1, $r0 ! $r2: Size of .bss
beqz $r2, clear_end
andi $r7, $r2, 0x1f ! $r7 = $r2 mod 32
movi $r3, 0
movi $r4, 0
movi $r5, 0
movi $r6, 0
movi $r8, 0
movi $r9, 0
movi $r10, 0
beqz $r7, clear_loop ! if $r7 == 0, bss_size%32 == 0
sub $r2, $r2, $r7
first_clear:
swi.bi $r3, [$r0], #4 ! clear each word
addi $r7, $r7, -4
bnez $r7, first_clear
li $r1, 0xffffffe0
and $r2, $r2, $r1 ! check bss_size/32 == 0 or not
beqz $r2, clear_end ! if bss_size/32 == 0 , needless to clear
clear_loop:
smw.bim $r3, [$r0], $r10 !clear each 8 words
addi $r2, $r2, -32
bgez $r2, clear_loop
clear_end:
#else /* Size prefer */
! Clear bss
la $r0, _edata
la $r1, _end
beq $r0, $r1, 2f
li $r2, #0
1:
swi.bi $r2, [$r0], #4
bne $r0, $r1, 1b
2:
#endif
! Set-up the stack pointer
la $sp, _stack
! System reset handler
bal reset
! Default exceptions / interrupts handler
OS_Default_Exception:
OS_Default_Interrupt:
die:
b die
!********************************************************************************************************
! Interrupt vector Table
!********************************************************************************************************
.data
.align 2
! These tables contain the isr pointers used to deliver interrupts
.global OS_CPU_Vector_Table
OS_CPU_Vector_Table:
.rept 32
.long OS_Default_Interrupt
.endr
.end

113
bsp/AE210P/startup.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* File : startup.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2006-08-31 Bernard first implementation
*/
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_COMPONENTS_INIT
#include <components.h>
#endif /* RT_USING_COMPONENTS_INIT */
#include "board.h"
extern int rt_application_init(void); // define in application/application.c
#ifdef __CC_ARM
extern int Image$$RW_IRAM1$$ZI$$Limit;
#elif __ICCARM__
#pragma section="HEAP"
#else
extern int __bss_end;
extern int _stack;
#endif
/*******************************************************************************
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert error has occurred.
* Input : - file: pointer to the source file name
* - line: assert error line source number
* Output : None
* Return : None
*******************************************************************************/
void assert_failed(char* file, int line)
{
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
while (1) ;
}
/**
* This function will startup RT-Thread RTOS.
*/
void rtthread_startup(void)
{
/* show version */
rt_show_version();
#ifdef RT_USING_HEAP
#if STM32_EXT_SRAM
rt_system_heap_init((void*)STM32_EXT_SRAM_BEGIN, (void*)STM32_EXT_SRAM_END);
#else
#ifdef __CC_ARM
rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)MXT_IRAM_END);
#elif __ICCARM__
rt_system_heap_init(__segment_end("HEAP"), (void*)STM32_SRAM_END);
#else
/* init memory system */
rt_system_heap_init((void *)0x00250000, (void *)0x00280000);
#endif
#endif /* STM32_EXT_SRAM */
#endif /* RT_USING_HEAP */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
/* init scheduler system */
rt_system_scheduler_init();
/* initialize timer */
rt_system_timer_init();
/* init timer thread */
rt_system_timer_thread_init();
/* init application */
rt_application_init();
/* init idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
}
//int main(void)
//{
// /* disable interrupt first */
// rt_hw_interrupt_disable();
//
// /* startup RT-Thread RTOS */
// rtthread_startup();
//
// return 0;
//}
/*@}*/

View File

@@ -72,7 +72,9 @@ typedef unsigned long u_long;
/* only for GNU GCC */
#if !(defined(__GNUC__) && defined(__x86_64__))
typedef unsigned int size_t;
//typedef unsigned int size_t;
#include <stddef.h>
#include <string.h>
#else
#include <stdio.h>
#endif

View File

@@ -311,10 +311,11 @@ void finsh_thread_entry(void *parameter)
if (shell->device == RT_NULL)
{
#ifdef RT_USING_CONSOLE
shell->device = rt_console_get_device();
RT_ASSERT(shell->device);
rt_device_set_rx_indicate(shell->device, finsh_rx_ind);
rt_device_open(shell->device, (RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX));
shell->device = rt_console_get_device();
RT_ASSERT(shell->device);
// rt_device_set_rx_indicate(shell->device, finsh_rx_ind);
// rt_device_open(shell->device, (RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX));
rt_device_open(shell->device, (RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM));
#else
RT_ASSERT(shell->device);
#endif
@@ -323,7 +324,7 @@ void finsh_thread_entry(void *parameter)
while (1)
{
/* wait receive */
if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;
// if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;
/* read one character from device */
while (rt_device_read(shell->device, 0, &ch, 1) == 1)
@@ -550,6 +551,8 @@ void finsh_thread_entry(void *parameter)
shell->line_curpos = 0;
}
} /* end of device read */
rt_thread_delay(1);
}
}

188
libcpu/nds32/context_gcc.S Normal file
View File

@@ -0,0 +1,188 @@
#include "nds32.h"
#include "os_cpu_common.h"
#include "config.h"
.align 4
! void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
! R0 --> from
! R1 --> to
.section .text
.global rt_hw_context_switch_interrupt
.global rt_hw_context_switch
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
push25 $r6,#8 ! {$r6, $fp, $gp, $lp}
la $r2, rt_thread_switch_interrupt_flag
lw $r3, [$r2]
movi $r4, #1
beq $r3, $r4, _reswitch
sw $r4, [$r2] ! set rt_thread_switch_interrupt_flag to 1
la $r2, rt_interrupt_from_thread
sw $r0, [$r2] ! set rt_interrupt_from_thread
_reswitch:
la $r2, rt_interrupt_to_thread
sw $r1, [$r2] ! set rt_interrupt_to_thread
bal hal_intc_swi_trigger ! trigger the swi exception (causes context switch)
pop25 $r6,#8 ! {$r6, $fp, $gp, $lp}
! R0 --> switch from thread stack
! R1 --> switch to thread stack
! psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
.align 4
.global OS_Trap_Interrupt_SWI
OS_Trap_Interrupt_SWI:
! pushm $r0, $r5
setgie.d ! disable interrupt to protect context switch
dsb
IntlDescend ! Descend interrupt level
movi $r0, 0x0
mtsr $r0, $INT_PEND ! clean SWI pending
la $r0, rt_thread_switch_interrupt_flag ! get rt_thread_switch_interrupt_flag
lw $r1, [$r0]
beqz $r1, pendsv_exit ! swi has already been handled
movi $r1, #0
sw $r1, [$r0] ! clear rt_thread_switch_interrupt_flag to 0
la $r0, rt_interrupt_from_thread
lw $r1, [$r0]
beqz $r1, switch_to_thread ! skip register save at the first time(os startup phase)
SAVE_ALL
move $r1, $sp
la $r0, rt_interrupt_from_thread
lw $r0, [$r0]
sw $r1, [$r0]
switch_to_thread:
la $r1, rt_interrupt_to_thread
lw $r1, [$r1]
lw $r1, [$r1] ! load thread stack pointer
move $sp, $r1 ! update stack pointer
RESTORE_ALL ! pop registers
pendsv_exit:
setgie.e
iret
.align 4
! void rt_hw_context_switch_to(rt_uint32 to);
! R0 --> to
.global rt_hw_context_switch_to
rt_hw_context_switch_to:
la $r1, rt_interrupt_to_thread
sw $r0, [$r1]
! set from thread to 0
la $r1, rt_interrupt_from_thread
movi $r0, #0
sw $r0, [$r1]
! set interrupt flag to 1
la $r1, rt_thread_switch_interrupt_flag
movi $r0, #1
sw $r0, [$r1]
! set the SWI exception priority(must be the lowest level)
! todo
! trigger the SWI exception (causes context switch)
jal hal_intc_swi_trigger
setgie.e ! enable interrupts at processor level
1:
b 1b ! never reach here
#ifndef VECTOR_NUMINTRS
#define VECTOR_NUMINTRS 32
#endif
.global OS_Trap_Int_Common
! Set up Interrupt vector ISR
! HW#IRQ_SWI_VECTOR : OS_Trap_Interrupt_SWI (SWI)
! HW#n : OS_Trap_Int_Common
.macro SET_HWISR num
.global OS_Trap_Interrupt_HW\num
.if \num == IRQ_SWI_VECTOR
.set OS_Trap_Interrupt_HW\num, OS_Trap_Interrupt_SWI
.else
.set OS_Trap_Interrupt_HW\num, OS_Trap_Int_Common
.endif
.endm
.altmacro
.set irqno, 0
.rept VECTOR_NUMINTRS
SET_HWISR %irqno
.set irqno, irqno+1
.endr
.noaltmacro
! .global OS_Trap_Int_Common
OS_Trap_Int_Common:
#ifdef MPU_SUPPORT
mfsr $p1, $PSW
ori $p1, $p1, (PSW_mskIT | PSW_mskDT)
mtsr $p1, $PSW ! enable IT/DT
dsb
pushm $r0, $r5
move $r0, $p0 ! IRQ number
#endif
! $r0 : HW Interrupt vector number
SAVE_CALLER
IntlDescend ! Descend interrupt level
mfsr $r1, $IPSW ! Use IPSW.CPL to check come from thread or ISR
srli45 $r1, #PSW_offCPL
fexti33 $r1, #0x2 ! IPSW.CPL
bnec $r1, #0x7, 2f ! IPSW.CPL != 7, come form ISR, reentrant
move $fp, $sp ! save old stack pointer
la $sp, __OS_Int_Stack ! switch to interrupt stack
2:
setgie.e ! allow nested now
! The entire CPU state is now stashed on the stack,
! and the stack is also 8-byte alignment.
! We can call C program based interrupt handler now.
la $r1, OS_CPU_Vector_Table
lw $r1, [$r1+($r0<<2)] ! ISR function pointer
jral $r1 ! Call ISR
la $r1, __OS_Int_Stack ! Check for nested interruption return
bne $r1, $sp, 3f ! $sp != __OS_Int_Stack?
move $sp, $fp ! Move back to the thread stack
3:
RESTORE_CALLER
iret
! .set OS_Trap_Interrupt_HW9, OS_Trap_Interrupt_SWI
! .set OS_Trap_Interrupt_HW19, OS_Trap_Int_Common
!*********************************************
! POINTERS TO VARIABLES
!*********************************************
#ifdef MPU_SUPPORT
.section privileged_data
#else
.section .bss
#endif
.skip IRQ_STACK_SIZE
.align 3
__OS_Int_Stack:
.end

221
libcpu/nds32/cpuport.c Normal file
View File

@@ -0,0 +1,221 @@
/*
* File : cpuport.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first version
* 2011-02-14 onelife Modify for EFM32
* 2011-06-17 onelife Merge all of the C source code into cpuport.c
* 2012-12-23 aozima stack addr align to 8byte.
* 2012-12-29 Bernard Add exception hook.
* 2013-07-09 aozima enhancement hard fault exception handler.
*/
#include <rtthread.h>
#include "nds32.h"
/*
* Initialise the stack of a task to look exactly as if a call to
* SAVE_CONTEXT had been called.
*
* See header file for description.
*
*
* Stack Layout:
* High |-----------------|
* | $R5 |
* |-----------------|
* | . |
* | . |
* |-----------------|
* | $R0 |
* |-----------------|
* | $R30 (LP) |
* |-----------------|
* | $R29 (GP) |
* |-----------------|
* | $R28 (FP) |
* |-----------------|
* | $R15 $R27 |
* |-----------------|
* | $R10 $R26 |
* |-----------------|
* | . |
* | . |
* |-----------------|
* | $R6 |
* |-----------------|
* | $IFC_LP | (Option)
* |-----------------|
* | $LC/$LE/$LB | (Option)
* | (ZOL) |
* |-----------------|
* | $IPSW |
* |-----------------|
* | $IPC |
* |-----------------|
* | Dummy word | (Option, only exist when IFC & ZOL both configured)
* |-----------------|
* | $FPU | (Option)
* |-----------------|
* Low
*
*/
struct stack_frame
{
rt_uint32_t topOfStack[34];
};
/* flag in interrupt handling */
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
/* exception hook */
static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
rt_base_t rt_hw_interrupt_disable(void)
{
rt_base_t level = __nds32__mfsr(NDS32_SR_PSW);
GIE_DISABLE();
return level;
}
void rt_hw_interrupt_enable(rt_base_t level)
{
if (level & PSW_mskGIE)
GIE_ENABLE();
}
/* For relax support, must initial $gp at task init*/
extern uint32_t _SDA_BASE_ __attribute__ ((weak));
/**************************************************************
* This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
**************************************************************/
rt_uint8_t *rt_hw_stack_init(void *tentry,
void *parameter,
rt_uint8_t *stack_addr,
void *texit)
{
rt_int32_t i;
rt_uint32_t *pxTopOfStack;
pxTopOfStack = (rt_uint32_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 4);
/* Simulate the stack frame as it would be created by a context switch */
/* R0 ~ R5 registers */
for (i = 5; i >= 1; i--) /* R5, R4, R3, R2 and R1. */
*--pxTopOfStack = (rt_uint32_t)0x01010101UL * i;
*--pxTopOfStack = (rt_uint32_t)parameter; /* R0 : Argument */
/* R6 ~ R30 registers */
*--pxTopOfStack = (rt_uint32_t)texit; /* R30: $LP */
*--pxTopOfStack = (rt_uint32_t)&_SDA_BASE_; /* R29: $GP */
*--pxTopOfStack = (rt_uint32_t)0x2828282828; /* R28: $FP */
#ifdef __NDS32_REDUCE_REGS__
*--pxTopOfStack = (rt_uint32_t)0x1515151515; /* R15 */
for (i = 10; i >= 6; i--) /* R10 ~ R6 */
*--pxTopOfStack = (rt_uint32_t)0x01010101UL * i;
#else
for (i = 27; i >= 6; i--) /* R27 ~ R6 */
*--pxTopOfStack = (rt_uint32_t)0x01010101UL * i;
#endif
/* IFC system register */
#ifdef __TARGET_IFC_EXT
*--pxTopOfStack = (rt_uint32_t)0x0; /* $IFC_LP */
#endif
/* ZOL system registers */
#ifdef __TARGET_ZOL_EXT
*--pxTopOfStack = (rt_uint32_t)0x0; /* $LC */
*--pxTopOfStack = (rt_uint32_t)0x0; /* $LE */
*--pxTopOfStack = (rt_uint32_t)0x0; /* $LB */
#endif
/* IPSW and IPC system registers */
/* Default IPSW: enable GIE, set CPL to 7, clear IFCON */
i = (__nds32__mfsr(NDS32_SR_PSW) | PSW_mskGIE | PSW_mskCPL) & ~PSW_mskIFCON;
*--pxTopOfStack = (rt_uint32_t)i; /* $IPSW */
*--pxTopOfStack = (rt_uint32_t)tentry; /* $IPC */
/* Dummy word for 8-byte stack alignment */
#if defined(__TARGET_IFC_EXT) && defined(__TARGET_ZOL_EXT)
*--pxTopOfStack = (rt_uint32_t)0xFFFFFFFF; /* Dummy */
#endif
/* FPU registers */
#ifdef __TARGET_FPU_EXT
for (i = 0; i < FPU_REGS; i++)
*--pxTopOfStack = (rt_uint32_t)0x0; /* FPU */
#endif
return (rt_uint8_t *)pxTopOfStack;
}
/**
* This function set the hook, which is invoked on fault exception handling.
*
* @param exception_handle the exception handling hook function.
*/
void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
{
rt_exception_hook = exception_handle;
}
#ifdef RT_USING_CPU_FFS
/**
* This function finds the first bit set (beginning with the least significant bit)
* in value and return the index of that bit.
*
* Bits are numbered starting at 1 (the least significant bit). A return value of
* zero from any of these functions means that the argument was zero.
*
* @return return the index of the first bit set. If value is 0, then this function
* shall return 0.
*/
#if defined(__CC_ARM)
__asm int __rt_ffs(int value)
{
CMP r0, #0x00
BEQ exit
RBIT r0, r0
CLZ r0, r0
ADDS r0, r0, #0x01
exit
BX lr
}
#elif defined(__IAR_SYSTEMS_ICC__)
int __rt_ffs(int value)
{
if (value == 0) return value;
__ASM("RBIT r0, r0");
__ASM("CLZ r0, r0");
__ASM("ADDS r0, r0, #0x01");
}
#elif defined(__GNUC__)
int __rt_ffs(int value)
{
return __builtin_ffs(value);
}
#endif
#endif

33
libcpu/nds32/os_cpu.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef OS_CPU_H
#define OS_CPU_H
#include "nds32.h"
/*
* *********************************************************************************************************
* * DATA TYPES
* * (Compiler Specific)
* *********************************************************************************************************
* */
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
typedef signed char INT8S; /* Signed 8 bit quantity */
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
typedef signed short INT16S; /* Signed 16 bit quantity */
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
typedef signed int INT32S; /* Signed 32 bit quantity */
typedef float FP32; /* Single precision floating point */
typedef double FP64; /* Double precision floating point */
typedef unsigned long OS_STK; /* Each stack entry is 32-bit wide */
typedef unsigned long OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */
void OS_CPU_IRQ_ISR(void); /* See OS_CPU_A.S */
void OS_CPU_IRQ_ISR_Handler(void); /* See BSP code */
void OSCtxSw(void);
void CtxSave(void);
void CtxRestore(void);
void OS_DCache_Writeback(void *aVA, unsigned aSize);
#endif