[bsp]delete fh8620、gkipc, because of gpl license

This commit is contained in:
yangjie 2021-04-25 11:28:18 +08:00
parent e3c19a8463
commit 6152b37ca6
737 changed files with 0 additions and 891349 deletions

View File

@ -125,7 +125,6 @@ jobs:
- {RTT_BSP: "beaglebone", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "zynqmp-r5-axu4ev", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "frdm-k64f", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "fh8620", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "xplorer4330/M4", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "at32/at32f403a-start", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "at32/at32f407-start", RTT_TOOL_CHAIN: "sourcery-arm"}

2
Jenkinsfile vendored
View File

@ -29,7 +29,6 @@ pipeline {
// ['gd32e230k-start', 'sourcery-arm'], /* CI compile not support */
['gd32303e-eval', 'sourcery-arm'],
// ['gd32450z-eval', 'sourcery-arm'], /* CI link not support */
['gkipc', 'sourcery-arm'],
['imx6sx/cortex-a9', 'sourcery-arm'],
// ['imxrt/imxrt1052-atk-commander', 'sourcery-arm'], /* CI compile not support */
// ['imxrt/imxrt1052-fire-pro', 'sourcery-arm'], /* CI compile not support */
@ -108,7 +107,6 @@ pipeline {
['swm320-lq100', 'sourcery-arm'],
['beaglebone', 'sourcery-arm'],
['frdm-k64f', 'sourcery-arm'],
['fh8620', 'sourcery-arm'],
['xplorer4330/M4', 'sourcery-arm'],
// ['at32/at32f403a-start', 'sourcery-arm'],/* CI link not support */
// ['at32/at32f407-start', 'sourcery-arm']/* CI compile C99 not support */

View File

@ -1,14 +0,0 @@
# for module compiling
import os
Import('RTT_ROOT')
cwd = str(Dir('#'))
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View File

@ -1,34 +0,0 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = rtconfig.OUTPUT_NAME + rtconfig.TARGET_EXT
# add rtconfig.h path to the assembler
rtconfig.AFLAGS += ' -I' + str(Dir('#')) +' -I' + RTT_ROOT + '/libcpu/arm/armv6'
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT)
# make a building
DoBuilding(TARGET, objs)

View File

@ -1,11 +0,0 @@
import rtconfig
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -1,44 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
void init_thread(void *parameter)
{
rt_components_init();
return ;
}
int rt_application_init(void)
{
rt_thread_t tid;
tid = rt_thread_create("init", init_thread, RT_NULL,
4096, RT_THREAD_PRIORITY_MAX/3, 20);
if (tid) rt_thread_startup(tid);
return 0;
}

View File

@ -1,9 +0,0 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

File diff suppressed because it is too large Load Diff

View File

@ -1,232 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef ACW_H_
#define ACW_H_
#include <rtthread.h>
#include <rtdevice.h>
#ifdef RT_USING_DFS
#include <dfs_fs.h>
#endif
#include <rthw.h>
#define ACW_CAP_DMA_CHAN 2
#define ACW_PLY_DMA_CHAN 3
typedef unsigned long long dma_addr_t;
struct scatterlist {
#ifdef CONFIG_DEBUG_SG
unsigned long sg_magic;
#endif
unsigned long page_link;
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
#ifdef CONFIG_NEED_SG_DMA_LENGTH
unsigned int dma_length;
#endif
};
#define readl(a) (*(volatile rt_uint32_t *)(a))
#define rkqueue_struct rt_workqueue
#define work_struct rt_work
#define INIT_WORK(work,func) rt_work_init(work,func,RT_NULL);
#define queue_work rt_workqueue_dowork
//timer
#define timer_list rt_timer
#define wait_queue_head_t struct rt_event
#define init_waitqueue_head(event_t) rt_event_init(event_t, "audio_event", RT_IPC_FLAG_FIFO)
typedef enum{
AC_SR_8K = 8000,
AC_SR_16K = 16000,
AC_SR_32K = 32000,
AC_SR_441K = 44100,
AC_SR_48K = 48000,
} FH_AC_SAMPLE_RATE_E;
typedef enum{
AC_BW_8 = 8,
AC_BW_16 = 16,
AC_BW_24 = 24,
} FH_AC_BIT_WIDTH_E;
enum io_select{
mic_in = 0,
line_in = 1,
speaker_out = 2,
line_out = 3,
};
struct fh_audio_cfg_arg{
enum io_select io_type;
int volume;
int rate;
int frame_bit;
int channels;
int buffer_size;
int period_size;
};
typedef struct{
unsigned int len;
unsigned char *data;
}FH_AC_FRAME_S;
typedef enum{
FH_AC_MIC_IN = 0,
FH_AC_LINE_IN = 1,
FH_AC_SPK_OUT = 2,
FH_AC_LINE_OUT = 3
}FH_AC_IO_TYPE_E;
typedef struct {
FH_AC_IO_TYPE_E io_type;
FH_AC_SAMPLE_RATE_E sample_rate;
FH_AC_BIT_WIDTH_E bit_width;
unsigned int channels;
unsigned int period_size;
unsigned int volume;
} FH_AC_CONFIG;
struct device_dma_parameters {
/*
* a low level driver may set these to teach IOMMU code about
* sg limitations.
*/
unsigned int max_segment_size;
unsigned long segment_boundary_mask;
};
struct list_head {
struct list_head *next;
struct list_head *prev;
};
struct dma_coherent_mem {
void *virt_base;
dma_addr_t device_base;
int size;
int flags;
unsigned long *bitmap;
};
struct device_acw{
unsigned long long *dma_mask; /* dma mask (if dma'able device) */
unsigned long long coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
struct device_dma_parameters *dma_parms;
struct list_head dma_pools;
struct dma_coherent_mem *dma_mem;
};
#define false 0
#define true 1
#define AC_INIT_CAPTURE_MEM 0x10
#define AC_INIT_PLAYBACK_MEM 0x11
#define AC_SET_VOL 0x12
#define AC_SET_INPUT_MODE 0x13
#define AC_SET_OUTPUT_MODE 0x14
#define AC_AI_EN 0x15
#define AC_AO_EN 0x16
#define AC_AI_DISABLE 0x17
#define AC_AO_DISABLE 0x18
#define AC_AI_PAUSE 0x19
#define AC_AI_RESUME 0x1a
#define AC_AO_PAUSE 0x1b
#define AC_AO_RESUME 0x1c
#define AC_MIC_BOOST 0x1d
#define POLLIN 0x001 /* There is data to read. */
#define POLLPRI 0x002 /* There is urgent data to read. */
#define POLLOUT 0x004 /* Writing now will not block. */
/* These values are defined in XPG4.2. */
# define POLLRDNORM 0x040 /* Normal data may be read. */
# define POLLRDBAND 0x080 /* Priority data may be read. */
# define POLLWRNORM 0x100 /* Writing now will not block. */
# define POLLWRBAND 0x200 /* Priority data may be written. */
/* These are extensions for Linux. */
# define POLLMSG 0x400
# define POLLREMOVE 0x1000
# define POLLRDHUP 0x2000
/* Event types always implicitly polled for. These bits need not be set in
`events', but they will appear in `revents' to indicate the status of
the file descriptor. */
#define POLLERR 0x008 /* Error condition. */
#define POLLHUP 0x010 /* Hung up. */
#define POLLNVAL 0x020 /* Invalid polling request. */
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
extern void fh_audio_init(void);
extern void fh_acw_test();
#endif

View File

@ -1,170 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
*****************************************************************************/
#include "drivers/dma.h"
/*****************************************************************************
* Define section
* add all #define here
*****************************************************************************/
/****************************************************************************
* ADT section
* add definition of user defined Data Type that only be used in this file here
***************************************************************************/
/******************************************************************************
* Function prototype section
* add prototypes for all functions called by this file,execepting those
* declared in header file
*****************************************************************************/
/*****************************************************************************
* Global variables section - Exported
* add declaration of global variables that will be exported here
* e.g.
* int8_t foo;
****************************************************************************/
/*****************************************************************************
* static fun;
*****************************************************************************/
static rt_err_t rt_dma_init(struct rt_device *dev);
static rt_err_t rt_dma_open(struct rt_device *dev, rt_uint16_t oflag);
static rt_err_t rt_dma_close(struct rt_device *dev);
static rt_err_t rt_dma_control(struct rt_device *dev,
rt_uint8_t cmd,
void *args);
/*****************************************************************************
* Global variables section - Local
* define global variables(will be refered only in this file) here,
* static keyword should be used to limit scope of local variable to this file
* e.g.
* static uint8_t ufoo;
*****************************************************************************/
/* function body */
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
static rt_err_t rt_dma_init(struct rt_device *dev)
{
struct rt_dma_device *dma;
RT_ASSERT(dev != RT_NULL);
dma = (struct rt_dma_device *)dev;
if (dma->ops->init)
{
return (dma->ops->init(dma));
}
return (-RT_ENOSYS);
}
static rt_err_t rt_dma_open(struct rt_device *dev, rt_uint16_t oflag)
{
return (RT_EOK);
}
static rt_err_t rt_dma_close(struct rt_device *dev)
{
struct rt_dma_device *dma;
RT_ASSERT(dev != RT_NULL);
dma = (struct rt_dma_device *)dev;
if (dma->ops->control(dma, RT_DEVICE_CTRL_DMA_CLOSE, RT_NULL) != RT_EOK)
{
return (-RT_ERROR);
}
return (RT_EOK);
}
static rt_err_t rt_dma_control(struct rt_device *dev,
rt_uint8_t cmd,
void *args)
{
struct rt_dma_device *dma;
RT_ASSERT(dev != RT_NULL);
dma = (struct rt_dma_device *)dev;
//args is the private data for the soc!!
return (dma->ops->control(dma, cmd, args));
}
/**
* This function register a dma device
*/
rt_err_t rt_hw_dma_register(struct rt_dma_device *dma,
const char *name,
rt_uint32_t flag,
void *data)
{
rt_uint32_t ret;
struct rt_device *device;
RT_ASSERT(dma != RT_NULL);
device = &(dma->parent);
device->type = RT_Device_Class_Miscellaneous;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->init = rt_dma_init;
device->open = rt_dma_open;
device->close = rt_dma_close;
device->read = RT_NULL;
device->write = RT_NULL;
device->control = rt_dma_control;
device->user_data = data;
/* register a character device */
ret = rt_device_register(device, name, flag);
rt_kprintf("dma ret is :%x\n",ret);
return ret;
}

View File

@ -1,107 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef DMA_H_
#define DMA_H_
#include <rtthread.h>
/****************************************************************************
* #include section
* add #include here if any
***************************************************************************/
/****************************************************************************
* #define section
* add constant #define here if any
***************************************************************************/
#define RT_DEVICE_CTRL_DMA_OPEN (1)
#define RT_DEVICE_CTRL_DMA_CLOSE (2)
#define RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL (3)
#define RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL (4)
#define RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER (5)
//cyclic add func below....
#define RT_DEVICE_CTRL_DMA_CYCLIC_PREPARE (6)
#define RT_DEVICE_CTRL_DMA_CYCLIC_START (7)
#define RT_DEVICE_CTRL_DMA_CYCLIC_STOP (8)
#define RT_DEVICE_CTRL_DMA_CYCLIC_FREE (9)
//#define RT_DEVICE_CTRL_ (3) /* get the left time before reboot(in seconds) */
//#define RT_DEVICE_CTRL_ (4) /* refresh watchdog */
//#define RT_DEVICE_CTRL_ (5) /* start watchdog */
//#define RT_DEVICE_CTRL_ (6) /* stop watchdog */
/****************************************************************************
* ADT section
* add Abstract Data Type definition here
***************************************************************************/
struct rt_dma_ops;
struct rt_dma_device
{
// the parent must be the fitst para..
struct rt_device parent;
struct rt_dma_ops *ops;
};
struct rt_dma_ops
{
rt_err_t (*init)(struct rt_dma_device *dma);
rt_err_t (*control)(struct rt_dma_device *dma, int cmd, void *arg);
};
/****************************************************************************
* extern variable declaration section
***************************************************************************/
/****************************************************************************
* section
* add function prototype here if any
***************************************************************************/
rt_err_t rt_hw_dma_register(struct rt_dma_device *dma,
const char *name,
rt_uint32_t flag,
void *data);
/********************************End Of File********************************/
#endif

View File

@ -1,122 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
*****************************************************************************/
#include "dma_mem.h"
#ifdef RT_USING_DMA_MEM
/*****************************************************************************
* Define section
* add all #define here
*****************************************************************************/
//#define FH_TEST_DMA_MEM
/****************************************************************************
* ADT section
* add definition of user defined Data Type that only be used in this file here
***************************************************************************/
/******************************************************************************
* Function prototype section
* add prototypes for all functions called by this file,execepting those
* declared in header file
*****************************************************************************/
/*****************************************************************************
* Global variables section - Exported
* add declaration of global variables that will be exported here
* e.g.
* int8_t foo;
****************************************************************************/
/*****************************************************************************
* static fun;
*****************************************************************************/
/*****************************************************************************
* Global variables section - Local
* define global variables(will be refered only in this file) here,
* static keyword should be used to limit scope of local variable to this file
* e.g.
* static uint8_t ufoo;
*****************************************************************************/
static struct rt_memheap dma_heap = {0};
/* function body */
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
rt_err_t fh_dma_mem_init(rt_uint32_t *mem_start,rt_uint32_t size){
return rt_memheap_init(&dma_heap,"dma_heap",mem_start,size);
}
void *fh_dma_mem_malloc(rt_uint32_t size){
return rt_memheap_alloc(&dma_heap, size);
}
void fh_dma_mem_free(void *ptr){
rt_memheap_free(ptr);
}
#ifdef FH_TEST_DMA_MEM
int dma_mem_debug(void *ptr){
//rt_memheap_free(ptr);
rt_kprintf("dma mem start 0x%08x\n",(rt_uint32_t)dma_heap.start_addr);
rt_kprintf("dma mem total size 0x%08x\n",dma_heap.pool_size);
rt_kprintf("dma mem left size 0x%08x\n",dma_heap.available_size);
rt_kprintf("dma mem max use size 0x%08x\n",dma_heap.max_used_size);
return 0;
}
#endif
#ifdef RT_USING_FINSH
#include <finsh.h>
#ifdef FH_TEST_DMA_MEM
FINSH_FUNCTION_EXPORT(dma_mem_debug, dma_start & left size & max_use);
#endif
#endif
#endif

View File

@ -1,76 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef DMA_MEM_H_
#define DMA_MEM_H_
#ifndef RT_USING_MEMHEAP
#define RT_USING_MEMHEAP
#endif
#include <rtthread.h>
/****************************************************************************
* #include section
* add #include here if any
***************************************************************************/
/****************************************************************************
* #define section
* add constant #define here if any
***************************************************************************/
/****************************************************************************
* ADT section
* add Abstract Data Type definition here
***************************************************************************/
/****************************************************************************
* extern variable declaration section
***************************************************************************/
/****************************************************************************
* section
* add function prototype here if any
***************************************************************************/
#ifdef RT_USING_DMA_MEM
rt_err_t fh_dma_mem_init(rt_uint32_t *mem_start,rt_uint32_t size);
void *fh_dma_mem_malloc(rt_uint32_t size);
void fh_dma_mem_free(void *ptr);
/********************************End Of File********************************/
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,254 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_DMA_H_
#define FH_DMA_H_
/****************************************************************************
* #include section
* add #include here if any
***************************************************************************/
#include <rtthread.h>
/*********************************
*
* DMA SOC define start
*
*********************************/
#define FH81_MAX_CHANNEL (4)
#define FH81_CHANNEL_MAX_TRANSFER_SIZE (4095)
enum DMA_HW_HS_MAP{
ACODEC_RX = 0,
ACODEC_TX,
SPI0_RX,
SPI0_TX,
SPI1_RX,
SPI1_TX,
UART0_RX,
UART0_TX,
UART1_RX,
UART1_TX,
DMA_HW_HS_END,
};
/*********************************
*
* DMA SOC define end
*
*********************************/
//user use the dma could use callback function,when the dma make the work done...
typedef void (*dma_complete_callback)(void *complete_para);
typedef void (*user_prepare)(void *prepare_para);
/**************************** i'm cut-off line ************************************/
//controller private para...
struct fh81_dma;
struct dw_lli {
/* values that are not changed by hardware */
rt_uint32_t sar;
rt_uint32_t dar;
rt_uint32_t llp; /* chain to next lli */
rt_uint32_t ctllo;
/* values that may get written back: */
rt_uint32_t ctlhi;
/* sstat and dstat can snapshot peripheral register state.
* silicon config may discard either or both...
*/
rt_uint32_t sstat;
rt_uint32_t dstat;
rt_uint32_t reserve;
};
//transfer use below
struct dma_transfer{
//this is private for the dma drive....app don't touch it,the driver will manger it
//link interface for more transfer to the controller...
rt_list_t transfer_list;
struct fh81_dma *dma_controller;
//this the mem add....the dma controller will load the setting to move data ....
//user don't touch it
struct dw_lli *first_lli;
rt_uint32_t lli_size;
//new add for allign get desc...
rt_uint32_t actual_lli_size;
//user could set paras below~~~
#define AUTO_FIND_CHANNEL (0xff)
//transfer with which dma channel...if the data is 0xff, the driver will auto find a free channel.
rt_uint32_t channel_number;
//which dma you want to use...for fh81....only 0!!!
rt_uint32_t dma_number;
//user should set the para below
#define DMA_M2M (0) // MEM <=> MEM
#define DMA_M2P (1) // MEM => peripheral A
#define DMA_P2M (2) // MEM <= peripheral A
#define DMA_P2P (3) // peripheral A <=> peripheral B
rt_uint32_t fc_mode;//ip->mem. mem->mem. mem->ip
#define DMA_HW_HANDSHAKING (0)
#define DMA_SW_HANDSHAKING (1)
rt_uint32_t src_hs; //src
//if use hw handshaking ,you need to set the hw handshaking number, this SOC defined
rt_uint32_t src_per; //src hw handshake number
//rt_uint32_t irq_mode;//for each transfer,irq maybe not same. suggest for the default(transfer isr)
#define DW_DMA_SLAVE_WIDTH_8BIT (0)
#define DW_DMA_SLAVE_WIDTH_16BIT (1)
#define DW_DMA_SLAVE_WIDTH_32BIT (2)
rt_uint32_t src_width;
//the user should reference the hw handshaking watermark..
#define DW_DMA_SLAVE_MSIZE_1 (0)
#define DW_DMA_SLAVE_MSIZE_4 (1)
#define DW_DMA_SLAVE_MSIZE_8 (2)
#define DW_DMA_SLAVE_MSIZE_16 (3)
#define DW_DMA_SLAVE_MSIZE_32 (4)
#define DW_DMA_SLAVE_MSIZE_64 (5)
#define DW_DMA_SLAVE_MSIZE_128 (6)
#define DW_DMA_SLAVE_MSIZE_256 (7)
rt_uint32_t src_msize;
rt_uint32_t src_add;
#define DW_DMA_SLAVE_INC (0)
#define DW_DMA_SLAVE_DEC (1)
#define DW_DMA_SLAVE_FIX (2)
rt_uint32_t src_inc_mode; //increase mode: increase or not change
//#define DMA_DST_HW_HANDSHAKING (0)
//#define DMA_DST_SW_HANDSHAKING (1)
rt_uint32_t dst_hs; //src
//if use hw handshaking ,you need to set the hw handshaking number, this SOC defined
rt_uint32_t dst_per; //dst hw handshake number
//#define DW_DMA_SLAVE_WIDTH_8BIT (0)
//#define DW_DMA_SLAVE_WIDTH_16BIT (1)
//#define DW_DMA_SLAVE_WIDTH_32BIT (2)
rt_uint32_t dst_width;
//#define DW_DMA_SLAVE_MSIZE_1 (0)
//#define DW_DMA_SLAVE_MSIZE_4 (1)
//#define DW_DMA_SLAVE_MSIZE_8 (2)
//#define DW_DMA_SLAVE_MSIZE_16 (3)
//#define DW_DMA_SLAVE_MSIZE_32 (4)
//#define DW_DMA_SLAVE_MSIZE_64 (5)
//#define DW_DMA_SLAVE_MSIZE_128 (6)
//#define DW_DMA_SLAVE_MSIZE_256 (7)
rt_uint32_t dst_msize;
rt_uint32_t dst_add;
//#define DW_DMA_SLAVE_INC (0)
//#define DW_DMA_SLAVE_DEC (1)
//#define DW_DMA_SLAVE_FIX (2)
rt_uint32_t dst_inc_mode; //increase mode: increase or not change
//total sizes, unit: src_width/DW_DMA_SLAVE_WIDTH_8BIT...
//exg: src_width = DW_DMA_SLAVE_WIDTH_32BIT. trans_len = 2...means that: the dma will transfer 2*4 bytes..
//exg: src_width = DW_DMA_SLAVE_WIDTH_8BIT. trans_len = 6...means that: the dma will transfer 1*6 bytes..
rt_uint32_t trans_len;
//this is used when dma finish transfer job
dma_complete_callback complete_callback;
void *complete_para; //for the driver data use the dma driver.
//this is used when dma before work..the user maybe need to set his own private para..
user_prepare prepare_callback;
void *prepare_para;
//add cyclic para...
//period len..
rt_uint32_t period_len;
};
/****************************************************************************
* #define section
* add constant #define here if any
***************************************************************************/
/****************************************************************************
* ADT section
* add Abstract Data Type definition here
***************************************************************************/
/****************************************************************************
* extern variable declaration section
***************************************************************************/
/****************************************************************************
* section
* add function prototype here if any
***************************************************************************/
rt_err_t fh81_dma_register(struct fh81_dma * fh81_dma_p,
char * dma_name);
void rt_fh_dma_init(void);
/********************************End Of File********************************/
#endif /* FH81_DMA_H_ */

View File

@ -1,450 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "fh_def.h"
#include "gpio.h"
#include "libraries/inc/fh_gpio.h"
#include "interrupt.h"
#include "board_info.h"
#include <rtdevice.h>
#include "fh_arch.h"
//#define FH_GPIO_DEBUG
#ifdef FH_GPIO_DEBUG
#define PRINT_GPIO_DBG(fmt, args...) \
do \
{ \
rt_kprintf("FH_GPIO_DEBUG: "); \
rt_kprintf(fmt, ## args); \
} \
while(0)
#else
#define PRINT_GPIO_DBG(fmt, args...) do { } while (0)
#endif
int gpio_available[NUM_OF_GPIO];
extern struct rt_irq_desc irq_desc[];
static inline rt_uint32_t gpio_to_base(rt_uint32_t gpio)
{
if (gpio >= 32 && gpio < 64)
{
return GPIO1_REG_BASE;
}
else if(gpio < 32)
{
return GPIO0_REG_BASE;
}
else
{
rt_kprintf("ERROR: %s, incorrect GPIO num\n", __func__);
return -RT_ERROR;
}
}
static inline rt_uint32_t irq_to_base(rt_uint32_t irq)
{
return (irq-NR_INTERNAL_IRQS > 32) ? GPIO1_REG_BASE : GPIO0_REG_BASE;
}
static inline rt_uint32_t irq_to_bit(rt_uint32_t irq)
{
if(irq >= NR_INTERNAL_IRQS && irq < NR_INTERNAL_IRQS + 32)
return 0;
else
return 32;
}
rt_uint32_t gpio_to_irq(rt_uint32_t gpio)
{
return (gpio + NR_INTERNAL_IRQS);
}
void gpio_enable_debounce(rt_uint32_t gpio)
{
rt_uint32_t tmp, base, offset;
offset = gpio % 32;
base = gpio_to_base(gpio);
tmp = GET_REG(base + REG_GPIO_DEBOUNCE);
tmp |= BIT(offset);
SET_REG(base + REG_GPIO_DEBOUNCE, tmp);
}
void gpio_disable_debounce(rt_uint32_t gpio)
{
rt_uint32_t tmp, base, offset;
offset = gpio % 32;
base = gpio_to_base(gpio);
tmp = GET_REG(base + REG_GPIO_DEBOUNCE);
tmp &= ~BIT(offset);
SET_REG(base + REG_GPIO_DEBOUNCE, tmp);
}
int gpio_get_value(rt_uint32_t gpio)
{
rt_uint32_t tmp, base, offset;
offset = gpio % 32;
base = gpio_to_base(gpio);
tmp = GET_REG(base + REG_GPIO_SWPORTA_DDR);
tmp &= BIT(offset);
if (tmp) {
tmp = GET_REG(base + REG_GPIO_SWPORTA_DR);
} else {
tmp = GET_REG(base + REG_GPIO_EXT_PORTA);
}
tmp &= BIT(offset);
tmp = tmp >> offset;
return tmp;
}
void gpio_set_value(rt_uint32_t gpio, int val)
{
rt_uint32_t tmp, base, offset;
offset = gpio % 32;
base = gpio_to_base(gpio);
tmp = GET_REG(base + REG_GPIO_SWPORTA_DR);
if(val)
tmp |= BIT(offset);
else
tmp &= ~BIT(offset);
SET_REG(base + REG_GPIO_SWPORTA_DR, tmp);
}
int gpio_get_direction(rt_uint32_t gpio)
{
rt_uint32_t tmp, base, offset;
offset = gpio % 32;
base = gpio_to_base(gpio);
tmp = GET_REG(base + REG_GPIO_SWPORTA_DDR);
tmp &= BIT(offset);
tmp = tmp >> offset;
return tmp;
}
void gpio_set_direction(rt_uint32_t gpio, rt_uint32_t direction)
{
rt_uint32_t tmp, base, offset;
offset = gpio % 32;
base = gpio_to_base(gpio);
tmp = GET_REG(base + REG_GPIO_SWPORTA_DDR);
if(direction == GPIO_DIR_OUTPUT)
tmp |= BIT(offset);
else
tmp &= ~BIT(offset);
SET_REG(base + REG_GPIO_SWPORTA_DDR, tmp);
}
int gpio_set_irq_type(rt_uint32_t gpio, rt_uint32_t type)
{
rt_uint32_t int_type, int_polarity;
rt_uint32_t bit = gpio % 32;
rt_uint32_t base;
base = gpio_to_base(gpio);
int_type = GET_REG(base + REG_GPIO_INTTYPE_LEVEL);
int_polarity = GET_REG(base + REG_GPIO_INT_POLARITY);
switch (type & IRQ_TYPE_TRIGGER_MASK) {
case IRQ_TYPE_EDGE_BOTH:
int_type |= BIT(bit);
// toggle trigger
if (gpio_get_value(gpio))
int_polarity &= ~BIT(bit);
else
int_polarity |= BIT(bit);
break;
case IRQ_TYPE_EDGE_RISING:
int_type |= BIT(bit);
int_polarity |= BIT(bit);
break;
case IRQ_TYPE_EDGE_FALLING:
int_type |= BIT(bit);
int_polarity &= ~BIT(bit);
break;
case IRQ_TYPE_LEVEL_HIGH:
int_type &= ~BIT(bit);
int_polarity |= BIT(bit);
break;
case IRQ_TYPE_LEVEL_LOW:
int_type &= ~BIT(bit);
int_polarity &= ~BIT(bit);
break;
case IRQ_TYPE_NONE:
return 0;
default:
return -RT_ERROR;
}
SET_REG(base + REG_GPIO_INTTYPE_LEVEL, int_type);
SET_REG(base + REG_GPIO_INT_POLARITY, int_polarity);
return 0;
}
int gpio_irq_mask(rt_uint32_t irq)
{
rt_uint32_t tmp, base, bit;
base = irq_to_base(irq);
bit = irq_to_bit(irq);
tmp = GET_REG(base + REG_GPIO_INTMASK);
tmp |= BIT(irq - NR_INTERNAL_IRQS - bit);
SET_REG(base + REG_GPIO_INTMASK, tmp);
return 0;
}
int gpio_irq_unmask(rt_uint32_t irq)
{
rt_uint32_t tmp, base, bit;
base = irq_to_base(irq);
bit = irq_to_bit(irq);
tmp = GET_REG(base + REG_GPIO_INTMASK);
tmp &= ~BIT((irq - NR_INTERNAL_IRQS - bit));
SET_REG(base + REG_GPIO_INTMASK, tmp);
return 0;
}
void gpio_irq_enable(rt_uint32_t irq)
{
rt_uint32_t tmp, base, bit;
base = irq_to_base(irq);
bit = irq_to_bit(irq);
tmp = GET_REG(base + REG_GPIO_INTEN);
tmp |= BIT(irq - NR_INTERNAL_IRQS - bit);
SET_REG(base + REG_GPIO_INTEN, tmp);
}
void gpio_irq_disable(rt_uint32_t irq)
{
rt_uint32_t tmp, base, bit;
base = irq_to_base(irq);
bit = irq_to_bit(irq);
tmp = GET_REG(base + REG_GPIO_INTEN);
tmp &= ~BIT((irq - NR_INTERNAL_IRQS - bit));
SET_REG(base + REG_GPIO_INTEN, tmp);
}
static void fh_gpio_interrupt(int irq, void *param)
{
rt_uint32_t irq_status;
int gpio_num, gpio;
rt_uint32_t base;
struct fh_gpio_obj *gpio_obj = (struct fh_gpio_obj *)param;
//rt_kprintf("fh_gpio_interrupt start\n");
//fixme: spin lock???
base = (irq==40) ? GPIO0_REG_BASE : GPIO1_REG_BASE;
irq_status = GET_REG(base + REG_GPIO_INTSTATUS);
if (irq_status == 0) {
rt_kprintf("gpio irq status is zero.\n");
return;
}
/* temporarily mask (level sensitive) parent IRQ */
gpio_irq_mask(irq);
gpio_num = __rt_ffs(irq_status) - 1;
SET_REG(base + REG_GPIO_PORTA_EOI, BIT(gpio_num));
gpio = gpio_num + ((irq==40) ? 0 : 32);
//generic_handle_irq(gpio_to_irq(gpio));
if(irq_desc[gpio_to_irq(gpio)].handler)
irq_desc[gpio_to_irq(gpio)].handler(gpio_to_irq(gpio), irq_desc[gpio_to_irq(gpio)].param);
gpio_irq_mask(irq);
/* now it may re-trigger */
}
int gpio_direction_input(rt_uint32_t gpio)
{
rt_uint32_t reg, base;
if(gpio > NUM_OF_GPIO)
{
rt_kprintf("ERROR: %s, incorrect GPIO num\n", __func__);
return -RT_ERROR;
}
if(!gpio_available[gpio])
{
rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio);
return -RT_EBUSY;
}
base = gpio_to_base(gpio);
gpio = gpio % 32;
//fixme: lock
//spin_lock_irqsave(&chip->lock, flags);
reg = GET_REG(base + REG_GPIO_SWPORTA_DDR);
reg &= ~(1 << gpio);
SET_REG(base + REG_GPIO_SWPORTA_DDR, reg);
//spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
int gpio_direction_output(rt_uint32_t gpio, rt_uint32_t val)
{
rt_uint32_t reg, base;
if(gpio > NUM_OF_GPIO)
{
rt_kprintf("ERROR: %s, incorrect GPIO num\n", __func__);
return -RT_ERROR;
}
if(!gpio_available[gpio])
{
rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio);
return -RT_EBUSY;
}
base = gpio_to_base(gpio);
gpio = gpio % 32;
//fixme: lock
//spin_lock_irqsave(&chip->lock, flags);
reg = GET_REG(base + REG_GPIO_SWPORTA_DDR);
reg |= (1 << gpio);
SET_REG(base + REG_GPIO_SWPORTA_DDR, reg);
reg = GET_REG(base + REG_GPIO_SWPORTA_DR);
if(val)
reg |= (1 << gpio);
else
reg &= ~(1 << gpio);
SET_REG(base + REG_GPIO_SWPORTA_DR, reg);
//spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
int gpio_request(rt_uint32_t gpio)
{
if(gpio > NUM_OF_GPIO)
{
rt_kprintf("ERROR: %s, incorrect GPIO num\n", __func__);
return -RT_ERROR;
}
gpio_available[gpio] = 1;
return 0;
}
int gpio_release(rt_uint32_t gpio)
{
if(gpio > NUM_OF_GPIO)
{
rt_kprintf("ERROR: %s, incorrect GPIO num\n", __func__);
return -RT_ERROR;
}
gpio_available[gpio] = 0;
return 0;
}
int fh_gpio_probe(void *priv_data)
{
struct fh_gpio_obj *gpio_obj = (struct fh_gpio_obj *)priv_data;
int i;
if(gpio_obj->id == 0){
rt_hw_interrupt_install(gpio_obj->irq, fh_gpio_interrupt, (void *)gpio_obj, "gpio_0");
}
else if(gpio_obj->id == 1){
rt_hw_interrupt_install(gpio_obj->irq, fh_gpio_interrupt, (void *)gpio_obj, "gpio_1");
}
rt_hw_interrupt_umask(gpio_obj->irq);
for(i=0; i<32; i++)
{
irq_desc[NR_INTERNAL_IRQS + 32 * gpio_obj->id + i].param = gpio_obj;
}
return 0;
}
int fh_gpio_exit(void *priv_data)
{
return 0;
}
struct fh_board_ops gpio_driver_ops =
{
.probe = fh_gpio_probe,
.exit = fh_gpio_exit,
};
void rt_hw_gpio_init(void)
{
PRINT_GPIO_DBG("%s start\n", __func__);
rt_memset(gpio_available, 0, sizeof(int) * NUM_OF_GPIO);
fh_board_driver_register("gpio", &gpio_driver_ops);
PRINT_GPIO_DBG("%s end\n", __func__);
}

View File

@ -1,188 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef GPIO_H_
#define GPIO_H_
#include <rtdef.h>
/**
* GPIO interrupt trigger type macro,
* each represent an interrupt trigger mode
*
* @see gpio_set_irq_type();
*/
enum
{
IRQ_TYPE_NONE = 0x00000000, /**< none*/
IRQ_TYPE_EDGE_RISING = 0x00000001, /**< rising edge*/
IRQ_TYPE_EDGE_FALLING = 0x00000002, /**< falling edge*/
IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),
IRQ_TYPE_LEVEL_HIGH = 0x00000004, /**< high level*/
IRQ_TYPE_LEVEL_LOW = 0x00000008, /**< low level*/
IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),
IRQ_TYPE_TRIGGER_MASK = (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW | \
IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING),
};
/**
* GPIO direction macro,
* each represent a direction
*
* @see gpio_get_direction();
* @see gpio_set_direction();
*/
#define GPIO_DIR_OUTPUT 1 /**< output*/
#define GPIO_DIR_INPUT 0 /**< input*/
/**
* convert GPIO number to IRQ number
* @param gpio GPIO number to be converted
* @return IRQ number
*/
rt_uint32_t gpio_to_irq(rt_uint32_t gpio);
/**
* disable GPIO's debounce mode
* controls whether an external signal that is the source
* of an interrupt needs to be debounced to remove any
* spurious glitches.
* @param gpio GPIO number
*/
void gpio_disable_debounce(rt_uint32_t gpio);
/**
* enable GPIO's debounce mode
* controls whether an external signal that is the source
* of an interrupt needs to be debounced to remove any
* spurious glitches.
* @param gpio GPIO number
*/
void gpio_enable_debounce(rt_uint32_t gpio);
/**
* allows each GPIO to be configured for interrupts
* it configures the corresponding GPIO to become an interrupt
* @param gpio GPIO number
*/
void gpio_irq_enable(rt_uint32_t irq);
/**
* GPIO operates as a normal GPIO signal
* interrupts are disabled
* @param gpio GPIO number
*/
void gpio_irq_disable(rt_uint32_t irq);
/**
* it configures the interrupt type to be
* falling-edge or active-low sensitive
* rising-edge or active-high sensitive.
* @param gpio GPIO number
* @param type interrupt type
* @return 0 if OK
*/
int gpio_set_irq_type(rt_uint32_t gpio, rt_uint32_t type);
/**
* mask the interrupt
* @param gpio GPIO number
* @return 0 if OK
*/
int gpio_irq_mask(rt_uint32_t irq);
/**
* unmask the interrupt
* @param gpio GPIO number
* @return 0 if OK
*/
int gpio_irq_unmask(rt_uint32_t irq);
/**
* get corresponding GPIO's direction
* @param gpio GPIO number
* @return 0 - input
* 1 - output
*/
int gpio_get_direction(rt_uint32_t gpio);
/**
* set corresponding GPIO's direction
* @param gpio GPIO number
* @return 0 - input
* 1 - output
*/
void gpio_set_direction(rt_uint32_t gpio, rt_uint32_t direction);
/**
* get corresponding GPIO's value
* @param gpio GPIO number
* @return GPIO value
*/
int gpio_get_value(rt_uint32_t gpio);
/**
* set corresponding GPIO's value
* @param gpio GPIO number
* @param val GPIO value
*/
void gpio_set_value(rt_uint32_t gpio, int val);
/**
* set corresponding GPIO's direction to input
* @param gpio GPIO number
* @return 0 if OK
*/
int gpio_direction_input(rt_uint32_t gpio);
/**
* set corresponding GPIO's value and set direction to output
* @param gpio GPIO number
* @param val GPIO value
* @return 0 if OK
*/
int gpio_direction_output(rt_uint32_t gpio, rt_uint32_t val);
/**
* request a GPIO
* @param gpio GPIO number
* @return 0 if OK
*/
int gpio_request(rt_uint32_t gpio);
/**
* release a GPIO
* @param gpio GPIO number
* @return 0 if OK
*/
int gpio_release(rt_uint32_t gpio);
/**
* initialize GPIO driver
*/
void rt_hw_gpio_init(void);
#endif /* GPIO_H_ */

View File

@ -1,530 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rtdevice.h>
#include <rthw.h>
#include "i2c.h"
#include "inc/fh_driverlib.h"
#include "board_info.h"
//#define FH_I2C_DEBUG
#ifdef FH_I2C_DEBUG
#define PRINT_I2C_DBG(fmt, args...) \
do \
{ \
rt_kprintf("FH_I2C_DEBUG: "); \
rt_kprintf(fmt, ## args); \
} \
while(0)
#else
#define PRINT_I2C_DBG(fmt, args...) do { } while (0)
#endif
static void fh_i2c_xfer_init(struct rt_i2c_bus_device *dev, struct rt_i2c_msg msgs[], rt_uint32_t num)
{
struct i2c_driver *i2c_drv = (struct i2c_driver *)dev->priv;
struct fh_i2c_obj *i2c_obj = (struct fh_i2c_obj *)i2c_drv->priv;
rt_uint32_t ic_con;
/* if the slave address is ten bit address, ERROR*/
if (msgs[i2c_drv->msg_write_idx].flags & I2C_M_TEN)
{
rt_kprintf("ERROR: %s, ten bit address is NOT supported\n", __func__);
return;
}
/* Disable the adapter */
I2C_WaitMasterIdle(i2c_obj);
I2C_Enable(i2c_obj, RT_FALSE);
/* set the slave (target) address */
I2C_SetSlaveAddress(i2c_obj, msgs[i2c_drv->msg_write_idx].addr);
/* Enable interrupts */
I2C_SetInterruptMask(i2c_obj, DW_IC_INTR_DEFAULT_MASK);
/* Enable the adapter */
I2C_Enable(i2c_obj, RT_TRUE);
}
static rt_size_t fh_i2c_xfer(struct rt_i2c_bus_device *dev,
struct rt_i2c_msg msgs[], rt_uint32_t num)
{
struct i2c_driver *i2c_drv = (struct i2c_driver *)dev->priv;
struct fh_i2c_obj *i2c_obj = (struct fh_i2c_obj *)i2c_drv->priv;
int ret;
struct rt_i2c_msg *pmsg = RT_NULL;
PRINT_I2C_DBG(">>>>>>>>>>>>>%s start\n", __func__);
rt_completion_init(&i2c_drv->transfer_completion);
ret = rt_mutex_take(i2c_drv->lock, RT_WAITING_FOREVER);
if (ret != RT_EOK) {
goto done;
}
i2c_drv->msgs = msgs;
i2c_drv->msgs_num = num;
i2c_drv->msg_read_idx = 0;
i2c_drv->msg_write_idx = 0;
i2c_drv->cmd_err = 0;
i2c_drv->msg_err = 0;
i2c_drv->status = STATUS_IDLE;
i2c_obj->abort_source = 0;
ret = I2C_WaitDeviceIdle(i2c_obj);
if (ret < 0)
{
//I2C_SetDataCmd(i2c_obj, 0x200);
//goto done;
}
fh_i2c_xfer_init(dev, msgs, num);
ret = rt_completion_wait(&i2c_drv->transfer_completion, RT_TICK_PER_SECOND);
PRINT_I2C_DBG("%s transfer finished\n", "rt_completion_wait");
if(ret)
{
rt_kprintf("ERROR: %s, transfer timeout\n", __func__);
I2C_SetDataCmd(i2c_obj, 0x200);
I2C_Init(i2c_obj);
ret = -RT_ETIMEOUT;
goto done;
}
if (i2c_drv->msg_err)
{
rt_kprintf("i2c_priv->msg_err: %d\n", i2c_drv->msg_err);
ret = i2c_drv->msg_err;
goto done;
}
/* no error */
if (!i2c_drv->cmd_err)
{
/* Disable the adapter */
I2C_WaitMasterIdle(i2c_obj);
I2C_Enable(i2c_obj, RT_FALSE);
ret = num;
goto done;
}
/* We have an error */
if (i2c_drv->cmd_err == DW_IC_ERR_TX_ABRT)
{
rt_kprintf("ERROR: %s, i2c_priv>cmd_err == DW_IC_ERR_TX_ABRT\n", __func__);
ret = I2C_HandleTxAbort(i2c_obj);
goto done;
}
ret = 1;
done:
I2C_Enable(i2c_obj, RT_FALSE);
rt_mutex_release(i2c_drv->lock);
PRINT_I2C_DBG(">>>>>>>>>>>>>%s end\n", __func__);
return ret;
}
/*
* Initiate (and continue) low level master read/write transaction.
* This function is only called from i2c_fh_isr, and pumping i2c_msg
* messages into the tx buffer. Even if the size of i2c_msg data is
* longer than the size of the tx buffer, it handles everything.
*/
static void i2c_fh_xfer_msg(struct rt_i2c_bus_device *dev)
{
struct i2c_driver *i2c_drv = (struct i2c_driver *)dev->priv;
struct fh_i2c_obj *i2c_obj = (struct fh_i2c_obj *)i2c_drv->priv;
struct rt_i2c_msg *msgs = i2c_drv->msgs;
rt_uint32_t intr_mask, cmd;
int tx_limit, rx_limit;
rt_uint32_t addr = msgs[i2c_drv->msg_write_idx].addr;
rt_uint32_t buf_len = i2c_drv->tx_buf_len;
rt_uint8_t *buf = i2c_drv->tx_buf;
PRINT_I2C_DBG("%s start, msgs_num: %d, write_idx: %d\n", __func__, i2c_drv->msgs_num, i2c_drv->msg_write_idx);
intr_mask = DW_IC_INTR_DEFAULT_MASK;
for (; i2c_drv->msg_write_idx < i2c_drv->msgs_num; i2c_drv->msg_write_idx++)
{
/*
* if target address has changed, we need to
* reprogram the target address in the i2c
* adapter when we are done with this transfer
*/
if (msgs[i2c_drv->msg_write_idx].addr != addr) {
rt_kprintf(
"ERROR: %s, invalid target address\n", __func__);
i2c_drv->msg_err = 1;
break;
}
if (msgs[i2c_drv->msg_write_idx].len == 0) {
rt_kprintf(
"ERROR: %s, invalid message length\n", __func__);
i2c_drv->msg_err = 1;
break;
}
if (!(i2c_drv->status & STATUS_WRITE_IN_PROGRESS))
{
/* new i2c_msg */
buf = msgs[i2c_drv->msg_write_idx].buf;
buf_len = msgs[i2c_drv->msg_write_idx].len;
PRINT_I2C_DBG("new msg: len: %d, buf: 0x%x\n", buf_len, buf[0]);
}
tx_limit = i2c_obj->config.tx_fifo_depth - I2C_GetTransmitFifoLevel(i2c_obj);
rx_limit = i2c_obj->config.rx_fifo_depth - I2C_GetReceiveFifoLevel(i2c_obj);
while (buf_len > 0 && tx_limit > 0 && rx_limit > 0)
{
if (msgs[i2c_drv->msg_write_idx].flags & RT_I2C_RD)
{
cmd = 0x100;
rx_limit--;
}
else
{
cmd = *buf++;
}
tx_limit--; buf_len--;
if(!buf_len)
{
//2015-11-8 ar0130 bug fixed
while(I2C_GetTransmitFifoLevel(i2c_obj));
cmd |= 0x200;
}
I2C_SetDataCmd(i2c_obj, cmd);
}
i2c_drv->tx_buf = buf;
i2c_drv->tx_buf_len = buf_len;
if (buf_len > 0)
{
/* more bytes to be written */
i2c_drv->status |= STATUS_WRITE_IN_PROGRESS;
break;
}
else
{
i2c_drv->status &= ~STATUS_WRITE_IN_PROGRESS;
}
}
/*
* If i2c_msg index search is completed, we don't need TX_EMPTY
* interrupt any more.
*/
if (i2c_drv->msg_write_idx == i2c_drv->msgs_num)
intr_mask &= ~DW_IC_INTR_TX_EMPTY;
if (i2c_drv->msg_err)
{
rt_kprintf("ERROR: %s, msg_err: %d\n", __func__, i2c_drv->msg_err);
intr_mask = 0;
}
I2C_SetInterruptMask(i2c_obj, intr_mask);
PRINT_I2C_DBG("%s end\n", __func__);
}
static void i2c_fh_read(struct rt_i2c_bus_device *dev)
{
struct i2c_driver *i2c_drv = (struct i2c_driver *)dev->priv;
struct fh_i2c_obj *i2c_obj = (struct fh_i2c_obj *)i2c_drv->priv;
struct rt_i2c_msg *msgs = i2c_drv->msgs;
int rx_valid;
PRINT_I2C_DBG("%s start, msgs_num: %d, read_idx: %d\n", __func__, i2c_drv->msgs_num, i2c_drv->msg_read_idx);
for (; i2c_drv->msg_read_idx < i2c_drv->msgs_num; i2c_drv->msg_read_idx++)
{
rt_uint32_t len;
rt_uint8_t *buf;
if (!(msgs[i2c_drv->msg_read_idx].flags & RT_I2C_RD))
continue;
if (!(i2c_drv->status & STATUS_READ_IN_PROGRESS))
{
len = msgs[i2c_drv->msg_read_idx].len;
buf = msgs[i2c_drv->msg_read_idx].buf;
}
else
{
PRINT_I2C_DBG("STATUS_READ_IN_PROGRESS\n");
len = i2c_drv->rx_buf_len;
buf = i2c_drv->rx_buf;
}
rx_valid = I2C_GetReceiveFifoLevel(i2c_obj);
if(rx_valid == 0)
{
rt_kprintf("ERROR: %s, rx_valid == 0\n", __func__);
}
PRINT_I2C_DBG("%s, len=%d, rx_valid=%d\n", __func__, len, rx_valid);
for (; len > 0 && rx_valid > 0; len--, rx_valid--)
{
*buf++ = I2C_GetData(i2c_obj);
}
PRINT_I2C_DBG("i2c_fh_read, len: %d, buf[0]: 0x%x\n", msgs[i2c_drv->msg_read_idx].len, msgs[i2c_drv->msg_read_idx].buf[0]);
if (len > 0)
{
PRINT_I2C_DBG("len > 0\n");
i2c_drv->status |= STATUS_READ_IN_PROGRESS;
i2c_drv->rx_buf_len = len;
i2c_drv->rx_buf = buf;
return;
}
else
i2c_drv->status &= ~STATUS_READ_IN_PROGRESS;
}
PRINT_I2C_DBG("%s end\n", __func__);
}
/*
* Interrupt service routine. This gets called whenever an I2C interrupt
* occurs.
*/
static void fh_i2c_interrupt(int this_irq, void *dev_id)
{
struct i2c_driver *i2c_drv = dev_id;
struct rt_i2c_bus_device *i2c_bus_dev = i2c_drv->i2c_bus_dev;
struct fh_i2c_obj *i2c_obj = (struct fh_i2c_obj *)i2c_drv->priv;
rt_uint32_t stat;
stat = I2C_ClearAndGetInterrupts(i2c_obj);
PRINT_I2C_DBG("status: 0x%x, mask: 0x%x\n", stat, I2C_GetInterruptMask(i2c_obj));
if (stat & DW_IC_INTR_TX_ABRT)
{
PRINT_I2C_DBG("DW_IC_INTR_TX_ABRT\n");
i2c_drv->cmd_err |= DW_IC_ERR_TX_ABRT;
i2c_drv->status = STATUS_IDLE;
/*
* Anytime TX_ABRT is set, the contents of the tx/rx
* buffers are flushed. Make sure to skip them.
*/
I2C_SetInterruptMask(i2c_obj, 0);
goto tx_aborted;
}
if (stat & DW_IC_INTR_RX_FULL)
{
i2c_fh_read(i2c_bus_dev);
}
if (stat & DW_IC_INTR_TX_EMPTY)
{
i2c_fh_xfer_msg(i2c_bus_dev);
}
/*
* No need to modify or disable the interrupt mask here.
* i2c_fh_xfer_msg() will take care of it according to
* the current transmit status.
*/
tx_aborted:
if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || i2c_drv->msg_err)
rt_completion_done(&i2c_drv->transfer_completion);
}
static const struct rt_i2c_bus_device_ops fh_i2c_ops =
{
.master_xfer = fh_i2c_xfer,
};
int fh_i2c_probe(void *priv_data)
{
int ret;
struct i2c_driver *i2c_drv;
struct rt_i2c_bus_device *i2c_bus_dev;
struct fh_i2c_obj *i2c_obj = (struct fh_i2c_obj *)priv_data;
char i2c_dev_name[5] = {0};
PRINT_I2C_DBG("%s start\n", __func__);
i2c_bus_dev = (struct rt_i2c_bus_device*)rt_calloc(1, sizeof(struct rt_i2c_bus_device));
if (RT_NULL == i2c_bus_dev)
{
return -RT_ENOMEM;
}
i2c_bus_dev->ops = &fh_i2c_ops;
rt_sprintf(i2c_dev_name, "%s%d", "i2c", i2c_obj->id);
ret = rt_i2c_bus_device_register(i2c_bus_dev, i2c_dev_name);
if (ret != RT_EOK)
{
rt_kprintf("ERROR:rt_spi_bus_register failed, ret=%d\n", ret);
return -RT_ENOMEM;
}
//priv struct init
i2c_drv = (struct i2c_driver*)rt_calloc(1, sizeof(struct i2c_driver));
if (RT_NULL == i2c_drv)
{
return -RT_ENOMEM;
}
i2c_drv->i2c_bus_dev = i2c_bus_dev;
i2c_drv->priv = priv_data;
i2c_bus_dev->priv = i2c_drv;
i2c_drv->lock = rt_mutex_create("i2c_mux", RT_IPC_FLAG_FIFO);
if(i2c_obj->id == 0){
rt_hw_interrupt_install(i2c_obj->irq, fh_i2c_interrupt,
(void *)i2c_drv, "i2c_0");
}
else if(i2c_obj->id == 1){
rt_hw_interrupt_install(i2c_obj->irq, fh_i2c_interrupt,
(void *)i2c_drv, "i2c_1");
}
rt_hw_interrupt_umask(i2c_obj->irq);
//fixme: get from clk tree
i2c_obj->input_clock = 15000;
I2C_Init(i2c_obj);
PRINT_I2C_DBG("%s end\n", __func__);
return ret;
}
int fh_i2c_exit(void *priv_data)
{
return 0;
}
struct fh_board_ops i2c_driver_ops =
{
.probe = fh_i2c_probe,
.exit = fh_i2c_exit,
};
void rt_hw_i2c_init(void)
{
int ret;
PRINT_I2C_DBG("%s start\n", __func__);
fh_board_driver_register("i2c", &i2c_driver_ops);
PRINT_I2C_DBG("%s end\n", __func__);
//fixme: never release?
}
static rt_err_t fh_i2c_read_reg(struct rt_i2c_bus_device *fh81_i2c,
rt_uint16_t reg, rt_uint8_t *data) {
struct rt_i2c_msg msg[2];
rt_uint8_t send_buf[2];
rt_uint8_t recv_buf[1] = {0};
PRINT_I2C_DBG("%s start\n", __func__);
// send_buf[0] = ((reg >> 8) & 0xff);
send_buf[0] = (reg & 0xFF);
msg[0].addr = 0x51;
msg[0].flags = RT_I2C_WR;
msg[0].len = 1;
msg[0].buf = send_buf;
msg[1].addr = 0x51;
msg[1].flags = RT_I2C_RD;
msg[1].len = 1;
msg[1].buf = recv_buf;
rt_i2c_transfer(fh81_i2c, msg, 2);
*data = recv_buf[0];
return RT_EOK;
}
static rt_err_t fh_i2c_write_reg(struct rt_i2c_bus_device *fh81_i2c,
rt_uint16_t reg, rt_uint8_t data) {
struct rt_i2c_msg msg;
rt_uint8_t send_buf[3];
PRINT_I2C_DBG("%s start\n", __func__);
// send_buf[0] = ((reg >> 8) & 0xff);
send_buf[1] = (reg & 0xFF);
send_buf[2] = data;
msg.addr = 0x51;
msg.flags = RT_I2C_WR;
msg.len = 2;
msg.buf = send_buf;
rt_i2c_transfer(fh81_i2c, &msg, 1);
PRINT_I2C_DBG("%s end\n", __func__);
return RT_EOK;
}
void i2c_test_sensor() {
struct rt_i2c_bus_device *fh81_i2c;
struct rt_i2c_msg msg[2];
rt_uint8_t data[1] = { 0x00 };
fh81_i2c = rt_i2c_bus_device_find("i2c1");
fh_i2c_write_reg(fh81_i2c, 0x04, 0x02);
fh_i2c_read_reg(fh81_i2c, 0x02, data);
rt_kprintf("data read from 0x3038 is 0x%x\r\n", data[0]);
PRINT_I2C_DBG("%s end\n", __func__);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(i2c_test_sensor, sensor i2c test);
#endif

View File

@ -1,56 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef __FH81_I2C_H__
#define __FH81_I2C_H__
#include <rtthread.h>
struct i2c_driver
{
int cmd_err;
int msg_err;
rt_uint32_t status;
struct rt_i2c_msg *msgs;
int msgs_num;
int msg_write_idx;
rt_uint32_t tx_buf_len;
rt_uint8_t *tx_buf;
int msg_read_idx;
rt_uint32_t rx_buf_len;
rt_uint8_t *rx_buf;
struct rt_i2c_bus_device *i2c_bus_dev;
struct rt_completion transfer_completion;
rt_mutex_t lock;
void* priv;
};
void rt_hw_i2c_init(void);
#endif

View File

@ -1,216 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
*****************************************************************************/
#include "interrupt.h"
#include "fh_def.h"
#include "fh_arch.h"
#include "libraries/inc/fh_ictl.h"
/*****************************************************************************
* Define section
* add all #define here
*****************************************************************************/
#define MAX_HANDLERS (NR_INTERNAL_IRQS+NR_EXTERNAL_IRQS)
/****************************************************************************
* ADT section
* add definition of user defined Data Type that only be used in this file here
***************************************************************************/
/******************************************************************************
* Function prototype section
* add prototypes for all functions called by this file,execepting those
* declared in header file
*****************************************************************************/
/*****************************************************************************
* Global variables section - Exported
* add declaration of global variables that will be exported here
* e.g.
* int8_t foo;
****************************************************************************/
extern rt_uint32_t rt_interrupt_nest;
struct rt_irq_desc irq_desc[MAX_HANDLERS];
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
/*****************************************************************************
* Global variables section - Local
* define global variables(will be refered only in this file) here,
* static keyword should be used to limit scope of local variable to this file
* e.g.
* static uint8_t ufoo;
*****************************************************************************/
/* function body */
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
{
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
return RT_NULL;
}
/**
* This function will initialize hardware interrupt
*/
void rt_hw_interrupt_init(void)
{
rt_int32_t i;
register rt_uint32_t idx;
fh_intc *p = (fh_intc *)INTC_REG_BASE;
ictl_close_all_isr(p);
/* init exceptions table */
for(idx=0; idx < MAX_HANDLERS; idx++)
{
irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
irq_desc[idx].param = RT_NULL;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
irq_desc[idx].counter = 0;
#endif
}
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
rt_interrupt_from_thread = 0;
rt_interrupt_to_thread = 0;
rt_thread_switch_interrupt_flag = 0;
}
/**
* This function will mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_mask(int irq)
{
fh_intc *p = (fh_intc *)INTC_REG_BASE;
/* Disable irq on AIC */
ictl_mask_isr(p,irq);
// if (irq < 32)
// p->IRQ_EN_L &= ~(1 << irq);
// else
// p->IRQ_EN_H &= ~(1 << (irq - 32));
}
void rt_hw_interrupt_umask(int irq)
{
fh_intc *p = (fh_intc *)INTC_REG_BASE;
/* Enable irq on AIC */
ictl_unmask_isr(p,irq);
// if (irq < 32)
// p->IRQ_EN_L |= 1 << irq;
// else
// p->IRQ_EN_H |= 1 << (irq - 32);
}
/**
* This function will install a interrupt service routine to a interrupt.
* @param vector the interrupt number
* @param handler the interrupt service routine to be installed
* @param param the interrupt service function parameter
* @param name the interrupt name
* @return old handler
*/
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void *param, const char *name)
{
rt_isr_handler_t old_handler = RT_NULL;
if(vector < MAX_HANDLERS)
{
old_handler = irq_desc[vector].handler;
if (handler != RT_NULL)
{
irq_desc[vector].handler = (rt_isr_handler_t)handler;
irq_desc[vector].param = param;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
irq_desc[vector].counter = 0;
#endif
}
}
return old_handler;
}
#ifdef RT_USING_FINSH
void list_irq(void)
{
#ifdef RT_USING_INTERRUPT_INFO
int irq;
rt_kprintf("number\tcount\tname\n");
for (irq = 0; irq < MAX_HANDLERS; irq++)
{
if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default")))
{
rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].counter, irq_desc[irq].name);
}
}
#else
rt_kprintf("please open 'RT_USING_INTERRUPT_INFO'\n");
#endif
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(list_irq, list system irq);
#endif

View File

@ -1,40 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef INTERRUPT_H_
#define INTERRUPT_H_
#include <rthw.h>
#define NR_INTERNAL_IRQS 56
#define NR_EXTERNAL_IRQS 64
void rt_hw_interrupt_init(void);
void rt_hw_interrupt_mask(int irq);
void rt_hw_interrupt_umask(int irq);
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void *param, const char *name);
#endif /* INTERRUPT_H_ */

View File

@ -1,87 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "mmu.h"
#define CHANGLINE_SIZE (1)
//#define FH_DBG_MEM_PROCESS
#ifdef FH_DBG_MEM_PROCESS
void mem_input(rt_uint32_t t_addr, rt_uint32_t t_size, rt_uint8_t t_value) {
rt_kprintf("mem process add:%x \tsize:%x\tvalue:%x\n", t_addr, t_size,
t_value);
rt_memset((void *) t_addr, t_value, t_size);
mmu_clean_invalidated_dcache(t_addr, t_size);
}
void mem_output(rt_uint32_t t_addr, rt_uint32_t t_size) {
rt_uint32_t i;
rt_uint32_t cnt = 0;
rt_uint32_t value;
rt_uint32_t addr, size;
addr = t_addr;
if (t_size % 4) {
rt_kprintf("mem must be alligned\n");
}
size = t_size / 4;
rt_int32_t *p = (rt_uint32_t *) t_addr;
//mmu_clean_invalidated_dcache(addr,t_size);
rt_kprintf("mem process add:0x%x \tsize:0x%x\n", addr, t_size);
rt_kprintf("0x%08x:", addr);
for (i = 0; i < size; i++) {
value = *p++;
if ((cnt / CHANGLINE_SIZE) && (cnt % CHANGLINE_SIZE == 0)) {
rt_kprintf("\n");
}
if (cnt / CHANGLINE_SIZE && (cnt % CHANGLINE_SIZE) == 0) {
rt_kprintf("0x%08x:", addr + i * 4);
}
rt_kprintf("\t%08x", value);
cnt++;
}
rt_kprintf("\n");
}
#endif
#ifdef RT_USING_FINSH
#include <finsh.h>
#ifdef FH_DBG_MEM_PROCESS
FINSH_FUNCTION_EXPORT(mem_input, mem_input(addr,size,value));
FINSH_FUNCTION_EXPORT(mem_output, mem_output(add,size));
#endif
#endif

View File

@ -1,710 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "board_info.h"
#include <rtdef.h>
#include <rtdevice.h>
#include <drivers/mmcsd_core.h>
#include "mmc.h"
//#define FH_MMC_DEBUG
#define MMC_USE_INTERNAL_BUF
#ifdef FH_MMC_DEBUG
#define PRINT_MMC_DBG(fmt, args...) \
do \
{ \
rt_kprintf("FH_MMC_DEBUG: tick-%d, ", rt_tick_get()); \
rt_kprintf(fmt, ## args); \
} \
while(0)
#else
#define PRINT_MMC_DBG(fmt, args...) do { } while (0)
#endif
#define PRINT_MMC_REGS(base) \
do \
{ \
int i_for_marco; \
rt_uint32_t addr; \
for(i_for_marco=0; i_for_marco<20; i_for_marco++) \
{ \
addr = base + i_for_marco*4*4; \
rt_kprintf("0x%x: 0x%x, 0x%x, 0x%x, 0x%x\n", addr, \
GET_REG(addr+0x0), \
GET_REG(addr+0x4), \
GET_REG(addr+0x8), \
GET_REG(addr+0xc)); \
} \
} \
while(0)
#define MMC_INTERNAL_DMA_BUF_SIZE (32*1024)
static rt_uint32_t *g_mmc_dma_buf;
static int fh_mmc_write_pio(struct mmc_driver *mmc_drv)
{
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
struct rt_mmcsd_cmd *cmd = mmc_drv->cmd;
struct rt_mmcsd_data *data = RT_NULL;
rt_uint32_t size;
if(cmd)
data = cmd->data;
if(!data)
{
rt_kprintf("ERROR: %s, data is NULL\n", __func__);
return -RT_EIO;
}
size = data->blks * data->blksize;
PRINT_MMC_DBG("%s, Send %d bytes\n", __func__, size);
MMC_WriteData(mmc_obj, data->buf, size);
MMC_ResetFifo(mmc_obj);
return 0;
}
static int fh_mmc_read_pio(struct mmc_driver *mmc_drv)
{
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
struct rt_mmcsd_cmd *cmd = mmc_drv->cmd;
struct rt_mmcsd_data *data = RT_NULL;
rt_uint32_t size;
int ret;
if(cmd)
data = cmd->data;
if(!data)
{
rt_kprintf("ERROR: %s, data is NULL\n", __func__);
return -RT_EIO;
}
size = data->blks * data->blksize;
PRINT_MMC_DBG("%s, read %d bytes\n", __func__, size);
ret = MMC_ReadData(mmc_obj, data->buf, size);
if(ret)
{
rt_kprintf("ERROR: %s, fifo IO error, ret: %d\n", __func__, ret);
return -RT_EIO;
}
MMC_ResetFifo(mmc_obj);
return 0;
}
static void fh_mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
{
rt_uint32_t clkdiv;
struct mmc_driver *mmc_drv = host->private_data;
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
PRINT_MMC_DBG("%s start\n", __func__);
//fixme: read from PMU
//why io_cfg->clock == 0 ?
if(io_cfg->clock)
{
clkdiv = MMC_CLOCK_IN / io_cfg->clock / 2;
MMC_UpdateClockRegister(mmc_obj, clkdiv);
PRINT_MMC_DBG("io_cfg->clock: %lu, clock in: %lu, clkdiv: %d\n", io_cfg->clock, MMC_CLOCK_IN, clkdiv);
}
if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
{
MMC_SetCardWidth(mmc_obj, MMC_CARD_WIDTH_4BIT);
PRINT_MMC_DBG("set to 4-bit mode\n", MMC_CLOCK_IN, clkdiv);
}
else
{
MMC_SetCardWidth(mmc_obj, MMC_CARD_WIDTH_1BIT);
PRINT_MMC_DBG("set to 1-bit mode\n", MMC_CLOCK_IN, clkdiv);
}
/* maybe switch power to the card */
switch (io_cfg->power_mode)
{
case MMCSD_POWER_OFF:
break;
case MMCSD_POWER_UP:
break;
case MMCSD_POWER_ON:
break;
default:
rt_kprintf("ERROR: %s, unknown power_mode %d\n", __func__, io_cfg->power_mode);
break;
}
PRINT_MMC_DBG("%s end\n", __func__);
}
static void fh_mmc_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t enable)
{
struct mmc_driver *mmc_drv = host->private_data;
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
rt_uint32_t reg;
PRINT_MMC_DBG("%s start\n", __func__);
if (enable)
{
MMC_ClearRawInterrupt(mmc_obj, MMC_INT_STATUS_SDIO);
reg = MMC_GetInterruptMask(mmc_obj);
reg |= MMC_INT_STATUS_SDIO;
MMC_SetInterruptMask(mmc_obj, reg);
}
else
{
reg = MMC_GetInterruptMask(mmc_obj);
reg &= ~MMC_INT_STATUS_SDIO;
MMC_SetInterruptMask(mmc_obj, reg);
}
}
static rt_int32_t fh_mmc_get_card_status(struct rt_mmcsd_host *host)
{
PRINT_MMC_DBG("%s, start\n", __func__);
PRINT_MMC_DBG("%s, end\n", __func__);
return 0;
}
static void fh_mmc_send_command(struct mmc_driver *mmc_drv, struct rt_mmcsd_cmd *cmd)
{
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
struct rt_mmcsd_host *host = mmc_drv->host;
struct rt_mmcsd_req *req = mmc_drv->req;
//fixme: cmd->data or req->data
struct rt_mmcsd_data *data = cmd->data;
int ret;
rt_uint32_t retries = 0;
rt_uint32_t cmd_flags = 0;
PRINT_MMC_DBG("%s, start\n", __func__);
if (!cmd)
{
//fixme: stop dma
rt_kprintf("ERROR: %s, cmd is NULL\n", __func__);
return;
}
if (data)
{
cmd_flags |= MMC_CMD_FLAG_DATA_EXPECTED;
/* always set data start - also set direction flag for read */
if (data->flags & DATA_DIR_WRITE)
cmd_flags |= MMC_CMD_FLAG_WRITE_TO_CARD;
if (data->flags & DATA_STREAM)
cmd_flags |= MMC_CMD_FLAG_DATA_STREAM;
}
if (cmd == req->stop)
cmd_flags |= MMC_CMD_FLAG_STOP_TRANSFER;
else
cmd_flags |= MMC_CMD_FLAG_WAIT_PREV_DATA;
switch (resp_type(cmd))
{
case RESP_NONE:
break;
case RESP_R1:
case RESP_R5:
case RESP_R6:
case RESP_R7:
case RESP_R1B:
cmd_flags |= MMC_CMD_FLAG_RESPONSE_EXPECTED;
cmd_flags |= MMC_CMD_FLAG_CHECK_RESP_CRC;
break;
case RESP_R2:
cmd_flags |= MMC_CMD_FLAG_RESPONSE_EXPECTED;
cmd_flags |= MMC_CMD_FLAG_CHECK_RESP_CRC;
cmd_flags |= MMC_CMD_FLAG_LONG_RESPONSE;
break;
case RESP_R3:
case RESP_R4:
cmd_flags |= MMC_CMD_FLAG_RESPONSE_EXPECTED;
break;
default:
rt_kprintf("ERROR: %s, unknown cmd type %x\n", __func__, resp_type(cmd));
return;
}
if (cmd->cmd_code == GO_IDLE_STATE)
cmd_flags |= MMC_CMD_FLAG_SEND_INIT;
/* CMD 11 check switch voltage */
if (cmd->cmd_code == READ_DAT_UNTIL_STOP)
cmd_flags |= MMC_CMD_FLAG_SWITCH_VOLTAGE;
PRINT_MMC_DBG("cmd code: %d, args: 0x%x, resp type: 0x%x, flag: 0x%x\n", cmd->cmd_code, cmd->arg, resp_type(cmd), cmd_flags);
ret = MMC_SendCommand(mmc_obj, cmd->cmd_code, cmd->arg, cmd_flags);
if(ret)
{
rt_kprintf("ERROR: %s, Send command timeout, cmd: %d, status: 0x%x\n", __func__, cmd->cmd_code, MMC_GetStatus(mmc_obj));
}
}
static void fh_mmc_perpare_data(struct mmc_driver *mmc_drv)
{
struct rt_mmcsd_cmd *cmd = mmc_drv->cmd;
struct rt_mmcsd_data *data = cmd->data;
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
rt_uint32_t data_size;
int i;
if(!data)
{
MMC_SetBlockSize(mmc_obj, 0);
MMC_SetByteCount(mmc_obj, 0);
return;
}
PRINT_MMC_DBG("%s, start\n", __func__);
if(MMC_ResetFifo(mmc_obj))
{
return;
}
data_size = data->blks * data->blksize;
MMC_SetBlockSize(mmc_obj, data->blksize);
if(data_size % 4)
{
rt_kprintf("ERROR: data_size should be a multiple of 4, but now is %d\n", data_size);
}
MMC_SetByteCount(mmc_obj, data_size);
PRINT_MMC_DBG("%s, set blk size: 0x%x, byte count: 0x%x\n", __func__, data->blksize, data_size);
if(data_size > MMC_DMA_DESC_BUFF_SIZE * mmc_drv->max_desc)
{
rt_kprintf("ERROR: %s, given buffer is too big, size: 0x%x, max: 0x%x\n", __func__, data_size, MMC_DMA_DESC_BUFF_SIZE * mmc_drv->max_desc);
return;
}
if (data_size > MMC_INTERNAL_DMA_BUF_SIZE)
{
rt_kprintf("ERROR: please increase MMC_INTERNAL_DMA_BUF_SIZE.\n");
return;
}
#ifdef MMC_USE_DMA
#ifdef MMC_USE_INTERNAL_BUF
if (data->flags & DATA_DIR_WRITE)
{
rt_memcpy(g_mmc_dma_buf, data->buf, data_size);
mmu_clean_invalidated_dcache(g_mmc_dma_buf, data_size);
}
else
{
mmu_invalidate_dcache(g_mmc_dma_buf, data_size);
}
MMC_InitDescriptors(mmc_obj, (rt_uint32_t*)g_mmc_dma_buf, data_size);
mmu_clean_invalidated_dcache(mmc_obj->descriptors, sizeof(MMC_DMA_Descriptors) * mmc_drv->max_desc);
MMC_StartDma(mmc_obj);
#else
MMC_InitDescriptors(mmc_obj, data->buf, data_size);
mmu_clean_invalidated_dcache(mmc_obj->descriptors, sizeof(MMC_DMA_Descriptors) * mmc_drv->max_desc);
mmu_clean_invalidated_dcache(data->buf, data_size);
MMC_StartDma(mmc_obj);
#endif
#endif
PRINT_MMC_DBG("%s, end\n", __func__);
}
int fh_mmc_wait_card_idle(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t tick, timeout;
tick = rt_tick_get();
timeout = tick + RT_TICK_PER_SECOND / 2; //500ms
while(MMC_GetStatus(mmc_obj) & MMC_STATUS_DATA_BUSY)
{
tick = rt_tick_get();
if(tick > timeout)
{
return -RT_ETIMEOUT;
}
}
return 0;
}
static int fh_mmc_get_response(struct mmc_driver *mmc_drv, struct rt_mmcsd_cmd *cmd)
{
int i;
rt_uint32_t tick, timeout, status;
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
cmd->resp[0] = 0;
cmd->resp[1] = 0;
cmd->resp[2] = 0;
cmd->resp[3] = 0;
tick = rt_tick_get();
timeout = tick + RT_TICK_PER_SECOND / 2; //500ms
//fixme: spin_lock_irqsave?
do
{
status = MMC_GetRawInterrupt(mmc_obj);
tick = rt_tick_get();
if(tick > timeout)
{
PRINT_MMC_DBG("ERROR: %s, get response timeout(cmd is not received by card), RINTSTS: 0x%x, cmd: %d\n", __func__, status, cmd->cmd_code);
return -RT_ETIMEOUT;
}
}
while(!(status & MMC_INT_STATUS_CMD_DONE));
MMC_ClearRawInterrupt(mmc_obj, MMC_INT_STATUS_CMD_DONE);
for (i = 0; i < 4; i++)
{
if (resp_type(cmd) == RESP_R2)
{
cmd->resp[i] = MMC_GetResponse(mmc_obj, 3 - i);
//fixme : R2 must delay some time here ,when use UHI card, need check why
//1ms
//rt_thread_sleep(RT_TICK_PER_SECOND / 100);
}
else
{
cmd->resp[i] = MMC_GetResponse(mmc_obj, i);
}
}
PRINT_MMC_DBG("resp: 0x%x, 0x%x, 0x%x, 0x%x\n", cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
if (status & MMC_INT_STATUS_RESPONSE_TIMEOUT)
{
MMC_ClearRawInterrupt(mmc_obj, MMC_INT_STATUS_RESPONSE_TIMEOUT);
PRINT_MMC_DBG("ERROR: %s, get response timeout, RINTSTS: 0x%x\n", __func__, status);
return -RT_ETIMEOUT;
}
else if (status & (MMC_INT_STATUS_RESP_CRC_ERROR | MMC_INT_STATUS_RESPONSE_ERROR))
{
MMC_ClearRawInterrupt(mmc_obj, MMC_INT_STATUS_RESP_CRC_ERROR | MMC_INT_STATUS_RESPONSE_ERROR);
rt_kprintf("ERROR: %s, response error or response crc error, RINTSTS: 0x%x\n", __func__, status);
//return -RT_ERROR;
}
return 0;
}
static int fh_mmc_start_transfer(struct mmc_driver *mmc_drv)
{
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
struct rt_mmcsd_host *host = mmc_drv->host;
struct rt_mmcsd_req *req = mmc_drv->req;
struct rt_mmcsd_cmd *cmd = mmc_drv->cmd;
struct rt_mmcsd_data *data = RT_NULL;
int ret;
rt_uint32_t interrupt, status, reg;
if(cmd)
data = cmd->data;
if(!data)
{
return 0;
}
PRINT_MMC_DBG("%s, start\n", __func__);
//fixme: spin_lock_irqsave(&host->lock, flags);
//open data interrupts
reg = MMC_GetInterruptMask(mmc_obj);
reg |= MMC_INT_STATUS_DATA;
MMC_SetInterruptMask(mmc_obj, reg);
//fixme: spin_unlock_irqrestore(&host->lock, flags);
ret = rt_completion_wait(&mmc_drv->transfer_completion, RT_TICK_PER_SECOND * 5);
reg = MMC_GetInterruptMask(mmc_obj);
reg &= ~MMC_INT_STATUS_DATA;
MMC_SetInterruptMask(mmc_obj, reg);
if(ret)
{
//fixme: error handle
cmd->err = ret;
interrupt = MMC_GetRawInterrupt(mmc_obj);
status = MMC_GetStatus(mmc_obj);
rt_kprintf("ERROR: %s, transfer timeout, ret: %d, RINTSTS: 0x%x, STATUS: 0x%x\n", __func__, ret, interrupt, status);
//PRINT_MMC_REGS(mmc_obj->base);
return -RT_ETIMEOUT;
}
data->bytes_xfered = data->blks * data->blksize;
#ifdef MMC_USE_INTERNAL_BUF
if (!(data->flags & DATA_DIR_WRITE))
{
rt_memcpy(data->buf, g_mmc_dma_buf, data->bytes_xfered);
mmu_invalidate_dcache(g_mmc_dma_buf, data->bytes_xfered);
}
#endif
return 0;
}
static void fh_mmc_complete_request(struct mmc_driver *mmc_drv)
{
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
#ifdef MMC_USE_DMA
MMC_StopDma(mmc_obj);
#endif
mmc_drv->cmd = RT_NULL;
mmc_drv->req = RT_NULL;
mmc_drv->data = RT_NULL;
rt_memset(mmc_obj->descriptors, 0, 4096);
MMC_SetBlockSize(mmc_obj, 0);
MMC_SetByteCount(mmc_obj, 0);
mmcsd_req_complete(mmc_drv->host);
}
static void fh_mmc_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
{
int ret;
struct mmc_driver *mmc_drv = host->private_data;
struct rt_mmcsd_cmd *cmd = req->cmd;
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
PRINT_MMC_DBG("%s start\n", __func__);
mmc_drv->req = req;
mmc_drv->cmd = cmd;
rt_completion_init(&mmc_drv->transfer_completion);
ret = fh_mmc_wait_card_idle(mmc_obj);
if (ret)
{
rt_kprintf("ERROR: %s, data transfer timeout, status: 0x%x\n", __func__, MMC_GetStatus(mmc_obj));
return;
}
fh_mmc_perpare_data(mmc_drv);
fh_mmc_send_command(mmc_drv, cmd);
ret = fh_mmc_get_response(mmc_drv, cmd);
if(ret)
{
cmd->err = ret;
rt_kprintf("%s,get response returns %d, cmd: %d\n", __func__, ret, cmd->cmd_code);
goto out;
}
fh_mmc_start_transfer(mmc_drv);
if(req->stop)
{
/* send stop command */
PRINT_MMC_DBG("%s send stop\n", __func__);
fh_mmc_send_command(mmc_drv, req->stop);
}
out:
fh_mmc_complete_request(mmc_drv);
PRINT_MMC_DBG("%s end\n", __func__);
}
static const struct rt_mmcsd_host_ops fh_mmc_ops =
{
.request = fh_mmc_request,
.set_iocfg = fh_mmc_set_iocfg,
.enable_sdio_irq = fh_mmc_enable_sdio_irq,
.get_card_status = fh_mmc_get_card_status,
};
static void fh_mmc_interrupt(int irq, void *param)
{
struct mmc_driver *mmc_drv = (struct mmc_driver *)param;
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)mmc_drv->priv;
struct rt_mmcsd_req *req = mmc_drv->req;
struct rt_mmcsd_cmd *cmd = mmc_drv->cmd;
struct rt_mmcsd_data *data;
rt_uint32_t status;
if (cmd && cmd->data)
{
data = cmd->data;
}
status = MMC_GetUnmaskedInterrupt(mmc_obj);
PRINT_MMC_DBG("unmasked interrupts: 0x%x\n", status);
if(status & MMC_INT_STATUS_CARD_DETECT)
{
rt_uint32_t card_status = MMC_GetCardStatus(mmc_obj);
if (card_status == CARD_UNPLUGED)
{
rt_kprintf("card disconnected\n");
}
else
{
rt_kprintf("card connected\n");
}
mmcsd_change(mmc_drv->host);
}
if (status & MMC_INT_STATUS_SDIO)
{
//fixme: handle sdio
//mmc_signal_sdio_irq ?
}
if(status & MMC_INIT_STATUS_DATA_ERROR)
{
rt_kprintf("ERROR: %s, data error, status: 0x%x\n", __func__, status);
}
if (status & MMC_INT_STATUS_TRANSFER_OVER)
{
//MMC_ResetFifo(mmc_obj);
//rt_completion_done(&mmc_drv->transfer_completion);
}
if (status & MMC_INT_STATUS_TX_REQUEST)
{
fh_mmc_write_pio(mmc_drv);
}
if (status & MMC_INT_STATUS_RX_REQUEST)
{
fh_mmc_read_pio(mmc_drv);
}
MMC_ClearRawInterrupt(mmc_obj, MMC_INT_STATUS_ALL);
rt_completion_done(&mmc_drv->transfer_completion);
}
int fh_mmc_probe(void *priv_data)
{
struct mmc_driver *mmc_drv;
struct rt_mmcsd_host *host;
struct fh_mmc_obj *mmc_obj = (struct fh_mmc_obj *)priv_data;
PRINT_MMC_DBG("%s start\n", __func__);
mmc_drv = (struct mmc_driver*)rt_malloc(sizeof(struct mmc_driver));
rt_memset(mmc_drv, 0, sizeof(struct mmc_driver));
mmc_drv->priv = mmc_obj;
host = mmcsd_alloc_host();
if (!host)
{
rt_kprintf("ERROR: %s, failed to malloc host\n", __func__);
return -RT_ENOMEM;
}
mmc_obj->descriptors = (MMC_DMA_Descriptors*)rt_malloc(4096+64);
mmc_obj->descriptors = (MMC_DMA_Descriptors*)(((UINT32)(mmc_obj->descriptors)+31)&(~31)); //cache-line aligned...
g_mmc_dma_buf = rt_malloc(MMC_INTERNAL_DMA_BUF_SIZE+64);
g_mmc_dma_buf = (rt_uint32_t*)(((rt_uint32_t)g_mmc_dma_buf+31) & (~31));
if(!mmc_obj->descriptors)
{
rt_kprintf("ERROR: %s, failed to malloc dma descriptors\n", __func__);
return -RT_ENOMEM;
}
rt_memset(mmc_obj->descriptors, 0, 4096);
mmc_drv->max_desc = 4096 / (sizeof(MMC_DMA_Descriptors));
host->ops = &fh_mmc_ops;
host->freq_min = MMC_FEQ_MIN;
host->freq_max = MMC_FEQ_MAX;
host->valid_ocr = VDD_32_33 | VDD_33_34;
host->flags = MMCSD_MUTBLKWRITE | \
MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ;
host->max_seg_size = MMC_DMA_DESC_BUFF_SIZE;
host->max_dma_segs = mmc_drv->max_desc;
host->max_blk_size = 512;
//fixme: max_blk_count?
host->max_blk_count = 2048;
host->private_data = mmc_drv;
mmc_drv->host = host;
gpio_request(mmc_obj->power_pin_gpio);
gpio_direction_output(mmc_obj->power_pin_gpio, 0);
MMC_Init(mmc_obj);
if(mmc_obj->id == 0){
rt_hw_interrupt_install(mmc_obj->irq, fh_mmc_interrupt, (void *)mmc_drv, "mmc_isr_0");
}
else if(mmc_obj->id == 1){
rt_hw_interrupt_install(mmc_obj->irq, fh_mmc_interrupt, (void *)mmc_drv, "mmc_isr_1");
}
rt_hw_interrupt_umask(mmc_obj->irq);
mmcsd_change(host);
MMC_SetInterruptMask(mmc_obj, MMC_INT_STATUS_CARD_DETECT);
PRINT_MMC_DBG("%s end\n", __func__);
return 0;
}
int fh_mmc_exit(void *priv_data)
{
return 0;
}
struct fh_board_ops mmc_driver_ops =
{
.probe = fh_mmc_probe,
.exit = fh_mmc_exit,
};
void rt_hw_mmc_init(void)
{
PRINT_MMC_DBG("%s start\n", __func__);
fh_board_driver_register("mmc", &mmc_driver_ops);
PRINT_MMC_DBG("%s end\n", __func__);
}

View File

@ -1,51 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef MMC_H_
#define MMC_H_
#include "libraries/inc/fh_driverlib.h"
#define MMC_FEQ_MIN 100000
#define MMC_FEQ_MAX 50000000
#define CARD_UNPLUGED 1
#define CARD_PLUGED 0
struct mmc_driver
{
MMC_DMA_Descriptors* dma_descriptors;
rt_uint32_t max_desc;
struct rt_mmcsd_host *host;
struct rt_mmcsd_req *req;
struct rt_mmcsd_data *data;
struct rt_mmcsd_cmd *cmd;
struct rt_completion transfer_completion;
void* priv;
};
void rt_hw_mmc_init(void);
#endif /* MMC_H_ */

View File

@ -1,227 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "fh_def.h"
#include "pwm.h"
#include "interrupt.h"
#include "board_info.h"
#include "inc/fh_driverlib.h"
#include <rtthread.h>
#include <rtdevice.h>
#ifdef FH_PWM_DEBUG
#define PRINT_PWM_DBG(fmt, args...) \
do \
{ \
rt_kprintf("FH_PWM_DEBUG: "); \
rt_kprintf(fmt, ## args); \
} \
while(0)
#else
#define PRINT_PWM_DBG(fmt, args...) do { } while (0)
#endif
static struct pwm_driver pwm_drv =
{
};
static int pwm_get_duty_cycle_ns(struct pwm_device* pwm)
{
struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)pwm_drv.priv;
rt_uint32_t reg, period, duty;
rt_uint32_t clk_rate = 1000000/*todo: clk_get_rate(fh_pwm_ctrl.clk)*/;
reg = PWM_GetPwmCmd(pwm_obj, pwm->id);
period = reg & 0x0fff;
duty = (reg >> 16) & 0xfff;
duty = period - duty; //reverse duty cycle
if(period == 0)
{
period = duty;
}
pwm->counter_ns = duty * 1000000000 / clk_rate;
pwm->period_ns = period * 1000000000 / clk_rate;
PRINT_PWM_DBG("get duty: %d, period: %d, reg: 0x%x\n", duty, period, reg);
return 0;
}
static int pwm_set_duty_cycle_ns(struct pwm_device* pwm)
{
struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)pwm_drv.priv;
rt_uint32_t period, duty, reg, clk_rate, duty_revert;
clk_rate = 1000000/*todo: clk_get_rate(fh_pwm_ctrl.clk)*/;
if(!clk_rate)
{
rt_kprintf("PWM: clock rate is 0\n");
return -RT_EIO;
}
period = pwm->period_ns / (1000000000 / clk_rate);
if(period < 8)
{
rt_kprintf("PWM: min period is 8\n");
return -RT_EIO;
}
duty = pwm->counter_ns / (1000000000 / clk_rate);
if(period < duty)
{
rt_kprintf("PWM: period < duty\n");
return -RT_EIO;
}
duty_revert = period - duty;
if(duty == period)
{
reg = (duty & 0xfff) << 16 | (0 & 0xfff);
}
else
{
reg = (duty_revert & 0xfff) << 16 | (period & 0xfff);
}
PRINT_PWM_DBG("set duty_revert: %d, period: %d, reg: 0x%x\n", duty_revert, period, reg);
PWM_SetPwmCmd(pwm_obj, pwm->id, reg);
return 0;
}
static rt_err_t fh_pwm_open(rt_device_t dev, rt_uint16_t oflag)
{
struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)pwm_drv.priv;
PWM_Enable(pwm_obj, RT_TRUE);
return 0;
}
static rt_err_t fh_pwm_close(rt_device_t dev)
{
struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)pwm_drv.priv;
PWM_Enable(pwm_obj, RT_FALSE);
return 0;
}
static rt_err_t fh_pwm_ioctl(rt_device_t dev, int cmd, void *arg)
{
int ret = 0;
struct pwm_device *pwm;
struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)pwm_drv.priv;
switch(cmd)
{
case ENABLE_PWM:
PWM_Enable(pwm_obj, RT_FALSE);
break;
case DISABLE_PWM:
PWM_Enable(pwm_obj, RT_TRUE);
break;
case SET_PWM_DUTY_CYCLE:
pwm = (struct pwm_device *)arg;
PRINT_PWM_DBG("ioctl: pwm addr: %p, pwm->period: %d ns\n", pwm, pwm->period_ns);
pwm_set_duty_cycle_ns(pwm);
break;
case GET_PWM_DUTY_CYCLE:
pwm = (struct pwm_device *)arg;
PRINT_PWM_DBG("ioctl: pwm->id: %d, pwm->counter: %d, pwm->period: %d\n", pwm->id, pwm->counter_ns, pwm->period_ns);
pwm_get_duty_cycle_ns(pwm);
break;
}
return ret;
}
int fh_pwm_probe(void *priv_data)
{
rt_device_t pwm_dev ;
struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)priv_data;
rt_memset(&pwm_drv, 0, sizeof(struct pwm_driver));
pwm_drv.pwm[0].id = 0;
pwm_drv.pwm[1].id = 1;
pwm_drv.pwm[2].id = 2;
pwm_drv.pwm[0].working = 0;
pwm_drv.pwm[1].working = 0;
pwm_drv.pwm[2].working = 0;
pwm_drv.priv = pwm_obj;
//todo: clk
PWM_Enable(pwm_obj, RT_FALSE);
pwm_dev = rt_calloc(1,sizeof(struct rt_device));
if (pwm_dev == RT_NULL)
{
rt_kprintf("ERROR: %s rt_device calloc failed\n", __func__);
return -RT_ENOMEM;
}
pwm_dev->user_data = &pwm_drv;
pwm_dev->open =fh_pwm_open;
pwm_dev->close = fh_pwm_close;
pwm_dev->control = fh_pwm_ioctl;
pwm_dev->type = RT_Device_Class_Miscellaneous;
rt_device_register(pwm_dev, "pwm", RT_DEVICE_FLAG_RDWR);
return 0;
}
int fh_pwm_exit(void *priv_data)
{
return 0;
}
struct fh_board_ops pwm_driver_ops =
{
.probe = fh_pwm_probe,
.exit = fh_pwm_exit,
};
void rt_hw_pwm_init(void)
{
PRINT_PWM_DBG("%s start\n", __func__);
fh_board_driver_register("pwm", &pwm_driver_ops);
PRINT_PWM_DBG("%s end\n", __func__);
}

View File

@ -1,57 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef PWM_H_
#define PWM_H_
#include <rtthread.h>
#define ENABLE_PWM (0x10)
#define DISABLE_PWM (0x11)
#define SET_PWM_DUTY_CYCLE (0x12)
#define GET_PWM_DUTY_CYCLE (0x13)
struct pwm_device
{
int id;
int working;
rt_uint32_t period_ns;
rt_uint32_t counter_ns;
};
struct pwm_driver
{
//struct clk *clk;
struct pwm_device pwm[3];
struct pwm_device *cur;
void* priv;
};
#endif /* PWM_H_ */

View File

@ -1,416 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "sadc.h"
#ifdef RT_USING_SADC
#include "inc/fh_driverlib.h"
#include "board_info.h"
#include <rtdef.h>
//#define FH_SADC_DEBUG
//#define FH_TEST_SADC
#ifdef FH_SADC_DEBUG
#define PRINT_SADC_DBG(fmt, args...) \
do \
{ \
rt_kprintf("FH_SADC_DEBUG: "); \
rt_kprintf(fmt, ## args); \
} \
while(0)
#else
#define PRINT_SADC_DBG(fmt, args...) do { } while (0)
#endif
#define __raw_writeb(v,a) ( *(volatile unsigned char *)(a) = (v))
#define __raw_writew(v,a) ( *(volatile unsigned short *)(a) = (v))
#define __raw_writel(v,a) ( *(volatile unsigned int *)(a) = (v))
#define __raw_readb(a) ( *(volatile unsigned char *)(a))
#define __raw_readw(a) ( *(volatile unsigned short *)(a))
#define __raw_readl(a) ( *(volatile unsigned int *)(a))
#define wrap_readl(wrap, name) \
__raw_readl(&(((struct wrap_sadc_reg *)wrap->regs)->name))
#define wrap_writel(wrap, name, val) \
__raw_writel((val), &(((struct wrap_sadc_reg *)wrap->regs)->name))
#define wrap_readw(wrap, name) \
__raw_readw(&(((struct wrap_sadc_reg *)wrap->regs)->name))
#define wrap_writew(wrap, name, val) \
__raw_writew((val), &(((struct wrap_sadc_reg *)wrap->regs)->name))
#define wrap_readb(wrap, name) \
__raw_readb(&(((struct wrap_sadc_reg *)wrap->regs)->name))
#define wrap_writeb(wrap, name, val) \
__raw_writeb((val), &(((struct wrap_sadc_reg *)wrap->regs)->name))
#define IOCTL_GET_SADC_DATA 1
#define IOCTL_SADC_POWER_DOWN 0xff
#define SADC_WRAP_BASE (0xf1200000)
#define SADC_IRQn (23)
#define SADC_MAX_CONTROLLER (1)
#define SADC_STATUS_COLESD (0)
#define SADC_STATUS_OPEN (1)
rt_err_t fh_sadc_isr_read_data(struct wrap_sadc_obj *sadc, rt_uint32_t channel,
rt_uint16_t *buf) {
rt_uint32_t xainsel = 1 << channel;
rt_uint32_t xversel = 0;
rt_uint32_t xpwdb = 1;
//cnt
rt_uint32_t sel2sam_pre_cnt = 2;
rt_uint32_t sam_cnt = 2;
rt_uint32_t sam2sel_pos_cnt = 2;
//time out
rt_uint32_t eoc_tos = 0xff;
rt_uint32_t eoc_toe = 0xff;
rt_uint32_t time_out = 0xffff;
//set isr en..
rt_uint32_t sadc_isr = 0x01;
//start
rt_uint32_t sadc_cmd = 0x01;
//get data
rt_uint32_t temp_data = 0;
rt_err_t ret;
//control...
wrap_writel(sadc, sadc_control, xainsel | (xversel << 8) | (xpwdb << 12));
wrap_writel(sadc, sadc_cnt,
sel2sam_pre_cnt | (sam_cnt << 8) | (sam2sel_pos_cnt << 16));
wrap_writel(sadc, sadc_timeout,
eoc_tos | (eoc_toe << 8) | (time_out << 16));
wrap_writel(sadc, sadc_ier, sadc_isr);
wrap_writel(sadc, sadc_cmd, sadc_cmd);
// ret = rt_completion_wait(&sadc->completion, RT_TICK_PER_SECOND / 2);
ret = rt_sem_take(&sadc->completion, 5000);
if(ret != RT_EOK)
return ret;
switch (channel) {
case 0:
case 1:
//read channel 0 1
temp_data = wrap_readl(sadc, sadc_dout0);
break;
case 2:
case 3:
//read channel 2 3
temp_data = wrap_readl(sadc, sadc_dout1);
break;
case 4:
case 5:
//read channel 4 5
temp_data = wrap_readl(sadc, sadc_dout2);
break;
case 6:
case 7:
//read channel 6 7
temp_data = wrap_readl(sadc, sadc_dout3);
break;
default:
break;
}
if (channel % 2) {
//read low 16bit
*buf = (rt_uint16_t) (temp_data & 0xffff);
} else {
//read high 16bit
*buf = (rt_uint16_t) (temp_data >> 16);
}
return RT_EOK;
}
static rt_err_t fh_sadc_init(rt_device_t dev)
{
// struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)pwm_drv.priv;
PRINT_SADC_DBG("%s\n",__func__);
struct wrap_sadc_obj *sadc_pri =(struct wrap_sadc_obj *)dev->user_data;
return RT_EOK;
}
static rt_err_t fh_sadc_open(rt_device_t dev, rt_uint16_t oflag)
{
// struct fh_pwm_obj *pwm_obj = (struct fh_pwm_obj *)pwm_drv.priv;
PRINT_SADC_DBG("%s\n",__func__);
struct wrap_sadc_obj *sadc_pri =(struct wrap_sadc_obj *)dev->user_data;
return RT_EOK;
}
static rt_err_t fh_sadc_close(rt_device_t dev)
{
PRINT_SADC_DBG("%s\n",__func__);
struct wrap_sadc_obj *sadc_pri =(struct wrap_sadc_obj *)dev->user_data;
return RT_EOK;
}
static rt_err_t fh_sadc_ioctl(rt_device_t dev, int cmd, void *arg)
{
rt_uint32_t control_reg;
struct wrap_sadc_obj *sadc_pri =(struct wrap_sadc_obj *)dev->user_data;
rt_uint32_t ad_data;
rt_uint16_t ad_raw_data;
SADC_INFO *sadc_info = (SADC_INFO *)arg;
rt_err_t ret;
switch(cmd){
case SADC_CMD_READ_RAW_DATA:
ret = fh_sadc_isr_read_data(sadc_pri, sadc_info->channel, &ad_raw_data);
if(ret != RT_EOK)
return ret;
sadc_info->sadc_data = ad_raw_data;
break;
case SADC_CMD_READ_VOLT:
ret = fh_sadc_isr_read_data(sadc_pri, sadc_info->channel, &ad_raw_data);
if(ret != RT_EOK)
return ret;
ad_data = ad_raw_data * SADC_REF;
ad_data /= SADC_MAX_AD_VALUE;
sadc_info->sadc_data = ad_data;
break;
case SADC_CMD_DISABLE:
control_reg = wrap_readl(sadc_pri, sadc_control);
control_reg &= ~(1 << 12);
wrap_writel(sadc_pri, sadc_control, control_reg);
break;
default :
rt_kprintf("wrong para...\n");
return RT_EIO;
}
return RT_EOK;
}
static void fh_sadc_interrupt(int irq, void *param)
{
rt_uint32_t isr_status;
struct wrap_sadc_obj *sadc = (struct wrap_sadc_obj *) param;
isr_status = wrap_readl(sadc, sadc_int_status);
if (isr_status & 0x01) {
//close isr
rt_uint32_t sadc_isr = 0x00;
wrap_writel(sadc, sadc_ier, sadc_isr);
//clear status..
wrap_writel(sadc, sadc_int_status, isr_status);
rt_sem_release(&sadc->completion);
// rt_completion_done(&sadc->completion);
} else {
//add error handle process
rt_kprintf("sadc maybe error!\n");
}
}
int fh_sadc_probe(void *priv_data)
{
int ret;
rt_device_t sadc_dev;
//check if the hw is init already...
//caution this is a read only data...if the driver want to use.malloc and copy it..
struct wrap_sadc_obj *sadc_obj = (struct wrap_sadc_obj *)priv_data;
if(sadc_obj->init_flag == SADC_INIT_ALREADY)
return RT_EFULL;
//malloc a rt device..
sadc_dev = RT_KERNEL_MALLOC(sizeof(struct rt_device));
if(!sadc_dev){
return RT_ENOMEM;
}
rt_memset(sadc_dev, 0, sizeof(struct rt_device));
PRINT_SADC_DBG("id:%d,\treg:%x,\tirq:%d\n",sadc_obj->id,(rt_uint32_t)sadc_obj->regs,sadc_obj->irq_no);
//bind rtdev to obj data...
//caution ...this is used to free mem when exit....
//free step:1:get sadc obj...2:free sadc_obj->rt_dev->user_data..3:free sadc_obj->rt_dev 4:sadc_obj->rt_dev = NULL
sadc_obj->rt_dev = sadc_dev;
//malloc a private data sadc use only...copy data from platform...
struct wrap_sadc_obj *sadc_pri = RT_KERNEL_MALLOC(sizeof(struct wrap_sadc_obj));
if(!sadc_pri){
RT_KERNEL_FREE(sadc_dev);
return RT_ENOMEM;
}
//copy platform data to pri data..
rt_memcpy(sadc_pri,sadc_obj,sizeof(struct wrap_sadc_obj));
PRINT_SADC_DBG("pri....id:%d,\treg:%x,\tirq:%d\n",sadc_pri->id,(rt_uint32_t)sadc_pri->regs,sadc_pri->irq_no);
//init sem
//rt_completion_init(&sadc_obj->completion);
rt_sem_init(&sadc_pri->completion, "sadc_sem", 0, RT_IPC_FLAG_FIFO);
//init lock
rt_mutex_init(&sadc_pri->lock,"sadc_lock", RT_IPC_FLAG_FIFO);
//bind pri data to rt_sadc_dev...
sadc_dev->user_data = (void *)sadc_pri;
sadc_dev->open =fh_sadc_open;
sadc_dev->close = fh_sadc_close;
sadc_dev->control = fh_sadc_ioctl;
sadc_dev->init = fh_sadc_init;
if(sadc_pri->id ==0){
rt_hw_interrupt_install(sadc_pri->irq_no, fh_sadc_interrupt,
(void *)sadc_pri, "sadc_isr_0");
}
rt_hw_interrupt_umask(sadc_pri->irq_no);
rt_device_register(sadc_dev, "sadc", RT_DEVICE_FLAG_RDWR);
sadc_obj->init_flag = SADC_INIT_ALREADY;
return RT_EOK;
}
int fh_sadc_exit(void *priv_data)
{
PRINT_SADC_DBG("%s\n",__func__);
struct wrap_sadc_obj *sadc_obj = (struct wrap_sadc_obj *)priv_data;
struct wrap_sadc_obj *sadc_pri = sadc_obj->rt_dev->user_data;
//release sem;
rt_sem_detach(&sadc_pri->completion);
//sadc_pri->completion = RT_NULL;
//release lock;
rt_mutex_detach(&sadc_pri->lock);
RT_KERNEL_FREE(sadc_obj->rt_dev->user_data);
sadc_obj->rt_dev->user_data = RT_NULL;
RT_KERNEL_FREE(sadc_obj->rt_dev);
sadc_obj->rt_dev = RT_NULL;
return 0;
}
struct fh_board_ops sdac_driver_ops =
{
.probe = fh_sadc_probe,
.exit = fh_sadc_exit,
};
void rt_hw_sadc_init(void)
{
int ret;
fh_board_driver_register("sadc", &sdac_driver_ops);
}
#ifdef FH_TEST_SADC
int fh_sadc_test(void){
rt_device_t sadc_dev;
SADC_INFO info;
info.channel = 0;
info.sadc_data = 0;
sadc_dev = rt_device_find("sadc");
if(!sadc_dev){
rt_kprintf("cann't find the sadc dev\n");
}
sadc_dev->init(sadc_dev);
sadc_dev->open(sadc_dev,0);
while(1)
{
sadc_dev->control(sadc_dev,SADC_CMD_READ_VOLT,&info);
rt_kprintf("channel:%d,volt:%dmv\n",info.channel,info.sadc_data);
}
return 0;
}
#endif
#ifdef RT_USING_FINSH
#include <finsh.h>
#ifdef FH_TEST_SADC
FINSH_FUNCTION_EXPORT(fh_sadc_test, fh_sadc_test);
#endif
#endif
#endif

View File

@ -1,109 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef SADC_H_
#define SADC_H_
#include <rtdef.h>
#ifdef RT_USING_SADC
/****************************************************************************
* #define section
* add constant #define here if any
***************************************************************************/
//#define FH_SADC_PROC_FILE "driver/sadc"
#define MAX_CHANNEL_NO (8)
#define SADC_REF (3300)
#define SADC_MAX_AD_VALUE (0x3ff)
#define LOOP_MODE (0x55)
#define ISR_MODE (0xAA)
#define SADC_INIT_ALREADY (0x33)
#define SADC_INIT_NOT_YET (0)
#define SADC_CMD_READ_RAW_DATA (0x22)
#define SADC_CMD_READ_VOLT (0x33)
#define SADC_CMD_DISABLE (0x44)
/****************************************************************************
* ADT section
* add Abstract Data Type definition here
***************************************************************************/
struct wrap_sadc_reg {
rt_uint32_t sadc_cmd;
rt_uint32_t sadc_control;
rt_uint32_t sadc_ier;
rt_uint32_t sadc_int_status;
rt_uint32_t sadc_dout0;
rt_uint32_t sadc_dout1;
rt_uint32_t sadc_dout2;
rt_uint32_t sadc_dout3;
rt_uint32_t sadc_debuge0;
rt_uint32_t sadc_status;
rt_uint32_t sadc_cnt;
rt_uint32_t sadc_timeout;
};
struct wrap_sadc_obj {
rt_uint32_t id;
void *regs;
rt_uint32_t irq_no;
rt_uint32_t init_flag;
rt_uint32_t active_channel_no;
rt_uint32_t active_channel_status;
rt_uint16_t channel_data[MAX_CHANNEL_NO];
rt_uint32_t error_rec;
rt_uint32_t en_isr;
rt_uint32_t sample_mode;
struct rt_mutex lock;
struct rt_semaphore completion;
//bind to the rtdev..
rt_device_t rt_dev;
};
typedef struct{
rt_uint32_t channel;
rt_uint32_t sadc_data;
}SADC_INFO;
/****************************************************************************
* extern variable declaration section
***************************************************************************/
/****************************************************************************
* section
* add function prototype here if any
***************************************************************************/
void rt_hw_sadc_init(void);
#endif
#endif /* SADC_H_ */

View File

@ -1,212 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*
* spi_fh_adapt.c
*
* Created on: Mar 2, 2016
* Author: duobao
*/
#include <stdint.h>
#include "spi_fh_adapt.h"
#include "board_info.h"
#ifdef RT_USING_W25QXX
#include "spi_flash_w25qxx.h"
#endif
#ifdef RT_USING_AT45DBXX
#include "spi_flash_at45dbxx.h"
#endif
#ifdef RT_USING_SST25VFXX
#include "spi_flash_sst25vfxx.h"
#endif
#ifdef RT_USING_GD
#include "spi_flash_gd.h"
#endif
#ifdef RT_USING_FLASH_DEFAULT
#include "spi_flash_default.h"
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define WX_MANU_ID 0xEF
#define AT_MANU_ID 0x1F /* atmel */
#define SST_MANU_ID 0xBF
#define GD_MANU_ID 0xC8
#define SPI_ADAPT_DEBUG
#ifdef SPI_ADAPT_DEBUG
#define CMD_JEDEC_ID 0x9f
#define FH_SPI_ADAPT_DEBUG(fmt, args...) \
rt_kprintf(fmt,##args);
#else
#define FH_SPI_ADAPT_DEBUG(fmt, args...)
#endif
struct fh_flash_id{
unsigned char id;
rt_err_t (*fh_flash_init)(struct flash_platform_data *plat_flash);
char *name;
};
const struct fh_flash_id id_map[] = {
#ifdef RT_USING_W25QXX
WX_MANU_ID,w25qxx_init,"winbond",
#endif
#ifdef RT_USING_AT45DBXX
AT_MANU_ID,at45dbxx_init,"atmel",
#endif
#ifdef RT_USING_SST25VFXX
SST_MANU_ID,sst25vfxx_init,"SST",
#endif
#ifdef RT_USING_GD
GD_MANU_ID,gd_init,"GD",
#endif
};
struct fh_flash_id * fh_flash_check_id_map(unsigned char id){
struct fh_flash_id *p_map = RT_NULL;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(id_map); i++) {
p_map = (struct fh_flash_id *)&id_map[i];
if (p_map->id == id){
return p_map;
}
}
return RT_NULL;
}
int fh_flash_adapt_probe(void *priv_data)
{
struct flash_platform_data *plat_flash = priv_data;
const char * flash_device_name = plat_flash->flash_name;
const char * spi_device_name = plat_flash->spi_name;
struct rt_spi_device * rt_spi_device;
struct fh_flash_id * flash_model;
rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
if(rt_spi_device == RT_NULL)
{
rt_kprintf("spi device %s not found!\r\n", spi_device_name);
return -RT_ENOSYS;
}
/* config spi */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
cfg.max_hz = 50 * 1000 * 1000; /* 50M */
rt_spi_configure(rt_spi_device, &cfg);
}
/* init flash */
rt_uint8_t cmd;
rt_uint8_t id_recv[3];
uint16_t memory_type_capacity;
rt_err_t ret;
cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
rt_spi_send(rt_spi_device, &cmd, 1);
/* read flash id */
cmd = CMD_JEDEC_ID;
rt_spi_send_then_recv(rt_spi_device, &cmd, 1, id_recv, 3);
//if the flash is already connect.
if(id_recv[0] != 0xff){
flash_model =fh_flash_check_id_map(id_recv[0]);
if(flash_model){
ret = flash_model->fh_flash_init(plat_flash);
if(ret != RT_EOK){
rt_kprintf("flash:%s init error\n",flash_model->name);
rt_kprintf("use default flash ops..\n");
//flash_model->fh_flash_adapt_init =flash_default_init;
ret = flash_default_init(plat_flash);
}
}
else{
rt_kprintf(
"use default flash ops...\nunrecognized flash id is :%02X %02X %02X\n",
id_recv[0], id_recv[1], id_recv[2]);
ret = flash_default_init(plat_flash);
}
int i;
for(i=0; i<plat_flash->nr_parts; i++)
{
fh_spi_partition_register(plat_flash->flash_name, &plat_flash->parts[i]);
}
return ret;
}
else{
rt_kprintf("please check if you connect the flash already...\n");
return RT_ENOSYS;
}
}
int fh_flash_adapt_exit(void *priv_data)
{
return 0;
}
struct fh_board_ops flash_driver_ops =
{
.probe = fh_flash_adapt_probe,
.exit = fh_flash_adapt_exit,
};
rt_err_t fh_flash_adapt_init(void)
{
fh_board_driver_register("fh_flash", &flash_driver_ops);
return 0;
}

View File

@ -1,71 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*
* spi_fh_adapt.h
*
* Created on: Mar 2, 2016
* Author: duobao
*/
#ifndef SPI_FH_ADAPT_H_
#define SPI_FH_ADAPT_H_
#include <rtthread.h>
#include <drivers/spi.h>
#define MTD_WRITEABLE 0x400 /* Device is writeable */
#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */
#define MTD_NO_ERASE 0x1000 /* No erase necessary */
#define MTD_POWERUP_LOCK 0x2000 /* Always locked after reset */
struct mtd_partition {
char *name; /* identifier string */
rt_uint32_t size; /* partition size */
rt_uint32_t offset; /* offset within the master MTD space */
rt_uint32_t mask_flags; /* master MTD flags to mask out for this partition */
struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */
};
struct flash_platform_data {
char *flash_name;
char *spi_name;
struct mtd_partition *parts;
unsigned int nr_parts;
char *type;
/* we'll likely add more ... use JEDEC IDs, etc */
};
rt_err_t fh_flash_adapt_init(void);
#endif /* SPI_FH_ADAPT_H_ */

View File

@ -1,878 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rtdevice.h>
#include <drivers/spi.h>
#include "fh_arch.h"
#include "board_info.h"
#include "ssi.h"
#include "gpio.h"
#include "inc/fh_driverlib.h"
#include "dma.h"
#include "dma_mem.h"
#include "mmu.h"
//#define FH_SPI_DEBUG
#ifdef FH_SPI_DEBUG
#define PRINT_SPI_DBG(fmt, args...) \
do \
{ \
rt_kprintf("FH_SPI_DEBUG: "); \
rt_kprintf(fmt, ## args); \
} \
while(0)
#else
#define PRINT_SPI_DBG(fmt, args...) do { } while (0)
#endif
#define RX_DMA_CHANNEL AUTO_FIND_CHANNEL
#define TX_DMA_CHANNEL AUTO_FIND_CHANNEL
#define DMA_OR_ISR_THRESHOLD 20
#define MALLOC_DMA_MEM_SIZE 0x1000
//static rt_uint32_t allign_func(rt_uint32_t in_addr,rt_uint32_t allign_size){
// return (in_addr + allign_size-1) & (~(allign_size - 1));
//}
void * fh_get_spi_dev_pri_data(struct rt_spi_device* device){
return device->parent.user_data;
}
static rt_err_t fh_spi_configure(struct rt_spi_device* device,
struct rt_spi_configuration* configuration)
{
struct spi_slave_info *spi_slave;
struct spi_controller *spi_control;
struct fh_spi_obj *spi_obj;
struct spi_config *config;
rt_uint32_t status;
rt_uint32_t spi_hz;
spi_slave = ( struct spi_slave_info *)fh_get_spi_dev_pri_data(device);
spi_control = spi_slave->control;
spi_obj = &spi_control->obj;
config = &spi_obj->config;
PRINT_SPI_DBG("configuration: \n");
PRINT_SPI_DBG("\tmode: 0x%x\n", configuration->mode);
PRINT_SPI_DBG("\tdata_width: 0x%x\n", configuration->data_width);
PRINT_SPI_DBG("\tmax_hz: 0x%x\n", configuration->max_hz);
do{
status = SPI_ReadStatus(spi_obj);
}
while(status & SPI_STATUS_BUSY);
/* data_width */
if(configuration->data_width <= 8){
config->data_size = SPI_DATA_SIZE_8BIT;
}
else if(configuration->data_width <= 16){
config->data_size = SPI_DATA_SIZE_16BIT;
}
else{
return -RT_ERROR;
}
if(configuration->max_hz > spi_control->max_hz)
spi_hz = spi_control->max_hz;
else
spi_hz = configuration->max_hz;
//fixme: div
config->clk_div = spi_control->clk_in/spi_hz;
//config->clk_div = 8;
PRINT_SPI_DBG("config hz:%d spi div:%d\n",spi_hz,config->clk_div);
/* CPOL */
if(configuration->mode & RT_SPI_CPOL){
config->clk_polarity = SPI_POLARITY_HIGH;
}
else{
config->clk_polarity = SPI_POLARITY_LOW;
}
/* CPHA */
if(configuration->mode & RT_SPI_CPHA){
config->clk_phase = SPI_PHASE_TX_FIRST;
}
else{
config->clk_phase = SPI_PHASE_RX_FIRST;
}
config->frame_format = SPI_FORMAT_MOTOROLA;
config->transfer_mode = SPI_MODE_TX_RX;
SPI_Enable(spi_obj, 0);
SPI_SetParameter(spi_obj);
SPI_DisableInterrupt(spi_obj, SPI_IRQ_ALL);
SPI_Enable(spi_obj, 1);
return RT_EOK;
}
static void xfer_dma_done(void *arg)
{
struct spi_controller *spi_control = (struct spi_controller *)arg;
spi_control->dma_complete_times++;
struct fh_spi_obj *spi_obj;
int ret;
rt_uint32_t slave_id;
spi_obj = &spi_control->obj;
//rt_kprintf("spi dma isr done.....\n");
if (spi_control->dma_complete_times == 2) {
spi_control->dma_complete_times = 0;
//add memcpy to user buff
if(spi_control->current_message->recv_buf){
rt_memcpy((void*)spi_control->current_message->recv_buf,(void*)spi_control->dma.rx_dummy_buff,spi_control->current_message->length);
}
SPI_Enable(spi_obj,0);
SPI_DisableDma(spi_obj,SPI_TX_DMA|SPI_RX_DMA);
SPI_Enable(spi_obj,1);
rt_completion_done(&spi_control->transfer_completion);
}
}
void dma_set_tx_data(struct spi_controller *spi_control){
struct dma_transfer *trans;
rt_uint32_t hs_no;
struct rt_spi_message* current_message = spi_control->current_message;
trans = &spi_control->dma.tx_trans;
hs_no = spi_control->dma.tx_hs;
struct fh_spi_obj *spi_obj;
spi_obj = &spi_control->obj;
if(current_message->length > MALLOC_DMA_MEM_SIZE){
rt_kprintf("[spi_dma]message len too large..\n");
rt_kprintf("[spi_dma] message len is %d,max len is %d\n",current_message->length,MALLOC_DMA_MEM_SIZE);
RT_ASSERT(current_message->length <= MALLOC_DMA_MEM_SIZE);
}
rt_memset((void*)spi_control->dma.tx_dummy_buff,0xff,current_message->length);
//copy tx data....
if(current_message->send_buf){
rt_memcpy(spi_control->dma.tx_dummy_buff,current_message->send_buf,current_message->length);
}
trans->dma_number = 0;
trans->dst_add = (rt_uint32_t)(spi_obj->base + OFFSET_SPI_DR);
trans->dst_hs = DMA_HW_HANDSHAKING;
trans->dst_inc_mode = DW_DMA_SLAVE_FIX;
trans->dst_msize = DW_DMA_SLAVE_MSIZE_1;
trans->dst_per = hs_no;
trans->dst_width = DW_DMA_SLAVE_WIDTH_8BIT;
trans->fc_mode = DMA_M2P;
trans->src_add = (rt_uint32_t)spi_control->dma.tx_dummy_buff;
trans->src_inc_mode = DW_DMA_SLAVE_INC;
trans->src_msize = DW_DMA_SLAVE_MSIZE_1;
trans->src_width = DW_DMA_SLAVE_WIDTH_8BIT;
trans->trans_len = current_message->length;
trans->complete_callback = (void *)xfer_dma_done;
trans->complete_para = (void *)spi_control;
}
void dma_set_rx_data(struct spi_controller *spi_control){
struct dma_transfer *trans;
rt_uint32_t hs_no;
struct rt_spi_message* current_message = spi_control->current_message;
trans = &spi_control->dma.rx_trans;
hs_no = spi_control->dma.rx_hs;
struct fh_spi_obj *spi_obj;
spi_obj = &spi_control->obj;
if(current_message->length > MALLOC_DMA_MEM_SIZE){
rt_kprintf("[spi_dma]message len too large..len is %d\n",current_message->length);
RT_ASSERT(current_message->length <= MALLOC_DMA_MEM_SIZE);
}
//rt_memset((void *)spi_control->dma.rx_dummy_buff,0,MALLOC_DMA_MEM_SIZE);
trans->dma_number = 0;
trans->fc_mode = DMA_P2M;
trans->dst_add = (rt_uint32_t)spi_control->dma.rx_dummy_buff;
trans->dst_inc_mode = DW_DMA_SLAVE_INC;
trans->dst_msize = DW_DMA_SLAVE_MSIZE_1;
trans->dst_width = DW_DMA_SLAVE_WIDTH_8BIT;
trans->src_add = (rt_uint32_t)(spi_obj->base + OFFSET_SPI_DR);
trans->src_inc_mode = DW_DMA_SLAVE_FIX;
trans->src_msize = DW_DMA_SLAVE_MSIZE_1;
trans->src_width = DW_DMA_SLAVE_WIDTH_8BIT;
trans->src_hs = DMA_HW_HANDSHAKING;
trans->src_per = hs_no;
trans->trans_len = current_message->length;
trans->complete_callback = (void *)xfer_dma_done;
trans->complete_para = (void *)spi_control;
}
rt_uint32_t xfer_data_dma(struct spi_controller *spi_control){
int ret;
struct fh_spi_obj *spi_obj;
spi_obj = &spi_control->obj;
struct rt_dma_device *dma_dev = spi_control->dma.dma_dev;
//tx data prepare
dma_set_tx_data(spi_control);
//rx data prepare
dma_set_rx_data(spi_control);
//dma go...
SPI_Enable(spi_obj,0);
//SPI_WriteTxDmaLevel(spi_obj,SPI_FIFO_DEPTH / 4);
SPI_WriteTxDmaLevel(spi_obj,1);
//SPI_WriteTxDmaLevel(spi_obj,0);
SPI_WriteRxDmaLevel(spi_obj,0);
SPI_EnableDma(spi_obj,SPI_TX_DMA|SPI_RX_DMA);
SPI_Enable(spi_obj,1);
dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER,(void *)&spi_control->dma.rx_trans);
dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER,(void *)&spi_control->dma.tx_trans);
ret = rt_completion_wait(&spi_control->transfer_completion, RT_TICK_PER_SECOND*50);
//release channel..
//dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&spi_control->dma.tx_trans);
//dma_dev->ops->control(dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&spi_control->dma.rx_trans);
if(ret)
{
rt_kprintf("ERROR: %s, transfer timeout\n", __func__);
return -RT_ETIMEOUT;
}
return RT_EOK;
}
rt_uint32_t xfer_data_isr(struct spi_controller *spi_control){
int ret;
struct fh_spi_obj *spi_obj;
spi_obj = &spi_control->obj;
SPI_SetTxLevel(spi_obj, SPI_FIFO_DEPTH / 2);
SPI_EnableInterrupt(spi_obj, SPI_IRQ_TXEIM);
ret = rt_completion_wait(&spi_control->transfer_completion, RT_TICK_PER_SECOND*50);
if(ret)
{
rt_kprintf("ERROR: %s, transfer timeout\n", __func__);
return -RT_ETIMEOUT;
}
return RT_EOK;
}
void fix_spi_xfer_mode(struct spi_controller *spi_control){
//switch dma or isr....first check dma ...is error .use isr xfer...
struct rt_dma_device * rt_dma_dev;
struct dma_transfer *tx_trans;
struct dma_transfer *rx_trans;
int ret;
//retry to check if the dma status...
if(spi_control->dma.dma_flag == DMA_BIND_OK){
//if transfer data too short...use isr..
if(spi_control->current_message->length < DMA_OR_ISR_THRESHOLD){
spi_control->xfer_mode = XFER_USE_ISR;
return;
}
#if(0)
rt_dma_dev = spi_control->dma.dma_dev;
//first request channel
tx_trans = &spi_control->dma.tx_trans;
rx_trans = &spi_control->dma.rx_trans;
tx_trans->channel_number = TX_DMA_CHANNEL;
rx_trans->channel_number = RX_DMA_CHANNEL;
ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)tx_trans);
if(ret != RT_EOK){
spi_control->xfer_mode = XFER_USE_ISR;
return;
}
ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)rx_trans);
if(ret != RT_EOK){
//release tx channel...
rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&tx_trans);
spi_control->xfer_mode = XFER_USE_ISR;
return;
}
#endif
spi_control->xfer_mode = XFER_USE_DMA;
//if error use isr mode
}
else
spi_control->xfer_mode = XFER_USE_ISR;
}
static rt_uint32_t fh_spi_xfer(struct rt_spi_device* device, struct rt_spi_message* message)
{
struct spi_slave_info *spi_slave;
struct spi_controller *spi_control;
struct fh_spi_obj *spi_obj;
int ret;
rt_uint32_t slave_id;
spi_slave = ( struct spi_slave_info *)fh_get_spi_dev_pri_data(device);
spi_control = spi_slave->control;
spi_obj = &spi_control->obj;
spi_control->transfered_len = 0;
spi_control->received_len = 0;
rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
rt_completion_init(&spi_control->transfer_completion);
spi_control->current_message = message;
/* take CS */
if(message->cs_take)
{
if(spi_slave->plat_slave.actice_level == ACTIVE_LOW)
gpio_direction_output(spi_slave->plat_slave.cs_pin, 0);
else
gpio_direction_output(spi_slave->plat_slave.cs_pin, 1);
//here will always use the slave_0 because that the cs is gpio...
SPI_EnableSlaveen(spi_obj, 0);
}
//fix transfer mode .....
fix_spi_xfer_mode(spi_control);
switch(spi_control->xfer_mode){
case XFER_USE_DMA:
PRINT_SPI_DBG("use dma xfer.....###############\n");
ret = xfer_data_dma(spi_control);
if(ret == RT_EOK){
break;
}
else{
//use the isr mode to transfer
spi_control->xfer_mode = XFER_USE_ISR;
rt_kprintf("%s dma transfer error no:%x\n",__func__,ret);
}
case XFER_USE_ISR:
PRINT_SPI_DBG("use isr xfer.....&&&&&&&&&&&&&\n");
ret = xfer_data_isr(spi_control);
if(ret != RT_EOK)
rt_kprintf("%s isr transfer error no:%x\n",__func__,ret);
break;
default:
rt_kprintf("%s unknow xfer func...\n",__func__);
while(1)
;
}
/* release CS */
if(message->cs_release)
{
if(spi_slave->plat_slave.actice_level == ACTIVE_LOW)
gpio_direction_output(spi_slave->plat_slave.cs_pin, 1);
else
gpio_direction_output(spi_slave->plat_slave.cs_pin, 0);
SPI_DisableSlaveen(spi_obj, 0);
}
rt_sem_release(&spi_control->xfer_lock);
PRINT_SPI_DBG("%s end\n", __func__);
return message->length;
}
static struct rt_spi_ops fh_spi_ops =
{
.configure = fh_spi_configure,
.xfer = fh_spi_xfer,
};
static void fh_spi_interrupt(int irq, void *param)
{
struct spi_controller *spi_control;
struct fh_spi_obj *spi_obj;
spi_control = (struct spi_controller *)param;
spi_obj = &spi_control->obj;
rt_uint32_t rx_fifo_capability,tx_fifo_capability;
rt_uint8_t data = 0;
rt_uint8_t *p;
rt_uint32_t status;
//
if(spi_control->current_message == RT_NULL){
rt_kprintf("ERROR: %s, current_message is incorrect\n", __func__);
}
status = SPI_InterruptStatus(spi_obj);
PRINT_SPI_DBG("status: 0x%x\n", status);
//fixme: ??recv overflow, underflow; tran overflow??
if(status & SPI_ISR_ERROR){
rt_kprintf("ERROR: %s, status=%d\n", __func__, status);
SPI_ClearInterrupt(spi_obj);
//fixme: handle error
return;
}
rx_fifo_capability = SPI_ReadRxFifoLevel(spi_obj);
tx_fifo_capability = MIN(
(SPI_FIFO_DEPTH - SPI_ReadTxFifoLevel(spi_obj)) / 2,
(spi_control->current_message->length - spi_control->transfered_len));
PRINT_SPI_DBG("rx_fifo_capability=%d\n", rx_fifo_capability);
//rx
spi_control->received_len += rx_fifo_capability;
while(rx_fifo_capability)
{
data = SPI_ReadData(spi_obj);
if(spi_control->current_message->recv_buf){
*(rt_uint8_t *)spi_control->current_message->recv_buf++ = data;
}
PRINT_SPI_DBG("rx, data: 0x%x\n", data);
//rt_kprintf("rx, data: 0x%x\n", data);
rx_fifo_capability--;
}
if(spi_control->received_len == spi_control->current_message->length)
{
//rt_kprintf("asdasdq4902834908dklfkldjsdhgkljshfgljkhsgfkljhsdfkljghklj");
SPI_DisableInterrupt(spi_obj, SPI_ISR_FLAG);
PRINT_SPI_DBG("finished, length=%d, received_len=%d\n", spi_control->current_message->length, spi_control->received_len);
rt_completion_done(&spi_control->transfer_completion);
return;
}
//tx
spi_control->transfered_len +=tx_fifo_capability;
if(spi_control->current_message->send_buf){
p = (rt_uint8_t *)spi_control->current_message->send_buf;
while(tx_fifo_capability){
PRINT_SPI_DBG("tx, data: 0x%x\n", *p);
//rt_kprintf("tx, data: 0x%x\n", *p);
SPI_WriteData(spi_obj, *p++);
tx_fifo_capability--;
}
spi_control->current_message->send_buf = p;
}
else{
while(tx_fifo_capability){
SPI_WriteData(spi_obj, 0xff);
tx_fifo_capability--;
}
}
}
int fh_spi_probe(void *priv_data)
{
char spi_dev_name[20] = {0};
char spi_bus_name[20] = {0};
char spi_isr_name[20] = {0};
char spi_lock_name[20] = {0};
struct spi_slave_info *spi_slave;
struct spi_slave_info *next_slave;
struct spi_slave_info **control_slave;
struct spi_controller *spi_control;
struct spi_control_platform_data *plat_data;
int i,ret;
struct rt_dma_device * rt_dma_dev;
struct dma_transfer *tx_trans;
struct dma_transfer *rx_trans;
//check data...
plat_data = (struct spi_control_platform_data *)priv_data;
if(!plat_data){
rt_kprintf("ERROR:platform data null...\n");
return -RT_ENOMEM;
}
if(plat_data->slave_no > FH_SPI_SLAVE_MAX_NO){
rt_kprintf("ERROR:spi controller not support %d slave..\n",plat_data->slave_no);
return -RT_ENOMEM;
}
//malloc data
spi_control = (struct spi_controller*)rt_malloc(sizeof(struct spi_controller));
if(!spi_control){
rt_kprintf("ERROR:no mem for malloc the spi controller..\n");
goto error_malloc_bus;
}
rt_memset(spi_control, 0, sizeof(struct spi_controller));
//parse platform control data
spi_control->base = plat_data->base;
spi_control->id = plat_data->id;
spi_control->irq = plat_data->irq;
spi_control->max_hz = plat_data->max_hz;
spi_control->slave_no = plat_data->slave_no;
spi_control->obj.base = plat_data->base;
spi_control->clk_in = plat_data->clk_in;
spi_control->plat_data = plat_data;
rt_sprintf(spi_lock_name, "%s%d", "spi_lock", spi_control->id);
rt_sem_init(&spi_control->xfer_lock, spi_lock_name, 1, RT_IPC_FLAG_FIFO);
rt_sprintf(spi_bus_name, "%s%d", "spi_bus", spi_control->id);
ret = rt_spi_bus_register(&spi_control->spi_bus, spi_bus_name, &fh_spi_ops);
PRINT_SPI_DBG("bus name is :%s\n",spi_bus_name);
//isr...
rt_sprintf(spi_isr_name, "%s%d", "ssi_isr", spi_control->id);
rt_hw_interrupt_install(spi_control->irq, fh_spi_interrupt,
(void *)spi_control, spi_isr_name);
rt_hw_interrupt_umask(spi_control->irq);
PRINT_SPI_DBG("isr name is :%s\n",spi_isr_name);
//check dma ....
if(plat_data->transfer_mode == USE_DMA_TRANSFER){
spi_control->dma.dma_dev = (struct rt_dma_device *)rt_device_find(plat_data->dma_name);
if(spi_control->dma.dma_dev == RT_NULL){
rt_kprintf("can't find dma dev\n");
//goto error_malloc_slave;
//spi_control->dma_xfer_flag = USE_ISR_TRANSFER;
// spi_control->dma.dma_flag = DMA_BIND_ERROR;
// spi_control->xfer_mode = XFER_USE_ISR;
goto BIND_DMA_ERROR;
}
else{
spi_control->dma.control = spi_control;
spi_control->dma.rx_hs = plat_data->rx_hs_no;
spi_control->dma.tx_hs = plat_data->tx_hs_no;
spi_control->dma.dma_name = plat_data->dma_name;
spi_control->dma.rx_dummy_buff = fh_dma_mem_malloc(MALLOC_DMA_MEM_SIZE);
if(!spi_control->dma.rx_dummy_buff){
rt_kprintf("malloc rx dma buff failed...\n");
//spi_control->xfer_mode = XFER_USE_ISR;
goto BIND_DMA_ERROR;
}
spi_control->dma.tx_dummy_buff = fh_dma_mem_malloc(MALLOC_DMA_MEM_SIZE);
if(!spi_control->dma.tx_dummy_buff){
rt_kprintf("malloc tx dma buff failed...\n");
fh_dma_mem_free(spi_control->dma.rx_dummy_buff);
//spi_control->xfer_mode = XFER_USE_ISR;
goto BIND_DMA_ERROR;
}
if(((rt_uint32_t)spi_control->dma.tx_dummy_buff % 4)||((rt_uint32_t)spi_control->dma.rx_dummy_buff % 4)){
rt_kprintf("dma malloc buff not allign..\n");
fh_dma_mem_free(spi_control->dma.rx_dummy_buff);
fh_dma_mem_free(spi_control->dma.tx_dummy_buff);
goto BIND_DMA_ERROR;
}
//open dma dev.
spi_control->dma.dma_dev->ops->control(spi_control->dma.dma_dev,RT_DEVICE_CTRL_DMA_OPEN,RT_NULL);
//request channel
rt_dma_dev = spi_control->dma.dma_dev;
//first request channel
tx_trans = &spi_control->dma.tx_trans;
rx_trans = &spi_control->dma.rx_trans;
tx_trans->channel_number = TX_DMA_CHANNEL;
rx_trans->channel_number = RX_DMA_CHANNEL;
ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)tx_trans);
if(ret != RT_EOK){
goto BIND_DMA_ERROR;
}
ret = rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL,(void *)rx_trans);
if(ret != RT_EOK){
//release tx channel...
rt_dma_dev->ops->control(rt_dma_dev,RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL,(void *)&tx_trans);
goto BIND_DMA_ERROR;
}
//spi_control->xfer_mode = XFER_USE_DMA;
spi_control->dma.dma_flag = DMA_BIND_OK;
}
}
else{
BIND_DMA_ERROR:
spi_control->dma.dma_flag = DMA_BIND_ERROR;
//spi_control->xfer_mode = XFER_USE_ISR;
}
control_slave = &spi_control->spi_slave;
for(i=0;i<plat_data->slave_no;i++){
spi_slave = (struct spi_slave_info*)rt_malloc(sizeof(struct spi_slave_info));
if(!spi_slave){
rt_kprintf("ERROR:no mem for malloc the spi_slave%d..\n",i);
goto error_malloc_slave;
}
rt_memset(spi_slave, 0, sizeof(struct spi_slave_info));
//parse platform data...
spi_slave->id = i;
//bind to the spi control....will easy to find all the data...
spi_slave->control = spi_control;
spi_slave->plat_slave.cs_pin = plat_data->plat_slave[i].cs_pin;
spi_slave->plat_slave.actice_level = plat_data->plat_slave[i].actice_level;
rt_sprintf(spi_dev_name, "%s%d%s%d", "ssi", spi_control->id,"_",spi_slave->id);
*control_slave = spi_slave;
control_slave = &spi_slave->next;
//register slave dev...
ret = rt_spi_bus_attach_device(&spi_slave->spi_device,spi_dev_name,spi_bus_name,spi_slave);
if(ret != RT_EOK){
rt_kprintf("register dev to bus failed...\n");
goto error_malloc_slave;
}
}
//request gpio...
spi_slave = spi_control->spi_slave;
while(spi_slave != RT_NULL)
{
next_slave = spi_slave->next;
ret = gpio_request(spi_slave->plat_slave.cs_pin);
if(ret!=0){
rt_kprintf("request gpio_%d failed...\n",spi_slave->plat_slave.cs_pin);
goto error_malloc_slave;
}
PRINT_SPI_DBG("spi_slave info addr:%x,id:%d,cs:%d,active:%d\n",(rt_uint32_t)spi_slave, spi_slave->id,
spi_slave->plat_slave.cs_pin,
spi_slave->plat_slave.actice_level);
spi_slave = next_slave;
}
//this will be used in platform exit..
plat_data->control = spi_control;
return RT_EOK;
error_malloc_slave:
//free the slaveinfo already malloc
spi_slave = spi_control->spi_slave;
while(spi_slave != RT_NULL)
{
next_slave = spi_slave->next;
gpio_release(spi_slave->plat_slave.cs_pin);
rt_free(spi_slave);
spi_slave = next_slave;
}
//mask isr
rt_hw_interrupt_mask(spi_control->irq);
//release sem ..
rt_sem_detach(&spi_control->xfer_lock);
//free the control malloc .
rt_free(spi_control);
//fixme:unregister spi_bus...
error_malloc_bus:
return -RT_ENOMEM;
}
int fh_spi_exit(void *priv_data)
{
struct spi_controller *spi_control;
struct spi_control_platform_data *plat_data;
struct spi_slave_info *spi_slave;
struct spi_slave_info *next_slave;
plat_data = (struct spi_control_platform_data *)priv_data;
spi_control = plat_data->control;
spi_slave = spi_control->spi_slave;
while(spi_slave != RT_NULL)
{
next_slave = spi_slave->next;
gpio_release(spi_slave->plat_slave.cs_pin);
rt_free(spi_slave);
spi_slave = next_slave;
}
//mask isr
rt_hw_interrupt_mask(spi_control->irq);
//release sem ..
rt_sem_detach(&spi_control->xfer_lock);
//free the control malloc .
rt_free(spi_control);
//fixme free all the malloc data ...
return 0;
}
struct fh_board_ops spi_driver_ops =
{
.probe = fh_spi_probe,
.exit = fh_spi_exit,
};
void rt_hw_spi_init(void)
{
int ret;
// rt_kprintf("%s start\n", __func__);
PRINT_SPI_DBG("%s start\n", __func__);
fh_board_driver_register("spi", &spi_driver_ops);
PRINT_SPI_DBG("%s end\n", __func__);
//fixme: never release?
}
#if(0)
#define TEST_SPI_BUFF_SIZE 0x100
static rt_uint8_t tx_buf[TEST_SPI_BUFF_SIZE] = {0};
static rt_uint8_t rx_buf[TEST_SPI_BUFF_SIZE] = {0};
int ssi_test(void){
struct rt_spi_device * rt_spi_device;
int ret;
rt_spi_device = (struct rt_spi_device *)rt_device_find("ssi1_0");
if(rt_spi_device == RT_NULL)
{
rt_kprintf("%s spi device %s not found!\r\n",__func__ ,"ssi1_0");
return -RT_ENOSYS;
}
/* config spi */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
cfg.max_hz = 50 * 1000 * 1000; /* 50M */
rt_spi_configure(rt_spi_device, &cfg);
}
rt_memset(tx_buf,0x55,TEST_SPI_BUFF_SIZE);
rt_spi_transfer(rt_spi_device,tx_buf,rx_buf,TEST_SPI_BUFF_SIZE);
ret = rt_memcmp(tx_buf,rx_buf,TEST_SPI_BUFF_SIZE);
if(ret != 0){
rt_kprintf("compare error ..error data %x\n",ret);
}
rt_kprintf("test done \n");
return 0;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(ssi_test, fh_ssi_test);
#endif
#endif

View File

@ -1,134 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef SSI_H_
#define SSI_H_
#include "libraries/inc/fh_driverlib.h"
#include <drivers/spi.h>
#include <rtdevice.h>
#include "fh_dma.h"
#define SPI_PRIV(drv) ( (struct fh_spi_obj)(drv->priv) )
#define FH_SPI_SLAVE_MAX_NO 2
struct spi_controller;
//platform use below
struct spi_slave_platform_data{
rt_uint32_t cs_pin;
#define ACTIVE_LOW 1
#define ACTIVE_HIGH 2
rt_uint32_t actice_level;
};
struct spi_control_platform_data{
rt_uint32_t id;
rt_uint32_t irq;
rt_uint32_t base;
rt_uint32_t max_hz;
rt_uint32_t slave_no;
rt_uint32_t clk_in;
//handshake no...
rt_uint32_t rx_hs_no;
rt_uint32_t tx_hs_no;
char *dma_name;
//isr will be the default...
#define USE_ISR_TRANSFER 0
#define USE_DMA_TRANSFER 1
rt_uint32_t transfer_mode;
struct spi_controller *control;
struct spi_slave_platform_data plat_slave[FH_SPI_SLAVE_MAX_NO];
};
struct spi_controller;
//driver use below.......
struct spi_slave_info
{
struct rt_spi_device spi_device;
struct spi_controller *control;
struct spi_slave_platform_data plat_slave;
rt_uint32_t id;
//spi control will use to find all the slave info..
struct spi_slave_info *next;
};
struct spi_dma
{
char *dma_name;
#define DMA_BIND_OK 0
#define DMA_BIND_ERROR 1
rt_uint32_t dma_flag;
//bind to the dma dev..
rt_uint32_t rx_hs;
rt_uint32_t tx_hs;
rt_uint8_t *rx_dummy_buff;
rt_uint8_t *tx_dummy_buff;
struct rt_dma_device *dma_dev;
struct dma_transfer tx_trans;
struct dma_transfer rx_trans;
struct spi_controller *control;
};
struct spi_controller
{
rt_uint32_t id;
rt_uint32_t irq;
rt_uint32_t base;
rt_uint32_t max_hz;
rt_uint32_t slave_no;
rt_uint32_t clk_in;
//bind to the platform data....
struct spi_control_platform_data *plat_data;
//rt_uint32_t dma_xfer_flag;
#define XFER_USE_ISR 0
#define XFER_USE_DMA 1
rt_uint32_t xfer_mode;
struct spi_dma dma;
rt_uint32_t dma_complete_times;
struct rt_spi_bus spi_bus;
struct spi_slave_info *spi_slave;
struct rt_spi_message* current_message;
struct rt_completion transfer_completion;
struct rt_semaphore xfer_lock;
struct fh_spi_obj obj;
rt_uint32_t received_len;
rt_uint32_t transfered_len;
void* priv;
};
void rt_hw_spi_init(void);
#endif /* SPI_H_ */

View File

@ -1,197 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <armv6.h>
#include "fh_arch.h"
#include "interrupt.h"
#include "libraries/inc/fh_ictl.h"
/**
* @addtogroup FH81
*/
/*@{*/
extern struct rt_thread *rt_current_thread;
#ifdef RT_USING_FINSH
extern long list_thread(void);
#endif
/**
* this function will show registers of CPU
*
* @param regs the registers point
*/
void rt_hw_show_register (struct rt_hw_register *regs)
{
rt_kprintf("Execption:\n");
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
}
/**
* When ARM7TDMI comes across an instruction which it cannot handle,
* it takes the undefined instruction trap.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_udef(struct rt_hw_register *regs)
{
rt_hw_show_register(regs);
rt_kprintf("undefined instruction\n");
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
rt_hw_cpu_shutdown();
}
/**
* The software interrupt instruction (SWI) is used for entering
* Supervisor mode, usually to request a particular supervisor
* function.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_swi(struct rt_hw_register *regs)
{
rt_hw_show_register(regs);
rt_kprintf("software interrupt\n");
rt_hw_cpu_shutdown();
}
/**
* An abort indicates that the current memory access cannot be completed,
* which occurs during an instruction prefetch.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_pabt(struct rt_hw_register *regs)
{
rt_hw_show_register(regs);
rt_kprintf("prefetch abort\n");
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
rt_hw_cpu_shutdown();
}
/**
* An abort indicates that the current memory access cannot be completed,
* which occurs during a data access.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_dabt(struct rt_hw_register *regs)
{
rt_hw_show_register(regs);
rt_kprintf("data abort\n");
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
rt_hw_cpu_shutdown();
}
/**
* Normally, system will never reach here
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_resv(struct rt_hw_register *regs)
{
rt_kprintf("not used\n");
rt_hw_show_register(regs);
rt_hw_cpu_shutdown();
}
extern struct rt_irq_desc irq_desc[];
void rt_hw_trap_irq()
{
rt_isr_handler_t isr_func;
rt_uint32_t irqstat_l, irqstat_h, irq;
void *param;
fh_intc *p = (fh_intc *)INTC_REG_BASE;
irqstat_l = p->IRQ_FINALSTATUS_L;
irqstat_h = p->IRQ_FINALSTATUS_H;
if (irqstat_l)
{
irq = __rt_ffs(irqstat_l) - 1;
}
else if(irqstat_h)
{
irq = __rt_ffs(irqstat_h) - 1 + 32;
}
else
{
rt_kprintf("No interrupt occur\n");
return;
}
/* get interrupt service routine */
isr_func = irq_desc[irq].handler;
param = irq_desc[irq].param;
/* turn to interrupt service routine */
if(isr_func){
isr_func(irq, param);
}
#ifdef RT_USING_INTERRUPT_INFO
irq_desc[irq].counter ++;
#endif
}
void rt_hw_trap_fiq()
{
rt_kprintf("fast interrupt request\n");
}
/*@}*/

View File

@ -1,292 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <board.h>
#include <rtdevice.h>
#include "fh_arch.h"
#include "libraries/inc/fh_uart.h"
void rt_fh_uart_handler(int vector, void *param)
{
int status;
unsigned int ret;
struct fh_uart *uart;
unsigned int reg_status;
rt_device_t dev = (rt_device_t)param;
uart = (struct fh_uart *)dev->user_data;
status = uart_get_iir_status(uart->uart_port);
if (status & UART_IIR_NOINT)
{
return;
}
if(status & UART_IIR_THREMPTY){
//first close tx isr
uart_disable_irq(uart->uart_port,UART_IER_ETBEI);
rt_hw_serial_isr((struct rt_serial_device *)dev, RT_SERIAL_EVENT_TX_DONE);
}
else if((status & UART_IIR_CHRTOUT)==UART_IIR_CHRTOUT){
//bug....
//if no data in rx fifo
reg_status = uart_get_status(uart->uart_port);
if((reg_status & 1<<3) == 0)
ret = uart_getc(uart->uart_port);
}
else{
rt_interrupt_enter();
rt_hw_serial_isr((struct rt_serial_device *)dev, RT_SERIAL_EVENT_RX_IND);
rt_interrupt_leave();
}
}
/**
* UART device in RT-Thread
*/
static rt_err_t fh_uart_configure(struct rt_serial_device *serial,
struct serial_configure *cfg)
{
int div;
enum data_bits data_mode;
enum stop_bits stop_mode;
enum parity parity_mode;
struct fh_uart *uart;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uart = (struct fh_uart *)serial->parent.user_data;
switch (cfg->data_bits)
{
case DATA_BITS_8:
data_mode = UART_DATA_BIT8;
break;
case DATA_BITS_7:
data_mode = UART_DATA_BIT7;
break;
case DATA_BITS_6:
data_mode = UART_DATA_BIT6;
break;
case DATA_BITS_5:
data_mode = UART_DATA_BIT5;
break;
default:
data_mode = UART_DATA_BIT8;
break;
}
switch (cfg->stop_bits)
{
case STOP_BITS_2:
stop_mode = UART_STOP_BIT2;
break;
case STOP_BITS_1:
default:
stop_mode = UART_STOP_BIT1;
break;
}
switch (cfg->parity)
{
case PARITY_ODD:
parity_mode = UART_PARITY_ODD;
break;
case PARITY_EVEN:
parity_mode = UART_PARITY_EVEN;
break;
case PARITY_NONE:
default:
parity_mode = UART_PARITY_NONE;
break;
}
uart_disable_irq(uart->uart_port, UART_IER_ERBFI);
uart_configure(uart->uart_port, data_mode,
stop_mode, parity_mode,
cfg->baud_rate, UART_CLOCK_FREQ);
uart_enable_irq(uart->uart_port, UART_IER_ERBFI);
return RT_EOK;
}
static rt_err_t fh_uart_control(struct rt_serial_device *serial,
int cmd, void *arg)
{
struct fh_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct fh_uart *)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* disable rx irq */
rt_hw_interrupt_mask(uart->irq);
uart_disable_irq(uart->uart_port,UART_IER_ERBFI);
break;
case RT_DEVICE_CTRL_SET_INT:
/* enable rx irq */
rt_hw_interrupt_umask(uart->irq);
uart_enable_irq(uart->uart_port,UART_IER_ERBFI);
break;
}
return RT_EOK;
}
static int fh_uart_putc(struct rt_serial_device *serial, char c)
{
struct fh_uart *uart = serial->parent.user_data;
unsigned int ret;
ret = uart_get_status(uart->uart_port);
if(serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX){
//RT_DEVICE_FLAG_INT_TX
if(c == '\n'){
fh_uart_putc(serial,'\r');
}
if(ret & UART_USR_TFNF){
uart_putc(uart->uart_port, c);
return 1;
}
//open tx isr here..
uart_enable_irq(uart->uart_port,UART_IER_ETBEI);
return -1;
}
//poll mode
else{
while(!(uart_get_status(uart->uart_port) & UART_USR_TFNF))
;
uart_putc(uart->uart_port, c);
return 1;
}
}
static int fh_uart_getc(struct rt_serial_device *serial)
{
int result;
struct fh_uart *uart = serial->parent.user_data;
if (uart_is_rx_ready(uart->uart_port))
{
result = uart_getc(uart->uart_port);
}
else
{
result = -1;
}
return result;
}
static const struct rt_uart_ops fh_uart_ops =
{
fh_uart_configure,
fh_uart_control,
fh_uart_putc,
fh_uart_getc,
};
#if defined(RT_USING_UART0)
static struct rt_serial_device serial0;
struct fh_uart uart0 = {
(uart *)UART0_REG_BASE,
UART0_IRQn
};
#endif
#if defined(RT_USING_UART1)
static struct rt_serial_device serial1;
struct fh_uart uart1 = {
(uart *)UART1_REG_BASE,
UART1_IRQn
};
#endif
/**
* This function will handle init uart
*/
void rt_hw_uart_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#if defined(RT_USING_UART0)
#if(0)
serial0.ops = &fh_uart_ops;
serial0.config = config;
/* register vcom device */
rt_hw_serial_register(&serial0, "uart0",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_STANDALONE,
&uart0);
rt_hw_interrupt_install(uart0.irq, rt_fh_uart_handler,
(void *)&(serial0.parent), "UART0");
rt_hw_interrupt_umask(uart0.irq);
#endif
serial0.ops = &fh_uart_ops;
serial0.config = config;
/* register vcom device */
rt_hw_serial_register(&serial0, "uart0",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM ,
&uart0);
rt_hw_interrupt_install(uart0.irq, rt_fh_uart_handler,
(void *)&(serial0.parent), "UART0");
rt_hw_interrupt_umask(uart0.irq);
#endif
#if defined(RT_USING_UART1)
serial1.ops = &fh_uart_ops;
serial1.config = config;
/* register vcom device */
rt_hw_serial_register(&serial1, "uart1",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM ,
&uart1);
rt_hw_interrupt_install(uart1.irq, rt_fh_uart_handler,
(void *)&(serial1.parent), "UART1");
rt_hw_interrupt_umask(uart1.irq);
#endif
}

View File

@ -1,33 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef UART_H_
#define UART_H_
void rt_hw_uart_init(void);
#endif

View File

@ -1,269 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "fh_def.h"
#include "wdt.h"
#include "interrupt.h"
#include "board_info.h"
#include "inc/fh_driverlib.h"
#include <rtdevice.h>
#include <drivers/watchdog.h>
#define FH_WDT_DEBUG
#ifdef FH_WDT_DEBUG
#define PRINT_WDT_DBG(fmt, args...) \
do \
{ \
rt_kprintf("FH_WDT_DEBUG: "); \
rt_kprintf(fmt, ## args); \
} \
while(0)
#else
#define PRINT_WDT_DBG(fmt, args...) do { } while (0)
#endif
static int heartbeat = WDT_HEARTBEAT;
static rt_uint32_t fh_wdt_time_left(struct wdt_driver *wdt_drv)
{
struct fh_wdt_obj *wdt_obj = wdt_drv->priv;
//todo: get clk
//return WDT_GetCurrCount(wdt_obj) / WDT_CLOCK;
return WDT_GetCurrCount(wdt_obj) / 1800000;
}
static void fh_wdt_keepalive(struct wdt_driver *wdt_drv)
{
struct fh_wdt_obj *wdt_obj = wdt_drv->priv;
WDT_Kick(wdt_obj);
}
static inline void fh_wdt_set_next_heartbeat(struct wdt_driver *wdt_drv)
{
wdt_drv->next_heartbeat = rt_tick_get() + heartbeat * RT_TICK_PER_SECOND;
}
static inline int fh_wdt_top_in_seconds(struct wdt_driver *wdt_drv, unsigned top)
{
/*
* There are 16 possible timeout values in 0..15 where the number of
* cycles is 2 ^ (16 + i) and the watchdog counts down.
*/
//todo: get_clk
return (1 << (17 + top)) / 1800000;
}
static int fh_wdt_set_top(struct wdt_driver *wdt_drv, unsigned top_s)
{
int i, top_val = FH_WDT_MAX_TOP;
struct fh_wdt_obj *wdt_obj = wdt_drv->priv;
/*
* Iterate over the timeout values until we find the closest match. We
* always look for >=.
*/
for (i = 0; i <= FH_WDT_MAX_TOP; ++i)
if (fh_wdt_top_in_seconds(wdt_drv, i) >= top_s) {
top_val = i;
break;
}
/* Set the new value in the watchdog. */
PRINT_WDT_DBG("[wdt] set topval: %d\n", top_val);
WDT_SetTopValue(wdt_obj, top_val);
fh_wdt_set_next_heartbeat(wdt_drv);
return fh_wdt_top_in_seconds(wdt_drv, top_val);
}
rt_err_t fh_watchdog_init(rt_watchdog_t *wdt)
{
struct wdt_driver *wdt_drv = wdt->parent.user_data;
struct fh_wdt_obj *wdt_obj = wdt_drv->priv;
if (wdt_drv->in_use)
return -RT_EBUSY;
//todo: spinlock
fh_wdt_set_top(wdt_drv, WDT_HW_TIMEOUT);///3000);
if (!WDT_IsEnable(wdt_obj))
{
/*
* The watchdog is not currently enabled. Set the timeout to
* the maximum and then start it.
*/
rt_uint32_t value;
value = WDOG_CONTROL_REG_WDT_EN_MASK;
value |= WDOG_CONTROL_REG_RMOD_MASK;
WDT_SetCtrl(wdt_obj, value);
fh_wdt_keepalive(wdt_drv);
}
fh_wdt_set_next_heartbeat(wdt_drv);
//todo: unlock
return RT_EOK;
}
rt_err_t fh_watchdog_ctrl(rt_watchdog_t *wdt, int cmd, void *arg)
{
struct wdt_driver *wdt_drv = wdt->parent.user_data;
struct fh_wdt_obj *wdt_obj = wdt_drv->priv;
rt_uint32_t val;
switch (cmd)
{
case RT_DEVICE_CTRL_WDT_START:
WDT_Enable(wdt_obj, RT_TRUE);
break;
case RT_DEVICE_CTRL_WDT_STOP:
WDT_Enable(wdt_obj, RT_FALSE);
break;
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
//fh_wdt_set_next_heartbeat(wdt_drv);
fh_wdt_keepalive(wdt_drv);
break;
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
heartbeat = *((int*)(arg));
PRINT_WDT_DBG("[wdt] settime value %lu\n", heartbeat);
fh_wdt_set_top(wdt_drv, heartbeat);///3000);
fh_wdt_keepalive(wdt_drv);
fh_wdt_set_next_heartbeat(wdt_drv);
break;
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
arg = &heartbeat;
break;
case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
val = fh_wdt_time_left(wdt_drv);
arg = &val;
break;
default:
return -RT_EIO;
}
return RT_EOK;
}
static void fh_wdt_interrupt(int irq, void *param)
{
//todo: stop
//fh81_pmu_stop();
}
struct rt_watchdog_ops fh_watchdog_ops =
{
.init = &fh_watchdog_init,
.control = &fh_watchdog_ctrl,
};
int fh_wdt_probe(void *priv_data)
{
rt_watchdog_t *wdt_dev;
struct wdt_driver *wdt_drv;
struct fh_wdt_obj *wdt_obj = (struct fh_wdt_obj *)priv_data;
wdt_drv = (struct wdt_driver *)rt_malloc(sizeof(struct wdt_driver));
rt_memset(wdt_drv, 0, sizeof(struct wdt_driver));
wdt_drv->priv = wdt_obj;
rt_hw_interrupt_install(wdt_obj->irq, fh_wdt_interrupt, (void *)wdt_drv, "wdt_irq");
rt_hw_interrupt_umask(wdt_obj->irq);
//todo: clk
wdt_dev = (rt_watchdog_t *)rt_malloc(sizeof(rt_watchdog_t));
if (wdt_dev == RT_NULL)
{
rt_kprintf("ERROR: %s rt_watchdog_t malloc failed\n", __func__);
}
wdt_dev->ops = &fh_watchdog_ops;
rt_hw_watchdog_register(wdt_dev, "fh_wdt", RT_DEVICE_OFLAG_RDWR, wdt_drv);
return 0;
}
int fh_wdt_exit(void *priv_data)
{
return 0;
}
struct fh_board_ops wdt_driver_ops =
{
.probe = fh_wdt_probe,
.exit = fh_wdt_exit,
};
void rt_hw_wdt_init(void)
{
PRINT_WDT_DBG("%s start\n", __func__);
fh_board_driver_register("wdt", &wdt_driver_ops);
PRINT_WDT_DBG("%s end\n", __func__);
}
void wdt_start(int timeout, int kick_times)
{
rt_device_t wdt_dev;
int ret;
wdt_dev = rt_device_find("fh_wdt");
rt_device_open(wdt_dev, 0);
ret = rt_device_control(wdt_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
int i = 0;
for( ; i < kick_times; i ++ )
{
rt_thread_sleep(timeout * RT_TICK_PER_SECOND / 2);
ret = rt_device_control(wdt_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, &timeout);
rt_kprintf( "kicked\n" );
}
rt_kprintf( "stop kick the watchdog, it shall reboot for %d seconds.\n", timeout * 2);
}
#ifdef RT_USING_WDT
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(wdt_start, enable wdt);
#endif
#endif

View File

@ -1,46 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef WDT_H_
#define WDT_H_
struct wdt_driver
{
//struct clk *clk;
unsigned long in_use;
unsigned long next_heartbeat;
//struct timer_list timer;
int expect_close;
void* priv;
};
#endif /* WDT_H_ */

View File

@ -1,14 +0,0 @@
# for module compiling
import os
from building import *
objs = []
cwd = GetCurrentDir()
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
objs = objs + SConscript(os.path.join(item, 'SConscript'))
Return('objs')

View File

@ -1,9 +0,0 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
path = [cwd + '/..']
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path)
Return('group')

View File

@ -1,27 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/

View File

@ -1,260 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "inc/fh_driverlib.h"
int I2C_WaitMasterIdle(struct fh_i2c_obj *i2c_obj)
{
UINT32 reg;
int timeout = 200; //20 ms
while (GET_REG(i2c_obj->base + OFFSET_I2C_STATUS) & DW_IC_STATUS_MASTER_ACTIVITY)
{
if(timeout < 0)
{
rt_kprintf( "ERROR: %s, timeout waiting for master not active, txflr: 0x%x, rxflr: 0x%x, stat: 0x%x\n",
__func__, I2C_GetReceiveFifoLevel(i2c_obj), I2C_GetTransmitFifoLevel(i2c_obj), GET_REG(i2c_obj->base + OFFSET_I2C_INTR_STAT));
return -RT_ETIMEOUT;
}
timeout--;
udelay(100);
}
return 0;
}
int I2C_WaitDeviceIdle(struct fh_i2c_obj *i2c_obj)
{
UINT32 reg;
int timeout = 2000; //200 ms
while (GET_REG(i2c_obj->base + OFFSET_I2C_STATUS) & DW_IC_STATUS_ACTIVITY)
{
if(timeout < 0)
{
rt_kprintf( "ERROR: %s, timeout waiting for device not active\n", __func__);
return -RT_ETIMEOUT;
}
timeout--;
udelay(100);
}
return 0;
}
static inline UINT32 I2C_CalcSclHcnt(UINT32 ic_clk, UINT32 tSYMBOL, UINT32 tf, int cond, int offset)
{
/*
* DesignWare I2C core doesn't seem to have solid strategy to meet
* the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec
* will result in violation of the tHD;STA spec.
*/
if (cond)
/*
* Conditional expression:
*
* IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH
*
* This is based on the DW manuals, and represents an ideal
* configuration. The resulting I2C bus speed will be
* faster than any of the others.
*
* If your hardware is free from tHD;STA issue, try this one.
*/
return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset;
else
/*
* Conditional expression:
*
* IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf)
*
* This is just experimental rule; the tHD;STA period turned
* out to be proportinal to (_HCNT + 3). With this setting,
* we could meet both tHIGH and tHD;STA timing specs.
*
* If unsure, you'd better to take this alternative.
*
* The reason why we need to take into account "tf" here,
* is the same as described in i2c_fh_scl_lcnt().
*/
return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset;
}
static inline UINT32 I2C_CalcSclLcnt(UINT32 ic_clk, UINT32 tLOW, UINT32 tf, int offset)
{
/*
* Conditional expression:
*
* IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf)
*
* DW I2C core starts counting the SCL CNTs for the LOW period
* of the SCL clock (tLOW) as soon as it pulls the SCL line.
* In order to meet the tLOW timing spec, we need to take into
* account the fall time of SCL signal (tf). Default tf value
* should be 0.3 us, for safety.
*/
return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset;
}
static int I2C_SetSpeedCount(struct fh_i2c_obj *i2c_obj)
{
UINT32 hcnt, lcnt;
/* set standard and fast speed count for high/low periods */
/* Standard-mode */
hcnt = I2C_CalcSclHcnt(i2c_obj->input_clock,
40, /* tHD;STA = tHIGH = 4.0 us */
3, /* tf = 0.3 us */
0, /* 0: DW default, 1: Ideal */
0); /* No offset */
lcnt = I2C_CalcSclLcnt(i2c_obj->input_clock,
47, /* tLOW = 4.7 us */
3, /* tf = 0.3 us */
0); /* No offset */
SET_REG(i2c_obj->base + OFFSET_I2C_SS_SCL_HCNT, hcnt);
SET_REG(i2c_obj->base + OFFSET_I2C_SS_SCL_LCNT, lcnt);
/* Fast-mode */
hcnt = I2C_CalcSclHcnt(i2c_obj->input_clock,
6, /* tHD;STA = tHIGH = 0.6 us */
3, /* tf = 0.3 us */
0, /* 0: DW default, 1: Ideal */
0); /* No offset */
lcnt = I2C_CalcSclLcnt(i2c_obj->input_clock,
13, /* tLOW = 1.3 us */
3, /* tf = 0.3 us */
0); /* No offset */
SET_REG(i2c_obj->base + OFFSET_I2C_FS_SCL_HCNT, hcnt);
SET_REG(i2c_obj->base + OFFSET_I2C_FS_SCL_LCNT, lcnt);
return 0;
}
UINT32 I2C_ClearAndGetInterrupts(struct fh_i2c_obj *i2c_obj)
{
UINT32 stat;
/*
* The IC_INTR_STAT register just indicates "enabled" interrupts.
* Ths unmasked raw version of interrupt status bits are available
* in the IC_RAW_INTR_STAT register.
*
* That is,
* stat = readl(IC_INTR_STAT);
* equals to,
* stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK);
*
* The raw version might be useful for debugging purposes.
*/
stat = GET_REG(i2c_obj->base + OFFSET_I2C_INTR_STAT);
/*
* Do not use the IC_CLR_INTR register to clear interrupts, or
* you'll miss some interrupts, triggered during the period from
* readl(IC_INTR_STAT) to readl(IC_CLR_INTR).
*
* Instead, use the separately-prepared IC_CLR_* registers.
*/
if (stat & DW_IC_INTR_RX_UNDER)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_RX_UNDER);
if (stat & DW_IC_INTR_RX_OVER)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_RX_OVER);
if (stat & DW_IC_INTR_TX_OVER)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_TX_OVER);
if (stat & DW_IC_INTR_RD_REQ)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_RD_REQ);
if (stat & DW_IC_INTR_TX_ABRT)
{
/*
* The IC_TX_ABRT_SOURCE register is cleared whenever
* the IC_CLR_TX_ABRT is read. Preserve it beforehand.
*/
i2c_obj->abort_source = GET_REG(i2c_obj->base + OFFSET_I2C_TX_ABRT_SOURCE);
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_TX_ABRT);
}
if (stat & DW_IC_INTR_RX_DONE)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_RX_DONE);
if (stat & DW_IC_INTR_ACTIVITY)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_ACTIVITY);
if (stat & DW_IC_INTR_STOP_DET)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_STOP_DET);
if (stat & DW_IC_INTR_START_DET)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_START_DET);
if (stat & DW_IC_INTR_GEN_CALL)
GET_REG(i2c_obj->base + OFFSET_I2C_CLR_GEN_CALL);
return stat;
}
int I2C_HandleTxAbort(struct fh_i2c_obj *i2c_obj)
{
unsigned long abort_source = i2c_obj->abort_source;
int i;
if (abort_source & DW_IC_TX_ABRT_NOACK)
{
//for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
// rt_kprintf( "%s: %s\n", __func__, abort_sources[i]);
return 0;
}
//for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
// rt_kprintf( "%s: %s\n", __func__, abort_sources[i]);
rt_kprintf("%s: abort_sources 0x%x\n", __func__, abort_sources);
if (abort_source & DW_IC_TX_ARB_LOST)
return 0;
else if (abort_source & DW_IC_TX_ABRT_GCALL_READ)
return 0; /* wrong msgs[] data */
else
return 0;
}
void I2C_Init(struct fh_i2c_obj *i2c_obj)
{
UINT32 ic_con;
UINT32 param0 = GET_REG(i2c_obj->base + OFFSET_I2C_COMP_PARAM1);
I2C_WaitMasterIdle(i2c_obj);
I2C_Enable(i2c_obj, RT_FALSE);
I2C_SetSpeedCount(i2c_obj);
i2c_obj->config.tx_fifo_depth = ((param0 >> 16) & 0xff) + 1;
i2c_obj->config.rx_fifo_depth = ((param0 >> 8) & 0xff) + 1;
/* Configure Tx/Rx FIFO threshold levels */
SET_REG(i2c_obj->base + OFFSET_I2C_TX_TL, i2c_obj->config.tx_fifo_depth - 1);
SET_REG(i2c_obj->base + OFFSET_I2C_RX_TL, 0);
/* configure the i2c master */
ic_con = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
/*OFFSET_I2C_CON_RESTART_EN |*/ DW_IC_CON_SPEED_FAST; //DW_IC_CON_SPEED_STD;
SET_REG( i2c_obj->base + OFFSET_I2C_CON, ic_con);
}

View File

@ -1,69 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "inc/fh_driverlib.h"
void ictl_close_all_isr(fh_intc *p){
if(p){
//enable all interrupts
p->IRQ_EN_L = 0xffffffff;
p->IRQ_EN_H = 0xffffffff;
//mask all interrupts
p->IRQ_MASK_L = 0xffffffff;
p->IRQ_MASK_H = 0xffffffff;
}
}
void ictl_mask_isr(fh_intc *p,int irq){
if(p){
if (irq < 32)
p->IRQ_MASK_L |= (1 << irq);
else
p->IRQ_MASK_H |= (1 << (irq - 32));
}
}
void ictl_unmask_isr(fh_intc *p,int irq){
if(p){
if (irq < 32)
p->IRQ_MASK_L &= ~(1 << irq);
else
p->IRQ_MASK_H &= ~(1 << (irq - 32));
}
}

View File

@ -1,327 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "inc/fh_driverlib.h"
// *1: card off
// *0: card on
void MMC_InitDescriptors(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size)
{
MMC_DMA_Descriptors *desc;
rt_uint32_t len = 0;
int i, desc_cnt = 0;
desc = mmc_obj->descriptors;
while(size > 0)
{
desc[desc_cnt].desc0.bit.own = 1;
desc[desc_cnt].desc0.bit.sencond_address_chained = 1;
desc[desc_cnt].desc1.bit.buffer1_size = MIN(MMC_DMA_DESC_BUFF_SIZE, size);
desc[desc_cnt].desc2.bit.buffer_addr0 = (rt_uint32_t)buf + len;
desc[desc_cnt].desc3.bit.buffer_addr1 = (rt_uint32_t)mmc_obj->descriptors + (desc_cnt + 1) * sizeof(MMC_DMA_Descriptors);
size -= desc[desc_cnt].desc1.bit.buffer1_size;
len += desc[desc_cnt].desc1.bit.buffer1_size;
desc_cnt++;
}
desc[0].desc0.bit.first_descriptor = 1;
desc[desc_cnt-1].desc0.bit.last_descriptor = 1;
desc[desc_cnt-1].desc3.bit.buffer_addr1 = 0;
}
int MMC_WriteData(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size)
{
int filled = 0, fifo_available, i, retries;
for (i=0; i<size/4; i++)
{
retries = 0;
do
{
fifo_available = MMC_FIFO_DEPTH - MMC_GetWaterlevel(mmc_obj);
if(retries++ > 10000)
{
rt_kprintf("ERROR: %s, get water level timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
while(!fifo_available);
SET_REG(mmc_obj->base + OFFSET_SDC_FIFO, *buf++);
}
retries = 0;
while(MMC_IsDataStateBusy(mmc_obj))
{
if(retries++ > 10000)
{
rt_kprintf("ERROR: %s, timeout, data line keep being busy\n", __func__);
return -RT_ETIMEOUT;
}
}
return 0;
}
int MMC_ReadData(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size)
{
int fifo_available, i, retries;
for (i=0; i<size/4; i++)
{
retries = 0;
do
{
fifo_available = MMC_GetWaterlevel(mmc_obj);
if(retries++ > 10000)
{
rt_kprintf("ERROR: %s, get water level timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
while(!fifo_available);
*buf++ = GET_REG(mmc_obj->base + OFFSET_SDC_FIFO);
}
retries = 0;
while(MMC_IsDataStateBusy(mmc_obj))
{
if(retries++ > 10000)
{
rt_kprintf("ERROR: %s, timeout, data line keep being busy\n", __func__);
return -RT_ETIMEOUT;
}
}
return 0;
}
int MMC_UpdateClockRegister(struct fh_mmc_obj *mmc_obj, int div)
{
rt_uint32_t tick, timeout;
tick = rt_tick_get();
timeout = tick + RT_TICK_PER_SECOND / 10; //100ms in total
/* disable clock */
SET_REG(mmc_obj->base + OFFSET_SDC_CLKENA, 0);
SET_REG(mmc_obj->base + OFFSET_SDC_CLKSRC, 0);
/* inform CIU */
SET_REG(mmc_obj->base + OFFSET_SDC_CMD, 1<<31 | 1<<21);
while(GET_REG(mmc_obj->base + OFFSET_SDC_CMD) & 0x80000000)
{
tick = rt_tick_get();
if(tick > timeout)
{
rt_kprintf("ERROR: %s, update clock timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
/* set clock to desired speed */
SET_REG(mmc_obj->base + OFFSET_SDC_CLKDIV, div);
/* inform CIU */
SET_REG(mmc_obj->base + OFFSET_SDC_CMD, 1<<31 | 1<<21);
while(GET_REG(mmc_obj->base + OFFSET_SDC_CMD) & 0x80000000)
{
tick = rt_tick_get();
if(tick > timeout)
{
rt_kprintf("ERROR: %s, update clock timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
/* enable clock */
SET_REG(mmc_obj->base + OFFSET_SDC_CLKENA, 1);
/* inform CIU */
SET_REG(mmc_obj->base + OFFSET_SDC_CMD, 1<<31 | 1<<21);
while(GET_REG(mmc_obj->base + OFFSET_SDC_CMD) & 0x80000000)
{
tick = rt_tick_get();
if(tick > timeout)
{
rt_kprintf("ERROR: %s, update clock timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
return 0;
}
int MMC_SetCardWidth(struct fh_mmc_obj *mmc_obj, int width)
{
switch(width)
{
case MMC_CARD_WIDTH_1BIT:
SET_REG(mmc_obj->base + OFFSET_SDC_CTYPE, 0);
break;
case MMC_CARD_WIDTH_4BIT:
SET_REG(mmc_obj->base + OFFSET_SDC_CTYPE, 1);
break;
default:
rt_kprintf("ERROR: %s, card width %d is not supported\n", __func__, width);
return -RT_ERROR;
}
return 0;
}
int MMC_SendCommand(struct fh_mmc_obj *mmc_obj, rt_uint32_t cmd, rt_uint32_t arg, rt_uint32_t flags)
{
rt_uint32_t reg, tick, timeout;
tick = rt_tick_get();
timeout = tick + RT_TICK_PER_SECOND; //1s
SET_REG(mmc_obj->base + OFFSET_SDC_CMDARG, arg);
flags |= 1<<31 | 1<<29 | cmd;
SET_REG(mmc_obj->base + OFFSET_SDC_CMD, flags);
while(GET_REG(mmc_obj->base + OFFSET_SDC_CMD) & MMC_CMD_START_CMD)
{
tick = rt_tick_get();
if(tick > timeout)
{
rt_kprintf("ERROR: %s, send cmd timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
//fixme: check HLE_INT_STATUS
return 0;
}
int MMC_ResetFifo(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t reg, tick, timeout;
tick = rt_tick_get();
timeout = tick + RT_TICK_PER_SECOND / 10; //100ms
reg = GET_REG(mmc_obj->base + OFFSET_SDC_CTRL);
reg |= 1 << 1;
SET_REG(mmc_obj->base + OFFSET_SDC_CTRL, reg);
//wait until fifo reset finish
while(GET_REG(mmc_obj->base + OFFSET_SDC_CTRL) & MMC_CTRL_FIFO_RESET)
{
tick = rt_tick_get();
if(tick > timeout)
{
rt_kprintf("ERROR: %s, FIFO reset timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
return 0;
}
int MMC_Reset(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t reg, tick, timeout;
tick = rt_tick_get();
timeout = tick + RT_TICK_PER_SECOND / 10; //100ms
reg = GET_REG(mmc_obj->base + OFFSET_SDC_BMOD);
reg |= MMC_BMOD_RESET;
SET_REG(mmc_obj->base + OFFSET_SDC_BMOD, reg);
while(GET_REG(mmc_obj->base + OFFSET_SDC_BMOD) & MMC_BMOD_RESET)
{
tick = rt_tick_get();
if(tick > timeout)
{
rt_kprintf("ERROR: %s, BMOD Software reset timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
reg = GET_REG(mmc_obj->base + OFFSET_SDC_CTRL);
reg |= MMC_CTRL_CONTROLLER_RESET | MMC_CTRL_FIFO_RESET | MMC_CTRL_DMA_RESET;
SET_REG(mmc_obj->base + OFFSET_SDC_CTRL, reg);
tick = rt_tick_get();
timeout = tick + RT_TICK_PER_SECOND / 10; //100ms
while(GET_REG(mmc_obj->base + OFFSET_SDC_CTRL) & (MMC_CTRL_CONTROLLER_RESET | MMC_CTRL_FIFO_RESET | MMC_CTRL_DMA_RESET))
{
tick = rt_tick_get();
if(tick > timeout)
{
rt_kprintf("ERROR: %s, CTRL dma|fifo|ctrl reset timeout\n", __func__);
return -RT_ETIMEOUT;
}
}
return 0;
}
void MMC_Init(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t reg;
if(mmc_obj->mmc_reset)
mmc_obj->mmc_reset(mmc_obj);
MMC_Reset(mmc_obj);
//fixed burst
reg = GET_REG(mmc_obj->base + OFFSET_SDC_BMOD);
reg |= 1 << 1;
SET_REG(mmc_obj->base + OFFSET_SDC_BMOD, reg);
//fixme: power on ? ctrl by gpio ?
MMC_ClearRawInterrupt(mmc_obj, MMC_INT_STATUS_ALL);
MMC_SetInterruptMask(mmc_obj, 0x0);
//fixme: use_internal_dma
reg = GET_REG(mmc_obj->base + OFFSET_SDC_CTRL);
reg |= MMC_CTRL_INT_ENABLE;
#ifdef MMC_USE_DMA
reg |= MMC_CTRL_USE_DMA;
#endif
SET_REG(mmc_obj->base + OFFSET_SDC_CTRL, reg);
//set timeout param
SET_REG(mmc_obj->base + OFFSET_SDC_TMOUT, 0xffffffff);
//set fifo
reg = GET_REG(mmc_obj->base + OFFSET_SDC_FIFOTH);
reg = (reg >> 16) & 0x7ff;
reg = ((0x2 << 28) | ((reg/2) << 16) | ((reg/2 + 1) << 0));
SET_REG(mmc_obj->base + OFFSET_SDC_FIFOTH, reg);
}

View File

@ -1,42 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "inc/fh_driverlib.h"
void PWM_Enable(struct fh_pwm_obj *pwm_obj, int enable)
{
SET_REG(pwm_obj->base + OFFSET_PWM_CTRL, enable);
}
unsigned int PWM_GetPwmCmd(struct fh_pwm_obj *pwm_obj, int device_id)
{
return GET_REG(pwm_obj->base + OFFSET_PWM_CMD(device_id));
}
void PWM_SetPwmCmd(struct fh_pwm_obj *pwm_obj, int device_id, unsigned int reg)
{
SET_REG(pwm_obj->base + OFFSET_PWM_CMD(device_id), reg);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,164 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "fh_def.h"
#include "fh_arch.h"
#include "inc/fh_driverlib.h"
void SPI_EnableSlaveen(struct fh_spi_obj *spi_obj, rt_uint32_t port)
{
rt_uint32_t reg;
reg = GET_REG(spi_obj->base + OFFSET_SPI_SER);
reg |= (1 << port);
SET_REG(spi_obj->base + OFFSET_SPI_SER, reg);
}
void SPI_DisableSlaveen(struct fh_spi_obj *spi_obj, rt_uint32_t port)
{
rt_uint32_t reg;
reg = GET_REG(spi_obj->base + OFFSET_SPI_SER);
reg &= ~(1 << port);
SET_REG(spi_obj->base + OFFSET_SPI_SER, reg);
}
void SPI_SetTxLevel(struct fh_spi_obj *spi_obj, rt_uint32_t level)
{
SET_REG(spi_obj->base + OFFSET_SPI_TXFTLR, level);
}
void SPI_EnableInterrupt(struct fh_spi_obj *spi_obj, rt_uint32_t flag)
{
rt_uint32_t reg;
reg = GET_REG(spi_obj->base + OFFSET_SPI_IMR);
reg |= flag;
SET_REG(spi_obj->base + OFFSET_SPI_IMR, reg);
}
void SPI_EnableDma(struct fh_spi_obj *spi_obj, rt_uint32_t channel)
{
rt_uint32_t reg;
reg = GET_REG(spi_obj->base + OFFSET_SPI_DMACTRL);
reg |= channel;
SET_REG(spi_obj->base + OFFSET_SPI_DMACTRL, reg);
}
void SPI_DisableDma(struct fh_spi_obj *spi_obj, rt_uint32_t channel)
{
rt_uint32_t reg;
reg = GET_REG(spi_obj->base + OFFSET_SPI_DMACTRL);
reg &= ~channel;
SET_REG(spi_obj->base + OFFSET_SPI_DMACTRL, reg);
}
void SPI_DisableInterrupt(struct fh_spi_obj *spi_obj, rt_uint32_t flag)
{
rt_uint32_t reg;
reg = GET_REG(spi_obj->base + OFFSET_SPI_IMR);
reg &= ~flag;
SET_REG(spi_obj->base + OFFSET_SPI_IMR, reg);
}
rt_uint32_t SPI_InterruptStatus(struct fh_spi_obj *spi_obj)
{
return GET_REG(spi_obj->base + OFFSET_SPI_ISR);
}
void SPI_ClearInterrupt(struct fh_spi_obj *spi_obj)
{
GET_REG(spi_obj->base + OFFSET_SPI_ICR);
}
rt_uint32_t SPI_ReadTxFifoLevel(struct fh_spi_obj *spi_obj)
{
return GET_REG(spi_obj->base + OFFSET_SPI_TXFLR);
}
rt_uint32_t SPI_ReadRxFifoLevel(struct fh_spi_obj *spi_obj)
{
return GET_REG(spi_obj->base + OFFSET_SPI_RXFLR);
}
UINT8 SPI_ReadData(struct fh_spi_obj *spi_obj)
{
return GET_REG(spi_obj->base + OFFSET_SPI_DR) & 0xff;
}
void SPI_WriteData(struct fh_spi_obj *spi_obj, UINT8 data)
{
SET_REG(spi_obj->base + OFFSET_SPI_DR, data);
}
rt_uint32_t SPI_ReadStatus(struct fh_spi_obj *spi_obj)
{
return GET_REG(spi_obj->base + OFFSET_SPI_SR);
}
void SPI_Enable(struct fh_spi_obj *spi_obj, int enable)
{
SET_REG(spi_obj->base + OFFSET_SPI_SSIENR, enable);
}
void SPI_WriteTxDmaLevel(struct fh_spi_obj *spi_obj, rt_uint32_t data)
{
SET_REG(spi_obj->base + OFFSET_SPI_DMATDL, data);
}
void SPI_WriteRxDmaLevel(struct fh_spi_obj *spi_obj, rt_uint32_t data)
{
SET_REG(spi_obj->base + OFFSET_SPI_DMARDL, data);
}
void SPI_SetParameter(struct fh_spi_obj *spi_obj)
{
rt_uint32_t reg;
struct spi_config *config;
config = &spi_obj->config;
SET_REG(spi_obj->base + OFFSET_SPI_BAUD, config->clk_div);
reg = GET_REG(spi_obj->base + OFFSET_SPI_CTRL0);
reg &= ~(0x3ff);
reg |= config->data_size \
| config->frame_format \
| config->clk_phase \
| config->clk_polarity \
| config->transfer_mode;
SET_REG(spi_obj->base + OFFSET_SPI_CTRL0, reg);
}

View File

@ -1,144 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
*****************************************************************************/
#include "inc/fh_driverlib.h"
/*****************************************************************************
* Define section
* add all #define here
*****************************************************************************/
/****************************************************************************
* ADT section
* add definition of user defined Data Type that only be used in this file here
***************************************************************************/
/******************************************************************************
* Function prototype section
* add prototypes for all functions called by this file,execepting those
* declared in header file
*****************************************************************************/
/*****************************************************************************
* Global variables section - Exported
* add declaration of global variables that will be exported here
* e.g.
* int8_t foo;
****************************************************************************/
/*****************************************************************************
* Global variables section - Local
* define global variables(will be refered only in this file) here,
* static keyword should be used to limit scope of local variable to this file
* e.g.
* static uint8_t ufoo;
*****************************************************************************/
/* function body */
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
int timer_init(timer *tim)
{
tim->TIMER_CTRL_REG = 0;
}
int timer_set_mode(timer *tim, enum timer_mode mode)
{
switch (mode)
{
case TIMER_MODE_PERIODIC:
tim->TIMER_CTRL_REG |= TIMER_CTRL_MODE;
break;
case TIMER_MODE_ONESHOT:
tim->TIMER_CTRL_REG |= TIMER_CTRL_MODE;
break;
default:
rt_kprintf("Not support TIMER mode\n");
return -1;
break;
}
return 0;
}
void timer_set_period(timer *tim, UINT32 period, UINT32 clock)
{
tim->TIMER_LOAD_COUNT = clock/period;
}
void timer_enable(timer *tim)
{
tim->TIMER_CTRL_REG |= TIMER_CTRL_ENABLE;
}
void timer_disable(timer *tim)
{
tim->TIMER_CTRL_REG &= ~TIMER_CTRL_ENABLE;
}
void timer_enable_irq(timer *tim)
{
tim->TIMER_CTRL_REG &= ~TIMER_CTRL_INTMASK;
}
void timer_disable_irq(timer *tim)
{
tim->TIMER_CTRL_REG |= TIMER_CTRL_INTMASK;
}
UINT32 timer_get_status(timer *tim)
{
return tim->TIMER_INT_STATUS;
}
UINT32 timer_get_eoi(timer *tim)
{
return tim->TIMER_EOI;
}
UINT32 timer_get_value(timer *tim)
{
return tim->TIMER_LOAD_COUNT - tim->TIMER_CURRENT_VALUE;
}

View File

@ -1,278 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
*****************************************************************************/
#include "inc/fh_driverlib.h"
/*****************************************************************************
* Define section
* add all #define here
*****************************************************************************/
/****************************************************************************
* ADT section
* add definition of user defined Data Type that only be used in this file here
***************************************************************************/
/******************************************************************************
* Function prototype section
* add prototypes for all functions called by this file,execepting those
* declared in header file
*****************************************************************************/
/*****************************************************************************
* Global variables section - Exported
* add declaration of global variables that will be exported here
* e.g.
* int8_t foo;
****************************************************************************/
/*****************************************************************************
* Global variables section - Local
* define global variables(will be refered only in this file) here,
* static keyword should be used to limit scope of local variable to this file
* e.g.
* static uint8_t ufoo;
*****************************************************************************/
/* function body */
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
int uart_init(uart *port)
{
port->UART_IER = 0;
port->UART_LCR = 0;
//port->UART_DLL = 0;
//port->UART_DLH = 0;
}
UINT32 uart_get_status(uart *port)
{
return port->UART_USR;
}
void uart_configure(uart *port, enum data_bits data_bit,
enum stop_bits stop_bit, enum parity parity,
UINT32 buard_rate, UINT32 uart_clk)
{
UINT32 divisor;
UINT32 freq;
UINT32 baud_div;
UINT32 lcr_reg = 0;
UINT32 ret;
/*divisor = DIV(buard_rate);
port->UART_LCR |= UART_LCR_DLAB;
port->UART_DLL = divisor & 0xFF;
port->UART_DLH = (divisor >> 8) & 0xFF;
port->UART_LCR &= ~UART_LCR_DLAB;*/
do{
//clear fifo...
port->UART_FCR = UART_FCR_RFIFOR | UART_FCR_XFIFOR;
//read status..
ret = uart_get_status(port);
}while(ret & UART_USR_BUSY);
switch (data_bit) {
case UART_DATA_BIT5:
lcr_reg |= UART_LCR_DLS5;
break;
case UART_DATA_BIT6:
lcr_reg |= UART_LCR_DLS6;
break;
case UART_DATA_BIT7:
lcr_reg |= UART_LCR_DLS7;
break;
case UART_DATA_BIT8:
lcr_reg |= UART_LCR_DLS8;
break;
default:
lcr_reg |= UART_LCR_DLS8;
break;
}
switch (stop_bit) {
case UART_STOP_BIT1:
lcr_reg |= UART_LCR_STOP1;
break;
case UART_STOP_BIT2:
lcr_reg |= UART_LCR_STOP2;
break;
default:
lcr_reg |= UART_LCR_STOP1;
break;
}
switch (parity) {
case UART_PARITY_EVEN:
lcr_reg |= UART_LCR_EVEN | UART_LCR_PEN;
break;
case UART_PARITY_ODD:
lcr_reg |= UART_LCR_PEN;
break;
case UART_PARITY_ST:
lcr_reg |= UART_LCR_SP;
break;
case UART_PARITY_NONE:
default:
break;
}
switch (buard_rate) {
case 115200:
baud_div = BAUDRATE_115200;
break;
case 57600:
baud_div = BAUDRATE_57600;
break;
case 38400:
baud_div = BAUDRATE_38400;
break;
case 19200:
baud_div = BAUDRATE_19200;
break;
case 9600:
baud_div = BAUDRATE_9600;
break;
default:
baud_div = BAUDRATE_115200;
break;
}
//clear fifo
port->UART_FCR = UART_FCR_RFIFOR | UART_FCR_XFIFOR;
//div
ret = port->UART_LCR;
ret |= UART_LCR_DLAB;
port->UART_LCR = ret;
port->RBRTHRDLL = baud_div & 0x00ff;
port->DLHIER = (baud_div & 0x00ff)>>8;
/* clear DLAB */
ret = ret & 0x7f;
port->UART_LCR = ret;
//line control
port->UART_LCR = lcr_reg;
//fifo control
port->UART_FCR = UART_FCR_FIFOE | UART_FCR_RFIFOR | UART_FCR_XFIFOR | UART_FCR_TET_1_4 | UART_FCR_RT_ONE;
}
int uart_enable_irq(uart *port, UINT32 mode)
{
unsigned int ret;
ret = port->UART_IER;
ret |= mode;
port->UART_IER = ret;
}
int uart_disable_irq(uart *port, UINT32 mode)
{
unsigned int ret;
ret = port->UART_IER;
ret &= ~mode;
port->UART_IER = ret;
}
UINT32 uart_get_iir_status(uart *port)
{
return port->UART_IIR;
}
UINT32 uart_get_line_status(uart *port)
{
return port->UART_LSR;
}
UINT32 uart_is_rx_ready(uart *port)
{
return port->UART_LSR & UART_LSR_DR;
}
UINT8 uart_getc(uart *port)
{
return port->UART_RBR & 0xFF;
}
void uart_putc(uart *port, UINT8 c)
{
//while(!(port->UART_USR & UART_USR_TFNF));
port->UART_THR = c;
}
void uart_set_fifo_mode(uart *port, UINT32 fifo_mode)
{
port->UART_FCR = fifo_mode;
}

View File

@ -1,52 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "inc/fh_driverlib.h"
void WDT_Enable(struct fh_wdt_obj *wdt_obj, int enable)
{
SET_REG(wdt_obj->base + WDOG_CONTROL_REG_OFFSET, enable);
}
void WDT_SetTopValue(struct fh_wdt_obj *wdt_obj, int top)
{
SET_REG(wdt_obj->base + WDOG_TIMEOUT_RANGE_REG_OFFSET, top);
}
void WDT_SetCtrl(struct fh_wdt_obj *wdt_obj, UINT32 reg)
{
SET_REG(wdt_obj->base + WDOG_CONTROL_REG_OFFSET, reg);
}
void WDT_Kick(struct fh_wdt_obj *wdt_obj)
{
SET_REG(wdt_obj->base + WDOG_COUNTER_RESTART_REG_OFFSET, WDOG_COUNTER_RESTART_KICK_VALUE);
}
UINT32 WDT_GetCurrCount(struct fh_wdt_obj *wdt_obj)
{
return GET_REG(wdt_obj->base + WDOG_CURRENT_COUNT_REG_OFFSET);
}

View File

@ -1,39 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#include <rthw.h>
#include "fh_def.h"
#include "fh_arch.h"
#include "fh_ictl.h"
#include "fh_timer.h"
#include "fh_uart.h"
#include "fh_spi.h"
#include "fh_gpio.h"
#include "fh_mmc.h"
#include "fh_i2c.h"
#include "fh_pwm.h"
#include "fh_wdt.h"

View File

@ -1,54 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_GPIO_H_
#define FH_GPIO_H_
#define REG_GPIO_SWPORTA_DR (0x0000)
#define REG_GPIO_SWPORTA_DDR (0x0004)
#define REG_GPIO_PORTA_CTL (0x0008)
#define REG_GPIO_INTEN (0x0030)
#define REG_GPIO_INTMASK (0x0034)
#define REG_GPIO_INTTYPE_LEVEL (0x0038)
#define REG_GPIO_INT_POLARITY (0x003C)
#define REG_GPIO_INTSTATUS (0x0040)
#define REG_GPIO_RAWINTSTATUS (0x0044)
#define REG_GPIO_DEBOUNCE (0x0048)
#define REG_GPIO_PORTA_EOI (0x004C)
#define REG_GPIO_EXT_PORTA (0x0050)
#define NUM_OF_GPIO (64)
struct fh_gpio_obj
{
unsigned int id;
unsigned int irq;
};
#endif /* FH_GPIO_H_ */

View File

@ -1,266 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_I2C_H_
#define FH_I2C_H_
#include "fh_def.h"
#define OFFSET_I2C_CON (0x0000)
#define OFFSET_I2C_TAR (0x0004)
#define OFFSET_I2C_SAR (0x0008)
#define OFFSET_I2C_HS_MADDR (0x000C)
#define OFFSET_I2C_DATA_CMD (0x0010)
#define OFFSET_I2C_SS_SCL_HCNT (0x0014)
#define OFFSET_I2C_SS_SCL_LCNT (0x0018)
#define OFFSET_I2C_FS_SCL_HCNT (0x001C)
#define OFFSET_I2C_FS_SCL_LCNT (0x0020)
#define OFFSET_I2C_HS_SCL_HCNT (0x0024)
#define OFFSET_I2C_HS_SCL_LCNT (0x0028)
#define OFFSET_I2C_INTR_STAT (0x002c)
#define OFFSET_I2C_INTR_MASK (0x0030)
#define OFFSET_I2C_RAW_INTR_STAT (0x0034)
#define OFFSET_I2C_RX_TL (0x0038)
#define OFFSET_I2C_TX_TL (0x003c)
#define OFFSET_I2C_CLR_INTR (0x0040)
#define OFFSET_I2C_CLR_RX_UNDER (0x0044)
#define OFFSET_I2C_CLR_RX_OVER (0x0048)
#define OFFSET_I2C_CLR_TX_OVER (0x004c)
#define OFFSET_I2C_CLR_RD_REQ (0x0050)
#define OFFSET_I2C_CLR_TX_ABRT (0x0054)
#define OFFSET_I2C_CLR_RX_DONE (0x0058)
#define OFFSET_I2C_CLR_ACTIVITY (0x005c)
#define OFFSET_I2C_CLR_STOP_DET (0x0060)
#define OFFSET_I2C_CLR_START_DET (0x0064)
#define OFFSET_I2C_CLR_GEN_CALL (0x0068)
#define OFFSET_I2C_ENABLE (0x006c)
#define OFFSET_I2C_STATUS (0x0070)
#define OFFSET_I2C_TXFLR (0x0074)
#define OFFSET_I2C_RXFLR (0x0078)
#define OFFSET_I2C_DMA_CR (0x0088)
#define OFFSET_I2C_DMA_TDLR (0x008c)
#define OFFSET_I2C_DMA_RDLR (0x0090)
#define OFFSET_I2C_COMP_PARAM1 (0x00f4)
#define OFFSET_I2C_TX_ABRT_SOURCE (0x0080)
#define I2C_M_TEN 0x0100 /* this is a ten bit chip address */
#define I2C_M_RD 0x0001 /* read data, from slave to master */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
#define DW_IC_CON_MASTER 0x1
#define DW_IC_CON_SPEED_STD 0x2
#define DW_IC_CON_SPEED_FAST 0x4
#define DW_IC_CON_10BITADDR_MASTER 0x10
#define DW_IC_CON_RESTART_EN 0x20
#define DW_IC_CON_SLAVE_DISABLE 0x40
#define DW_IC_INTR_RX_UNDER 0x001
#define DW_IC_INTR_RX_OVER 0x002
#define DW_IC_INTR_RX_FULL 0x004
#define DW_IC_INTR_TX_OVER 0x008
#define DW_IC_INTR_TX_EMPTY 0x010
#define DW_IC_INTR_RD_REQ 0x020
#define DW_IC_INTR_TX_ABRT 0x040
#define DW_IC_INTR_RX_DONE 0x080
#define DW_IC_INTR_ACTIVITY 0x100
#define DW_IC_INTR_STOP_DET 0x200
#define DW_IC_INTR_START_DET 0x400
#define DW_IC_INTR_GEN_CALL 0x800
#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
DW_IC_INTR_TX_EMPTY | \
DW_IC_INTR_TX_ABRT | \
DW_IC_INTR_STOP_DET)
#define DW_IC_STATUS_ACTIVITY 0x1
#define DW_IC_STATUS_MASTER_ACTIVITY 0x20
#define DW_IC_ERR_TX_ABRT 0x1
/*
* status codes
*/
#define STATUS_IDLE 0x0
#define STATUS_WRITE_IN_PROGRESS 0x1
#define STATUS_READ_IN_PROGRESS 0x2
#define TIMEOUT 20 /* ms */
/*
* hardware abort codes from the DW_IC_TX_ABRT_SOURCE register
*
* only expected abort codes are listed here
* refer to the datasheet for the full list
*/
#define ABRT_7B_ADDR_NOACK 0
#define ABRT_10ADDR1_NOACK 1
#define ABRT_10ADDR2_NOACK 2
#define ABRT_TXDATA_NOACK 3
#define ABRT_GCALL_NOACK 4
#define ABRT_GCALL_READ 5
#define ABRT_SBYTE_ACKDET 7
#define ABRT_SBYTE_NORSTRT 9
#define ABRT_10B_RD_NORSTRT 10
#define ABRT_MASTER_DIS 11
#define ARB_LOST 12
#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK)
#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK)
#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK)
#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK)
#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK)
#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ)
#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET)
#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT)
#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT)
#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS)
#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST)
#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \
DW_IC_TX_ABRT_10ADDR1_NOACK | \
DW_IC_TX_ABRT_10ADDR2_NOACK | \
DW_IC_TX_ABRT_TXDATA_NOACK | \
DW_IC_TX_ABRT_GCALL_NOACK)
static char *abort_sources[] = {
[ABRT_7B_ADDR_NOACK] =
"slave address not acknowledged (7bit mode)",
[ABRT_10ADDR1_NOACK] =
"first address byte not acknowledged (10bit mode)",
[ABRT_10ADDR2_NOACK] =
"second address byte not acknowledged (10bit mode)",
[ABRT_TXDATA_NOACK] =
"data not acknowledged",
[ABRT_GCALL_NOACK] =
"no acknowledgement for a general call",
[ABRT_GCALL_READ] =
"read after general call",
[ABRT_SBYTE_ACKDET] =
"start byte acknowledged",
[ABRT_SBYTE_NORSTRT] =
"trying to send start byte when restart is disabled",
[ABRT_10B_RD_NORSTRT] =
"trying to read when restart is disabled (10bit mode)",
[ABRT_MASTER_DIS] =
"trying to use disabled adapter",
[ARB_LOST] =
"lost arbitration",
};
/* i2c interrput definition */
#define M_GEN_CALL (1<<11)
#define M_START_DET (1<<10)
#define M_STOP_DET (1<<9)
#define M_ACTIVITY (1<<8)
#define M_RX_DONE (1<<7)
#define M_TX_ABRT (1<<6)
#define M_RD_REQ (1<<5)
#define M_TX_EMPTY (1<<4)
#define M_TX_OVER (1<<3)
#define M_RX_FULL (1<<2)
#define M_RX_OVER (1<<1)
#define M_RX_UNDER (1<<0)
#define M_NONE (0)
struct i2c_config
{
int speed_mode;
UINT32 tx_fifo_depth;
UINT32 rx_fifo_depth;
};
struct fh_i2c_obj
{
UINT32 id;
UINT32 irq;
UINT32 base;
UINT32 input_clock;
UINT32 abort_source;
struct i2c_config config;
};
rt_inline UINT32 I2C_SetTransmitThreshold(struct fh_i2c_obj *i2c_obj, int txtl)
{
return SET_REG(i2c_obj->base + OFFSET_I2C_TX_TL, txtl);
}
rt_inline UINT32 I2C_GetReceiveFifoLevel(struct fh_i2c_obj *i2c_obj)
{
return GET_REG(i2c_obj->base + OFFSET_I2C_RXFLR);
}
rt_inline UINT32 I2C_GetTransmitFifoLevel(struct fh_i2c_obj *i2c_obj)
{
return GET_REG(i2c_obj->base + OFFSET_I2C_TXFLR);
}
rt_inline void I2C_SetSlaveAddress(struct fh_i2c_obj *i2c_obj, rt_uint16_t addr)
{
UINT32 reg;
reg = GET_REG(i2c_obj->base + OFFSET_I2C_TAR);
reg &= ~(0x3ff);
reg |= addr & 0x3ff;
SET_REG(i2c_obj->base + OFFSET_I2C_TAR, reg);
}
rt_inline void I2C_Enable(struct fh_i2c_obj *i2c_obj, int enable)
{
SET_REG(i2c_obj->base + OFFSET_I2C_ENABLE, enable);
}
rt_inline UINT8 I2C_GetData(struct fh_i2c_obj *i2c_obj)
{
return GET_REG(i2c_obj->base + OFFSET_I2C_DATA_CMD) & 0xff;
}
rt_inline void I2C_SetDataCmd(struct fh_i2c_obj *i2c_obj, UINT32 reg)
{
SET_REG(i2c_obj->base + OFFSET_I2C_DATA_CMD, reg);
}
rt_inline void I2C_SetInterruptMask(struct fh_i2c_obj *i2c_obj, UINT32 mask)
{
SET_REG(i2c_obj->base + OFFSET_I2C_INTR_MASK, mask);
}
rt_inline UINT32 I2C_GetInterruptMask(struct fh_i2c_obj *i2c_obj)
{
return GET_REG(i2c_obj->base + OFFSET_I2C_INTR_MASK);
}
void I2C_Init(struct fh_i2c_obj *i2c_obj);
int I2C_HandleTxAbort(struct fh_i2c_obj *i2c_obj);
UINT32 I2C_ClearAndGetInterrupts(struct fh_i2c_obj *i2c_obj);
int I2C_WaitMasterIdle(struct fh_i2c_obj *i2c_obj);
int I2C_WaitDeviceIdle(struct fh_i2c_obj *i2c_obj);
#endif /* FH_I2C_H_ */

View File

@ -1,58 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_ICTL_H_
#define FH_ICTL_H_
#include "fh_def.h"
typedef struct {
RwReg IRQ_EN_L;
RwReg IRQ_EN_H;
RwReg IRQ_MASK_L;
RwReg IRQ_MASK_H;
RwReg IRQ_FORCE_L;
RwReg IRQ_FORCE_H;
RwReg IRQ_RAWSTARUS_L;
RwReg IRQ_RAWSTARUS_H;
RwReg IRQ_STATUS_L;
RwReg IRQ_STATUS_H;
RwReg IRQ_MASKSTATUS_L;
RwReg IRQ_MASKSTATUS_H;
RwReg IRQ_FINALSTATUS_L;
RwReg IRQ_FINALSTATUS_H;
RwReg IRQ_VECTOR;
}fh_intc;
void ictl_close_all_isr(fh_intc *p);
void ictl_mask_isr(fh_intc *p,int irq);
void ictl_unmask_isr(fh_intc *p,int irq);
#endif

View File

@ -1,299 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_MMC_H_
#define FH_MMC_H_
#include "fh_def.h"
#define OFFSET_SDC_CTRL (0x0000)
#define OFFSET_SDC_PWREN (0x0004)
#define OFFSET_SDC_CLKDIV (0x0008)
#define OFFSET_SDC_CLKSRC (0x000C)
#define OFFSET_SDC_CLKENA (0x0010)
#define OFFSET_SDC_TMOUT (0x0014)
#define OFFSET_SDC_CTYPE (0x0018)
#define OFFSET_SDC_BLKSIZ (0x001C)
#define OFFSET_SDC_BYTCNT (0x0020)
#define OFFSET_SDC_INTMASK (0x0024)
#define OFFSET_SDC_CMDARG (0x0028)
#define OFFSET_SDC_CMD (0x002C)
#define OFFSET_SDC_RESP0 (0x0030)
#define OFFSET_SDC_RESP1 (0x0034)
#define OFFSET_SDC_RESP2 (0x0038)
#define OFFSET_SDC_RESP3 (0x003C)
#define OFFSET_SDC_MINTSTS (0x0040)
#define OFFSET_SDC_RINTSTS (0x0044)
#define OFFSET_SDC_STATUS (0x0048)
#define OFFSET_SDC_FIFOTH (0x004C)
#define OFFSET_SDC_CDETECT (0x0050)
#define OFFSET_SDC_WRTPRT (0x0054)
#define OFFSET_SDC_GPIO (0x0058)
#define OFFSET_SDC_TCBCNT (0x005C)
#define OFFSET_SDC_TBBCNT (0x0060)
#define OFFSET_SDC_DEBNCE (0x0064)
#define OFFSET_SDC_USRID (0x0068)
#define OFFSET_SDC_VERID (0x006C)
#define OFFSET_SDC_HCON (0x0070)
#define OFFSET_SDC_UHS_REG (0x0074)
#define OFFSET_SDC_RST_N (0x0078)
#define OFFSET_SDC_BMOD (0x0080)
#define OFFSET_SDC_PLDMND (0x0084)
#define OFFSET_SDC_DBADDR (0x0088)
#define OFFSET_SDC_IDSTS (0x008C)
#define OFFSET_SDC_IDINTEN (0x0090)
#define OFFSET_SDC_DSCADDR (0x0094)
#define OFFSET_SDC_BUFADDR (0x0098)
#define OFFSET_SDC_CARDTHRCTL (0x0100)
#define OFFSET_SDC_BACK_END_POWER (0x0104)
#define OFFSET_SDC_FIFO (0x0200)
#define MMC_FIFO_DEPTH (16)
#define MMC_CMD_FLAG_RESPONSE_EXPECTED BIT(6)
#define MMC_CMD_FLAG_LONG_RESPONSE BIT(7)
#define MMC_CMD_FLAG_CHECK_RESP_CRC BIT(8)
#define MMC_CMD_FLAG_DATA_EXPECTED BIT(9)
#define MMC_CMD_FLAG_WRITE_TO_CARD BIT(10)
#define MMC_CMD_FLAG_DATA_STREAM BIT(11)
#define MMC_CMD_FLAG_AUTO_STOP BIT(12)
#define MMC_CMD_FLAG_WAIT_PREV_DATA BIT(13)
#define MMC_CMD_FLAG_STOP_TRANSFER BIT(14)
#define MMC_CMD_FLAG_SEND_INIT BIT(15)
#define MMC_CMD_FLAG_SWITCH_VOLTAGE BIT(28)
#define MMC_STATUS_DATA_BUSY BIT(9)
#define MMC_CTRL_CONTROLLER_RESET BIT(0)
#define MMC_CTRL_FIFO_RESET BIT(1)
#define MMC_CTRL_DMA_RESET BIT(2)
#define MMC_CTRL_INT_ENABLE BIT(4)
#define MMC_CTRL_USE_DMA BIT(25)
#define MMC_CMD_START_CMD BIT(31)
#define MMC_BMOD_RESET BIT(0)
#define MMC_CLOCK_IN (50000000)
#define MMC_CARD_WIDTH_1BIT (0)
#define MMC_CARD_WIDTH_4BIT (1)
#define MMC_INT_STATUS_CARD_DETECT BIT(0)
#define MMC_INT_STATUS_RESPONSE_ERROR BIT(1)
#define MMC_INT_STATUS_CMD_DONE BIT(2)
#define MMC_INT_STATUS_TRANSFER_OVER BIT(3)
#define MMC_INT_STATUS_TX_REQUEST BIT(4)
#define MMC_INT_STATUS_RX_REQUEST BIT(5)
#define MMC_INT_STATUS_RESP_CRC_ERROR BIT(6)
#define MMC_INT_STATUS_DATA_CRC_ERROR BIT(7)
#define MMC_INT_STATUS_RESPONSE_TIMEOUT BIT(8)
#define MMC_INT_STATUS_READ_TIMEOUT BIT(9)
#define MMC_INT_STATUS_STARVATION_TIMEOUT BIT(10)
#define MMC_INT_STATUS_OVERRUN_UNDERRUN BIT(11)
#define MMC_INT_STATUS_HARDWARE_LOCKED BIT(12)
#define MMC_INT_STATUS_START_BIT_ERROR BIT(13)
#define MMC_INT_STATUS_AUTO_CMD_DONE BIT(14)
#define MMC_INT_STATUS_END_BIT_ERROR BIT(15)
#define MMC_INT_STATUS_SDIO BIT(16)
#define MMC_INT_STATUS_ALL (~0)
#define MMC_INIT_STATUS_DATA_ERROR (MMC_INT_STATUS_DATA_CRC_ERROR \
| MMC_INT_STATUS_START_BIT_ERROR | MMC_INT_STATUS_END_BIT_ERROR)
#define MMC_USE_DMA
#ifdef MMC_USE_DMA
#define MMC_INT_STATUS_DATA (MMC_INT_STATUS_TRANSFER_OVER | MMC_INIT_STATUS_DATA_ERROR)
#else
#define MMC_INT_STATUS_DATA (MMC_INT_STATUS_TRANSFER_OVER | MMC_INIT_STATUS_DATA_ERROR \
| MMC_INT_STATUS_TX_REQUEST | MMC_INT_STATUS_RX_REQUEST)
#endif
#define MMC_DMA_DESC_BUFF_SIZE (0x1f00)
typedef union
{
struct
{
UINT32 reserved :1; //0~15
UINT32 disable_interrupt_on_completion :1; //16~31
UINT32 last_descriptor :1; //0~15
UINT32 first_descriptor :1; //16~31
UINT32 sencond_address_chained :1; //0~15
UINT32 end_of_ring :1; //16~31
UINT32 reserved_29_6 :24; //0~15
UINT32 card_error_summary :1; //16~31
UINT32 own :1; //16~31
}bit;
UINT32 dw;
}MMC_DMA_Descriptor0;
typedef union
{
struct
{
UINT32 buffer1_size :13; //0~15
UINT32 buffer2_size :13; //16~31
UINT32 reserved_26_31 :6; //0~15
}bit;
UINT32 dw;
}MMC_DMA_Descriptor1;
typedef union
{
struct
{
UINT32 buffer_addr0 :32; //0~15
}bit;
UINT32 dw;
}MMC_DMA_Descriptor2;
typedef union
{
struct
{
UINT32 buffer_addr1 :32; //0~15
}bit;
UINT32 dw;
}MMC_DMA_Descriptor3;
typedef struct
{
MMC_DMA_Descriptor0 desc0; /* control and status information of descriptor */
MMC_DMA_Descriptor1 desc1; /* buffer sizes */
MMC_DMA_Descriptor2 desc2; /* physical address of the buffer 1 */
MMC_DMA_Descriptor3 desc3; /* physical address of the buffer 2 */
}MMC_DMA_Descriptors;
struct fh_mmc_obj
{
rt_uint32_t id;
rt_uint32_t irq;
rt_uint32_t base;
rt_uint32_t power_pin_gpio;
MMC_DMA_Descriptors *descriptors;
void (*mmc_reset)(struct fh_mmc_obj *);
};
rt_inline rt_uint32_t MMC_GetCardStatus(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t card_status = GET_REG(mmc_obj->base + OFFSET_SDC_CDETECT);
return card_status & 0x1;
}
rt_inline void MMC_StartDma(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t reg;
SET_REG(mmc_obj->base + OFFSET_SDC_DBADDR, (rt_uint32_t)mmc_obj->descriptors);
reg = GET_REG(mmc_obj->base + OFFSET_SDC_BMOD);
reg |= 1 << 7;
SET_REG(mmc_obj->base + OFFSET_SDC_BMOD, reg);
}
rt_inline void MMC_StopDma(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t reg;
reg = GET_REG(mmc_obj->base + OFFSET_SDC_BMOD);
reg &= ~(1 << 7);
SET_REG(mmc_obj->base + OFFSET_SDC_BMOD, reg);
}
rt_inline rt_uint32_t MMC_GetWaterlevel(struct fh_mmc_obj *mmc_obj)
{
return (GET_REG(mmc_obj->base + OFFSET_SDC_STATUS) >> 17) & 0x1fff;
}
rt_inline rt_uint32_t MMC_GetStatus(struct fh_mmc_obj *mmc_obj)
{
return GET_REG(mmc_obj->base + OFFSET_SDC_STATUS);
}
rt_inline rt_uint32_t MMC_GetRawInterrupt(struct fh_mmc_obj *mmc_obj)
{
return GET_REG(mmc_obj->base + OFFSET_SDC_RINTSTS);
}
rt_inline rt_uint32_t MMC_GetUnmaskedInterrupt(struct fh_mmc_obj *mmc_obj)
{
return GET_REG(mmc_obj->base + OFFSET_SDC_MINTSTS);
}
rt_inline rt_uint32_t MMC_ClearRawInterrupt(struct fh_mmc_obj *mmc_obj, rt_uint32_t interrupts)
{
return SET_REG(mmc_obj->base + OFFSET_SDC_RINTSTS, interrupts);
}
rt_inline rt_uint32_t MMC_GetInterruptMask(struct fh_mmc_obj *mmc_obj)
{
return GET_REG(mmc_obj->base + OFFSET_SDC_INTMASK);
}
rt_inline rt_uint32_t MMC_SetInterruptMask(struct fh_mmc_obj *mmc_obj, rt_uint32_t mask)
{
return SET_REG(mmc_obj->base + OFFSET_SDC_INTMASK, mask);
}
rt_inline void MMC_SetByteCount(struct fh_mmc_obj *mmc_obj, rt_uint32_t bytes)
{
SET_REG(mmc_obj->base + OFFSET_SDC_BYTCNT, bytes);
}
rt_inline void MMC_SetBlockSize(struct fh_mmc_obj *mmc_obj, rt_uint32_t size)
{
SET_REG(mmc_obj->base + OFFSET_SDC_BLKSIZ, size);
}
rt_inline rt_uint32_t MMC_GetResponse(struct fh_mmc_obj *mmc_obj, int resp_num)
{
return GET_REG(mmc_obj->base + OFFSET_SDC_RESP0 + resp_num * 4);
}
rt_inline rt_uint32_t MMC_IsFifoEmpty(struct fh_mmc_obj *mmc_obj)
{
return (GET_REG(mmc_obj->base + OFFSET_SDC_STATUS) >> 2) & 0x1;
}
rt_inline rt_uint32_t MMC_IsDataStateBusy(struct fh_mmc_obj *mmc_obj)
{
return (GET_REG(mmc_obj->base + OFFSET_SDC_STATUS) >> 10) & 0x1;
}
void MMC_Init(struct fh_mmc_obj *mmc_obj);
int MMC_ResetFifo(struct fh_mmc_obj *mmc_obj);
int MMC_SetCardWidth(struct fh_mmc_obj *mmc_obj, int width);
int MMC_UpdateClockRegister(struct fh_mmc_obj *mmc_obj, int div);
int MMC_SendCommand(struct fh_mmc_obj *mmc_obj, rt_uint32_t cmd, rt_uint32_t arg, rt_uint32_t flags);
int MMC_WriteData(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size);
int MMC_ReadData(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size);
inline void MMC_StartDma(struct fh_mmc_obj *mmc_obj);
inline void MMC_StopDma(struct fh_mmc_obj *mmc_obj);
void MMC_InitDescriptors(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size);
#endif /* FH_MMC_H_ */

View File

@ -1,44 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_PWM_H_
#define FH_PWM_H_
#define OFFSET_PWM_CTRL (0x00)
#define OFFSET_PWM_CMD(n) (((n) * 4) + OFFSET_PWM_CTRL + 4)
struct fh_pwm_obj
{
int id;
int irq;
unsigned int base;
};
void PWM_Enable(struct fh_pwm_obj *pwm_obj, int enable);
void PWM_SetPwmCmd(struct fh_pwm_obj *pwm_obj, int device_id, unsigned int reg);
unsigned int PWM_GetPwmCmd(struct fh_pwm_obj *pwm_obj, int device_id);
#endif /* FH_PWM_H_ */

View File

@ -1,356 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_SDIO_H_
#define FH_SDIO_H_
#include <rtthread.h>
//#define __ASIC_BRANCH__
enum {
CTRL = 0x0, /** Control */
PWREN = 0x4, /** Power-enable */
CLKDIV = 0x8, /** Clock divider */
CLKSRC = 0xC, /** Clock source */
CLKENA = 0x10, /** Clock enable */
TMOUT = 0x14, /** Timeout */
CTYPE = 0x18, /** Card type */
BLKSIZ = 0x1C, /** Block Size */
BYTCNT = 0x20, /** Byte count */
INTMSK = 0x24, /** Interrupt Mask */
CMDARG = 0x28, /** Command Argument */
CMD = 0x2C, /** Command */
RESP0 = 0x30, /** Response 0 */
RESP1 = 0x34, /** Response 1 */
RESP2 = 0x38, /** Response 2 */
RESP3 = 0x3C, /** Response 3 */
MINTSTS = 0x40, /** Masked interrupt status */
RINTSTS = 0x44, /** Raw interrupt status */
STATUS = 0x48, /** Status */
FIFOTH = 0x4C, /** FIFO threshold */
CDETECT = 0x50, /** Card detect */
WRTPRT = 0x54, /** Write protect */
GPIO = 0x58, /** General Purpose IO */
TCBCNT = 0x5C, /** Transferred CIU byte count */
TBBCNT = 0x60, /** Transferred host/DMA to/from byte count */
DEBNCE = 0x64, /** Card detect debounce */
USRID = 0x68, /** User ID */
VERID = 0x6C, /** Version ID */
HCON = 0x70, /** Hardware Configuration */
UHSREG = 0x74, /** Reserved */
BMOD = 0x80, /** Bus mode Register */
PLDMND = 0x84, /** Poll Demand */
DBADDR = 0x88, /** Descriptor Base Address */
IDSTS = 0x8C, /** Internal DMAC Status */
IDINTEN = 0x90, /** Internal DMAC Interrupt Enable */
DSCADDR = 0x94, /** Current Host Descriptor Address */
BUFADDR = 0x98, /** Current Host Buffer Address */
FIFODAT = 0x200, /** FIFO data read write */
};
/* Control register definitions */
#define CTRL_RESET 0x00000001
#define FIFO_RESET 0x00000002
#define DMA_RESET 0x00000004
#define INT_ENABLE 0x00000010
#define READ_WAIT 0x00000040
#define CTRL_USE_IDMAC 0x02000000
/* Interrupt mask defines */
#define INTMSK_CDETECT 0x00000001
#define INTMSK_RESP_ERR 0x00000002
#define INTMSK_CMD_DONE 0x00000004
#define INTMSK_DAT_OVER 0x00000008
#define INTMSK_TXDR 0x00000010
#define INTMSK_RXDR 0x00000020
#define INTMSK_RCRC 0x00000040
#define INTMSK_DCRC 0x00000080
#define INTMSK_RTO 0x00000100
#define INTMSK_DTO 0x00000200
#define INTMSK_HTO 0x00000400
#define INTMSK_VSI INTMSK_HTO // VSI => Voltage Switch Interrupt
#define INTMSK_FRUN 0x00000800
#define INTMSK_HLE 0x00001000
#define INTMSK_SBE 0x00002000
#define INTMSK_ACD 0x00004000
#define INTMSK_EBE 0x00008000
#define INTMSK_SDIO 0x00010000
#define INTMASK_ERROR (INTMSK_RESP_ERR|INTMSK_RCRC|INTMSK_DCRC|INTMSK_RTO|INTMSK_DTO|INTMSK_HTO|INTMSK_FRUN|INTMSK_HLE|INTMSK_SBE|INTMSK_EBE)
/*BMOD register define */
#define BMOD_SWR 0x00000001
#define BMOD_DE 0x00000080
/* for STATUS register */
#define GET_FIFO_COUNT(x) (((x)&0x3ffe0000)>>17)
#define GET_FIFO_DEPTH(x) ((((x)&0x0FFF0000)>>16)+1)
/* for IDMA intr register */
#define IDMAINTBITS 0x337
/* PMU related registers */
//#define PMU_REG_BASE 0xF0000000
#define PMU_REG_RST 0xF0000100
#define PMU_REG_CLK_DIV3 0xF0000030
#define PMU_SDC0_RST_BIT 9
#define PMU_SDC1_RST_BIT 10
#define PMU_RST_MODULE(x) *((volatile unsigned int*)(PMU_REG_RST)) = (~((1<<(x))))
/* Define Card status bits (R1 response) */
#define R1CS_ADDRESS_OUT_OF_RANGE 0x80000000
#define R1CS_ADDRESS_MISALIGN 0x40000000
#define R1CS_BLOCK_LEN_ERR 0x20000000
#define R1CS_ERASE_SEQ_ERR 0x10000000
#define R1CS_ERASE_PARAM 0x08000000
#define R1CS_WP_VIOLATION 0x04000000
#define R1CS_CARD_IS_LOCKED 0x02000000
#define R1CS_LCK_UNLCK_FAILED 0x01000000
#define R1CS_COM_CRC_ERROR 0x00800000
#define R1CS_ILLEGAL_COMMAND 0x00400000
#define R1CS_CARD_ECC_FAILED 0x00200000
#define R1CS_CC_ERROR 0x00100000
#define R1CS_ERROR 0x00080000
#define R1CS_UNDERRUN 0x00040000
#define R1CS_OVERRUN 0x00020000
#define R1CS_CSD_OVERWRITE 0x00010000
#define R1CS_WP_ERASE_SKIP 0x00008000
#define R1CS_RESERVED_0 0x00004000
#define R1CS_ERASE_RESET 0x00002000
#define R1CS_CURRENT_STATE_MASK 0x00001e00
#define R1CS_READY_FOR_DATA 0x00000100
#define R1CS_SWITCH_ERROR 0x00000080
#define R1CS_RESERVED_1 0x00000040
#define R1CS_APP_CMD 0x00000020
#define R1CS_RESERVED_2 0x00000010
#define R1CS_APP_SPECIFIC_MASK 0x0000000c
#define R1CS_MANUFAC_TEST_MASK 0x00000003
#define R1CS_ERROR_OCCURED_MAP 0xfdffa080
#define R1CS_CURRENT_STATE(x) (((x)&R1CS_CURRENT_STATE_MASK)>>9)
/* R5 response */
#define R5_IO_CRC_ERR 0x00008000
#define R5_IO_BAD_CMD 0x00004000
#define R5_IO_GEN_ERR 0x00000800
#define R5_IO_FUNC_ERR 0x00000200
#define R5_IO_OUT_RANGE 0x00000100
#define R5_IO_ERR_BITS 0x0000cb00
enum {
NONE_TYPE = 0,
SD_TYPE,
SD_2_0_TYPE,
SDIO_TYPE,
};
enum {
CARD_STATE_EMPTY = -1,
CARD_STATE_IDLE = 0,
CARD_STATE_READY = 1,
CARD_STATE_IDENT = 2,
CARD_STATE_STBY = 3,
CARD_STATE_TRAN = 4,
CARD_STATE_DATA = 5,
CARD_STATE_RCV = 6,
CARD_STATE_PRG = 7,
CARD_STATE_DIS = 8,
CARD_STATE_INA = 9
};
enum DmaDescriptorDES1 // Buffer's size field of Descriptor
{
DescBuf2SizMsk = 0x03FFE000, /* Mask for Buffer2 Size 25:13 */
DescBuf2SizeShift = 13, /* Shift value for Buffer2 Size */
DescBuf1SizMsk = 0x00001FFF, /* Mask for Buffer1 Size 12:0 */
DescBuf1SizeShift = 0, /* Shift value for Buffer2 Size */
};
enum DmaDescriptorDES0 // Control and status word of DMA descriptor DES0
{
DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 */
DescCardErrSummary = 0x40000000, /* Indicates EBE/RTO/RCRC/SBE/DRTO/DCRC/RE 30 */
DescEndOfRing = 0x00000020, /* A "1" indicates End of Ring for Ring Mode 05 */
DescSecAddrChained = 0x00000010, /* A "1" indicates DES3 contains Next Desc Address 04 */
DescFirstDesc = 0x00000008, /* A "1" indicates this Desc contains first 03
buffer of the data */
DescLastDesc = 0x00000004, /* A "1" indicates buffer pointed to by this this 02
Desc contains last buffer of Data */
DescDisInt = 0x00000002, /* A "1" in this field disables the RI/TI of IDSTS 01
for data that ends in the buffer pointed to by
this descriptor */
};
typedef struct DmaDescStruct {
unsigned int desc0; /* control and status information of descriptor */
unsigned int desc1; /* buffer sizes */
unsigned int desc2; /* physical address of the buffer 1 */
unsigned int desc3; /* physical address of the buffer 2 */
}DmaDesc;
typedef struct {
unsigned int wkmod;
volatile DmaDesc *pDmaDesc;
unsigned int idma_support;
unsigned int rca;
unsigned int ip_base;
unsigned int card_type;
unsigned int fifo_depth;
unsigned int fifo_threth;
unsigned int sectors;
unsigned int scr[2];
unsigned int csd[4];
unsigned int idsts;
rt_sem_t sem;
rt_sem_t mutex;
void (*cb)(void);
} sdc_t;
#define ONE_BIT_MODE (0)
#define FOUR_BIT_MODE (1)
#define BE32_TO_CPU(x) ((unsigned int)( \
(((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
(((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24)))
#define synopmob_set_bits(reg, bit_id) *((volatile unsigned int *)(reg)) |= ((unsigned int)(bit_id))
#define synopmob_clear_bits(reg, bit_id) *((volatile unsigned int *)(reg)) &= (~((unsigned int)(bit_id)))
#define synopmob_set_register(reg, val) *((volatile unsigned int*)(reg)) = (val)
#define synopmob_read_register(reg) (*((volatile unsigned int*)(reg)))
enum {
ERRNOERROR = 0,
// for raw interrupt status error
ERRRESPRECEP, // 1
ERRRESPCRC,
ERRDCRC,
ERRRESPTIMEOUT,
ERRDRTIMEOUT,
ERRUNDERWRITE,
ERROVERREAD,
ERRHLE,
ERRSTARTBIT,
ERRENDBITERR, // 10
// for R1 response
ERRADDRESSRANGE, // 11
ERRADDRESSMISALIGN,
ERRBLOCKLEN,
ERRERASESEQERR,
ERRERASEPARAM,
ERRPROT,
ERRCARDLOCKED,
ERRCRC,
ERRILLEGALCOMMAND,
ERRECCFAILED,
ERRCCERR,
ERRUNKNOWN,
ERRUNDERRUN,
ERROVERRUN,
ERRCSDOVERWRITE,
ERRERASERESET,
ERRFSMSTATE, // 27
// for R5 response
ERRBADFUNC, // 28
// others
ERRCARDNOTCONN, // 29
ERRCARDWPROTECT,
ERRCMDRETRIESOVER,
ERRNOTSUPPORTED,
ERRHARDWARE,
ERRDATANOTREADY,
ERRCARDINTERNAL,
ERRACMD41TIMEOUT,
ERRIDMA,
ERRNORES,
ERRNOTEQUAL,
};
#ifdef __ASIC_BRANCH__
#define SDC_WHERE() *((volatile unsigned int*)0x9b800000) = ((unsigned int)(__LINE__))
#define SDC_ERROR() do { *((volatile unsigned int*)0x9b800008)=ret; *((volatile unsigned int*)0x9a7ff000) = 0;}while(0)
#define SDC_FINISH() *((volatile unsigned int*)0x9a7ff004) = 0;
#else
#define SDC_WHERE()
#define SDC_ERROR()
#define SDC_FINISH()
#endif //__ASIC_BRANCH__
#define SDC_WKMOD_25M_STAND_SPEED 0x0002 // 25M standard speed
#define SDC_WKMOD_50M_HI_SPEED 0x0004 // 50M high speed
#define SDC_WKMOD_1WIRE 0x0008 // 1 wire transfer mode
#define SDC_WKMOD_4WIRE 0x0010 // 4 wire transfer mode
#define SDC_RW_USE_DMA 0x80000000 // Use DMA transfer?
typedef void* HSDC;
// map to DmaDesc
typedef struct _buf_chain {
unsigned int csi; // desc0
unsigned int size; // desc1
void * buf; // desc2
struct _buf_chain *next; // desc3
}buf_chain_t;
/*
* for SD card
*/
extern int sdc_is_connected(unsigned int which);
extern int sdc_init(unsigned int which, unsigned int wkmod, unsigned int* dma_desc/*4Byte aligned,16 bytes space*/, HSDC* phandle);
extern int sdc_read_block(HSDC handle, unsigned int blk, unsigned int num, unsigned char* buffer);
extern int sdc_write_block(HSDC handle, unsigned int blk, unsigned int num, unsigned char* buffer);
extern int sdc_erase_block(HSDC handle, unsigned int blk, unsigned int num);
extern int sdc_get_sector_num(HSDC handle);
extern int sdc_set_clk_divider(unsigned int divider);
/*
* for SDIO WIFI card
*/
extern void fh_sdio0_init(void);
extern void fh_sdio1_init(void);
extern void fh_sdio_init(void);
extern int sdio_init(unsigned int which, unsigned int wkmod, unsigned int* dma_desc/*4Byte aligned,16 bytes space*/, HSDC* phandle);
extern int sdio_high_speed_mode(HSDC handle, int bitwidth, int freq);
extern int sdio_enable_card_int(HSDC handle, int enable);
extern int sdio_set_card_int_cb(HSDC handle, void (*cb)(void));
extern int sdio_drv_read(HSDC handle, unsigned int addr, unsigned int fn, unsigned int bcnt, unsigned int bsize, unsigned char *buf);
extern int sdio_drv_write(HSDC handle, unsigned int addr, unsigned int fn, unsigned int bcnt, unsigned int bsize, unsigned char *buf);
extern int sdio_drv_creg_read(HSDC handle, int addr, int fn, unsigned int *resp);
extern int sdio_drv_creg_write(HSDC handle, int addr, int fn, unsigned char data, unsigned int *resp);
extern void inv_dcache_range(unsigned long start, unsigned long len);
extern void flush_dcache_range(unsigned long start, unsigned long len);
#endif //__sdcard_h__

View File

@ -1,148 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_SPI_H_
#define FH_SPI_H_
#include "fh_def.h"
#include "fh_arch.h"
#define OFFSET_SPI_CTRL0 (0x00)
#define OFFSET_SPI_CTRL1 (0x04)
#define OFFSET_SPI_SSIENR (0x08)
#define OFFSET_SPI_MWCR (0x0c)
#define OFFSET_SPI_SER (0x10)
#define OFFSET_SPI_BAUD (0x14)
#define OFFSET_SPI_TXFTLR (0x18)
#define OFFSET_SPI_RXFTLR (0x1c)
#define OFFSET_SPI_TXFLR (0x20)
#define OFFSET_SPI_RXFLR (0x24)
#define OFFSET_SPI_SR (0x28)
#define OFFSET_SPI_IMR (0x2c)
#define OFFSET_SPI_ISR (0x30)
#define OFFSET_SPI_RISR (0x34)
#define OFFSET_SPI_TXOIC (0x38)
#define OFFSET_SPI_RXOIC (0x3c)
#define OFFSET_SPI_RXUIC (0x40)
#define OFFSET_SPI_MSTIC (0x44)
#define OFFSET_SPI_ICR (0x48)
#define OFFSET_SPI_DMACTRL (0x4c)
#define OFFSET_SPI_DMATDL (0x50)
#define OFFSET_SPI_DMARDL (0x54)
#define OFFSET_SPI_IDR (0x58)
#define OFFSET_SPI_SSI_COMPVER (0x5c)
#define OFFSET_SPI_DR (0x60)
#define SPI_FORMAT_MOTOROLA (0x00)
#define SPI_FORMAT_TI (0x10)
#define SPI_FORMAT_MICROWIRE (0x20)
#define SPI_MODE_TX_RX (0x000)
#define SPI_MODE_TX_ONLY (0x100)
#define SPI_MODE_RX_ONLY (0x200)
#define SPI_MODE_EEPROM (0x300)
#define SPI_DATA_SIZE_4BIT (0x03)
#define SPI_DATA_SIZE_5BIT (0x04)
#define SPI_DATA_SIZE_6BIT (0x05)
#define SPI_DATA_SIZE_7BIT (0x06)
#define SPI_DATA_SIZE_8BIT (0x07)
#define SPI_DATA_SIZE_9BIT (0x08)
#define SPI_DATA_SIZE_10BIT (0x09)
#define SPI_DATA_SIZE_16BIT (0x0f)
#define SPI_POLARITY_HIGH (1<<7)
#define SPI_POLARITY_LOW (0<<7)
#define SPI_PHASE_RX_FIRST (0<<6)
#define SPI_PHASE_TX_FIRST (1<<6)
#define SPI_FIFO_DEPTH (32)
#define SPI_IRQ_TXEIM (1<<0)
#define SPI_IRQ_TXOIM (1<<1)
#define SPI_IRQ_RXUIM (1<<2)
#define SPI_IRQ_RXOIM (1<<3)
#define SPI_IRQ_RXFIM (1<<4)
#define SPI_IRQ_MSTIM (1<<5)
#define SPI_IRQ_ALL (0x3f)
#define SPI_ISR_FLAG (SPI_IRQ_TXEIM|SPI_IRQ_TXOIM|SPI_IRQ_RXUIM|SPI_IRQ_RXOIM)
#define SPI_ISR_ERROR (SPI_IRQ_TXOIM | SPI_IRQ_RXUIM | SPI_IRQ_RXOIM)
#define SPI_STATUS_BUSY (1)
#define SPI_TX_DMA (1<<1)
#define SPI_RX_DMA (1<<0)
struct spi_config
{
rt_uint32_t frame_format;
rt_uint32_t transfer_mode;
rt_uint32_t clk_polarity;
rt_uint32_t clk_phase;
rt_uint32_t data_size;
rt_uint32_t clk_div;
};
struct fh_spi_obj
{
rt_uint32_t id;
rt_uint32_t irq;
rt_uint32_t base;
rt_uint32_t fifo_len;
rt_uint32_t transfered_len;
rt_uint32_t received_len;
rt_uint32_t cs_gpio_pin;
struct spi_config config;
};
void SPI_EnableSlaveen(struct fh_spi_obj *spi_obj, rt_uint32_t port);
void SPI_DisableSlaveen(struct fh_spi_obj *spi_obj, rt_uint32_t port);
void SPI_SetTxLevel(struct fh_spi_obj *spi_obj, rt_uint32_t level);
void SPI_EnableIrq(struct fh_spi_obj *spi_obj, rt_uint32_t flag);
void SPI_DisableIrq(struct fh_spi_obj *spi_obj, rt_uint32_t flag);
rt_uint32_t SPI_InterruptStatus(struct fh_spi_obj *spi_obj);
void SPI_ClearInterrupt(struct fh_spi_obj *spi_obj);
rt_uint32_t SPI_ReadTxFifoLevel(struct fh_spi_obj *spi_obj);
rt_uint32_t SPI_ReadRxFifoLevel(struct fh_spi_obj *spi_obj);
UINT8 SPI_ReadData(struct fh_spi_obj *spi_obj);
void SPI_WriteData(struct fh_spi_obj *spi_obj, UINT8 data);
rt_uint32_t SPI_ReadStatus(struct fh_spi_obj *spi_obj);
void SPI_Enable(struct fh_spi_obj *spi_obj, int enable);
void SPI_SetParameter(struct fh_spi_obj *spi_obj);
void SPI_EnableDma(struct fh_spi_obj *spi_obj, rt_uint32_t channel);
void SPI_DisableDma(struct fh_spi_obj *spi_obj, rt_uint32_t channel);
void SPI_WriteTxDmaLevel(struct fh_spi_obj *spi_obj, rt_uint32_t data);
void SPI_WriteRxDmaLevel(struct fh_spi_obj *spi_obj, rt_uint32_t data);
#endif /* FH_SPI_H_ */

View File

@ -1,100 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_TIMER_H_
#define FH_TIMER_H_
/****************************************************************************
* #include section
* add #include here if any
***************************************************************************/
#include "fh_def.h"
/****************************************************************************
* #define section
* add constant #define here if any
***************************************************************************/
#define TIMER_CTRL_ENABLE (1u << 0)
#define TIMER_CTRL_MODE (1u << 1)
#define TIMER_CTRL_INTMASK (1u << 2)
#define TIMER_CTRL_PWMEN (1u << 3)
/****************************************************************************
* ADT section
* add Abstract Data Type definition here
***************************************************************************/
typedef struct {
RwReg TIMER_LOAD_COUNT;
RwReg TIMER_CURRENT_VALUE;
RwReg TIMER_CTRL_REG;
RwReg TIMER_EOI;
RwReg TIMER_INT_STATUS;
}timer;
enum timer_mode {
TIMER_MODE_PERIODIC = 0,
TIMER_MODE_ONESHOT = 1,
};
/****************************************************************************
* extern variable declaration section
***************************************************************************/
/****************************************************************************
* section
* add function prototype here if any
***************************************************************************/
int timer_init(timer *tim);
int timer_set_mode(timer *tim, enum timer_mode);
void timer_set_period(timer *tim, UINT32 period, UINT32 clock);
void timer_enable(timer *tim);
void timer_disable(timer *tim);
void timer_enable_irq(timer *tim);
void timer_disable_irq(timer *tim);
UINT32 timer_get_status(timer *tim);
void udelay(unsigned long usec);
#endif /* #ifndef _TIMER_ */

View File

@ -1,245 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_UART_H_
#define FH_UART_H_
/****************************************************************************
* #include section
* add #include here if any
***************************************************************************/
#include "fh_def.h"
/****************************************************************************
* #define section
* add constant #define here if any
***************************************************************************/
#define UART_RBR RBRTHRDLL
#define UART_THR RBRTHRDLL
#define UART_DLL RBRTHRDLL
#define UART_DLH DLHIER
#define UART_IER DLHIER
#define UART_IIR IIRFCR
#define UART_FCR IIRFCR
/* LSR register bits */
#define UART_LSR_DR (1 << 0)
#define UART_LSR_OE (1 << 1)
#define UART_LSR_PE (1 << 2)
#define UART_LSR_FE (1 << 3)
#define UART_LSR_BI (1 << 4)
#define UART_LSR_THER (1 << 5)
#define UART_LST_TEMT (1 << 6)
#define UART_LSR_RFE (1 << 7)
/* LCR register bits */
#define UART_LCR_DLS5 0x00
#define UART_LCR_DLS6 0x01
#define UART_LCR_DLS7 0x02
#define UART_LCR_DLS8 0x03
#define UART_LCR_STOP1 0
#define UART_LCR_STOP2 (1 << 2)
#define UART_LCR_PEN (1 << 3)
#define UART_LCR_EVEN (1 << 4)
#define UART_LCR_SP (1 << 5)
#define UART_LCR_BC (1 << 6)
#define UART_LCR_DLAB (1 << 7)
/* MCR register bits */
#define UART_MCR_DTR (1 << 0)
#define UART_MCR_RTS (1 << 1)
#define UART_MCR_OUT1 (1 << 2)
#define UART_MCR_OUT2 (1 << 3)
#define UART_MCR_LB (1 << 4)
#define UART_MCR_AFCE (1 << 5)
#define UART_MCR_SIRE (1 << 6)
/* FCR register bits */
#define UART_FCR_FIFOE (1 << 0)
#define UART_FCR_RFIFOR (1 << 1)
#define UART_FCR_XFIFOR (1 << 2)
#define UART_FCR_DMAM (1 << 3)
#define UART_FCR_TET_EMPTY (0x00 << 4)
#define UART_FCR_TET_TWO (0x01 << 4)
#define UART_FCR_TET_1_4 (0x02 << 4)
#define UART_FCR_TET_1_2 (0x03 << 4)
#define UART_FCR_RT_ONE (0x00 << 6)
#define UART_FCR_RT_1_4 (0x01 << 6)
#define UART_FCR_RT_1_2 (0x02 << 6)
#define UART_FCR_RT_L2 (0x03 << 6)
/* IER register bits */
#define UART_IER_ERBFI (1 << 0)
#define UART_IER_ETBEI (1 << 1)
#define UART_IER_ELSI (1 << 2)
#define UART_IER_EDSSI (1 << 3)
#define UART_IER_PTIME (1 << 7)
/* USR register bits */
#define UART_USR_BUSY (1 << 0)
#define UART_USR_TFNF (1 << 1)
#define UART_USR_TFE (1 << 2)
#define UART_USR_RNFE (1 << 3)
#define UART_USR_RFE (1 << 4)
/* IIR register bits */
#define UART_IIR_RIID_MASK 0x0f
#define UART_IIR_MODEM 0x00
#define UART_IIR_NOINT 0x01
#define UART_IIR_THREMPTY 0x02
#define UART_IIR_RDATD 0x04
#define UART_IIR_RLINEST 0x06
#define UART_IIR_BUSY 0x07
#define UART_IIR_CHRTOUT 0x0c
#define UART_IIR_FIFOSE (0x03 << 6)
//uart baudrate cofig
//#define UART_CLOCK_FREQ (27000000) //27MHZ
//
//#define DIV(n) (((UART_CLOCK_FREQ/(n))+8)/16)
/****************************************************************************
* ADT section
* add Abstract Data Type definition here
***************************************************************************/
typedef struct {
RwReg RBRTHRDLL; /* UART_RBR, UART_THR, UART_DLL */
RwReg DLHIER; /* UART_DLH, UART_IER */
RwReg IIRFCR; /* UART_IIR, UART_FCR */
RwReg UART_LCR; /*(0x000c) */
RwReg UART_MCR; /*(0x0010) */
RwReg UART_LSR; /*(0x0014) */
RwReg UART_MSR; /*(0x0018) */
RwReg UART_SCR; /*(0x001c) */
RwReg reserved[20];
RwReg UART_FAR; /* (0x0070) */
RwReg UART_TFR; /* (0x0074) */
RwReg UART_RFW; /* (0x0078) */
RwReg UART_USR; /* (0x007c) */
RwReg UART_TFL; /* (0x0080) */
RwReg UART_RFL; /* (0x0084) */
RwReg UART_SRR; /* (0x0088) */
RwReg reserved1[3];
RwReg UART_SFE; /* (0x0098) */
RwReg UART_SRT; /* (0x009c) */
RwReg UART_STET; /* (0x00a0) */
RwReg UART_HTX; /* (0x00a4) */
RwReg UART_DMASA; /* (0x00a8) */
RwReg reserved2[18];
RwReg UART_CPR; /* (0x00f4) */
RwReg UART_UCV; /* (0x00f8) */
RwReg UART_CTR; /* (0x00fc) */
}uart;
struct fh_uart {
uart *uart_port;
int irq;
};
enum data_bits {
UART_DATA_BIT5 = 0,
UART_DATA_BIT6 = 1,
UART_DATA_BIT7 = 2,
UART_DATA_BIT8 = 3
};
enum stop_bits {
UART_STOP_BIT1 = 0,
UART_STOP_BIT1_5 = 1,
UART_STOP_BIT2 = 2
};
enum parity {
UART_PARITY_NONE = 0,
UART_PARITY_EVEN = 1,
UART_PARITY_ODD = 2,
UART_PARITY_ST = 3 /* Stick Parity */
};
#define UART_CLOCK_FREQ (30000000) //30MHZ
typedef enum enum_uart_baudrate{
BAUDRATE_9600 = (((UART_CLOCK_FREQ/9600)+8)/16),
BAUDRATE_19200 = (((UART_CLOCK_FREQ/19200)+8)/16),
BAUDRATE_38400 = (((UART_CLOCK_FREQ/38400)+8)/16),
BAUDRATE_57600 = (((UART_CLOCK_FREQ/57600)+8)/16),
BAUDRATE_115200 = (((UART_CLOCK_FREQ/115200)+8)/16),
BAUDRATE_194000 = (((UART_CLOCK_FREQ/194000)+8)/16),
}uart_baudrate_e;
/****************************************************************************
* extern variable declaration section
***************************************************************************/
extern int uart_init(uart *port);
extern UINT32 uart_get_status(uart *port);
extern void uart_configure(uart *port, enum data_bits data_bit,
enum stop_bits stop_bit, enum parity parity,
UINT32 buard_rate, UINT32 uart_clk);
extern int uart_enable_irq(uart *port, UINT32 mode);
extern int uart_disable_irq(uart *port, UINT32 mode);
extern UINT32 uart_get_iir_status(uart *port);
extern UINT32 uart_get_line_status(uart *port);
extern UINT32 uart_is_rx_ready(uart *port);
extern UINT8 uart_getc(uart *port);
extern void uart_putc(uart *port, UINT8 c);
extern void uart_set_fifo_mode(uart *port, UINT32 fifo_mode);
/****************************************************************************
* section
* add function prototype here if any
***************************************************************************/
#endif /* #ifndef _TIMER_ */

View File

@ -1,71 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_WDT_H_
#define FH_WDT_H_
#include "fh_def.h"
#define WDOG_CONTROL_REG_OFFSET 0x00
#define WDOG_CONTROL_REG_WDT_EN_MASK 0x01
#define WDOG_CONTROL_REG_RMOD_MASK 0x02
#define WDOG_TIMEOUT_RANGE_REG_OFFSET 0x04
#define WDOG_CURRENT_COUNT_REG_OFFSET 0x08
#define WDOG_COUNTER_RESTART_REG_OFFSET 0x0c
#define WDOG_COUNTER_RESTART_KICK_VALUE 0x76
/* Hardware timeout in seconds */
#define WDT_HW_TIMEOUT 2
/* User land timeout */
#define WDT_HEARTBEAT 15
/* The maximum TOP (timeout period) value that can be set in the watchdog. */
#define FH_WDT_MAX_TOP 15
#define WDT_TIMEOUT (HZ / 2)
struct fh_wdt_obj
{
int id;
int irq;
unsigned int base;
};
void WDT_Enable(struct fh_wdt_obj *wdt_obj, int enable);
rt_inline int WDT_IsEnable(struct fh_wdt_obj *wdt_obj)
{
return GET_REG(wdt_obj->base + WDOG_CONTROL_REG_OFFSET) &
WDOG_CONTROL_REG_WDT_EN_MASK;
}
void WDT_SetTopValue(struct fh_wdt_obj *wdt_obj, int top);
void WDT_SetCtrl(struct fh_wdt_obj *wdt_obj, UINT32 reg);
void WDT_Kick(struct fh_wdt_obj *wdt_obj);
unsigned int WDT_GetCurrCount(struct fh_wdt_obj *wdt_obj);
#endif /* FH_WDT_H_ */

View File

@ -1,10 +0,0 @@
from building import *
Import('rtconfig')
cwd = GetCurrentDir()
src = ['gcc/start_gcc.S']
group = DefineGroup('Libraries', src, depend = [''])
Return('group')

View File

@ -1,416 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rtconfig.h>
#include <armv6.h>
#define CONFIG_STACKSIZE 512
#define FPEXC_EN (1 << 30) /* VFP enable bit */
.equ I_BIT, 0x80 @ when I bit is set, IRQ is disabled
.equ F_BIT, 0x40 @ when F bit is set, FIQ is disabled
#.equ USERMODE, 0x10
#.equ FIQMODE, 0x11
#.equ IRQMODE, 0x12
#.equ SVCMODE, 0x13
#.equ ABORTMODE, 0x17
#.equ UNDEFMODE, 0x1b
#.equ MODEMASK, 0x1f
#.equ NOINT, 0xc0
.equ RAM_BASE, 0x00000000 /*Start address of RAM*/
.equ ROM_BASE, 0xA0000000 /*Start address of Flash*/
#define FH81_INTC_BASE 0xE0200000
/*
*************************************************************************
*
* Jump vector table
*
*************************************************************************
*/
.section .init, "ax"
.code 32
.globl _start
_start:
b reset
ldr pc, _vector_undef
ldr pc, _vector_swi
ldr pc, _vector_pabt
ldr pc, _vector_dabt
ldr pc, _vector_resv
ldr pc, _vector_irq
ldr pc, _vector_fiq
_vector_undef: .word vector_undef
_vector_swi: .word vector_swi
_vector_pabt: .word vector_pabt
_vector_dabt: .word vector_dabt
_vector_resv: .word vector_resv
_vector_irq: .word vector_irq
_vector_fiq: .word vector_fiq
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
* relocate armboot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
/*
* rtthread kernel start and end
* which are defined in linker script
*/
.globl _rtthread_start
_rtthread_start:
.word _start
.globl _rtthread_end
_rtthread_end:
.word _end
/*
* rtthread bss start and end which are defined in linker script
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word __bss_end
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word _irq_stack_start + 1024
.globl FIQ_STACK_START
FIQ_STACK_START:
.word _fiq_stack_start + 1024
.globl UNDEFINED_STACK_START
UNDEFINED_STACK_START:
.word _undefined_stack_start + CONFIG_STACKSIZE
.globl ABORT_STACK_START
ABORT_STACK_START:
.word _abort_stack_start + CONFIG_STACKSIZE
.globl _STACK_START
_STACK_START:
.word _svc_stack_start + 4096
/* ----------------------------------entry------------------------------*/
reset:
/* set the cpu to SVC32 mode */
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r0,r0,#SVCMODE
msr cpsr,r0
@vector 0x0
@enable icaches
@little endian
@disable dcaches, mmu
//ldr r0, =0x00400078
@ldr r0, =0x0000107a
// mcr p15, 0, r0, c1, c0, 0
//read
ldr r0, =0x0
mrc p15, 0, r0, c1, c0, 0
//change
ldr r0, =0x00400078
mcr p15, 0, r0, c1, c0, 0
//check
ldr r0, =0x0
mrc p15, 0, r0, c1, c0, 0
ldr r0, =0x00000000
mcr p15, 0, r0, c8, c7, 0 @ Flush TLB
mcr p15, 0, r0, c7, c7, 0 @ Flush Caches
mcr p15, 0, r0, c7, c10, 4 @ Flush Write Buffer
/* mask all IRQs by clearing all bits in the INTMRs set low and high to 0 */
ldr r1, =FH81_INTC_BASE
ldr r0, =0x0
str r0, [r1]
str r0, [r1, #4]
/* setup stack */
bl stack_setup
/* clear .bss */
mov r0,#0 /* get a zero */
ldr r1,=__bss_start /* bss start */
ldr r2,=__bss_end /* bss end */
bss_loop:
cmp r1,r2 /* check if data to clear */
strlo r0,[r1],#4 /* clear 4 bytes */
blo bss_loop /* loop until done */
/* call C++ constructors of global objects */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0], #4
stmfd sp!, {r0-r1}
mov lr, pc
bx r2
ldmfd sp!, {r0-r1}
b ctor_loop
ctor_end:
/* enable_unaligned_access */
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x02 /*Clear the A bit, bit 1*/
and r0, r0, #(1 << 22) /*Set the U bit, bit 22*/
mcr p15, 0, r0, c1, c0, 0
#ifdef RT_USING_VFP
bl vfp_init
#endif
/* start RT-Thread Kernel */
ldr pc, _rtthread_startup
_rtthread_startup:
.word rtthread_startup
.global cpu_reset
cpu_reset:
#ldr r0, =0xfffffd00
#ldr r1, =(AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST)
#str r1, [r0]
#mov pc, lr
B cpu_reset
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
.macro push_exp_reg
sub sp, sp, #S_FRAME_SIZE @/* Sizeof(struct rt_hw_stack) */
stmib sp, {r0 - r12} @/* Calling r0-r12 */
mov r0, sp
mrs r6, spsr @/* Save CPSR */
str lr, [r0, #S_PC] @/* Push PC */
str r6, [r0, #S_CPSR] @/* Push CPSR */
@ switch to SVC mode with no interrupt
msr cpsr_c, #I_BIT|F_BIT|SVCMODE
str sp, [r0, #S_SP] @/* Save calling SP */
str lr, [r0, #S_LR] @/* Save calling PC */
.endm
#ifdef RT_USING_VFP
__ret_to_undef:
ldmfd sp!, {r4} @ pop task's cpsr to spsr
msr spsr_cxsf, r4
ldmfd sp!, {r0-r12}
add sp, sp, #4
ldmfd sp!, {lr,pc}^
#endif
/* exception handlers */
.align 5
vector_undef:
push_exp_reg
#ifdef RT_USING_VFP
cps #UNDEFMODE
ldr r2, [r0, #S_PC] @ r2=faulted PC+4
adr r9, __ret_to_undef @ r9=exception success return
sub r1, r2, #4
ldr r0, [r1] @ r0=faulted instruction
bl undef_entry
mov r0, sp
#endif
bl rt_hw_trap_udef
.align 5
vector_swi:
push_exp_reg
bl rt_hw_trap_swi
.align 5
vector_pabt:
push_exp_reg
bl rt_hw_trap_pabt
.align 5
vector_dabt:
push_exp_reg
bl rt_hw_trap_dabt
.align 5
vector_resv:
push_exp_reg
bl rt_hw_trap_resv
.globl rt_interrupt_enter
.globl rt_interrupt_leave
.globl rt_thread_switch_interrupt_flag
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
vector_irq:
stmfd sp!, {r0-r12,lr}
@
#ifdef RT_USING_VFP
vmrs r0, fpexc
stmfd sp!, {r0} @ save VFP status -- irq_fpexc = fpexc
bic r0, r0, #FPEXC_EN @ always disable VFP so we can
@ lazily save/restore the old state.
vmsr fpexc, r0
#endif
bl rt_interrupt_enter
bl rt_hw_trap_irq
bl rt_interrupt_leave
#ifdef RT_USING_VFP
ldmfd sp!, {r1}
vmrs r0, fpexc
tst r0, #FPEXC_EN @ irq used VFP?
bicne r1, r0, #FPEXC_EN @ if irq used VFP, then clear fpexc.en bit
vmsr fpexc, r1 @ restore VFP status
@ if irq not used VFP, then fpexc = irq_fpexc
@ if irq used VFP, then disable VFP
#endif
@ if rt_thread_switch_interrupt_flag set, jump to
@ rt_hw_context_switch_interrupt_do and don't return
ldr r0, =rt_thread_switch_interrupt_flag
ldr r1, [r0]
cmp r1, #1
beq rt_hw_context_switch_interrupt_do
ldmfd sp!, {r0-r12,lr}
@mrs r8,spsr
@msr cpsr, r8
subs pc, lr, #4
.align 5
vector_fiq:
stmfd sp!,{r0-r7,lr}
bl rt_hw_trap_fiq
ldmfd sp!,{r0-r7,lr}
subs pc,lr,#4
rt_hw_context_switch_interrupt_do:
mov r1, #0 @ clear flag
str r1, [r0]
ldmfd sp!, {r0-r12,lr}@ reload saved registers
stmfd sp, {r0-r2} @ save r0-r2
mrs r0, spsr @ get cpsr of interrupt thread
sub r1, sp, #4*3
sub r2, lr, #4 @ save old task's pc to r2
@ switch to SVC mode with no interrupt
msr cpsr_c, #I_BIT|F_BIT|SVCMODE
stmfd sp!, {r2} @ push old task's pc
stmfd sp!, {r3-r12,lr}@ push old task's lr,r12-r4
ldmfd r1, {r1-r3} @ restore r0-r2 of the interrupt thread
stmfd sp!, {r1-r3} @ push old task's r0-r2
stmfd sp!, {r0} @ push old task's cpsr
ldr r4, =rt_interrupt_from_thread
ldr r5, [r4]
str sp, [r5] @ store sp in preempted tasks's TCB
ldr r6, =rt_interrupt_to_thread
ldr r6, [r6]
ldr sp, [r6] @ get new task's stack pointer
ldmfd sp!, {r4} @ pop new task's cpsr to spsr
msr spsr_cxsf, r4
#ifdef RT_USING_VFP
vmrs r0, fpexc
bic r0, r0, #FPEXC_EN @ always disable VFP so we can
@ lazily save/restore the old state.
vmsr fpexc, r0
#endif
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
stack_setup:
mrs r0, cpsr
bic r0, r0, #MODEMASK
orr r1, r0, #UNDEFMODE|NOINT
msr cpsr_cxsf, r1 /* undef mode */
ldr sp, UNDEFINED_STACK_START
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 /* abort mode */
ldr sp, ABORT_STACK_START
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 /* IRQ mode */
ldr sp, IRQ_STACK_START
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 /* FIQ mode */
ldr sp, FIQ_STACK_START
bic r0,r0,#MODEMASK
orr r1,r0,#SVCMODE|NOINT
msr cpsr_cxsf,r1 /* SVC mode */
ldr sp, _STACK_START
/* USER mode is not initialized. */
bx lr /* The LR register may be not valid for the mode changes.*/
/*/*}*/

View File

@ -1,96 +0,0 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. =0xA0000000;
. = ALIGN(4);
__text_start = .;
.text :
{
*(.init)
*(.text)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
/* section information for modules */
. = ALIGN(4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
}
__text_end = .;
. = ALIGN(4);
__rodata_start = .;
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) *(.eh_frame) }
__rodata_end = .;
. = ALIGN(4);
.ctors :
{
PROVIDE(__ctors_start__ = .);
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
PROVIDE(__ctors_end__ = .);
}
.dtors :
{
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end__ = .);
}
. = ALIGN(4);
__data_start = .;
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
__data_end = .;
. = ALIGN(4);
.nobss : { *(.nobss) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
__bss_end = .;
/* stabs debugging sections. */
.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) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
_end = .;
}

View File

@ -1,15 +0,0 @@
# RT-Thread building script for bridge
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View File

@ -1,33 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include "platform_def.h"
void rt_hw_board_init(void);
#endif

View File

@ -1,83 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef __BOARD_INFO_H__
#define __BOARD_INFO_H__
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************************
* #include section
* add #include here if any
***************************************************************************/
/****************************************************************************
* #define section
* add constant #define here if any
***************************************************************************/
/****************************************************************************
* ADT section
* add Abstract Data Type definition here
***************************************************************************/
typedef int (*probe_p)(void *);
typedef int (*exit_p)(void *);
struct fh_board_ops {
//void *ops_data;
probe_p probe;
probe_p exit;
};
struct fh_board_info {
char *name;
void *data;
struct fh_board_ops *ops;
};
/****************************************************************************
* extern variable declaration section
***************************************************************************/
int fh_board_info_init(void);
struct fh_board_info *fh_board_info_register(char *info_name, void *data);
int fh_board_driver_register(char *info_name, struct fh_board_ops *ops);
void fh_print_all_board_info(void);
void fh_free_all_info(void);
/****************************************************************************
* section
* add function prototype here if any
***************************************************************************/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,8 +0,0 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
group = DefineGroup('Drivers', src, depend = [''])
Return('group')

View File

@ -1,250 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
*****************************************************************************/
#include "board_info.h"
#include <rtdevice.h>
#include <string.h>
/*****************************************************************************
* Define section
* add all #define here
*****************************************************************************/
struct fh_board_info_list_node {
struct fh_board_info obj;
rt_list_t list;
};
#define CHECK_TEST_LIST_EMPTY \
if(rt_list_isempty(&board_info_head.list)) \
rt_kprintf("board info is null...please register first..\n")
/****************************************************************************
* ADT section
* add definition of user defined Data Type that only be used in this file here
***************************************************************************/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = rt_list_entry((head)->next, typeof(*pos), member), \
n = rt_list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = rt_list_entry(n->member.next, typeof(*n), member))
#define PARA_ERROR (-1)
#define PROBE_FUNC_MISS (-2)
/******************************************************************************
* Function prototype section
* add prototypes for all functions called by this file,execepting those
* declared in header file
*****************************************************************************/
//static void fh81_soc_free_all_test(void);
//static void fh81_soc_print_all_test(void);
//static void fh81_soc_auto_test_all(void);
//static void fh81_soc_test_help(void);
/*****************************************************************************
* Global variables section - Exported
* add declaration of global variables that will be exported here
* e.g.
* int8_t foo;
****************************************************************************/
/*****************************************************************************
* static fun;
*****************************************************************************/
static struct fh_board_info_list_node board_info_head;
/*****************************************************************************
* Global variables section - Local
* define global variables(will be refered only in this file) here,
* static keyword should be used to limit scope of local variable to this file
* e.g.
* static uint8_t ufoo;
*****************************************************************************/
/* function body */
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
int fh_board_info_init(void) {
memset(&board_info_head, 0x0, sizeof(struct fh_board_info_list_node));
rt_list_init(&board_info_head.list);
board_info_head.obj.name = "NO INFO";
return 0;
}
void fh_free_all_info(void) {
rt_list_t *p_list;
struct fh_board_info_list_node *info_node;
struct fh_board_info_list_node *_info_node;
p_list = &board_info_head.list;
CHECK_TEST_LIST_EMPTY;
list_for_each_entry_safe(info_node, _info_node, p_list, list)
{
if (info_node->obj.ops->exit) {
info_node->obj.ops->exit(info_node->obj.data);
}
rt_kprintf("soc free list name:(%s)\n", info_node->obj.name);
rt_free(info_node);
}
fh_board_info_init();
}
void fh_print_all_board_info(void) {
rt_list_t *p_list;
struct fh_board_info_list_node *info_node;
struct fh_board_info_list_node *_info_node;
p_list = &board_info_head.list;
CHECK_TEST_LIST_EMPTY;
list_for_each_entry_safe(info_node, _info_node, p_list, list)
{
rt_kprintf("%s\n", info_node->obj.name);
}
}
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
//register the platform info such as base add,isr no..
//caution:do not free the name and data because of here not copy
struct fh_board_info *fh_board_info_register(char *info_name, void *data) {
rt_list_t *p_list;
struct fh_board_info_list_node *new_node;
struct fh_board_info_list_node *info_node;
struct fh_board_info_list_node *_info_node;
p_list = &board_info_head.list;
if (RT_NULL == info_name || RT_NULL == data) {
rt_kprintf("info name or info data is NULL!\n");
return RT_NULL;
}
//check if the func is already in the test list....
#if(0)
list_for_each_entry_safe(info_node, _info_node, p_list, list) {
if (!memcmp(info_node->obj.name, info_name, strlen(info_name))) {
rt_kprintf("info_name(%s) is already registered\n", info_name);
return RT_NULL;
}
}
#endif
new_node = (struct fh_board_info_list_node *) rt_malloc(
sizeof(struct fh_board_info_list_node));
if (!new_node) {
rt_kprintf("malloc new_list_node failed~\n");
return RT_NULL;
}
new_node->obj.name = info_name;
new_node->obj.data = data;
//here insert "before" and test is "after" will make the list like a fifo...
rt_list_insert_before(&board_info_head.list, &new_node->list);
return &new_node->obj;
}
//back the platform info
static void *fh_get_board_info_data(char *info_name) {
rt_list_t *p_list;
struct fh_board_info_list_node *info_node;
struct fh_board_info_list_node *_info_node;
p_list = &board_info_head.list;
//check info name
if (RT_NULL == info_name) {
rt_kprintf("info name is NULL!\n");
return RT_NULL;
}
CHECK_TEST_LIST_EMPTY;
list_for_each_entry_safe(info_node, _info_node, p_list, list)
{
if (!strcmp(info_node->obj.name, info_name)) {
return info_node->obj.data;
}
}
rt_kprintf("Can't find the board info name:%s\n", info_name);
}
int fh_board_driver_register(char *info_name, struct fh_board_ops *ops) {
rt_list_t *p_list;
struct fh_board_info_list_node *new_node;
struct fh_board_info_list_node *info_node;
struct fh_board_info_list_node *_info_node;
p_list = &board_info_head.list;
if (RT_NULL == info_name || RT_NULL == ops) {
rt_kprintf("info name or ops func is NULL!\n");
return PARA_ERROR;
}
list_for_each_entry_safe(info_node, _info_node, p_list, list)
{
if (!strcmp(info_node->obj.name, info_name)) {
info_node->obj.ops = ops;
if (info_node->obj.ops->probe) {
info_node->obj.ops->probe(info_node->obj.data);
}
//return info_node->obj.data;
}
}
//rt_kprintf("Can't find the board info name:%s\n",info_name);
return 0;
}

View File

@ -1,120 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
* those macro below should define....
* or the dsp or isp lib will not be supported
*****************************************************************************/
#include <rtconfig.h>
//#pragma comment ( linker, "/EXPORT: MyExportFunction = _MyExportFunctio" )
//#pragma message
//#warning RT_NAME_MAX=32
//#error ....
//#define yu_error(macro) #error ##macro
/**************************
*
*
* define value below.
*
*
**************************/
#if RT_NAME_MAX != 16
#error "define RT_NAME_MAX 16"
#endif
#if RT_TICK_PER_SECOND != 100
#warning "RT_TICK_PER_SECOND = 100"
#endif
#if RT_ALIGN_SIZE != 4
#error "define RT_ALIGN_SIZE 4"
#endif
/**************************
*
*
* should define below..
*
*
**************************/
#ifndef RT_USING_SEMAPHORE
#error need define "RT_USING_SEMAPHORE"
#endif
#ifndef RT_USING_MUTEX
#error need define "RT_USING_MUTEX"
#endif
#ifndef RT_USING_EVENT
#error need define "RT_USING_EVENT"
#endif
#ifndef RT_USING_MAILBOX
#error need define "RT_USING_MAILBOX"
#endif
#ifndef RT_USING_MESSAGEQUEUE
#warning need define "RT_USING_MESSAGEQUEUE"
#endif
#ifndef RT_USING_MEMPOOL
#warning need define "RT_USING_MEMPOOL"
#endif
#ifndef RT_USING_HEAP
#error need define "RT_USING_HEAP"
#endif
#ifndef RT_USING_MEMHEAP
#warning need define "RT_USING_MEMHEAP"
#endif
#ifndef RT_USING_DEVICE
#error need define "RT_USING_DEVICE"
#endif
#ifndef RT_USING_CONSOLE
#error need define "RT_USING_CONSOLE"
#endif
#ifndef RT_USING_FINSH
#error need define "RT_USING_FINSH"
#endif
#ifndef RT_USING_I2C
#error need define "RT_USING_I2C"
#endif

View File

@ -1,15 +0,0 @@
# RT-Thread building script for bridge
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View File

@ -1,117 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef ARCH_H_
#define ARCH_H_
/*****************************/
/* BSP CONTROLLER BASE */
/*****************************/
#define INTC_REG_BASE (0xE0200000)
#define SDC0_REG_BASE (0xE2000000)
#define SDC1_REG_BASE (0xE2100000)
#define TVE_REG_BASE (0xE8000000)
#define VOU_REG_BASE (0xE8100000)
#define AES_REG_BASE (0xE8200000)
#define JPEG_REG_BASE (0xE8300000)
#define ISPB_REG_BASE (0xEA000000)
#define ISPF_REG_BASE (0xEA100000)
#define VPU_REG_BASE (0xEC000000)
#define VCU_REG_BASE (0xEC100000)
#define DDRC_REG_BASE (0xED000000)
#define DMAC_REG_BASE (0xEE000000)
#define GMAC_REG_BASE (0xEF000000)
#define PMU_REG_BASE (0xF0000000)
#define I2C0_REG_BASE (0xF0200000)
#define GPIO0_REG_BASE (0xF0300000)
#define GPIO1_REG_BASE (0xf4000000)
#define PWM_REG_BASE (0xF0400000)
#define SPI0_REG_BASE (0xF0500000)
#define SPI1_REG_BASE (0xF0600000)
#define UART0_REG_BASE (0xF0700000)
#define UART1_REG_BASE (0xF0800000)
#define I2S_REG_BASE (0xF0900000)
#define ACODEC_REG_BASE (0xF0A00000)
#define I2C1_REG_BASE (0xF0B00000)
#define TMR_REG_BASE (0xF0C00000)
#define WDT_REG_BASE (0xF0D00000)
#define DPHY_REG_BASE (0xF1000000)
#define MIPIC_REG_BASE (0xF1100000)
#define SADC_REG_BASE (0xF1200000)
typedef enum IRQn
{
PAE_IRQn = 0,
VPU_IRQn = 1,
ISP_F_IRQn = 2,
ISP_B_IRQn = 3,
VOU_IRQn = 4,
JPEG_IRQn = 5,
TVE_IRQn = 6,
TOE_IRQn = 7,
DDRC_IRQn = 8,
DMAC_IRQn = 9,
AES_IRQn = 10,
MIPIC_IRQn = 11,
MIPI_WRAP_IRQn = 12,
PMU_IRQn = 13,
EMAC_IRQn = 14,
AXIC0_IRQn = 16,
AXIC1_IRQn = 17,
X2H0_IRQn = 18,
X2H1_IRQn = 19,
AHBC0_IRQn = 20,
AHBC1_IRQn = 21,
SADC_IRQn = 23,
SDC0_IRQn = 24,
SDC1_IRQn = 25,
ACW_IRQn = 26,
WDT_IRQn = 27,
SPI0_IRQn = 28,
SPI1_IRQn = 29,
UART0_IRQn = 30,
UART1_IRQn = 31,
I2S0_IRQn = 32,
I2S1_IRQn = 33,
RTC_IRQn = 34,
PWM_IRQn = 35,
TMR0_IRQn = 36,
TMR1_IRQn = 37,
USB0_IRQn = 38,
USB1_IRQn = 39,
GPIO0_IRQn = 40,
GPIO1_IRQn = 41,
I2C0_IRQn = 42,
I2C1_IRQn = 43,
} IRQn_Type;
#endif /* ARCH_H_ */

View File

@ -1,9 +0,0 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
path = [cwd, cwd + '/..']
group = DefineGroup('Drivers', src, depend = ['CONFIG_BOARD_IOTCAM', 'CONFIG_CHIP_FH8620'], CPPPATH = path)
Return('group')

View File

@ -1,688 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
/*****************************************************************************
* Include Section
* add all #include here
*****************************************************************************/
#include <mmu.h>
#include "fh_def.h"
#include "arch.h"
#include "board_info.h"
#include "inc/fh_driverlib.h"
#include "iomux.h"
#include "fh_pmu.h"
#include "spi_fh_adapt.h"
#ifdef RT_USING_SADC
#include "sadc.h"
#endif
#ifdef RT_USING_SPI
#include "ssi.h"
#include "fh_dma.h"
#endif
#ifdef RT_USING_ENC28J60
#include "enc28j60.h"
#include "gpio.h"
#endif
#ifndef HW_WIFI_POWER_GPIO
#define HW_WIFI_POWER_GPIO 47 // wifi power on
#endif
#ifndef HW_WIFI_POWER_GPIO_ON_LEVEL
#define HW_WIFI_POWER_GPIO_ON_LEVEL 0
#endif
#ifndef HW_CIS_RST_GPIO
#define HW_CIS_RST_GPIO 45 // cis(sensor) reset
#endif
#ifndef HW_CIS_RST_GPIO_LEVEL
#define HW_CIS_RST_GPIO_LEVEL 1
#endif
#ifndef HW_SDCARD_POWER_GPIO
#define HW_SDCARD_POWER_GPIO 63 //not used
#endif
/****************************************************************************
* ADT section
* add definition of user defined Data Type that only be used in this file here
***************************************************************************/
struct st_platform_info {
char *name;
void *private_data;
};
/******************************************************************************
* Function prototype section
* add prototypes for all functions called by this file,execepting those
* declared in header file
*****************************************************************************/
/*****************************************************************************
* Global variables section - Exported
* add declaration of global variables that will be exported here
* e.g.
* int8_t foo;
****************************************************************************/
/*****************************************************************************
* Global variables section - Local
* define global variables(will be refered only in this file) here,
* static keyword should be used to limit scope of local variable to this file
* e.g.
* static uint8_t ufoo;
*****************************************************************************/
void fh_mmc_reset(struct fh_mmc_obj *mmc_obj)
{
rt_uint32_t value;
if (mmc_obj->id)
fh_pmu_write(REG_PMU_SWRST_AHB_CTRL, 0xfffffffd);
else
fh_pmu_write(REG_PMU_SWRST_AHB_CTRL, 0xfffffffb);
do {
fh_pmu_read(REG_PMU_SWRST_AHB_CTRL, &value);
} while (value != 0xffffffff);
}
static struct fh_mmc_obj mmc0_obj =
{
.id = 0,
.irq = SDC0_IRQn,
.base = SDC0_REG_BASE,
.power_pin_gpio = HW_SDCARD_POWER_GPIO,
.mmc_reset = fh_mmc_reset,
};
static struct fh_mmc_obj mmc1_obj =
{
.id = 1,
.irq = SDC1_IRQn,
.base = SDC1_REG_BASE,
.power_pin_gpio = HW_WIFI_POWER_GPIO,
.mmc_reset = fh_mmc_reset,
};
#ifdef RT_USING_SPI
#define SPI0_CLK_IN (50000000)
#define SPI0_MAX_BAUD (SPI0_CLK_IN/2)
static struct spi_control_platform_data spi0_platform_data =
{
.id = 0,
.irq = SPI0_IRQn,
.base = SPI0_REG_BASE,
.max_hz = SPI0_MAX_BAUD,
.slave_no = FH_SPI_SLAVE_MAX_NO,
.clk_in = SPI0_CLK_IN,
.rx_hs_no = SPI0_RX,
.tx_hs_no = SPI0_TX,
.dma_name = "fh81_dma",
.transfer_mode = SPI0_TRANSFER_MODE,
.plat_slave[0].cs_pin = SPI_CRTOLLER0_SLAVE0_CS,
.plat_slave[0].actice_level = ACTIVE_LOW,
.plat_slave[1].cs_pin = SPI_CRTOLLER0_SLAVE1_CS,
.plat_slave[1].actice_level = ACTIVE_LOW,
};
#define SPI1_CLK_IN (50000000)
#define SPI1_MAX_BAUD (SPI1_CLK_IN/2)
static struct spi_control_platform_data spi1_platform_data =
{
.id = 1,
.irq = SPI1_IRQn,
.base = SPI1_REG_BASE,
.max_hz = SPI1_MAX_BAUD,
.slave_no = FH_SPI_SLAVE_MAX_NO,
.clk_in = SPI1_CLK_IN,
.rx_hs_no = SPI1_RX,
.tx_hs_no = SPI1_TX,
.dma_name = "fh81_dma",
.transfer_mode = SPI1_TRANSFER_MODE,
.plat_slave[0].cs_pin = SPI_CRTOLLER1_SLAVE0_CS,
.plat_slave[0].actice_level = ACTIVE_LOW,
.plat_slave[1].cs_pin = SPI_CRTOLLER1_SLAVE1_CS,
.plat_slave[1].actice_level = ACTIVE_LOW,
};
#endif
static struct fh_i2c_obj i2c0_obj =
{
.id = 0,
.irq = I2C0_IRQn,
.base = I2C0_REG_BASE,
};
static struct fh_i2c_obj i2c1_obj =
{
.id = 1,
.irq = I2C1_IRQn,
.base = I2C1_REG_BASE,
};
static struct fh_gpio_obj gpio0_obj =
{
.id = 0,
.irq = GPIO0_IRQn,
};
static struct fh_gpio_obj gpio1_obj =
{
.id = 1,
.irq = GPIO1_IRQn,
};
static struct fh_pwm_obj pwm_obj =
{
.id = 0,
.base = PWM_REG_BASE,
};
static struct fh_wdt_obj wdt_obj =
{
.id = 0,
.base = WDT_REG_BASE,
.irq = WDT_IRQn,
};
#ifdef RT_USING_SADC
static struct wrap_sadc_obj sadc_obj =
{
.id = 0,
.regs = (void *)SADC_REG_BASE,
.irq_no = SADC_IRQn,
.sample_mode = ISR_MODE,
};
#endif
static struct mtd_partition fh_sf_parts[] = {
{
/* head & Ramboot */
.name = "bootstrap",
.offset = 0,
.size = 0x4000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
/* isp param */
.name = "isp-param",
.offset = 0x4000,
.size = 0x4000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
/* pae param */
.name = "pae-param",
.offset = 0x8000,
.size = 0x8000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
/* Uboot SPL */
.name = "uboot-spl",
.offset = 0x10000,
.size = 0x10000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
/* U-Boot environment */
.name = "uboot-env",
.offset = 0x20000,
.size = 0x10000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
/* U-Boot */
.name = "uboot",
.offset = 0x30000,
.size = 0x30000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "kernel",
.offset = 0x60000,
.size = 0x400000,
.mask_flags = 0,
}, {
.name = "rootfs",
.offset = 0x460000,
.size = 0x300000,
.mask_flags = 0,
}, {
.name = "app",
.offset = 0x760000,
.size = 0x8a0000,
.mask_flags = 0,
}//mtdparts=spi0.0:64k(bootstrap),64k(u-boot-env),192k(u-boot),4M(kernel),8M(rootfs),-(app)
/* two blocks with bad block table (and mirror) at the end */
};
static struct flash_platform_data fh_flash_platform_data =
{
.flash_name = "fh_flash",
.spi_name = "ssi0_0",
.parts = fh_sf_parts,
.nr_parts = ARRAY_SIZE(fh_sf_parts),
};
struct st_platform_info plat_mmc0 =
{
.name = "mmc",
.private_data = &mmc0_obj,
};
struct st_platform_info plat_mmc1 =
{
.name = "mmc",
.private_data = &mmc1_obj,
};
#ifdef RT_USING_SPI
struct st_platform_info plat_spi0 =
{
.name = "spi",
.private_data = &spi0_platform_data,
};
struct st_platform_info plat_spi1 =
{
.name = "spi",
.private_data = &spi1_platform_data,
};
#endif
struct st_platform_info plat_flash =
{
.name = "fh_flash",
.private_data = &fh_flash_platform_data,
};
struct st_platform_info plat_i2c0 =
{
.name = "i2c",
.private_data = &i2c0_obj,
};
struct st_platform_info plat_i2c1 =
{
.name = "i2c",
.private_data = &i2c1_obj,
};
struct st_platform_info plat_gpio0 =
{
.name = "gpio",
.private_data = &gpio0_obj,
};
struct st_platform_info plat_gpio1 =
{
.name = "gpio",
.private_data = &gpio1_obj,
};
struct st_platform_info plat_pwm =
{
.name = "pwm",
.private_data = &pwm_obj,
};
struct st_platform_info plat_wdt =
{
.name = "wdt",
.private_data = &wdt_obj,
};
#ifdef RT_USING_SADC
struct st_platform_info plat_sadc =
{
.name = "sadc",
.private_data = &sadc_obj,
};
#endif
const static struct st_platform_info *platform_info[] = {
&plat_mmc0,
//&plat_mmc1,//by PeterJiang, wifi don't use SDIO framework...
#ifdef RT_USING_SPI
&plat_spi0,
#endif
#ifdef RT_USING_SPI1
&plat_spi1,
#endif
&plat_flash,
&plat_i2c0,
&plat_i2c1,
&plat_gpio0,
&plat_gpio1,
&plat_pwm,
&plat_wdt,
#ifdef RT_USING_SADC
&plat_sadc,
#endif
};
/* function body */
/*****************************************************************************
* Description:
* add funtion description here
* Parameters:
* description for each argument, new argument starts at new line
* Return:
* what does this function returned?
*****************************************************************************/
void clock_init(void)
{
//UINT32 reg;
//gate enable, spi0, gmac, uart0, timer0, wdt, pts
#ifdef YG_TEK
fh_pmu_write_mask(REG_PMU_PAD_MAC_TXER_CFG, 0x100000, 0x100000);
#endif
//SPI0
fh_pmu_write_mask(REG_PMU_CLK_DIV3, 0xb, 0xff);
//GMAC
fh_pmu_write_mask(REG_PMU_CLK_DIV6, 0x5000000, 0xf000000);
//UART0
fh_pmu_write_mask(REG_PMU_CLK_DIV4, 0x1, 0xf);
//TIMER0
fh_pmu_write_mask(REG_PMU_CLK_DIV5, 0x1d0000, 0x3f0000);
//PTS
fh_pmu_write_mask(REG_PMU_CLK_DIV2, 0x23, 0x3f);
//WDT
//fh_pmu_write_mask(REG_PMU_CLK_DIV5, 0x1d00, 0x3f00);
fh_pmu_write_mask(REG_PMU_CLK_DIV5, 0x3500, 0x3f00);
//clock enable
fh_pmu_write_mask(REG_PMU_CLK_GATE, 0, 0x720ba080);
//sd0_drv_sel
fh_pmu_write_mask(REG_PMU_CLK_SEL, 0x200000, 0x300000);
//sd0_sample_sel
fh_pmu_write_mask(REG_PMU_CLK_SEL, 0x00000, 0x30000);
//sd1_drv_sel
fh_pmu_write_mask(REG_PMU_CLK_SEL, 0x2000, 0x3000);
//sd1_sample_sel
fh_pmu_write_mask(REG_PMU_CLK_SEL, 0x000, 0x300);
}
void fh_platform_info_register(void){
struct fh_board_info *test_info;
int i;
for(i=0;i<sizeof(platform_info)/sizeof(struct st_platform_info *);i++){
test_info = fh_board_info_register(platform_info[i]->name,platform_info[i]->private_data);
if(!test_info){
rt_kprintf("info_name(%s) failed registered\n", platform_info[i]->name);
}
}
}
void rt_hw_board_init()
{
/* initialize the system clock */
rt_hw_clock_init();
//add iomux init 2015-3-11 by yu.zhang for fh81(fullhan)
//iomux_init();
fh_iomux_init(PMU_REG_BASE + 0x5c);
//add clk init 2015-3-11 by yu.zhang for fh81(fullhan)
clock_init();
/* initialize uart */
rt_hw_uart_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
/* initialize timer1 */
rt_hw_timer_init();
//board data info init...
fh_board_info_init();
fh_platform_info_register();
}
void rt_board_driver_init(){
//add board init lock here...
/*rt_show_version();*/
int ret;
/* Filesystem Initialization */
#ifdef RT_USING_DFS
{
/* init the device filesystem */
dfs_init();
rt_kprintf("DFS initialized!\n");
#if defined(RT_USING_DFS_ELMFAT)
/* init the elm chan FatFs filesystam*/
elm_init();
rt_kprintf("ELM initialized!\n");
#endif
#if defined(RT_USING_DFS_ROMFS)
dfs_romfs_init();
if (dfs_mount(RT_NULL, "/rom", "rom", 0, &romfs_root) == 0)
{
rt_kprintf("ROM File System initialized!\n");
}
else
rt_kprintf("ROM File System initialzation failed!\n");
#endif
#if defined(RT_USING_DFS_DEVFS)
devfs_init();
if (dfs_mount(RT_NULL, "/dev", "devfs", 0, 0) == 0)
rt_kprintf("Device File System initialized!\n");
else
rt_kprintf("Device File System initialzation failed!\n");
#ifdef RT_USING_NEWLIB
/* init libc */
libc_system_init(RT_CONSOLE_DEVICE_NAME);
#endif
#endif
#if defined(RT_USING_DFS_UFFS)
{
/* init the uffs filesystem */
dfs_uffs_init();
/* mount flash device as flash directory */
if(dfs_mount("nand0", "/nand0", "uffs", 0, 0) == 0)
rt_kprintf("UFFS File System initialized!\n");
else
rt_kprintf("UFFS File System initialzation failed!\n");
}
#endif
#ifdef RT_USING_DFS_RAMFS
dfs_ramfs_init();
{
rt_uint8_t *ramfs_pool = RT_NULL;
struct dfs_ramfs* ramfs;
ramfs_pool = rt_malloc(0x800000);
if(ramfs_pool)
{
ramfs =(struct dfs_ramfs*) dfs_ramfs_create((rt_uint8_t*)ramfs_pool, 0x800000);
if (ramfs != RT_NULL)
{
if (dfs_mount(RT_NULL, "/", "ram", 0, ramfs) == 0)
{
rt_kprintf("Mount RAMDisk done!\n");
}
else
{
rt_kprintf("Mount RAMDisk failed.\n");
}
}
}
else
{
rt_kprintf("alloc ramfs poll failed\n");
}
}
#endif
}
#endif
/* Filesystem Initialization end*/
#ifdef RT_USING_GPIO
{
rt_hw_gpio_init();
rt_kprintf("GPIO initialized!\n");
#ifdef RT_USING_SDIO
//wifi
gpio_request(HW_WIFI_POWER_GPIO);
gpio_direction_output(HW_WIFI_POWER_GPIO, !HW_WIFI_POWER_GPIO_ON_LEVEL);
udelay(1000);
gpio_direction_output(HW_WIFI_POWER_GPIO, HW_WIFI_POWER_GPIO_ON_LEVEL);
//micro sd
gpio_request(HW_SDCARD_POWER_GPIO);
gpio_direction_output(HW_SDCARD_POWER_GPIO, 0);
rt_kprintf("SDIO initialized!\n");
#endif
//sensor
gpio_request(HW_CIS_RST_GPIO);
gpio_direction_output(HW_CIS_RST_GPIO, HW_CIS_RST_GPIO_LEVEL);
}
#endif
#ifdef RT_USING_SDIO
#ifndef RT_USING_WIFI_MARVEL
rt_hw_mmc_init();
rt_kprintf("MMC initialized!\n");
rt_thread_delay(RT_TICK_PER_SECOND*2);
/* mount sd card fat partition 1 as root directory */
#ifdef RT_USING_DFS_ELMFAT
if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
{
rt_kprintf("File System initialized!\n");
}
else
rt_kprintf("File System initialization failed!\n");
#endif
#endif
#endif
#ifdef RT_USING_FH_DMA
{
rt_fh_dma_init();
rt_kprintf("DMA initialized!\n");
}
#endif
#ifdef RT_USING_FH_ACW
{
fh_audio_init();
rt_kprintf("AUDIO initialized!\n");
}
#endif
#ifdef RT_USING_LWIP
{
/* init lwip system */
lwip_sys_init();
rt_kprintf("LWIP SYS initialized!\n");
eth_system_device_init();
rt_kprintf("ETH initialized!\n");
}
#endif
#ifdef RT_USING_GMAC
/* register ethernetif device */
rt_app_fh_gmac_init();
rt_kprintf("GMAC initialized!\n");
#endif
#ifdef RT_USING_I2C
{
rt_hw_i2c_init();
rt_kprintf("I2C initialized!\n");
}
#endif
#ifdef RT_USING_PWM
{
rt_hw_pwm_init();
rt_kprintf("PWM initialized!\n");
}
#endif
#ifdef RT_USING_WDT
{
rt_hw_wdt_init();
rt_kprintf("WDT initialized!\n");
}
#endif
#ifdef RT_USING_SPI
{
rt_hw_spi_init();
rt_kprintf("SPI initialized!\n");
}
#endif
#ifdef RT_USING_FH_FLASH_ADAPT
fh_flash_adapt_init();
rt_kprintf("FLASH initialized!\n");
#endif
rt_kprintf("init done\n");
#ifdef RT_USING_SADC
rt_hw_sadc_init();
rt_kprintf("SADC initialized!\n");
#endif
#ifdef RT_USING_ENC28J60
gpio_request(ENC28J60_INT);
gpio_direction_input(ENC28J60_INT);
gpio_set_irq_type(ENC28J60_INT, IRQ_TYPE_EDGE_FALLING);
rt_hw_interrupt_install(gpio_to_irq(ENC28J60_INT), (void *)enc28j60_isr, RT_NULL, RT_NULL);
gpio_irq_enable(gpio_to_irq(ENC28J60_INT));
gpio_release(ENC28J60_INT);
enc28j60_attach(ENC28J60_SPI_DEV);
#endif
}

View File

@ -1,106 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef BOARD_DEF_H_
#define BOARD_DEF_H_
/* ***********************
* SECTION: DRIVE
* ***********************/
// Basic drive..
#define RT_USING_UART1
#define RT_USING_GPIO
#define RT_USING_SDIO
#define RT_USING_FH_DMA
#define RT_USING_FH_ACW
#define RT_USING_I2C
#define RT_USING_PWM
#define RT_USING_WDT
#define RT_USING_SPI
#define RT_USING_SADC
#define RT_USING_DSP
#define RT_USING_ISP
#define CONFIG_PLAT_V2
#ifndef FH_DDR_START
#define FH_DDR_START 0xA0000000
#define FH_DDR_END 0xA1000000
#define FH_RTT_OS_MEM_SIZE 0x00600000
#define FH_DMA_MEM_SIZE 0x20000 /* 128k */
#define FH_RTT_OS_MEM_END (FH_DDR_START + FH_RTT_OS_MEM_SIZE)
#define FH_SDK_MEM_START (FH_RTT_OS_MEM_END + FH_DMA_MEM_SIZE)
#define FH_RTT_OS_HEAP_END FH_SDK_MEM_START
#define FH_SDK_MEM_SIZE (FH_DDR_END - FH_SDK_MEM_START)
#endif /* end of FH_DDR_START*/
/* ***********************
* SECTION: DRIVE COMPONENT
* ***********************/
#define UART_NAME "uart1"
#define RT_USING_DMA_MEM
#define RT_USING_MCI0
#define RT_USING_GD
#define RT_USING_FLASH_DEFAULT
#define RT_USING_FH_FLASH_ADAPT
#ifndef _FH_AUTO_CONFIG_
#define CHANNUM 2
#define CHN0_Height 720
#define CHN0_WIDTH 1280
#define CHN0_Framerate 0x00010019
#define CHN0_Bitrate (2048 *4)
#define CHN1_Framerate 0x00010019
#define CHN1_WIDTH 352
#define CHN1_Height 288
#define CHN1_Bitrate 512
#define VPU_FRAME_CTRL 1
#define CONFIG_IRCUT_OFF 1
#define CONFIG_ISP_25FPS 1
#define NOT_RECORD 1
#define ENABLE_JPEG 1
#define CONFIG_ISP_720P 1
#define ENABLE_COOLVIEW 1
#define ENABLE_OSD 1
#define USE_RC 1
#define OSD_CHN_FONT_USING 1
#endif
#endif /* BOARD_H_ */

View File

@ -1,668 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "rtdef.h"
#include "iomux.h"
#include "rtconfig.h"
Iomux_Pad fh_iomux_cfg[] = {
{
.func_name = { "RESETN", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = -1,
},
{
.func_name = { "TEST", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = -1,
},
{
.func_name = { "CIS_CLK", "", "", "", },
.reg_type = 5,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "CIS_HSYNC", "GPIO20", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_VSYNC", "GPIO21", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_PCLK", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 0,
},
{
.func_name = { "CIS_D0", "GPIO22", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D1", "GPIO23", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D2", "GPIO24", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D3", "GPIO25", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D4", "GPIO26", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D5", "GPIO27", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D6", "GPIO28", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D7", "GPIO29", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D8", "GPIO30", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D9", "GPIO31", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D10", "GPIO32", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_D11", "GPIO33", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_REF_CLK", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 3,
},
{
.func_name = { "MAC_MDC", "GPIO34", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 0,
},
{
.func_name = { "MAC_MDIO", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_COL", "GPIO35", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_CRS", "GPIO36", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_RXCK", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = -1,
},
{
.func_name = { "MAC_RXD0", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = -1,
},
{
.func_name = { "MAC_RXD1", "GPIO38", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_RXD2", "GPIO39", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_RXD3", "GPIO40", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_RXDV", "GPIO41", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_TXCK", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = -1,
},
{
.func_name = { "MAC_TXD0", "GPIO42", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_TXD1", "GPIO43", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_TXD2", "GPIO44", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_TXD3", "GPIO45", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_TXEN", "GPIO46", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "MAC_RXER", "GPIO47", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "GPIO0", "ARC_JTAG_TCK", "GPIO0", "CIS_SSI0_CSN1", },
.reg_type = 21,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "GPIO1", "ARC_JTAG_TRSTN", "GPIO1", "CIS_SSI0_RXD", },
.reg_type = 21,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "GPIO2", "ARC_JTAG_TMS", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "GPIO3", "ARC_JTAG_TDI", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "GPIO4", "ARC_JTAG_TDO", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "JTAG_TCK", "GPIO5", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "JTAG_TRSTN", "GPIO6", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "JTAG_TMS", "GPIO7", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "JTAG_TDI", "GPIO8", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "JTAG_TDO", "GPIO9", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "GPIO10", "UART1_OUT", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 1,
},
{
.func_name = { "GPIO11", "UART1_IN", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 1,
},
{
.func_name = { "GPIO12", "PWM_OUT0", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "GPIO13", "PWM_OUT1", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "GPIO14", "PWM_OUT2", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "UART0_IN", "GPIO48", "UART0_IN", " I2S_WS", },
.reg_type = 21,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 1,
},
{
.func_name = { "UART0_OUT", "GPIO49", "UART0_OUT", "I2S_CLK", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "CIS_SCL", "GPIO56", "CIS_SCL", "CIS_SSI0_CLK", },
.reg_type = 13,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "CIS_SDA", "GPIO57", "CIS_SDA", "CIS_SSI0_TXD", },
.reg_type = 13,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "SCL1", "GPIO50", "SCL1", "I2S_DI", },
.reg_type = 21,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "SDA1", "GPIO51", "I2S_DO", "", },
.reg_type = 21,
.func_sel = 1,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "SSI0_CLK", "", "", "", },
.reg_type = 5,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "SSI0_TXD", "", "", "", },
.reg_type = 5,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "SSI0_CSN0", "GPIO54", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "SSI0_CSN1", "GPIO55", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "SSI0_RXD", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = -1,
},
{
.func_name = { "SD0_CD", "GPIO52", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "SD0_WP", "GPIO53", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "SD0_CLK", "", "", "", },
.reg_type = 5,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 3,
},
{
.func_name = { "SD0_CMD_RSP", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD0_DATA0", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD0_DATA1", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 2,
},
{
.func_name = { "SD0_DATA2", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD0_DATA3", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD1_CLK", "SSI1_CLK", "", "", },
.reg_type = 8,
.func_sel = 0,
.pupd = IOMUX_PUPD_NONE,
.drv_cur = 1,
},
{
.func_name = { "SD1_CD", "GPIO_58", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "SD1_WP", "GPIO_59", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
{
.func_name = { "SD1_DATA0", "SSI1_TXD", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD1_DATA1", "SSI1_CSN0", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD1_DATA2", "SSI1_CSN1", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD1_DATA3", "", "", "", },
.reg_type = 17,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "SD1_CMD_RSP", "SSI1_RXD", "", "", },
.reg_type = 20,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = 3,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "CLK_SW0", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = -1,
},
{
.func_name = { "CLK_SW1", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = -1,
},
{
.func_name = { "CLK_SW2", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = -1,
},
{
.func_name = { "CLK_SW3", "", "", "", },
.reg_type = 9,
.func_sel = 0,
.pupd = IOMUX_PUPD_UP,
.drv_cur = -1,
},
{
.func_name = { "RESERVED", "", "", "", },
.reg_type = 20,
.func_sel = 0,
},
{
.func_name = { "MAC_TXER", "GPIO37", "", "", },
.reg_type = 20,
.func_sel = 1,
.pupd = IOMUX_PUPD_DOWN,
.drv_cur = 1,
},
};
const int fh_iomux_cfg_count = ARRAY_SIZE(fh_iomux_cfg);

View File

@ -1,4 +0,0 @@
IoT Camera
powered by RT-Thread
V1.0
2016-3-14

View File

@ -1,117 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtthread.h>
#include <mmu.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#ifdef RT_USING_DMA_MEM
#include "dma_mem.h"
#endif
#include "board_def.h"
extern void rt_hw_interrupt_init(void);
extern void rt_hw_board_init(void);
extern void rt_system_timer_init(void);
extern void rt_system_scheduler_init(void);
extern void rt_thread_idle_init(void);
extern void mmu_invalidate_icache();
extern void rt_hw_cpu_icache_enable(void);
extern void rt_show_version(void);
extern void rt_system_heap_init(void*, void*);
extern void rt_hw_finsh_init(void);
extern void rt_application_init(void);
static struct mem_desc fh_mem_desc[] =
{
{ 0xA0000000, FH_RTT_OS_MEM_END-1, 0xA0000000, SECT_RWX_CB, 0, SECT_MAPPED },
{ FH_RTT_OS_MEM_END, FH_DDR_END-1, FH_RTT_OS_MEM_END, SECT_RWNX_NCNB, 0, SECT_MAPPED },
{ 0xFFFF0000, 0xFFFF1000-1, 0xA0000000, SECT_TO_PAGE, PAGE_ROX_CB, PAGE_MAPPED }, /* isr vector table */
{ 0xE0000000, 0xF1300000-1, 0xE0000000, SECT_RWNX_NCNB, 0, SECT_MAPPED }, /* io table */
{ 0xF4000000, 0xF4100000-1, 0xF4000000, SECT_RWNX_NCNB, 0, SECT_MAPPED }, /* GPIO#1 io table */
};
rt_uint8_t _irq_stack_start[1024];
rt_uint8_t _fiq_stack_start[1024];
rt_uint8_t _undefined_stack_start[512];
rt_uint8_t _abort_stack_start[512];
rt_uint8_t _svc_stack_start[4096] RT_SECTION(".nobss");
extern unsigned char __bss_start;
extern unsigned char __bss_end;
/**
* This function will startup RT-Thread RTOS.
*/
void rtthread_startup(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
/* initialize hardware interrupt */
rt_hw_interrupt_init();
/* initialize mmu */
rt_hw_mmu_init(fh_mem_desc, sizeof(fh_mem_desc)/sizeof(fh_mem_desc[0]));
rt_system_heap_init((void*)&__bss_end, (void*)FH_RTT_OS_MEM_END);
#ifdef RT_USING_DMA_MEM
//just use the last 100KB
fh_dma_mem_init((rt_uint32_t *)FH_RTT_OS_MEM_END, FH_DMA_MEM_SIZE);
#endif
/* initialize board */
rt_hw_board_init();
/* show version */
rt_show_version();
/* initialize timer system */
rt_system_timer_init();
/* initialize scheduler system */
rt_system_scheduler_init();
/* initialize application */
rt_application_init();
/* initialize system timer thread */
rt_system_timer_thread_init();
/* initialize idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
}

View File

@ -1,44 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_ARCH_H_
#define FH_ARCH_H_
#ifdef CONFIG_CHIP_FH8620
#include "plat-v2/arch.h"
#endif
#ifdef CONFIG_CHIP_FH8620G
#include "plat-v2/arch.h"
#endif
#ifdef CONFIG_CHIP_FH8810
#include "plat-v2/arch.h"
#endif
#endif /* FH_ARCH_H_ */

View File

@ -1,90 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_DEF_H_
#define FH_DEF_H_
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
typedef char SINT8;
typedef short SINT16;
typedef int SINT32;
typedef long long SINT64;
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
#ifndef TYPE_DEFINED
typedef unsigned char uchar;
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef signed long long int64;
typedef unsigned long long uint64;
typedef float ieee_single;
typedef double ieee_double;
typedef unsigned long boolean;
#define TYPE_DEFINED
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define reg_read(addr) (*((volatile UINT32 *)(addr)))
#define reg_write(addr,value) (*(volatile UINT32 *)(addr)=(value))
#define GET_REG(addr) reg_read(addr)
#define SET_REG(addr,value) reg_write(addr,value)
#define SET_REG_M(addr,value,mask) reg_write(addr,(reg_read(addr)&(~(mask)))|((value)&(mask)))
#define SET_REG_B(addr,element,highbit,lowbit) SET_REG_M((addr),((element)<<(lowbit)),(((1<<((highbit)-(lowbit)+1))-1)<<(lowbit)))
#define GET_REG8(addr) (*((volatile UINT8 *)(addr)))
#define SET_REG8(addr,value) (*(volatile UINT8 *)(addr)=(value))
#define read_reg(addr) (*((volatile uint32 *)(addr)))
#define write_reg(addr, reg) (*((volatile uint32 *)(addr))) = (uint32)(reg)
#define inw(addr) (*((volatile uint32 *)(addr)))
#define outw(addr, reg) (*((volatile uint32 *)(addr))) = (uint32)(reg)
#ifndef BIT
#define BIT(nr) (1UL << (nr))
#endif
typedef volatile const unsigned int RoReg; /**< Read only 32-bit register (volatile const unsigned int) */
typedef volatile unsigned int WoReg; /**< Write only 32-bit register (volatile unsigned int) */
typedef volatile unsigned int RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */
#endif /* FH_DEF_H_ */

View File

@ -1,13 +0,0 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
path = [cwd, cwd + '/..']
group = DefineGroup('Drivers', src, depend = ['CONFIG_PLAT_V2'], CPPPATH = path)
Return('group')

View File

@ -1,116 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef ARCH_H_
#define ARCH_H_
/*****************************/
/* BSP CONTROLLER BASE */
/*****************************/
#define INTC_REG_BASE (0xE0200000)
#define SDC0_REG_BASE (0xE2000000)
#define SDC1_REG_BASE (0xE2100000)
#define TVE_REG_BASE (0xE8000000)
#define VOU_REG_BASE (0xE8100000)
#define AES_REG_BASE (0xE8200000)
/*
#define JPEG_REG_BASE (0xE8300000)
#define ISPB_REG_BASE (0xEA000000)
#define ISPF_REG_BASE (0xEA100000)
#define VPU_REG_BASE (0xEC000000)
#define VCU_REG_BASE (0xEC100000)
#define DDRC_REG_BASE (0xED000000)
*/
#define DMAC_REG_BASE (0xEE000000)
#define GMAC_REG_BASE (0xEF000000)
#define PMU_REG_BASE (0xF0000000)
#define I2C0_REG_BASE (0xF0200000)
#define GPIO0_REG_BASE (0xF0300000)
#define GPIO1_REG_BASE (0xf4000000)
#define PWM_REG_BASE (0xF0400000)
#define SPI0_REG_BASE (0xF0500000)
#define SPI1_REG_BASE (0xF0600000)
#define UART0_REG_BASE (0xF0700000)
#define UART1_REG_BASE (0xF0800000)
/*#define I2S_REG_BASE (0xF0900000)*/
#define ACODEC_REG_BASE (0xF0A00000)
#define I2C1_REG_BASE (0xF0B00000)
#define TMR_REG_BASE (0xF0C00000)
#define WDT_REG_BASE (0xF0D00000)
/*
#define DPHY_REG_BASE (0xF1000000)
#define MIPIC_REG_BASE (0xF1100000)
*/
#define SADC_REG_BASE (0xF1200000)
typedef enum IRQn
{
PAE_IRQn = 0,
VPU_IRQn = 1,
ISP_F_IRQn = 2,
ISP_B_IRQn = 3,
VOU_IRQn = 4,
JPEG_IRQn = 5,
TVE_IRQn = 6,
TOE_IRQn = 7,
DDRC_IRQn = 8,
DMAC_IRQn = 9,
AES_IRQn = 10,
MIPIC_IRQn = 11,
MIPI_WRAP_IRQn = 12,
PMU_IRQn = 13,
EMAC_IRQn = 14,
AXIC0_IRQn = 16,
AXIC1_IRQn = 17,
X2H0_IRQn = 18,
X2H1_IRQn = 19,
AHBC0_IRQn = 20,
AHBC1_IRQn = 21,
SADC_IRQn = 23,
SDC0_IRQn = 24,
SDC1_IRQn = 25,
ACW_IRQn = 26,
WDT_IRQn = 27,
SPI0_IRQn = 28,
SPI1_IRQn = 29,
UART0_IRQn = 30,
UART1_IRQn = 31,
I2S0_IRQn = 32,
I2S1_IRQn = 33,
RTC_IRQn = 34,
PWM_IRQn = 35,
TMR0_IRQn = 36,
TMR1_IRQn = 37,
USB0_IRQn = 38,
USB1_IRQn = 39,
GPIO0_IRQn = 40,
GPIO1_IRQn = 41,
I2C0_IRQn = 42,
I2C1_IRQn = 43,
} IRQn_Type;
#endif /* ARCH_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef TIMER_H_
#define TIMER_H_
#include <rtdef.h>
void rt_hw_clock_init(void);
void rt_hw_get_clock(void);
void rt_hw_set_dividor(rt_uint8_t hdivn, rt_uint8_t pdivn);
void rt_hw_set_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv);
struct fh_clk;
/*
void fh_pmu_open(void);
void fh_pmu_close(void);
*/
#define DIFF_SDC_REFCLK_0 (0)
#define DIFF_SDC_REFCLK_90 (1)
#define DIFF_SDC_REFCLK_180 (2)
#define DIFF_SDC_REFCLK_270 (3)
#define SDC_CLK_PARA_ERROR (0xffff0000)
#define SDC_CLK_PARA_OK (0)
void clk_gate(struct fh_clk *p_clk);
void clk_ungate(struct fh_clk *p_clk);
struct fh_clk *clk_get(const char *name);
rt_uint32_t clk_get_rate(struct fh_clk *p_clk);
void clk_set_rate(struct fh_clk *p_clk,rt_uint32_t rate_value);
rt_uint32_t sdc_get_phase(struct fh_clk *p_clk);
rt_uint32_t sdc_set_phase(struct fh_clk *p_clk,rt_uint32_t phase);
#endif

View File

@ -1,62 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "rtdebug.h"
#include "arch.h"
#include "fh_pmu.h"
#include "fh_def.h"
#define FH_PMU_WRITEL(offset,value) SET_REG((PMU_REG_BASE + offset),value)
#define FH_PMU_WRITEL_MASK(offset,value, mask) SET_REG_M((PMU_REG_BASE + offset), value, mask)
#define FH_PMU_READL(offset) GET_REG((PMU_REG_BASE + offset))
#define PMU_OFFSET_MAX 0x1d0
int fh_pmu_read(rt_uint32_t offset, rt_uint32_t *value)
{
RT_ASSERT(offset < PMU_OFFSET_MAX);
*value = FH_PMU_READL(offset);
return 0;
}
int fh_pmu_write(rt_uint32_t offset, const rt_uint32_t value)
{
RT_ASSERT(offset < PMU_OFFSET_MAX);
FH_PMU_WRITEL(offset, value);
return 0;
}
int fh_pmu_write_mask(rt_uint32_t offset, const rt_uint32_t value,
const rt_uint32_t mask)
{
RT_ASSERT(offset < PMU_OFFSET_MAX);
FH_PMU_WRITEL_MASK(offset, value, mask);
return 0;
}

View File

@ -1,59 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef FH_PMU_H_
#define FH_PMU_H_
#include <rtdef.h>
#define REG_PMU_CHIP_ID (0x000)
#define REG_PMU_IP_VER (0x004)
#define REG_PMU_FW_VER (0x008)
#define REG_PMU_SYS_CTRL (0x00c)
#define REG_PMU_PLL0_CTRL (0x010)
#define REG_PMU_PLL1_CTRL (0x014)
#define REG_PMU_ARC_CLK_GATE (0x018)
#define REG_PMU_CLK_GATE (0x01c)
#define REG_PMU_CLK_SEL (0x020)
#define REG_PMU_CLK_DIV0 (0x024)
#define REG_PMU_CLK_DIV1 (0x028)
#define REG_PMU_CLK_DIV2 (0x02c)
#define REG_PMU_CLK_DIV3 (0x030)
#define REG_PMU_CLK_DIV4 (0x034)
#define REG_PMU_CLK_DIV5 (0x038)
#define REG_PMU_CLK_DIV6 (0x03c)
#define REG_PMU_SWRST_MAIN_CTRL (0x040)
#define REG_PMU_SWRST_AXI_CTRL (0x044)
#define REG_PMU_SWRST_AHB_CTRL (0x048)
#define REG_PMU_SWRST_APB_CTRL (0x04c)
#define REG_PMU_VDAC_CTRL (0x050)
#define REG_PMU_MAC_REF_CLK_CFG (0x0a4)
int fh_pmu_read(rt_uint32_t offset,rt_uint32_t *value);
int fh_pmu_write(rt_uint32_t offset, const rt_uint32_t value);
int fh_pmu_write_mask(rt_uint32_t offset,const rt_uint32_t value, const rt_uint32_t mask);
#endif /* FH_PMU_H_ */

View File

@ -1,284 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "rtdebug.h"
#include "iomux.h"
static void fh_iomux_setmfs(Iomux_Pad *pad)
{
switch (pad->reg_type) {
case 8:
(IOMUX_PADTYPE(8)pad->reg)->bit.mfs = pad->func_sel;
break;
case 13:
(IOMUX_PADTYPE(13)pad->reg)->bit.mfs = pad->func_sel;
break;
case 20:
(IOMUX_PADTYPE(20)pad->reg)->bit.mfs = pad->func_sel;
break;
case 21:
(IOMUX_PADTYPE(21)pad->reg)->bit.mfs = pad->func_sel;
break;
default:
break;
}
}
#ifdef IOMUX_DEBUG
static int fh_iomux_getmfs(Iomux_Pad *pad)
{
int mfs;
switch (pad->reg_type) {
case 8:
mfs = (IOMUX_PADTYPE(8)pad->reg)->bit.mfs;
break;
case 13:
mfs = (IOMUX_PADTYPE(13)pad->reg)->bit.mfs;
break;
case 20:
mfs = (IOMUX_PADTYPE(20)pad->reg)->bit.mfs;
break;
case 21:
mfs = (IOMUX_PADTYPE(21)pad->reg)->bit.mfs;
break;
default:
mfs = -1;
break;
}
return mfs;
}
static void fh_iomux_print()
{
int i;
UINT32 reg;
for (i = 0; i < ARRAY_SIZE(fh81_iomux_cfg); i++) {
int curr_func;
curr_func = fh81_iomux_getmfs(iomux_obj, &iomux_obj.pads[i]);
reg = readl((UINT32)iomux_obj.pads[i].reg);
if (curr_func < 0)
rt_kprintf("\t%d\t\t%-8s(no mfs)\t0x%08x\n", i, iomux_obj.pads[i].func_name[0],
reg);
else
rt_kprintf("\t%d\t\t%-16s\t0x%08x\n", i, iomux_obj.pads[i].func_name[curr_func],
reg);
}
}
#endif
static void fh_iomux_setcur(Iomux_Pad *pad)
{
switch (pad->reg_type) {
case 5:
(IOMUX_PADTYPE(5)pad->reg)->bit.e8_e4 = pad->drv_cur;
break;
case 8:
(IOMUX_PADTYPE(8)pad->reg)->bit.e8_e4 = pad->drv_cur;
break;
case 13:
(IOMUX_PADTYPE(13)pad->reg)->bit.e4_e2 = pad->drv_cur;
break;
case 17:
(IOMUX_PADTYPE(17)pad->reg)->bit.e8_e4 = pad->drv_cur;
break;
case 20:
(IOMUX_PADTYPE(20)pad->reg)->bit.e4_e2 = pad->drv_cur;
break;
case 21:
(IOMUX_PADTYPE(21)pad->reg)->bit.e4_e2 = pad->drv_cur;
break;
default:
break;
}
}
static void fh_iomux_setpupd(Iomux_Pad *pad)
{
switch (pad->reg_type) {
case 9:
(IOMUX_PADTYPE(9)pad->reg)->bit.pu_pd = pad->pupd;
break;
case 17:
(IOMUX_PADTYPE(17)pad->reg)->bit.pu_pd = pad->pupd;
break;
case 20:
(IOMUX_PADTYPE(20)pad->reg)->bit.pu_pd = pad->pupd;
break;
case 21:
(IOMUX_PADTYPE(21)pad->reg)->bit.pu_pd = pad->pupd;
break;
default:
break;
}
}
static void fh_iomux_setrest(Iomux_Pad *pad)
{
switch (pad->reg_type) {
case 5:
(IOMUX_PADTYPE(5)pad->reg)->bit.sr = 0;
break;
case 8:
(IOMUX_PADTYPE(8)pad->reg)->bit.sr = 0;
break;
case 9:
(IOMUX_PADTYPE(9)pad->reg)->bit.ie = 1;
(IOMUX_PADTYPE(9)pad->reg)->bit.smt = 1;
break;
case 13:
(IOMUX_PADTYPE(13)pad->reg)->bit.ie = 1;
(IOMUX_PADTYPE(13)pad->reg)->bit.smt = 1;
break;
case 17:
(IOMUX_PADTYPE(17)pad->reg)->bit.sr = 0;
(IOMUX_PADTYPE(17)pad->reg)->bit.ie = 1;
(IOMUX_PADTYPE(17)pad->reg)->bit.e = 1;
(IOMUX_PADTYPE(17)pad->reg)->bit.smt = 1;
break;
case 20:
(IOMUX_PADTYPE(20)pad->reg)->bit.sr = 0;
(IOMUX_PADTYPE(20)pad->reg)->bit.ie = 1;
(IOMUX_PADTYPE(20)pad->reg)->bit.smt = 1;
break;
case 21:
(IOMUX_PADTYPE(21)pad->reg)->bit.sr = 0;
(IOMUX_PADTYPE(21)pad->reg)->bit.ie = 1;
(IOMUX_PADTYPE(21)pad->reg)->bit.smt = 1;
break;
default:
break;
}
}
static Iomux_Object iomux_obj;
extern Iomux_Pad fh_iomux_cfg[];
extern const int fh_iomux_cfg_count;
void __fh_setiomux(Iomux_Pad *pad, void *iobase)
{
UINT32 regvalue = 0;
pad->reg = &regvalue;
fh_iomux_setmfs(pad);
fh_iomux_setcur(pad);
fh_iomux_setpupd(pad);
fh_iomux_setrest(pad);
SET_REG(iobase, regvalue);
}
static UINT32 g_iomux_base;
void fh_iomux_init(UINT32 base)
{
// return;
int i;
// int test_cnt = 0;
UINT32 reg;
g_iomux_base = base;
iomux_obj.pbase = (void *)base;
// iomux_obj.vbase = (UINT32 *)rt_malloc(1024);
iomux_obj.pads = fh_iomux_cfg;
for (i = 0; i < fh_iomux_cfg_count; i++) {
#if (1)
iomux_obj.pads[i].id = i;
iomux_obj.pads[i].reg_offset = i * 4;
iomux_obj.pads[i].reg = &reg;//(UINT32 *)(iomux_obj.vbase + iomux_obj.pads[i].reg_offset);
fh_iomux_setmfs(&fh_iomux_cfg[i]);
fh_iomux_setcur(&fh_iomux_cfg[i]);
fh_iomux_setpupd(&fh_iomux_cfg[i]);
fh_iomux_setrest(&fh_iomux_cfg[i]);
SET_REG(iomux_obj.pbase + iomux_obj.pads[i].reg_offset, reg);
// *((UINT32 *)(iomux_obj.vbase + iomux_obj.pads[i].reg_offset)));
//rt_kprintf("addr: 0x%x, pmu data: 0x%x\n", iomux_obj.pbase + iomux_obj.pads[i].reg_offset, GET_REG(iomux_obj.pbase + iomux_obj.pads[i].reg_offset));
// test_cnt++;
#else
#ifdef FH_USING_JTAG
if (strncmp(fh_iomux_cfg[i].func_name[0], "JTAG", 4) == 0)
continue;
#endif
/*
if (strncmp(fh_iomux_cfg[i].func_name[1], "UART1", 5) == 0)
break;
*/
__fh_setiomux(&fh_iomux_cfg[i], (void *) base + i * 4);
#endif
}
#ifdef CONFIG_RMII
//(IOMUX_PADTYPE(17)(iomux_obj.pads[18]).reg)->bit.e = 1;
reg = GET_REG(0xf00000a4);
reg |= (1 << 13);
SET_REG(0xf00000a4, reg);
#else
//(IOMUX_PADTYPE(17)(iomux_obj.pads[18]).reg)->bit.e = 0;
reg = GET_REG(0xf00000a4);
reg &= ~(1 << 13);
SET_REG(0xf00000a4, reg);
#endif
#ifdef IOMUX_DEBUG
fh_iomux_print(iomux_obj);
#endif
//rt_free(iomux_obj.vbase);
//iomux_obj.vbase = 0;
}
void fh_iomux_pin_switch(int pin_num, int func_num)
{
RT_ASSERT(pin_num < fh_iomux_cfg_count);
__fh_setiomux(&fh_iomux_cfg[pin_num], (void *)g_iomux_base + pin_num * 4);
/*
fh_iomux_cfg[pin_num].func_sel = func_num;
fh_iomux_setmfs(&fh_iomux_cfg[pin_num]);
SET_REG(iomux_obj.pbase + iomux_obj.pads[pin_num].reg_offset, *((UINT32 *)(iomux_obj.vbase + iomux_obj.pads[pin_num].reg_offset)));
*/
}

View File

@ -1,314 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef IOMUX_H_
#define IOMUX_H_
#include "fh_def.h"
#define PMU_PAD_RESETN (0)
#define PMU_PAD_TEST (1)
#define PMU_PAD_CIS_CLK (2)
#define PMU_PAD_CIS_HSYNC (3)
#define PMU_PAD_CIS_VSYNC (4)
#define PMU_PAD_CIS_PCLK (5)
#define PMU_PAD_CIS_D_0 (6)
#define PMU_PAD_CIS_D_1 (7)
#define PMU_PAD_CIS_D_2 (8)
#define PMU_PAD_CIS_D_3 (9)
#define PMU_PAD_CIS_D_4 (10)
#define PMU_PAD_CIS_D_5 (11)
#define PMU_PAD_CIS_D_6 (12)
#define PMU_PAD_CIS_D_7 (13)
#define PMU_PAD_CIS_D_8 (14)
#define PMU_PAD_CIS_D_9 (15)
#define PMU_PAD_CIS_D_10 (16)
#define PMU_PAD_CIS_D_11 (17)
#define PMU_PAD_MAC_REF_CLK (18)
#define PMU_PAD_MAC_MDC (19)
#define PMU_PAD_MAC_MDIO (20)
#define PMU_PAD_MAC_COL (21)
#define PMU_PAD_MAC_CRS (22)
#define PMU_PAD_MAC_RXCK (23)
#define PMU_PAD_MAC_RXD0 (24)
#define PMU_PAD_MAC_RXD1 (25)
#define PMU_PAD_MAC_RXD2 (26)
#define PMU_PAD_MAC_RXD3 (27)
#define PMU_PAD_MAC_RXDV (28)
#define PMU_PAD_MAC_TXCK (29)
#define PMU_PAD_MAC_TXD0 (30)
#define PMU_PAD_MAC_TXD1 (31)
#define PMU_PAD_MAC_TXD2 (32)
#define PMU_PAD_MAC_TXD3 (33)
#define PMU_PAD_MAC_TXEN (34)
#define PMU_PAD_MAC_RXER (35)
#define PMU_PAD_GPIO_0 (36)
#define PMU_PAD_GPIO_1 (37)
#define PMU_PAD_GPIO_2 (38)
#define PMU_PAD_GPIO_3 (39)
#define PMU_PAD_GPIO_4 (40)
#define PMU_PAD_GPIO_5 (41)
#define PMU_PAD_GPIO_6 (42)
#define PMU_PAD_GPIO_7 (43)
#define PMU_PAD_GPIO_8 (44)
#define PMU_PAD_GPIO_9 (45)
#define PMU_PAD_GPIO_10 (46)
#define PMU_PAD_GPIO_11 (47)
#define PMU_PAD_GPIO_12 (48)
#define PMU_PAD_GPIO_13 (49)
#define PMU_PAD_GPIO_14 (50)
#define PMU_PAD_GPIO_15 (51)
#define PMU_PAD_GPIO_16 (52)
#define PMU_PAD_GPIO_17 (53)
#define PMU_PAD_GPIO_18 (54)
#define PMU_PAD_GPIO_19 (55)
#define PMU_PAD_UART0_IN (56)
#define PMU_PAD_UART0_OUT (57)
#define PMU_PAD_CIS_SCL (58)
#define PMU_PAD_CIS_SDA (59)
#define PMU_PAD_SCL1 (60)
#define PMU_PAD_SDA1 (61)
#define PMU_PAD_SSI0_CLK (62)
#define PMU_PAD_SSI0_TXD (63)
#define PMU_PAD_SSI0_CSN_0 (64)
#define PMU_PAD_SSI0_CSN_1 (65)
#define PMU_PAD_SSI0_RXD (66)
#define PMU_PAD_SD0_CD (67)
#define PMU_PAD_SD0_WP (68)
#define PMU_PAD_SD0_CLK (69)
#define PMU_PAD_SD0_CMD_RSP (70)
#define PMU_PAD_SD0_DATA_0 (71)
#define PMU_PAD_SD0_DATA_1 (72)
#define PMU_PAD_SD0_DATA_2 (73)
#define PMU_PAD_SD0_DATA_3 (74)
#define PMU_PAD_SD1_CLK (75)
#define PMU_PAD_SD1_CD (76)
#define PMU_PAD_SD1_WP (77)
#define PMU_PAD_SD1_DATA_0 (78)
#define PMU_PAD_SD1_DATA_1 (79)
#define PMU_PAD_SD1_DATA_2 (80)
#define PMU_PAD_SD1_DATA_3 (81)
#define PMU_PAD_SD1_CMD_RSP (82)
#define PMU_PAD_GPIO_60 (83)
#define PMU_PAD_GPIO_61 (84)
#define PMU_PAD_GPIO_62 (85)
#define PMU_PAD_GPIO_63 (86)
#define PMU_PAD_CLK_SW0 (87)
#define PMU_PAD_CLK_SW1 (88)
#define PMU_PAD_CLK_SW2 (89)
#define PMU_PAD_CLK_SW3 (90)
#define PMU_PAD_CRYSTAL (91)
#define PMU_PAD_MAC_TXER (92)
#define IOMUX_PADTYPE(n) (Iomux_PadType##n *)
#define IOMUX_PUPD_NONE 0
#define IOMUX_PUPD_DOWN 1
#define IOMUX_PUPD_UP 2
#define IOMUX_PUPD_KEEPER 3
//#define IOMUX_DEBUG
typedef union
{
struct
{
UINT32 sr :1;
UINT32 reserved_3_1 :3;
UINT32 e8_e4 :2;
UINT32 reserved_31_6 :24;
}bit;
UINT32 dw;
}Iomux_PadType5;
typedef union
{
struct
{
UINT32 sr :1;
UINT32 reserved_3_1 :3;
UINT32 e8_e4 :2;
UINT32 reserved_7_6 :2;
UINT32 mfs :1;
UINT32 reserved_31_9 :23;
}bit;
UINT32 dw;
}Iomux_PadType8;
typedef union
{
struct
{
UINT32 smt :1;
UINT32 reserved_3_1 :3;
UINT32 ie :1;
UINT32 reserved_7_5 :3;
UINT32 pu_pd :2;
UINT32 reserved_31_10 :22;
}bit;
UINT32 dw;
}Iomux_PadType9;
typedef union
{
struct
{
UINT32 e4_e2 :2;
UINT32 reserved_3_2 :2;
UINT32 smt :1;
UINT32 reserved_7_5 :3;
UINT32 ie :1;
UINT32 reserved_11_9 :3;
UINT32 mfs :2;
UINT32 reserved_31_14 :18;
}bit;
UINT32 dw;
}Iomux_PadType13;
typedef union
{
struct
{
UINT32 sr :1;
UINT32 reserved_3_1 :3;
UINT32 e8_e4 :2;
UINT32 reserved_7_6 :2;
UINT32 smt :1;
UINT32 reserved_11_9 :3;
UINT32 ie :1;
UINT32 e :1; //only for PAD_MAC_REF_CLK_CFG (0x00a4)
UINT32 reserved_15_12 :2;
UINT32 pu_pd :2;
UINT32 reserved_31_18 :14;
}bit;
UINT32 dw;
}Iomux_PadType17;
typedef union
{
struct
{
UINT32 sr :1;
UINT32 reserved_3_1 :3;
UINT32 e4_e2 :2;
UINT32 reserved_7_6 :2;
UINT32 smt :1;
UINT32 reserved_11_9 :3;
UINT32 ie :1;
UINT32 reserved_15_13 :3;
UINT32 pu_pd :2;
UINT32 reserved_19_18 :2;
UINT32 mfs :1;
UINT32 reserved_31_21 :11;
}bit;
UINT32 dw;
}Iomux_PadType20;
typedef union
{
struct
{
UINT32 sr :1;
UINT32 reserved_3_1 :3;
UINT32 e4_e2 :2;
UINT32 reserved_7_6 :2;
UINT32 smt :1;
UINT32 reserved_11_9 :3;
UINT32 ie :1;
UINT32 reserved_15_13 :3;
UINT32 pu_pd :2;
UINT32 reserved_19_18 :2;
UINT32 mfs :2;
UINT32 reserved_31_21 :10;
}bit;
UINT32 dw;
}Iomux_PadType21;
typedef struct
{
int id;
UINT32* reg;
UINT32 reg_offset;
char* func_name[4];
int reg_type;
int func_sel;
int drv_cur;
int pupd;
//UINT32 value;
}Iomux_Pad;
typedef struct
{
void *vbase;
void *pbase;
Iomux_Pad *pads;
}Iomux_Object;
void fh_iomux_init(UINT32 base);
void fh_iomux_pin_switch(int pin_num, int func_num);
#endif /* IOMUX_H_ */

View File

@ -1,50 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtthread.h>
#include "fh_pmu.h"
#include "fh_def.h"
#include "fh_arch.h"
void machine_reset(void)
{
fh_pmu_write(REG_PMU_SWRST_MAIN_CTRL, 0x7fffffff);
}
void machine_shutdown(void)
{
while(1)
;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_cpu_reset, reset, system reset);
#endif
/*@}*/

View File

@ -1,109 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#include "timer.h"
#include <rtdevice.h>
#include "fh_arch.h"
#include "libraries/inc/fh_timer.h"
//#include "fh_pmu.h"
//#include "chip_reg.h"
//NEED_CAUTION.
#define TIMER_CLOCK 1000000
#define CONFIG_PAE_PTS_CLOCK (1000000)
#define TICKS_PER_USEC (CONFIG_PAE_PTS_CLOCK / 1000000)
#define REG_PAE_PTS_REG (0xec100000 + 0x0040)
static unsigned long lastdec;
static unsigned long long timestamp;
rt_uint32_t read_pts(void)
{
return GET_REG(REG_PAE_PTS_REG);
}
unsigned long long get_ticks(void)
{
rt_uint32_t now = read_pts();
if (now >= lastdec) {
/* normal mode */
timestamp += now - lastdec;
} else {
now = read_pts();
if (now >= lastdec)
timestamp += now - lastdec;
else {
/* we have an overflow ... */
timestamp += now + 0xffffffff - lastdec;
}
}
lastdec = now;
return timestamp / (TICKS_PER_USEC * 10);
}
void udelay(unsigned long usec)
{
unsigned long long tmp;
rt_uint32_t tmo;
tmo = (usec + 9) / 10;
tmp = get_ticks() + tmo; /* get current timestamp */
while (get_ticks() < tmp)
/* loop till event */
/*NOP*/;
}
void rt_timer_handler(int vector, void *param)
{
timer *tim = param;
rt_interrupt_enter();
timer_get_eoi(tim);
rt_tick_increase();
rt_interrupt_leave();
}
/**
* This function will init pit for system ticks
*/
void rt_hw_timer_init()
{
timer *tim = (timer *) TMR_REG_BASE;
timer_init(tim);
/* install interrupt handler */
rt_hw_interrupt_install(TMR0_IRQn, rt_timer_handler, (void *) tim,
"sys_tick");
rt_hw_interrupt_umask(TMR0_IRQn);
timer_set_mode(tim, TIMER_MODE_PERIODIC);
timer_set_period(tim, RT_TICK_PER_SECOND, TIMER_CLOCK);
//timer_set_period(tim, RT_TIMER_TICK_PER_SECOND, TIMER_CLOCK);
timer_enable_irq(tim);
timer_enable(tim);
}

View File

@ -1,36 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef TIMER_H_
#define TIMER_H_
#include <rtdef.h>
void rt_hw_timer_init(void);
#endif

View File

@ -1,81 +0,0 @@
/*
* This file is part of FH8620 BSP for RT-Thread distribution.
*
* Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
* All rights reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Visit http://www.fullhan.com to get contact with Fullhan.
*
* Change Logs:
* Date Author Notes
*/
#ifndef PLATFORM_DEF_H_
#define PLATFORM_DEF_H_
#include "rtconfig.h"
#ifdef CONFIG_CHIP_FH8620
#ifdef CONFIG_BOARD_DEV
#include "fh8620/dev_board/board_def.h"
#endif
#endif
#ifdef CONFIG_CHIP_FH8620
#ifdef CONFIG_BOARD_TEST
#include "fh8620/test_board/board_def.h"
#endif
#endif
#ifdef CONFIG_CHIP_FH8620
#ifdef CONFIG_BOARD_IOTCAM
#include "fh8620/iot_cam/board_def.h"
#endif
#endif
#ifdef CONFIG_CHIP_FH8620G
#ifdef CONFIG_BOARD_DEV
#include "fh8620g/dev_board/board_def.h"
#endif
#endif
#ifdef CONFIG_CHIP_FH8620G
#ifdef CONFIG_BOARD_TEST
#include "fh8620g/test_board/board_def.h"
#endif
#endif
#ifdef CONFIG_CHIP_FH8810
#ifdef CONFIG_BOARD_DEV
#include "fh8810/dev_board/board_def.h"
#endif
#endif
#ifdef CONFIG_CHIP_FH8810
#ifdef CONFIG_BOARD_TEST
#include "fh8810/test_board/board_def.h"
#endif
#endif
#endif /* TEST_H_ */

View File

@ -1,203 +0,0 @@
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
// <RDTConfigurator URL="http://www.rt-thread.com/eclipse">
// <integer name="RT_NAME_MAX" description="Maximal size of kernel object name length" default="6" />
#define RT_NAME_MAX 16
// <integer name="RT_ALIGN_SIZE" description="Alignment size for CPU architecture data access" default="4" />
#define RT_ALIGN_SIZE 4
// <integer name="RT_THREAD_PRIORITY_MAX" description="Maximal level of thread priority" default="32">
// <item description="8">8</item>
// <item description="32">32</item>
// <item description="256">256</item>
// </integer>
#define RT_THREAD_PRIORITY_MAX 256
// <integer name="RT_TICK_PER_SECOND" description="OS tick per second" default="100" />
#define RT_TICK_PER_SECOND 100
// <integer name="IDLE_THREAD_STACK_SIZE" description="The stack size of idle thread" default="512" />
#define IDLE_THREAD_STACK_SIZE 512
// <bool name="RT_USING_MODULE" description="Using Application Module" default="true" />
// #define RT_USING_MODULE
// <bool name="RT_USING_CPU_FFS" description="Using CPU instructions for ffs function" default="true" />
#define RT_USING_CPU_FFS
// <section name="RT_DEBUG" description="Kernel Debug Configuration" default="true" >
#define RT_DEBUG
#define RT_DEBUG_COLOR
// <bool name="RT_THREAD_DEBUG" description="Thread debug enable" default="false" />
// #define RT_THREAD_DEBUG
// <bool name="RT_USING_OVERFLOW_CHECK" description="Thread stack over flow detect" default="true" />
#define RT_USING_OVERFLOW_CHECK
// </section>
// <bool name="RT_USING_HOOK" description="Using hook functions" default="true" />
#define RT_USING_HOOK
// <section name="RT_USING_TIMER_SOFT" description="Using software timer which will start a thread to handle soft-timer" default="true" >
// #define RT_USING_TIMER_SOFT
// <integer name="RT_TIMER_THREAD_PRIO" description="The priority level of timer thread" default="4" />
#define RT_TIMER_THREAD_PRIO 4
// <integer name="RT_TIMER_THREAD_STACK_SIZE" description="The stack size of timer thread" default="512" />
#define RT_TIMER_THREAD_STACK_SIZE 512
// <integer name="RT_TIMER_TICK_PER_SECOND" description="The soft-timer tick per second" default="10" />
#define RT_TIMER_TICK_PER_SECOND 100
// </section>
// <section name="IPC" description="Inter-Thread communication" default="always" >
// <bool name="RT_USING_SEMAPHORE" description="Using semaphore in the system" default="true" />
#define RT_USING_SEMAPHORE
// <bool name="RT_USING_MUTEX" description="Using mutex in the system" default="true" />
#define RT_USING_MUTEX
// <bool name="RT_USING_EVENT" description="Using event group in the system" default="true" />
#define RT_USING_EVENT
// <bool name="RT_USING_MAILBOX" description="Using mailbox in the system" default="true" />
#define RT_USING_MAILBOX
// <bool name="RT_USING_MESSAGEQUEUE" description="Using message queue in the system" default="true" />
#define RT_USING_MESSAGEQUEUE
// </section>
// <section name="MM" description="Memory Management" default="always" >
// <bool name="RT_USING_MEMPOOL" description="Using Memory Pool Management in the system" default="true" />
#define RT_USING_MEMPOOL
// <bool name="RT_USING_MEMHEAP" description="Using Memory Heap Object in the system" default="true" />
#define RT_USING_MEMHEAP
// <bool name="RT_USING_HEAP" description="Using Dynamic Heap Management in the system" default="true" />
#define RT_USING_HEAP
// <bool name="RT_USING_SMALL_MEM" description="Optimizing for small memory" default="false" />
#define RT_USING_SMALL_MEM
// <bool name="RT_USING_SLAB" description="Using SLAB memory management for large memory" default="false" />
// #define RT_USING_SLAB
// </section>
// <section name="RT_USING_DEVICE" description="Using Device Driver Framework" default="true" >
#define RT_USING_DEVICE
// <bool name=RT_USING_DEVICE_IPC description="Using IPC in Device Driver Framework" default="true" />
#define RT_USING_DEVICE_IPC
// <bool name="RT_USING_SERIAL" description="Using Serial Device Driver Framework" default="true" />
#define RT_USING_SERIAL
#define RT_SERIAL_USING_DMA
// <integer name="RT_UART_RX_BUFFER_SIZE" description="The buffer size for UART reception" default="64" />
#define RT_UART_RX_BUFFER_SIZE 64
// </section>
// <bool name="RT_USING_SPI" description="Using SPI Device Driver Framework" default="true" />
//#define RT_USING_SPI
// <bool name="RT_USING_I2C" description="Using I2C Device Driver Framework" default="true" />
#define RT_USING_I2C
// <bool name="RT_USING_RTC" description="Using RTC Device Driver Framework" default="true" />
//#define RT_USING_RTC
// <integer name="RT_MMCSD_THREAD_PREORITY" description="The prority of mmcsd thread" default="15" />
#define RT_MMCSD_THREAD_PREORITY 15
// <section name="RT_USING_CONSOLE" description="Using console" default="true" >
#define RT_USING_CONSOLE
// <integer name="RT_CONSOLEBUF_SIZE" description="The buffer size for console output" default="128" />
#define RT_CONSOLEBUF_SIZE 128
// <string name="RT_CONSOLE_DEVICE_NAME" description="The device name for console" default="uart" />
#define RT_CONSOLE_DEVICE_NAME "uart1"
// </section>
// <bool name="RT_USING_COMPONENTS_INIT" description="Using RT-Thread components initialization" default="true" />
#define RT_USING_COMPONENTS_INIT
// <section name="RT_USING_FINSH" description="Using finsh as shell, which is a C-Express shell" default="true" >
#define RT_USING_FINSH
#define FINSH_USING_MSH
// <bool name="FINSH_USING_SYMTAB" description="Using symbol table in finsh shell" default="true" />
#define FINSH_USING_SYMTAB
// <bool name="FINSH_USING_DESCRIPTION" description="Keeping description in symbol table" default="true" />
#define FINSH_USING_DESCRIPTION
// <integer name="FINSH_THREAD_STACK_SIZE" description="The stack size for finsh thread" default="4096" />
#define FINSH_THREAD_STACK_SIZE 4096
// </section>
// <section name="LIBC" description="C Runtime library setting" default="always" >
// <bool name="RT_USING_LIBC" description="Using C library" default="true" />
#define RT_USING_LIBC
// <bool name="RT_USING_POSIX" description="Using POSIX library" default="true" />
#define RT_USING_POSIX
// <bool name="RT_USING_PTHREADS" description="Using POSIX threads library" default="true" />
#define RT_USING_PTHREADS
// <bool name="RT_USING_CPLUSPLUS" description="Support C++ programming language" default="true" />
#define RT_USING_CPLUSPLUS
// </section>
// <section name="RT_USING_DFS" description="Device file system" default="true" >
#define RT_USING_DFS
// <bool name="DFS_USING_WORKDIR" description="Using working directory" default="true" />
#define DFS_USING_WORKDIR
// <integer name="DFS_FILESYSTEMS_MAX" description="The maximal number of mounted file system" default="4" />
#define DFS_FILESYSTEMS_MAX 2
// <integer name="DFS_FD_MAX" description="The maximal number of opened files" default="4" />
#define DFS_FD_MAX 16
// <bool name="RT_USING_DFS_ELMFAT" description="Using ELM FatFs" default="true" />
#define RT_USING_DFS_ELMFAT
// <integer name="RT_DFS_ELM_DRIVES" description="The maximal number of drives of FatFs" default="4" />
#define RT_DFS_ELM_DRIVES 2
// <bool name="RT_DFS_ELM_REENTRANT" description="Support reentrant" default="true" />
#define RT_DFS_ELM_REENTRANT
// <integer name="RT_DFS_ELM_USE_LFN" description="Support long file name" default="0">
// <item description="LFN with static LFN working buffer">1</item>
// <item description="LFN with dynamic LFN working buffer on the stack">2</item>
// <item description="LFN with dynamic LFN working buffer on the heap">3</item>
// </integer>
#define RT_DFS_ELM_USE_LFN 3
// <integer name="RT_DFS_ELM_CODE_PAGE" description="OEM code page" default="936">
#define RT_DFS_ELM_CODE_PAGE 936
// <bool name="RT_DFS_ELM_CODE_PAGE_FILE" description="Using OEM code page file" default="false" />
#define RT_DFS_ELM_CODE_PAGE_FILE
// <integer name="RT_DFS_ELM_MAX_LFN" description="Maximal size of file name length" default="255" />
#define RT_DFS_ELM_MAX_LFN 255
// <integer name="RT_DFS_ELM_MAX_SECTOR_SIZE" description="Maximal size of sector" default="512" />
#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096
// <bool name="RT_USING_DFS_YAFFS2" description="Using YAFFS2" default="false" />
// #define RT_USING_DFS_YAFFS2
// <bool name="RT_USING_DFS_UFFS" description="Using UFFS" default="false" />
// #define RT_USING_DFS_UFFS
// <bool name="RT_USING_DFS_DEVFS" description="Using devfs for device objects" default="true" />
#define RT_USING_DFS_DEVFS
// <bool name="RT_USING_DFS_ROMFS" description="Using ROMFS" default="false" />
//#define RT_USING_DFS_ROMFS
// </section>
// <section name="RT_USING_LWIP" description="lwip, a lightweight TCP/IP protocol stack" default="true" >
// #define RT_USING_LWIP
// <bool name="RT_LWIP_ICMP" description="Enable ICMP protocol" default="true" />
#define RT_LWIP_ICMP
// <bool name="RT_LWIP_IGMP" description="Enable IGMP protocol" default="false" />
// #define RT_LWIP_IGMP
// <bool name="RT_LWIP_UDP" description="Enable UDP protocol" default="true" />
#define RT_LWIP_UDP
// <bool name="RT_LWIP_TCP" description="Enable TCP protocol" default="true" />
#define RT_LWIP_TCP
// <bool name="RT_LWIP_DNS" description="Enable DNS protocol" default="true" />
#define RT_LWIP_DNS
// <bool name="RT_LWIP_SNMP" description="Enable SNMP protocol" default="false" />
// #define RT_LWIP_SNMP
// <bool name="RT_LWIP_DHCP" description="Enable DHCP client to get IP address" default="false" />
#define RT_LWIP_DHCP
// <integer name="RT_LWIP_TCPTHREAD_PRIORITY" description="the thread priority of TCP thread" default="128" />
#define RT_LWIP_TCPTHREAD_PRIORITY 12
// <integer name="RT_LWIP_TCPTHREAD_MBOX_SIZE" description="the mail box size of TCP thread to wait for" default="32" />
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
// <integer name="RT_LWIP_TCPTHREAD_STACKSIZE" description="the thread stack size of TCP thread" default="4096" />
#define RT_LWIP_TCPTHREAD_STACKSIZE 4096
// <integer name="RT_LWIP_ETHTHREAD_PRIORITY" description="the thread priority of ethnetif thread" default="144" />
#define RT_LWIP_ETHTHREAD_PRIORITY 14
// <integer name="RT_LWIP_ETHTHREAD_MBOX_SIZE" description="the mail box size of ethnetif thread to wait for" default="8" />
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
// <integer name="RT_LWIP_ETHTHREAD_STACKSIZE" description="the stack size of ethnetif thread" default="512" />
#define RT_LWIP_ETHTHREAD_STACKSIZE 512
// <ipaddr name="RT_LWIP_IPADDR" description="IP address of device" default="192.168.1.30" />
#define RT_LWIP_IPADDR "192.168.1.30"
// <ipaddr name="RT_LWIP_GWADDR" description="Gateway address of device" default="192.168.1.1" />
#define RT_LWIP_GWADDR "192.168.1.1"
// <ipaddr name="RT_LWIP_MSKADDR" description="Mask address of device" default="255.255.255.0" />
#define RT_LWIP_MSKADDR "255.255.255.0"
// </section>
// </RDTConfigurator>
#define CONFIG_BOARD_IOTCAM
#define CONFIG_CHIP_FH8620
#define CONFIG_PLAT_V2
#define RT_USING_DMA_MEM
#endif

View File

@ -1,44 +0,0 @@
import os
import sys
import re
# toolchains options
ARCH = 'arm'
CPU = 'armv6'
OUTPUT_NAME = 'rtthread'
CROSS_TOOL = 'gcc' # we use gcc compiler always
PLATFORM = 'gcc'
LD_NAME = 'link'
EXEC_PATH = r'D:\arm-2013.11\bin'
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'release'
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = '.elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=soft'
CFLAGS = DEVICE + ' -mno-unaligned-access'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map='+ OUTPUT_NAME +'.map,-cref,-u,_start -T' + LD_NAME +'.ld'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2 '
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
POST_ACTION = OBJCPY + ' -O binary $TARGET '+ OUTPUT_NAME +'.bin\n' + SIZE + ' $TARGET \n'

View File

@ -1,342 +0,0 @@
#
# Automatically generated file; DO NOT EDIT.
# RT-Thread Configuration
#
#
# RT-Thread Kernel
#
CONFIG_RT_NAME_MAX=32
CONFIG_RT_ALIGN_SIZE=4
# CONFIG_RT_THREAD_PRIORITY_8 is not set
# CONFIG_RT_THREAD_PRIORITY_32 is not set
CONFIG_RT_THREAD_PRIORITY_256=y
CONFIG_RT_THREAD_PRIORITY_MAX=256
CONFIG_RT_TICK_PER_SECOND=100
CONFIG_RT_DEBUG=y
CONFIG_RT_DEBUG_COLOR=y
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_DEBUG_INIT=0
CONFIG_RT_DEBUG_THREAD=0
CONFIG_RT_USING_HOOK=y
CONFIG_IDLE_THREAD_STACK_SIZE=1024
CONFIG_RT_USING_TIMER_SOFT=y
CONFIG_RT_TIMER_THREAD_PRIO=4
CONFIG_RT_TIMER_THREAD_STACK_SIZE=10240
#
# Inter-Thread communication
#
CONFIG_RT_USING_SEMAPHORE=y
CONFIG_RT_USING_MUTEX=y
CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MAILBOX=y
CONFIG_RT_USING_MESSAGEQUEUE=y
# CONFIG_RT_USING_SIGNALS is not set
#
# Memory Management
#
# CONFIG_RT_USING_MEMPOOL is not set
CONFIG_RT_USING_MEMHEAP=y
# CONFIG_RT_USING_NOHEAP is not set
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
# CONFIG_RT_USING_MEMTRACE is not set
CONFIG_RT_USING_HEAP=y
#
# Kernel Device Object
#
CONFIG_RT_USING_DEVICE=y
CONFIG_RT_USING_INTERRUPT_INFO=y
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
# CONFIG_RT_USING_MODULE is not set
#
# RT-Thread Components
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=16384
#
# C++ features
#
CONFIG_RT_USING_CPLUSPLUS=y
#
# Command shell
#
CONFIG_RT_USING_FINSH=y
CONFIG_FINSH_THREAD_NAME="tshell"
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=5
CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_USING_DESCRIPTION=y
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=4096
CONFIG_FINSH_CMD_SIZE=80
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_USING_MSH_DEFAULT=y
# CONFIG_FINSH_USING_MSH_ONLY is not set
#
# Device virtual file system
#
CONFIG_RT_USING_DFS=y
CONFIG_DFS_USING_WORKDIR=y
CONFIG_DFS_FILESYSTEMS_MAX=9
CONFIG_DFS_FILESYSTEM_TYPES_MAX=9
CONFIG_DFS_FD_MAX=16
CONFIG_RT_USING_DFS_ELMFAT=y
#
# elm-chan's FatFs, Generic FAT Filesystem Module
#
CONFIG_RT_DFS_ELM_CODE_PAGE=437
CONFIG_RT_DFS_ELM_WORD_ACCESS=y
CONFIG_RT_DFS_ELM_USE_LFN_0=y
# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
CONFIG_RT_DFS_ELM_USE_LFN=0
CONFIG_RT_DFS_ELM_MAX_LFN=255
CONFIG_RT_DFS_ELM_DRIVES=2
CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
# CONFIG_RT_DFS_ELM_USE_ERASE is not set
CONFIG_RT_DFS_ELM_REENTRANT=y
CONFIG_RT_USING_DFS_DEVFS=y
# CONFIG_RT_USING_DFS_NET is not set
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_UFFS is not set
CONFIG_RT_USING_DFS_JFFS2=y
CONFIG_RT_USING_DFS_NFS=y
CONFIG_RT_NFS_HOST_EXPORT="192.168.10.82:/"
#
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_SERIAL_USING_DMA=y
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
CONFIG_RT_USING_I2C=y
CONFIG_RT_USING_I2C_BITOPS=y
CONFIG_RT_USING_PIN=y
CONFIG_RT_USING_MTD_NOR=y
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_RTC is not set
CONFIG_RT_USING_SDIO=y
CONFIG_RT_USING_SPI=y
# CONFIG_RT_USING_SPI_MSD is not set
# CONFIG_RT_USING_SFUD is not set
# CONFIG_RT_USING_W25QXX is not set
# CONFIG_RT_USING_GD is not set
# CONFIG_RT_USING_ENC28J60 is not set
# CONFIG_RT_USING_SPI_WIFI is not set
CONFIG_RT_USING_WDT=y
# CONFIG_RT_USING_WIFI is not set
#
# Using USB
#
# CONFIG_RT_USING_USB_HOST is not set
# CONFIG_RT_USING_USB_DEVICE is not set
#
# POSIX layer and C standard library
#
CONFIG_RT_USING_LIBC=y
CONFIG_RT_USING_PTHREADS=y
# CONFIG_RT_USING_POSIX is not set
#
# Network stack
#
#
# light weight TCP/IP stack
#
CONFIG_RT_USING_LWIP=y
# CONFIG_RT_USING_LWIP141 is not set
CONFIG_RT_USING_LWIP202=y
# CONFIG_RT_USING_LWIP_IPV6 is not set
CONFIG_RT_LWIP_IGMP=y
CONFIG_RT_LWIP_ICMP=y
# CONFIG_RT_LWIP_SNMP is not set
CONFIG_RT_LWIP_DNS=y
CONFIG_RT_LWIP_DHCP=y
CONFIG_IP_SOF_BROADCAST=1
CONFIG_IP_SOF_BROADCAST_RECV=1
#
# Static IPv4 Address
#
CONFIG_RT_LWIP_IPADDR="192.168.1.30"
CONFIG_RT_LWIP_GWADDR="192.168.1.1"
CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
CONFIG_RT_LWIP_UDP=y
CONFIG_RT_LWIP_TCP=y
# CONFIG_RT_LWIP_RAW is not set
# CONFIG_RT_LWIP_PPP is not set
CONFIG_RT_MEMP_NUM_NETCONN=64
CONFIG_RT_LWIP_PBUF_NUM=16
CONFIG_RT_LWIP_RAW_PCB_NUM=10
CONFIG_RT_LWIP_UDP_PCB_NUM=64
CONFIG_RT_LWIP_TCP_PCB_NUM=8
CONFIG_RT_LWIP_TCP_SEG_NUM=256
CONFIG_RT_LWIP_TCP_SND_BUF=12040
CONFIG_RT_LWIP_TCP_WND=11680
CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=100
CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=32
CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=32768
CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=126
CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=32
CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
CONFIG_SO_REUSE=1
CONFIG_LWIP_SO_RCVTIMEO=1
CONFIG_LWIP_SO_SNDTIMEO=1
CONFIG_LWIP_SO_RCVBUF=1
# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
CONFIG_LWIP_NETIF_LOOPBACK=0
#
# Modbus master and slave stack
#
# CONFIG_RT_USING_MODBUS is not set
CONFIG_LWIP_USING_DHCPD=y
#
# RT-Thread UI Engine
#
# CONFIG_RT_USING_GUIENGINE is not set
#
# VBUS(Virtual Software BUS)
#
# CONFIG_RT_USING_VBUS is not set
#
# Utilities
#
# CONFIG_RT_USING_LOGTRACE is not set
# CONFIG_RT_USING_RYM is not set
#
# RT-Thread online packages
#
#
# system packages
#
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
#
# IoT - internet of things
#
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_MONGOOSE is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_LJSON is not set
# CONFIG_PKG_USING_EZXML is not set
# CONFIG_PKG_USING_NANOPB is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
#
# Wi-Fi
#
#
# Marvell WiFi
#
# CONFIG_PKG_USING_WLANMARVELL is not set
#
# Wiced WiFi
#
# CONFIG_PKG_USING_WLAN_WICED is not set
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_libsodium is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
#
# language packages
#
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
#
# multimedia packages
#
# CONFIG_PKG_USING_OPENMV is not set
#
# tools packages
#
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_IPERF is not set
#
# miscellaneous packages
#
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
#
# example package: hello
#
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_SOC_GK7101 is not set
# CONFIG_SOC_GK7102 is not set
# CONFIG_SOC_GK7101S is not set
# CONFIG_SOC_GK7102S is not set
CONFIG_SOC_GK7102C=y
CONFIG_BOARD_GK7102C_EVB=y
CONFIG_SENSOR_TYPE_SC1135=y
# CONFIG_SENSOR_TYPE_SC1145 is not set
# CONFIG_SENSOR_TYPE_JXH65 is not set
# CONFIG_SENSOR_TYPE_OV9750 is not set
# CONFIG_SENSOR_TYPE_AR0130 is not set
# CONFIG_SENSOR_TYPE_JXH42 is not set
CONFIG_TUNNING_TOOL_SUPPORT=y
CONFIG_RT_USING_DMA_MEM=y
CONFIG_ARM1176_USE_VFP=y
CONFIG_RT_USING_VFP=y
CONFIG_RT_USING_CPU_FFS=y
#
# Goke Peripheral Device Config
#
CONFIG_RT_USING_ADC=y
CONFIG_RT_USING_GMAC=y
CONFIG_RT_USING_PWM=y
CONFIG_RT_USING_GK_DMA=y
CONFIG_RT_USING_LIBZ=y
CONFIG_RT_USING_LOGCAPTURE=y
CONFIG_RT_ALIGN_UC_SIZE=8
CONFIG_RT_ALIGN_DSP_SIZE=32
CONFIG_RT_DEBUG_UC_MEM=0
CONFIG_RT_DEBUG_DSP_MEM=0

View File

@ -1,139 +0,0 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../.."
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
config SOC_GK710
bool
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
choice
prompt "Device type"
default GK7102C
config SOC_GK7101
bool "GK7101"
config SOC_GK7102
bool "GK7102"
config SOC_GK7101S
bool "GK7101S"
config SOC_GK7102S
bool "GK7102S"
config SOC_GK7102C
bool "GK7102C"
endchoice
choice
prompt "Board type"
default GK7102C_EVB
config BOARD_GK7101_EVB
bool "GK7101_EVB"
depends on SOC_GK7101
config BOARD_GK7101_EVB
bool "GK7101_EVB"
depends on SOC_GK7102
config BOARD_GK7101S_EVB
bool "GK7101S_EVB"
depends on SOC_GK7101S
config BOARD_GK7101S_EVB
bool "GK7101S_EVB"
depends on SOC_GK7102S
config BOARD_GK7102C_EVB
bool "GK7102C_EVB"
depends on SOC_GK7102C
endchoice
choice
prompt "Sensor type"
default SENSOR_TYPE_SC1135
config SENSOR_TYPE_SC1135
bool "SC1135"
config SENSOR_TYPE_SC1145
bool "SC1145"
config SENSOR_TYPE_JXH65
bool "JXH65"
config SENSOR_TYPE_OV9750
bool "OV9750"
config SENSOR_TYPE_AR0130
bool "AR0130"
config SENSOR_TYPE_JXH42
bool "JXH42"
endchoice
config TUNNING_TOOL_SUPPORT
bool "Using Tuning Tool"
default y
config RT_USING_DMA_MEM
bool "Enable DMA Mem"
default y
config ARM1176_USE_VFP
bool "Enable ARM1176 VFP"
default y
config RT_USING_VFP
bool "Enable VFP"
default y
config RT_USING_CPU_FFS
bool "Enable CPU FFS"
default y
menu "Goke Peripheral Device Config"
config RT_USING_ADC
bool "Enable ADC"
default y
config RT_USING_GMAC
bool "Enable GMAC"
default y
config RT_USING_PWM
bool "Enable PWM"
default y
config RT_USING_GK_DMA
bool "Enable DMA"
default y
config RT_USING_LIBZ
bool "Enable Zlib for firmware uncompress"
default y
config RT_USING_LOGCAPTURE
bool "Enable DSP Logcaputure"
default y
config RT_ALIGN_UC_SIZE
int "Align UC Size"
default 8
config RT_ALIGN_DSP_SIZE
int "Align DSP Size"
default 32
config RT_DEBUG_UC_MEM
int "Debug UC Memory"
default 0
config RT_DEBUG_DSP_MEM
int "Debug DSP Memory"
default 0
endmenu

View File

@ -1,61 +0,0 @@
# gkipc板级支持包
标签: bsp说明文档
---
## 1. 简介
GK7102C是针对高清IP Camera产品开发的一款低功耗高性能 SOC芯片支持 960@30p多路码流 H.264 编码及高质量的 ISP 处理,内置 3D降噪和动态对比度提升模块支持主流的多种并口 8bit/10bit/12bit sensor。视频输出支持 RGB 小型 LCD 屏显示接口。 GK7102C 内封 DDR2 DRAM 芯片,内置 Ethernet PHY, Audio codec,USB PHY 等模拟 IP。 GK7102C 拥有
丰富的外设接口,如 USB2.0,SDIO,PWM,SPI,I2C 等等,支持最多 32 个GPIO可灵活配置各功能模块的输出管脚为实现高集成度 IPC提供了高性价比的解决方案。包括如下硬件特性
| 硬件 | 描述 |
| -- | -- |
|芯片型号| GK7102C |
|CPU| ARM1176ZJFS |
|主频| 432MHz |
|片内DDR2| 512M bit@800MHz |
## 2. 编译说明
推荐使用[env工具][1]可以在console下进入到`bsp/gkipc`目录中,运行以下命令:
scons
来编译这个板级支持包。如果编译正确无误会产生rtthread.elf、rtthread.bin文件。其中rtthread.bin可以通过网络加载或者烧写到设备中进行运行。
## 3. 烧写及执行
[需要说明电源连接情况,串口连接情况]
连接好串口可以使用115200-N-8-1的配置方式连接到设备上。设备使用的串口引脚是`[GPIO25/GPIO26]`
当正确编译产生出rtthread.bin映像文件后可以使用tftp的方式来加载到设备中运行。
### 3.1 运行结果
如果编译 & 烧写无误当复位设备后会在串口上看到RT-Thread的启动logo信息
## 4. 驱动支持情况及计划
| 驱动 | 支持情况 | 备注 |
| ------ | ---- | :------: |
| UART | 支持 | UART0/1/2 |
| clock | 支持 | |
| SPI | | SPI0 |
| ADC | 支持 | |
| DMA | 支持 | |
| GMAC | 支持 | |
| I2C | 支持 | |
| PWM | 支持 | |
| SDIO | 支持 | SDIO0/1 |
| WDT | 支持 | |
| MMC | 支持 | |
| SSI | 支持 | |
## 5. 联系人信息
维护人gokemicro < gokemicro@yeah.net >
[1]: https://www.rt-thread.org/page/download.html

View File

@ -1,19 +0,0 @@
# for module compiling
import os
Import('RTT_ROOT')
cwd = str(Dir('#'))
objs = []
list = os.listdir(cwd)
print('------------------------------------------------')
print('rtt_root: ' + RTT_ROOT)
print('current dir: ' + cwd)
print('------------------------------------------------')
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

View File

@ -1,34 +0,0 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = rtconfig.OUTPUT_NAME + rtconfig.TARGET_EXT
# add rtconfig.h path to the assembler
rtconfig.AFLAGS += ' -I' + str(Dir('#')) +' -I' + str(Dir('#')) + '/bsp'
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
# make a building
DoBuilding(TARGET, objs)

View File

@ -1,10 +0,0 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd, cwd + '/../drivers', cwd + '/../libraries/inc']
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef RT_USING_GMAC
#include <drv_gmac.h>
#endif
int main(void)
{
#ifdef RT_USING_GMAC
rt_app_gk_gmac_init();
#endif
printf("Hello\n");
return 0;
}

Some files were not shown because too many files have changed in this diff Show More