snd驱动以及优化
This commit is contained in:
14
.vscode/settings.json
vendored
14
.vscode/settings.json
vendored
@@ -153,10 +153,20 @@
|
||||
"at_surf_f437_board_emac.h": "c",
|
||||
"at_surf_f437_board_pca9555.h": "c",
|
||||
"net_drv_svr.h": "c",
|
||||
"u_factory.h": "c"
|
||||
"u_factory.h": "c",
|
||||
"mk_eth_drv_impl.h": "c",
|
||||
"mk_snd_drv.h": "c",
|
||||
"at_surf_f437_board_player.h": "c",
|
||||
"mk_snd_drv_impl.h": "c",
|
||||
"ns_cli.h": "c",
|
||||
"snd_drv_svr.h": "c",
|
||||
"net_drv_cli.h": "c",
|
||||
"lwiperf.h": "c",
|
||||
"stdio_impl.h": "c",
|
||||
"stack.h": "c"
|
||||
},
|
||||
"cortex-debug.showRTOS": false,
|
||||
"cortex-debug.variableUseNaturalFormat": false,
|
||||
"cortex-debug.variableUseNaturalFormat": true,
|
||||
"C_Cpp.default.systemIncludePath": [""],
|
||||
"C_Cpp.default.forcedInclude": ["${workspaceFolder}/build/autoconf.h"]
|
||||
}
|
||||
@@ -1,14 +1,5 @@
|
||||
/dts-v1/;
|
||||
/ {
|
||||
// usart0:usart_0 {
|
||||
// compatible = "st,usart";
|
||||
// regs = <0x0000000 0x1000>;
|
||||
// baud = <115200>;
|
||||
// stopbits = <1>;
|
||||
// };
|
||||
// log {
|
||||
// dev = <&usart0>;
|
||||
// };
|
||||
pin {
|
||||
compatible = "at32f43x,pin";
|
||||
regs = <
|
||||
@@ -25,13 +16,16 @@
|
||||
0x40023800 0x400 /*CRM*/
|
||||
0x60000000 0x100000 /*XMC_MEM*/
|
||||
>;
|
||||
/*TODO: pca9555 set*/
|
||||
/*TODO: pin set*/
|
||||
};
|
||||
i2c2:i2c@40005800 {
|
||||
i2c2:i2c2 {
|
||||
compatible = "at32f43x,i2c2";
|
||||
regs = <
|
||||
0x40023800 0x400 /*CRM*/
|
||||
0x40005800 0x400 /*I2C2*/
|
||||
>;
|
||||
/*TODO: pin set*/
|
||||
};
|
||||
pca9555 {
|
||||
compatible = "at32f43x,pca9555";
|
||||
@@ -48,5 +42,21 @@
|
||||
0x40013800 0x400 /*EXINT & SCFG*/
|
||||
0x40013C00 0x400 /*EXINT & SCFG*/
|
||||
>;
|
||||
/*TODO: pin set*/
|
||||
/*TODO: pca9555 set*/
|
||||
};
|
||||
snd {
|
||||
compatible = "at32f43x,snd";
|
||||
regs = <
|
||||
0x40023800 0x400 /*CRM*/
|
||||
0x40003800 0x400 /*SPI2/I2S2*/
|
||||
0x40000000 0x20000
|
||||
/*0x40010400 0x400 TMR8*/
|
||||
/*0x40017800 0x400 I2S2EXT*/
|
||||
0x40026400 0x400 /*DMA1_2*/
|
||||
>;
|
||||
/*TODO: pin set*/
|
||||
/*TODO: pca9555 set*/
|
||||
/*TODO: i2c set*/
|
||||
};
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ static const unsigned char states[]['z'-'A'+1] = {
|
||||
S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
|
||||
S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
|
||||
S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
|
||||
S('c') = CHAR, S('C') = INT,
|
||||
S('c') = INT, S('C') = UINT,
|
||||
S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
|
||||
S('m') = NOARG,
|
||||
S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
|
||||
@@ -62,7 +62,7 @@ static const unsigned char states[]['z'-'A'+1] = {
|
||||
S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
|
||||
S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
|
||||
S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
|
||||
S('c') = INT, S('s') = PTR, S('n') = PTR,
|
||||
S('c') = UINT, S('s') = PTR, S('n') = PTR,
|
||||
S('l') = LLPRE,
|
||||
}, { /* 2: ll-prefixed */
|
||||
S('d') = LLONG, S('i') = LLONG,
|
||||
@@ -438,7 +438,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
|
||||
unsigned st, ps;
|
||||
int cnt=0, l=0;
|
||||
size_t i;
|
||||
char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
|
||||
char buf[sizeof(uintmax_t)*3];
|
||||
const char *prefix;
|
||||
int t, pl;
|
||||
wchar_t wc[2], *ws;
|
||||
@@ -589,6 +589,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
|
||||
}
|
||||
p = MAX(p, z-a + !arg.i);
|
||||
break;
|
||||
narrow_c:
|
||||
case 'c':
|
||||
*(a=z-(p=1))=arg.i;
|
||||
fl &= ~ZERO_PAD;
|
||||
@@ -603,6 +604,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
|
||||
fl &= ~ZERO_PAD;
|
||||
break;
|
||||
case 'C':
|
||||
if (!arg.i) goto narrow_c;
|
||||
wc[0] = arg.i;
|
||||
wc[1] = 0;
|
||||
arg.p = wc;
|
||||
|
||||
@@ -53,3 +53,8 @@
|
||||
#define NET_DRV_WRITE ((umword_t)0) //!< 网络驱动写
|
||||
#define NET_DRV_READ ((umword_t)1) //!< 网络驱动读
|
||||
#define NET_DRV_MAP ((umword_t)2) //!< net map
|
||||
|
||||
#define SND_DRV_PROT 0x0009
|
||||
#define SND_DRV_WRITE ((umword_t)0) //!< snd驱动写
|
||||
#define SND_DRV_READ ((umword_t)1) //!< snd驱动读
|
||||
#define SND_DRV_MAP ((umword_t)2) //!< snd map
|
||||
|
||||
8
mkrtos_user/lib/sys_svr/inc/snd_drv_cli.h
Normal file
8
mkrtos_user/lib/sys_svr/inc/snd_drv_cli.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "u_types.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_slist.h"
|
||||
|
||||
int snd_drv_cli_write(obj_handler_t dm9000_obj, obj_handler_t shm_obj, int len);
|
||||
int snd_drv_cli_read(obj_handler_t dm9000_obj, obj_handler_t shm_obj);
|
||||
int snd_drv_cli_map(obj_handler_t dm9000_obj, obj_handler_t *sem_obj);
|
||||
9
mkrtos_user/lib/sys_svr/inc/snd_drv_svr.h
Normal file
9
mkrtos_user/lib/sys_svr/inc/snd_drv_svr.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "u_types.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_slist.h"
|
||||
#include "snd_drv_types.h"
|
||||
int snd_drv_write(obj_handler_t obj, int len);
|
||||
int snd_drv_read(obj_handler_t obj, int len);
|
||||
int snd_drv_map(obj_handler_t *hd);
|
||||
void snd_drv_init(snd_drv_t *ns);
|
||||
9
mkrtos_user/lib/sys_svr/inc/snd_drv_types.h
Normal file
9
mkrtos_user/lib/sys_svr/inc/snd_drv_types.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "u_types.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_slist.h"
|
||||
|
||||
typedef struct snd_drv
|
||||
{
|
||||
rpc_svr_obj_t svr;
|
||||
} snd_drv_t;
|
||||
73
mkrtos_user/lib/sys_svr/src/snd_drv_cli.c
Normal file
73
mkrtos_user/lib/sys_svr/src/snd_drv_cli.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "rpc_prot.h"
|
||||
#include "snd_drv_cli.h"
|
||||
#include "snd_drv_types.h"
|
||||
#include "u_rpc.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_arch.h"
|
||||
#include "u_rpc_buf.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_rpc_buf.h"
|
||||
#include <u_env.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
RPC_GENERATION_CALL2(snd_drv_t, SND_DRV_PROT, SND_DRV_WRITE, write,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, shm_obj,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
|
||||
int snd_drv_cli_write(obj_handler_t dm9000_obj, obj_handler_t shm_obj, int len)
|
||||
{
|
||||
rpc_obj_handler_t_t rpc_hd = {
|
||||
.data = shm_obj,
|
||||
};
|
||||
rpc_int_t rpc_len = {
|
||||
.data = len,
|
||||
};
|
||||
|
||||
msg_tag_t tag = snd_drv_t_write_call(dm9000_obj, &rpc_hd, &rpc_len);
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
RPC_GENERATION_CALL2(snd_drv_t, SND_DRV_PROT, SND_DRV_READ, read,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, shm_obj,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
|
||||
|
||||
int snd_drv_cli_read(obj_handler_t dm9000_obj, obj_handler_t shm_obj)
|
||||
{
|
||||
rpc_obj_handler_t_t rpc_hd = {
|
||||
.data = shm_obj,
|
||||
};
|
||||
rpc_int_t rpc_len = {
|
||||
.data = 0,
|
||||
};
|
||||
msg_tag_t tag = snd_drv_t_read_call(dm9000_obj, &rpc_hd, &rpc_len);
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
RPC_GENERATION_CALL1(snd_drv_t, SND_DRV_PROT, SND_DRV_MAP, map,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd)
|
||||
|
||||
int snd_drv_cli_map(obj_handler_t dm9000_obj, obj_handler_t *sem_obj)
|
||||
{
|
||||
assert(sem_obj);
|
||||
|
||||
obj_handler_t newfd;
|
||||
|
||||
newfd = handler_alloc();
|
||||
if (newfd == HANDLER_INVALID)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
rpc_obj_handler_t_t rpc_sem_obj = {
|
||||
.data = newfd,
|
||||
.del_map_flags = VPAGE_FLAGS_MAP,
|
||||
};
|
||||
msg_tag_t tag = snd_drv_t_map_call(dm9000_obj, &rpc_sem_obj);
|
||||
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
handler_free(newfd);
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
*sem_obj = newfd;
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
51
mkrtos_user/lib/sys_svr/src/snd_drv_svr.c
Normal file
51
mkrtos_user/lib/sys_svr/src/snd_drv_svr.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "rpc_prot.h"
|
||||
#include "snd_drv_svr.h"
|
||||
#include "snd_drv_types.h"
|
||||
#include "u_rpc.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_arch.h"
|
||||
#include "u_rpc_buf.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_rpc_buf.h"
|
||||
#include <stdio.h>
|
||||
|
||||
RPC_GENERATION_OP2(snd_drv_t, SND_DRV_PROT, SND_DRV_WRITE, write,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, shm_obj,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
|
||||
{
|
||||
return snd_drv_write(rpc_hd_get(0), len->data);
|
||||
}
|
||||
RPC_GENERATION_DISPATCH2(snd_drv_t, SND_DRV_PROT, SND_DRV_WRITE, write,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type)
|
||||
|
||||
RPC_GENERATION_OP2(snd_drv_t, SND_DRV_PROT, SND_DRV_READ, read,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, shm_obj,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
|
||||
{
|
||||
return snd_drv_read(rpc_hd_get(0), len->data);
|
||||
}
|
||||
|
||||
RPC_GENERATION_DISPATCH2(snd_drv_t, SND_DRV_PROT, SND_DRV_READ, read,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, shm_obj,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
|
||||
|
||||
RPC_GENERATION_OP1(snd_drv_t, SND_DRV_PROT, SND_DRV_MAP, map,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd)
|
||||
{
|
||||
int ret = snd_drv_map(&cli_hd->data);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("snd drv aailed to request map");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
RPC_GENERATION_DISPATCH1(snd_drv_t, SND_DRV_PROT, SND_DRV_MAP, map,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd)
|
||||
|
||||
RPC_DISPATCH3(snd_drv_t, SND_DRV_PROT, typeof(SND_DRV_READ), SND_DRV_WRITE, write, SND_DRV_READ, read, SND_DRV_MAP, map)
|
||||
|
||||
void snd_drv_init(snd_drv_t *ns)
|
||||
{
|
||||
rpc_svr_obj_init(&ns->svr, rpc_snd_drv_t_dispatch, SND_DRV_PROT);
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
int u_irq_request(int irq_no, void *stack, void *msg_buf, obj_handler_t *ret_irq_obj, void (*irq_func)(void), u_irq_prio_t prio)
|
||||
{
|
||||
static obj_handler_t irq_obj;
|
||||
obj_handler_t irq_obj;
|
||||
|
||||
irq_obj = handler_alloc();
|
||||
if (irq_obj == HANDLER_INVALID)
|
||||
@@ -28,16 +28,16 @@ int u_irq_request(int irq_no, void *stack, void *msg_buf, obj_handler_t *ret_irq
|
||||
}
|
||||
obj_handler_t th_hd;
|
||||
|
||||
if (ret_irq_obj)
|
||||
{
|
||||
*ret_irq_obj = irq_obj;
|
||||
}
|
||||
int ret = u_thread_create(&th_hd, stack, msg_buf, irq_func);
|
||||
if (ret < 0)
|
||||
{
|
||||
handler_free_umap(irq_obj);
|
||||
return ret;
|
||||
}
|
||||
if (ret_irq_obj)
|
||||
{
|
||||
*ret_irq_obj = irq_obj;
|
||||
}
|
||||
u_thread_run(th_hd, IRQ_THREAD_PRIO);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define STACK_SIZE (4 * 1024) //(1024 + 256)
|
||||
#else
|
||||
#define HEAP_SIZE (2 * 1024)
|
||||
#define STACK_SIZE (3 * 1024) //(1024 + 256)
|
||||
#define STACK_SIZE (4 * 1024) //(1024 + 256)
|
||||
#endif
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#一次读取一行,每行代表启动的应用程序
|
||||
# fatfs
|
||||
# dm9000_drv
|
||||
# net
|
||||
cpiofs -m /bin
|
||||
pin
|
||||
i2c
|
||||
pca9555
|
||||
display
|
||||
eth
|
||||
nes
|
||||
net
|
||||
# pin
|
||||
# i2c
|
||||
# pca9555
|
||||
# display
|
||||
# eth
|
||||
# snd
|
||||
# net
|
||||
# nes
|
||||
sh
|
||||
@@ -193,6 +193,7 @@ static ns_node_t *node_lookup(ns_node_t *dir, const char *name,
|
||||
}
|
||||
if (name[0] == 0)
|
||||
{
|
||||
*ret_inx = 0;
|
||||
return dir;
|
||||
}
|
||||
node = dir;
|
||||
@@ -605,7 +606,7 @@ int namespace_query(const char *path, obj_handler_t *hd)
|
||||
if (path[0] == '/' && path[1] == 0)
|
||||
{
|
||||
*hd = ns_hd;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
ns_lock();
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <u_util.h>
|
||||
#if !IS_ENABLED(CONFIG_MMU)
|
||||
#define HEAP_SIZE 2048
|
||||
#define STACK_SIZE (3*1024)
|
||||
#define HEAP_SIZE 32 * 1024
|
||||
#define STACK_SIZE (3 * 1024)
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#define HEAP_ATTR SECTION("HEAP") __attribute__((zero_init))
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
add_subdirectory(nes_simulator)
|
||||
# add_subdirectory(nes_simulator)
|
||||
add_subdirectory(coremark)
|
||||
add_subdirectory(tinycc-arm-thumb)
|
||||
add_subdirectory(app_test)
|
||||
# add_subdirectory(tinycc-arm-thumb)
|
||||
# add_subdirectory(app_test)
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${CONFIG_BOARD_NAME})
|
||||
add_subdirectory(${CONFIG_BOARD_NAME})
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#define HEAP_SIZE (100 * 1024)
|
||||
#define HEAP_SIZE (64 * 1024)
|
||||
#define STACK_SIZE (1024 * 3)
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.balign 4
|
||||
.global nes_rom
|
||||
nes_rom:
|
||||
.incbin "/Users/zhangzheng/mkrtos-real/mkrtos_user/user/app/nes_simulator/nes_rom/超级玛丽.nes"
|
||||
.incbin "/Users/zhangzheng/mkrtos-real/mkrtos_user/user/app/nes_simulator/nes_rom/超级马里奥兄弟3[MM之神汉化](JP)[ACT](3Mb).nes"
|
||||
.global nes_rom_end
|
||||
nes_rom_end:
|
||||
.long 0
|
||||
|
||||
Binary file not shown.
@@ -2249,9 +2249,9 @@ IO_W: //I/O write
|
||||
ldr r2,=io_write_tbl ////改过,加3行
|
||||
add r2,r2,r4
|
||||
add r2,r2,r1,lsl#2 //<<2
|
||||
ldrmi r1,[r2] ////直接操作pc太他妈危险了
|
||||
orr r1,r1,#0x1
|
||||
bx r1
|
||||
ldrmi r2,[r2] ////直接操作pc太他妈危险了
|
||||
orr r2,r2,#0x1
|
||||
bx r2
|
||||
b empty_R //读地址不正确
|
||||
nop
|
||||
.data
|
||||
@@ -2521,16 +2521,17 @@ joy1_R: //4017
|
||||
K6502_Read://apu Rendering DPCM channel #5 r0=APU->ApuC5Address不确定正确*
|
||||
//---------------------------------------------------------------
|
||||
//EXPORT K6502_Read //switch ( wAddr & 0xe000 ) apu.c
|
||||
stmfd sp!,{lr}
|
||||
|
||||
stmfd sp!,{r4, lr}
|
||||
mov r4, r1
|
||||
mov r1,r0,lsr#13 //>>13= & 0xe000
|
||||
ldr r2,=CPU_RAM//////存储器映象 ram+rom
|
||||
add r2, r2, r4
|
||||
ldr r1,[r2,r1,lsl#2] //lookup rom ptr..查找ptr
|
||||
|
||||
bic r0,r0,#0xe000 //and r0,#0x1fff &0x1fff
|
||||
ldrb r0,[r1,r0]
|
||||
|
||||
ldmfd sp!,{lr}
|
||||
ldmfd sp!,{r4, lr}
|
||||
bx lr
|
||||
// nop
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define APU_OVERSAMPLE
|
||||
#define APU_VOLUME_DECAY(x) ((x) -= ((x) >> 7))
|
||||
//需要用到的汇编的代码及参数
|
||||
uint8_t K6502_Read( uint16_t wAddr ); //6502.s
|
||||
uint8_t K6502_Read( uint16_t wAddr, uint32_t nes_ram_offset ); //6502.s
|
||||
extern uint32_t clocks; //6502.s
|
||||
//noise lookups for both modes */
|
||||
//噪音查找两种模式 */
|
||||
@@ -512,6 +512,7 @@ void apu_dmcreload(dmc_t *chan)
|
||||
chan->dma_length = chan->cached_dmalength;
|
||||
chan->irq_occurred = FALSE;
|
||||
}
|
||||
extern uint32_t nes_ram_offset;
|
||||
|
||||
/* DELTA MODULATION CHANNEL
|
||||
** =========================
|
||||
@@ -540,7 +541,7 @@ int apu_dmc(dmc_t *chan)
|
||||
|
||||
if (7 == delta_bit)
|
||||
{
|
||||
chan->cur_byte = K6502_Read(chan->address); //chan->cur_byte = nes6502_getbyte(chan->address);*********************
|
||||
chan->cur_byte = K6502_Read(chan->address, nes_ram_offset); //chan->cur_byte = nes6502_getbyte(chan->address);*********************
|
||||
/* steal a cycle from CPU偷从CPU周期*/
|
||||
clocks++; // nes6502_burn(1);//要CPU时钟数加1**********************************************************************
|
||||
|
||||
@@ -1082,7 +1083,6 @@ void Apu_Write4017(uint8 value, uint32 address )
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void Apu_Write4015(uint8_t value, uint32_t address )
|
||||
{
|
||||
apudata_t d;
|
||||
|
||||
@@ -9,8 +9,14 @@
|
||||
#include <u_sys.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
// #include "drv_audio.h"
|
||||
// #include "drv_input.h"
|
||||
#include "ns_cli.h"
|
||||
#include "u_sleep.h"
|
||||
#include <u_hd_man.h>
|
||||
#include <u_task.h>
|
||||
#include <u_factory.h>
|
||||
#include <u_share_mem.h>
|
||||
#include <snd_drv_cli.h>
|
||||
#include <assert.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// 本程序移植自网友ye781205的NES模拟器工程
|
||||
@@ -495,6 +501,7 @@ void nes_emulate_frame(void)
|
||||
apu_soundoutput(); // 输出游戏声音
|
||||
framecnt++;
|
||||
nes_frame++;
|
||||
#if 0
|
||||
if (nes_frame > jump_frame_cnt)
|
||||
{
|
||||
nes_frame = 0; // 跳帧
|
||||
@@ -507,6 +514,13 @@ void nes_emulate_frame(void)
|
||||
jump_frame_cnt = 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
if (nes_frame > NES_SKIP_FRAME)
|
||||
{
|
||||
nes_frame = 0;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
printf("fps:%d\n", 1000 / ((sys_read_tick() - st_tick) / framecnt));
|
||||
#endif
|
||||
@@ -520,9 +534,31 @@ void debug_6502(u16 reg0, u8 reg1)
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// nes,音频输出支持部分
|
||||
|
||||
static obj_handler_t snd_drv_hd;
|
||||
static addr_t addr;
|
||||
static umword_t size;
|
||||
static obj_handler_t shm_hd;
|
||||
|
||||
// NES打开音频输出
|
||||
int nes_sound_open(int samples_per_sync, int sample_rate)
|
||||
{
|
||||
int ret;
|
||||
msg_tag_t tag;
|
||||
again:
|
||||
ret = ns_query("/snd", &snd_drv_hd, 0x1);
|
||||
if (ret < 0)
|
||||
{
|
||||
u_sleep_ms(50);
|
||||
goto again;
|
||||
}
|
||||
shm_hd = handler_alloc();
|
||||
assert(shm_hd != HANDLER_INVALID);
|
||||
tag = facotry_create_share_mem(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, shm_hd),
|
||||
SHARE_MEM_CNT_BUDDY_CNT, 2048);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
tag = share_mem_map(shm_hd, vma_addr_create(VPAGE_PROT_RW, VMA_ADDR_RESV, 0), &addr, &size);
|
||||
assert(msg_tag_get_prot(tag) >= 0);
|
||||
|
||||
// f1c100s_audio_config(1,16,sample_rate);
|
||||
// f1c100s_audio_open(samples_per_sync*2);
|
||||
return 1;
|
||||
@@ -534,5 +570,10 @@ void nes_sound_close(void)
|
||||
// NES音频输出到SAI缓存
|
||||
void nes_apu_fill_buffer(int samples, u16 *wavebuf)
|
||||
{
|
||||
// audio_pcm_play((unsigned char*)wavebuf,APU_PCMBUF_SIZE*2);
|
||||
memcpy((void *)addr, wavebuf, APU_PCMBUF_SIZE * 2);
|
||||
int ret = snd_drv_cli_write(snd_drv_hd, shm_hd, APU_PCMBUF_SIZE * 2);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("snd write error.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,3 +5,4 @@ add_subdirectory(display)
|
||||
add_subdirectory(i2c)
|
||||
add_subdirectory(pca9555)
|
||||
add_subdirectory(eth)
|
||||
add_subdirectory(snd)
|
||||
|
||||
@@ -480,6 +480,7 @@ error_status emac_speed_config(emac_auto_negotiation_type nego, emac_duplex_type
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
u_sleep_ms(10);
|
||||
} while (!(data & PHY_LINKED_STATUS_BIT) && (timeout < PHY_TIMEOUT));
|
||||
|
||||
if (timeout == PHY_TIMEOUT)
|
||||
@@ -501,6 +502,7 @@ error_status emac_speed_config(emac_auto_negotiation_type nego, emac_duplex_type
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
u_sleep_ms(10);
|
||||
} while (!(data & PHY_NEGO_COMPLETE_BIT) && (timeout < PHY_TIMEOUT));
|
||||
|
||||
if (timeout == PHY_TIMEOUT)
|
||||
|
||||
@@ -23,7 +23,7 @@ typedef struct eth_priv_data
|
||||
|
||||
static eth_priv_data_t eth_priv_data;
|
||||
|
||||
static int eth_bus_configure(mk_eth_t *drv, enum mk_eth_ioctl_op op, mk_ioctl_set_info_t *info)
|
||||
static int eth_bus_configure(mk_eth_t *drv, enum mk_eth_ioctl_op op, mk_eth_ioctl_set_info_t *info)
|
||||
{
|
||||
assert(drv);
|
||||
eth_priv_data_t *priv_data = drv->priv_data;
|
||||
|
||||
@@ -59,6 +59,12 @@ int pca9555_set_mode(pca9555_t *io9555, enum pca9555_io_mode mode, uint16_t val)
|
||||
{
|
||||
io9555->imode &= ~val;
|
||||
}
|
||||
ret = lseek(io9555->i2c_fd, (0 << 16) | (io9555->i2c_addr), SEEK_SET);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
return ret;
|
||||
}
|
||||
const uint8_t write_init_data[] = {
|
||||
PCA_REG_CTRL,
|
||||
io9555->imode & 0xff,
|
||||
@@ -84,6 +90,14 @@ int pca9555_output_write(pca9555_t *io9555, uint16_t val)
|
||||
io9555->odata & 0xff,
|
||||
(io9555->odata >> 8) & 0xff,
|
||||
};
|
||||
|
||||
ret = lseek(io9555->i2c_fd, (0 << 16) | (io9555->i2c_addr), SEEK_SET);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = write(io9555->i2c_fd, write_init_data, sizeof(write_init_data));
|
||||
if (ret != sizeof(write_init_data))
|
||||
{
|
||||
|
||||
@@ -153,6 +153,24 @@ static int pin_configure(mk_pin_t *pin, int number, mk_pin_mode_t cfg)
|
||||
gpio_pin_mux_config(pin_port_data, number % 16, cfg.mux_cfg);
|
||||
break;
|
||||
}
|
||||
case MK_PIN_MODE_MUX_OUTPUT_UP:
|
||||
{
|
||||
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
||||
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
|
||||
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
|
||||
gpio_pin_mux_config(pin_port_data, number % 16, cfg.mux_cfg);
|
||||
break;
|
||||
}
|
||||
case MK_PIN_MODE_MUX_OUTPUT_DOWN:
|
||||
{
|
||||
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
||||
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
|
||||
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
|
||||
gpio_pin_mux_config(pin_port_data, number % 16, cfg.mux_cfg);
|
||||
break;
|
||||
}
|
||||
case MK_PIN_MODE_IRQ_RISING:
|
||||
{
|
||||
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
||||
|
||||
89
mkrtos_user/user/drv/ATSURFF437/snd/CMakeLists.txt
Normal file
89
mkrtos_user/user/drv/ATSURFF437/snd/CMakeLists.txt
Normal file
@@ -0,0 +1,89 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAT32F437ZMT7 -DUSE_STDPERIPH_DRIVER -DAT_SURF_F437_V1 ")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DAT32F437ZMT7 -DUSE_STDPERIPH_DRIVER -DAT_SURF_F437_V1 ")
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -DAT32F437ZMT7 -DUSE_STDPERIPH_DRIVER -DAT_SURF_F437_V1 ")
|
||||
|
||||
file(
|
||||
GLOB deps
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/AT32/AT32F435_437_Firmware_Library_V2.2.0/libraries/drivers/src/*.c
|
||||
*.c
|
||||
)
|
||||
|
||||
|
||||
add_executable(
|
||||
snd.elf
|
||||
${deps}
|
||||
${START_SRC}
|
||||
)
|
||||
target_link_libraries(
|
||||
snd.elf
|
||||
PUBLIC
|
||||
-Bstatic
|
||||
${LIBC_NAME}
|
||||
mk_drv
|
||||
mk_char
|
||||
--whole-archive
|
||||
${START_LIB}
|
||||
libc_be
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
printf
|
||||
--no-whole-archive
|
||||
${GCC_LIB_PATH}/libgcc.a
|
||||
)
|
||||
target_include_directories(
|
||||
snd.elf
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/util/inc
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/AT32/AT32F435_437_Firmware_Library_V2.2.0/libraries/drivers/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/AT32/AT32F435_437_Firmware_Library_V2.2.0/libraries/cmsis/cm4/device_support
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/AT32/AT32F435_437_Firmware_Library_V2.2.0/libraries/cmsis/cm4/core_support
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/AT32/AT32F435_437_Firmware_Library_V2.2.0/project/at_surf_f437_board/
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_bsp/AT32/AT32F435_437_Firmware_Library_V2.2.0/middlewares/i2c_application_library
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_snd
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_pin
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_pca9555
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_i2c
|
||||
)
|
||||
add_dependencies(
|
||||
snd.elf
|
||||
${START_LIB}
|
||||
sys
|
||||
sys_util
|
||||
mk_char
|
||||
mk_drv
|
||||
printf
|
||||
# mk_snd
|
||||
)
|
||||
set_target_properties(
|
||||
snd.elf PROPERTIES LINK_FLAGS
|
||||
"-T ${CMAKE_CURRENT_LIST_DIR}/${ARCH_NAME}/link.lds ${CORTEX_M_LINK_FLAGS} --gc-section -no-dynamic-linker "
|
||||
#--no-warn-rwx-segments
|
||||
)
|
||||
add_custom_target(
|
||||
snd_dump ALL
|
||||
COMMAND
|
||||
${CMAKE_OBJDUMP} -s -S snd.elf > ${CMAKE_SOURCE_DIR}/build/output/snd.S
|
||||
COMMAND
|
||||
${CMAKE_READELF} -a snd.elf > ${CMAKE_SOURCE_DIR}/build/output/snd.txt
|
||||
COMMAND
|
||||
${CMAKE_OBJCOPY} -O binary -S snd.elf snd.bin
|
||||
COMMAND
|
||||
${CMAKE_SIZE} snd.elf
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy snd.bin ${CMAKE_SOURCE_DIR}/build/output/cpio/snd
|
||||
COMMAND
|
||||
cp snd.elf ${CMAKE_SOURCE_DIR}/build/output/snd.elf
|
||||
)
|
||||
|
||||
add_dependencies(snd_dump snd.elf)
|
||||
|
||||
124
mkrtos_user/user/drv/ATSURFF437/snd/armv7_8m/link.lds
Normal file
124
mkrtos_user/user/drv/ATSURFF437/snd/armv7_8m/link.lds
Normal file
@@ -0,0 +1,124 @@
|
||||
ENTRY(_start_)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
. = ALIGN(4);
|
||||
__text_start__ = .;
|
||||
KEEP(*(.first))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(SORT(.rodata.*))
|
||||
*(.rodata)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
|
||||
. = ALIGN(4);
|
||||
__rel_start__ = .;
|
||||
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
|
||||
__rel_end__ = .;
|
||||
}
|
||||
.ARM.exidx : {
|
||||
. = ALIGN(4);
|
||||
__exdix_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
/* This is used by the startup in order to initialize the .data secion */
|
||||
__exdix_end = .;
|
||||
}
|
||||
|
||||
.permissions_table : {
|
||||
. = ALIGN(4);
|
||||
__permissions_table_start__ = .;
|
||||
KEEP(*(.permissions_table))
|
||||
__permissions_table_end__ = .;
|
||||
}
|
||||
|
||||
|
||||
PROVIDE(__ram_size__ = __bss_end__ - __data_start__);
|
||||
.data : {
|
||||
. = ALIGN(4);
|
||||
__data_start__ = .;
|
||||
__got_start__ = .;
|
||||
*(.got)
|
||||
__got_end__ = .;
|
||||
. = ALIGN(4);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
_shell_command_start = .;
|
||||
KEEP(*(shellCommand))
|
||||
_shell_command_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
}
|
||||
|
||||
PROVIDE(__heap_size__ = __heap_end__ - __heap_start__);
|
||||
PROVIDE(__stack_size__ = __stack_end__ - __stack_start__);
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
__heap_start__ = .;
|
||||
KEEP(*(.bss.heap))
|
||||
__heap_end__ = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__stack_start__ = .;
|
||||
KEEP(*(.bss.stack))
|
||||
__stack_end__ = .;
|
||||
|
||||
*(.bss.*)
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
}
|
||||
_end = .;
|
||||
}
|
||||
176
mkrtos_user/user/drv/ATSURFF437/snd/at32f435_437_conf.h
Normal file
176
mkrtos_user/user/drv/ATSURFF437/snd/at32f435_437_conf.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file at32f435_437_conf.h
|
||||
* @brief at32f435_437 config header file
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/* define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __AT32F435_437_CONF_H
|
||||
#define __AT32F435_437_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <u_types.h>
|
||||
|
||||
/**
|
||||
* @brief in the following line adjust the value of high speed external crystal (hext)
|
||||
* used in your application
|
||||
*
|
||||
* tip: to avoid modifying this file each time you need to use different hext, you
|
||||
* can define the hext value in your toolchain compiler preprocessor.
|
||||
*
|
||||
*/
|
||||
#if !defined HEXT_VALUE
|
||||
#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief in the following line adjust the high speed external crystal (hext) startup
|
||||
* timeout value
|
||||
*/
|
||||
#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
|
||||
#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */
|
||||
#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */
|
||||
|
||||
/* module define -------------------------------------------------------------*/
|
||||
#define CRM_MODULE_ENABLED
|
||||
#define TMR_MODULE_ENABLED
|
||||
#define ERTC_MODULE_ENABLED
|
||||
#define GPIO_MODULE_ENABLED
|
||||
#define I2C_MODULE_ENABLED
|
||||
#define USART_MODULE_ENABLED
|
||||
#define PWC_MODULE_ENABLED
|
||||
#define CAN_MODULE_ENABLED
|
||||
#define ADC_MODULE_ENABLED
|
||||
#define DAC_MODULE_ENABLED
|
||||
#define SPI_MODULE_ENABLED
|
||||
#define EDMA_MODULE_ENABLED
|
||||
#define DMA_MODULE_ENABLED
|
||||
#define DEBUG_MODULE_ENABLED
|
||||
#define FLASH_MODULE_ENABLED
|
||||
#define CRC_MODULE_ENABLED
|
||||
#define WWDT_MODULE_ENABLED
|
||||
#define WDT_MODULE_ENABLED
|
||||
#define EXINT_MODULE_ENABLED
|
||||
#define SDIO_MODULE_ENABLED
|
||||
#define XMC_MODULE_ENABLED
|
||||
#define USB_MODULE_ENABLED
|
||||
#define ACC_MODULE_ENABLED
|
||||
#define MISC_MODULE_ENABLED
|
||||
#define QSPI_MODULE_ENABLED
|
||||
#define DVP_MODULE_ENABLED
|
||||
#define SCFG_MODULE_ENABLED
|
||||
#define EMAC_MODULE_ENABLED
|
||||
|
||||
/* includes ------------------------------------------------------------------*/
|
||||
#ifdef CRM_MODULE_ENABLED
|
||||
#include "at32f435_437_crm.h"
|
||||
#endif
|
||||
#ifdef TMR_MODULE_ENABLED
|
||||
#include "at32f435_437_tmr.h"
|
||||
#endif
|
||||
#ifdef ERTC_MODULE_ENABLED
|
||||
#include "at32f435_437_ertc.h"
|
||||
#endif
|
||||
#ifdef GPIO_MODULE_ENABLED
|
||||
#include "at32f435_437_gpio.h"
|
||||
#endif
|
||||
#ifdef I2C_MODULE_ENABLED
|
||||
#include "at32f435_437_i2c.h"
|
||||
#endif
|
||||
#ifdef USART_MODULE_ENABLED
|
||||
#include "at32f435_437_usart.h"
|
||||
#endif
|
||||
#ifdef PWC_MODULE_ENABLED
|
||||
#include "at32f435_437_pwc.h"
|
||||
#endif
|
||||
#ifdef CAN_MODULE_ENABLED
|
||||
#include "at32f435_437_can.h"
|
||||
#endif
|
||||
#ifdef ADC_MODULE_ENABLED
|
||||
#include "at32f435_437_adc.h"
|
||||
#endif
|
||||
#ifdef DAC_MODULE_ENABLED
|
||||
#include "at32f435_437_dac.h"
|
||||
#endif
|
||||
#ifdef SPI_MODULE_ENABLED
|
||||
#include "at32f435_437_spi.h"
|
||||
#endif
|
||||
#ifdef DMA_MODULE_ENABLED
|
||||
#include "at32f435_437_dma.h"
|
||||
#endif
|
||||
#ifdef DEBUG_MODULE_ENABLED
|
||||
#include "at32f435_437_debug.h"
|
||||
#endif
|
||||
#ifdef FLASH_MODULE_ENABLED
|
||||
#include "at32f435_437_flash.h"
|
||||
#endif
|
||||
#ifdef CRC_MODULE_ENABLED
|
||||
#include "at32f435_437_crc.h"
|
||||
#endif
|
||||
#ifdef WWDT_MODULE_ENABLED
|
||||
#include "at32f435_437_wwdt.h"
|
||||
#endif
|
||||
#ifdef WDT_MODULE_ENABLED
|
||||
#include "at32f435_437_wdt.h"
|
||||
#endif
|
||||
#ifdef EXINT_MODULE_ENABLED
|
||||
#include "at32f435_437_exint.h"
|
||||
#endif
|
||||
#ifdef SDIO_MODULE_ENABLED
|
||||
#include "at32f435_437_sdio.h"
|
||||
#endif
|
||||
#ifdef XMC_MODULE_ENABLED
|
||||
#include "at32f435_437_xmc.h"
|
||||
#endif
|
||||
#ifdef ACC_MODULE_ENABLED
|
||||
#include "at32f435_437_acc.h"
|
||||
#endif
|
||||
#ifdef MISC_MODULE_ENABLED
|
||||
#include "at32f435_437_misc.h"
|
||||
#endif
|
||||
#ifdef EDMA_MODULE_ENABLED
|
||||
#include "at32f435_437_edma.h"
|
||||
#endif
|
||||
#ifdef QSPI_MODULE_ENABLED
|
||||
#include "at32f435_437_qspi.h"
|
||||
#endif
|
||||
#ifdef SCFG_MODULE_ENABLED
|
||||
#include "at32f435_437_scfg.h"
|
||||
#endif
|
||||
#ifdef EMAC_MODULE_ENABLED
|
||||
#include "at32f435_437_emac.h"
|
||||
#endif
|
||||
#ifdef DVP_MODULE_ENABLED
|
||||
#include "at32f435_437_dvp.h"
|
||||
#endif
|
||||
#ifdef USB_MODULE_ENABLED
|
||||
#include "at32f435_437_usb.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
640
mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.c
Normal file
640
mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.c
Normal file
@@ -0,0 +1,640 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file at_surf_f437_board_audio.c
|
||||
* @brief the driver library of the audio.
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include "at_surf_f437_board_audio.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "string.h"
|
||||
#include "mk_pca9555_drv.h"
|
||||
#include "u_irq_helper.h"
|
||||
#include "mk_i2c_drv.h"
|
||||
#include "u_sleep.h"
|
||||
#include "u_sys.h"
|
||||
#include "mk_pin_drv.h"
|
||||
|
||||
/**
|
||||
* @brief wm8988 register default value
|
||||
*/
|
||||
uint16_t reg_addr_data[] =
|
||||
{
|
||||
(WM8988_R0_LEFT_INPUT_VOLUME << 9) | 0x012F, /*Left Input Channel Volume*/
|
||||
(WM8988_R1_RIGHT_INPUT_VOLUME << 9) | 0x012F, /*Right Input Channel Volume*/
|
||||
(WM8988_R2_LOUT1_VOLUME << 9) | 0x0179, /*Left Output Channel Volume*/
|
||||
(WM8988_R3_ROUT1_VOLUME << 9) | 0x0179, /*Right Output Channel Volume*/
|
||||
(WM8988_R5_ADC_DAC_CONTROL << 9) | 0x0006, /*De-emphasis Control and Digital soft mute*/
|
||||
(WM8988_REG_BITW16),
|
||||
(WM8988_REG_FREQ_48_K),
|
||||
(WM8988_R10_LEFT_DAC_VOLUME << 9) | 0x01FF, /*Left Digital DAC Volume Control*/
|
||||
(WM8988_R11_RIGHT_DAC_VOLUME << 9) | 0x01FF, /*Right Digital DAC Volume Control*/
|
||||
(WM8988_R12_BASS_CONTROL << 9) | 0x000F, /*Bass Control*/
|
||||
(WM8988_R13_TREBLE_CONTROL << 9) | 0x000F, /*Treble Control*/
|
||||
(WM8988_R16_3D_CONTROL << 9) | 0x0000, /*3D stereo Enhancment*/
|
||||
(WM8988_R21_LEFT_ADC_VOLUME << 9) | 0x01C3, /*Left ADC Digital Volume*/
|
||||
(WM8988_R22_RIGHT_ADC_VOLUME << 9) | 0x01C3, /*Right ADC Digital Volume*/
|
||||
(WM8988_R23_ADDITIONAL_1_CONTROL << 9) | 0x00C2, /*Additional Control 1*/
|
||||
(WM8988_R24_ADDITIONAL_2_CONTROL << 9) | 0x0000, /*Additional Control 2*/
|
||||
(WM8988_R27_ADDITIONAL_3_CONTROL << 9) | 0x0000, /*Additional Control 3*/
|
||||
(WM8988_R31_ADC_INPUT_MODE << 9) | 0x0000, /*ADC input mode*/
|
||||
// (WM8988_R32_ADC_L_SIGNAL_PATH << 9) | 0x0040, /*ADC Signal Path Control left LINPUT2*/
|
||||
// (WM8988_R33_ADC_R_SIGNAL_PATH << 9) | 0x0040, /*ADC Signal Path Control right RINPUT2*/
|
||||
(WM8988_R32_ADC_L_SIGNAL_PATH << 9) | 0x0000, /*ADC Signal Path Control left LINPUT1 */
|
||||
(WM8988_R33_ADC_R_SIGNAL_PATH << 9) | 0x0000, /*ADC Signal Path Control right RINPUT1*/
|
||||
(WM8988_R34_LEFT_OUT_MIX_1 << 9) | 0x0152, /*Left DAC mixer Control*/
|
||||
(WM8988_R35_LEFT_OUT_MIX_2 << 9) | 0x0050, /*Left DAC mixer Control*/
|
||||
(WM8988_R36_RIGHT_OUT_MIX_1 << 9) | 0x0052, /*Right DAC mixer Control*/
|
||||
(WM8988_R37_RIGHT_OUT_MIX_2 << 9) | 0x0150, /*Right DAC mixer Control*/
|
||||
(WM8988_R40_LOUT2_VOLUME << 9) | 0x01FF, /*Output left channel volume*/
|
||||
(WM8988_R41_ROUT2_VOLUME << 9) | 0x01FF, /*Output left channel volume*/
|
||||
(WM8988_R43_LOW_POWER_PALYBACK << 9) | 0x0008, /*Output left channel volume*/
|
||||
(WM8988_R25_PWR_1_MGMT << 9) | 0x017C, /*Power Management1*/
|
||||
(WM8988_R26_PWR_2_MGMT << 9) | 0x01F8, /*Power Management2*/
|
||||
};
|
||||
static int pca9555_fd;
|
||||
static int i2c_fd;
|
||||
static int pin_fd;
|
||||
#define DEV_PIN_PATH "/pin"
|
||||
#define DEV_PCA9555_PATH "/pca9555"
|
||||
#define DEV_I2C2_PATH "/i2c2"
|
||||
#define WAV_DECODE_SIZE (367) /* single channel */
|
||||
int16_t music_output_buffer[DMA_BUFFER_SIZE];
|
||||
audio_codec_type audio_codec;
|
||||
uint16_t spk_dma_buffer[DMA_BUFFER_SIZE];
|
||||
uint16_t mic_dma_buffer[DMA_BUFFER_SIZE];
|
||||
void DMA1_Channel3_IRQHandler(void);
|
||||
void DMA1_Channel4_IRQHandler(void);
|
||||
volatile uint32_t i2s_dma_tx_end;
|
||||
volatile uint32_t i2s_dma_rx_end;
|
||||
|
||||
void audio_output_cp(void *src, int len)
|
||||
{
|
||||
audio_wait_data_tx_end();
|
||||
memcpy(spk_dma_buffer, src, len);
|
||||
dma_channel_enable(I2S_DMA_TX_CHANNEL, FALSE);
|
||||
dma_data_number_set(I2S_DMA_TX_CHANNEL, len >> 1);
|
||||
dma_channel_enable(I2S_DMA_TX_CHANNEL, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mclk clock conifg
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void mclk_timer_init(void)
|
||||
{
|
||||
int ret;
|
||||
#if 0
|
||||
gpio_init_type gpio_init_struct;
|
||||
#endif
|
||||
tmr_output_config_type tmr_oc_init_structure;
|
||||
uint16_t prescaler_value = (uint16_t)(sys_read_clk() / 24000000) - 1;
|
||||
|
||||
crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, TRUE);
|
||||
#if 0
|
||||
crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
|
||||
|
||||
gpio_default_para_init(&gpio_init_struct);
|
||||
|
||||
gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE6, GPIO_MUX_3);
|
||||
|
||||
gpio_init_struct.gpio_pins = GPIO_PINS_6;
|
||||
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
||||
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
||||
gpio_init(GPIOC, &gpio_init_struct);
|
||||
#endif
|
||||
again:
|
||||
pin_fd = open(DEV_PIN_PATH, O_RDWR, 0777);
|
||||
|
||||
if (pin_fd < 0)
|
||||
{
|
||||
u_sleep_ms(50);
|
||||
goto again;
|
||||
}
|
||||
ret = ioctl(pin_fd, MK_PIN_SET_MODE, ((mk_pin_cfg_t){
|
||||
.mode = MK_PIN_MODE_MUX_OUTPUT,
|
||||
.pin = (2 * 16) + 6,
|
||||
.cfg = GPIO_MUX_3,
|
||||
})
|
||||
.cfg_raw);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("gpio init failed.\n");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
tmr_base_init(TMR8, 1, prescaler_value);
|
||||
tmr_cnt_dir_set(TMR8, TMR_COUNT_UP);
|
||||
tmr_clock_source_div_set(TMR8, TMR_CLOCK_DIV1);
|
||||
|
||||
tmr_output_default_para_init(&tmr_oc_init_structure);
|
||||
tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
|
||||
tmr_oc_init_structure.oc_idle_state = FALSE;
|
||||
tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
|
||||
tmr_oc_init_structure.oc_output_state = TRUE;
|
||||
tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
|
||||
tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_1, 1);
|
||||
tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_1, TRUE);
|
||||
|
||||
/* tmr enable counter */
|
||||
tmr_counter_enable(TMR8, TRUE);
|
||||
tmr_output_enable(TMR8, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief audio codec i2s reset
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void codec_i2s_reset(void)
|
||||
{
|
||||
i2s_enable(SPI1, FALSE);
|
||||
i2s_enable(I2S_SPIx, FALSE);
|
||||
dma_channel_enable(I2S_DMA_TX_CHANNEL, FALSE);
|
||||
dma_channel_enable(I2S_DMA_RX_CHANNEL, FALSE);
|
||||
}
|
||||
typedef struct pin_cfg
|
||||
{
|
||||
int pin;
|
||||
gpio_mux_sel_type mux_type;
|
||||
int mode;
|
||||
} pin_cfg_t;
|
||||
|
||||
static const pin_cfg_t audio_pins[] = {
|
||||
{(1 * 16 + 13), GPIO_MUX_5, MK_PIN_MODE_MUX_OUTPUT_DOWN},
|
||||
{(1 * 16 + 12), GPIO_MUX_5, MK_PIN_MODE_MUX_OUTPUT_UP},
|
||||
{(1 * 16 + 15), GPIO_MUX_5, MK_PIN_MODE_MUX_OUTPUT_DOWN},
|
||||
{(1 * 16 + 14), GPIO_MUX_6, MK_PIN_MODE_MUX_OUTPUT_UP},
|
||||
};
|
||||
static uint8_t i2s_dma_tx_intr_stack[1024];
|
||||
static obj_handler_t i2s_dma_tx_intr_obj;
|
||||
static uint8_t i2s_dma_rx_intr_stack[1024];
|
||||
static obj_handler_t i2s_dma_rx_intr_obj;
|
||||
/**
|
||||
* @brief audio codec i2s init
|
||||
* @param freq: audio sampling freq
|
||||
* @param bitw_format: bit width
|
||||
* @retval error status
|
||||
*/
|
||||
void codec_i2s_init(audio_codec_type *param)
|
||||
{
|
||||
int ret;
|
||||
dma_init_type dma_init_struct;
|
||||
i2s_init_type i2s_init_struct;
|
||||
|
||||
crm_periph_clock_enable(I2S_CK_GPIO_CLK, TRUE);
|
||||
crm_periph_clock_enable(I2S_WS_GPIO_CLK, TRUE);
|
||||
crm_periph_clock_enable(I2S_SD_OUT_GPIO_CLK, TRUE);
|
||||
crm_periph_clock_enable(I2S_SD_IN_GPIO_CLK, TRUE);
|
||||
|
||||
crm_periph_clock_enable(I2S_DMAx_CLK, TRUE);
|
||||
crm_periph_clock_enable(I2S_SPIx_CLK, TRUE);
|
||||
|
||||
param->spk_tx_size = DMA_BUFFER_SIZE;
|
||||
param->mic_rx_size = DMA_BUFFER_SIZE;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(audio_pins); i++)
|
||||
{
|
||||
ret = ioctl(pin_fd, MK_PIN_SET_MODE, ((mk_pin_cfg_t){
|
||||
.mode = audio_pins[i].mode,
|
||||
.pin = audio_pins[i].pin,
|
||||
.cfg = audio_pins[i].mux_type,
|
||||
})
|
||||
.cfg_raw);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("audio pin set error.\n");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
gpio_init_type gpio_init_struct;
|
||||
gpio_default_para_init(&gpio_init_struct);
|
||||
|
||||
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
|
||||
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
|
||||
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
|
||||
|
||||
/* i2s2 ws pins */
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
|
||||
gpio_init_struct.gpio_pins = I2S_WS_GPIO_PIN;
|
||||
gpio_init(I2S_WS_GPIO_PORT, &gpio_init_struct);
|
||||
gpio_pin_mux_config(I2S_WS_GPIO_PORT, I2S_WS_GPIO_PINS_SOURCE, I2S_WS_GPIO_MUX);
|
||||
|
||||
/* i2s2 ck pins */
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
|
||||
gpio_init_struct.gpio_pins = I2S_CK_GPIO_PIN;
|
||||
gpio_init(I2S_CK_GPIO_PORT, &gpio_init_struct);
|
||||
gpio_pin_mux_config(I2S_CK_GPIO_PORT, I2S_CK_GPIO_PINS_SOURCE, I2S_CK_GPIO_MUX);
|
||||
|
||||
/* i2s2 SD pins */
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
|
||||
gpio_init_struct.gpio_pins = I2S_SD_OUT_GPIO_PIN;
|
||||
gpio_init(I2S_SD_OUT_GPIO_PORT, &gpio_init_struct);
|
||||
gpio_pin_mux_config(I2S_SD_OUT_GPIO_PORT, I2S_SD_OUT_GPIO_PINS_SOURCE, I2S_SD_OUT_GPIO_MUX);
|
||||
|
||||
/* i2s2_EXT pins slave rx */
|
||||
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
|
||||
gpio_init_struct.gpio_pins = I2S_SD_IN_GPIO_PIN;
|
||||
gpio_init(I2S_SD_IN_GPIO_PORT, &gpio_init_struct);
|
||||
gpio_pin_mux_config(I2S_SD_IN_GPIO_PORT, I2S_SD_IN_GPIO_PINS_SOURCE, I2S_SD_IN_GPIO_MUX);
|
||||
#endif
|
||||
/* dma config */
|
||||
dma_reset(I2S_DMA_TX_CHANNEL);
|
||||
dma_reset(I2S_DMA_RX_CHANNEL);
|
||||
|
||||
/* dma1 channel3: speaker i2s1 tx */
|
||||
dma_default_para_init(&dma_init_struct);
|
||||
dma_init_struct.buffer_size = param->spk_tx_size;
|
||||
dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
|
||||
dma_init_struct.memory_base_addr = (uint32_t)spk_dma_buffer;
|
||||
dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
|
||||
dma_init_struct.memory_inc_enable = TRUE;
|
||||
dma_init_struct.peripheral_base_addr = (uint32_t)I2S_DT_ADDRESS;
|
||||
dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
|
||||
dma_init_struct.peripheral_inc_enable = FALSE;
|
||||
dma_init_struct.priority = DMA_PRIORITY_HIGH;
|
||||
dma_init_struct.loop_mode_enable = FALSE;
|
||||
dma_init(I2S_DMA_TX_CHANNEL, &dma_init_struct);
|
||||
dma_interrupt_enable(I2S_DMA_TX_CHANNEL, DMA_FDT_INT, TRUE);
|
||||
// dma_interrupt_enable(I2S_DMA_TX_CHANNEL, DMA_HDT_INT, TRUE);
|
||||
// nvic_irq_enable(I2S_DMA_TX_IRQn, 1, 0);
|
||||
|
||||
ret = u_irq_request(I2S_DMA_TX_IRQn, (void *)(i2s_dma_tx_intr_stack + sizeof(i2s_dma_tx_intr_stack)),
|
||||
NULL, &i2s_dma_tx_intr_obj, DMA1_Channel3_IRQHandler, u_irq_prio_create(1, 0));
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("irq request error.\n");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
/* dma1 channel4: microphone i2s2 rx */
|
||||
dma_default_para_init(&dma_init_struct);
|
||||
dma_init_struct.buffer_size = param->mic_rx_size;
|
||||
dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
|
||||
dma_init_struct.memory_base_addr = (uint32_t)mic_dma_buffer;
|
||||
dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
|
||||
dma_init_struct.memory_inc_enable = TRUE;
|
||||
dma_init_struct.peripheral_base_addr = (uint32_t)(&(I2S_EXTx->dt));
|
||||
dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
|
||||
dma_init_struct.peripheral_inc_enable = FALSE;
|
||||
dma_init_struct.priority = DMA_PRIORITY_HIGH;
|
||||
dma_init_struct.loop_mode_enable = FALSE;
|
||||
dma_init(I2S_DMA_RX_CHANNEL, &dma_init_struct);
|
||||
dma_interrupt_enable(I2S_DMA_RX_CHANNEL, DMA_FDT_INT, TRUE);
|
||||
// dma_interrupt_enable(I2S_DMA_RX_CHANNEL, DMA_HDT_INT, TRUE);
|
||||
// nvic_irq_enable(I2S_DMA_RX_IRQn, 2, 0);
|
||||
|
||||
ret = u_irq_request(I2S_DMA_RX_IRQn, (void *)(i2s_dma_rx_intr_stack + sizeof(i2s_dma_rx_intr_stack)),
|
||||
NULL, &i2s_dma_rx_intr_obj, DMA1_Channel4_IRQHandler, u_irq_prio_create(2, 0));
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("irq request error.\n");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
/* i2s2 rx init */
|
||||
/* i2s2 Tx init */
|
||||
spi_i2s_reset(I2S_SPIx);
|
||||
i2s_default_para_init(&i2s_init_struct);
|
||||
i2s_init_struct.audio_protocol = I2S_AUDIO_PROTOCOL_PHILLIPS;
|
||||
i2s_init_struct.data_channel_format = I2S_DATA_16BIT_CHANNEL_16BIT;
|
||||
i2s_init_struct.mclk_output_enable = TRUE;
|
||||
i2s_init_struct.audio_sampling_freq = I2S_AUDIO_FREQUENCY_48K;
|
||||
i2s_init_struct.clock_polarity = I2S_CLOCK_POLARITY_LOW;
|
||||
i2s_init_struct.operation_mode = I2S_MODE_SLAVE_TX;
|
||||
i2s_init(I2S_SPIx, &i2s_init_struct);
|
||||
/* i2s2EXT Rx init */
|
||||
i2s_init_struct.operation_mode = I2S_MODE_SLAVE_RX;
|
||||
i2s_init(I2S_EXTx, &i2s_init_struct);
|
||||
|
||||
spi_i2s_dma_transmitter_enable(I2S_SPIx, TRUE);
|
||||
spi_i2s_dma_receiver_enable(I2S_EXTx, TRUE);
|
||||
|
||||
dmamux_enable(I2S_DMAx, TRUE);
|
||||
dmamux_init(I2S_DMA_TX_DMAMUX_CHANNEL, I2S_DMA_TX_DMAREQ);
|
||||
dmamux_init(I2S_DMA_RX_DMAMUX_CHANNEL, I2S_DMA_RX_DMAREQ);
|
||||
dma_channel_enable(I2S_DMA_TX_CHANNEL, TRUE);
|
||||
dma_channel_enable(I2S_DMA_RX_CHANNEL, TRUE);
|
||||
|
||||
i2s_enable(I2S_EXTx, TRUE);
|
||||
i2s_enable(I2S_SPIx, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief power on
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void audio_pa_power_on(void)
|
||||
{
|
||||
#if 0
|
||||
pca9555_out_mode_config(AUDIO_PA_ON_PIN);
|
||||
|
||||
pca9555_bits_reset(AUDIO_PA_ON_PIN);
|
||||
#endif
|
||||
ioctl(pca9555_fd, PCA9555_SET_OUTPUT_MODE, AUDIO_PA_ON_PIN);
|
||||
ioctl(pca9555_fd, PCA9555_IO_RESET, AUDIO_PA_ON_PIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief power off
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void audio_pa_power_off(void)
|
||||
{
|
||||
#if 0
|
||||
pca9555_out_mode_config(AUDIO_PA_ON_PIN);
|
||||
|
||||
pca9555_bits_set(AUDIO_PA_ON_PIN);
|
||||
#endif
|
||||
ioctl(pca9555_fd, PCA9555_SET_OUTPUT_MODE, AUDIO_PA_ON_PIN);
|
||||
ioctl(pca9555_fd, PCA9555_IO_SET, AUDIO_PA_ON_PIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief audio codec init
|
||||
* @param none
|
||||
* @retval error status
|
||||
*/
|
||||
error_status audio_init(void)
|
||||
{
|
||||
uint32_t reg_len = sizeof(reg_addr_data) / sizeof(uint16_t);
|
||||
uint32_t i = 0;
|
||||
uint8_t i2c_cmd[2];
|
||||
int ret;
|
||||
|
||||
again:
|
||||
pca9555_fd = open(DEV_PCA9555_PATH, O_RDWR, 0777);
|
||||
if (pca9555_fd < 0)
|
||||
{
|
||||
u_sleep_ms(50);
|
||||
goto again;
|
||||
}
|
||||
again2:
|
||||
i2c_fd = open(DEV_I2C2_PATH, O_RDWR, 0777);
|
||||
if (i2c_fd < 0)
|
||||
{
|
||||
u_sleep_ms(50);
|
||||
goto again2;
|
||||
}
|
||||
|
||||
audio_pa_power_on();
|
||||
ret = lseek(i2c_fd, (0 << 16) | (WM8988_I2C_ADDR_CSB_LOW), SEEK_SET);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
return ret;
|
||||
}
|
||||
for (i = 0; i < reg_len; i++)
|
||||
{
|
||||
i2c_cmd[0] = (uint8_t)(reg_addr_data[i] >> 8);
|
||||
|
||||
i2c_cmd[1] = (uint8_t)reg_addr_data[i] & 0xFF;
|
||||
|
||||
ret = write(i2c_fd, i2c_cmd, 2);
|
||||
if (ret != 2)
|
||||
{
|
||||
printf("error:%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* timer init */
|
||||
mclk_timer_init();
|
||||
|
||||
codec_i2s_init(&audio_codec);
|
||||
|
||||
audio_codec_modify_freq(WM8988_REG_FREQ_22_05K);
|
||||
|
||||
audio_dma_counter_set(WAV_DECODE_SIZE);
|
||||
|
||||
// audio_wait_data_tx_end();
|
||||
|
||||
audio_spk_volume_set(220, 220);
|
||||
|
||||
#if 1
|
||||
for (int i = 0; i < DMA_BUFFER_SIZE; i++)
|
||||
{
|
||||
music_output_buffer[i] = 0;
|
||||
}
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set audio volume
|
||||
* @param left_volume
|
||||
* @param right_volume
|
||||
* @retval error_status
|
||||
*/
|
||||
error_status audio_spk_volume_set(uint8_t left_volume, uint8_t right_volume)
|
||||
{
|
||||
|
||||
uint16_t audio_left;
|
||||
uint16_t audio_right;
|
||||
int ret;
|
||||
|
||||
uint8_t i2c_cmd[2];
|
||||
|
||||
audio_left = WM8988_R10_LEFT_DAC_VOLUME << 9 | 0x100 | left_volume;
|
||||
audio_right = WM8988_R11_RIGHT_DAC_VOLUME << 9 | 0x100 | right_volume;
|
||||
|
||||
i2c_cmd[0] = (uint8_t)(audio_left >> 8);
|
||||
i2c_cmd[1] = (uint8_t)audio_left & 0xFF;
|
||||
|
||||
ret = write(i2c_fd, i2c_cmd, 2);
|
||||
if (ret != 2)
|
||||
{
|
||||
printf("error:%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
i2c_cmd[0] = (uint8_t)(audio_right >> 8);
|
||||
i2c_cmd[1] = (uint8_t)audio_right & 0xFF;
|
||||
|
||||
ret = write(i2c_fd, i2c_cmd, 2);
|
||||
if (ret != 2)
|
||||
{
|
||||
printf("error:%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
return ERROR;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief audio codec modify freq
|
||||
* @param freq: freq (wm8988 microphone and speaker must as same freq)
|
||||
WM8988_REG_FREQ_8_K
|
||||
WM8988_REG_FREQ_8_0214_K
|
||||
WM8988_REG_FREQ_11_025_K
|
||||
WM8988_REG_FREQ_12_K
|
||||
WM8988_REG_FREQ_16K
|
||||
WM8988_REG_FREQ_22_05K
|
||||
WM8988_REG_FREQ_24K
|
||||
WM8988_REG_FREQ_32_K
|
||||
WM8988_REG_FREQ_44_1_K
|
||||
WM8988_REG_FREQ_48_K
|
||||
WM8988_REG_FREQ_88_235K
|
||||
WM8988_REG_FREQ_96_K
|
||||
* @retval none
|
||||
*/
|
||||
void audio_codec_modify_freq(uint16_t freq)
|
||||
{
|
||||
int ret;
|
||||
uint8_t i2c_cmd[2];
|
||||
|
||||
i2c_cmd[0] = (uint8_t)(freq >> 8);
|
||||
|
||||
i2c_cmd[1] = (uint8_t)freq & 0xFF;
|
||||
|
||||
ret = write(i2c_fd, i2c_cmd, 2);
|
||||
if (ret != 2)
|
||||
{
|
||||
printf("error:%s:%d ret:%d\n", __func__, __LINE__, ret);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief audio codec modify freq
|
||||
* @param freq: freq (wm8988 microphone and speaker must as same freq)
|
||||
WM8988_REG_FREQ_8_K
|
||||
WM8988_REG_FREQ_8_0214_K
|
||||
WM8988_REG_FREQ_11_025_K
|
||||
WM8988_REG_FREQ_12_K
|
||||
WM8988_REG_FREQ_16K
|
||||
WM8988_REG_FREQ_22_05K
|
||||
WM8988_REG_FREQ_24K
|
||||
WM8988_REG_FREQ_32_K
|
||||
WM8988_REG_FREQ_44_1_K
|
||||
WM8988_REG_FREQ_48_K
|
||||
WM8988_REG_FREQ_88_235K
|
||||
WM8988_REG_FREQ_96_K
|
||||
* @retval none
|
||||
*/
|
||||
void audio_dma_counter_set(uint16_t counter)
|
||||
{
|
||||
audio_codec.spk_tx_size = counter * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief wait data transmit end
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void audio_wait_data_tx_end(void)
|
||||
{
|
||||
while (i2s_dma_tx_end == 0)
|
||||
;
|
||||
|
||||
i2s_dma_tx_end = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief audio codec modify freq
|
||||
* @param counter: freq (wm8988 microphone and speaker must as same freq)
|
||||
* @retval none
|
||||
*/
|
||||
void modify_dma_tx_counter(uint16_t counter)
|
||||
{
|
||||
static uint16_t counter_last = 0xFFFF;
|
||||
|
||||
/* the frequency value changes */
|
||||
if (counter_last != counter)
|
||||
{
|
||||
dma_channel_enable(I2S_DMA_TX_CHANNEL, FALSE);
|
||||
|
||||
dma_data_number_set(I2S_DMA_TX_CHANNEL, counter);
|
||||
|
||||
dma_channel_enable(I2S_DMA_TX_CHANNEL, TRUE);
|
||||
|
||||
audio_codec.spk_tx_size = counter;
|
||||
|
||||
counter_last = counter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function handles dma1 channel3 interrupt.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void DMA1_Channel3_IRQHandler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
msg_tag_t tag = uirq_wait(i2s_dma_tx_intr_obj, 0);
|
||||
if (msg_tag_get_val(tag) >= 0)
|
||||
{
|
||||
if (dma_interrupt_flag_get(I2S_DMA_TX_HDT_FLAG) == SET)
|
||||
{
|
||||
dma_flag_clear(I2S_DMA_TX_HDT_FLAG);
|
||||
}
|
||||
else if (dma_interrupt_flag_get(I2S_DMA_TX_FDT_FLAG) == SET)
|
||||
{
|
||||
// memcpy(spk_dma_buffer, (uint16_t *)music_output_buffer, DMA_BUFFER_SIZE);
|
||||
// modify_dma_tx_counter(audio_codec.spk_tx_size);
|
||||
i2s_dma_tx_end = 1;
|
||||
dma_flag_clear(I2S_DMA_TX_FDT_FLAG);
|
||||
}
|
||||
uirq_ack(i2s_dma_tx_intr_obj, I2S_DMA_TX_IRQn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief this function handles dma1 channel4 interrupt.
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void DMA1_Channel4_IRQHandler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
msg_tag_t tag = uirq_wait(i2s_dma_rx_intr_obj, 0);
|
||||
if (msg_tag_get_val(tag) >= 0)
|
||||
{
|
||||
if (dma_interrupt_flag_get(I2S_DMA_RX_HDT_FLAG) == SET)
|
||||
{
|
||||
dma_flag_clear(I2S_DMA_RX_HDT_FLAG);
|
||||
}
|
||||
else if (dma_interrupt_flag_get(I2S_DMA_RX_FDT_FLAG) == SET)
|
||||
{
|
||||
dma_flag_clear(I2S_DMA_RX_FDT_FLAG);
|
||||
}
|
||||
uirq_ack(i2s_dma_rx_intr_obj, I2S_DMA_RX_IRQn);
|
||||
}
|
||||
}
|
||||
}
|
||||
200
mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.h
Normal file
200
mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.h
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file at_surf_f437_board_audio.c
|
||||
* @brief header file for at-start board. set of firmware functions to
|
||||
* manage leds and push-button. initialize delay function.
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __AT32_SURF_F437_BOARD_AUDIO_H
|
||||
#define __AT32_SURF_F437_BOARD_AUDIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "at32f435_437_conf.h"
|
||||
#include "u_types.h"
|
||||
/**
|
||||
* @brief wm8988 register
|
||||
*/
|
||||
#define WM8988_R0_LEFT_INPUT_VOLUME 0x00
|
||||
#define WM8988_R1_RIGHT_INPUT_VOLUME 0x01
|
||||
#define WM8988_R2_LOUT1_VOLUME 0x02
|
||||
#define WM8988_R3_ROUT1_VOLUME 0x03
|
||||
#define WM8988_R4_RESERVED 0x04
|
||||
#define WM8988_R5_ADC_DAC_CONTROL 0x05
|
||||
#define WM8988_R6_RESERVED 0x06
|
||||
#define WM8988_R7_AUDIO_INTERFACE 0x07
|
||||
#define WM8988_R8_SAMPLE_RATE 0x08
|
||||
#define WM8988_R9_RESERVED 0x09
|
||||
#define WM8988_R10_LEFT_DAC_VOLUME 0x0A
|
||||
#define WM8988_R11_RIGHT_DAC_VOLUME 0x0B
|
||||
#define WM8988_R12_BASS_CONTROL 0x0C
|
||||
#define WM8988_R13_TREBLE_CONTROL 0x0D
|
||||
#define WM8988_R14_
|
||||
#define WM8988_R15_RESET 0x0F
|
||||
#define WM8988_R16_3D_CONTROL 0x10
|
||||
#define WM8988_R17_ALC1 0x11
|
||||
#define WM8988_R18_ALC2 0x12
|
||||
#define WM8988_R19_ALC3 0x13
|
||||
#define WM8988_R20_NOISE_GATE 0x14
|
||||
#define WM8988_R21_LEFT_ADC_VOLUME 0x15
|
||||
#define WM8988_R22_RIGHT_ADC_VOLUME 0x16
|
||||
#define WM8988_R23_ADDITIONAL_1_CONTROL 0x17
|
||||
#define WM8988_R24_ADDITIONAL_2_CONTROL 0x18
|
||||
#define WM8988_R25_PWR_1_MGMT 0x19
|
||||
#define WM8988_R26_PWR_2_MGMT 0x1A
|
||||
#define WM8988_R27_ADDITIONAL_3_CONTROL 0x1B
|
||||
|
||||
#define WM8988_R31_ADC_INPUT_MODE 0x1F
|
||||
#define WM8988_R32_ADC_L_SIGNAL_PATH 0x20
|
||||
#define WM8988_R33_ADC_R_SIGNAL_PATH 0x21
|
||||
#define WM8988_R34_LEFT_OUT_MIX_1 0x22
|
||||
#define WM8988_R35_LEFT_OUT_MIX_2 0x23
|
||||
#define WM8988_R36_RIGHT_OUT_MIX_1 0x24
|
||||
#define WM8988_R37_RIGHT_OUT_MIX_2 0x25
|
||||
#define WM8988_R38_RESERVED
|
||||
#define WM8988_R39_RESERVED
|
||||
#define WM8988_R40_LOUT2_VOLUME 0x28
|
||||
#define WM8988_R41_ROUT2_VOLUME 0x29
|
||||
#define WM8988_R42_RESERVED
|
||||
#define WM8988_R43_LOW_POWER_PALYBACK 0x43
|
||||
|
||||
#define WM8988_I2C_ADDR_CSB_LOW 0x34
|
||||
#define WM8988_I2C_ADDR_CSB_HIGH 0x36
|
||||
|
||||
/**
|
||||
* @brief wm8988 freq
|
||||
*/
|
||||
#define WM8988_REG_FREQ_8_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x000C) /* 8 kHz */
|
||||
#define WM8988_REG_FREQ_8_0214_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x002E) /* 8.0214 kHz */
|
||||
#define WM8988_REG_FREQ_11_025_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0032) /* 11.0259 kHz */
|
||||
#define WM8988_REG_FREQ_12_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0010) /* 12 kHz */
|
||||
#define WM8988_REG_FREQ_16K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0014) /* 16kHz */
|
||||
#define WM8988_REG_FREQ_22_05K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0036) /* 22.0588kHz */
|
||||
#define WM8988_REG_FREQ_24K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0038) /* 24kHz */
|
||||
#define WM8988_REG_FREQ_32_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0018) /* 32 kHz */
|
||||
#define WM8988_REG_FREQ_44_1_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0022) /* 44.118 kHz */
|
||||
#define WM8988_REG_FREQ_48_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x0000) /* 48 kHz */
|
||||
#define WM8988_REG_FREQ_88_235K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x003E) /* 88.235kHz */
|
||||
#define WM8988_REG_FREQ_96_K ((WM8988_R8_SAMPLE_RATE << 9) | 0x0081 | 0x001C) /* 96 kHz */
|
||||
|
||||
/**
|
||||
* @brief wm8988 bit width
|
||||
*/
|
||||
#define WM8988_REG_BITW16 ((WM8988_R7_AUDIO_INTERFACE << 9) | 0x0042)
|
||||
|
||||
/** @defgroup USB_device_audio_codec_exported_functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief wm8988 buffer size
|
||||
*/
|
||||
#define DMA_BUFFER_SIZE 367
|
||||
|
||||
|
||||
#define AUDIO_FREQ_16K 16000
|
||||
#define AUDIO_FREQ_48K 48000
|
||||
#define AUDIO_BITW_16 16
|
||||
|
||||
#define AUDIO_MIC_CHANEL_NUM 2
|
||||
#define AUDIO_MIC_DEFAULT_BITW AUDIO_BITW_16
|
||||
|
||||
#define AUDIO_SPK_CHANEL_NUM 2
|
||||
#define AUDIO_SPK_DEFAULT_BITW AUDIO_BITW_16
|
||||
|
||||
/**
|
||||
* @brief wm8988 pin definition
|
||||
*/
|
||||
#define I2S_DMAx_CLK CRM_DMA1_PERIPH_CLOCK
|
||||
#define I2S_SPIx_CLK CRM_SPI2_PERIPH_CLOCK
|
||||
|
||||
#define I2S_SPIx SPI2
|
||||
#define I2S_EXTx I2S2EXT
|
||||
#define I2S_DMAx DMA1
|
||||
#define I2S_DT_ADDRESS (&(SPI2->dt))
|
||||
|
||||
#define I2S_CK_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
|
||||
#define I2S_CK_GPIO_PIN GPIO_PINS_13
|
||||
#define I2S_CK_GPIO_PINS_SOURCE GPIO_PINS_SOURCE13
|
||||
#define I2S_CK_GPIO_PORT GPIOB
|
||||
#define I2S_CK_GPIO_MUX GPIO_MUX_5
|
||||
|
||||
#define I2S_WS_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
|
||||
#define I2S_WS_GPIO_PIN GPIO_PINS_12
|
||||
#define I2S_WS_GPIO_PINS_SOURCE GPIO_PINS_SOURCE12
|
||||
#define I2S_WS_GPIO_PORT GPIOB
|
||||
#define I2S_WS_GPIO_MUX GPIO_MUX_5
|
||||
|
||||
#define I2S_SD_OUT_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
|
||||
#define I2S_SD_OUT_GPIO_PIN GPIO_PINS_15
|
||||
#define I2S_SD_OUT_GPIO_PINS_SOURCE GPIO_PINS_SOURCE15
|
||||
#define I2S_SD_OUT_GPIO_PORT GPIOB
|
||||
#define I2S_SD_OUT_GPIO_MUX GPIO_MUX_5
|
||||
|
||||
#define I2S_SD_IN_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
|
||||
#define I2S_SD_IN_GPIO_PIN GPIO_PINS_14
|
||||
#define I2S_SD_IN_GPIO_PINS_SOURCE GPIO_PINS_SOURCE14
|
||||
#define I2S_SD_IN_GPIO_PORT GPIOB
|
||||
#define I2S_SD_IN_GPIO_MUX GPIO_MUX_6
|
||||
|
||||
#define AUDIO_PA_ON_PIN PCA_IO0_PINS_2
|
||||
|
||||
#define I2S_DMA_TX_CHANNEL DMA1_CHANNEL3
|
||||
#define I2S_DMA_TX_DMAMUX_CHANNEL DMA1MUX_CHANNEL3
|
||||
#define I2S_DMA_TX_DMAREQ DMAMUX_DMAREQ_ID_SPI2_TX
|
||||
#define I2S_DMA_TX_IRQn DMA1_Channel3_IRQn
|
||||
// #define I2S_DMA_TX_IRQHandler DMA1_Channel3_IRQHandler
|
||||
#define I2S_DMA_TX_HDT_FLAG DMA1_HDT3_FLAG
|
||||
#define I2S_DMA_TX_FDT_FLAG DMA1_FDT3_FLAG
|
||||
|
||||
#define I2S_DMA_RX_CHANNEL DMA1_CHANNEL4
|
||||
#define I2S_DMA_RX_DMAMUX_CHANNEL DMA1MUX_CHANNEL4
|
||||
#define I2S_DMA_RX_DMAREQ DMAMUX_DMAREQ_ID_I2S2_EXT_RX
|
||||
#define I2S_DMA_RX_IRQn DMA1_Channel4_IRQn
|
||||
// #define I2S_DMA_RX_IRQHandler DMA1_Channel4_IRQHandler
|
||||
#define I2S_DMA_RX_HDT_FLAG DMA1_HDT4_FLAG
|
||||
#define I2S_DMA_RX_FDT_FLAG DMA1_FDT4_FLAG
|
||||
|
||||
/**
|
||||
* @brief audio codec interface
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t spk_tx_size;
|
||||
uint32_t mic_rx_size;
|
||||
}audio_codec_type;
|
||||
|
||||
/**
|
||||
* @brief audio codec interface
|
||||
*/
|
||||
error_status audio_init(void);
|
||||
error_status audio_spk_volume_set(uint8_t left_volume, uint8_t right_volume);
|
||||
void audio_codec_modify_freq(uint16_t freq);
|
||||
void audio_dma_counter_set(uint16_t counter);
|
||||
extern audio_codec_type audio_codec;
|
||||
void audio_wait_data_tx_end(void);
|
||||
void audio_output_cp(void *src, int len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
17
mkrtos_user/user/drv/ATSURFF437/snd/heap_stack.c
Normal file
17
mkrtos_user/user/drv/ATSURFF437/snd/heap_stack.c
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
#define HEAP_SIZE (2048)
|
||||
#define STACK_SIZE (1024 * 2)
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
#define HEAP_ATTR SECTION("HEAP") __attribute__((zero_init))
|
||||
#define STACK_ATTR SECTION("STACK") __attribute__((zero_init))
|
||||
#elif defined(__GNUC__)
|
||||
#define HEAP_ATTR __attribute__((__section__(".bss.heap")))
|
||||
#define STACK_ATTR __attribute__((__section__(".bss.stack")))
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#define HEAP_ATTR
|
||||
#define STACK_ATTR
|
||||
#endif
|
||||
|
||||
__attribute__((used)) HEAP_ATTR static char _____heap_____[HEAP_SIZE];
|
||||
__attribute__((used)) STACK_ATTR static char _____stack_____[STACK_SIZE];
|
||||
81
mkrtos_user/user/drv/ATSURFF437/snd/main.c
Normal file
81
mkrtos_user/user/drv/ATSURFF437/snd/main.c
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <u_vmam.h>
|
||||
#include <at32f435_437_conf.h>
|
||||
#include <u_sleep.h>
|
||||
#include <u_sys.h>
|
||||
#include <u_task.h>
|
||||
#include <mk_dtb_parse.h>
|
||||
#include <mk_dev.h>
|
||||
#include <mk_drv.h>
|
||||
#include "ns_cli.h"
|
||||
#include "rpc_prot.h"
|
||||
#include "u_hd_man.h"
|
||||
#include "u_share_mem.h"
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <snd_drv_svr.h>
|
||||
|
||||
#include "mk_snd_drv_impl.h"
|
||||
static snd_drv_t snd_drv; //!< 网络驱动的协议
|
||||
|
||||
int snd_drv_write(obj_handler_t obj, int len)
|
||||
{
|
||||
int ret = -1;
|
||||
addr_t addr = 0;
|
||||
umword_t size = 0;
|
||||
msg_tag_t tag = share_mem_map(obj, vma_addr_create(VPAGE_PROT_RWX, 0, 0), &addr, &size);
|
||||
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
handler_free_umap(obj);
|
||||
printf("snd write error.\n");
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
|
||||
audio_output_cp((uint8_t *)addr, len);
|
||||
// mk_printf("snd write len:%d.\n", MIN(size, len));
|
||||
handler_free_umap(obj);
|
||||
return len;
|
||||
}
|
||||
int snd_drv_read(obj_handler_t obj, int len)
|
||||
{
|
||||
int ret = -1;
|
||||
addr_t addr = 0;
|
||||
umword_t size = 0;
|
||||
msg_tag_t tag = share_mem_map(obj, vma_addr_create(VPAGE_PROT_RWX, 0, 0), &addr, &size);
|
||||
uint32_t _err;
|
||||
|
||||
// ret = emac_read_packet((uint8_t *)addr, size);
|
||||
handler_free_umap(obj);
|
||||
return ret;
|
||||
}
|
||||
int snd_drv_map(obj_handler_t *hd)
|
||||
{
|
||||
// *hd = emac_get_sema();
|
||||
return -1;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
obj_handler_t hd;
|
||||
int ret;
|
||||
task_set_obj_name(TASK_THIS, TASK_THIS, "tk_snd");
|
||||
task_set_obj_name(TASK_THIS, THREAD_MAIN, "th_snd");
|
||||
printf("%s init..\n", argv[0]);
|
||||
mk_drv_init();
|
||||
mk_dev_init();
|
||||
drv_snd_init();
|
||||
dtb_parse_init();
|
||||
|
||||
snd_drv_init(&snd_drv);
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
ns_register("/snd", hd, FILE_NODE);
|
||||
meta_reg_svr_obj(&snd_drv.svr, SND_DRV_PROT);
|
||||
while (1)
|
||||
{
|
||||
rpc_loop();
|
||||
}
|
||||
}
|
||||
92
mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.c
Normal file
92
mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.c
Normal file
@@ -0,0 +1,92 @@
|
||||
|
||||
|
||||
#include <u_types.h>
|
||||
#include <errno.h>
|
||||
#include <libfdt.h>
|
||||
#include <mk_dev.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "mk_drv.h"
|
||||
#include "mk_snd_drv.h"
|
||||
#include "mk_dtb_parse.h"
|
||||
#include <u_prot.h>
|
||||
#include <u_vmam.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include "mk_snd_drv_impl.h"
|
||||
#include "at_surf_f437_board_audio.h"
|
||||
|
||||
typedef struct snd_priv_data
|
||||
{
|
||||
} snd_priv_data_t;
|
||||
|
||||
static snd_priv_data_t snd_priv_data;
|
||||
|
||||
static int snd_bus_configure(mk_snd_t *drv)
|
||||
{
|
||||
assert(drv);
|
||||
snd_priv_data_t *priv_data = drv->priv_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int snd_bus_read(mk_snd_t *drv, uint8_t *data, int len)
|
||||
{
|
||||
|
||||
return -1;
|
||||
}
|
||||
static int snd_bus_write(mk_snd_t *drv, uint8_t *data, int len)
|
||||
{
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static mk_snd_ops_t snd_ops = {
|
||||
.snd_configure = snd_bus_configure,
|
||||
.snd_read = snd_bus_read,
|
||||
.snd_write = snd_bus_write,
|
||||
};
|
||||
static mk_snd_dev_t snd_dev = {
|
||||
.ops = &snd_ops,
|
||||
.snd.priv_data = &snd_priv_data,
|
||||
};
|
||||
|
||||
static int snd_probe(mk_dev_t *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* ioremap */
|
||||
ret = dev_regs_map(dev, dev->dtb);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("snd dev regs map failed.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (audio_init() != SUCCESS)
|
||||
{
|
||||
printf("audio init failed.\n");
|
||||
return -EIO;
|
||||
}
|
||||
printf("snd init success.\r\n");
|
||||
/* 注册snd设备 */
|
||||
// mk_snd_register(dev, &snd_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mk_drv_compatible_t drv_compatilbe[] =
|
||||
{
|
||||
{"at32f43x,snd"},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static mk_drv_t snd_drv =
|
||||
{
|
||||
.compatilbe = drv_compatilbe,
|
||||
.probe = snd_probe,
|
||||
.data = NULL,
|
||||
};
|
||||
void drv_snd_init(void)
|
||||
{
|
||||
mk_drv_register(&snd_drv);
|
||||
}
|
||||
5
mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.h
Normal file
5
mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "at_surf_f437_board_audio.h"
|
||||
|
||||
void drv_snd_init(void);
|
||||
@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMKRTOS_DRV " )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMKRTOS_DRV ")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_ASM_FLAGS} -DMKRTOS_DRV ")
|
||||
# if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${CONFIG_BOARD_NAME})
|
||||
# add_subdirectory(${CONFIG_BOARD_NAME})
|
||||
# endif()
|
||||
add_subdirectory(ATSURFF437)
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${CONFIG_BOARD_NAME})
|
||||
add_subdirectory(${CONFIG_BOARD_NAME})
|
||||
endif()
|
||||
# add_subdirectory(ATSURFF437)
|
||||
add_subdirectory(lib)
|
||||
|
||||
@@ -80,7 +80,7 @@ static int mk_eth_drv_ioctl(mk_dev_t *pin, int cmd, umword_t args)
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
ret = mk_copy_mem_to_task(src_pid, (void *)args,
|
||||
cur_pid, &info, sizeof(mk_ioctl_set_info_t));
|
||||
cur_pid, &info, sizeof(mk_eth_ioctl_set_info_t));
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
|
||||
@@ -8,10 +8,10 @@ enum mk_eth_ioctl_op
|
||||
ETH_SET_MAC_ADDR,
|
||||
};
|
||||
|
||||
typedef struct mk_ioctl_set_info
|
||||
typedef struct mk_eth_ioctl_set_info
|
||||
{
|
||||
uint8_t mac_addr[6];
|
||||
} mk_ioctl_set_info_t;
|
||||
} mk_eth_ioctl_set_info_t;
|
||||
/**
|
||||
* @brief eth设备数据
|
||||
*
|
||||
@@ -26,7 +26,7 @@ typedef struct mk_eth
|
||||
*/
|
||||
typedef struct mk_eth_ops
|
||||
{
|
||||
int (*eth_configure)(mk_eth_t *drv, enum mk_eth_ioctl_op op, mk_ioctl_set_info_t *info);
|
||||
int (*eth_configure)(mk_eth_t *drv, enum mk_eth_ioctl_op op, mk_eth_ioctl_set_info_t *info);
|
||||
int (*eth_read)(mk_eth_t *drv, uint8_t *data, int len);
|
||||
int (*eth_write)(mk_eth_t *drv, uint8_t *dat, int len);
|
||||
} mk_eth_ops_t;
|
||||
|
||||
@@ -56,6 +56,8 @@ enum mk_pin_mode_cfg
|
||||
|
||||
MK_PIN_MODE_MUX_OUTPUT,
|
||||
MK_PIN_MODE_MUX_OUTPUT_OD,
|
||||
MK_PIN_MODE_MUX_OUTPUT_UP,
|
||||
MK_PIN_MODE_MUX_OUTPUT_DOWN,
|
||||
|
||||
MK_PIN_MODE_IRQ_RISING,
|
||||
MK_PIN_MODE_IRQ_FALLING,
|
||||
|
||||
38
mkrtos_user/user/drv/lib/mk_snd/CMakeLists.txt
Normal file
38
mkrtos_user/user/drv/lib/mk_snd/CMakeLists.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
|
||||
file(GLOB_RECURSE deps *.c *.S)
|
||||
add_library(
|
||||
mk_snd
|
||||
STATIC
|
||||
${deps}
|
||||
)
|
||||
target_link_libraries(
|
||||
mk_snd
|
||||
PRIVATE
|
||||
fdt
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
mk_drv
|
||||
)
|
||||
add_dependencies(
|
||||
mk_snd
|
||||
fdt
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
mk_drv
|
||||
)
|
||||
target_include_directories(
|
||||
mk_snd
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../mk_drv
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/user/drv/lib/mk_char
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc/${ARCH_NAME}
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/util/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/libfdt/lib/contrib
|
||||
)
|
||||
120
mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.c
Normal file
120
mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.c
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
#include "mk_snd_drv.h"
|
||||
#include "u_types.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <mk_char_dev.h>
|
||||
#include <sys/types.h>
|
||||
#include <mk_access.h>
|
||||
#include "u_prot.h"
|
||||
#include "u_task.h"
|
||||
/**
|
||||
* @brief 写pin操作
|
||||
*
|
||||
* @param pin pin设备
|
||||
* @param buf 写的buf
|
||||
* @param size 写入大小
|
||||
* @return int 写入的个数
|
||||
*/
|
||||
static int mk_snd_drv_write(mk_dev_t *pin, void *buf, size_t size, off_t *offset)
|
||||
{
|
||||
assert(buf);
|
||||
assert(pin);
|
||||
mk_snd_dev_t *pin_dev = pin->priv_data;
|
||||
mk_snd_ops_t *ops = pin_dev->ops;
|
||||
assert(ops);
|
||||
|
||||
int ret = ops->snd_write(&pin_dev->snd, buf, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief 读取pin数据
|
||||
*
|
||||
* @param pin
|
||||
* @param buf
|
||||
* @param size
|
||||
* @return int
|
||||
*/
|
||||
static int mk_snd_drv_read(mk_dev_t *pin, void *buf, size_t size, off_t *offset)
|
||||
{
|
||||
assert(buf);
|
||||
assert(pin);
|
||||
mk_snd_dev_t *pin_dev = pin->priv_data;
|
||||
mk_snd_ops_t *ops = pin_dev->ops;
|
||||
assert(ops);
|
||||
|
||||
int ret = ops->snd_read(&pin_dev->snd, buf, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 控制pin状态
|
||||
*
|
||||
* @param pin
|
||||
* @param cmd
|
||||
* @param args
|
||||
* @return int
|
||||
*/
|
||||
static int mk_snd_drv_ioctl(mk_dev_t *pin, int cmd, umword_t args)
|
||||
{
|
||||
assert(pin);
|
||||
pid_t src_pid = thread_get_src_pid();
|
||||
pid_t cur_pid;
|
||||
mk_snd_dev_t *snd_dev = pin->priv_data;
|
||||
mk_snd_ops_t *ops = snd_dev->ops;
|
||||
assert(ops);
|
||||
int ret = 0;
|
||||
msg_tag_t tag;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case ETH_SET_MAC_ADDR:
|
||||
{
|
||||
mk_ioctl_set_info_t info;
|
||||
|
||||
tag = task_get_pid(TASK_THIS, (umword_t *)(&cur_pid));
|
||||
if (msg_tag_get_val(tag) < 0)
|
||||
{
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
ret = mk_copy_mem_to_task(src_pid, (void *)args,
|
||||
cur_pid, &info, sizeof(mk_snd_ioctl_set_info_t));
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (ops->snd_configure) {
|
||||
ops->snd_configure(snd_dev, cmd, &info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// static mk_file_ops_t file_ops = {
|
||||
// .open = NULL,
|
||||
// .write = mk_snd_drv_write,
|
||||
// .read = mk_snd_drv_read,
|
||||
// .ioctl = mk_snd_drv_ioctl,
|
||||
// .release = NULL,
|
||||
// };
|
||||
|
||||
int mk_snd_register(mk_dev_t *dev, mk_snd_dev_t *pin_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
assert(dev);
|
||||
assert(pin_drv);
|
||||
|
||||
// ret = mk_char_dev_register(dev, &file_ops);
|
||||
// if (ret < 0)
|
||||
// {
|
||||
// return ret;
|
||||
// }
|
||||
mk_dev_set_priv_data(dev, pin_drv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
37
mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.h
Normal file
37
mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <u_types.h>
|
||||
#include <mk_drv.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief snd设备数据
|
||||
*
|
||||
*/
|
||||
typedef struct mk_snd
|
||||
{
|
||||
void *priv_data;
|
||||
} mk_snd_t;
|
||||
/**
|
||||
* @brief snd设备操作对象
|
||||
*
|
||||
*/
|
||||
typedef struct mk_snd_ops
|
||||
{
|
||||
int (*snd_configure)(mk_snd_t *drv);
|
||||
int (*snd_read)(mk_snd_t *drv, uint8_t *data, int len);
|
||||
int (*snd_write)(mk_snd_t *drv, uint8_t *dat, int len);
|
||||
} mk_snd_ops_t;
|
||||
|
||||
/**
|
||||
* @brief snd设备
|
||||
*
|
||||
*/
|
||||
typedef struct mk_snd_dev
|
||||
{
|
||||
mk_snd_t snd;
|
||||
mk_snd_ops_t *ops;
|
||||
} mk_snd_dev_t;
|
||||
|
||||
int mk_snd_register(mk_dev_t *dev, mk_snd_dev_t *pin_drv);
|
||||
Reference in New Issue
Block a user