mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-27 01:10:20 +08:00
[bsp]update x1000 bsp driver
This commit is contained in:
24
bsp/x1000/Kconfig
Normal file
24
bsp/x1000/Kconfig
Normal file
@@ -0,0 +1,24 @@
|
||||
mainmenu "RT-Thread Configuration"
|
||||
|
||||
config $BSP_DIR
|
||||
string
|
||||
option env="BSP_ROOT"
|
||||
default "."
|
||||
|
||||
config $RTT_DIR
|
||||
string
|
||||
option env="RTT_ROOT"
|
||||
default "E:/rt-thread"
|
||||
|
||||
# you can change the RTT_ROOT default "../.." to your rtthread_root,
|
||||
# example : default "F:/git_repositories/rt-thread"
|
||||
|
||||
config $PKGS_DIR
|
||||
string
|
||||
option env="PKGS_ROOT"
|
||||
default "packages"
|
||||
|
||||
source "$RTT_DIR/KConfig"
|
||||
source "$PKGS_DIR/KConfig"
|
||||
source "$BSP_DIR/drivers/Kconfig"
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import os
|
||||
import sys
|
||||
import rtconfig
|
||||
from rtconfig import RTT_ROOT
|
||||
|
||||
if os.getenv('RTT_ROOT'):
|
||||
RTT_ROOT = os.getenv('RTT_ROOT')
|
||||
else:
|
||||
RTT_ROOT = os.path.join(Dir('#').get_abspath(), 'rt-thread')
|
||||
|
||||
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
|
||||
from building import *
|
||||
|
||||
@@ -11,16 +15,19 @@ TARGET = 'rtthread-x1000.' + rtconfig.TARGET_EXT
|
||||
env = Environment(tools = ['mingw'],
|
||||
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
|
||||
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
|
||||
CXX = rtconfig.CC, CXXFLAGS = rtconfig.CXXFLAGS,
|
||||
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
|
||||
AR = rtconfig.AR, ARFLAGS = '-rc',
|
||||
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
|
||||
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
|
||||
|
||||
# add --start-group and --end-group for GNU GCC
|
||||
env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group'
|
||||
|
||||
Export('RTT_ROOT')
|
||||
Export('rtconfig')
|
||||
|
||||
# prepare building environment
|
||||
objs = PrepareBuilding(env, RTT_ROOT)
|
||||
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
|
||||
|
||||
# make a building
|
||||
DoBuilding(TARGET, objs)
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
|
||||
CPPPATH = [cwd, str(Dir('#'))]
|
||||
|
||||
if not GetDepend("RT_USING_DFS_ROMFS"):
|
||||
SrcRemove(src, "romfs.c")
|
||||
|
||||
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
|
||||
74
bsp/x1000/applications/blink.c
Normal file
74
bsp/x1000/applications/blink.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* File : blink.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2017, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-11-8 Tangyuxin first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include <board.h>
|
||||
#include <drv_gpio.h>
|
||||
|
||||
void blink_task(void* param)
|
||||
{
|
||||
rt_uint8_t cnt = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 4);
|
||||
|
||||
if(cnt & 0x01)
|
||||
gpio_set_value(BLINK_LED0_PORT,BLINK_LED0_PIN,0);
|
||||
else
|
||||
gpio_set_value(BLINK_LED0_PORT,BLINK_LED0_PIN,1);
|
||||
|
||||
if(cnt & 0x02)
|
||||
gpio_set_value(BLINK_LED1_PORT,BLINK_LED1_PIN,0);
|
||||
else
|
||||
gpio_set_value(BLINK_LED1_PORT,BLINK_LED1_PIN,1);
|
||||
|
||||
if(cnt & 0x04)
|
||||
gpio_set_value(BLINK_LED2_PORT,BLINK_LED2_PIN,0);
|
||||
else
|
||||
gpio_set_value(BLINK_LED2_PORT,BLINK_LED2_PIN,1);
|
||||
|
||||
if(cnt & 0x08)
|
||||
gpio_set_value(BLINK_LED3_PORT,BLINK_LED3_PIN,0);
|
||||
else
|
||||
gpio_set_value(BLINK_LED3_PORT,BLINK_LED3_PIN,1);
|
||||
|
||||
cnt ++;
|
||||
}
|
||||
}
|
||||
|
||||
int blink_init(void)
|
||||
{
|
||||
rt_thread_t tid;
|
||||
|
||||
tid = rt_thread_create("blink",
|
||||
blink_task, RT_NULL,
|
||||
512,
|
||||
RT_THREAD_PRIORITY_MAX - 2,
|
||||
10);
|
||||
if (tid != RT_NULL)
|
||||
rt_thread_startup(tid);
|
||||
}
|
||||
INIT_APP_EXPORT(blink_init);
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* File : _main.c
|
||||
* File : main.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
* COPYRIGHT (C) 2008 - 2017, RT-Thread Development Team
|
||||
*
|
||||
* 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
|
||||
@@ -19,14 +19,12 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
* 2017-11-8 Tangyuxin first version
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("Hello RT-Thread!\n");
|
||||
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
72
bsp/x1000/applications/mnt_init.c
Normal file
72
bsp/x1000/applications/mnt_init.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* File : mnt_init.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2017, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-11-8 Tangyuxin first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#ifdef RT_USING_DFS
|
||||
#include <dfs_fs.h>
|
||||
|
||||
int mnt_init(void)
|
||||
{
|
||||
rt_kprintf("init filesystem...\n");
|
||||
#ifdef RT_USING_MTD_NOR
|
||||
//mount rootfs
|
||||
if (dfs_mount("rootfs", "/", "elm", 0, 0) == 0)
|
||||
{
|
||||
rt_kprintf("File System on root initialized!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("File System on root initialization failed!\n");
|
||||
}
|
||||
|
||||
//mount appfs
|
||||
if (dfs_mount("appfs", "/appfs", "elm", 0, 0) == 0)
|
||||
{
|
||||
rt_kprintf("File System on appfs initialized!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("File System on appfs initialization failed!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(RT_USING_SDIO) && defined(RT_USING_MSC0))
|
||||
rt_thread_delay(RT_TICK_PER_SECOND/5);
|
||||
if (dfs_mount("sd0", "/sd", "elm", 0, 0) == 0)
|
||||
{
|
||||
rt_kprintf("File System on TF initialized!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("File System on TF fail!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_ENV_EXPORT(mnt_init);
|
||||
|
||||
#endif
|
||||
154
bsp/x1000/applications/rtgui_demo.c
Normal file
154
bsp/x1000/applications/rtgui_demo.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* File : rtgui_demo.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2017, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-11-8 Tangyuxin first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
// #define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINTF(...)
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_GUIENGINE
|
||||
|
||||
#include <rtgui/rtgui.h>
|
||||
#include <rtgui/rtgui_system.h>
|
||||
#include <rtgui/rtgui_app.h>
|
||||
|
||||
#include <rtgui/widgets/window.h>
|
||||
#include <rtgui/dc.h>
|
||||
|
||||
struct rtgui_win *main_win;
|
||||
rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event);
|
||||
|
||||
static void rt_gui_demo_entry(void *parameter)
|
||||
{
|
||||
struct rtgui_app *app;
|
||||
|
||||
DEBUG_PRINTF("gui demo entry\n");
|
||||
|
||||
/* create gui app */
|
||||
app = rtgui_app_create("gui_demo");
|
||||
if (app == RT_NULL)
|
||||
{
|
||||
DEBUG_PRINTF("rtgui_app_create faild\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* create main window */
|
||||
main_win = rtgui_mainwin_create(RT_NULL,
|
||||
"UiWindow", RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER);
|
||||
if (main_win == RT_NULL)
|
||||
{
|
||||
DEBUG_PRINTF("main_win is null\n");
|
||||
rtgui_app_destroy(app);
|
||||
return;
|
||||
}
|
||||
|
||||
rtgui_object_set_event_handler(RTGUI_OBJECT(main_win), dc_event_handler);
|
||||
|
||||
DEBUG_PRINTF("rtgui_win_show\n");
|
||||
rtgui_win_show(main_win, RT_FALSE);
|
||||
|
||||
DEBUG_PRINTF("rtgui_app_run\n");
|
||||
rtgui_app_run(app);
|
||||
|
||||
DEBUG_PRINTF("rtgui_win_destroy\n");
|
||||
rtgui_win_destroy(main_win);
|
||||
|
||||
DEBUG_PRINTF("rtgui_app_destroy\n");
|
||||
rtgui_app_destroy(app);
|
||||
}
|
||||
|
||||
rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event)
|
||||
{
|
||||
struct rtgui_widget *widget = RTGUI_WIDGET(object);
|
||||
|
||||
if (event->type == RTGUI_EVENT_PAINT)
|
||||
{
|
||||
struct rtgui_dc *dc;
|
||||
rtgui_rect_t rect;
|
||||
|
||||
rt_kprintf("\r\n RTGUI_EVENT_PAINT \r\n");
|
||||
rtgui_win_event_handler(RTGUI_OBJECT(widget), event);
|
||||
|
||||
rtgui_widget_get_rect(widget, &rect);
|
||||
DEBUG_PRINTF("widget react x1: %d, y1: %d, x2: %d, y2: %d\r\n",
|
||||
rect.x1, rect.y1, rect.x2, rect.y2);
|
||||
|
||||
dc = rtgui_dc_begin_drawing(widget);
|
||||
if(dc == RT_NULL)
|
||||
{
|
||||
DEBUG_PRINTF("\r\n dc is null \r\n");
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
rtgui_dc_draw_line(dc, rect.x1, rect.y1, rect.x2, rect.y2);
|
||||
rtgui_dc_draw_line(dc, rect.x1, rect.y2, rect.x2, rect.y1);
|
||||
|
||||
rect.x1 += (rect.x2 - rect.x1) / 2;
|
||||
rect.y1 += (rect.y2 - rect.y1) / 2;
|
||||
rtgui_dc_draw_text_stroke(dc, __DATE__"--"__TIME__, &rect, HIGH_LIGHT, BLUE);
|
||||
|
||||
rtgui_dc_end_drawing(dc,RT_TRUE);
|
||||
}
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
int rt_gui_demo_init(void)
|
||||
{
|
||||
rt_thread_t tid;
|
||||
rt_device_t device;
|
||||
rt_err_t err;
|
||||
|
||||
device = rt_device_find("lcd");
|
||||
if(device == RT_NULL)
|
||||
{
|
||||
rt_kprintf("Not found LCD driver\n");
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
err = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
|
||||
if (err != RT_EOK)
|
||||
{
|
||||
rt_kprintf("Open LCD driver fail\n");
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
/* set graphic device */
|
||||
rtgui_graphic_set_device(device);
|
||||
|
||||
tid = rt_thread_create("mygui",
|
||||
rt_gui_demo_entry, RT_NULL,
|
||||
2048, 25, 10);
|
||||
|
||||
if (tid != RT_NULL)
|
||||
rt_thread_startup(tid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_APP_EXPORT(rt_gui_demo_init);
|
||||
#endif /* RT_USING_GUIENGINE */
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* File : board.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "x1000.h"
|
||||
|
||||
#define RT_USING_JZ_X1000
|
||||
|
||||
// #define BOARD_PHOENIX
|
||||
// #define BOARD_CANNA
|
||||
|
||||
#ifdef BOARD_PHOENIX
|
||||
#define RT_USING_EMAC
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************************
|
||||
** Clock for Board
|
||||
*********************************************************************************************************/
|
||||
#define BOARD_EXTAL_CLK 24000000
|
||||
#define BOARD_RTC_CLK 32768
|
||||
#define BOARD_CPU_CLK (1008 * 1000 * 1000UL)
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** HEAP Setting
|
||||
*********************************************************************************************************/
|
||||
extern unsigned char __bss_start;
|
||||
extern unsigned char __bss_end;
|
||||
|
||||
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
|
||||
#define RT_HW_HEAP_END (void*)(0x80000000 + 32 * 1024 * 1024)
|
||||
|
||||
/*********************************************************************************************************
|
||||
** UART Setting
|
||||
*********************************************************************************************************/
|
||||
#define RT_USING_UART2
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
* File : drv_uart.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_uart.h"
|
||||
|
||||
struct jz_uart_s
|
||||
{
|
||||
rt_uint32_t hw_base;
|
||||
|
||||
rt_uint32_t irqno;
|
||||
char name[RT_NAME_MAX];
|
||||
};
|
||||
|
||||
static rt_err_t uart_configure (struct rt_serial_device *serial, struct serial_configure *cfg);
|
||||
static rt_err_t uart_control (struct rt_serial_device *serial, int cmd, void *arg);
|
||||
static int uart_putc (struct rt_serial_device *serial, char c);
|
||||
static int uart_getc (struct rt_serial_device *serial);
|
||||
static rt_size_t uart_dma_transmit (struct rt_serial_device *serial, const rt_uint8_t *buf, rt_size_t size, int direction);
|
||||
|
||||
static void uart_irq_handler (int irqno, void *param);
|
||||
|
||||
const struct rt_uart_ops _uart_ops =
|
||||
{
|
||||
uart_configure,
|
||||
uart_control,
|
||||
uart_putc,
|
||||
uart_getc,
|
||||
uart_dma_transmit
|
||||
};
|
||||
|
||||
/*
|
||||
* UART Initiation
|
||||
*/
|
||||
void rt_hw_uart_init(void)
|
||||
{
|
||||
struct rt_serial_device *serial;
|
||||
struct jz_uart_s *uart;
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
|
||||
#ifdef RT_USING_UART1
|
||||
{
|
||||
static struct rt_serial_device serial1;
|
||||
static struct jz_uart_s uart1;
|
||||
|
||||
serial = &serial1;
|
||||
uart = &uart1;
|
||||
|
||||
serial->ops = &_uart_ops;
|
||||
serial->config = config;
|
||||
serial->config.baud_rate = 115200;
|
||||
|
||||
uart->hw_base = UART0_BASE;
|
||||
uart->irqno = IRQ_UART0;
|
||||
|
||||
rt_hw_serial_register(serial,
|
||||
"uart1",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART2
|
||||
{
|
||||
static struct rt_serial_device serial2;
|
||||
static struct jz_uart_s uart2;
|
||||
|
||||
serial = &serial2;
|
||||
uart = &uart2;
|
||||
|
||||
serial->ops = &_uart_ops;
|
||||
serial->config = config;
|
||||
serial->config.baud_rate = 115200;
|
||||
|
||||
uart->hw_base = UART2_BASE;
|
||||
uart->irqno = IRQ_UART2;
|
||||
|
||||
rt_hw_serial_register(serial,
|
||||
"uart2",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART3
|
||||
{
|
||||
static struct rt_serial_device serial3;
|
||||
static struct jz_uart_s uart3;
|
||||
|
||||
serial = &serial3;
|
||||
uart = &uart3;
|
||||
|
||||
serial->ops = &_uart_ops;
|
||||
serial->config = config;
|
||||
serial->config.baud_rate = 115200;
|
||||
|
||||
uart->hw_base = UART3_BASE;
|
||||
uart->irqno = IRQ_UART3;
|
||||
|
||||
rt_hw_serial_register(serial,
|
||||
"uart3",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* UART interface
|
||||
*/
|
||||
static rt_err_t uart_configure (struct rt_serial_device *serial, struct serial_configure *cfg)
|
||||
{
|
||||
rt_uint32_t baud_div;
|
||||
struct jz_uart_s * uart;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
serial->config = *cfg;
|
||||
|
||||
uart = serial->parent.user_data;
|
||||
RT_ASSERT(uart != RT_NULL);
|
||||
|
||||
/* Init UART Hardware */
|
||||
UART_IER(uart->hw_base) = 0; /* clear interrupt */
|
||||
UART_FCR(uart->hw_base) = ~UARTFCR_UUE; /* disable UART unite */
|
||||
|
||||
/* Enable UART clock */
|
||||
|
||||
/* Set both receiver and transmitter in UART mode (not SIR) */
|
||||
UART_SIRCR(uart->hw_base) = ~(SIRCR_RSIRE | SIRCR_TSIRE);
|
||||
|
||||
/* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
|
||||
UART_LCR(uart->hw_base) = UARTLCR_WLEN_8;
|
||||
|
||||
/* set baudrate */
|
||||
#if defined(RT_USING_JZ4750) || defined(RT_USING_JZ4755) || defined(RT_USING_JZ4760)
|
||||
if(REG_CPM_CPCCR & (1UL << 30))
|
||||
{
|
||||
/* CPCCR.ECS = 1: clock source is EXCLK/2 */
|
||||
baud_div = BOARD_EXTAL_CLK / 2 / 16 / cfg->baud_rate;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* CPCCR.ECS = 0: clock source is EXCLK */
|
||||
baud_div = BOARD_EXTAL_CLK / 16 / cfg->baud_rate;
|
||||
}
|
||||
|
||||
UART_LCR(uart->hw_base) |= UARTLCR_DLAB;
|
||||
UART_DLHR(uart->hw_base) = (baud_div >> 8) & 0xff;
|
||||
UART_DLLR(uart->hw_base) = baud_div & 0xff;
|
||||
|
||||
UART_LCR(uart->hw_base) &= ~UARTLCR_DLAB;
|
||||
|
||||
/* Enable UART unit, enable and clear FIFO */
|
||||
UART_FCR(uart->hw_base) = UARTFCR_UUE | UARTFCR_FE | UARTFCR_TFLS | UARTFCR_RFLS;
|
||||
|
||||
return (RT_EOK);
|
||||
}
|
||||
|
||||
static rt_err_t uart_control (struct rt_serial_device *serial, int cmd, void *arg)
|
||||
{
|
||||
struct jz_uart_s * uart;
|
||||
|
||||
uart = serial->parent.user_data;
|
||||
|
||||
RT_ASSERT(uart != RT_NULL);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* Disable the UART Interrupt */
|
||||
UART_IER(uart->hw_base) &= ~(UARTIER_RIE | UARTIER_RTIE);
|
||||
rt_hw_interrupt_mask(uart->irqno);
|
||||
break;
|
||||
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* install interrupt */
|
||||
rt_hw_interrupt_install(uart->irqno, uart_irq_handler,
|
||||
serial, uart->name);
|
||||
rt_hw_interrupt_umask(uart->irqno);
|
||||
|
||||
/* Enable the UART Interrupt */
|
||||
UART_IER(uart->hw_base) |= (UARTIER_RIE | UARTIER_RTIE);
|
||||
break;
|
||||
}
|
||||
|
||||
return (RT_EOK);
|
||||
}
|
||||
|
||||
static int uart_putc (struct rt_serial_device *serial, char c)
|
||||
{
|
||||
struct jz_uart_s* uart;
|
||||
|
||||
uart = serial->parent.user_data;
|
||||
|
||||
/* FIFO status, contain valid data */
|
||||
while (!((UART_LSR(uart->hw_base) & (UARTLSR_TDRQ | UARTLSR_TEMT)) == 0x60));
|
||||
/* write data */
|
||||
UART_TDR(uart->hw_base) = c;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int uart_getc (struct rt_serial_device *serial)
|
||||
{
|
||||
struct jz_uart_s* uart = serial->parent.user_data;
|
||||
|
||||
/* Receive Data Available */
|
||||
if (UART_LSR(uart->hw_base) & UARTLSR_DR)
|
||||
{
|
||||
return UART_RDR(uart->hw_base);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static rt_size_t uart_dma_transmit (struct rt_serial_device *serial, const rt_uint8_t *buf, rt_size_t size, int direction)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* UART ISR */
|
||||
static void uart_irq_handler(int irqno, void *param)
|
||||
{
|
||||
rt_ubase_t isr;
|
||||
struct rt_serial_device *serial = (struct rt_serial_device*)param;
|
||||
struct jz_uart_s* uart = serial->parent.user_data;
|
||||
|
||||
/* read interrupt status and clear it */
|
||||
isr = UART_ISR(uart->hw_base);
|
||||
if (isr & UARTISR_IID_RDI) /* Receive Data Available */
|
||||
{
|
||||
rt_hw_serial_isr(serial,RT_SERIAL_EVENT_RX_IND);
|
||||
}
|
||||
|
||||
if(isr & UARTISR_IID_THRI)
|
||||
{
|
||||
rt_hw_serial_isr(serial,RT_SERIAL_EVENT_TX_DONE);
|
||||
}
|
||||
}
|
||||
131
bsp/x1000/drivers/Kconfig
Normal file
131
bsp/x1000/drivers/Kconfig
Normal file
@@ -0,0 +1,131 @@
|
||||
choice
|
||||
prompt "Choice bsp board"
|
||||
default BOARD_HALLEY2_REALBOARD_V2
|
||||
|
||||
config BOARD_HALLEY2
|
||||
bool "Using haller2 board"
|
||||
|
||||
config BOARD_PHOENIX
|
||||
bool "Using phoenix board"
|
||||
|
||||
config BOARD_CANNA
|
||||
bool "Using canna board"
|
||||
|
||||
config BOARD_HALLEY2_FIR
|
||||
bool "Using haller2 fir board"
|
||||
|
||||
config BOARD_HALLEY2_REALBOARD
|
||||
bool "Using haller2 realboard board"
|
||||
|
||||
config BOARD_HALLEY2_REALBOARD_V2
|
||||
bool "Using haller2 realboard v2 board"
|
||||
|
||||
config BOARD_HALLEY2_IDELAN
|
||||
bool "Using haller2 idelan board"
|
||||
endchoice
|
||||
|
||||
if RT_USING_SERIAL
|
||||
config RT_USING_UART0
|
||||
bool "Using UART0"
|
||||
default n
|
||||
|
||||
config RT_USING_UART1
|
||||
bool "Using UART1"
|
||||
default n
|
||||
|
||||
config RT_USING_UART2
|
||||
bool "Using UART2"
|
||||
default y
|
||||
endif
|
||||
|
||||
if RT_USING_SDIO
|
||||
config RT_USING_MSC0
|
||||
bool "Using MSC0 for sd card"
|
||||
default y
|
||||
|
||||
config RT_USING_MSC1
|
||||
bool "Using MSC1 for wifi"
|
||||
default y
|
||||
|
||||
config RT_MMCSD_STACK_SIZE
|
||||
int "Set mmc thread stack size"
|
||||
default 2048
|
||||
endif
|
||||
|
||||
if RT_USING_GUIENGINE
|
||||
config RT_USING_SLCD
|
||||
bool "Using lcd display"
|
||||
default y
|
||||
|
||||
if RT_USING_SLCD
|
||||
choice
|
||||
prompt "Choice LCD controller"
|
||||
default RT_USING_ILI9488
|
||||
|
||||
config RT_USING_ILI9488
|
||||
bool "Using ILI9488 controller"
|
||||
|
||||
config RT_USING_ILI9341
|
||||
bool "Using ILI9341 controller"
|
||||
|
||||
config RT_USING_OTM4802
|
||||
bool "Using OTM4802 controller"
|
||||
|
||||
config RT_USING_TRULY_TFT240240
|
||||
bool "Using TFT240240 controller"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
if RT_USING_I2C
|
||||
config RT_USING_TOUCH
|
||||
bool "Using touch"
|
||||
default y
|
||||
|
||||
if RT_USING_TOUCH
|
||||
choice
|
||||
prompt "Choice touch controller"
|
||||
default RT_USING_GT9XX
|
||||
|
||||
config RT_USING_GT9XX
|
||||
bool "Using GT9XX controller"
|
||||
|
||||
config RT_USING_FT6x06
|
||||
bool "Using FT6x06 controller"
|
||||
endchoice
|
||||
|
||||
config RT_TOUCH_THREAD_PRIORITY
|
||||
int "Set touch thread priority"
|
||||
range 2 32
|
||||
default 10
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if RT_USING_I2C
|
||||
config RT_USING_I2C0
|
||||
bool "Using iic0 bus"
|
||||
default y
|
||||
|
||||
config RT_USING_I2C1
|
||||
bool "Using iic1 bus"
|
||||
default n
|
||||
|
||||
config RT_USING_I2C2
|
||||
bool "Using iic2 bus"
|
||||
default n
|
||||
endif
|
||||
|
||||
config RT_USING_AUDIO
|
||||
bool "Using audio"
|
||||
default n
|
||||
if RT_USING_AUDIO
|
||||
config RT_USING_ICODEC
|
||||
bool "Using icodec"
|
||||
default n
|
||||
endif
|
||||
|
||||
config RT_USING_CPU_FFS
|
||||
bool "Using CPU FFS"
|
||||
default y
|
||||
|
||||
|
||||
28
bsp/x1000/drivers/SConscript
Normal file
28
bsp/x1000/drivers/SConscript
Normal file
@@ -0,0 +1,28 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.S')
|
||||
CPPPATH = [cwd, str(Dir('#'))]
|
||||
|
||||
if not GetDepend('RT_USING_I2C'):
|
||||
SrcRemove(src, ['drv_i2c.c'])
|
||||
if not GetDepend('RT_USING_SPI'):
|
||||
SrcRemove(src, ['drv_spi.c'])
|
||||
if not GetDepend('RT_USING_WDT'):
|
||||
SrcRemove(src, ['drv_reset.c'])
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
# build for sub-directory
|
||||
list = os.listdir(cwd)
|
||||
objs = []
|
||||
|
||||
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'))
|
||||
group = group + objs
|
||||
|
||||
Return('group')
|
||||
11
bsp/x1000/drivers/audio/SConscript
Normal file
11
bsp/x1000/drivers/audio/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.S')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('drv_audio', src, depend = ['RT_USING_AUDIO'], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
670
bsp/x1000/drivers/audio/drv_aic.h
Normal file
670
bsp/x1000/drivers/audio/drv_aic.h
Normal file
File diff suppressed because it is too large
Load Diff
619
bsp/x1000/drivers/audio/drv_aic_i2s.c
Normal file
619
bsp/x1000/drivers/audio/drv_aic_i2s.c
Normal file
File diff suppressed because it is too large
Load Diff
94
bsp/x1000/drivers/audio/drv_aic_i2s.h
Normal file
94
bsp/x1000/drivers/audio/drv_aic_i2s.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* drv_aic_i2s.h
|
||||
*
|
||||
* Created on: 2016年4月1日
|
||||
* Author: Urey
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_DRV_AIC_I2S_H_
|
||||
#define DRIVER_DRV_AIC_I2S_H_
|
||||
|
||||
#include "board.h"
|
||||
|
||||
|
||||
#ifdef RT_USING_ICODEC
|
||||
# define CODEC_AS_MASTER
|
||||
|
||||
#define CODEC_DEF_RATE (24000000)
|
||||
#else
|
||||
//# undef CODEC_AS_MASTER
|
||||
//# define CODEC_AS_MASTER
|
||||
|
||||
#define CODEC_DEF_RATE (44100)
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_ECODEC_WM8978
|
||||
# define CFG_AIC_I2S_EXT_CODEC
|
||||
#endif
|
||||
|
||||
#define CFG_AIC_SOC_CLKOUT
|
||||
//#define CFG_AIC_SOC_CLKIN
|
||||
|
||||
#define CFG_I2S_DMA_PAGE_SIZE (32 * 1024)
|
||||
#define CFG_I2S_DMA_PAGE_NUM 8
|
||||
|
||||
enum
|
||||
{
|
||||
I2S_TRIGGER_STOP = 0,
|
||||
I2S_TRIGGER_START ,
|
||||
I2S_TRIGGER_PAUSE_PUSH ,
|
||||
I2S_TRIGGER_PAUSE_RELEASE ,
|
||||
I2S_TRIGGER_SUSPEND ,
|
||||
I2S_TRIGGER_RESUME,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 数据结构
|
||||
*********************************************************************************************************/
|
||||
struct jz_i2s
|
||||
{
|
||||
struct jz_aic *aic;
|
||||
int i2s_init;
|
||||
#define I2S_WRITE 0x1
|
||||
#define I2S_READ 0x2
|
||||
#define I2S_INCODEC (0x1 <<4)
|
||||
#define I2S_EXCODEC (0x2 <<4)
|
||||
#define I2S_SLAVE (0x1 << 8)
|
||||
#define I2S_MASTER (0x2 << 8)
|
||||
int i2s_mode;
|
||||
uint32_t tx_dr_base;
|
||||
|
||||
int channels;
|
||||
int fmt_width;
|
||||
int rates;
|
||||
|
||||
/* used for DMA transform */
|
||||
struct rt_dma_channel *tx_dmac;
|
||||
struct rt_dma_channel *rx_dmac;
|
||||
};
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数申明
|
||||
*********************************************************************************************************/
|
||||
int aic_set_rate(struct jz_aic *aic, uint32_t freq);
|
||||
|
||||
struct jz_i2s *rt_hw_aic_i2s_init(void);
|
||||
|
||||
//void aic_i2s_start_substream(struct jz_i2s *i2s,int stream);
|
||||
//void aic_i2s_stop_substream(struct jz_i2s *i2s,int stream);
|
||||
int aic_i2s_set_sysclk(struct jz_i2s *i2s,uint32_t freq);
|
||||
int aic_i2s_set_clkdiv(struct jz_i2s *i2s,int div_id, int div);
|
||||
int aic_i2s_startup(struct jz_i2s *i2s,int stream);
|
||||
int aic_i2s_trigger(struct jz_i2s* i2s,int cmd,int stream);
|
||||
|
||||
int aic_i2s_hw_params(struct jz_i2s* i2s,int stream);
|
||||
void aic_i2s_shutdown(struct jz_i2s *i2s,int stream);
|
||||
|
||||
rt_size_t aic_i2s_send(struct jz_i2s *i2s, const void* buffer, rt_size_t size,void (*tx_callback)(void *,void *), void *tx_arg);
|
||||
rt_size_t aic_i2s_recv(struct jz_i2s *i2s, void* buffer, rt_size_t size,void (*rx_callback)(void *,void *), void *rx_arg);
|
||||
|
||||
|
||||
void aic_i2s_set_rate(struct jz_i2s *i2s,int rate);
|
||||
#endif /* DRIVER_DRV_AIC_I2S_H_ */
|
||||
826
bsp/x1000/drivers/audio/drv_codec_icodec.c
Normal file
826
bsp/x1000/drivers/audio/drv_codec_icodec.c
Normal file
File diff suppressed because it is too large
Load Diff
406
bsp/x1000/drivers/audio/drv_codec_icodec.h
Normal file
406
bsp/x1000/drivers/audio/drv_codec_icodec.h
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* drv_codec_icodec.h
|
||||
*
|
||||
* Created on: 2017Äê1ÔÂ10ÈÕ
|
||||
* Author: Urey
|
||||
*/
|
||||
|
||||
#ifndef _DRV_CODEC_ICODEC_H_
|
||||
#define _DRV_CODEC_ICODEC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "x1000.h"
|
||||
#include "drv_clock.h"
|
||||
|
||||
|
||||
struct jz_icodec
|
||||
{
|
||||
struct jz_i2s *i2s;
|
||||
struct rt_audio_configure replay_config;
|
||||
#ifdef AUDIO_DEVICE_USE_PRIVATE_BUFFER
|
||||
struct rt_mempool mp;
|
||||
#endif /* AUDIO_DEVICE_USE_PRIVATE_BUFFER */
|
||||
uint32_t mapped_base;
|
||||
|
||||
/* replay */
|
||||
int user_replay_volume;
|
||||
int dac_user_mute; /*dac user mute state*/
|
||||
int aohp_in_pwsq; /*aohp in power up/down seq*/
|
||||
int hpl_wished_gain; /*keep original hpl/r gain register value*/
|
||||
int hpr_wished_gain;
|
||||
int linl_wished_gain; /*keep original hpl/r gain register value*/
|
||||
int linr_wished_gain;
|
||||
|
||||
};
|
||||
|
||||
#define ICODEC_PCM_FORMAT AUDIO_FMT_PCM_S16_LE
|
||||
#define ICODEC_SAMPLING_RATE 44100
|
||||
|
||||
|
||||
/* icodec internal register space */
|
||||
enum {
|
||||
SCODA_REG_SR = 0x0,
|
||||
SCODA_REG_SR2,
|
||||
SCODA_REG_SIGR,
|
||||
SCODA_REG_SIGR2,
|
||||
SCODA_REG_SIGR3,
|
||||
SCODA_REG_SIGR5,
|
||||
SCODA_REG_SIGR7,
|
||||
SCODA_REG_MR,
|
||||
SCODA_REG_AICR_DAC,
|
||||
SCODA_REG_AICR_ADC,
|
||||
SCODA_REG_CR_DMIC,
|
||||
SCODA_REG_CR_MIC1,
|
||||
SCODA_REG_CR_MIC2,
|
||||
SCODA_REG_CR_DAC,
|
||||
SCODA_REG_CR_DAC2,
|
||||
SCODA_REG_CR_ADC,
|
||||
SCODA_REG_CR_MIX,
|
||||
SCODA_REG_DR_MIX,
|
||||
SCODA_REG_CR_VIC,
|
||||
SCODA_REG_CR_CK,
|
||||
SCODA_REG_FCR_DAC,
|
||||
SCODA_REG_SFCCR_DAC,
|
||||
SCODA_REG_SFFCR_DAC,
|
||||
SCODA_REG_FCR_ADC,
|
||||
SCODA_REG_CR_TIMER_MSB,
|
||||
SCODA_REG_CR_TIMER_LSB,
|
||||
SCODA_REG_ICR,
|
||||
SCODA_REG_IMR,
|
||||
SCODA_REG_IFR,
|
||||
SCODA_REG_IMR2,
|
||||
SCODA_REG_IFR2,
|
||||
SCODA_REG_GCR_DACL,
|
||||
SCODA_REG_GCR_DACR,
|
||||
SCODA_REG_GCR_DACL2,
|
||||
SCODA_REG_GCR_DACR2,
|
||||
SCODA_REG_GCR_MIC1,
|
||||
SCODA_REG_GCR_MIC2,
|
||||
SCODA_REG_GCR_ADCL,
|
||||
SCODA_REG_GCR_ADCR,
|
||||
SCODA_REG_GCR_MIXDACL,
|
||||
SCODA_REG_GCR_MIXDACR,
|
||||
SCODA_REG_GCR_MIXADCL,
|
||||
SCODA_REG_GCR_MIXADCR,
|
||||
SCODA_REG_CR_DAC_AGC,
|
||||
SCODA_REG_DR_DAC_AGC,
|
||||
SCODA_REG_CR_DAC2_AGC,
|
||||
SCODA_REG_DR_DAC2_AGC,
|
||||
SCODA_REG_CR_ADC_AGC,
|
||||
SCODA_REG_DR_ADC_AGC,
|
||||
SCODA_REG_SR_ADC_AGCDGL,
|
||||
SCODA_REG_SR_ADC_AGCDGR,
|
||||
SCODA_REG_SR_ADC_AGCAGL,
|
||||
SCODA_REG_SR_ADC_AGCAGR,
|
||||
SCODA_REG_CR_TR,
|
||||
SCODA_REG_DR_TR,
|
||||
SCODA_REG_SR_TR1,
|
||||
SCODA_REG_SR_TR2,
|
||||
SCODA_REG_SR_TR_SRCDAC,
|
||||
|
||||
/* icodec internal register extend space */
|
||||
SCODA_MIX_0,
|
||||
SCODA_MIX_1,
|
||||
SCODA_MIX_2,
|
||||
SCODA_MIX_3,
|
||||
SCODA_MIX_4,
|
||||
|
||||
SCODA_DAC_AGC0,
|
||||
SCODA_DAC_AGC1,
|
||||
SCODA_DAC_AGC2,
|
||||
SCODA_DAC_AGC3,
|
||||
|
||||
SCODA_DAC2_AGC0,
|
||||
SCODA_DAC2_AGC1,
|
||||
SCODA_DAC2_AGC2,
|
||||
SCODA_DAC2_AGC3,
|
||||
|
||||
SCODA_ADC_AGC0,
|
||||
SCODA_ADC_AGC1,
|
||||
SCODA_ADC_AGC2,
|
||||
SCODA_ADC_AGC3,
|
||||
SCODA_ADC_AGC4,
|
||||
SCODA_MAX_REG_NUM,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*aicr dac*/
|
||||
#define SCODA_AICR_DAC_ADWL_SHIFT (6)
|
||||
#define SCODA_AICR_DAC_ADWL_MASK (0x3 << SCODA_AICR_DAC_ADWL_SHIFT)
|
||||
#define SCODA_AICR_DAC_SLAVE_SHIFT (5)
|
||||
#define SCODA_AICR_DAC_SLAVE_MASK (0x1 << SCODA_AICR_DAC_SLAVE_SHIFT)
|
||||
#define SCODA_AICR_DAC_SLAVE (1 << 5)
|
||||
#define SCODA_AICR_DAC_SB_SHIFT (4)
|
||||
#define SCODA_AICR_DAC_SB_MASK (0x1 << SCODA_AICR_DAC_SB_SHIFT)
|
||||
#define SCODA_AICR_DAC_AUDIOIF_SHIFT (0)
|
||||
#define SCODA_AICR_DAC_AUDIO_MASK (0x3 << SCODA_AICR_DAC_AUDIOIF_SHIFT)
|
||||
#define SCODA_AICR_DAC_AUDIOIF_I2S (0x3)
|
||||
|
||||
/* aicr adc */
|
||||
#define SCODA_AICR_ADC_ADWL_SHIFT (6)
|
||||
#define SCODA_AICR_ADC_ADWL_MASK (0x3 << SCODA_AICR_ADC_ADWL_SHIFT)
|
||||
#define SCODA_AICR_ADC_SB_SHIFT (4)
|
||||
#define SCODA_AICR_ADC_SB_MASK (0x1 << SCODA_AICR_ADC_SB_SHIFT)
|
||||
#define SCODA_AICR_ADC_AUDIOIF_SHIFT (0)
|
||||
#define SCODA_AICR_ADC_AUDIO_MASK (0x3 << SCODA_AICR_ADC_AUDIOIF_SHIFT)
|
||||
#define SCODA_AICR_ADC_AUDIOIF_I2S (0x3)
|
||||
|
||||
/* cr vic */
|
||||
#define SCODA_CR_VIC_SB_SHIFT (0)
|
||||
#define SCODA_CR_VIC_SB_MASK (1 << SCODA_CR_VIC_SB_SHIFT)
|
||||
#define SCODA_CR_VIC_SB_SLEEP_SHIFT (1)
|
||||
#define SCODA_CR_VIC_SB_SLEEP_MASK (1 << SCODA_CR_VIC_SB_SLEEP_SHIFT)
|
||||
|
||||
/* fcr adc/dac */
|
||||
#define SCODA_FCR_FREQ_SHIFT (0)
|
||||
#define SCODA_FCR_FREQ_MASK (0xf << SCODA_FCR_FREQ_SHIFT)
|
||||
|
||||
/* cr dac */
|
||||
#define SCODA_CR_DAC_SMUTE_SHIFT (7)
|
||||
#define SCODA_CR_DAC_SMUTE_MASK (0x1 << SCODA_CR_DAC_SMUTE_SHIFT)
|
||||
#define SCODA_CR_DAC_SB_SHIFT (4)
|
||||
#define SCODA_CR_DAC_SB_MASK (0x1 << SCODA_CR_DAC_SB_SHIFT)
|
||||
#define SCODA_CR_DAC_ZERO_SHIFT (0)
|
||||
#define SCODA_CR_DAC_ZERO_MASK (0x1 << SCODA_CR_DAC_ZERO_SHIFT)
|
||||
|
||||
/* cr dac */
|
||||
#define SCODA_CR_ADC_SMUTE_SHIFT (7)
|
||||
#define SCODA_CR_ADC_SMUTE_MASK (0x1 << SCODA_CR_ADC_SMUTE_SHIFT)
|
||||
#define SCODA_CR_ADC_MIC_SEL_SHIFT (6)
|
||||
#define SCODA_CR_ADC_MIC_SEL_MASK (0x1 << SCODA_CR_ADC_MIC_SEL_SHIFT)
|
||||
#define SCODA_CR_ADC_SB_SHIFT (4)
|
||||
#define SCODA_CR_ADC_SB_MASK (0x1 << SCODA_CR_ADC_SB_SHIFT)
|
||||
#define SCODA_CR_ADC_ZERO_SHIFT (0)
|
||||
#define SCODA_CR_ADC_ZERO_MASK (0x1 << SCODA_CR_ADC_ZERO_SHIFT)
|
||||
|
||||
/* ifr */
|
||||
#define SCODA_IFR_DAC_MUTE_SHIFT (0)
|
||||
#define SCODA_IFR_DAC_MUTE_MASK (0x1 << SCODA_IFR_DAC_MUTE_SHIFT)
|
||||
#define SCODA_IFR_ADC_MUTE_SHIFT (2)
|
||||
#define SCODA_IFR_ADC_MUTE_MASK (0x1 << SCODA_IFR_ADC_MUTE_SHIFT)
|
||||
#define SCODA_IFR_ADAS_LOCK_SHIFT (7)
|
||||
#define SCODA_IFR_ADAS_LOCK_MASK (0x1 << SCODA_IFR_ADAS_LOCK_SHIFT)
|
||||
|
||||
/* cr ck */
|
||||
#define SCODA_CR_CK_MCLK_DIV_SHIFT (6)
|
||||
#define SCODA_CR_CK_MCLK_DIV_MASK (0x1 << SCODA_CR_CK_MCLK_DIV_SHIFT)
|
||||
#define SCODA_CR_CK_SDCLK_SHIFT (4)
|
||||
#define SCODA_CR_CK_SDCLK_MASK (0x1 << SCODA_CR_CK_SDCLK_SHIFT)
|
||||
#define SCODA_CR_CRYSTAL_SHIFT (0)
|
||||
#define SCODA_CR_CRYSTAL_MASK (0xf << SCODA_CR_CRYSTAL_SHIFT)
|
||||
|
||||
/* icr */
|
||||
#define SCODA_ICR_INT_FORM_SHIFT (6)
|
||||
#define SCODA_ICR_INT_FORM_MASK (0x3 << SCODA_ICR_INT_FORM_SHIFT)
|
||||
#define SCODA_ICR_INT_FORM_HIGH (0)
|
||||
#define SCODA_ICR_INT_FORM_LOW (1)
|
||||
|
||||
/* imr */
|
||||
#define SCODA_IMR_COMMON_MASK (0xff)
|
||||
#define SCODA_IMR2_COMMON_MASK (0xff)
|
||||
|
||||
/*For Codec*/
|
||||
#define RGADW (0x4)
|
||||
#define RGDATA (0x8)
|
||||
|
||||
|
||||
static inline void icodec_mapped_reg_set(uint32_t xreg, int xmask, int xval)
|
||||
{
|
||||
int val = readl(xreg);
|
||||
val &= ~(xmask);
|
||||
val |= xval;
|
||||
writel(val, xreg);
|
||||
}
|
||||
|
||||
|
||||
static inline int icodec_mapped_test_bits(uint32_t xreg, int xmask, int xval)
|
||||
{
|
||||
int val = readl(xreg);
|
||||
val &= xmask;
|
||||
return (val == xval);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RGADW
|
||||
*/
|
||||
#define SCODA_RGDIN_BIT (0)
|
||||
#define SCODA_RGDIN_MASK (0xff << SCODA_RGDIN_BIT)
|
||||
#define SCODA_RGADDR_BIT (8)
|
||||
#define SCODA_RGADDR_MASK (0x7f << SCODA_RGADDR_BIT)
|
||||
#define SCODA_RGWR_BIT (16)
|
||||
#define SCODA_RGWR_MASK (0x1 << SCODA_RGWR_BIT)
|
||||
|
||||
#define icodec_test_rw_inval(icodec) \
|
||||
icodec_mapped_test_bits((icodec->mapped_base + RGADW), SCODA_RGWR_MASK, (1 << SCODA_RGWR_BIT))
|
||||
/*
|
||||
* RGDATA
|
||||
*/
|
||||
#define SCODA_RGDOUT_BIT (0)
|
||||
#define SCODA_RGDOUT_MASK (0xff << SCODA_RGDOUT_BIT)
|
||||
#define SCODA_IRQ_BIT (8)
|
||||
#define SCODA_IRQ_MASK (0x1 << SCODA_IRQ_BIT)
|
||||
|
||||
#define icodec_test_irq(icodec) \
|
||||
icodec_mapped_test_bits((icodec->mapped_base + RGDATA), SCODA_IRQ_MASK, (1 << SCODA_IRQ_BIT))
|
||||
|
||||
static inline uint8_t icodec_hw_read_normal(struct jz_icodec *icodec, int reg)
|
||||
{
|
||||
uint32_t mapped_base = icodec->mapped_base;
|
||||
int reval;
|
||||
int timeout = 0xfffff;
|
||||
uint32_t flags;
|
||||
|
||||
while (icodec_test_rw_inval(icodec))
|
||||
{
|
||||
timeout--;
|
||||
if (!timeout)
|
||||
{
|
||||
// rt_kprintf("icodec test_rw_inval timeout\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
icodec_mapped_reg_set((mapped_base + RGADW), SCODA_RGWR_MASK,(0 << SCODA_RGWR_BIT));
|
||||
icodec_mapped_reg_set((mapped_base + RGADW), SCODA_RGADDR_MASK,(reg << SCODA_RGADDR_BIT));
|
||||
|
||||
reval = readl((mapped_base + RGDATA));
|
||||
reval = readl((mapped_base + RGDATA));
|
||||
reval = readl((mapped_base + RGDATA));
|
||||
reval = readl((mapped_base + RGDATA));
|
||||
reval = readl((mapped_base + RGDATA));
|
||||
reval = ((reval & SCODA_RGDOUT_MASK) >> SCODA_RGDOUT_BIT);
|
||||
// rt_kprintf("reg %x = %x\n", reg, reval);
|
||||
|
||||
return (uint8_t) reval;
|
||||
}
|
||||
|
||||
|
||||
static inline int icodec_hw_write_normal(struct jz_icodec *icodec, int reg, int data)
|
||||
{
|
||||
uint32_t mapped_base = icodec->mapped_base;
|
||||
int ret = 0;
|
||||
int timeout = 0xfffff;
|
||||
uint32_t flags;
|
||||
|
||||
|
||||
while (icodec_test_rw_inval(icodec))
|
||||
{
|
||||
timeout--;
|
||||
if (!timeout)
|
||||
{
|
||||
// rt_kprintf("icodec test_rw_inval timeout\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
icodec_mapped_reg_set((mapped_base + RGADW), SCODA_RGDIN_MASK | SCODA_RGADDR_MASK,
|
||||
(data << SCODA_RGDIN_BIT) | (reg << SCODA_RGADDR_BIT));
|
||||
icodec_mapped_reg_set((mapped_base + RGADW), SCODA_RGWR_MASK ,
|
||||
1 << SCODA_RGWR_BIT);
|
||||
|
||||
if (reg != SCODA_REG_IFR && reg != SCODA_REG_IFR2)
|
||||
{
|
||||
ret = icodec_hw_read_normal(icodec, reg);
|
||||
if (data != ret)
|
||||
{
|
||||
// rt_kprintf("icdc write reg %x err exp %x now is %x\n", reg, data, ret);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int icodec_hw_write_extend(struct jz_icodec *icodec, uint8_t sreg, uint8_t sdata)
|
||||
{
|
||||
int creg, cdata, dreg;
|
||||
switch (sreg) {
|
||||
case SCODA_MIX_0 ... SCODA_MIX_4:
|
||||
creg = SCODA_REG_CR_MIX;
|
||||
dreg = SCODA_REG_DR_MIX;
|
||||
sreg -= (SCODA_REG_SR_TR_SRCDAC + 1);
|
||||
break;
|
||||
case SCODA_DAC_AGC0 ... SCODA_DAC_AGC3:
|
||||
creg = SCODA_REG_CR_DAC_AGC;
|
||||
dreg = SCODA_REG_DR_DAC_AGC;
|
||||
sreg -= (SCODA_MIX_4 +1);
|
||||
break;
|
||||
case SCODA_DAC2_AGC0 ... SCODA_DAC2_AGC3:
|
||||
creg = SCODA_REG_CR_DAC2;
|
||||
dreg = SCODA_REG_DR_DAC2_AGC;
|
||||
sreg -= (SCODA_DAC_AGC3 + 1);
|
||||
break;
|
||||
case SCODA_ADC_AGC0 ... SCODA_ADC_AGC4:
|
||||
creg = SCODA_REG_CR_ADC_AGC;
|
||||
dreg = SCODA_REG_DR_ADC_AGC;
|
||||
sreg -= (SCODA_ADC_AGC4 + 1);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
// rt_kprintf("write extend : sreg: %d [0 - 4], creg: %x sdata: %d\n", sreg, creg, sdata);
|
||||
|
||||
cdata = (icodec_hw_read_normal(icodec,creg)&(~0x3f))|((sreg&0x3f)|0x40);
|
||||
|
||||
icodec_hw_write_normal(icodec, creg, cdata);
|
||||
icodec_hw_write_normal(icodec, dreg, sdata);
|
||||
if(sdata!=icodec_hw_read_normal(icodec,dreg))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t icodec_hw_read_extend(struct jz_icodec *icodec, uint8_t sreg)
|
||||
{
|
||||
int creg, cdata, dreg, ddata;
|
||||
switch (sreg)
|
||||
{
|
||||
case SCODA_MIX_0 ... SCODA_MIX_4:
|
||||
creg = SCODA_REG_CR_MIX;
|
||||
dreg = SCODA_REG_DR_MIX;
|
||||
sreg -= (SCODA_REG_SR_TR_SRCDAC + 1);
|
||||
break;
|
||||
case SCODA_DAC_AGC0 ... SCODA_DAC_AGC3:
|
||||
creg = SCODA_REG_CR_DAC_AGC;
|
||||
dreg = SCODA_REG_DR_DAC_AGC;
|
||||
sreg -= (SCODA_MIX_4 +1);
|
||||
break;
|
||||
case SCODA_DAC2_AGC0 ... SCODA_DAC2_AGC3:
|
||||
creg = SCODA_REG_CR_DAC2;
|
||||
dreg = SCODA_REG_DR_DAC2_AGC;
|
||||
sreg -= (SCODA_DAC_AGC3 + 1);
|
||||
break;
|
||||
case SCODA_ADC_AGC0 ... SCODA_ADC_AGC4:
|
||||
creg = SCODA_REG_CR_ADC_AGC;
|
||||
dreg = SCODA_REG_DR_ADC_AGC;
|
||||
sreg -= (SCODA_ADC_AGC4 + 1);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
cdata = (icodec_hw_read_normal(icodec, creg) & (~0x7f)) | (sreg & 0x3f);
|
||||
icodec_hw_write_normal(icodec, creg, cdata);
|
||||
ddata = icodec_hw_read_normal(icodec, dreg);
|
||||
|
||||
return (uint8_t) ddata;
|
||||
}
|
||||
|
||||
|
||||
static inline uint8_t icodec_hw_read(struct jz_icodec *icodec, int reg)
|
||||
{
|
||||
if (reg > SCODA_REG_SR_TR_SRCDAC)
|
||||
return icodec_hw_read_extend(icodec, reg);
|
||||
else
|
||||
return icodec_hw_read_normal(icodec, reg);
|
||||
}
|
||||
static inline int icodec_hw_write(struct jz_icodec *icodec, int reg, int data)
|
||||
{
|
||||
if (reg > SCODA_REG_SR_TR_SRCDAC)
|
||||
return icodec_hw_write_extend(icodec, reg, data);
|
||||
else
|
||||
return icodec_hw_write_normal(icodec, reg, data);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _DRV_CODEC_ICODEC_H_ */
|
||||
428
bsp/x1000/drivers/audio/drv_dmic.c
Normal file
428
bsp/x1000/drivers/audio/drv_dmic.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* File : drv_dmic.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <drivers/audio.h>
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
# include <finsh.h>
|
||||
#endif
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_gpio.h"
|
||||
#include "drv_dma.h"
|
||||
#include "drv_aic.h"
|
||||
#include "drv_clock.h"
|
||||
#include "drv_dmic.h"
|
||||
#include "dma.h"
|
||||
#include "audio_pipe.h"
|
||||
|
||||
#define DMIC_DEBUG 0
|
||||
#if DMIC_DEBUG
|
||||
# define DMIC_DBG(...) rt_kprintf("[DMIC]"),rt_kprintf(__VA_ARGS__)
|
||||
#else
|
||||
# define DMIC_DBG(...)
|
||||
#endif
|
||||
|
||||
#define DMIC_DMA_RX_CHAN 4
|
||||
#define DMIC_FIFO_DEPTH 64
|
||||
#define JZ_DMIC_FORMATS 16
|
||||
#define JZ_DMIC_RATE (8000)
|
||||
ALIGN(32) rt_uint32_t _g_dmic_dma_buffer[DMIC_DMA_PAGE_NUM*DMIC_DMA_PAGE_SIZE/sizeof(rt_uint32_t)];
|
||||
static struct jz_dmic _g_jz_dmic=
|
||||
{
|
||||
.io_base = DMIC_BASE,
|
||||
.dma_buf = (rt_uint8_t *)_g_dmic_dma_buffer,
|
||||
.dma_offset = 0,
|
||||
};
|
||||
|
||||
static void dump_dmic_registers(void)
|
||||
{
|
||||
struct jz_dmic *jz_dmic = &_g_jz_dmic;
|
||||
rt_kprintf("DMICCR0 %p : 0x%08x\n", (jz_dmic->io_base+DMICCR0),dmic_read_reg(jz_dmic, DMICCR0));
|
||||
rt_kprintf("DMICGCR %p : 0x%08x\n", (jz_dmic->io_base+DMICGCR),dmic_read_reg(jz_dmic, DMICGCR));
|
||||
rt_kprintf("DMICIMR %p : 0x%08x\n", (jz_dmic->io_base+DMICIMR),dmic_read_reg(jz_dmic, DMICIMR));
|
||||
rt_kprintf("DMICINTCR %p : 0x%08x\n", (jz_dmic->io_base+DMICINTCR),dmic_read_reg(jz_dmic, DMICINTCR));
|
||||
rt_kprintf("DMICTRICR %p : 0x%08x\n", (jz_dmic->io_base+DMICTRICR),dmic_read_reg(jz_dmic, DMICTRICR));
|
||||
rt_kprintf("DMICTHRH %p : 0x%08x\n", (jz_dmic->io_base+DMICTHRH),dmic_read_reg(jz_dmic, DMICTHRH));
|
||||
rt_kprintf("DMICTHRL %p : 0x%08x\n", (jz_dmic->io_base+DMICTHRL),dmic_read_reg(jz_dmic, DMICTHRL));
|
||||
rt_kprintf("DMICTRIMMAX %p : 0x%08x\n", (jz_dmic->io_base+DMICTRIMMAX),dmic_read_reg(jz_dmic, DMICTRIMMAX));
|
||||
rt_kprintf("DMICTRINMAX %p : 0x%08x\n", (jz_dmic->io_base+DMICTRINMAX),dmic_read_reg(jz_dmic, DMICTRINMAX));
|
||||
rt_kprintf("DMICDR %p : 0x%08x\n", (jz_dmic->io_base+DMICDR),dmic_read_reg(jz_dmic, DMICDR));
|
||||
rt_kprintf("DMICFTHR %p : 0x%08x\n", (jz_dmic->io_base+DMICFTHR),dmic_read_reg(jz_dmic, DMICFTHR));
|
||||
rt_kprintf("DMICFSR %p : 0x%08x\n", (jz_dmic->io_base+DMICFSR),dmic_read_reg(jz_dmic, DMICFSR));
|
||||
rt_kprintf("DMICCGDIS %p : 0x%08x\n", (jz_dmic->io_base+DMICCGDIS),dmic_read_reg(jz_dmic, DMICCGDIS));
|
||||
return;
|
||||
}
|
||||
MSH_CMD_EXPORT(dump_dmic_registers,"dump dmic regs...\n");
|
||||
|
||||
int jz_dmic_set_rate(struct jz_dmic* dmic, int rate)
|
||||
{
|
||||
// rt_kprintf("rate = %d\n",rate);
|
||||
switch (rate)
|
||||
{
|
||||
case 8000:
|
||||
__dmic_set_sr_8k(dmic);
|
||||
break;
|
||||
case 16000:
|
||||
__dmic_set_sr_16k(dmic);
|
||||
break;
|
||||
case 48000:
|
||||
__dmic_set_sr_48k(dmic);
|
||||
break;
|
||||
default:
|
||||
DMIC_DBG("dmic unsupport rate %d\n", rate);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jz_dmic_set_channels(struct jz_dmic* dmic, int channels)
|
||||
{
|
||||
if (channels > 4)
|
||||
channels = 4;
|
||||
if (channels <= 1)
|
||||
channels = 1;
|
||||
|
||||
__dmic_set_chnum(dmic,channels - 1);
|
||||
}
|
||||
|
||||
|
||||
int jz_dmic_set_record_volume(struct jz_dmic* dmic, int vol)
|
||||
{
|
||||
if(vol >= 32)
|
||||
vol = 31;
|
||||
__dmic_set_gcr(dmic,vol);
|
||||
|
||||
dmic->record_gain = vol;
|
||||
}
|
||||
|
||||
static void jz_dmic_dma_complete(struct rt_dma_channel *dmac, struct dma_message *msg)
|
||||
{
|
||||
rt_base_t level;
|
||||
if(msg->complete_cb)
|
||||
msg->complete_cb(msg->complete_arg,msg->dst_addr);
|
||||
|
||||
/* restart DMA Job */
|
||||
rt_dma_trans_message(dmac,msg);
|
||||
}
|
||||
|
||||
|
||||
void jz_dmic_start_recv(struct jz_dmic* dmic,void (*rx_callback)(void *,void *), void *rx_arg)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_uint32_t i;
|
||||
struct dma_message message;
|
||||
__dmic_enable_rdms(dmic);
|
||||
__dmic_enable(dmic);
|
||||
level = rt_hw_interrupt_disable();
|
||||
dmic->dma_offset = 0;
|
||||
dmic->dma_buf = (rt_uint8_t *)_g_dmic_dma_buffer;
|
||||
|
||||
for (i = 0; i < DMIC_DMA_PAGE_NUM; ++i)
|
||||
{
|
||||
message.src_addr = (uint8_t *) (DMIC_BASE + DMICDR);
|
||||
message.src_option = RT_DMA_ADDR_FIX;
|
||||
message.dst_addr = (uint8_t *) (dmic->dma_buf + DMIC_DMA_PAGE_SIZE * i);
|
||||
message.dst_option = RT_DMA_ADDR_INC;
|
||||
message.t_size = DMIC_DMA_PAGE_SIZE;
|
||||
message.t_mode = JZDMA_REQ_DMIC_RX;
|
||||
/* init callback */
|
||||
message.complete_cb = rx_callback;
|
||||
message.complete_arg = rx_arg;
|
||||
rt_dma_trans_message(dmic->rx_dmac,&message);
|
||||
}
|
||||
rt_hw_interrupt_enable(level);
|
||||
return ;
|
||||
}
|
||||
|
||||
void jz_dmic_stop_recv(struct jz_dmic* dmic)
|
||||
{
|
||||
if (__dmic_is_enable_rdms(dmic))
|
||||
{
|
||||
__dmic_disable_rdms(dmic);
|
||||
}
|
||||
__dmic_disable(dmic);
|
||||
}
|
||||
|
||||
|
||||
void dmic_rx_complete(void *data,void *pbuf)
|
||||
{
|
||||
struct jz_dmic *dmic = (struct jz_dmic *)data;
|
||||
|
||||
rt_device_write(RT_DEVICE(&dmic->pipe),0,pbuf,DMIC_DMA_PAGE_SIZE);
|
||||
}
|
||||
|
||||
#define CFG_DMIC_PIPE_SIZE (2 * 1024)
|
||||
struct jz_dmic* rt_hw_dmic_init(void)
|
||||
{
|
||||
struct jz_dmic *dmic = &_g_jz_dmic;
|
||||
|
||||
//init pipe for record
|
||||
{
|
||||
rt_uint8_t *buf = rt_malloc(CFG_DMIC_PIPE_SIZE);
|
||||
|
||||
if(buf == RT_NULL)
|
||||
{
|
||||
rt_kprintf("request pipe memory error\n");
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
rt_audio_pipe_init(&dmic->pipe,"recdmic",RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD,buf,(CFG_DMIC_PIPE_SIZE));
|
||||
|
||||
rt_device_open(RT_DEVICE(&dmic->pipe),RT_DEVICE_OFLAG_RDONLY);
|
||||
}
|
||||
|
||||
/* GPIO config
|
||||
* PB05 -> FUNC1 DMIC1_IN
|
||||
* PB21 -> FUNC0 DMIC_CLK
|
||||
* PB22 -> FUNC0 DMIC0_IN
|
||||
* */
|
||||
gpio_set_func(GPIO_PORT_B,GPIO_Pin_5,GPIO_FUNC_1);
|
||||
gpio_set_func(GPIO_PORT_B,GPIO_Pin_21,GPIO_FUNC_0);
|
||||
gpio_set_func(GPIO_PORT_B,GPIO_Pin_22,GPIO_FUNC_0);
|
||||
|
||||
/* enable clock */
|
||||
dmic->clk_gate = clk_get("dmic");
|
||||
if (dmic->clk_gate == RT_NULL)
|
||||
{
|
||||
DMIC_DBG("Failed to get dmic gate clock \n");
|
||||
return RT_NULL;
|
||||
}
|
||||
clk_enable(dmic->clk_gate);
|
||||
|
||||
/*gain: 0, ..., e*/
|
||||
__dmic_reset(dmic);
|
||||
while (__dmic_get_reset(dmic)) ;
|
||||
|
||||
jz_dmic_set_rate(dmic, 8000);
|
||||
__dmic_set_chnum(dmic,0); //mono
|
||||
__dmic_enable_hpf1(dmic);
|
||||
__dmic_set_gcr(dmic, 27);
|
||||
__dmic_mask_all_int(dmic);
|
||||
__dmic_enable_pack(dmic);
|
||||
__dmic_enable_sw_lr(dmic);
|
||||
__dmic_enable_lp(dmic);
|
||||
__dmic_disable_lp(dmic);
|
||||
__dmic_set_request(dmic, 48);
|
||||
__dmic_enable_hpf2(dmic);
|
||||
__dmic_set_thr_high(dmic, 32);
|
||||
__dmic_set_thr_low(dmic, 16);
|
||||
__dmic_enable_tri(dmic);
|
||||
|
||||
|
||||
//config DMA
|
||||
{
|
||||
int trigger;
|
||||
|
||||
/* DMA config */
|
||||
struct dma_config config;
|
||||
dmic->rx_dmac = rt_dma_get_channel(DMIC_DMA_RX_CHAN);
|
||||
if (dmic->rx_dmac != RT_NULL)
|
||||
{
|
||||
DMIC_DBG("config dmic dma rx channel...\n");
|
||||
config.direction = RT_DMA_DEV_TO_MEM;
|
||||
config.src_addr_width = RT_DMA_BUSWIDTH_2_BYTES;
|
||||
config.src_maxburst = (DMIC_FIFO_DEPTH * RT_DMA_BUSWIDTH_2_BYTES) / 2;
|
||||
config.dst_addr_width = RT_DMA_BUSWIDTH_2_BYTES;
|
||||
config.dst_maxburst = (64 * 1024);
|
||||
rt_dma_configture(dmic->rx_dmac, &config);
|
||||
|
||||
dmic->rx_dmac->start = RT_NULL;
|
||||
dmic->rx_dmac->complete = jz_dmic_dma_complete;
|
||||
}
|
||||
trigger = config.src_maxburst / config.src_addr_width;
|
||||
__dmic_set_request(dmic, trigger);
|
||||
}
|
||||
|
||||
jz_dmic_start_recv(dmic,dmic_rx_complete,dmic);
|
||||
|
||||
return dmic;
|
||||
|
||||
_error_exit:
|
||||
__dmic_disable(dmic);
|
||||
|
||||
rt_audio_pipe_detach(&dmic->pipe);
|
||||
|
||||
clk_disable(dmic->clk_gate);
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
//INIT_ENV_EXPORT(rt_hw_dmic_init);
|
||||
|
||||
|
||||
struct speech_wav_header
|
||||
{
|
||||
char riff_id[4]; //"RIFF"
|
||||
uint32_t size0; //file len - 8
|
||||
char wave_fmt[8]; //"WAVEfmt "
|
||||
uint32_t size1; //0x10
|
||||
uint16_t fmttag; //0x01
|
||||
uint16_t channel; //1
|
||||
uint32_t samplespersec; //8000
|
||||
uint32_t bytepersec; //8000 * 2
|
||||
uint16_t blockalign; //1 * 16 / 8
|
||||
uint16_t bitpersamples; //16
|
||||
char data_id[4]; //"data"
|
||||
uint32_t size2; //file len - 44
|
||||
};
|
||||
|
||||
static void speech_wav_init_header(struct speech_wav_header *header,rt_uint16_t Channels,int SamplesPerSec,int BitsPerSample)
|
||||
{
|
||||
strcpy(header->riff_id, "RIFF");
|
||||
header->size0 = 0; // Final file size not known yet, write 0
|
||||
strcpy(header->wave_fmt, "WAVEfmt ");
|
||||
header->size1 = 16; // Sub-chunk size, 16 for PCM
|
||||
header->fmttag = 1; // AudioFormat, 1 for PCM
|
||||
header->channel = Channels; // Number of channels, 1 for mono, 2 for stereo
|
||||
header->samplespersec = SamplesPerSec; // Sample rate
|
||||
header->bytepersec = SamplesPerSec * BitsPerSample * Channels / 8; //Byte rate
|
||||
header->blockalign = Channels * BitsPerSample / 8; // Block align, NumberOfChannels*BitsPerSample/8
|
||||
header->bitpersamples = BitsPerSample;
|
||||
strcpy(header->data_id, "data");
|
||||
header->size2 = 0;
|
||||
}
|
||||
|
||||
static void speech_wav_upgrade_size(struct speech_wav_header *header,rt_uint32_t paylodSize)
|
||||
{
|
||||
header->size0 = paylodSize + 36;
|
||||
header->size2 = paylodSize;
|
||||
}
|
||||
|
||||
|
||||
#include <finsh.h>
|
||||
#include <dfs_posix.h>
|
||||
|
||||
rt_uint8_t rec_buff[2048];
|
||||
int dmic_record(int samplingrates)
|
||||
{
|
||||
struct jz_dmic *dmic = &_g_jz_dmic;
|
||||
rt_device_t dmic_pipe;
|
||||
struct speech_wav_header wav_header;
|
||||
rt_uint32_t wav_len = 0;
|
||||
char *file_name;
|
||||
int fd;
|
||||
int i = 0;
|
||||
int rdlen, wrlen;
|
||||
|
||||
rt_kprintf("samplingrates = %d\n",samplingrates);
|
||||
if((samplingrates != 8000) && (samplingrates != 16000))
|
||||
{
|
||||
rt_kprintf("un-support this samplingrates\n");
|
||||
return -RT_EIO;
|
||||
}
|
||||
|
||||
dmic_pipe = rt_device_find("recdmic");
|
||||
if(dmic_pipe == RT_NULL)
|
||||
{
|
||||
rt_kprintf("can't find the record device\n");
|
||||
return -RT_ERROR ;
|
||||
}
|
||||
|
||||
rt_kprintf("pls hold WAKE key to start record...\n");
|
||||
while(gpio_get_value(GPIO_PORT_B, GPIO_Pin_31) == 1)
|
||||
rt_thread_delay(100);
|
||||
rt_kprintf("OK,start record....\n");
|
||||
if(samplingrates == 8000)
|
||||
file_name = "/appfs/dmic8k.wav";
|
||||
else
|
||||
file_name = "/appfs/dmic16k.wav";
|
||||
|
||||
fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
rt_kprintf("open file for write failed\n");
|
||||
return -RT_EIO;
|
||||
}
|
||||
|
||||
speech_wav_init_header(&wav_header,1,samplingrates,16);
|
||||
write(fd, &wav_header, wav_len);
|
||||
|
||||
jz_dmic_set_rate(dmic,samplingrates);
|
||||
wav_len = 0;
|
||||
while(i++ < 1000)
|
||||
{
|
||||
rdlen = rt_device_read(dmic_pipe,0,rec_buff,sizeof(rec_buff));
|
||||
|
||||
wrlen = write(fd, rec_buff, rdlen);
|
||||
if (wrlen != rdlen)
|
||||
{
|
||||
rt_kprintf("write data failed\n");
|
||||
close(fd);
|
||||
|
||||
return -RT_EIO;
|
||||
}
|
||||
|
||||
wav_len += wrlen;
|
||||
|
||||
if(gpio_get_value(GPIO_PORT_B, GPIO_Pin_31) == 1)
|
||||
break;
|
||||
}
|
||||
rt_kprintf("record complete...\n");
|
||||
|
||||
//upgrage wav header
|
||||
lseek(fd,0,SEEK_SET);
|
||||
speech_wav_upgrade_size(&wav_header,wav_len);
|
||||
write(fd, &wav_header, sizeof(struct speech_wav_header));
|
||||
|
||||
close(fd);
|
||||
|
||||
rt_kprintf("WAV file saved ok!\n");
|
||||
}
|
||||
FINSH_FUNCTION_EXPORT(dmic_record,dmic record test);
|
||||
|
||||
#if 0
|
||||
int dmic_test(void)
|
||||
{
|
||||
rt_device_t device;
|
||||
int i = 0;
|
||||
|
||||
device = rt_device_find("recdmic");
|
||||
if(device == RT_NULL)
|
||||
{
|
||||
rt_kprintf("can't find the record device\n");
|
||||
return -RT_ERROR ;
|
||||
}
|
||||
|
||||
audio_device_set_rate(8000);
|
||||
|
||||
while(i++ < 1000)
|
||||
{
|
||||
int len;
|
||||
uint8_t *sendBuf;
|
||||
|
||||
sendBuf = audio_device_get_buffer(&len);
|
||||
len = rt_device_read(device,0,sendBuf,len);
|
||||
|
||||
audio_device_write(sendBuf,len);
|
||||
}
|
||||
|
||||
rt_kprintf("dmic test complete...\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(dmic_test,dmic test ....);
|
||||
#endif
|
||||
262
bsp/x1000/drivers/audio/drv_dmic.h
Normal file
262
bsp/x1000/drivers/audio/drv_dmic.h
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* drv_dmic.h
|
||||
*
|
||||
* Created on: 2017Äê1ÔÂ11ÈÕ
|
||||
* Author: Urey
|
||||
*/
|
||||
|
||||
#ifndef _DRV_DMIC_H_
|
||||
#define _DRV_DMIC_H_
|
||||
|
||||
/*
|
||||
* File : drv_dmic.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
|
||||
#include <dma.h>
|
||||
#include "audio_pipe.h"
|
||||
#define DMIC_DMA_PAGE_SIZE 512
|
||||
#define DMIC_DMA_PAGE_NUM RT_DMA_MAX_NODES
|
||||
struct jz_dmic
|
||||
{
|
||||
struct rt_audio_pipe pipe;
|
||||
struct rt_audio_configure record_config;
|
||||
uint32_t io_base;
|
||||
|
||||
struct clk *clk_gate;
|
||||
struct rt_dma_channel *rx_dmac;
|
||||
|
||||
rt_uint8_t *dma_buf;
|
||||
rt_uint32_t dma_offset;
|
||||
|
||||
/* record */
|
||||
int record_gain;
|
||||
};
|
||||
static inline void dmic_write_reg(struct jz_dmic *dmic, uint32_t reg, uint32_t val)
|
||||
{
|
||||
writel(val, dmic->io_base + reg);
|
||||
}
|
||||
static inline uint32_t dmic_read_reg(struct jz_dmic *jz_dmic, unsigned int reg)
|
||||
{
|
||||
return readl(jz_dmic->io_base + reg);
|
||||
}
|
||||
#define dmic_set_reg(dmic, addr, val, mask, offset)\
|
||||
do { \
|
||||
int tmp_val = val; \
|
||||
int read_val = dmic_read_reg(dmic, addr); \
|
||||
read_val &= (~mask); \
|
||||
tmp_val = ((tmp_val << offset) & mask); \
|
||||
tmp_val |= read_val; \
|
||||
dmic_write_reg(dmic, addr, tmp_val); \
|
||||
}while(0)
|
||||
#define dmic_get_reg(dmic, addr, mask, offset) \
|
||||
((dmic_read_reg(dmic, addr) & mask) >> offset)
|
||||
/*********************************************************************************************************
|
||||
**
|
||||
*********************************************************************************************************/
|
||||
#define DMICCR0 0x00
|
||||
#define DMICGCR 0x04
|
||||
#define DMICIMR 0x08
|
||||
#define DMICINTCR 0x0c
|
||||
#define DMICTRICR 0x10
|
||||
#define DMICTHRH 0x14
|
||||
#define DMICTHRL 0x18
|
||||
#define DMICTRIMMAX 0x1c
|
||||
#define DMICTRINMAX 0x20
|
||||
#define DMICDR 0x30
|
||||
#define DMICFTHR 0x34
|
||||
#define DMICFSR 0x38
|
||||
#define DMICCGDIS 0x50
|
||||
/* DMICCR0 */
|
||||
#define DMIC_RESET 31
|
||||
#define DMIC_RESET_MASK (0x1 << DMIC_RESET)
|
||||
#define DMIC_RESET_TRI 30
|
||||
#define DMIC_RESET_TRI_MASK (0x1 << DMIC_RESET_TRI)
|
||||
#define DMIC_CHNUM 16
|
||||
#define DMIC_CHNUM_MASK (0x7 << DMIC_CHNUM)
|
||||
#define DMIC_UNPACK_MSB 13
|
||||
#define DMIC_UNPACK_MSB_MASK (0x1 << DMIC_UNPACK_MSB)
|
||||
#define DMIC_UNPACK_DIS 12
|
||||
#define DMIC_UNPACK_DIS_MASK (0x1 << DMIC_UNPACK_DIS)
|
||||
#define DMIC_SW_LR 11
|
||||
#define DMIC_SW_LR_MASK (0x1 << DMIC_SW_LR)
|
||||
#define DMIC_SPLIT_DI 10
|
||||
#define DMIC_SPLIT_DI_MASK (0x1 << DMIC_SPLIT_DI)
|
||||
#define DMIC_PACK_EN 8
|
||||
#define DMIC_PACK_EN_MASK (0x1 << DMIC_PACK_EN)
|
||||
#define DMIC_SR 6
|
||||
#define DMIC_SR_MASK (0x3 << DMIC_SR)
|
||||
#define DMIC_LP_MODE 3
|
||||
#define DMIC_LP_MODE_MASK (0x1 << DMIC_LP_MODE)
|
||||
#define DMIC_HPF1_MODE 2
|
||||
#define DMIC_HPF1_MODE_MASK (0x1 << DMIC_HPF1_MODE)
|
||||
#define DMIC_TRI_EN 1
|
||||
#define DMIC_TRI_EN_MASK (0x1 << DMIC_TRI_EN)
|
||||
#define DMIC_EN 0
|
||||
#define DMIC_EN_MASK (0x1 << DMIC_EN)
|
||||
#define __dmic_reset(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_RESET_MASK,DMIC_RESET)
|
||||
#define __dmic_get_reset(dmic)\
|
||||
dmic_get_reg(dmic,DMICCR0,DMIC_RESET_MASK,DMIC_RESET)
|
||||
#define __dmic_reset_tri(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_RESET_TRI_MASK,DMIC_RESET_TRI)
|
||||
#define __dmic_set_chnum(dmic,n)\
|
||||
dmic_set_reg(dmic,DMICCR0,n,DMIC_CHNUM_MASK,DMIC_CHNUM)
|
||||
#define __dmic_get_chnum(dmic,n)\
|
||||
dmic_set_reg(dmic,DMICCR0,DMIC_CHNUM_MASK,DMIC_CHNUM)
|
||||
#define __dmic_unpack_msb(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_UNPACK_MSB_MASK,DMIC_UNPACK_MSB)
|
||||
#define __dmic_unpack_dis(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_UNPACK_DIS_MASK,DMIC_UNPACK_DIS)
|
||||
#define __dmic_enable_sw_lr(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_SW_LR_MASK,DMIC_SW_LR)
|
||||
#define __dmic_disable_sw_lr(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,0,DMIC_SW_LR_MASK,DMIC_SW_LR)
|
||||
#define __dmic_split(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_SPLIT_DI_MASK,DMIC_SPLIT_DI)
|
||||
#define __dmic_enable_pack(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_PACK_EN_MASK,DMIC_PACK_EN)
|
||||
#define __dmic_set_sr(dmic,n)\
|
||||
dmic_set_reg(dmic,DMICCR0,n,DMIC_SR_MASK,DMIC_SR)
|
||||
#define __dmic_set_sr_8k(dmic)\
|
||||
__dmic_set_sr(dmic,0)
|
||||
#define __dmic_set_sr_16k(dmic)\
|
||||
__dmic_set_sr(dmic,1)
|
||||
#define __dmic_set_sr_48k(dmic)\
|
||||
__dmic_set_sr(dmic,2)
|
||||
#define __dmic_enable_lp(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_LP_MODE_MASK,DMIC_LP_MODE)
|
||||
#define __dmic_disable_lp(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,0,DMIC_LP_MODE_MASK,DMIC_LP_MODE)
|
||||
#define __dmic_enable_hpf1(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_HPF1_MODE_MASK,DMIC_HPF1_MODE)
|
||||
#define __dmic_disable_hpf1(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,0,DMIC_HPF1_MODE_MASK,DMIC_HPF1_MODE)
|
||||
#define __dmic_is_enable_tri(dmic)\
|
||||
dmic_get_reg(dmic,DMICCR0,DMIC_TRI_EN_MASK,DMIC_TRI_EN)
|
||||
#define __dmic_enable_tri(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_TRI_EN_MASK,DMIC_TRI_EN)
|
||||
#define __dmic_disable_tri(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,0,DMIC_TRI_EN_MASK,DMIC_TRI_EN)
|
||||
#define __dmic_is_enable(dmic)\
|
||||
dmic_get_reg(dmic,DMICCR0,DMIC_EN_MASK,DMIC_EN)
|
||||
#define __dmic_enable(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,1,DMIC_EN_MASK,DMIC_EN)
|
||||
#define __dmic_disable(dmic)\
|
||||
dmic_set_reg(dmic,DMICCR0,0,DMIC_EN_MASK,DMIC_EN)
|
||||
/*DMICGCR*/
|
||||
#define DMIC_GCR 0
|
||||
#define DMIC_GCR_MASK (0Xf << DMIC_GCR)
|
||||
#define __dmic_set_gcr(dmic,n)\
|
||||
dmic_set_reg(dmic, DMICGCR, n, DMIC_GCR_MASK,DMIC_GCR)
|
||||
/* DMICIMR */
|
||||
#define DMIC_FIFO_TRIG_MASK 5
|
||||
#define DMIC_FIFO_TRIG_MSK (1 << DMIC_FIFO_TRIG_MASK)
|
||||
#define DMIC_WAKE_MASK 4
|
||||
#define DMIC_WAKE_MSK (1 << DMIC_WAKE_MASK)
|
||||
#define DMIC_EMPTY_MASK 3
|
||||
#define DMIC_EMPTY_MSK (1 << DMIC_EMPTY_MASK)
|
||||
#define DMIC_FULL_MASK 2
|
||||
#define DMIC_FULL_MSK (1 << DMIC_FULL_MASK)
|
||||
#define DMIC_PRERD_MASK 1
|
||||
#define DMIC_PRERD_MSK (1 << DMIC_PRERD_MASK)
|
||||
#define DMIC_TRI_MASK 0
|
||||
#define DMIC_TRI_MSK (1 << DMIC_TRI_MASK)
|
||||
#define __dmic_mask_all_int(dmic)\
|
||||
dmic_set_reg(dmic,DMICIMR, 0x3f, 0x3f, 0)
|
||||
/*DMICINTCR*/
|
||||
#define DMIC_FIFO_TRIG_FLAG 4
|
||||
#define DMIC_FIFO_TRIG_FLAG_MASK (1 << DMIC_WAKE_FLAG)
|
||||
#define DMIC_WAKE_FLAG 4
|
||||
#define DMIC_WAKE_FLAG_MASK (1 << DMIC_WAKE_FLAG)
|
||||
#define DMIC_EMPTY_FLAG 3
|
||||
#define DMIC_EMPTY_FLAG_MASK (1 << DMIC_EMPTY_FLAG)
|
||||
#define DMIC_FULL_FLAG 2
|
||||
#define DMIC_FULL_FLAG_MASK (1 << DMIC_FULL_FLAG)
|
||||
#define DMIC_PRERD_FLAG 1
|
||||
#define DMIC_PRERD_FLAG_MASK (1 << DMIC_PRERD_FLAG)
|
||||
#define DMIC_TRI_FLAG 0
|
||||
#define DMIC_TRI_FLAG_MASK (1 << DMIC_TRI_FLAG)
|
||||
/*DMICTRICR*/
|
||||
#define DMIC_TRI_MODE 16
|
||||
#define DMIC_TRI_MODE_MASK (0xf << DMIC_TRI_MODE)
|
||||
#define DMIC_TRI_DEBUG 4
|
||||
#define DMIC_TRI_DEBUG_MASK (0x1 << DMIC_TRI_DEBUG)
|
||||
#define DMIC_HPF2_EN 3
|
||||
#define DMIC_HPF2_EN_MASK (0x1 << DMIC_HPF2_EN)
|
||||
#define DMIC_PREFETCH 1
|
||||
#define DMIC_PREFETCH_MASK (0x3 << DMIC_PREFETCH)
|
||||
#define DMIC_TRI_CLR 0
|
||||
#define DMIC_TRI_CLR_MASK (0x1 << DMIC_TRI_CLR)
|
||||
#define __dmic_enable_hpf2(dmic) \
|
||||
dmic_set_reg(dmic, DMICTRICR, 1, DMIC_HPF2_EN_MASK, DMIC_HPF2_EN)
|
||||
#define __dmic_disable_hpf2(dmic) \
|
||||
dmic_set_reg(dmic, DMICTRICR, 0, DMIC_HPF2_EN_MASK, DMIC_HPF2_EN)
|
||||
/*DMICTHRH*/
|
||||
#define DMIC_THR_H 0
|
||||
#define DMIC_THR_H_MASK (0xfffff << DMIC_THR_H)
|
||||
#define __dmic_set_thr_high(dmic,n) \
|
||||
dmic_set_reg(dmic, DMICTHRH, n, DMIC_THR_H_MASK, DMIC_THR_H)
|
||||
/*DMICTHRL*/
|
||||
#define DMIC_THR_L 0
|
||||
#define DMIC_THR_L_MASK (0xfffff << DMIC_THR_L)
|
||||
#define __dmic_set_thr_low(dmic,n) \
|
||||
dmic_set_reg(dmic, DMICTHRL, n, DMIC_THR_L_MASK, DMIC_THR_L)
|
||||
/* DMICTRIMMAX */
|
||||
#define DMIC_M_MAX 0
|
||||
#define DMIC_M_MAX_MASK (0xffffff << DMIC_M_MAX)
|
||||
/* DMICTRINMAX */
|
||||
#define DMIC_N_MAX 0
|
||||
#define DMIC_N_MAX_MASK (0xffff << DMIC_N_MAX)
|
||||
/* DMICFTHR */
|
||||
#define DMIC_RDMS 31
|
||||
#define DMIC_RDMS_MASK (0x1 << DMIC_RDMS)
|
||||
#define DMIC_FIFO_THR 0
|
||||
#define DMIC_FIFO_THR_MASK (0x3f << DMIC_FIFO_THR)
|
||||
#define __dmic_is_enable_rdms(dmic)\
|
||||
dmic_get_reg(dmic, DMICFTHR,DMIC_RDMS_MASK,DMIC_RDMS)
|
||||
#define __dmic_enable_rdms(dmic)\
|
||||
dmic_set_reg(dmic, DMICFTHR,1,DMIC_RDMS_MASK,DMIC_RDMS)
|
||||
#define __dmic_disable_rdms(dmic)\
|
||||
dmic_set_reg(dmic, DMICFTHR,1,DMIC_RDMS_MASK,DMIC_RDMS)
|
||||
#define __dmic_set_request(dmic,n) \
|
||||
dmic_set_reg(dmic, DMICFTHR, n, DMIC_FIFO_THR_MASK, DMIC_FIFO_THR)
|
||||
/*DMICFSR*/
|
||||
#define DMIC_FULLS 19
|
||||
#define DMIC_FULLS_MASK (0x1 << DMIC_FULLS)
|
||||
#define DMIC_TRIGS 18
|
||||
#define DMIC_TRIGS_MASK (0x1 << DMIC_TRIGS)
|
||||
#define DMIC_PRERDS 17
|
||||
#define DMIC_PRERDS_MASK (0x1 << DMIC_PRERDS)
|
||||
#define DMIC_EMPTYS 16
|
||||
#define DMIC_EMPTYS_MASK (0x1 << DMIC_EMPTYS)
|
||||
#define DMIC_FIFO_LVL 0
|
||||
#define DMIC_FIFO_LVL_MASK (0x3f << DMIC_FIFO_LVL)
|
||||
/*********************************************************************************************************
|
||||
**
|
||||
*********************************************************************************************************/
|
||||
struct jz_dmic* rt_hw_dmic_init(void);
|
||||
int jz_dmic_set_rate(struct jz_dmic* dmic, int rate);
|
||||
int jz_dmic_set_gain(struct jz_dmic* dmic, int vol);
|
||||
int jz_dmic_set_channels(struct jz_dmic* dmic, int channels);
|
||||
|
||||
#endif /* _DRV_DMIC_H_ */
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_clock.h"
|
||||
@@ -32,12 +33,38 @@
|
||||
|
||||
extern void rt_hw_cache_init(void);
|
||||
|
||||
extern unsigned char _iramcopy;
|
||||
extern unsigned char _iramstart;
|
||||
extern unsigned char _iramend;
|
||||
|
||||
#ifdef RT_USING_CPLUSPLUS
|
||||
int cplusplus_system_init(void)
|
||||
{
|
||||
typedef void (*pfunc) ();
|
||||
extern pfunc __ctors_start__[];
|
||||
extern pfunc __ctors_end__[];
|
||||
pfunc *p;
|
||||
for (p = __ctors_end__ - 2; p > __ctors_start__; )
|
||||
{
|
||||
(*p)();
|
||||
p--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void rt_hw_board_init(void)
|
||||
{
|
||||
memcpy((void*)&_iramstart, (void*)&_iramcopy, (rt_uint32_t)&_iramend - (rt_uint32_t)&_iramstart);
|
||||
memset((void*)&__bss_start, 0x0, (rt_uint32_t)&__bss_end - (rt_uint32_t)&__bss_start);
|
||||
|
||||
rt_hw_cache_init();
|
||||
rt_hw_exception_init();
|
||||
|
||||
/* init hardware interrupt */
|
||||
rt_hw_interrupt_init();
|
||||
rt_hw_uart_init();
|
||||
|
||||
#ifdef RT_USING_CONSOLE
|
||||
/* set console device */
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
102
bsp/x1000/drivers/board.h
Normal file
102
bsp/x1000/drivers/board.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* File : board.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <stdint.h>
|
||||
#include "x1000.h"
|
||||
|
||||
#define RT_USING_JZ_X1000
|
||||
#define X1000
|
||||
|
||||
#ifdef BOARD_HALLEY2_FIR
|
||||
#include "board/halley2_fir/board_halley2_fir.h"
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_HALLEY2_REALBOARD
|
||||
#include "board/halley2_realboard/board_halley2_readboard.h"
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_HALLEY2_REALBOARD_V2
|
||||
#include "board/halley2_realboard_v2/board_halley2_readboard_v2.h"
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_HALLEY2_IDELAN
|
||||
#include "board/halley2_idelan/board_halley2_idelan.h"
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_HALLEY2
|
||||
#include "board/halley2/board_halley2.h"
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_PHOENIX
|
||||
#include "board/phoenix/board_phoenix.h"
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_CANNA
|
||||
#include "board/canna/board_canna.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clock setting
|
||||
*/
|
||||
#define BOARD_EXTAL_CLK 24000000
|
||||
#define BOARD_RTC_CLK 32768
|
||||
#define BOARD_CPU_CLK (1008 * 1000 * 1000UL)
|
||||
|
||||
#define BOARD_APLL_FREQ 1008000000 /*If APLL not use mast be set 0*/
|
||||
#define BOARD_MPLL_FREQ 600000000 /*If MPLL not use mast be set 0*/
|
||||
|
||||
/*
|
||||
* Heap setting
|
||||
*/
|
||||
extern unsigned char __bss_start;
|
||||
extern unsigned char __bss_end;
|
||||
|
||||
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
|
||||
#define RT_HW_HEAP_END (void*)(0x80000000 + 32 * 1024 * 1024)
|
||||
|
||||
/* HW EVENT */
|
||||
#define EVENT_NONE 0x0000
|
||||
|
||||
#define EVENT_TYPE_MSK 0xFF00
|
||||
#define EVENT_VALUE_MSK 0x00FF
|
||||
|
||||
#define EVENT_LINEIN 0x0100
|
||||
#define EVENT_LINEIN_INSERT 0x0101
|
||||
#define EVENT_LINEIN_REMOVE 0x0102
|
||||
#define EVENT_LINEIN_SHUTDOWN 0x0103
|
||||
|
||||
#define EVENT_BAT 0x0200
|
||||
#define EVENT_BAT_ALONE 0x0201
|
||||
#define EVENT_BAT_CHARGE_IN 0x0202
|
||||
#define EVENT_BAT_CHARGE_FULL 0x0203
|
||||
#define EVENT_BAT_ERROR 0x0204
|
||||
|
||||
#define EVENT_KEY_DOWN 0x0300
|
||||
#define EVENT_KEY_UP 0x0400
|
||||
|
||||
#endif /* _BOARD_H_ */
|
||||
BIN
bsp/x1000/drivers/board/canna/PD_X1000_CANNA_BASEBOARD_V2.1.pdf
Normal file
BIN
bsp/x1000/drivers/board/canna/PD_X1000_CANNA_BASEBOARD_V2.1.pdf
Normal file
Binary file not shown.
BIN
bsp/x1000/drivers/board/canna/PD_X1000_CANNA_COREBOARD_V1.0.pdf
Normal file
BIN
bsp/x1000/drivers/board/canna/PD_X1000_CANNA_COREBOARD_V1.0.pdf
Normal file
Binary file not shown.
6
bsp/x1000/drivers/board/canna/board_canna.h
Normal file
6
bsp/x1000/drivers/board/canna/board_canna.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef BOARD_CANNA_H__
|
||||
#define BOARD_CANNA_H__
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
14
bsp/x1000/drivers/board/halley2/board_halley2.h
Normal file
14
bsp/x1000/drivers/board/halley2/board_halley2.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef BOARD_HALLEY2_H__
|
||||
#define BOARD_HALLEY2_H__
|
||||
|
||||
#define LCD_RST_PORT GPIO_PORT_D
|
||||
#define LCD_RST_PIN GPIO_Pin_0
|
||||
|
||||
#define LCD_BLPWM_PORT GPIO_PORT_C
|
||||
#define LCD_BLPWM_PIN GPIO_Pin_25
|
||||
|
||||
#define LCD_BLEN_PORT GPIO_PORT_A
|
||||
#define LCD_BLEN_PIN GPIO_Pin_25
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
bsp/x1000/drivers/board/halley2_fir/PD_X1000_FIR_V1.1.pdf
Normal file
BIN
bsp/x1000/drivers/board/halley2_fir/PD_X1000_FIR_V1.1.pdf
Normal file
Binary file not shown.
80
bsp/x1000/drivers/board/halley2_fir/board_halley2_fir.h
Normal file
80
bsp/x1000/drivers/board/halley2_fir/board_halley2_fir.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef BOARD_HALLEY2_IDELAN_H__
|
||||
#define BOARD_HALLEY2_IDELAN_H__
|
||||
|
||||
#define AUDIO_SHUTDOWN_PORT GPIO_PORT_B
|
||||
#define AUDIO_SHUTDOWN_PIN GPIO_Pin_7
|
||||
#define AUDIO_SHUTDOWN_MUTE 1
|
||||
|
||||
/*
|
||||
* IO LCD
|
||||
*/
|
||||
#define LCD_PWEN_PORT GPIO_PORT_B
|
||||
#define LCD_PWEN_PIN GPIO_Pin_19 //原理图不对,实际连接到LCD_TE
|
||||
|
||||
#define LCD_RST_PORT GPIO_PORT_B
|
||||
#define LCD_RST_PIN GPIO_Pin_14
|
||||
|
||||
#define LCD_BL_PORT GPIO_PORT_B
|
||||
#define LCD_BL_PIN GPIO_Pin_9
|
||||
|
||||
/*
|
||||
* IO Touch
|
||||
*/
|
||||
#define TP_INT_PORT GPIO_PORT_B
|
||||
#define TP_INT_PIN GPIO_Pin_11
|
||||
|
||||
#define TP_RST_PORT GPIO_PORT_B
|
||||
#define TP_RST_PIN GPIO_Pin_12
|
||||
|
||||
#define TP_PWEN_PORT GPIO_PORT_B
|
||||
#define TP_PWEN_PIN GPIO_Pin_15
|
||||
|
||||
|
||||
/*
|
||||
* IO KeyBoard:
|
||||
*/
|
||||
#define KEY_WIFI_PORT GPIO_PORT_A
|
||||
#define KEY_WIFI_PIN GPIO_Pin_20
|
||||
|
||||
#define KEY_BT_PORT GPIO_PORT_A
|
||||
#define KEY_BT_PIN GPIO_Pin_21
|
||||
|
||||
#define KEY_VOLD_PORT GPIO_PORT_A
|
||||
#define KEY_VOLD_PIN GPIO_Pin_22
|
||||
|
||||
#define KEY_VOLU_PORT GPIO_PORT_B
|
||||
#define KEY_VOLU_PIN GPIO_Pin_28
|
||||
|
||||
#define KEY_WKUP_PORT GPIO_PORT_B
|
||||
#define KEY_WKUP_PIN GPIO_Pin_31
|
||||
|
||||
/*
|
||||
* IO Camera
|
||||
*/
|
||||
#define CIM_PWDN_PORT GPIO_PORT_A
|
||||
#define CIM_PWDN_PIN GPIO_Pin_25
|
||||
#define CIM_RST_PORT GPIO_PORT_A
|
||||
#define CIM_RST_PIN GPIO_Pin_24
|
||||
#define CIM_PWEN_PORT GPIO_PORT_A
|
||||
#define CIM_PWEN_PIN GPIO_Pin_23
|
||||
/*
|
||||
* IO LED Config
|
||||
*/
|
||||
#define LED_BT_PORT GPIO_PORT_B
|
||||
#define LED_BT_PIN GPIO_Pin_6
|
||||
|
||||
#define LED_WIFI_PORT GPIO_PORT_B
|
||||
#define LED_WIFI_PIN GPIO_Pin_24
|
||||
|
||||
#define LED_ZB_PORT GPIO_PORT_C
|
||||
#define LED_ZB_PIN GPIO_Pin_27
|
||||
|
||||
/*
|
||||
* Others
|
||||
*/
|
||||
|
||||
#define IO_IRQ_FG_PORT GPIO_PORT_B
|
||||
#define IO_IRQ_FG_PIN GPIO_Pin_13
|
||||
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
2016/08/29发布
|
||||
已知的硬件错误:
|
||||
-I2S 信号分配错误 I2SDI I2SDO反了 核心板的DO是输出 Codec的DO也是输出,核心板的DO需要接到Codec的SDI0上
|
||||
-X1 12.288晶振不焊接,R13 需要焊接,核心板提供时钟(layout的时候,晶振保留)
|
||||
-
|
||||
-layout问题,整个板子GND走线 很多实连接,手工焊接质量不保证
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifndef BOARD_HALLEY2_IDELAN_H__
|
||||
#define BOARD_HALLEY2_IDELAN_H__
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef BOARD_HALLEY2_IDELAN_H__
|
||||
#define BOARD_HALLEY2_IDELAN_H__
|
||||
|
||||
#define AUDIO_SHUTDOWN_PORT GPIO_PORT_B
|
||||
#define AUDIO_SHUTDOWN_PIN GPIO_Pin_6
|
||||
#define AUDIO_SHUTDOWN_MUTE 1
|
||||
|
||||
#define LCD_RST_PORT GPIO_PORT_C
|
||||
#define LCD_RST_PIN GPIO_Pin_25
|
||||
|
||||
#define LCD_BL_PORT GPIO_PORT_B
|
||||
#define LCD_BL_PIN GPIO_Pin_19
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* File : board_halley2_readboard_v2.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2017-01-01 Urey first version
|
||||
*/
|
||||
#ifndef DRIVER_BOARD_HALLEY2_REALBOARD_V2_BOARD_HALLEY2_READBOARD_V2_H_
|
||||
#define DRIVER_BOARD_HALLEY2_REALBOARD_V2_BOARD_HALLEY2_READBOARD_V2_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AUDIO_SHUTDOWN_PORT GPIO_PORT_C
|
||||
#define AUDIO_SHUTDOWN_PIN GPIO_Pin_26
|
||||
#define AUDIO_SHUTDOWN_MUTE 0
|
||||
|
||||
#define LCD_RST_PORT GPIO_PORT_C
|
||||
#define LCD_RST_PIN GPIO_Pin_23
|
||||
|
||||
#define LCD_BL_PORT GPIO_PORT_D
|
||||
#define LCD_BL_PIN GPIO_Pin_1
|
||||
|
||||
#define LCD_TP_INT_PORT GPIO_PORT_C
|
||||
#define LCD_TP_INT_PIN GPIO_Pin_25
|
||||
|
||||
/* BLINK LED */
|
||||
#define BLINK_LED0_PORT GPIO_PORT_B
|
||||
#define BLINK_LED0_PIN GPIO_Pin_9
|
||||
|
||||
#define BLINK_LED1_PORT GPIO_PORT_B
|
||||
#define BLINK_LED1_PIN GPIO_Pin_8
|
||||
|
||||
#define BLINK_LED2_PORT GPIO_PORT_B
|
||||
#define BLINK_LED2_PIN GPIO_Pin_13
|
||||
|
||||
#define BLINK_LED3_PORT GPIO_PORT_B
|
||||
#define BLINK_LED3_PIN GPIO_Pin_11
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DRIVER_BOARD_HALLEY2_REALBOARD_V2_BOARD_HALLEY2_READBOARD_V2_H_ */
|
||||
BIN
bsp/x1000/drivers/board/phoenix/Ingenic Studio User Guide.docx
Normal file
BIN
bsp/x1000/drivers/board/phoenix/Ingenic Studio User Guide.docx
Normal file
Binary file not shown.
BIN
bsp/x1000/drivers/board/phoenix/JDI User Guide.docx
Normal file
BIN
bsp/x1000/drivers/board/phoenix/JDI User Guide.docx
Normal file
Binary file not shown.
BIN
bsp/x1000/drivers/board/phoenix/RD_X1000_PHOENIX_V2.0.pdf
Normal file
BIN
bsp/x1000/drivers/board/phoenix/RD_X1000_PHOENIX_V2.0.pdf
Normal file
Binary file not shown.
4
bsp/x1000/drivers/board/phoenix/board_phoenix.h
Normal file
4
bsp/x1000/drivers/board/phoenix/board_phoenix.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef BOARD_HALLEY2_H__
|
||||
#define BOARD_HALLEY2_H__
|
||||
|
||||
#endif
|
||||
11
bsp/x1000/drivers/board/phoenix/jz-x1000.gdbinit
Normal file
11
bsp/x1000/drivers/board/phoenix/jz-x1000.gdbinit
Normal file
@@ -0,0 +1,11 @@
|
||||
#connect to the JDI gdb server
|
||||
target remote 169.28.23.51:2823
|
||||
|
||||
#set remote write size
|
||||
set remotewritesize fixed
|
||||
set remotewritesize 8192
|
||||
|
||||
#load the debug image
|
||||
load
|
||||
|
||||
#debug begin
|
||||
222
bsp/x1000/drivers/board_io.c
Normal file
222
bsp/x1000/drivers/board_io.c
Normal file
@@ -0,0 +1,222 @@
|
||||
#include <board.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "drv_gpio.h"
|
||||
|
||||
static void _delay_us(rt_uint32_t ns)
|
||||
{
|
||||
volatile rt_uint16_t delay;
|
||||
|
||||
while(ns--)
|
||||
{
|
||||
delay = 200;
|
||||
while(delay--);
|
||||
}
|
||||
}
|
||||
|
||||
static void _delay_ms(rt_uint32_t ms)
|
||||
{
|
||||
volatile rt_uint16_t delay;
|
||||
|
||||
while(ms--)
|
||||
{
|
||||
_delay_us(1000);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RT_USING_WIFI) && (defined(WIFI_USING_AP6212) || defined(WIFI_USING_AP6181))
|
||||
/**
|
||||
* PC16 WL_WAKE_HOST
|
||||
* PC17 WL_REG_EN
|
||||
*/
|
||||
int io_AP6212(void)
|
||||
{
|
||||
gpio_set_func(GPIO_PORT_C, GPIO_Pin_17, GPIO_FUNC_0);
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_17, 0);
|
||||
|
||||
rt_kprintf("Enable WL_REG_EN\n");
|
||||
gpio_set_value(GPIO_PORT_C, GPIO_Pin_17, 0);
|
||||
rt_thread_delay(1);
|
||||
gpio_set_value(GPIO_PORT_C, GPIO_Pin_17, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(io_AP6212);
|
||||
#endif
|
||||
|
||||
#if defined(RT_USING_BT) && (defined(WIFI_USING_AP6212) || defined(WIFI_USING_AP6181))
|
||||
#include <drv_rtc.h>
|
||||
/**
|
||||
* PC16 32768 clock
|
||||
*/
|
||||
int io_AP6212_bt(void)
|
||||
{
|
||||
rtc32k_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(io_AP6212_bt);
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_CANNA)
|
||||
int io_canna(void)
|
||||
{
|
||||
/* PC25(1) for Audio Shutdown IO */
|
||||
gpio_set_func(GPIO_PORT_C, GPIO_Pin_25, GPIO_FUNC_1);
|
||||
gpio_direction_output(GPIO_PORT_C,GPIO_Pin_25, 0);
|
||||
gpio_set_value(GPIO_PORT_C,GPIO_Pin_25, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(io_canna);
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_HALLEY2)
|
||||
int io_halley2(void)
|
||||
{
|
||||
#ifdef RT_USING_EMAC
|
||||
/* PC23 for MAC_RST_N */
|
||||
gpio_set_func(GPIO_PORT_C, GPIO_Pin_23, GPIO_FUNC_0);
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_23, 0);
|
||||
rt_thread_delay(1);
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_23, 1);
|
||||
rt_thread_delay(1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(io_halley2);
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_PHOENIX)
|
||||
int io_phoenix(void)
|
||||
{
|
||||
/* PB0(1) for Audio Shutdown IO */
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_0, GPIO_FUNC_2);
|
||||
gpio_direction_output(GPIO_PORT_B,GPIO_Pin_0, 0);
|
||||
gpio_set_value(GPIO_PORT_B,GPIO_Pin_0,0);
|
||||
|
||||
/* PB3 for reset EMAC PHY */
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_3, GPIO_FUNC_2);
|
||||
gpio_direction_output(GPIO_PORT_B, GPIO_Pin_3, 0);
|
||||
rt_thread_delay(1);
|
||||
gpio_direction_output(GPIO_PORT_B, GPIO_Pin_3, 1);
|
||||
rt_thread_delay(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(io_phoenix);
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_OX)
|
||||
int io_ox(void)
|
||||
{
|
||||
/* PB6 for Audio Shutdown IO */
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_6, GPIO_FUNC_1);
|
||||
gpio_direction_output(GPIO_PORT_B,GPIO_Pin_6, 0);
|
||||
gpio_set_value(GPIO_PORT_B,GPIO_Pin_6, 0);
|
||||
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_25, GPIO_OUTPUT0);
|
||||
rt_thread_delay(rt_tick_from_millisecond(100));
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_25, GPIO_OUTPUT1);
|
||||
|
||||
/* PB19 for LCD black light */
|
||||
gpio_direction_output(GPIO_PORT_B,GPIO_Pin_19, GPIO_OUTPUT1);
|
||||
|
||||
#ifdef RT_USING_EMAC
|
||||
/* PC23 for MAC_RST_N */
|
||||
// gpio_set_func(GPIO_PORT_C, GPIO_Pin_23, GPIO_FUNC_0);
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_23, 0);
|
||||
rt_thread_delay(1);
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_23, 1);
|
||||
rt_thread_delay(1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(io_ox);
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_HALLEY2_REALBOARD
|
||||
int io_realboard(void)
|
||||
{
|
||||
/* Audio Shutdown IO */
|
||||
gpio_direction_output(AUDIO_SHUTDOWN_PORT,AUDIO_SHUTDOWN_PIN, AUDIO_SHUTDOWN_MUTE);
|
||||
gpio_set_value(AUDIO_SHUTDOWN_PORT,AUDIO_SHUTDOWN_PIN, AUDIO_SHUTDOWN_MUTE);
|
||||
|
||||
#ifdef RT_USING_EMAC
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_7, GPIO_OUTPUT0);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_8, GPIO_OUTPUT0);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_9, GPIO_OUTPUT0);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_10, GPIO_OUTPUT0);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_11, GPIO_OUTPUT0);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_12, GPIO_OUTPUT0);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_13, GPIO_INPUT);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_14, GPIO_INPUT);
|
||||
gpio_set_func(GPIO_PORT_B, GPIO_Pin_15, GPIO_INPUT);
|
||||
|
||||
/* PC23 for MAC_RST_N */
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_23, 0);
|
||||
_delay_ms(100);
|
||||
gpio_direction_output(GPIO_PORT_C, GPIO_Pin_23, 1);
|
||||
_delay_ms(100);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(io_realboard);
|
||||
#endif /* BOARD_HALLEY2_REALBOARD_X1000 */
|
||||
|
||||
#ifdef BOARD_HALLEY2_REALBOARD_V2
|
||||
int io_realboard_v2(void)
|
||||
{
|
||||
/* Audio Shutdown IO */
|
||||
gpio_direction_output(AUDIO_SHUTDOWN_PORT,AUDIO_SHUTDOWN_PIN, AUDIO_SHUTDOWN_MUTE);
|
||||
gpio_set_value(AUDIO_SHUTDOWN_PORT,AUDIO_SHUTDOWN_PIN, AUDIO_SHUTDOWN_MUTE);
|
||||
|
||||
/* Reset lcd,TP,... */
|
||||
gpio_direction_output(LCD_TP_INT_PORT, LCD_TP_INT_PIN,1);
|
||||
_delay_ms(300);
|
||||
gpio_direction_output(LCD_RST_PORT, LCD_RST_PIN,0);
|
||||
_delay_ms(100);
|
||||
gpio_set_value(LCD_RST_PORT, LCD_RST_PIN, 1);
|
||||
|
||||
|
||||
/* LED */
|
||||
gpio_direction_output(BLINK_LED0_PORT, BLINK_LED0_PIN,1);
|
||||
gpio_direction_output(BLINK_LED1_PORT, BLINK_LED1_PIN,1);
|
||||
gpio_direction_output(BLINK_LED2_PORT, BLINK_LED2_PIN,1);
|
||||
gpio_direction_output(BLINK_LED3_PORT, BLINK_LED3_PIN,1);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(io_realboard_v2);
|
||||
#endif /* BOARD_HALLEY2_REALBOARD_V2 */
|
||||
|
||||
|
||||
#ifdef BOARD_HALLEY2_FIR
|
||||
int io_halley2_fir(void)
|
||||
{
|
||||
/* Audio Shutdown IO */
|
||||
gpio_direction_output(AUDIO_SHUTDOWN_PORT,AUDIO_SHUTDOWN_PIN, AUDIO_SHUTDOWN_MUTE);
|
||||
|
||||
/* LCD */
|
||||
rt_kprintf("lcd power enable...\n");
|
||||
gpio_direction_output(LCD_PWEN_PORT,LCD_PWEN_PIN, 0); //LCD Power Enable
|
||||
gpio_direction_output(LCD_RST_PORT,LCD_RST_PIN, 0);
|
||||
gpio_direction_output(LCD_BL_PORT,LCD_BL_PIN, 0);
|
||||
|
||||
/* Touch */
|
||||
gpio_direction_output(TP_PWEN_PORT,TP_PWEN_PIN, 0);
|
||||
gpio_direction_output(TP_RST_PORT,TP_RST_PIN, 0);
|
||||
|
||||
/* LED */
|
||||
gpio_direction_output(LED_BT_PORT,LED_BT_PIN, 1);
|
||||
gpio_direction_output(LED_WIFI_PORT,LED_WIFI_PIN, 1);
|
||||
gpio_direction_output(LED_ZB_PORT,LED_ZB_PIN, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(io_halley2_fir);
|
||||
#endif /* BOARD_HALLEY2_FIR */
|
||||
305
bsp/x1000/drivers/board_key.c
Normal file
305
bsp/x1000/drivers/board_key.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* File : drv_gpio_keyboard.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
|
||||
/*********************************************************************************************************
|
||||
** Include Files
|
||||
*********************************************************************************************************/
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_gpio.h"
|
||||
#include "board_key.h"
|
||||
|
||||
#ifdef RT_USING_AUDIO_PLAYER
|
||||
#include <player_app.h>
|
||||
#endif
|
||||
|
||||
#define KEY_DEBUG
|
||||
|
||||
#ifdef KEY_DEBUG
|
||||
#define KEY_DBG(...) rt_kprintf("[KEY]"),rt_kprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define KEY_DBG(...)
|
||||
#endif
|
||||
|
||||
static keyboard_event_handler_t _handler = RT_NULL;
|
||||
|
||||
|
||||
#if defined(BOARD_HALLEY2)
|
||||
/* 4 keys
|
||||
* SW1 SW2 SW3 SW5
|
||||
* Vol- Vol+ Play/Pause Mode/Config
|
||||
* PA10 PA11 PB28 PB31
|
||||
*/
|
||||
static struct keyboard_io_def keyboard_io_tbl[] =
|
||||
{
|
||||
//Vol-/Next Song
|
||||
{
|
||||
GPIO_PORT_A, GPIO_Pin_10 ,
|
||||
KEY_NEXT, KEY_VOLDEC,
|
||||
},
|
||||
|
||||
//Vol+/Prev Song
|
||||
{
|
||||
GPIO_PORT_A, GPIO_Pin_11 ,
|
||||
KEY_PREV, KEY_VOLINC,
|
||||
},
|
||||
|
||||
//Play_Pause
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_28 ,
|
||||
KEY_UNKNOWN, KEY_PLAY_PAUSE,
|
||||
},
|
||||
|
||||
//Mode/Config
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_31,
|
||||
KEY_CONFIG, KEY_NETWORK_MODE,
|
||||
},
|
||||
};
|
||||
#elif defined(BOARD_HALLEY2_REALBOARD)
|
||||
/* 6 keys
|
||||
* 11 12 21 22 31 32
|
||||
* ON/OFF MODE V+ V- BT/MUTE WIFI
|
||||
*/
|
||||
static struct keyboard_io_def keyboard_io_tbl[] =
|
||||
{
|
||||
//ON/OFF
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_31,
|
||||
KEY_UNKNOWN, KEY_PWROFF,
|
||||
},
|
||||
//V+
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_25,
|
||||
KEY_UNKNOWN, KEY_VOLINC,
|
||||
},
|
||||
//V-
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_2,
|
||||
KEY_UNKNOWN, KEY_VOLDEC,
|
||||
},
|
||||
//BT/MUTE
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_3,
|
||||
KEY_SOURCE, KEY_MUTE,
|
||||
},
|
||||
//WIFI
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_28,
|
||||
KEY_UNKNOWN, KEY_CONFIG,
|
||||
},
|
||||
};
|
||||
#elif defined(BOARD_HALLEY2_REALBOARD_V2)
|
||||
struct keyboard_io_def keyboard_io_tbl[] =
|
||||
{
|
||||
//ON/OFF
|
||||
{
|
||||
GPIO_PORT_D, GPIO_Pin_0,
|
||||
KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
},
|
||||
//V+
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_28,
|
||||
KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
},
|
||||
//V-
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_31,
|
||||
KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
},
|
||||
//WIFI config
|
||||
{
|
||||
GPIO_PORT_D, GPIO_Pin_2,
|
||||
KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
},
|
||||
};
|
||||
|
||||
#else
|
||||
struct keyboard_io_def keyboard_io_tbl[] =
|
||||
{
|
||||
//PWRKEY KEY
|
||||
{
|
||||
GPIO_PORT_B, GPIO_Pin_31,
|
||||
KEY_UNKNOWN, KEY_UNKNOWN
|
||||
},
|
||||
};
|
||||
#endif
|
||||
#define CFG_MAX_KEY_NBR sizeof(keyboard_io_tbl)/sizeof(keyboard_io_tbl[0])
|
||||
|
||||
static struct rt_mailbox* _keyMb = RT_NULL;
|
||||
|
||||
void keyboard_irq_callback(void *param)
|
||||
{
|
||||
KEY_DBG("%d\n", (int)param);
|
||||
if (_keyMb)
|
||||
{
|
||||
struct keyboard_io_def* key;
|
||||
int value = (int)param;
|
||||
|
||||
key = &keyboard_io_tbl[value];
|
||||
if(rt_mb_send(_keyMb, (rt_uint32_t)param) == RT_EOK)
|
||||
gpio_mask_irq(key->port, key->pin);
|
||||
}
|
||||
}
|
||||
|
||||
#define KEY_EVENT_DOWN 0x01
|
||||
#define KEY_EVENT_HOLD 0x02
|
||||
#define KEY_EVENT_UP 0x04
|
||||
|
||||
#define KEY_SCAN_STEP_TIME 10
|
||||
#define KEY_SCAN_HOLD_THRESHOLD 2000
|
||||
|
||||
//Scan the single key
|
||||
rt_uint8_t key_scan(struct keyboard_io_def *keyIO)
|
||||
{
|
||||
static rt_uint8_t keyTrigger = 0;
|
||||
static rt_uint8_t keyRelease = 0;
|
||||
static rt_uint8_t keyHold = 0;
|
||||
|
||||
rt_uint8_t keyValue = 0;
|
||||
|
||||
//elimination buffeting
|
||||
do
|
||||
{
|
||||
keyValue = gpio_get_value(keyIO->port,keyIO->pin);
|
||||
rt_thread_delay(rt_tick_from_millisecond(KEY_SCAN_STEP_TIME));
|
||||
}while(keyValue != gpio_get_value(keyIO->port,keyIO->pin));
|
||||
|
||||
keyValue ^= 0x01;
|
||||
keyTrigger = keyValue &(keyValue ^ keyHold);
|
||||
keyRelease = (keyValue ^ keyTrigger ^ keyHold);
|
||||
keyHold = keyValue;
|
||||
|
||||
// KEY_DBG("keyValue = %x\n,keyTrigger = %x\n,keyRelese = %x\n,keyHold = %x\n",keyValue,keyTrigger,keyRelease,keyHold);
|
||||
|
||||
if(keyTrigger != 0)
|
||||
return KEY_EVENT_DOWN;
|
||||
else if(keyHold != 0)
|
||||
return KEY_EVENT_HOLD;
|
||||
|
||||
return KEY_EVENT_UP;
|
||||
}
|
||||
|
||||
void kbd_thread(void* parameter)
|
||||
{
|
||||
int keyId;
|
||||
rt_uint8_t keyEvent;
|
||||
rt_uint8_t keyValue;
|
||||
rt_uint32_t keyHoldTime;
|
||||
_keyMb = rt_mb_create("key", 4, RT_IPC_FLAG_FIFO);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if(rt_mb_recv(_keyMb, (rt_uint32_t*)&keyId, RT_TICK_PER_SECOND) != RT_EOK)
|
||||
{
|
||||
//if no key pressed,check power key...
|
||||
keyId = 0;
|
||||
}
|
||||
|
||||
{
|
||||
struct keyboard_io_def* key;
|
||||
|
||||
// Check key ID
|
||||
if(keyId >= CFG_MAX_KEY_NBR)
|
||||
{
|
||||
rt_kprintf("keyID error\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
key = &keyboard_io_tbl[keyId];
|
||||
|
||||
keyEvent = key_scan(key);
|
||||
/* No key input */
|
||||
if(keyEvent == KEY_EVENT_UP)
|
||||
{
|
||||
gpio_unmask_irq(key->port, key->pin);
|
||||
continue;
|
||||
}
|
||||
KEY_DBG("key %d down\n", keyId);
|
||||
|
||||
//Wait for key RELEASE
|
||||
keyHoldTime = 0;
|
||||
do
|
||||
{
|
||||
keyEvent = key_scan(key);
|
||||
if(keyEvent == KEY_EVENT_HOLD)
|
||||
{
|
||||
keyHoldTime += KEY_SCAN_STEP_TIME;
|
||||
|
||||
if(keyHoldTime > KEY_SCAN_HOLD_THRESHOLD)
|
||||
break;
|
||||
}
|
||||
|
||||
} while (keyEvent != KEY_EVENT_UP);
|
||||
KEY_DBG("key %d up,hold time = %dms\n", keyId,keyHoldTime);
|
||||
|
||||
if(keyHoldTime > KEY_SCAN_HOLD_THRESHOLD)
|
||||
keyValue = key->longKey;
|
||||
else
|
||||
keyValue = key->shortKey;
|
||||
|
||||
//send key event
|
||||
if (_handler) _handler(EVENT_KEY_DOWN | keyValue);
|
||||
|
||||
//Wait for KEYUP
|
||||
while (keyEvent != KEY_EVENT_UP)
|
||||
{
|
||||
keyEvent = key_scan(key);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND / 10);
|
||||
}
|
||||
|
||||
if (_handler) _handler(EVENT_KEY_UP | keyValue);
|
||||
|
||||
gpio_unmask_irq(key->port, key->pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rt_hw_keyboard_set_handler(keyboard_event_handler_t handler)
|
||||
{
|
||||
_handler = handler;
|
||||
}
|
||||
|
||||
void rt_hw_keyboard_init(void)
|
||||
{
|
||||
int i;
|
||||
rt_thread_t tid;
|
||||
|
||||
tid = rt_thread_create("key", kbd_thread, RT_NULL, 2048, 16, 10);
|
||||
if (tid)
|
||||
rt_thread_startup(tid);
|
||||
|
||||
/* initialize all IO for keyboard */
|
||||
for (i = 0; i < CFG_MAX_KEY_NBR; ++i)
|
||||
{
|
||||
gpio_set_func(keyboard_io_tbl[i].port,keyboard_io_tbl[i].pin,GPIO_INPUT_PULL | GPIO_INT_FE);
|
||||
|
||||
gpio_set_irq_callback(keyboard_io_tbl[i].port,keyboard_io_tbl[i].pin,keyboard_irq_callback, (void*)i);
|
||||
|
||||
gpio_unmask_irq(keyboard_io_tbl[i].port,keyboard_io_tbl[i].pin);
|
||||
}
|
||||
}
|
||||
48
bsp/x1000/drivers/board_key.h
Normal file
48
bsp/x1000/drivers/board_key.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef BOARD_KEY_H__
|
||||
#define BOARD_KEY_H__
|
||||
|
||||
#ifndef RT_USING_AUDIO_PLAYER
|
||||
enum KEY_VALUE
|
||||
{
|
||||
KEY_VOLINC,
|
||||
KEY_VOLDEC,
|
||||
KEY_NEXT,
|
||||
KEY_PREV,
|
||||
|
||||
KEY_PAUSE,
|
||||
KEY_PLAY,
|
||||
KEY_PLAY_PAUSE,
|
||||
|
||||
KEY_MUTE,
|
||||
|
||||
KEY_MIC,
|
||||
KEY_EQ,
|
||||
KEY_MENU,
|
||||
KEY_CHANNEL,
|
||||
KEY_FAVORITE,
|
||||
|
||||
//system shutdown, wifi config...
|
||||
KEY_PWROFF,
|
||||
KEY_CONFIG,
|
||||
KEY_NETWORK_MODE,
|
||||
|
||||
KEY_SOURCE,
|
||||
KEY_UNKNOWN,
|
||||
};
|
||||
#endif
|
||||
|
||||
struct keyboard_io_def
|
||||
{
|
||||
enum gpio_port port;
|
||||
enum gpio_pin pin;
|
||||
|
||||
int longKey;
|
||||
int shortKey;
|
||||
};
|
||||
|
||||
typedef void (*keyboard_event_handler_t)(uint32_t event);
|
||||
|
||||
void rt_hw_keyboard_init(void);
|
||||
void rt_hw_keyboard_set_handler(keyboard_event_handler_t handler);
|
||||
|
||||
#endif
|
||||
104
bsp/x1000/drivers/board_led.c
Normal file
104
bsp/x1000/drivers/board_led.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* File : drv_gpio_led.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016/05/13 Urey the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_gpio.h"
|
||||
|
||||
#if 0
|
||||
#include "board_led.h"
|
||||
|
||||
#if defined(BOARD_CANNA)
|
||||
|
||||
#define MAX_LED_NBR 3
|
||||
|
||||
struct led_io_def led_io_tbl[MAX_LED_NBR] =
|
||||
{
|
||||
//LED_POWER
|
||||
{
|
||||
GPIO_PORT_C,
|
||||
GPIO_Pin_24
|
||||
},
|
||||
|
||||
//LED_WIFI
|
||||
{
|
||||
GPIO_PORT_D,
|
||||
GPIO_Pin_5
|
||||
},
|
||||
|
||||
//LED_CHARGING
|
||||
{
|
||||
GPIO_PORT_A,
|
||||
GPIO_Pin_0
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
#else
|
||||
#define MAX_LED_NBR 0
|
||||
struct led_io_def led_io_tbl[] =
|
||||
{
|
||||
//LED_POWER
|
||||
{
|
||||
GPIO_PORT_B,
|
||||
GPIO_Pin_6
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
void rt_hw_led_on(int led)
|
||||
{
|
||||
if((led >= LED_LAST) || (led > MAX_LED_NBR))
|
||||
return;
|
||||
|
||||
gpio_set_value(led_io_tbl[led].port,led_io_tbl[led].pin,0);
|
||||
}
|
||||
|
||||
void rt_hw_led_off(int led)
|
||||
{
|
||||
if((led >= LED_LAST) || (led > MAX_LED_NBR))
|
||||
return;
|
||||
|
||||
gpio_set_value(led_io_tbl[led].port,led_io_tbl[led].pin,1);
|
||||
}
|
||||
|
||||
int rt_hw_led_init(void)
|
||||
{
|
||||
rt_uint8_t i;
|
||||
|
||||
/* Init all IO for keyboard */
|
||||
for (i = 0; i < MAX_LED_NBR; ++i)
|
||||
{
|
||||
gpio_set_func(led_io_tbl[i].port,led_io_tbl[i].pin,GPIO_OUTPUT1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_hw_led_init);
|
||||
|
||||
|
||||
#endif
|
||||
13
bsp/x1000/drivers/board_led.h
Normal file
13
bsp/x1000/drivers/board_led.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef BOARD_LED_H__
|
||||
#define BOARD_LED_H__
|
||||
|
||||
struct led_io_def
|
||||
{
|
||||
enum gpio_port port;
|
||||
enum gpio_pin pin;
|
||||
};
|
||||
|
||||
void rt_hw_led_off(int led);
|
||||
void rt_hw_led_on (int led);
|
||||
|
||||
#endif
|
||||
357
bsp/x1000/drivers/dma.c
Normal file
357
bsp/x1000/drivers/dma.c
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* File : dma.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 头文件
|
||||
*********************************************************************************************************/
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "dma.h"
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 全局变量
|
||||
*********************************************************************************************************/
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 宏定义
|
||||
*********************************************************************************************************/
|
||||
#define DMA_DEBUG 0
|
||||
#if DMA_DEBUG
|
||||
#include <stdio.h>
|
||||
#define DMA_DBG(...) rt_kprintf("[DMA]"),rt_kprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define DMA_DBG(...)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define __DMA_CHANNEL_RESET(dmac) do { \
|
||||
if (dmac->ops && dmac->ops->reset) {\
|
||||
dmac->ops->reset(dmac); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __DMA_CHANNEL_TRANS(dmac, message, ret) do { \
|
||||
if (dmac->ops && dmac->ops->trans) { \
|
||||
ret = dmac->ops->trans(dmac, message); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __DMA_CHANNEL_STATUS(ch, ret) do { \
|
||||
if (dmac->ops && dmac->ops->status) {\
|
||||
ret = dmac->ops->status(dmac); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 全局变量
|
||||
*********************************************************************************************************/
|
||||
struct rt_dma_channel _g_dma_chan_head;
|
||||
static rt_bool_t rt_dma_init_flag = RT_FALSE;
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数名称: _dma_init
|
||||
** 功能描述: 初始化 DMA
|
||||
** 输 入: void
|
||||
** 返 回: void
|
||||
** 备 注: NONE
|
||||
*********************************************************************************************************/
|
||||
void _dma_init (void)
|
||||
{
|
||||
_g_dma_chan_head.ch = -1;
|
||||
rt_list_init(&(_g_dma_chan_head.list));
|
||||
} /* _dma_init */
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数名称: rt_dma_drv_install
|
||||
** 功能描述: DMA 通用驱动程序安装
|
||||
** 输 入: rt_uint32_t channel,RT_DMA_FUNCS* funcs,rt_size_t maxBurstBytes
|
||||
** 返 回: rt_err_t
|
||||
** 备 注: NONE
|
||||
*********************************************************************************************************/
|
||||
rt_err_t rt_dma_drv_install(struct rt_dma_channel *dmac, struct dma_ops *ops,struct dma_config *config,void* user_data)
|
||||
{
|
||||
/* 参数检查 */
|
||||
RT_ASSERT(dmac != RT_NULL);
|
||||
|
||||
if(rt_dma_init_flag == RT_FALSE)
|
||||
{
|
||||
rt_dma_init_flag = RT_TRUE;
|
||||
|
||||
_dma_init();
|
||||
}
|
||||
|
||||
if(ops == RT_NULL)
|
||||
{
|
||||
DMA_DBG("dma param invalid.\r\n");
|
||||
|
||||
return -RT_EIO;
|
||||
}
|
||||
/* 挂载到通道列表 */
|
||||
rt_list_insert_after(&(_g_dma_chan_head.list),&(dmac->list));
|
||||
|
||||
dmac->ops = ops;
|
||||
if(config != RT_NULL)
|
||||
{
|
||||
dmac->config.direction = config->direction;
|
||||
dmac->config.src_addr_width = config->src_addr_width;
|
||||
dmac->config.src_maxburst = config->src_maxburst;
|
||||
dmac->config.dst_addr_width = config->dst_addr_width;
|
||||
dmac->config.dst_maxburst = config->dst_maxburst;
|
||||
}
|
||||
|
||||
dmac->user_data = user_data;
|
||||
rt_memset(dmac->msg_list,0,RT_DMA_MAX_NODES * sizeof(struct dma_message));
|
||||
__DMA_CHANNEL_RESET(dmac);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
struct rt_dma_channel *rt_dma_get_channel(int id)
|
||||
{
|
||||
struct rt_dma_channel *dmac;
|
||||
struct rt_list_node *node;
|
||||
|
||||
for (node = _g_dma_chan_head.list.next; node != &(_g_dma_chan_head.list); node = node->next)
|
||||
{
|
||||
dmac = rt_list_entry(node, struct rt_dma_channel, list);
|
||||
|
||||
if(dmac->ch == id)
|
||||
return dmac;
|
||||
}
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
//
|
||||
///*********************************************************************************************************
|
||||
//** 函数名称: rt_dma_flush
|
||||
//** 功能描述: 删除所有被延迟处理的传输请求 (不调用回调函数)
|
||||
//** 输 入: rt_uint32_t channel
|
||||
//** 返 回: rt_err_t
|
||||
//** 备 注: NONE
|
||||
//*********************************************************************************************************/
|
||||
//rt_err_t rt_dma_flush (struct rt_dma_channel *dmac)
|
||||
//{
|
||||
// rt_size_t data_size;
|
||||
// struct dma_message *last_message,*message;
|
||||
// rt_uint16_t next_index;
|
||||
// /* 参数检查 */
|
||||
// RT_ASSERT(dmac != RT_NULL);
|
||||
//
|
||||
//
|
||||
// next_index = dmac->get_index + 1;
|
||||
// if(next_index >= RT_DMA_MAX_NODES)
|
||||
// next_index = 0;
|
||||
//
|
||||
//
|
||||
//// while (rt_data_queue_pop(&(dmac->tmsg_queue),(const void **)&message, &data_size, 0) == RT_EOK)
|
||||
//// {
|
||||
//// /* 清除 DMA消息 */
|
||||
////// if(message->release_cb != RT_NULL)
|
||||
////// message->release_cb(dmac,message);
|
||||
//// }
|
||||
//
|
||||
// __DMA_CHANNEL_RESET(dmac);
|
||||
//
|
||||
//// dmac->tmsg_actived = RT_FALSE;
|
||||
// return RT_EOK;
|
||||
//}
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数名称: rt_dma_trans_message
|
||||
** 功能描述: 添加 一个DMA请求
|
||||
** 输 入: rt_uint32_t channel DMA_MSG *pMsg
|
||||
** 返 回: rt_err_t
|
||||
** 备 注: NONE
|
||||
*********************************************************************************************************/
|
||||
rt_err_t rt_dma_trans_message (struct rt_dma_channel *dmac,struct dma_message* message)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_err_t result;
|
||||
rt_uint16_t next_index;
|
||||
struct dma_message *msg_node;
|
||||
/* 参数检查 */
|
||||
RT_ASSERT(dmac != RT_NULL);
|
||||
RT_ASSERT(message != RT_NULL);
|
||||
RT_ASSERT(message->t_size <= (64 * 1024));
|
||||
|
||||
if(message->t_size == 0)
|
||||
{
|
||||
if (dmac->complete != RT_NULL)
|
||||
{
|
||||
dmac->complete(dmac, message);
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
//判断传输队列是否满
|
||||
next_index = dmac->put_index + 1;
|
||||
if(next_index >= RT_DMA_MAX_NODES)
|
||||
next_index = 0;
|
||||
if(next_index == dmac->get_index)
|
||||
return -RT_ENOMEM;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
msg_node = &(dmac->msg_list[dmac->put_index]);
|
||||
dmac->put_index = next_index;
|
||||
|
||||
//保存message
|
||||
rt_memcpy(msg_node,message,sizeof(struct dma_message));
|
||||
|
||||
next_index = dmac->get_index + 1;
|
||||
if(next_index >= RT_DMA_MAX_NODES)
|
||||
next_index = 0;
|
||||
/* check message list whether is empty */
|
||||
if(next_index == dmac->put_index)
|
||||
{
|
||||
rt_hw_interrupt_enable(level);
|
||||
/* Make a DMA transfer */
|
||||
if(dmac->start != RT_NULL)
|
||||
dmac->start(dmac,message);
|
||||
|
||||
do{
|
||||
int ret;
|
||||
__DMA_CHANNEL_TRANS(dmac, message, ret); /* 初始化传输诸元 */
|
||||
(void)ret;
|
||||
} while (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数名称: rt_dma_configture
|
||||
** 功能描述: DMA 通道配置
|
||||
** 输 入: struct rt_dma_channel *dmac,struct dma_config *config
|
||||
** 返 回: rt_err_t
|
||||
** 备 注: NONE
|
||||
*********************************************************************************************************/
|
||||
rt_err_t rt_dma_configture (struct rt_dma_channel *dmac,struct dma_config *config)
|
||||
{
|
||||
/* 参数检查 */
|
||||
RT_ASSERT(dmac != RT_NULL);
|
||||
RT_ASSERT(config != RT_NULL);
|
||||
|
||||
dmac->config.direction = config->direction;
|
||||
dmac->config.src_addr_width = config->src_addr_width;
|
||||
dmac->config.src_maxburst = config->src_maxburst;
|
||||
dmac->config.dst_addr_width = config->dst_addr_width;
|
||||
dmac->config.dst_maxburst = config->dst_maxburst;
|
||||
|
||||
__DMA_CHANNEL_RESET(dmac);
|
||||
|
||||
return RT_EOK;
|
||||
} /* rt_dma_configture */
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数名称: rt_dma_get_current_message
|
||||
** 功能描述: DMA 获取当前传输的消息句柄
|
||||
** 输 入: struct rt_dma_channel *dmac
|
||||
** 返 回: struct dma_message *
|
||||
** 备 注: NONE
|
||||
*********************************************************************************************************/
|
||||
struct dma_message * rt_dma_get_current_message (struct rt_dma_channel *dmac)
|
||||
{
|
||||
rt_base_t level;
|
||||
struct dma_message *message;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
message = &(dmac->msg_list[dmac->get_index]);
|
||||
|
||||
rt_hw_interrupt_enable(level);
|
||||
return message;
|
||||
} /* rt_dma_get_current_message */
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数名称: rt_dma_contex_service
|
||||
** 功能描述: DMA 中断服务
|
||||
** 输 入: rt_uint32_t channel
|
||||
** 返 回: rt_err_t
|
||||
** 备 注: global
|
||||
*********************************************************************************************************/
|
||||
rt_err_t rt_dma_contex_service (struct rt_dma_channel *dmac,rt_uint32_t event)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_size_t data_size;
|
||||
struct dma_message *last_message,*message;
|
||||
rt_uint16_t next_index;
|
||||
|
||||
/* 参数检查 */
|
||||
RT_ASSERT(dmac != RT_NULL);
|
||||
switch (event)
|
||||
{
|
||||
case RT_DMA_EVENT_COMPLETE:
|
||||
next_index = dmac->get_index + 1;
|
||||
if(next_index >= RT_DMA_MAX_NODES)
|
||||
next_index = 0;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
/* 优先发送 缓冲区中的消息 */
|
||||
last_message = &(dmac->msg_list[dmac->get_index]);
|
||||
dmac->get_index = next_index;
|
||||
if(dmac->get_index != dmac->put_index)
|
||||
{
|
||||
/* 队列中有消息未发送,优先处理 */
|
||||
message = &(dmac->msg_list[dmac->get_index]);
|
||||
|
||||
rt_hw_interrupt_enable(level);
|
||||
/* Make a DMA transfer */
|
||||
if(dmac->start != RT_NULL)
|
||||
dmac->start(dmac,message);
|
||||
|
||||
do{
|
||||
int ret;
|
||||
__DMA_CHANNEL_TRANS(dmac, message, ret); /* 初始化传输诸元 */
|
||||
(void)ret;
|
||||
} while (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/* 处理上一个消息的回调函数 */
|
||||
if (dmac->complete != RT_NULL)
|
||||
{
|
||||
dmac->complete(dmac, last_message);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
155
bsp/x1000/drivers/dma.h
Normal file
155
bsp/x1000/drivers/dma.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* File : dma.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _DMA_H_
|
||||
#define _DMA_H_
|
||||
/*********************************************************************************************************
|
||||
** 头文件
|
||||
*********************************************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <rtdef.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
#define RT_DMA_CHANNEL(n) (n)
|
||||
#ifndef RT_DMA_MAX_NODES
|
||||
# define RT_DMA_MAX_NODES 8
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************************
|
||||
** DMA 状态定义
|
||||
*********************************************************************************************************/
|
||||
#define RT_DMA_STATUS_IDLE 0 /* DMA 处于空闲模式 */
|
||||
#define RT_DMA_STATUS_BUSY 1 /* DMA 处于正在工作 */
|
||||
#define RT_DMA_STATUS_ERROR 2 /* DMA 处于错误状态 */
|
||||
|
||||
/*********************************************************************************************************
|
||||
** DMA 地址方向定义
|
||||
*********************************************************************************************************/
|
||||
#define RT_DMA_ADDR_INC 0 /* 地址增长方式 */
|
||||
#define RT_DMA_ADDR_FIX 1 /* 地址不变 */
|
||||
#define RT_DMA_ADDR_DEC 2 /* 地址减少方式 */
|
||||
|
||||
/*********************************************************************************************************
|
||||
** DMA 传输方向定义
|
||||
*********************************************************************************************************/
|
||||
#define RT_DMA_MEM_TO_MEM 0
|
||||
#define RT_DMA_MEM_TO_DEV 1
|
||||
#define RT_DMA_DEV_TO_MEM 2
|
||||
#define RT_DMA_DEV_TO_DEV 3
|
||||
#define RT_DMA_TRANS_NONE 4
|
||||
|
||||
/*********************************************************************************************************
|
||||
** DMA 总线宽度
|
||||
*********************************************************************************************************/
|
||||
#define RT_DMA_BUSWIDTH_UNDEFINED 0
|
||||
#define RT_DMA_BUSWIDTH_1_BYTE 1
|
||||
#define RT_DMA_BUSWIDTH_2_BYTES 2
|
||||
#define RT_DMA_BUSWIDTH_4_BYTES 4
|
||||
#define RT_DMA_BUSWIDTH_8_BYTES 8
|
||||
|
||||
/*********************************************************************************************************
|
||||
** DMA 传输 时间
|
||||
*********************************************************************************************************/
|
||||
#define RT_DMA_EVENT_COMPLETE 0x01
|
||||
#define RT_DMA_EVENT_ERROR 0x02
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 数据结构
|
||||
*********************************************************************************************************/
|
||||
struct rt_dma_channel;
|
||||
struct dma_message;
|
||||
struct dma_config;
|
||||
struct dma_ops
|
||||
{
|
||||
void (*reset)(struct rt_dma_channel *dmac);
|
||||
rt_size_t (*trans)(struct rt_dma_channel *dmac,struct dma_message *message);
|
||||
int (*status)(struct rt_dma_channel *dmac);
|
||||
int (*configure)(struct rt_dma_channel *dmac,struct dma_config *config);
|
||||
};
|
||||
|
||||
struct dma_message
|
||||
{
|
||||
rt_uint8_t *src_addr; /* 源端缓冲区地址 */
|
||||
rt_uint8_t *dst_addr; /* 目的端缓冲区地址 */
|
||||
rt_uint8_t src_option; /* 源端地址方向控制 */
|
||||
rt_uint8_t dst_option; /* 目的地址方向控制 */
|
||||
rt_size_t t_size; /* 传输的字节数 */
|
||||
|
||||
rt_uint32_t t_mode; /* 传输模式, 自定义 */
|
||||
|
||||
void (*complete_cb)(void *data,void *pbuf);
|
||||
void *complete_arg;
|
||||
};
|
||||
|
||||
|
||||
struct dma_config
|
||||
{
|
||||
rt_uint32_t direction;
|
||||
rt_uint32_t src_addr_width;
|
||||
rt_uint32_t dst_addr_width;
|
||||
rt_uint32_t src_maxburst;
|
||||
rt_uint32_t dst_maxburst;
|
||||
};
|
||||
|
||||
struct rt_dma_channel
|
||||
{
|
||||
int ch;
|
||||
rt_list_t list; /* channel list */
|
||||
|
||||
struct dma_config config;
|
||||
struct dma_ops *ops;
|
||||
|
||||
struct dma_message msg_list[RT_DMA_MAX_NODES];
|
||||
rt_uint16_t get_index;
|
||||
rt_uint16_t put_index;
|
||||
|
||||
void (*start)(struct rt_dma_channel *dmac,struct dma_message *msg); /* 启动传输 回调函数 */
|
||||
void (*complete)(struct rt_dma_channel *dmac,struct dma_message *msg); /* 传输完成 回调函数 */
|
||||
|
||||
void *user_data; /* 自定义数据 */
|
||||
};
|
||||
|
||||
|
||||
/*********************************************************************************************************
|
||||
** 函数申明
|
||||
*********************************************************************************************************/
|
||||
rt_err_t rt_dma_drv_install(struct rt_dma_channel *dmac, struct dma_ops *ops,struct dma_config *config,void* user_data);
|
||||
struct rt_dma_channel *rt_dma_get_channel(int id);
|
||||
struct dma_message *rt_dma_get_current_message (struct rt_dma_channel *dmac);
|
||||
rt_err_t rt_dma_reset (struct rt_dma_channel *dmac);
|
||||
rt_err_t rt_dma_trans_message (struct rt_dma_channel *dmac,struct dma_message* message);
|
||||
rt_err_t rt_dma_configture (struct rt_dma_channel *dmac,struct dma_config *config);
|
||||
rt_err_t rt_dma_contex_service (struct rt_dma_channel *dmac,rt_uint32_t event);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DMA_H_ */
|
||||
@@ -21,16 +21,16 @@
|
||||
* Date Author Notes
|
||||
* 2015-11-19 Urey the first version
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include <x1000.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_clock.h"
|
||||
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#define PRINT(...) rt_kprintf(__VA_ARGS__)
|
||||
@@ -834,8 +834,42 @@ const struct clk_selectors audio_selector[] =
|
||||
[SELECTOR_AUDIO].route = {CLK(EXT1),CLK(SCLKA),CLK(EXT1),CLK(MPLL)},
|
||||
#undef CLK
|
||||
};
|
||||
static int audio_div_apll[64];
|
||||
static int audio_div_mpll[64];
|
||||
static int audio_div_apll[64] =
|
||||
{
|
||||
8000 , 1 , 126000 ,
|
||||
11025 , 2 , 182857 ,
|
||||
12000 , 1 , 84000 ,
|
||||
16000 , 1 , 63000 ,
|
||||
22050 , 4 , 182857 ,
|
||||
24000 , 1 , 42000 ,
|
||||
32000 , 1 , 31500 ,
|
||||
44100 , 7 , 160000 ,
|
||||
48000 , 1 , 21000 ,
|
||||
88200 , 21 , 240000 ,
|
||||
96000 , 1 , 10500 ,
|
||||
176400 , 42 , 240000 ,
|
||||
192000 , 1 , 5250 ,
|
||||
|
||||
0
|
||||
};
|
||||
static int audio_div_mpll[64] =
|
||||
{
|
||||
8000 , 1 , 75000 ,
|
||||
11025 , 4 , 217687 ,
|
||||
12000 , 1 , 50000 ,
|
||||
16000 , 1 , 37500 ,
|
||||
22050 , 8 , 217687 ,
|
||||
24000 , 1 , 25000 ,
|
||||
32000 , 1 , 18750 ,
|
||||
44100 , 16 , 217687 ,
|
||||
48000 , 1 , 12500 ,
|
||||
88200 , 25 , 170068 ,
|
||||
96000 , 1 , 6250 ,
|
||||
176400 , 75 , 255102 ,
|
||||
192000 , 1 , 3125 ,
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
struct cgu_audio_clk
|
||||
{
|
||||
@@ -920,13 +954,14 @@ static int get_div_val(int max1,int max2,int machval, int* res1, int* res2)
|
||||
*res2 = tmp2;
|
||||
return 0;
|
||||
}
|
||||
static int cgu_audio_calculate_set_rate(struct clk* clk, uint32_t rate, uint32_t pid){
|
||||
|
||||
static int cgu_audio_calculate_set_rate(struct clk* clk, uint32_t rate, uint32_t pid)
|
||||
{
|
||||
int i,m,n,d,sync,tmp_val,d_max,sync_max;
|
||||
int no = CLK_CGU_AUDIO_NO(clk->flags);
|
||||
int n_max = cgu_audio_clks[no].maskn >> cgu_audio_clks[no].bitn;
|
||||
int *audio_div;
|
||||
|
||||
|
||||
if(pid == CLK_ID_MPLL)
|
||||
{
|
||||
audio_div = (int*)audio_div_mpll;
|
||||
@@ -946,7 +981,8 @@ static int cgu_audio_calculate_set_rate(struct clk* clk, uint32_t rate, uint32_t
|
||||
PRINT("cgu aduio set rate err!\n");
|
||||
return -1;
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
m = audio_div[i+1];
|
||||
if(no == CGU_AUDIO_I2S)
|
||||
{
|
||||
@@ -954,7 +990,7 @@ static int cgu_audio_calculate_set_rate(struct clk* clk, uint32_t rate, uint32_t
|
||||
m*=2;
|
||||
#endif
|
||||
d_max = 0x1ff;
|
||||
tmp_val = audio_div[i+2]/64;
|
||||
tmp_val = audio_div[i + 2] / 64;
|
||||
if (tmp_val > n_max)
|
||||
{
|
||||
if (get_div_val(n_max, d_max, tmp_val, &n, &d))
|
||||
@@ -962,8 +998,8 @@ static int cgu_audio_calculate_set_rate(struct clk* clk, uint32_t rate, uint32_t
|
||||
}
|
||||
else
|
||||
{
|
||||
n = tmp_val;
|
||||
d = 1;
|
||||
n = tmp_val / 4;
|
||||
d = 4;
|
||||
}
|
||||
tmp_val = cpm_inl(cgu_audio_clks[no].off)&(~(cgu_audio_clks[no].maskm|cgu_audio_clks[no].maskn));
|
||||
tmp_val |= (m<<cgu_audio_clks[no].bitm)|(n<<cgu_audio_clks[no].bitn);
|
||||
@@ -975,8 +1011,9 @@ static int cgu_audio_calculate_set_rate(struct clk* clk, uint32_t rate, uint32_t
|
||||
{
|
||||
cgu_audio_clks[no].cache = tmp_val;
|
||||
}
|
||||
writel(d - 1,I2S_PRI_DIV);
|
||||
|
||||
cpm_outl(0,CPM_I2SCDR1);
|
||||
writel(d - 1,I2S_PRI_DIV);
|
||||
}
|
||||
else if (no == CGU_AUDIO_PCM)
|
||||
{
|
||||
@@ -1094,10 +1131,12 @@ static int cgu_audio_set_rate(struct clk *clk, uint32_t rate)
|
||||
}
|
||||
else
|
||||
{
|
||||
cgu_audio_calculate_set_rate(clk,rate,CLK_ID_MPLL);
|
||||
if(get_clk_id(clk->parent) == CLK_ID_EXT1)
|
||||
cgu_audio_set_parent(clk,get_clk_from_id(CLK_ID_MPLL));
|
||||
clk->parent = get_clk_from_id(CLK_ID_MPLL);
|
||||
cgu_audio_set_parent(clk,get_clk_from_id(CLK_ID_SCLKA));
|
||||
|
||||
cgu_audio_calculate_set_rate(clk,rate,CLK_ID_SCLKA);
|
||||
|
||||
clk->parent = get_clk_from_id(CLK_ID_SCLKA);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1124,9 +1163,6 @@ void init_cgu_audio_clk(struct clk *clk)
|
||||
{
|
||||
int no,id,tmp_val;
|
||||
|
||||
rt_memcpy(audio_div_apll,(void*)(0xf4000000),256);
|
||||
rt_memcpy(audio_div_mpll,(void*)(0xf4000000)+256,256);
|
||||
|
||||
if (clk->flags & CLK_FLG_PARENT)
|
||||
{
|
||||
id = CLK_PARENT(clk->flags);
|
||||
@@ -1461,3 +1497,61 @@ int init_all_clk(void)
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(init_all_clk);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
#include <finsh.h>
|
||||
#endif
|
||||
|
||||
int clk_dump(int argc, char** argv)
|
||||
{
|
||||
// dump = 1;
|
||||
rt_kprintf("CCLK:%luMHz L2CLK:%luMhz H0CLK:%luMHz H2CLK:%luMhz PCLK:%luMhz\n",
|
||||
clk_srcs[CLK_ID_CCLK].rate/1000/1000,
|
||||
clk_srcs[CLK_ID_L2CLK].rate/1000/1000,
|
||||
clk_srcs[CLK_ID_H0CLK].rate/1000/1000,
|
||||
clk_srcs[CLK_ID_H2CLK].rate/1000/1000,
|
||||
clk_srcs[CLK_ID_PCLK].rate/1000/1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(clk_dump, dump clock debug log);
|
||||
|
||||
int clk(int argc, char**argv)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = cpm_inl(CPM_CLKGR);
|
||||
rt_kprintf("CLKGR = 0x%08x\n", value);
|
||||
|
||||
value &= ~(1 << 14);
|
||||
cpm_outl(value, CPM_CLKGR);
|
||||
|
||||
value = cpm_inl(CPM_CLKGR);
|
||||
rt_kprintf("CLKGR = 0x%08x\n", value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(clk, clock information dump);
|
||||
|
||||
int uart0_clk(void)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = cpm_inl(CPM_CLKGR);
|
||||
value &= ~(1 << 14);
|
||||
cpm_outl(value, CPM_CLKGR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uart1_clk(void)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = cpm_inl(CPM_CLKGR);
|
||||
value &= ~(1 << 15);
|
||||
cpm_outl(value, CPM_CLKGR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,66 +27,6 @@
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define CPM_CPCCR (0x00)
|
||||
#define CPM_CPCSR (0xd4)
|
||||
|
||||
#define CPM_DDRCDR (0x2c)
|
||||
#define CPM_I2SCDR (0x60)
|
||||
#define CPM_I2SCDR1 (0x70)
|
||||
#define CPM_LPCDR (0x64)
|
||||
#define CPM_MSC0CDR (0x68)
|
||||
#define CPM_MSC1CDR (0xa4)
|
||||
#define CPM_USBCDR (0x50)
|
||||
#define CPM_MACCDR (0x54)
|
||||
#define CPM_UHCCDR (0x6c)
|
||||
#define CPM_SFCCDR (0x74)
|
||||
#define CPM_CIMCDR (0x7c)
|
||||
#define CPM_PCMCDR (0x84)
|
||||
#define CPM_PCMCDR1 (0xe0)
|
||||
#define CPM_MPHYC (0xe8)
|
||||
|
||||
#define CPM_INTR (0xb0)
|
||||
#define CPM_INTRE (0xb4)
|
||||
#define CPM_DRCG (0xd0)
|
||||
#define CPM_CPSPPR (0x38)
|
||||
#define CPM_CPPSR (0x34)
|
||||
|
||||
#define CPM_USBPCR (0x3c)
|
||||
#define CPM_USBRDT (0x40)
|
||||
#define CPM_USBVBFIL (0x44)
|
||||
#define CPM_USBPCR1 (0x48)
|
||||
|
||||
#define CPM_CPAPCR (0x10)
|
||||
#define CPM_CPMPCR (0x14)
|
||||
|
||||
#define CPM_LCR (0x04)
|
||||
#define CPM_PSWC0ST (0x90)
|
||||
#define CPM_PSWC1ST (0x94)
|
||||
#define CPM_PSWC2ST (0x98)
|
||||
#define CPM_PSWC3ST (0x9c)
|
||||
#define CPM_CLKGR (0x20)
|
||||
#define CPM_MESTSEL (0xec)
|
||||
#define CPM_SRBC (0xc4)
|
||||
#define CPM_ERNG (0xd8)
|
||||
#define CPM_RNG (0xdc)
|
||||
#define CPM_SLBC (0xc8)
|
||||
#define CPM_SLPC (0xcc)
|
||||
#define CPM_OPCR (0x24)
|
||||
#define CPM_RSR (0x08)
|
||||
|
||||
#define LCR_LPM_MASK (0x3)
|
||||
#define LCR_LPM_SLEEP (0x1)
|
||||
|
||||
#define OPCR_ERCS (0x1<<2)
|
||||
#define OPCR_PD (0x1<<3)
|
||||
#define OPCR_IDLE (0x1<<31)
|
||||
|
||||
#define cpm_inl(off) readl(CPM_BASE + (off))
|
||||
#define cpm_outl(val,off) writel(val, CPM_BASE + (off))
|
||||
#define cpm_test_bit(bit,off) (cpm_inl(off) & 0x1<<(bit))
|
||||
#define cpm_set_bit(bit,off) (cpm_outl((cpm_inl(off) | 0x1<<(bit)),off))
|
||||
#define cpm_clear_bit(bit,off) (cpm_outl(cpm_inl(off) & ~(0x1 << bit), off))
|
||||
|
||||
|
||||
#define I2S_PRI_DIV 0xb0020030
|
||||
#define PCM_PRI_DIV 0xb0030014
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user