提交 43f68131 编写于 作者: B Bernard Xiong

[BSP] Add fh8620 bsp from Shanghai Fullhan Microelectronics Co., Ltd.

FH8620 BSP
Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
All rights reserved
上级 6d03ce9a
# 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')
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'
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)
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')
/*
* 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 <components.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;
}
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
此差异已折叠。
/*
* 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
/*
* 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;
}
/*
* 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
/*
* 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
/*
* 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
此差异已折叠。
/*
* 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_ */
/*
* 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__);
}
/*
* 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_ */
此差异已折叠。
/*
* 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
/*
* 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, 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
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
path = [cwd + '/..']
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path)
Return('group')
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册