未验证 提交 385ee9af 编写于 作者: B Bernard Xiong 提交者: GitHub

Merge pull request #1483 from TanekLiang/nds32-update

remove AE210P bsp and nds32 porting
#************************************************************
# 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$(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 \
-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
Andes Maintainer: **It's a very early and draft porting yet.**
E-Mail : Archer Zhang <archer.zhang@wh-mx.com>
## 文件(夹)添加和修改
1. 在bsp目录下,添加AE210P目录,这是Andes AE210P EVB(N1068A)的主目录;
2. 在libcpu目录下,添加nds32目录,这是Andes N10系列Core的体系目录;
3. 由于编译器的原因,修改了finsh.h文件的Line:74 - 75,如下
```c
#if !(defined(__GNUC__) && defined(__x86_64__))
//typedef unsigned int size_t; // 注释这个typedef
#include <stddef.h> // 添加两个头文件包含
#include <string.h>
#else
```
4. 由于串口未使用中断接收,而是使用了查询接收,所以修改了shell.c文件,如下
```c
a. Line316317
//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. Line326,注释该行
// if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;
c. Line553,添加CPU占用的释放
rt_thread_delay(1); // 或者rt-schedule();
```
## 工程管理
1. 该工程使用Makefile管理,Makefile即文件AE210P/Makefile。编译如下:
```bash
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:AndeSight_V300_STD
这是一个基于Eclipse和GNU、GDB的环境,参阅对应工具/环境的标准文档即可。
关于创建工程和调试,请参阅《Andes工程创建和调试.docx》。
## 测试目标板(PCBA)
1. AE210P EVB
/*
* 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;
}
/*@}*/
/*
* 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);
}
/*@}*/
/*
* 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__ */
#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);
}
/*****************************************************************************
*
* 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__ */
/* 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");
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
}
}
\ No newline at end of file
/*****************************************************************************
*
* 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__ */
/*****************************************************************************
*
* 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__ */
/*
* 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 */
}
/*
* 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__"
#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
#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
}
#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__ */
#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"
#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__ */
此差异已折叠。
/*****************************************************************************
*
* 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__ */
#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;
}
#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__
lib-${CONFIG_FB_FTLCDC100} += font.o lcd.o
#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++;
}
}
#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__ */
#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;
}
#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__ */
#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;
}
#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
lib-y +=
lib-y += sdd.o
lib-y += sdd_sd.o
/*****************************************************************************
*
* 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__ */
此差异已折叠。
/*****************************************************************************
*
* 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__ */
此差异已折叠。
此差异已折叠。
lib-${CONFIG_FTSSP010} := sspd_ac97.o sspd_rts.o
#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;
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
#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__ */
#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__ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册