diff --git a/.vscode/settings.json b/.vscode/settings.json index 617ea7c7d..ac8c5393e 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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"] } \ No newline at end of file diff --git a/mkrtos_configs/ATSURFF437.dts b/mkrtos_configs/ATSURFF437.dts index ed8d7b7e2..2dbc2d4c3 100644 --- a/mkrtos_configs/ATSURFF437.dts +++ b/mkrtos_configs/ATSURFF437.dts @@ -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*/ }; }; diff --git a/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c b/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c index 29b78c475..81bfc9406 100644 --- a/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c +++ b/mkrtos_user/lib/mlibc/src/stdio/vfprintf.c @@ -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; diff --git a/mkrtos_user/lib/sys_svr/inc/rpc_prot.h b/mkrtos_user/lib/sys_svr/inc/rpc_prot.h index 246e715f3..9be0b5a57 100644 --- a/mkrtos_user/lib/sys_svr/inc/rpc_prot.h +++ b/mkrtos_user/lib/sys_svr/inc/rpc_prot.h @@ -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 diff --git a/mkrtos_user/lib/sys_svr/inc/snd_drv_cli.h b/mkrtos_user/lib/sys_svr/inc/snd_drv_cli.h new file mode 100644 index 000000000..90186bbbb --- /dev/null +++ b/mkrtos_user/lib/sys_svr/inc/snd_drv_cli.h @@ -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); diff --git a/mkrtos_user/lib/sys_svr/inc/snd_drv_svr.h b/mkrtos_user/lib/sys_svr/inc/snd_drv_svr.h new file mode 100644 index 000000000..655226b3d --- /dev/null +++ b/mkrtos_user/lib/sys_svr/inc/snd_drv_svr.h @@ -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); diff --git a/mkrtos_user/lib/sys_svr/inc/snd_drv_types.h b/mkrtos_user/lib/sys_svr/inc/snd_drv_types.h new file mode 100644 index 000000000..50cda719c --- /dev/null +++ b/mkrtos_user/lib/sys_svr/inc/snd_drv_types.h @@ -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; diff --git a/mkrtos_user/lib/sys_svr/src/snd_drv_cli.c b/mkrtos_user/lib/sys_svr/src/snd_drv_cli.c new file mode 100644 index 000000000..e33c80ab6 --- /dev/null +++ b/mkrtos_user/lib/sys_svr/src/snd_drv_cli.c @@ -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 +#include +#include + +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); +} diff --git a/mkrtos_user/lib/sys_svr/src/snd_drv_svr.c b/mkrtos_user/lib/sys_svr/src/snd_drv_svr.c new file mode 100644 index 000000000..0cc523676 --- /dev/null +++ b/mkrtos_user/lib/sys_svr/src/snd_drv_svr.c @@ -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 + +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); +} diff --git a/mkrtos_user/lib/sys_util/src/u_irq_helper.c b/mkrtos_user/lib/sys_util/src/u_irq_helper.c index 27e3e1788..c21d7d1ca 100644 --- a/mkrtos_user/lib/sys_util/src/u_irq_helper.c +++ b/mkrtos_user/lib/sys_util/src/u_irq_helper.c @@ -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; diff --git a/mkrtos_user/server/init/src/heap_stack.c b/mkrtos_user/server/init/src/heap_stack.c index 55d2a0861..44e2ed2a2 100644 --- a/mkrtos_user/server/init/src/heap_stack.c +++ b/mkrtos_user/server/init/src/heap_stack.c @@ -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) diff --git a/mkrtos_user/server/init/src/init.cfg b/mkrtos_user/server/init/src/init.cfg index 56cf2384c..d650f4d8e 100644 --- a/mkrtos_user/server/init/src/init.cfg +++ b/mkrtos_user/server/init/src/init.cfg @@ -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 \ No newline at end of file diff --git a/mkrtos_user/server/init/src/namespace.c b/mkrtos_user/server/init/src/namespace.c index f196a58f9..74da0445d 100644 --- a/mkrtos_user/server/init/src/namespace.c +++ b/mkrtos_user/server/init/src/namespace.c @@ -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); diff --git a/mkrtos_user/server/shell/src/heap_stack.c b/mkrtos_user/server/shell/src/heap_stack.c index 844224655..994a07c10 100644 --- a/mkrtos_user/server/shell/src/heap_stack.c +++ b/mkrtos_user/server/shell/src/heap_stack.c @@ -1,7 +1,7 @@ #include #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)) diff --git a/mkrtos_user/user/app/CMakeLists.txt b/mkrtos_user/user/app/CMakeLists.txt index b41f4cd5c..4f302e5a4 100644 --- a/mkrtos_user/user/app/CMakeLists.txt +++ b/mkrtos_user/user/app/CMakeLists.txt @@ -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() diff --git a/mkrtos_user/user/app/nes_simulator/heap_stack.c b/mkrtos_user/user/app/nes_simulator/heap_stack.c index 796bdb8ef..f1c45a6a0 100644 --- a/mkrtos_user/user/app/nes_simulator/heap_stack.c +++ b/mkrtos_user/user/app/nes_simulator/heap_stack.c @@ -1,5 +1,5 @@ -#define HEAP_SIZE (100 * 1024) +#define HEAP_SIZE (64 * 1024) #define STACK_SIZE (1024 * 3) #if defined(__CC_ARM) diff --git a/mkrtos_user/user/app/nes_simulator/nes.S b/mkrtos_user/user/app/nes_simulator/nes.S index 375f56fba..3efe28586 100644 --- a/mkrtos_user/user/app/nes_simulator/nes.S +++ b/mkrtos_user/user/app/nes_simulator/nes.S @@ -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 diff --git a/mkrtos_user/user/app/nes_simulator/nes_rom/超级马里奥兄弟3[MM之神汉化](JP)[ACT](3Mb).nes b/mkrtos_user/user/app/nes_simulator/nes_rom/超级马里奥兄弟3[MM之神汉化](JP)[ACT](3Mb).nes new file mode 100644 index 000000000..afcf11887 Binary files /dev/null and b/mkrtos_user/user/app/nes_simulator/nes_rom/超级马里奥兄弟3[MM之神汉化](JP)[ACT](3Mb).nes differ diff --git a/mkrtos_user/user/app/nes_simulator/vnes/6502.S b/mkrtos_user/user/app/nes_simulator/vnes/6502.S index b2694cad2..5f7cdd5f3 100644 --- a/mkrtos_user/user/app/nes_simulator/vnes/6502.S +++ b/mkrtos_user/user/app/nes_simulator/vnes/6502.S @@ -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 //------------------------------------------------------------------------ diff --git a/mkrtos_user/user/app/nes_simulator/vnes/nes_apu.c b/mkrtos_user/user/app/nes_simulator/vnes/nes_apu.c index 927f3baa0..e37cfac93 100644 --- a/mkrtos_user/user/app/nes_simulator/vnes/nes_apu.c +++ b/mkrtos_user/user/app/nes_simulator/vnes/nes_apu.c @@ -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; diff --git a/mkrtos_user/user/app/nes_simulator/vnes/nes_main.c b/mkrtos_user/user/app/nes_simulator/vnes/nes_main.c index 13cccd6b5..7bf346cf6 100644 --- a/mkrtos_user/user/app/nes_simulator/vnes/nes_main.c +++ b/mkrtos_user/user/app/nes_simulator/vnes/nes_main.c @@ -9,8 +9,14 @@ #include #include #include -// #include "drv_audio.h" -// #include "drv_input.h" +#include "ns_cli.h" +#include "u_sleep.h" +#include +#include +#include +#include +#include +#include ////////////////////////////////////////////////////////////////////////////////// // 本程序移植自网友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"); + } } diff --git a/mkrtos_user/user/drv/ATSURFF437/CMakeLists.txt b/mkrtos_user/user/drv/ATSURFF437/CMakeLists.txt index 657f373ed..9fce41ef5 100644 --- a/mkrtos_user/user/drv/ATSURFF437/CMakeLists.txt +++ b/mkrtos_user/user/drv/ATSURFF437/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(display) add_subdirectory(i2c) add_subdirectory(pca9555) add_subdirectory(eth) +add_subdirectory(snd) diff --git a/mkrtos_user/user/drv/ATSURFF437/eth/at_surf_f437_board_emac.c b/mkrtos_user/user/drv/ATSURFF437/eth/at_surf_f437_board_emac.c index fbb4f4362..51c8f7df5 100644 --- a/mkrtos_user/user/drv/ATSURFF437/eth/at_surf_f437_board_emac.c +++ b/mkrtos_user/user/drv/ATSURFF437/eth/at_surf_f437_board_emac.c @@ -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) diff --git a/mkrtos_user/user/drv/ATSURFF437/eth/mk_eth_drv_impl.c b/mkrtos_user/user/drv/ATSURFF437/eth/mk_eth_drv_impl.c index 87a3d52dd..dacdc81c7 100644 --- a/mkrtos_user/user/drv/ATSURFF437/eth/mk_eth_drv_impl.c +++ b/mkrtos_user/user/drv/ATSURFF437/eth/mk_eth_drv_impl.c @@ -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; diff --git a/mkrtos_user/user/drv/ATSURFF437/pca9555/pca9555.c b/mkrtos_user/user/drv/ATSURFF437/pca9555/pca9555.c index 55f7d1429..589362133 100644 --- a/mkrtos_user/user/drv/ATSURFF437/pca9555/pca9555.c +++ b/mkrtos_user/user/drv/ATSURFF437/pca9555/pca9555.c @@ -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)) { diff --git a/mkrtos_user/user/drv/ATSURFF437/pin/mk_pin_drv_impl.c b/mkrtos_user/user/drv/ATSURFF437/pin/mk_pin_drv_impl.c index a3c3faa1b..5c9a1d1c1 100644 --- a/mkrtos_user/user/drv/ATSURFF437/pin/mk_pin_drv_impl.c +++ b/mkrtos_user/user/drv/ATSURFF437/pin/mk_pin_drv_impl.c @@ -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; diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/CMakeLists.txt b/mkrtos_user/user/drv/ATSURFF437/snd/CMakeLists.txt new file mode 100644 index 000000000..9299d5124 --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/CMakeLists.txt @@ -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) + \ No newline at end of file diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/armv7_8m/link.lds b/mkrtos_user/user/drv/ATSURFF437/snd/armv7_8m/link.lds new file mode 100644 index 000000000..34fdd0c60 --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/armv7_8m/link.lds @@ -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 = .; +} diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/at32f435_437_conf.h b/mkrtos_user/user/drv/ATSURFF437/snd/at32f435_437_conf.h new file mode 100644 index 000000000..4d0bb6570 --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/at32f435_437_conf.h @@ -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 + +/** + * @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 diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.c b/mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.c new file mode 100644 index 000000000..a53e6202d --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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); + } + } +} diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.h b/mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.h new file mode 100644 index 000000000..bc949af55 --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/at_surf_f437_board_audio.h @@ -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 diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/heap_stack.c b/mkrtos_user/user/drv/ATSURFF437/snd/heap_stack.c new file mode 100644 index 000000000..28c616857 --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/heap_stack.c @@ -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]; diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/main.c b/mkrtos_user/user/drv/ATSURFF437/snd/main.c new file mode 100644 index 000000000..84a81c42c --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/main.c @@ -0,0 +1,81 @@ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ns_cli.h" +#include "rpc_prot.h" +#include "u_hd_man.h" +#include "u_share_mem.h" +#include +#include +#include +#include + +#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(); + } +} diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.c b/mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.c new file mode 100644 index 000000000..1fd623419 --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.c @@ -0,0 +1,92 @@ + + +#include +#include +#include +#include +#include +#include +#include "mk_drv.h" +#include "mk_snd_drv.h" +#include "mk_dtb_parse.h" +#include +#include +#include +#include +#include +#include +#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); +} diff --git a/mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.h b/mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.h new file mode 100644 index 000000000..5b05d086c --- /dev/null +++ b/mkrtos_user/user/drv/ATSURFF437/snd/mk_snd_drv_impl.h @@ -0,0 +1,5 @@ +#pragma once + +#include "at_surf_f437_board_audio.h" + +void drv_snd_init(void); diff --git a/mkrtos_user/user/drv/CMakeLists.txt b/mkrtos_user/user/drv/CMakeLists.txt index 64c8e8a75..e7d484496 100644 --- a/mkrtos_user/user/drv/CMakeLists.txt +++ b/mkrtos_user/user/drv/CMakeLists.txt @@ -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) diff --git a/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.c b/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.c index 6a9402804..05a87aee2 100644 --- a/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.c +++ b/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.c @@ -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; diff --git a/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.h b/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.h index 143942141..93738f13a 100644 --- a/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.h +++ b/mkrtos_user/user/drv/lib/mk_eth/mk_eth_drv.h @@ -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; diff --git a/mkrtos_user/user/drv/lib/mk_pin/mk_pin_drv.h b/mkrtos_user/user/drv/lib/mk_pin/mk_pin_drv.h index 6f31300a0..085f0a383 100644 --- a/mkrtos_user/user/drv/lib/mk_pin/mk_pin_drv.h +++ b/mkrtos_user/user/drv/lib/mk_pin/mk_pin_drv.h @@ -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, diff --git a/mkrtos_user/user/drv/lib/mk_snd/CMakeLists.txt b/mkrtos_user/user/drv/lib/mk_snd/CMakeLists.txt new file mode 100644 index 000000000..b8f71bb8f --- /dev/null +++ b/mkrtos_user/user/drv/lib/mk_snd/CMakeLists.txt @@ -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 +) diff --git a/mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.c b/mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.c new file mode 100644 index 000000000..64f877367 --- /dev/null +++ b/mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.c @@ -0,0 +1,120 @@ + +#include "mk_snd_drv.h" +#include "u_types.h" +#include +#include +#include +#include +#include +#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; +} \ No newline at end of file diff --git a/mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.h b/mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.h new file mode 100644 index 000000000..fb2881647 --- /dev/null +++ b/mkrtos_user/user/drv/lib/mk_snd/mk_snd_drv.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + + +/** + * @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);