[feat][examples/audio_cube] add audio_cube demo

This commit is contained in:
jzlv 2021-09-30 15:01:42 +08:00
parent 205e179d8c
commit 2be4cea4d3
16 changed files with 4250 additions and 0 deletions

View File

@ -0,0 +1,9 @@
set(BSP_COMMON_DIR ${CMAKE_SOURCE_DIR}/bsp/bsp_common)
set(TARGET_REQUIRED_PRIVATE_INCLUDE ${BSP_COMMON_DIR}/es8388 )
set(TARGET_REQUIRED_SRCS ${BSP_COMMON_DIR}/es8388/bsp_es8388.c data_protocol.c wav_play_from_isp.c)
set(mains main.c)
generate_bin()

View File

@ -0,0 +1,742 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project Name="audio_cube" Version="1" Language="C">
<Description>CPU: RV32IMAFC
Chip: bl70x
Board: bl70x_iot
</Description>
<Dependencies Name="Debug"/>
<VirtualDirectory Name="app">
<File Name="../main.c">
<FileOption/>
</File>
<File Name="../wav_play_from_isp.c">
<FileOption/>
</File>
<File Name="../data_protocol.c"/>
</VirtualDirectory>
<VirtualDirectory Name="chip">
<VirtualDirectory Name="riscv">
<File Name="../../../drivers/bl702_driver/startup/interrupt.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/startup/system_bl702.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="startup">
<File Name="../../../drivers/bl702_driver/startup/GCC/entry.S">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/startup/GCC/start_load.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="hal">
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_acomp.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_adc.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_boot2.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_cam.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_clock.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_common.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_dac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_dma.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_emac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_flash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_gpio.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_i2c.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_i2s.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_keyscan.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_mjpeg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_mtimer.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_pm.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_pwm.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_qdec.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_rtc.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_aes.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_dsa.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_ecdsa.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_hash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_spi.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_timer.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_uart.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_usb.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_wdt.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="std">
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_acomp.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_adc.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_aon.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_cam.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_clock.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_dac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_dma.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_ef_ctrl.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_emac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_glb.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_hbn.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_i2c.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_i2c_gpio_sim.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_i2s.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_ir.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_common.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_kys.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_l1c.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_mjpeg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_pds.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_psram.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_pwm.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_qdec.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_romapi.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sec_dbg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sec_eng.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sf_cfg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sf_cfg_ext.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sf_ctrl.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sflash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sflash_ext.c" ExcludeProjConfig="">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_spi.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_timer.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_uart.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_usb.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_xip_sflash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_xip_sflash_ext.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="bsp">
<VirtualDirectory Name="board">
<File Name="../../../bsp/board/bl702/board.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="bsp_common">
<File Name="../../../bsp/bsp_common/platform/bflb_platform.c">
<FileOption/>
</File>
<File Name="../../../bsp/bsp_common/platform/syscalls.c">
<FileOption/>
</File>
<File Name="../../../bsp/bsp_common/es8388/bsp_es8388.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="common">
<File Name="../../../common/device/drv_device.c">
<FileOption/>
</File>
<File Name="../../../common/memheap/drv_mmheap.c">
<FileOption/>
</File>
<File Name="../../../common/ring_buffer/ring_buffer.c">
<FileOption/>
</File>
<File Name="../../../common/soft_crc/softcrc.c">
<FileOption/>
</File>
<File Name="../../../common/misc/misc.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="script">
<File Name="../../../tools/openocd/bl70x_gdb.init">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/regs/bl70x_reg.svc">
<FileOption/>
</File>
</VirtualDirectory>
<MonitorProgress>
<DebugLaunch>83</DebugLaunch>
<FlashOperate>107</FlashOperate>
</MonitorProgress>
<VirtualDirectory Name="components">
<VirtualDirectory Name="fatfs">
<File Name="../../../components/fatfs/diskio.c">
<FileOption/>
</File>
<File Name="../../../components/fatfs/ff.c">
<FileOption/>
</File>
<File Name="../../../components/fatfs/ffsystem.c">
<FileOption/>
</File>
<File Name="../../../components/fatfs/ffunicode.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="shell">
<File Name="../../../components/shell/shell.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="usb_stack">
<VirtualDirectory Name="class">
<VirtualDirectory Name="cdc">
<File Name="../../../components/usb_stack/class/cdc/usbd_cdc.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="hid">
<File Name="../../../components/usb_stack/class/hid/usbd_hid.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="msc">
<File Name="../../../components/usb_stack/class/msc/usbd_msc.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="core">
<File Name="../../../components/usb_stack/core/usbd_core.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
</VirtualDirectory>
<Dependencies Name="BuildSet"/>
<Dependencies Name="CK_Link_Debug"/>
<Dependencies Name="OpenOCD_Debug"/>
<BuildConfigs>
<BuildConfig Name="OpenOCD_Debug">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>no</InUse>
<Start>0x23000000</Start>
<Size>0x100000</Size>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start>0x22014000</Start>
<Size>0x4000</Size>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start>0x42018000</Start>
<Size>0x8000</Size>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>yes</InUse>
<Start>0x42020000</Start>
<Size>0xc000</Size>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>rv32imafc</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>no</UseEnhancedLRW>
<UseContinueBuild>no</UseContinueBuild>
<UseSemiHost>no</UseSemiHost>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>no</CreateHexFile>
<CreateBinFile>yes</CreateBinFile>
<Preprocessor>no</Preprocessor>
<Disassmeble>yes</Disassmeble>
<CallGraph>no</CallGraph>
<Map>yes</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName>$(ProjectPath)../../../tools/bflb_flash_tool/bflb_mcu_tool.exe --chipname=bl702 --interface=openocd --firmware="$(ProjectPath)/Obj/$(ProjectName).bin" </UserProgName>
</AfterMake>
</User>
<Compiler>
<Define>ARCH_RISCV;BFLB_USE_HAL_DRIVER;BFLB_USE_ROM_DRIVER;bl706_iot</Define>
<Undefine/>
<Optim>Optimize more (-O2)</Optim>
<DebugLevel>Default (-g)</DebugLevel>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../bsp/bsp_common/es8388;$(ProjectPath)../../../common/libc/inc;$(ProjectPath)../../../common/libc/inc/arm_gcc;$(ProjectPath)../../../common/libc/inc/bits;$(ProjectPath)../../../common/libc/inc/sys;$(ProjectPath)../../../common/libc/src;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc</IncludePath>
<OtherFlags>-fshort-enums -fno-common -fms-extensions -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wall -Wshift-negative-value -Wchar-subscripts -Wformat -Wuninitialized -Winit-self -Wignored-qualifiers -Wunused -Wundef -msmall-data-limit=4 -std=c99</OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>yes</OneElfS>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define/>
<Undefine/>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../bsp/bsp_common/es8388;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl602_driver/startup;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl602_driver/regs;$(ProjectPath)../../../drivers/bl602_driver/std_drv/inc</IncludePath>
<OtherFlags/>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<Garbage2>yes</Garbage2>
<LDFile>$(ProjectPath)../../../drivers/bl702_driver/bl702_flash.ld</LDFile>
<LibName>c</LibName>
<LibPath/>
<OtherFlags>--specs=nano.specs</OtherFlags>
<AutoLDFile>no</AutoLDFile>
<LinkType/>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>OpenOCD</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile/>
<AfterLoadFile>$(ProjectPath)/../../../tools/openocd/bl70x_gdb.init</AfterLoadFile>
<AutoRun>yes</AutoRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>23000000</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<Dumpcore>no</Dumpcore>
<DumpcoreText>$(ProjectPath)/$(ProjectName).cdkcore</DumpcoreText>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<CPUNumber>0</CPUNumber>
<Clock>2000</Clock>
<Delay>10</Delay>
<WaitReset>50</WaitReset>
<DDC>yes</DDC>
<TRST>no</TRST>
<DebugPrint>no</DebugPrint>
<Connect>Normal</Connect>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>21000000</SoftResetVal>
<RTOSType>Bare Metal</RTOSType>
<DownloadToFlash>yes</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
<GDBName/>
<GDBServerType>Local</GDBServerType>
<OtherFlags>-arch riscv</OtherFlags>
</ConfigICE>
<ConfigSIM>
<SIMTarget/>
<OtherFlags/>
<NoGraphic>yes</NoGraphic>
<Log>no</Log>
<SimTrace>no</SimTrace>
</ConfigSIM>
<ConfigOpenOCD>
<OpenOCDExecutablePath>openocd-hifive</OpenOCDExecutablePath>
<OpenOCDTelnetPortEnable>no</OpenOCDTelnetPortEnable>
<OpenOCDTelnetPort>4444</OpenOCDTelnetPort>
<OpenOCDTclPortEnable>no</OpenOCDTclPortEnable>
<OpenOCDTclPort>6666</OpenOCDTclPort>
<OpenOCDConfigOptions>-f ../../../tools/openocd/if_rv_dbg_plus.cfg -f ../../../tools/openocd/tgt_702.cfg</OpenOCDConfigOptions>
</ConfigOpenOCD>
</Debug>
<Flash>
<InitFile/>
<Erase>Erase Sectors</Erase>
<Algorithms Path="">bl70x_flasher.elf</Algorithms>
<Program>yes</Program>
<Verify>yes</Verify>
<ResetAndRun>no</ResetAndRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal/>
<External>no</External>
<Command/>
<Arguments/>
</Flash>
</BuildConfig>
<BuildConfig Name="CK_Link_Debug">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>no</InUse>
<Start>0x23000000</Start>
<Size>0x100000</Size>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start>0x22014000</Start>
<Size>0x4000</Size>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start>0x42018000</Start>
<Size>0x8000</Size>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>yes</InUse>
<Start>0x42020000</Start>
<Size>0xc000</Size>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>rv32imafc</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>no</UseEnhancedLRW>
<UseContinueBuild>no</UseContinueBuild>
<UseSemiHost>no</UseSemiHost>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>no</CreateHexFile>
<CreateBinFile>yes</CreateBinFile>
<Preprocessor>no</Preprocessor>
<Disassmeble>yes</Disassmeble>
<CallGraph>no</CallGraph>
<Map>yes</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName>$(ProjectPath)../../../tools/bflb_flash_tool/bflb_mcu_tool.exe --chipname=bl702 --interface=openocd --firmware="$(ProjectPath)/Obj/$(ProjectName).bin" </UserProgName>
</AfterMake>
</User>
<Compiler>
<Define>BL702;BL702_EVB;ARCH_RISCV;bl706_avb</Define>
<Undefine/>
<Optim>Optimize more (-O2)</Optim>
<DebugLevel>Default (-g)</DebugLevel>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../bsp/bsp_common/es8388;$(ProjectPath)../../../common/libc/inc;$(ProjectPath)../../../common/libc/inc/arm_gcc;$(ProjectPath)../../../common/libc/inc/bits;$(ProjectPath)../../../common/libc/inc/sys;$(ProjectPath)../../../common/libc/src;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl602_driver/regs;$(ProjectPath)../../../drivers/bl602_driver/std_drv/inc</IncludePath>
<OtherFlags>-fshort-enums -fno-common -fms-extensions -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wall -Wshift-negative-value -Wchar-subscripts -Wformat -Wuninitialized -Winit-self -Wignored-qualifiers -Wunused -Wundef -msmall-data-limit=4 -std=c99</OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>yes</OneElfS>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define/>
<Undefine/>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl602_driver/startup;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl602_driver/regs;$(ProjectPath)../../../drivers/bl602_driver/std_drv/inc</IncludePath>
<OtherFlags/>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<Garbage2>yes</Garbage2>
<LDFile>$(ProjectPath)../../../drivers/bl702_driver/bl702_flash.ld</LDFile>
<LibName>c</LibName>
<LibPath/>
<OtherFlags>--specs=nano.specs</OtherFlags>
<AutoLDFile>no</AutoLDFile>
<LinkType/>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>Remote ICE</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile/>
<AfterLoadFile>$(ProjectPath)/../../../tools/openocd/bl70x_gdb.init</AfterLoadFile>
<AutoRun>yes</AutoRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>23000000</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<Dumpcore>no</Dumpcore>
<DumpcoreText>$(ProjectPath)/$(ProjectName).cdkcore</DumpcoreText>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<CPUNumber>0</CPUNumber>
<Clock>2000</Clock>
<Delay>10</Delay>
<WaitReset>50</WaitReset>
<DDC>yes</DDC>
<TRST>no</TRST>
<DebugPrint>no</DebugPrint>
<Connect>Normal</Connect>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>21000000</SoftResetVal>
<RTOSType>Bare Metal</RTOSType>
<DownloadToFlash>yes</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
<GDBName/>
<GDBServerType>Local</GDBServerType>
<OtherFlags>-arch riscv</OtherFlags>
</ConfigICE>
<ConfigSIM>
<SIMTarget/>
<OtherFlags/>
<NoGraphic>yes</NoGraphic>
<Log>no</Log>
<SimTrace>no</SimTrace>
</ConfigSIM>
<ConfigOpenOCD>
<OpenOCDExecutablePath>openocd-hifive</OpenOCDExecutablePath>
<OpenOCDTelnetPortEnable>no</OpenOCDTelnetPortEnable>
<OpenOCDTelnetPort>4444</OpenOCDTelnetPort>
<OpenOCDTclPortEnable>no</OpenOCDTclPortEnable>
<OpenOCDTclPort>6666</OpenOCDTclPort>
<OpenOCDConfigOptions>-f ../../../tools/openocd/if_rv_dbg_plus.cfg -f ../../../tools/openocd/tgt_702.cfg</OpenOCDConfigOptions>
</ConfigOpenOCD>
</Debug>
<Flash>
<InitFile/>
<Erase>Erase Sectors</Erase>
<Algorithms Path="">bl70x_flasher.elf</Algorithms>
<Program>yes</Program>
<Verify>yes</Verify>
<ResetAndRun>no</ResetAndRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal/>
<External>no</External>
<Command/>
<Arguments/>
</Flash>
</BuildConfig>
</BuildConfigs>
<DebugSessions>
<watchExpressions>audio_isp_test:1;isp_obj_uart:1;audio_test:4;time_node:1;Wav_Information:1</watchExpressions>
<memoryExpressions>0x4201D700;;;</memoryExpressions>
<statistics>;;MHZ;</statistics>
<peripheralTabs>
<Tab disFormat="Hex">glb</Tab>
<Tab disFormat="Hex">uart</Tab>
</peripheralTabs>
<WatchDisplayFormat>1</WatchDisplayFormat>
<LocalDisplayFormat>1</LocalDisplayFormat>
<debugLayout/>
<memoryTabColSizeExpressions>72:4;100:8;100:8;100:8;</memoryTabColSizeExpressions>
</DebugSessions>
<DebugSessions>
<watchExpressions/>
<memoryExpressions>;;;</memoryExpressions>
<statistics>;;MHZ;</statistics>
<peripheralTabs>
<Tab disFormat="Hex">glb</Tab>
<Tab disFormat="Hex">uart</Tab>
</peripheralTabs>
<WatchDisplayFormat>1</WatchDisplayFormat>
<LocalDisplayFormat>1</LocalDisplayFormat>
<debugLayout/>
<memoryTabColSizeExpressions>100:8;100:8;100:8;100:8;</memoryTabColSizeExpressions>
</DebugSessions>
</Project>

View File

@ -0,0 +1,395 @@
/**
* @file ips.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "drv_mmheap.h"
#include "hal_uart.h"
#include "hal_dma.h"
#include "data_protocol.h"
struct device *uart;
static isp_obj_t *isp_obj_uart;
void ips_obj_init(isp_obj_t *isp_obj_p)
{
if (!isp_obj_p)
return;
isp_obj_p->cmd_id = 0;
isp_obj_p->check = 0;
isp_obj_p->length = 0;
isp_obj_p->file_type = 0;
isp_obj_p->auot_ack = 1;
isp_obj_p->status.isp_state_mode = 0;
isp_obj_p->status.already_steps = 0;
}
/**
* @brief uart tx dma irq, ch0
*
* @param dev
* @param args
* @param size
* @param state
*/
void dma_ch0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (isp_obj_uart == NULL) {
return;
}
/* close dma and dma irq */
device_control(uart, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
device_control(UART_DEV(uart)->tx_dma, DEVICE_CTRL_CLR_INT, NULL);
if (isp_obj_uart->status.isp_state_mode == SEND_DATA) {
isp_obj_uart->status.isp_state_mode = SEND_WAIT_ACK;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_ACK_WAIT);
}
}
// void dma_ch1_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
// {
// if (isp_obj_uart == NULL) {
// return;
// }
// if (isp_obj_uart->status.isp_state_mode == RECEIVE_DATA) {
// isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
// isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_RECEIVE_ACK_WAIT);
// }
// device_control(uart, DEVICE_CTRL_RX_DMA_SUSPEND, 0);
// isp_obj_uart->status.already_steps = 0;
// device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT));
// MSG("tx dma init\r\n");
// }
uint8_t isp_check(isp_obj_t *isp_obj)
{
if (isp_obj == NULL) {
return 0;
}
uint8_t check = isp_obj->cmd_id + (isp_obj->length & 0x00FF) + ((isp_obj->length >> 8) & 0x00FF);
if (isp_obj->length && isp_obj->file_data) {
for (uint16_t i = 0; i < isp_obj->length; i++) {
check += isp_obj->file_data[i];
}
}
return check;
}
/**
* @brief
*
* @param isp_obj_uart
* @return int
*/
int isp_uart_send_data(isp_obj_t *isp_obj_uart)
{
if (isp_obj_uart == NULL || isp_obj_uart->cmd_id == 0) {
return -1;
}
if ((isp_obj_uart->cmd_id & 0xF0) != 0x50)
return -2;
if (isp_obj_uart->status.isp_state_mode != NO_TASK)
return -3;
isp_obj_uart->check = isp_check(isp_obj_uart);
/* use tx blocking */
device_write(uart, 0, (void *)isp_obj_uart, sizeof(isp_cmd_id_t) + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(isp_file_type_t));
/* use DMA tx non-blocking */
device_control(uart, DEVICE_CTRL_TX_DMA_RESUME, NULL);
device_control(UART_DEV(uart)->tx_dma, DEVICE_CTRL_SET_INT, NULL);
device_write(uart, 0, isp_obj_uart->file_data, isp_obj_uart->length);
isp_obj_uart->status.already_steps = 0;
isp_obj_uart->status.isp_state_mode = SEND_DATA;
return 0;
}
/**
* @brief
*
* @param isp_obj_uart
* @return int
*/
int isp_uart_send_ack(isp_obj_t *isp_obj_uart, ips_reply_t ips_reply)
{
if (isp_obj_uart == NULL || isp_obj_uart->cmd_id == 0) {
return -1;
}
// if (isp_obj_uart->status.isp_state_mode != RECEIVE_WAIT_ACK) {
// return -2;
// }
/* use DMA tx blocking */
device_write(uart, 0, (uint8_t *)&ips_reply, 2);
return 0;
}
/**
* @brief
*
* @param isp_obj
* @param buff
* @param size
*/
void isp_task_handler(isp_obj_t *isp_obj, uint8_t *buff, uint32_t size)
{
static uint32_t time_last = 0;
uint32_t time_now = bflb_platform_get_time_ms();
/* debug information */
// MSG("hand:%d, len:%d, mode:%d\r\n", isp_obj_uart->status.already_steps, isp_obj_uart->status.receive_length, isp_obj_uart->status.isp_state_mode);
if (size == 0) {
if ((time_now - time_last > isp_obj->time_out) && isp_obj->time_out) {
/* time out */
}
}
for (uint32_t i = 0; i < size; i++) {
/* receive 状态机 */
switch (isp_obj_uart->status.already_steps) {
case 0:
if (isp_obj_uart->status.isp_state_mode == NO_TASK) {
isp_obj_uart->status.isp_state_mode = OTHER_STATE;
} else if (isp_obj_uart->status.isp_state_mode != SEND_WAIT_ACK) {
return;
}
isp_obj_uart->cmd_id = *buff;
isp_obj_uart->status.already_steps++;
break;
case 1:
isp_obj_uart->check = *buff;
isp_obj_uart->status.already_steps++;
if (isp_obj_uart->status.isp_state_mode == SEND_WAIT_ACK) {
isp_obj_uart->status.isp_state_mode = NO_TASK;
if (isp_obj_uart->cmd_id == 0X4F && isp_obj_uart->check == 0X4B) {
isp_obj_uart->status.ips_reply = REPLY_SUCCES;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_SUCCES_ACK);
isp_obj_uart->status.isp_state_mode = NO_TASK;
isp_obj_uart->status.already_steps = 0;
} else if (isp_obj_uart->cmd_id == 0X52 && isp_obj_uart->check == 0X45) {
isp_obj_uart->status.ips_reply = REPLY_ERROR;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_ERROR_ACK);
isp_obj_uart->status.isp_state_mode = NO_TASK;
isp_obj_uart->status.already_steps = 0;
}
}
break;
case 2:
isp_obj_uart->length = *buff;
isp_obj_uart->status.already_steps++;
break;
case 3:
isp_obj_uart->length += *buff << 8;
isp_obj_uart->status.already_steps++;
break;
case 4: /* 接收的如果是命令,无法判断命令是简短命令(只需回复2个字节信息),还是复杂命令(需要回复一段数据包),需要自己在用户回调函数里处理,但这似乎不太合理 */
isp_obj_uart->file_type = *buff;
isp_obj_uart->status.already_steps++;
if ((isp_obj_uart->cmd_id & 0xF0) == 0x50) {
isp_obj_uart->status.isp_state_mode = RECEIVE_DATA;
isp_obj_uart->status.receive_length = 0;
} else {
isp_obj_uart->status.already_steps = 0;
/* 等待ACK的时候收到命令同时代表 命令 与 成功ACK */
if (isp_obj_uart->status.isp_state_mode == SEND_WAIT_ACK) {
/* 响应 CMD 含义 */
isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_CMD_);
/* 响应 ACK 含义 */
isp_obj_uart->status.ips_reply = REPLY_SUCCES;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_SUCCES_ACK);
isp_obj_uart->status.isp_state_mode = NO_TASK;
} else {
/* 正常空闲收到命令 */
isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_CMD_);
}
//isp_obj_uart->status.isp_state_mode = NO_TASK;
}
break;
case 5:
if (isp_obj_uart->status.receive_length < isp_obj_uart->length) {
isp_obj_uart->file_data[isp_obj_uart->status.receive_length] = *buff;
isp_obj_uart->status.receive_length++;
}
if (isp_obj_uart->status.receive_length >= isp_obj_uart->length) {
isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
uint8_t check_data = isp_check(isp_obj_uart);
//MSG("check:%X\r\n", check);
if (isp_obj_uart->check == check_data) {
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_RECEIVE_ACK_WAIT);
/* auot send ack */
if (isp_obj_uart->auot_ack == 0) {
isp_uart_send_ack(isp_obj_uart, REPLY_SUCCES);
isp_obj_uart->status.isp_state_mode = NO_TASK;
}
} else {
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_RECEIVE_NACK_WAIT);
/* auot send Nack */
if (isp_obj_uart->auot_ack == 0) {
isp_uart_send_ack(isp_obj_uart, REPLY_ERROR);
isp_obj_uart->status.isp_state_mode = NO_TASK;
}
}
isp_obj_uart->status.receive_length = 0;
isp_obj_uart->status.already_steps = 0;
}
break;
default:
break;
}
buff++;
}
time_last = time_now;
}
/**
* @brief uart_irq_callback
*
* @param dev
* @param args
* @param size
* @param state
*/
void uart_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
static uint8_t fer_err_flag = 0;
if (state == UART_EVENT_RX_FIFO || state == UART_EVENT_RTO) {
if (isp_obj_uart == NULL) {
return;
}
/* Tx fifo overflow, send nack*/
if(fer_err_flag){
if(state == UART_EVENT_RX_FIFO){
}else if(state == UART_EVENT_RTO){
isp_obj_uart->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj_uart, REPLY_ERROR);
fer_err_flag = 0;
}
return;
}
isp_task_handler(isp_obj_uart, args, size);
}
else if(state == UART_EVENT_RX_FER){
/* Tx fifo overflow, baud rate should be reduced */
fer_err_flag = 1;
device_control(dev,DEVICE_CTRL_UART_CLEAR_RX_FIFO,NULL);
}
}
/**
* @brief
*
*/
uint8_t isp_uart_init(isp_obj_t *isp_obj)
{
if (isp_obj == NULL)
return 1;
uart = device_find("debug_log");
if(uart){
device_close(uart);
}else{
uart_register(UART0_INDEX, "debug_log");
uart = device_find("debug_log");
}
if (uart) {
device_close(uart);
UART_DEV(uart)->id = 0;
UART_DEV(uart)->baudrate = 3000000;
UART_DEV(uart)->databits = UART_DATA_LEN_8;
UART_DEV(uart)->stopbits = UART_STOP_ONE;
UART_DEV(uart)->parity = UART_PAR_NONE;
UART_DEV(uart)->fifo_threshold = 4;
device_close(uart);
device_open(uart, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
bflb_platform_delay_ms(5);
device_set_callback(uart, uart_irq_callback);
device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
}
dma_register(DMA0_CH0_INDEX, "ch0");
struct device *dma_ch0 = device_find("ch0");
if (dma_ch0) {
DMA_DEV(dma_ch0)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch0)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch0)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch0)->dst_req = DMA_REQUEST_UART0_TX;
DMA_DEV(dma_ch0)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch0)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch0, 0);
device_control(uart, DEVICE_CTRL_ATTACH_TX_DMA, dma_ch0);
device_set_callback(dma_ch0, dma_ch0_irq_callback);
/* close dma irq */
//device_control(UART_DEV(uart)->tx_dma, DEVICE_CTRL_CLR_INT, NULL);
}
// dma_register(DMA0_CH1_INDEX, "ch1");
// struct device *dma_ch1 = device_find("ch1");
// if (dma_ch1) {
// DMA_DEV(dma_ch1)->direction = DMA_PERIPH_TO_MEMORY;
// DMA_DEV(dma_ch1)->transfer_mode = DMA_LLI_ONCE_MODE;
// DMA_DEV(dma_ch1)->src_req = DMA_REQUEST_UART0_RX;
// DMA_DEV(dma_ch1)->dst_req = DMA_REQUEST_NONE;
// DMA_DEV(dma_ch1)->src_width = DMA_TRANSFER_WIDTH_8BIT;
// DMA_DEV(dma_ch1)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
// device_open(dma_ch1, 0);
// device_control(uart, DEVICE_CTRL_ATTACH_RX_DMA, dma_ch1);
// device_set_callback(dma_ch1, dma_ch1_irq_callback);
// device_control(dma_ch1, DEVICE_CTRL_SET_INT, NULL);
// }
device_control(uart, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
isp_obj_uart = isp_obj;
return 0;
}

View File

@ -0,0 +1,104 @@
/**
* @file ips.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
//#include "drv_list.h"
typedef enum {
FILE_START = 0x50,
FILE_DATA = 0X51,
FILE_END = 0X52,
CMD_PLAY_START = 0X40,
CMD_PLAY_PAUSE = 0X41,
CMD_PLAY_STOP = 0X42,
CMD_VOLUME_INCREASE = 0x43,
CMD_VOLUME_DECREASE = 0x44,
CMD_VOLUME_SET = 0x45,
CMD_VOLUME_GET = 0x46,
CMD_SAMPLING_RATE = 0x47,
CMD_CHANNEL_NUM = 0X48,
CMD_RECORD_START = 0x49,
CMD_RECORD_STOP = 0x4A,
} isp_cmd_id_t;
typedef enum {
DATA_UVVV = 0X53,
DATA_VUVV = 0X54,
} isp_file_type_t;
typedef enum {
REPLY_SUCCES = 0x4B4Fu,
REPLY_ERROR = 0x4552u,
} ips_reply_t;
/* 内部状态类型 */
typedef enum {
NO_TASK = 0,
SEND_DATA = 1, /* 发数据中 */
RECEIVE_DATA, /* 接收数据中 */
SEND_WAIT_ACK, /* 发送后等待 ack */
RECEIVE_WAIT_ACK, /* 接收后对方在等待 ack */
OTHER_STATE, /*其他状态,一般是接收数据或命令的帧头过程中 */
} isp_state_mode_t;
typedef struct {
isp_state_mode_t isp_state_mode; /* 单帧状态 */
uint8_t already_steps; /* 状态机控制 */
uint16_t buff_length_max; /* buff 最大长度 */
ips_reply_t ips_reply; /* ack 状态 */
uint16_t receive_length; /* 已经接收数量 */
} isp_status_t;
/* 回调触发原因 */
typedef enum {
ISP_CALLBACK_SEND_SUCCES_ACK, /* 发送后收到正确的ACK */
ISP_CALLBACK_SEND_ERROR_ACK, /* 发送后收到错误的ACK */
ISP_CALLBACK_RECEIVE_ACK_WAIT, /* 数据已经收到,校验正确对方在等待ACK */
ISP_CALLBACK_RECEIVE_NACK_WAIT, /* 数据已经收到,校验错误对方在等待NACK */
ISP_CALLBACK_SEND_ACK_WAIT, /* 数据已经发出等待对面ACK */
ISP_CALLBACK_CMD_, /* 收到命令,对方在等待ACK */
} isp_callback_reason_t;
typedef struct __attribute__((packed)) isp_obj_struct {
isp_cmd_id_t cmd_id;
uint8_t check;
uint16_t length;
isp_file_type_t file_type;
uint8_t *file_data;
uint8_t auot_ack; /* 数据包自动回ack0自动非零不自动*/
uint32_t time_out;
isp_status_t status; /* 中间变量,用以状态机控制 */
void (*isp_callback)(struct isp_obj_struct *isp_obj, isp_callback_reason_t isp_callback_reason);
} isp_obj_t;
int isp_uart_send_data(isp_obj_t *isp_obj_uart);
uint8_t isp_uart_init(isp_obj_t *isp_obj);
int isp_uart_send_ack(isp_obj_t *isp_obj_uart, ips_reply_t ips_reply);

241
examples/audio_cube/main.c Normal file
View File

@ -0,0 +1,241 @@
/**
* @file main.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_i2s.h"
#include "hal_dma.h"
#include "data_protocol.h"
#include "wav_play_from_isp.h"
audio_dev_t audio_test;
isp_obj_t isp_obj_uart;
struct device *uart_isp;
uint8_t flag = 0;
/**
* @brief isp
*
* @param isp_obj
* @param isp_callback_reason
*/
void isp_uart_callback(isp_obj_t *isp_obj, isp_callback_reason_t isp_callback_reason)
{
int vol;
switch (isp_callback_reason) {
case ISP_CALLBACK_RECEIVE_ACK_WAIT:
/* receive data information */
if (isp_obj->cmd_id == 0x50) {
/* receive data information */
if (isp_obj->file_type == 0x59 && audio_test.audio_state)
audio_test.audio_state = 1;
isp_obj->auot_ack = 0; /* auto ack */
} else if (isp_obj->cmd_id == 0x51) {
/* updata buff */
if (audio_test.audio_state == 0) { /* Not allowed to play */
isp_obj->auot_ack = 0;
} else if (audio_test.audio_state < 4) { /* start play */
audio_test.buff_using = (isp_obj->file_data == audio_test.buff[0]) ? 1 : 0;
audio_test.buff_data_size[!audio_test.buff_using] = isp_obj->length;
// audio_test.audio_control(&audio_test, AUDIO_CMD_PLAY_START, NULL);
if (audio_test.audio_state == 1) {
if (audio_test.audio_init(&audio_test, 0, isp_obj->file_data)) {
break;
}
}
audio_test.audio_control(&audio_test, AUDIO_CMD_PLAY_START, NULL);
isp_obj->file_data = audio_test.buff[!audio_test.buff_using];
audio_test.buff_data_size[!audio_test.buff_using] = 0;
isp_obj->auot_ack = 0;
} else if (audio_test.audio_state == 4) { /* play ing */
if (isp_obj->file_data == audio_test.buff[0])
audio_test.buff_data_size[0] = isp_obj->length;
else
audio_test.buff_data_size[1] = isp_obj->length;
/* non auto ack , audio callback */
isp_obj->auot_ack = 1;
}
}
// MSG("ISP_CALLBACK_RECEIVE_ACK_WAIT\r\n");
break;
case ISP_CALLBACK_RECEIVE_NACK_WAIT:
/* receive data err */
// MSG("ISP_CALLBACK_RECEIVE_NACK_WAIT\r\n");
isp_obj->auot_ack = 0; /* auto ack */
break;
case ISP_CALLBACK_SEND_ACK_WAIT:
/* receive data end,wait ack */
// MSG("ISP_CALLBACK_SEND_ACK_WAIT\r\n");
break;
case ISP_CALLBACK_SEND_SUCCES_ACK:
/* send ok,send file next data */
if (audio_test.audio_state == 11) {
/* Continue to the recording */
audio_test.audio_control(&audio_test, AUDIO_CMD_RECORD_START, NULL);
isp_obj_uart.file_data = audio_test.buff[!audio_test.buff_using];
isp_obj_uart.length = audio_test.buff_data_size[!audio_test.buff_using];
isp_uart_send_data(&isp_obj_uart);
audio_test.buff_data_size[!audio_test.buff_using] = 0;
audio_test.audio_state = 12;
}
// MSG("ISP_CALLBACK_SEND_SUCCES_ACK\r\n");
break;
case ISP_CALLBACK_SEND_ERROR_ACK:
/* send err,resend last data */
// MSG("ISP_CALLBACK_SEND_ERROR_ACK\r\n");
break;
case ISP_CALLBACK_CMD_:
// MSG("ISP_CALLBACK_CMD_\r\n");
switch (isp_obj->cmd_id) {
case CMD_PLAY_START: /* play */
if (audio_test.audio_state == 0)
audio_test.audio_state = 1;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_PLAY_PAUSE: /* pause */
// if (audio_test.audio_state == 3)
// audio_test.audio_state = 2;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_PLAY_STOP: /* stop */
if (audio_test.audio_state)
audio_test.audio_state = 0;
// device_close(i2s);
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_INCREASE: /* volume +1 */
vol = audio_test.audio_control(&audio_test, AUDIO_CMD_GET_VOLUME, NULL);
if (vol >= 100)
vol = 99;
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)(vol + 1));
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_DECREASE: /* volume -1 */
vol = audio_test.audio_control(&audio_test, AUDIO_CMD_GET_VOLUME, NULL);
if (vol <= 0)
vol = 1;
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)(vol - 1));
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_SET: /* volume set */
vol = isp_obj->file_type;
if (vol <= 0)
vol = 0;
else if (vol >= 100)
vol = 100;
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)vol);
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_GET: /* volume get */
vol = audio_test.audio_control(&audio_test, AUDIO_CMD_GET_VOLUME, NULL);
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, (vol << 8) & 0xFF00);
break;
case CMD_SAMPLING_RATE: /* sampling_rate */
audio_test.record_config->sampl_freq = isp_obj->file_type;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_CHANNEL_NUM: /* channel */
audio_test.record_config->channel_num = isp_obj->file_type;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_RECORD_START: /* record */
if (audio_test.audio_state == 4 || /* play ing */
audio_test.audio_init(&audio_test, 1, isp_obj->file_data)) {
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_ERROR);
break;
}
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
audio_test.audio_state = 10;
audio_test.audio_control(&audio_test, AUDIO_CMD_RECORD_START, NULL);
break;
case CMD_RECORD_STOP: /* stop record */
audio_test.audio_control(&audio_test, AUDIO_CMD_PLAY_STOP, NULL);
audio_test.audio_state = 10;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
default:
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
}
break;
default:
MSG("unkown\r\n");
break;
}
}
int main(void)
{
/* Disable log output */
bflb_platform_print_set(1);
bflb_platform_init(0);
/* init audio */
// audio_init(&audio_test);
isp_wav_play_register(&audio_test);
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)40);
/* init isp uart */
isp_uart_init(&isp_obj_uart);
isp_obj_uart.isp_callback = isp_uart_callback;
isp_obj_uart.file_data = audio_test.buff[!audio_test.buff_using];
while (1) {
bflb_platform_delay_ms(100);
/* code */
if (isp_obj_uart.status.isp_state_mode == NO_TASK) {
/* code */
}
}
}

View File

@ -0,0 +1,34 @@
**board/bl706_avb/pinmux_config.h** 中 **PINMUX_SELECT** 选择 **PINMUX_LVGL**
```bash
$ make APP=isp_audio_test BOARD=bl706_avb
isp 协议 测试
isp 协议 实现方式:
isp_uart_init 函数为 串口初始化
isp_task_handler 函数为 接收 处理 数据的主要实现,若需要实现超时处理功能,需要定时调用。 需要传入数据地址和sizesize可以为0表示无数据可以用来处理超时。
只有在等待ACK或者帧空闲时允许接收数据接收到数据后按照协议解析内容。
若是在等待ACK接收到ACK后会调用注册好的回调函数。
若是空闲状态,判断接收的数据来区分命令和数据包,
收到命令或数据包后会调用回调函数。
若是数据包退出回调后会自动根据校验回复ACK或NACK不要自动回复把auot_ack写1就可,但需要自己去合适的地方回复ack。
命令帧不会自动回复ACK需要在回调里结合具体命令类型去回复2字节信息或者直接开始发送数据包
isp_uart_send_data 函数 为发送数据包或命令isp_uart_send_data 函数只允许在帧状态机空闲时发送数据或命令,避免冲突。预期是放在回调函数里使用。
在发送数据时命令或数据包的帧头部分会使用阻塞发送但是数据部分会使用DMA-UART方式发送启动DMA后立即返回并在DMA结束中断里调用回调函数并将进入等待 ACK 状态,
回调函数需要自己根据需求来设计isp触发事件后会调用回调函数并传入触发原因预期中流程是
连续上传数据包 1.上位机给出命令 --> 2.触发命令回调,发送第一个数据包(文件名) --> 3.发完等待ACK --> 4.收到ACK,触发ACK回调 --> 5.继续发送下一个数据包--> 回到步骤 3
问题:发送中间上位机如何发送其他命令包进行其他操作?
下传数据包 1.上位机直接发出数据包 --> 2.触发WAIT_ACK回调 --> 3.回调里完成数据操作,退出回调后自动完成ACK --> 4.上位机发送数据包回到步骤1
|______-----> 5.上位机发送命令包,其他操作
```

View File

@ -0,0 +1,490 @@
/**
* @file wav_play_form_sd_card.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bsp_es8388.h"
#include "hal_i2s.h"
#include "hal_dma.h"
#include "data_protocol.h"
#include "wav_play_from_isp.h"
extern isp_obj_t isp_obj_uart;
static int wav_data_parser(uint8_t *buff, uint16_t max_size, wav_information_t *wav_information);
static uint32_t pcm_24bit_to_32bit(uint8_t *buff, uint32_t data_size);
static int isp_wav_play_init(struct audio_dev *audio_dev, uint8_t mode, uint8_t *buff);
static int isp_wav_play_control(struct audio_dev *audio_dev, AUDIO_CMD_t cmd, void *args);
static int isp_wav_play_callback(audio_dev_t *audio_dev);
uint8_t audio_buff[2][4 * 1024] __attribute__((section(".system_ram"), aligned(4)));
static ES8388_Cfg_Type ES8388Cfg = {
.work_mode = ES8388_CODEC_MDOE, /*!< ES8388 work mode */
.role = ES8388_SLAVE, /*!< ES8388 role */
.mic_input_mode = ES8388_DIFF_ENDED_MIC, /*!< ES8388 mic input mode */
.mic_pga = ES8388_MIC_PGA_9DB, /*!< ES8388 mic PGA */
.i2s_frame = ES8388_LEFT_JUSTIFY_FRAME, /*!< ES8388 I2S frame */
.data_width = ES8388_DATA_LEN_16, /*!< ES8388 I2S dataWitdh */
};
static wav_information_t Wav_Information;
static record_config_t record_config;
static audio_dev_t *p_Audio_Dev = NULL;
static void dma_ch2_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (p_Audio_Dev && p_Audio_Dev->audio_callback) {
p_Audio_Dev->audio_callback(p_Audio_Dev);
}
}
static void dma_ch3_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (p_Audio_Dev && p_Audio_Dev->audio_callback) {
p_Audio_Dev->audio_callback(p_Audio_Dev);
}
}
/* get File pointer from top of file*/
static int wav_data_parser(uint8_t *buff, uint16_t max_size, wav_information_t *wav_information)
{
uint32_t offset = 0;
uint32_t chunk_id;
if (buff == NULL)
return 1;
/* RIFF WAVE Chunk */
chunk_id = ((chunk_riff_t *)&buff[offset])->chunk_id;
if (chunk_id == 0x46464952) {
wav_information->chunk_riff_offset = offset;
wav_information->chunk_riff = *((chunk_riff_t *)&buff[offset]);
offset += sizeof(chunk_riff_t);
} else {
wav_information->chunk_riff_offset = -1;
return 1;
}
/* Format Chunk */
chunk_id = ((chunk_format_t *)&buff[offset])->chunk_id;
if (chunk_id == 0x20746D66 && offset < max_size) /* fmt */
{
wav_information->chunk_format_offset = offset;
wav_information->chunk_format = *((chunk_format_t *)&buff[offset]);
offset += ((chunk_format_t *)&buff[offset])->chunk_size + 8;
} else {
wav_information->chunk_format_offset = -1;
return 1;
}
/* Fact/list Chunk */
chunk_id = ((chunk_fact_t *)&buff[offset])->chunk_id;
if ((chunk_id == 0X74636166 || chunk_id == 0X5453494C) && offset < max_size) /*fact or list*/
{
wav_information->chunk_fact_offset = offset;
wav_information->chunk_fact = *((chunk_fact_t *)&buff[offset]);
offset += ((chunk_fact_t *)&buff[offset])->chunk_size + 8;
} else {
wav_information->chunk_fact_offset = -1;
}
/* Data Chunk */
chunk_id = ((chunk_data_t *)&buff[offset])->chunk_id;
if (chunk_id == 0X61746164 && offset < max_size) {
wav_information->chunk_data_offset = offset;
wav_information->chunk_data = *((chunk_data_t *)&buff[offset]);
} else {
wav_information->chunk_data_offset = -1;
return 1;
}
return 0;
}
static uint32_t pcm_24bit_to_32bit(uint8_t *buff, uint32_t data_size)
{
/* buff大小应该在data_size的三分之四倍以上 */
for (uint16_t i = data_size / 3; i > 0; i--) {
buff[i * 4 - 1] = buff[i * 3 - 1];
buff[i * 4 - 2] = buff[i * 3 - 2];
buff[i * 4 - 3] = buff[i * 3 - 3];
buff[i * 4 - 4] = 0;
}
return data_size / 3 * 4;
}
static int isp_wav_play_init(struct audio_dev *audio_dev, uint8_t mode, uint8_t *buff)
{
int res;
struct device *dma_ch2 = device_find("i2s_ch2");
struct device *dma_ch3 = device_find("i2s_ch3");
audio_dev->device = device_find("I2S");
if (audio_dev->device) {
device_close(audio_dev->device);
} else {
i2s_register(I2S0_INDEX, "I2S");
audio_dev->device = device_find("I2S");
}
if (mode == 1) {
goto record_conf;
}
/* play config */
if (dma_ch2) {
device_close(dma_ch2);
} else {
dma_register(DMA0_CH2_INDEX, "i2s_ch2");
dma_ch2 = device_find("i2s_ch2");
}
/* Parse the WAV file */
res = wav_data_parser(buff, 1000, &Wav_Information);
if (!res) {
audio_dev->wav_information = &Wav_Information;
} else {
/* MSG("wav file parse error\r\n"); */
return 1;
}
if ((audio_dev->device) && dma_ch2) {
/* I2S Config */
I2S_DEV(audio_dev->device)->interface_mode = I2S_MODE_LEFT;
I2S_DEV(audio_dev->device)->sampl_freq_hz = audio_dev->wav_information->chunk_format.sample_rate;
I2S_DEV(audio_dev->device)->channel_num = audio_dev->wav_information->chunk_format.num_of_channels;
uint8_t pcm_w = audio_dev->wav_information->chunk_format.bits_per_sample / 8;
if (pcm_w <= 2) {
I2S_DEV(audio_dev->device)->frame_size = I2S_FRAME_LEN_16;
} else {
I2S_DEV(audio_dev->device)->frame_size = I2S_FRAME_LEN_32;
}
I2S_DEV(audio_dev->device)->data_size = I2S_DEV(audio_dev->device)->frame_size;
I2S_DEV(audio_dev->device)->fifo_threshold = 3;
res = device_open((audio_dev->device), DEVICE_OFLAG_DMA_TX);
/* ES8388 Config */
switch (I2S_DEV(audio_dev->device)->data_size) {
case I2S_FRAME_LEN_16:
ES8388Cfg.data_width = ES8388_DATA_LEN_16;
break;
case I2S_FRAME_LEN_24:
ES8388Cfg.data_width = ES8388_DATA_LEN_24;
break;
case I2S_FRAME_LEN_32:
ES8388Cfg.data_width = ES8388_DATA_LEN_32;
break;
default:
return 1;
break;
}
ES8388_Init(&ES8388Cfg);
ES8388_Set_Voice_Volume(50);
/* DMA Config */
DMA_DEV(dma_ch2)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch2)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch2)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch2)->dst_req = DMA_REQUEST_I2S_TX;
DMA_DEV(dma_ch2)->src_burst_size = DMA_BURST_4BYTE;
DMA_DEV(dma_ch2)->dst_burst_size = DMA_BURST_4BYTE;
switch (I2S_DEV(audio_dev->device)->data_size * I2S_DEV(audio_dev->device)->channel_num) {
case 1:
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
break;
case 2:
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_16BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_16BIT;
break;
default:
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_32BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_32BIT;
break;
}
device_open(dma_ch2, 0);
device_set_callback(dma_ch2, dma_ch2_irq_callback);
device_control(dma_ch2, DEVICE_CTRL_SET_INT, NULL);
device_control((audio_dev->device), DEVICE_CTRL_ATTACH_TX_DMA, (void *)dma_ch2);
/* Delete the information data*/
uint32_t data_size = audio_dev->buff_data_size[!audio_dev->buff_using];
data_size = data_size - audio_dev->wav_information->chunk_data_offset;
audio_dev->buff_data_size[!audio_dev->buff_using] = data_size;
uint8_t *p_dst = audio_dev->buff[!audio_dev->buff_using];
uint8_t *p_src = &(audio_dev->buff[!audio_dev->buff_using][audio_dev->wav_information->chunk_data_offset]);
memcpy(p_dst, p_src, data_size);
if (audio_dev->wav_information->chunk_format.bits_per_sample / 8 == 3) {
audio_dev->buff_data_size[!audio_dev->buff_using] = pcm_24bit_to_32bit(audio_dev->buff[!audio_dev->buff_using], data_size);
} else {
}
} else {
return 1;
}
return 0;
/* record config */
record_conf:
if (dma_ch3) {
device_close(dma_ch3);
} else {
dma_register(DMA0_CH3_INDEX, "i2s_ch3");
dma_ch3 = device_find("i2s_ch3");
}
if ((audio_dev->device) && dma_ch3) {
I2S_DEV(audio_dev->device)->iis_mode = I2S_MODE_MASTER;
I2S_DEV(audio_dev->device)->interface_mode = I2S_MODE_LEFT;
I2S_DEV(audio_dev->device)->channel_num = audio_dev->record_config->channel_num;
I2S_DEV(audio_dev->device)->data_size = audio_dev->record_config->data_size;
if (I2S_DEV(audio_dev->device)->data_size <= 2) {
I2S_DEV(audio_dev->device)->frame_size = I2S_FRAME_LEN_16;
} else {
I2S_DEV(audio_dev->device)->frame_size = I2S_FRAME_LEN_32;
}
I2S_DEV(audio_dev->device)->fifo_threshold = 4;
switch (audio_dev->record_config->sampl_freq) {
case SAMPL_FREQ_8000:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 8000;
break;
case SAMPL_FREQ_16000:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 16000;
break;
// case SAMPL_FREQ_32000:
// I2S_DEV(audio_dev->device)->sampl_freq_hz = 32000;
// break;
case SAMPL_FREQ_44100:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 44100;
break;
case SAMPL_FREQ_48000:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 48000;
break;
default:
break;
}
device_open(audio_dev->device, DEVICE_OFLAG_DMA_RX);
/* ES8388 Config */
switch (I2S_DEV(audio_dev->device)->data_size) {
case I2S_FRAME_LEN_16:
ES8388Cfg.data_width = ES8388_DATA_LEN_16;
break;
case I2S_FRAME_LEN_24:
ES8388Cfg.data_width = ES8388_DATA_LEN_24;
break;
case I2S_FRAME_LEN_32:
ES8388Cfg.data_width = ES8388_DATA_LEN_32;
break;
default:
return 1;
break;
}
ES8388_Init(&ES8388Cfg);
/* DMA Config */
DMA_DEV(dma_ch3)->direction = DMA_PERIPH_TO_MEMORY;
DMA_DEV(dma_ch3)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch3)->src_req = DMA_REQUEST_I2S_RX;
DMA_DEV(dma_ch3)->dst_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_4BYTE;
DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_4BYTE;
switch (I2S_DEV(audio_dev->device)->data_size * I2S_DEV(audio_dev->device)->channel_num) {
case 1:
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
break;
case 2:
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_16BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_16BIT;
break;
default:
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_32BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_32BIT;
break;
}
device_open(dma_ch3, 0);
device_set_callback(dma_ch3, dma_ch3_irq_callback);
device_control(dma_ch3, DEVICE_CTRL_SET_INT, NULL);
device_control((audio_dev->device), DEVICE_CTRL_ATTACH_RX_DMA, (void *)dma_ch3);
}
return 0;
}
static int isp_wav_play_control(struct audio_dev *audio_dev, AUDIO_CMD_t cmd, void *args)
{
static uint32_t volume = 50;
int res = -1;
switch (cmd) {
case AUDIO_CMD_PLAY_START:
if (audio_dev->audio_state) {
audio_dev->buff_using = !audio_dev->buff_using;
res = device_write(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_data_size[audio_dev->buff_using]);
audio_dev->audio_state = 4;
res = 0;
}
break;
case AUDIO_CMD_PLAY_STOP:
if (audio_dev->audio_state) {
audio_dev->audio_state = 1;
res = 0;
}
break;
case AUDIO_CMD_RECORD_START:
if (audio_dev->audio_state >= 10) {
audio_dev->buff_using = !audio_dev->buff_using;
res = device_read(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_size_max);
audio_dev->audio_state = 12;
}
break;
case AUDIO_CMD_RECORD_STOP:
if (audio_dev->audio_state > 10) {
audio_dev->audio_state = 10;
res = 0;
}
break;
case AUDIO_CMD_SET_VOLUME:
if (audio_dev->audio_state) {
res = ES8388_Set_Voice_Volume((uint32_t)args);
res = 0;
volume = (uint32_t)args;
}
break;
case AUDIO_CMD_GET_VOLUME:
if (audio_dev->audio_state) {
// res = ES8388_Set_Voice_Volume((uint32_t)args);
res = (int)volume;
}
break;
default:
break;
}
return res;
}
static int isp_wav_play_callback(audio_dev_t *audio_dev)
{
if (audio_dev->audio_state < 10) { /* play*/
if (audio_dev->buff_data_size[!audio_dev->buff_using] > 0 && isp_obj_uart.status.isp_state_mode == RECEIVE_WAIT_ACK) {
/* data ready, switch buff */
audio_dev->buff_using = !audio_dev->buff_using;
device_write(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_data_size[audio_dev->buff_using]);
audio_dev->buff_data_size[audio_dev->buff_using] = 0;
audio_dev->buff_data_size[!audio_dev->buff_using] = isp_obj_uart.length;
isp_obj_uart.file_data = audio_dev->buff[!audio_dev->buff_using];
isp_obj_uart.status.isp_state_mode = NO_TASK;
isp_uart_send_ack(&isp_obj_uart, REPLY_SUCCES);
} else {
/* Data not ready, wait data receive*/
audio_dev->audio_state = 3;
}
} else { /* record */
audio_dev->buff_data_size[audio_dev->buff_using] = audio_dev->buff_size_max;
if (audio_dev->audio_state == 12) {
if (isp_obj_uart.status.isp_state_mode == NO_TASK) {
/* Continue to the recording */
audio_dev->buff_using = !audio_dev->buff_using;
device_read(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_size_max);
/* send data to PC */
isp_obj_uart.file_data = audio_dev->buff[!audio_dev->buff_using];
isp_obj_uart.length = audio_dev->buff_data_size[!audio_dev->buff_using];
isp_obj_uart.cmd_id = FILE_DATA;
isp_obj_uart.file_type = 0x58;
isp_uart_send_data(&isp_obj_uart);
audio_dev->buff_data_size[!audio_dev->buff_using] = 0;
} else {
/* Data not ready, wait data transmit*/
audio_dev->audio_state = 11;
}
}
}
return 0;
}
int isp_wav_play_register(audio_dev_t *audio_dev)
{
p_Audio_Dev = audio_dev;
audio_dev->audio_init = isp_wav_play_init,
audio_dev->audio_control = isp_wav_play_control,
audio_dev->audio_callback = isp_wav_play_callback,
audio_dev->buff[0] = audio_buff[0];
audio_dev->buff[1] = audio_buff[1];
audio_dev->buff_data_size[0] = 0;
audio_dev->buff_data_size[1] = 0;
audio_dev->audio_state = 0;
audio_dev->buff_size_max = sizeof(audio_buff) / 2;
record_config.data_size = 2;
record_config.channel_num = 1;
record_config.sampl_freq = SAMPL_FREQ_16000;
audio_dev->record_config = &record_config;
return 0;
}

View File

@ -0,0 +1,132 @@
/**
* @file wav_play_form_sd_card.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __MAV_PLAY_H__
#define __MAV_PLAY_H__
#include "hal_i2s.h"
//WAV文件块定义
/* RIFF (RIFF WAVE Chunk) */
typedef struct __attribute__((packed)) {
uint32_t chunk_id; /*chunk id:"RIFF",(0X46464952) */
uint32_t chunk_size; /*file size -8 */
uint32_t format; /* "WAVE" (0X45564157) */
} chunk_riff_t;
/* fmt (Format Chunk)*/
typedef struct __attribute__((packed)) {
uint32_t chunk_id; /* chunk id:"fmt",(0X20746D66) */
uint32_t chunk_size; /* fmt size -8 = 20*/
uint16_t audio_format; /* 音频格式;0X10,表示线性 PCM; 0X11 表示 IMA ADPCM */
uint16_t num_of_channels; /* 通道数量;1,表示单声道;2,表示双声道*/
uint32_t sample_rate; /* 采样率;0X1F40,表示 8Khz */
uint32_t byte_rate; /* 字节速率 */
uint16_t block_align; /*块对齐(字节)*/
uint16_t bits_per_sample; /*单个采样数据大小;4 位 ADPCM,设置为 4*/
} chunk_format_t;
//fact (Fact Chunk)
typedef struct __attribute__((packed)) {
uint32_t chunk_id; //chunk id;这里固定为"fact",即 0X74636166;
uint32_t chunk_size; //子集合大小(不包括 ID 和 Size);这里为:4.
uint32_t data_fact_size; //数据转换为 PCM 格式后的大小
} chunk_fact_t;
//data (Data Chunk)
typedef struct __attribute__((packed)) {
uint32_t chunk_id; //chunk id;这里固定为"data",即 0X61746164
uint32_t chunk_size; //子集合大小(不包括 ID 和 Size);文件大小-60.
} chunk_data_t;
//
typedef enum {
CHUNK_RIFF,
CHUNK_FORMAT,
CHUNK_FACT,
CHUNK_DATA,
} mav_chunk_t;
//.wav information
typedef struct
{
int chunk_riff_offset; //在数据里的位置偏移,-1表示没有此块
chunk_riff_t chunk_riff;
int chunk_format_offset;
chunk_format_t chunk_format;
int chunk_fact_offset;
chunk_fact_t chunk_fact;
int chunk_data_offset;
chunk_data_t chunk_data;
} wav_information_t;
typedef enum {
AUDIO_CMD_PLAY_START,
AUDIO_CMD_PLAY_STOP,
AUDIO_CMD_RECORD_START,
AUDIO_CMD_RECORD_STOP,
AUDIO_CMD_GET_VOLUME,
AUDIO_CMD_SET_VOLUME,
} AUDIO_CMD_t;
/* 频率索引*/
typedef enum {
SAMPL_FREQ_8000 = 0,
SAMPL_FREQ_16000 = 1,
SAMPL_FREQ_44100 = 2,
SAMPL_FREQ_48000 = 3,
} sampl_freq_t;
/* 录音设置参数 */
typedef struct
{
uint16_t data_size;
uint16_t channel_num;
sampl_freq_t sampl_freq;
} record_config_t;
/* 播放控制块 */
typedef struct audio_dev {
uint8_t *buff[2];
uint32_t buff_data_size[2]; //buff内数据长度
uint32_t buff_size_max; //buff的大小
uint8_t buff_using; //正在使用的buff
uint8_t audio_state; //状态 0:就是不允许播放 1:暂停中,如果要播放,需要重新解析wav信息头 2:暂停中,可以接着播放(不用重新解析wav信息) 3:播放中,但在等待数据(数据不及时) 4:正常播放中,数据正常
// 11:录音模式(数据堆积,未及时发送完,在等待上位机ACK) 12录音模式(正常,数据及时发送)
uint8_t audio_type; //类型
int (*audio_init)(struct audio_dev *audio_dev, uint8_t mode, uint8_t *buff); //初始化函数播放需要传入wav文件头地址
int (*audio_control)(struct audio_dev *audio_dev, AUDIO_CMD_t cmd, void *args);
int (*audio_callback)(struct audio_dev *audio_dev); //中断回调函数用来重新装载buff
struct device *device; //i2s的device可以考虑换成指向其他外设
wav_information_t *wav_information; //播放wav信息结构体
record_config_t *record_config; //录音配置结构体
} audio_dev_t;
int isp_wav_play_register(audio_dev_t *audio_dev);
#endif

View File

@ -0,0 +1,9 @@
set(BSP_COMMON_DIR ${CMAKE_SOURCE_DIR}/bsp/bsp_common)
set(TARGET_REQUIRED_PRIVATE_INCLUDE ${BSP_COMMON_DIR}/es8388 )
set(TARGET_REQUIRED_SRCS ${BSP_COMMON_DIR}/es8388/bsp_es8388.c data_protocol.c wav_play_from_isp.c)
set(mains main.c)
generate_bin()

View File

@ -0,0 +1,742 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project Name="audio_cube" Version="1" Language="C">
<Description>CPU: RV32IMAFC
Chip: bl70x
Board: bl70x_iot
</Description>
<Dependencies Name="Debug"/>
<VirtualDirectory Name="app">
<File Name="../main.c">
<FileOption/>
</File>
<File Name="../wav_play_from_isp.c">
<FileOption/>
</File>
<File Name="../data_protocol.c"/>
</VirtualDirectory>
<VirtualDirectory Name="chip">
<VirtualDirectory Name="riscv">
<File Name="../../../drivers/bl702_driver/startup/interrupt.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/startup/system_bl702.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="startup">
<File Name="../../../drivers/bl702_driver/startup/GCC/entry.S">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/startup/GCC/start_load.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="hal">
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_acomp.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_adc.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_boot2.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_cam.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_clock.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_common.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_dac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_dma.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_emac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_flash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_gpio.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_i2c.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_i2s.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_keyscan.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_mjpeg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_mtimer.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_pm.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_pwm.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_qdec.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_rtc.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_aes.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_dsa.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_ecdsa.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_sec_hash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_spi.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_timer.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_uart.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_usb.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/hal_drv/src/hal_wdt.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="std">
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_acomp.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_adc.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_aon.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_cam.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_clock.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_dac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_dma.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_ef_ctrl.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_emac.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_glb.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_hbn.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_i2c.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_i2c_gpio_sim.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_i2s.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_ir.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_common.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_kys.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_l1c.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_mjpeg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_pds.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_psram.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_pwm.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_qdec.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_romapi.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sec_dbg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sec_eng.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sf_cfg.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sf_cfg_ext.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sf_ctrl.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sflash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_sflash_ext.c" ExcludeProjConfig="">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_spi.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_timer.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_uart.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_usb.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_xip_sflash.c">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/std_drv/src/bl702_xip_sflash_ext.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="bsp">
<VirtualDirectory Name="board">
<File Name="../../../bsp/board/bl702/board.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="bsp_common">
<File Name="../../../bsp/bsp_common/platform/bflb_platform.c">
<FileOption/>
</File>
<File Name="../../../bsp/bsp_common/platform/syscalls.c">
<FileOption/>
</File>
<File Name="../../../bsp/bsp_common/es8388/bsp_es8388.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="common">
<File Name="../../../common/device/drv_device.c">
<FileOption/>
</File>
<File Name="../../../common/memheap/drv_mmheap.c">
<FileOption/>
</File>
<File Name="../../../common/ring_buffer/ring_buffer.c">
<FileOption/>
</File>
<File Name="../../../common/soft_crc/softcrc.c">
<FileOption/>
</File>
<File Name="../../../common/misc/misc.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="script">
<File Name="../../../tools/openocd/bl70x_gdb.init">
<FileOption/>
</File>
<File Name="../../../drivers/bl702_driver/regs/bl70x_reg.svc">
<FileOption/>
</File>
</VirtualDirectory>
<MonitorProgress>
<DebugLaunch>83</DebugLaunch>
<FlashOperate>107</FlashOperate>
</MonitorProgress>
<VirtualDirectory Name="components">
<VirtualDirectory Name="fatfs">
<File Name="../../../components/fatfs/diskio.c">
<FileOption/>
</File>
<File Name="../../../components/fatfs/ff.c">
<FileOption/>
</File>
<File Name="../../../components/fatfs/ffsystem.c">
<FileOption/>
</File>
<File Name="../../../components/fatfs/ffunicode.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="shell">
<File Name="../../../components/shell/shell.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="usb_stack">
<VirtualDirectory Name="class">
<VirtualDirectory Name="cdc">
<File Name="../../../components/usb_stack/class/cdc/usbd_cdc.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="hid">
<File Name="../../../components/usb_stack/class/hid/usbd_hid.c">
<FileOption/>
</File>
</VirtualDirectory>
<VirtualDirectory Name="msc">
<File Name="../../../components/usb_stack/class/msc/usbd_msc.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
<VirtualDirectory Name="core">
<File Name="../../../components/usb_stack/core/usbd_core.c">
<FileOption/>
</File>
</VirtualDirectory>
</VirtualDirectory>
</VirtualDirectory>
<Dependencies Name="BuildSet"/>
<Dependencies Name="CK_Link_Debug"/>
<Dependencies Name="OpenOCD_Debug"/>
<BuildConfigs>
<BuildConfig Name="OpenOCD_Debug">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>no</InUse>
<Start>0x23000000</Start>
<Size>0x100000</Size>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start>0x22014000</Start>
<Size>0x4000</Size>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start>0x42018000</Start>
<Size>0x8000</Size>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>yes</InUse>
<Start>0x42020000</Start>
<Size>0xc000</Size>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>rv32imafc</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>no</UseEnhancedLRW>
<UseContinueBuild>no</UseContinueBuild>
<UseSemiHost>no</UseSemiHost>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>no</CreateHexFile>
<CreateBinFile>yes</CreateBinFile>
<Preprocessor>no</Preprocessor>
<Disassmeble>yes</Disassmeble>
<CallGraph>no</CallGraph>
<Map>yes</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName>$(ProjectPath)../../../tools/bflb_flash_tool/bflb_mcu_tool.exe --chipname=bl702 --interface=openocd --firmware="$(ProjectPath)/Obj/$(ProjectName).bin" </UserProgName>
</AfterMake>
</User>
<Compiler>
<Define>ARCH_RISCV;BFLB_USE_HAL_DRIVER;BFLB_USE_ROM_DRIVER;bl706_iot</Define>
<Undefine/>
<Optim>Optimize more (-O2)</Optim>
<DebugLevel>Default (-g)</DebugLevel>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../bsp/bsp_common/es8388;$(ProjectPath)../../../common/libc/inc;$(ProjectPath)../../../common/libc/inc/arm_gcc;$(ProjectPath)../../../common/libc/inc/bits;$(ProjectPath)../../../common/libc/inc/sys;$(ProjectPath)../../../common/libc/src;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc</IncludePath>
<OtherFlags>-fshort-enums -fno-common -fms-extensions -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wall -Wshift-negative-value -Wchar-subscripts -Wformat -Wuninitialized -Winit-self -Wignored-qualifiers -Wunused -Wundef -msmall-data-limit=4 -std=c99</OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>yes</OneElfS>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define/>
<Undefine/>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../bsp/bsp_common/es8388;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl602_driver/startup;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl602_driver/regs;$(ProjectPath)../../../drivers/bl602_driver/std_drv/inc</IncludePath>
<OtherFlags/>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<Garbage2>yes</Garbage2>
<LDFile>$(ProjectPath)../../../drivers/bl702_driver/bl702_flash.ld</LDFile>
<LibName>c</LibName>
<LibPath/>
<OtherFlags>--specs=nano.specs</OtherFlags>
<AutoLDFile>no</AutoLDFile>
<LinkType/>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>OpenOCD</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile/>
<AfterLoadFile>$(ProjectPath)/../../../tools/openocd/bl70x_gdb.init</AfterLoadFile>
<AutoRun>yes</AutoRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>23000000</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<Dumpcore>no</Dumpcore>
<DumpcoreText>$(ProjectPath)/$(ProjectName).cdkcore</DumpcoreText>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<CPUNumber>0</CPUNumber>
<Clock>2000</Clock>
<Delay>10</Delay>
<WaitReset>50</WaitReset>
<DDC>yes</DDC>
<TRST>no</TRST>
<DebugPrint>no</DebugPrint>
<Connect>Normal</Connect>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>21000000</SoftResetVal>
<RTOSType>Bare Metal</RTOSType>
<DownloadToFlash>yes</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
<GDBName/>
<GDBServerType>Local</GDBServerType>
<OtherFlags>-arch riscv</OtherFlags>
</ConfigICE>
<ConfigSIM>
<SIMTarget/>
<OtherFlags/>
<NoGraphic>yes</NoGraphic>
<Log>no</Log>
<SimTrace>no</SimTrace>
</ConfigSIM>
<ConfigOpenOCD>
<OpenOCDExecutablePath>openocd-hifive</OpenOCDExecutablePath>
<OpenOCDTelnetPortEnable>no</OpenOCDTelnetPortEnable>
<OpenOCDTelnetPort>4444</OpenOCDTelnetPort>
<OpenOCDTclPortEnable>no</OpenOCDTclPortEnable>
<OpenOCDTclPort>6666</OpenOCDTclPort>
<OpenOCDConfigOptions>-f ../../../tools/openocd/if_rv_dbg_plus.cfg -f ../../../tools/openocd/tgt_702.cfg</OpenOCDConfigOptions>
</ConfigOpenOCD>
</Debug>
<Flash>
<InitFile/>
<Erase>Erase Sectors</Erase>
<Algorithms Path="">bl70x_flasher.elf</Algorithms>
<Program>yes</Program>
<Verify>yes</Verify>
<ResetAndRun>no</ResetAndRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal/>
<External>no</External>
<Command/>
<Arguments/>
</Flash>
</BuildConfig>
<BuildConfig Name="CK_Link_Debug">
<Target>
<ROMBank Selected="1">
<ROM1>
<InUse>no</InUse>
<Start>0x23000000</Start>
<Size>0x100000</Size>
</ROM1>
<ROM2>
<InUse>no</InUse>
<Start>0x22014000</Start>
<Size>0x4000</Size>
</ROM2>
<ROM3>
<InUse>no</InUse>
<Start>0x42018000</Start>
<Size>0x8000</Size>
</ROM3>
<ROM4>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM4>
<ROM5>
<InUse>no</InUse>
<Start/>
<Size/>
</ROM5>
</ROMBank>
<RAMBank>
<RAM1>
<InUse>yes</InUse>
<Start>0x42020000</Start>
<Size>0xc000</Size>
<Init>yes</Init>
</RAM1>
<RAM2>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM2>
<RAM3>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM3>
<RAM4>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM4>
<RAM5>
<InUse>no</InUse>
<Start/>
<Size/>
<Init>yes</Init>
</RAM5>
</RAMBank>
<CPU>rv32imafc</CPU>
<UseMiniLib>yes</UseMiniLib>
<Endian>little</Endian>
<UseHardFloat>no</UseHardFloat>
<UseEnhancedLRW>no</UseEnhancedLRW>
<UseContinueBuild>no</UseContinueBuild>
<UseSemiHost>no</UseSemiHost>
</Target>
<Output>
<OutputName>$(ProjectName)</OutputName>
<Type>Executable</Type>
<CreateHexFile>no</CreateHexFile>
<CreateBinFile>yes</CreateBinFile>
<Preprocessor>no</Preprocessor>
<Disassmeble>yes</Disassmeble>
<CallGraph>no</CallGraph>
<Map>yes</Map>
</Output>
<User>
<BeforeCompile>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeCompile>
<BeforeMake>
<RunUserProg>no</RunUserProg>
<UserProgName/>
</BeforeMake>
<AfterMake>
<RunUserProg>no</RunUserProg>
<UserProgName>$(ProjectPath)../../../tools/bflb_flash_tool/bflb_mcu_tool.exe --chipname=bl702 --interface=openocd --firmware="$(ProjectPath)/Obj/$(ProjectName).bin" </UserProgName>
</AfterMake>
</User>
<Compiler>
<Define>BL702;BL702_EVB;ARCH_RISCV;bl706_avb</Define>
<Undefine/>
<Optim>Optimize more (-O2)</Optim>
<DebugLevel>Default (-g)</DebugLevel>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../bsp/bsp_common/es8388;$(ProjectPath)../../../common/libc/inc;$(ProjectPath)../../../common/libc/inc/arm_gcc;$(ProjectPath)../../../common/libc/inc/bits;$(ProjectPath)../../../common/libc/inc/sys;$(ProjectPath)../../../common/libc/src;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl602_driver/regs;$(ProjectPath)../../../drivers/bl602_driver/std_drv/inc</IncludePath>
<OtherFlags>-fshort-enums -fno-common -fms-extensions -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wall -Wshift-negative-value -Wchar-subscripts -Wformat -Wuninitialized -Winit-self -Wignored-qualifiers -Wunused -Wundef -msmall-data-limit=4 -std=c99</OtherFlags>
<Verbose>no</Verbose>
<Ansi>no</Ansi>
<Syntax>no</Syntax>
<Pedantic>no</Pedantic>
<PedanticErr>no</PedanticErr>
<InhibitWarn>no</InhibitWarn>
<AllWarn>yes</AllWarn>
<WarnErr>no</WarnErr>
<OneElfS>yes</OneElfS>
<Fstrict>no</Fstrict>
</Compiler>
<Asm>
<Define/>
<Undefine/>
<IncludePath>$(ProjectPath);$(ProjectPath)../;$(ProjectPath)../../../components/fatfs;$(ProjectPath)../../../components/freertos/Source/include;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../components/usb_stack/class/audio;$(ProjectPath)../../../components/usb_stack/class/cdc;$(ProjectPath)../../../components/usb_stack/class/hid;$(ProjectPath)../../../components/usb_stack/class/msc;$(ProjectPath)../../../components/usb_stack/class/video;$(ProjectPath)../../../components/usb_stack/class/webusb;$(ProjectPath)../../../components/usb_stack/class/winusb;$(ProjectPath)../../../components/usb_stack/common;$(ProjectPath)../../../components/usb_stack/core;$(ProjectPath)../../../bsp/board/bl702;$(ProjectPath)../../../bsp/bsp_common/platform;$(ProjectPath)../../../common/device;$(ProjectPath)../../../common/list;$(ProjectPath)../../../common/memheap;$(ProjectPath)../../../common/misc;$(ProjectPath)../../../common/ring_buffer;$(ProjectPath)../../../common/soft_crc;$(ProjectPath)../../../components/shell;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl702_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl702_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl702_driver/regs;$(ProjectPath)../../../drivers/bl702_driver/startup;$(ProjectPath)../../../drivers/bl702_driver/std_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/risc-v/Core/Include;$(ProjectPath)../../../drivers/bl602_driver/startup;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/inc;$(ProjectPath)../../../drivers/bl602_driver/hal_drv/default_config;$(ProjectPath)../../../drivers/bl602_driver/regs;$(ProjectPath)../../../drivers/bl602_driver/std_drv/inc</IncludePath>
<OtherFlags/>
<DebugLevel>gdwarf2</DebugLevel>
</Asm>
<Linker>
<Garbage>yes</Garbage>
<Garbage2>yes</Garbage2>
<LDFile>$(ProjectPath)../../../drivers/bl702_driver/bl702_flash.ld</LDFile>
<LibName>c</LibName>
<LibPath/>
<OtherFlags>--specs=nano.specs</OtherFlags>
<AutoLDFile>no</AutoLDFile>
<LinkType/>
</Linker>
<Debug>
<LoadApplicationAtStartup>yes</LoadApplicationAtStartup>
<Connector>Remote ICE</Connector>
<StopAt>yes</StopAt>
<StopAtText>main</StopAtText>
<InitFile/>
<AfterLoadFile>$(ProjectPath)/../../../tools/openocd/bl70x_gdb.init</AfterLoadFile>
<AutoRun>yes</AutoRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>23000000</SoftResetVal>
<ResetAfterLoad>no</ResetAfterLoad>
<Dumpcore>no</Dumpcore>
<DumpcoreText>$(ProjectPath)/$(ProjectName).cdkcore</DumpcoreText>
<ConfigICE>
<IP>localhost</IP>
<PORT>1025</PORT>
<CPUNumber>0</CPUNumber>
<Clock>2000</Clock>
<Delay>10</Delay>
<WaitReset>50</WaitReset>
<DDC>yes</DDC>
<TRST>no</TRST>
<DebugPrint>no</DebugPrint>
<Connect>Normal</Connect>
<ResetType>Hard Reset</ResetType>
<SoftResetVal>21000000</SoftResetVal>
<RTOSType>Bare Metal</RTOSType>
<DownloadToFlash>yes</DownloadToFlash>
<ResetAfterConnect>yes</ResetAfterConnect>
<GDBName/>
<GDBServerType>Local</GDBServerType>
<OtherFlags>-arch riscv</OtherFlags>
</ConfigICE>
<ConfigSIM>
<SIMTarget/>
<OtherFlags/>
<NoGraphic>yes</NoGraphic>
<Log>no</Log>
<SimTrace>no</SimTrace>
</ConfigSIM>
<ConfigOpenOCD>
<OpenOCDExecutablePath>openocd-hifive</OpenOCDExecutablePath>
<OpenOCDTelnetPortEnable>no</OpenOCDTelnetPortEnable>
<OpenOCDTelnetPort>4444</OpenOCDTelnetPort>
<OpenOCDTclPortEnable>no</OpenOCDTclPortEnable>
<OpenOCDTclPort>6666</OpenOCDTclPort>
<OpenOCDConfigOptions>-f ../../../tools/openocd/if_rv_dbg_plus.cfg -f ../../../tools/openocd/tgt_702.cfg</OpenOCDConfigOptions>
</ConfigOpenOCD>
</Debug>
<Flash>
<InitFile/>
<Erase>Erase Sectors</Erase>
<Algorithms Path="">bl70x_flasher.elf</Algorithms>
<Program>yes</Program>
<Verify>yes</Verify>
<ResetAndRun>no</ResetAndRun>
<ResetType>Hard Reset</ResetType>
<SoftResetVal/>
<External>no</External>
<Command/>
<Arguments/>
</Flash>
</BuildConfig>
</BuildConfigs>
<DebugSessions>
<watchExpressions>audio_isp_test:1;isp_obj_uart:1;audio_test:4;time_node:1;Wav_Information:1</watchExpressions>
<memoryExpressions>0x4201D700;;;</memoryExpressions>
<statistics>;;MHZ;</statistics>
<peripheralTabs>
<Tab disFormat="Hex">glb</Tab>
<Tab disFormat="Hex">uart</Tab>
</peripheralTabs>
<WatchDisplayFormat>1</WatchDisplayFormat>
<LocalDisplayFormat>1</LocalDisplayFormat>
<debugLayout/>
<memoryTabColSizeExpressions>72:4;100:8;100:8;100:8;</memoryTabColSizeExpressions>
</DebugSessions>
<DebugSessions>
<watchExpressions/>
<memoryExpressions>;;;</memoryExpressions>
<statistics>;;MHZ;</statistics>
<peripheralTabs>
<Tab disFormat="Hex">glb</Tab>
<Tab disFormat="Hex">uart</Tab>
</peripheralTabs>
<WatchDisplayFormat>1</WatchDisplayFormat>
<LocalDisplayFormat>1</LocalDisplayFormat>
<debugLayout/>
<memoryTabColSizeExpressions>100:8;100:8;100:8;100:8;</memoryTabColSizeExpressions>
</DebugSessions>
</Project>

View File

@ -0,0 +1,392 @@
/**
* @file ips.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "drv_mmheap.h"
#include "hal_uart.h"
#include "hal_dma.h"
#include "data_protocol.h"
struct device *uart;
static isp_obj_t *isp_obj_uart;
void ips_obj_init(isp_obj_t *isp_obj_p)
{
if (!isp_obj_p)
return;
isp_obj_p->cmd_id = 0;
isp_obj_p->check = 0;
isp_obj_p->length = 0;
isp_obj_p->file_type = 0;
isp_obj_p->auot_ack = 1;
isp_obj_p->status.isp_state_mode = 0;
isp_obj_p->status.already_steps = 0;
}
/**
* @brief uart tx dma irq, ch0
*
* @param dev
* @param args
* @param size
* @param state
*/
void dma_ch0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (isp_obj_uart == NULL) {
return;
}
/* close dma and dma irq */
device_control(uart, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
device_control(UART_DEV(uart)->tx_dma, DEVICE_CTRL_CLR_INT, NULL);
if (isp_obj_uart->status.isp_state_mode == SEND_DATA) {
isp_obj_uart->status.isp_state_mode = SEND_WAIT_ACK;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_ACK_WAIT);
}
}
// void dma_ch1_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
// {
// if (isp_obj_uart == NULL) {
// return;
// }
// if (isp_obj_uart->status.isp_state_mode == RECEIVE_DATA) {
// isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
// isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_RECEIVE_ACK_WAIT);
// }
// device_control(uart, DEVICE_CTRL_RX_DMA_SUSPEND, 0);
// isp_obj_uart->status.already_steps = 0;
// device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT));
// MSG("tx dma init\r\n");
// }
uint8_t isp_check(isp_obj_t *isp_obj)
{
if (isp_obj == NULL) {
return 0;
}
uint8_t check = isp_obj->cmd_id + (isp_obj->length & 0x00FF) + ((isp_obj->length >> 8) & 0x00FF);
if (isp_obj->length && isp_obj->file_data) {
for (uint16_t i = 0; i < isp_obj->length; i++) {
check += isp_obj->file_data[i];
}
}
return check;
}
/**
* @brief
*
* @param isp_obj_uart
* @return int
*/
int isp_uart_send_data(isp_obj_t *isp_obj_uart)
{
if (isp_obj_uart == NULL || isp_obj_uart->cmd_id == 0) {
return -1;
}
if ((isp_obj_uart->cmd_id & 0xF0) != 0x50)
return -2;
if (isp_obj_uart->status.isp_state_mode != NO_TASK)
return -3;
isp_obj_uart->check = isp_check(isp_obj_uart);
/* use tx blocking */
device_write(uart, 0, (void *)isp_obj_uart, sizeof(isp_cmd_id_t) + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(isp_file_type_t));
/* use DMA tx non-blocking */
device_control(uart, DEVICE_CTRL_TX_DMA_RESUME, NULL);
device_control(UART_DEV(uart)->tx_dma, DEVICE_CTRL_SET_INT, NULL);
device_write(uart, 0, isp_obj_uart->file_data, isp_obj_uart->length);
isp_obj_uart->status.already_steps = 0;
isp_obj_uart->status.isp_state_mode = SEND_DATA;
return 0;
}
/**
* @brief
*
* @param isp_obj_uart
* @return int
*/
int isp_uart_send_ack(isp_obj_t *isp_obj_uart, ips_reply_t ips_reply)
{
if (isp_obj_uart == NULL || isp_obj_uart->cmd_id == 0) {
return -1;
}
// if (isp_obj_uart->status.isp_state_mode != RECEIVE_WAIT_ACK) {
// return -2;
// }
/* use DMA tx blocking */
device_write(uart, 0, (uint8_t *)&ips_reply, 2);
return 0;
}
/**
* @brief
*
* @param isp_obj
* @param buff
* @param size
*/
void isp_task_handler(isp_obj_t *isp_obj, uint8_t *buff, uint32_t size)
{
static uint32_t time_last = 0;
uint32_t time_now = bflb_platform_get_time_ms();
/* debug information */
// MSG("hand:%d, len:%d, mode:%d\r\n", isp_obj_uart->status.already_steps, isp_obj_uart->status.receive_length, isp_obj_uart->status.isp_state_mode);
if (size == 0) {
if ((time_now - time_last > isp_obj->time_out) && isp_obj->time_out) {
/* time out */
}
}
for (uint32_t i = 0; i < size; i++) {
/* receive 状态机 */
switch (isp_obj_uart->status.already_steps) {
case 0:
if (isp_obj_uart->status.isp_state_mode == NO_TASK) {
isp_obj_uart->status.isp_state_mode = OTHER_STATE;
} else if (isp_obj_uart->status.isp_state_mode != SEND_WAIT_ACK) {
return;
}
isp_obj_uart->cmd_id = *buff;
isp_obj_uart->status.already_steps++;
break;
case 1:
isp_obj_uart->check = *buff;
isp_obj_uart->status.already_steps++;
if (isp_obj_uart->status.isp_state_mode == SEND_WAIT_ACK) {
isp_obj_uart->status.isp_state_mode = NO_TASK;
if (isp_obj_uart->cmd_id == 0X4F && isp_obj_uart->check == 0X4B) {
isp_obj_uart->status.ips_reply = REPLY_SUCCES;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_SUCCES_ACK);
isp_obj_uart->status.isp_state_mode = NO_TASK;
isp_obj_uart->status.already_steps = 0;
} else if (isp_obj_uart->cmd_id == 0X52 && isp_obj_uart->check == 0X45) {
isp_obj_uart->status.ips_reply = REPLY_ERROR;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_ERROR_ACK);
isp_obj_uart->status.isp_state_mode = NO_TASK;
isp_obj_uart->status.already_steps = 0;
}
}
break;
case 2:
isp_obj_uart->length = *buff;
isp_obj_uart->status.already_steps++;
break;
case 3:
isp_obj_uart->length += *buff << 8;
isp_obj_uart->status.already_steps++;
break;
case 4:
isp_obj_uart->file_type = *buff;
isp_obj_uart->status.already_steps++;
if ((isp_obj_uart->cmd_id & 0xF0) == 0x50) {
isp_obj_uart->status.isp_state_mode = RECEIVE_DATA;
isp_obj_uart->status.receive_length = 0;
} else {
isp_obj_uart->status.already_steps = 0;
/* 等待ACK的时候收到命令同时代表 命令 与 成功ACK */
if (isp_obj_uart->status.isp_state_mode == SEND_WAIT_ACK) {
/* 响应 CMD 含义 */
isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_CMD_);
/* 响应 ACK 含义 */
isp_obj_uart->status.ips_reply = REPLY_SUCCES;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_SEND_SUCCES_ACK);
isp_obj_uart->status.isp_state_mode = NO_TASK;
} else {
/* 正常空闲收到命令 */
isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_CMD_);
}
//isp_obj_uart->status.isp_state_mode = NO_TASK;
}
break;
case 5:
if (isp_obj_uart->status.receive_length < isp_obj_uart->length) {
isp_obj_uart->file_data[isp_obj_uart->status.receive_length] = *buff;
isp_obj_uart->status.receive_length++;
}
if (isp_obj_uart->status.receive_length >= isp_obj_uart->length) {
isp_obj_uart->status.isp_state_mode = RECEIVE_WAIT_ACK;
uint8_t check_data = isp_check(isp_obj_uart);
//MSG("check:%X\r\n", check);
if (isp_obj_uart->check == check_data) {
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_RECEIVE_ACK_WAIT);
/* auot send ack */
if (isp_obj_uart->auot_ack == 0) {
isp_uart_send_ack(isp_obj_uart, REPLY_SUCCES);
isp_obj_uart->status.isp_state_mode = NO_TASK;
}
} else {
isp_obj_uart->isp_callback(isp_obj_uart, ISP_CALLBACK_RECEIVE_NACK_WAIT);
/* auot send Nack */
if (isp_obj_uart->auot_ack == 0) {
isp_uart_send_ack(isp_obj_uart, REPLY_ERROR);
isp_obj_uart->status.isp_state_mode = NO_TASK;
}
}
isp_obj_uart->status.receive_length = 0;
isp_obj_uart->status.already_steps = 0;
}
break;
default:
break;
}
buff++;
}
time_last = time_now;
}
/**
* @brief uart_irq_callback
*
* @param dev
* @param args
* @param size
* @param state
*/
void uart_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
static uint8_t fer_err_flag = 0;
if (state == UART_EVENT_RX_FIFO || state == UART_EVENT_RTO) {
if (isp_obj_uart == NULL) {
return;
}
/* Tx fifo overflow, send nack*/
if(fer_err_flag){
if(state == UART_EVENT_RX_FIFO){
}else if(state == UART_EVENT_RTO){
isp_obj_uart->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj_uart, REPLY_ERROR);
fer_err_flag = 0;
}
return;
}
isp_task_handler(isp_obj_uart, args, size);
}
else if(state == UART_EVENT_RX_FER){
/* Tx fifo overflow, baud rate should be reduced */
fer_err_flag = 1;
device_control(dev,DEVICE_CTRL_UART_CLEAR_RX_FIFO,NULL);
}
}
/**
* @brief
*
*/
uint8_t isp_uart_init(isp_obj_t *isp_obj)
{
if (isp_obj == NULL)
return 1;
uart = device_find("debug_log");
if(uart){
device_close(uart);
}else{
uart_register(UART0_INDEX, "debug_log");
uart = device_find("debug_log");
}
if (uart) {
UART_DEV(uart)->id = 0;
UART_DEV(uart)->baudrate = 3000000;
UART_DEV(uart)->databits = UART_DATA_LEN_8;
UART_DEV(uart)->stopbits = UART_STOP_ONE;
UART_DEV(uart)->parity = UART_PAR_NONE;
UART_DEV(uart)->fifo_threshold = 16;
device_open(uart, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
bflb_platform_delay_ms(5);
device_set_callback(uart, uart_irq_callback);
device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
}
dma_register(DMA0_CH0_INDEX, "ch0");
struct device *dma_ch0 = device_find("ch0");
if (dma_ch0) {
DMA_DEV(dma_ch0)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch0)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch0)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch0)->dst_req = DMA_REQUEST_UART0_TX;
DMA_DEV(dma_ch0)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch0)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch0, 0);
device_control(uart, DEVICE_CTRL_ATTACH_TX_DMA, dma_ch0);
device_set_callback(dma_ch0, dma_ch0_irq_callback);
/* close dma irq */
//device_control(UART_DEV(uart)->tx_dma, DEVICE_CTRL_CLR_INT, NULL);
}
// dma_register(DMA0_CH1_INDEX, "ch1");
// struct device *dma_ch1 = device_find("ch1");
// if (dma_ch1) {
// DMA_DEV(dma_ch1)->direction = DMA_PERIPH_TO_MEMORY;
// DMA_DEV(dma_ch1)->transfer_mode = DMA_LLI_ONCE_MODE;
// DMA_DEV(dma_ch1)->src_req = DMA_REQUEST_UART0_RX;
// DMA_DEV(dma_ch1)->dst_req = DMA_REQUEST_NONE;
// DMA_DEV(dma_ch1)->src_width = DMA_TRANSFER_WIDTH_8BIT;
// DMA_DEV(dma_ch1)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
// device_open(dma_ch1, 0);
// device_control(uart, DEVICE_CTRL_ATTACH_RX_DMA, dma_ch1);
// device_set_callback(dma_ch1, dma_ch1_irq_callback);
// device_control(dma_ch1, DEVICE_CTRL_SET_INT, NULL);
// }
device_control(uart, DEVICE_CTRL_TX_DMA_SUSPEND, NULL);
isp_obj_uart = isp_obj;
return 0;
}

View File

@ -0,0 +1,104 @@
/**
* @file ips.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "bflb_platform.h"
//#include "drv_list.h"
typedef enum {
FILE_START = 0x50,
FILE_DATA = 0X51,
FILE_END = 0X52,
CMD_PLAY_START = 0X40,
CMD_PLAY_PAUSE = 0X41,
CMD_PLAY_STOP = 0X42,
CMD_VOLUME_INCREASE = 0x43,
CMD_VOLUME_DECREASE = 0x44,
CMD_VOLUME_SET = 0x45,
CMD_VOLUME_GET = 0x46,
CMD_SAMPLING_RATE = 0x47,
CMD_CHANNEL_NUM = 0X48,
CMD_RECORD_START = 0x49,
CMD_RECORD_STOP = 0x4A,
} isp_cmd_id_t;
typedef enum {
DATA_UVVV = 0X53,
DATA_VUVV = 0X54,
} isp_file_type_t;
typedef enum {
REPLY_SUCCES = 0x4B4Fu,
REPLY_ERROR = 0x4552u,
} ips_reply_t;
/* 内部状态类型 */
typedef enum {
NO_TASK = 0,
SEND_DATA = 1, /* 发数据中 */
RECEIVE_DATA, /* 接收数据中 */
SEND_WAIT_ACK, /* 发送后等待 ack */
RECEIVE_WAIT_ACK, /* 接收后对方在等待 ack */
OTHER_STATE, /*其他状态,一般是接收数据或命令的帧头过程中 */
} isp_state_mode_t;
typedef struct {
isp_state_mode_t isp_state_mode; /* 单帧状态 */
uint8_t already_steps; /* 状态机控制 */
uint16_t buff_length_max; /* buff 最大长度 */
ips_reply_t ips_reply; /* ack 状态 */
uint16_t receive_length; /* 已经接收数量 */
} isp_status_t;
/* 回调触发原因 */
typedef enum {
ISP_CALLBACK_SEND_SUCCES_ACK, /* 发送后收到正确的ACK */
ISP_CALLBACK_SEND_ERROR_ACK, /* 发送后收到错误的ACK */
ISP_CALLBACK_RECEIVE_ACK_WAIT, /* 数据已经收到,校验正确对方在等待ACK */
ISP_CALLBACK_RECEIVE_NACK_WAIT, /* 数据已经收到,校验错误对方在等待NACK */
ISP_CALLBACK_SEND_ACK_WAIT, /* 数据已经发出等待对面ACK */
ISP_CALLBACK_CMD_, /* 收到命令,对方在等待ACK */
} isp_callback_reason_t;
typedef struct __attribute__((packed)) isp_obj_struct {
isp_cmd_id_t cmd_id;
uint8_t check;
uint16_t length;
isp_file_type_t file_type;
uint8_t *file_data;
uint8_t auot_ack; /* 数据包自动回ack0自动非零不自动*/
uint32_t time_out;
isp_status_t status; /* 中间变量,用以状态机控制 */
void (*isp_callback)(struct isp_obj_struct *isp_obj, isp_callback_reason_t isp_callback_reason);
} isp_obj_t;
int isp_uart_send_data(isp_obj_t *isp_obj_uart);
uint8_t isp_uart_init(isp_obj_t *isp_obj);
int isp_uart_send_ack(isp_obj_t *isp_obj_uart, ips_reply_t ips_reply);

View File

@ -0,0 +1,238 @@
/**
* @file main.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_i2s.h"
#include "hal_dma.h"
#include "data_protocol.h"
#include "wav_play_from_isp.h"
audio_dev_t audio_test;
isp_obj_t isp_obj_uart;
struct device *uart_isp;
/**
* @brief isp Event callbacks, normally run in interrupts, do not block operations
*
* @param isp_obj
* @param isp_callback_reason
*/
void isp_uart_callback(isp_obj_t *isp_obj, isp_callback_reason_t isp_callback_reason)
{
int vol;
switch (isp_callback_reason) {
case ISP_CALLBACK_RECEIVE_ACK_WAIT:
/* receive data information */
if (isp_obj->cmd_id == 0x50) {
/* receive data information */
if (isp_obj->file_type == 0x59 && audio_test.audio_state)
audio_test.audio_state = 1;
isp_obj->auot_ack = 0; /* auto ack */
} else if (isp_obj->cmd_id == 0x51) {
if (audio_test.audio_state == 0) { /* Not allowed to play */
isp_obj->auot_ack = 0;
} else if (audio_test.audio_state < 4) { /* start play */
audio_test.buff_using = (isp_obj->file_data == audio_test.buff[0]) ? 1 : 0;
audio_test.buff_data_size[!audio_test.buff_using] = isp_obj->length;
/* Parsing file Information, Initialize the peripheral*/
if (audio_test.audio_state == 1) {
if (audio_test.audio_init(&audio_test, 0, isp_obj->file_data)) {
break;
}
}
audio_test.audio_control(&audio_test, AUDIO_CMD_PLAY_START, NULL);
isp_obj->file_data = audio_test.buff[!audio_test.buff_using];
audio_test.buff_data_size[!audio_test.buff_using] = 0;
isp_obj->auot_ack = 0;
} else if (audio_test.audio_state == 4) { /* play ing */
if (isp_obj->file_data == audio_test.buff[0])
audio_test.buff_data_size[0] = isp_obj->length;
else
audio_test.buff_data_size[1] = isp_obj->length;
/* not auto ack , send ack in audio callback */
isp_obj->auot_ack = 1;
}
}
// MSG("ISP_CALLBACK_RECEIVE_ACK_WAIT\r\n");
break;
case ISP_CALLBACK_RECEIVE_NACK_WAIT:
/* receive data err */
// MSG("ISP_CALLBACK_RECEIVE_NACK_WAIT\r\n");
isp_obj->auot_ack = 0; /* auto ack */
break;
case ISP_CALLBACK_SEND_ACK_WAIT:
/* receive data end,wait ack */
// MSG("ISP_CALLBACK_SEND_ACK_WAIT\r\n");
break;
case ISP_CALLBACK_SEND_SUCCES_ACK:
/* send ok,send file next data */
if (audio_test.audio_state == 11) {
/* Continue to the recording */
audio_test.audio_control(&audio_test, AUDIO_CMD_RECORD_START, NULL);
isp_obj_uart.file_data = audio_test.buff[!audio_test.buff_using];
isp_obj_uart.length = audio_test.buff_data_size[!audio_test.buff_using];
isp_uart_send_data(&isp_obj_uart);
audio_test.buff_data_size[!audio_test.buff_using] = 0;
audio_test.audio_state = 12;
}
// MSG("ISP_CALLBACK_SEND_SUCCES_ACK\r\n");
break;
case ISP_CALLBACK_SEND_ERROR_ACK:
/* send err,resend last data */
// MSG("ISP_CALLBACK_SEND_ERROR_ACK\r\n");
break;
case ISP_CALLBACK_CMD_:
// MSG("ISP_CALLBACK_CMD_\r\n");
switch (isp_obj->cmd_id) {
case CMD_PLAY_START: /* play */
if (audio_test.audio_state == 0)
audio_test.audio_state = 1;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_PLAY_PAUSE: /* pause */
// if (audio_test.audio_state == 3)
// audio_test.audio_state = 2;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_PLAY_STOP: /* stop */
if (audio_test.audio_state)
audio_test.audio_state = 0;
// device_close(i2s);
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_INCREASE: /* volume +1 */
vol = audio_test.audio_control(&audio_test, AUDIO_CMD_GET_VOLUME, NULL);
if (vol >= 100)
vol = 99;
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)(vol + 1));
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_DECREASE: /* volume -1 */
vol = audio_test.audio_control(&audio_test, AUDIO_CMD_GET_VOLUME, NULL);
if (vol <= 0)
vol = 1;
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)(vol - 1));
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_SET: /* volume set */
vol = isp_obj->file_type;
if (vol <= 0)
vol = 0;
else if (vol >= 100)
vol = 100;
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)vol);
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_VOLUME_GET: /* volume get */
vol = audio_test.audio_control(&audio_test, AUDIO_CMD_GET_VOLUME, NULL);
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, (vol << 8) & 0xFF00);
break;
case CMD_SAMPLING_RATE: /* sampling_rate */
audio_test.record_config->sampl_freq = isp_obj->file_type;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_CHANNEL_NUM: /* channel */
audio_test.record_config->channel_num = isp_obj->file_type;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
case CMD_RECORD_START: /* record */
if (audio_test.audio_state == 4 || /* play ing */
audio_test.audio_init(&audio_test, 1, isp_obj->file_data)) {
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_ERROR);
break;
}
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
audio_test.audio_state = 10;
audio_test.audio_control(&audio_test, AUDIO_CMD_RECORD_START, NULL);
break;
case CMD_RECORD_STOP: /* stop record */
audio_test.audio_control(&audio_test, AUDIO_CMD_PLAY_STOP, NULL);
audio_test.audio_state = 10;
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
default:
isp_obj->status.isp_state_mode = NO_TASK;
isp_uart_send_ack(isp_obj, REPLY_SUCCES);
break;
}
break;
default:
break;
}
}
int main(void)
{
/* Disable log output */
bflb_platform_print_set(1);
bflb_platform_init(0);
/* register audio fun*/
isp_wav_play_register(&audio_test);
audio_test.audio_control(&audio_test, AUDIO_CMD_SET_VOLUME, (void *)40);
/* init isp uart */
isp_uart_init(&isp_obj_uart);
isp_obj_uart.isp_callback = isp_uart_callback;
isp_obj_uart.file_data = audio_test.buff[!audio_test.buff_using];
while (1) {
bflb_platform_delay_ms(100);
/* code */
if (isp_obj_uart.status.isp_state_mode == NO_TASK) {
/* code */
}
}
}

View File

@ -0,0 +1,8 @@
**board/bl706_avb/pinmux_config.h** 中 **PINMUX_SELECT** 选择 **PINMUX_LVGL**
```bash
$ make APP=audiocube_firmware_for_sph0645 BOARD=bl706_avb
```

View File

@ -0,0 +1,478 @@
/**
* @file wav_play_form_sd_card.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
// #include "bsp_es8388.h"
#include "hal_i2s.h"
#include "hal_dma.h"
#include "data_protocol.h"
#include "wav_play_from_isp.h"
extern isp_obj_t isp_obj_uart;
static int wav_data_parser(uint8_t *buff, uint16_t max_size, wav_information_t *wav_information);
static uint32_t pcm_24bit_to_32bit(uint8_t *buff, uint32_t data_size);
static int isp_wav_play_init(struct audio_dev *audio_dev, uint8_t mode, uint8_t *buff);
static int isp_wav_play_control(struct audio_dev *audio_dev, AUDIO_CMD_t cmd, void *args);
static int isp_wav_play_callback(audio_dev_t *audio_dev);
uint8_t audio_buff[2][4 * 1024] __attribute__((section(".system_ram"), aligned(4)));
// static ES8388_Cfg_Type ES8388Cfg = {
// .work_mode = ES8388_CODEC_MDOE, /*!< ES8388 work mode */
// .role = ES8388_SLAVE, /*!< ES8388 role */
// .mic_input_mode = ES8388_DIFF_ENDED_MIC, /*!< ES8388 mic input mode */
// .mic_pga = ES8388_MIC_PGA_3DB, /*!< ES8388 mic PGA */
// .i2s_frame = ES8388_LEFT_JUSTIFY_FRAME, /*!< ES8388 I2S frame */
// .data_width = ES8388_DATA_LEN_16, /*!< ES8388 I2S dataWitdh */
// };
static wav_information_t Wav_Information;
static record_config_t record_config;
static audio_dev_t *p_Audio_Dev = NULL;
static void dma_ch2_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (p_Audio_Dev && p_Audio_Dev->audio_callback) {
p_Audio_Dev->audio_callback(p_Audio_Dev);
}
}
static void dma_ch3_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (p_Audio_Dev && p_Audio_Dev->audio_callback) {
p_Audio_Dev->audio_callback(p_Audio_Dev);
}
}
/* get File pointer from top of file*/
static int wav_data_parser(uint8_t *buff, uint16_t max_size, wav_information_t *wav_information)
{
uint32_t offset = 0;
uint32_t chunk_id;
if (buff == NULL)
return 1;
/* RIFF WAVE Chunk */
chunk_id = ((chunk_riff_t *)&buff[offset])->chunk_id;
if (chunk_id == 0x46464952) {
wav_information->chunk_riff_offset = offset;
wav_information->chunk_riff = *((chunk_riff_t *)&buff[offset]);
offset += sizeof(chunk_riff_t);
} else {
wav_information->chunk_riff_offset = -1;
return 1;
}
/* Format Chunk */
chunk_id = ((chunk_format_t *)&buff[offset])->chunk_id;
if (chunk_id == 0x20746D66 && offset < max_size) /* fmt */
{
wav_information->chunk_format_offset = offset;
wav_information->chunk_format = *((chunk_format_t *)&buff[offset]);
offset += ((chunk_format_t *)&buff[offset])->chunk_size + 8;
} else {
wav_information->chunk_format_offset = -1;
return 1;
}
/* Fact/list Chunk */
chunk_id = ((chunk_fact_t *)&buff[offset])->chunk_id;
if ((chunk_id == 0X74636166 || chunk_id == 0X5453494C) && offset < max_size) /*fact or list*/
{
wav_information->chunk_fact_offset = offset;
wav_information->chunk_fact = *((chunk_fact_t *)&buff[offset]);
offset += ((chunk_fact_t *)&buff[offset])->chunk_size + 8;
} else {
wav_information->chunk_fact_offset = -1;
}
/* Data Chunk */
chunk_id = ((chunk_data_t *)&buff[offset])->chunk_id;
if (chunk_id == 0X61746164 && offset < max_size) {
wav_information->chunk_data_offset = offset;
wav_information->chunk_data = *((chunk_data_t *)&buff[offset]);
} else {
wav_information->chunk_data_offset = -1;
return 1;
}
return 0;
}
static uint32_t pcm_24bit_to_32bit(uint8_t *buff, uint32_t data_size)
{
/* The buff size should be more than four thirds of the data_size */
for (uint16_t i = data_size / 3; i > 0; i--) {
buff[i * 4 - 1] = buff[i * 3 - 1];
buff[i * 4 - 2] = buff[i * 3 - 2];
buff[i * 4 - 3] = buff[i * 3 - 3];
buff[i * 4 - 4] = 0;
}
return data_size / 3 * 4;
}
static int isp_wav_play_init(struct audio_dev *audio_dev, uint8_t mode, uint8_t *buff)
{
int res;
struct device *dma_ch2 = device_find("i2s_ch2");
struct device *dma_ch3 = device_find("i2s_ch3");
audio_dev->device = device_find("I2S");
if (audio_dev->device) {
device_close(audio_dev->device);
} else {
i2s_register(I2S0_INDEX, "I2S");
audio_dev->device = device_find("I2S");
}
if (mode == 1) {
goto record_conf;
}
/* play config */
if (dma_ch2) {
device_close(dma_ch2);
} else {
dma_register(DMA0_CH2_INDEX, "i2s_ch2");
dma_ch2 = device_find("i2s_ch2");
}
/* Parse the WAV file */
res = wav_data_parser(buff, 1000, &Wav_Information);
if (!res) {
audio_dev->wav_information = &Wav_Information;
} else {
return 1;
}
if ((audio_dev->device) && dma_ch2) {
/* I2S Config */
I2S_DEV(audio_dev->device)->interface_mode = I2S_MODE_LEFT;
I2S_DEV(audio_dev->device)->sampl_freq_hz = audio_dev->wav_information->chunk_format.sample_rate;
I2S_DEV(audio_dev->device)->channel_num = audio_dev->wav_information->chunk_format.num_of_channels;
uint8_t pcm_w = audio_dev->wav_information->chunk_format.bits_per_sample / 8;
if (pcm_w <= 2) {
I2S_DEV(audio_dev->device)->frame_size = I2S_FRAME_LEN_16;
} else {
I2S_DEV(audio_dev->device)->frame_size = I2S_FRAME_LEN_32;
}
I2S_DEV(audio_dev->device)->data_size = I2S_DEV(audio_dev->device)->frame_size;
I2S_DEV(audio_dev->device)->fifo_threshold = 3;
res = device_open((audio_dev->device), DEVICE_OFLAG_DMA_TX);
/* ES8388 Config */
// switch (I2S_DEV(audio_dev->device)->data_size) {
// case I2S_FRAME_LEN_16:
// ES8388Cfg.data_width = ES8388_DATA_LEN_16;
// break;
// case I2S_FRAME_LEN_24:
// ES8388Cfg.data_width = ES8388_DATA_LEN_24;
// break;
// case I2S_FRAME_LEN_32:
// ES8388Cfg.data_width = ES8388_DATA_LEN_32;
// break;
// default:
// return 1;
// break;
// }
// ES8388_Init(&ES8388Cfg);
// ES8388_Set_Voice_Volume(50);
/* DMA Config */
DMA_DEV(dma_ch2)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch2)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch2)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch2)->dst_req = DMA_REQUEST_I2S_TX;
DMA_DEV(dma_ch2)->src_burst_size = DMA_BURST_4BYTE;
DMA_DEV(dma_ch2)->dst_burst_size = DMA_BURST_4BYTE;
switch (I2S_DEV(audio_dev->device)->data_size * I2S_DEV(audio_dev->device)->channel_num) {
case 1:
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
break;
case 2:
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_16BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_16BIT;
break;
default:
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_32BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_32BIT;
break;
}
device_open(dma_ch2, 0);
device_set_callback(dma_ch2, dma_ch2_irq_callback);
device_control(dma_ch2, DEVICE_CTRL_SET_INT, NULL);
device_control((audio_dev->device), DEVICE_CTRL_ATTACH_TX_DMA, (void *)dma_ch2);
/* Delete the information data*/
uint32_t data_size = audio_dev->buff_data_size[!audio_dev->buff_using];
data_size = data_size - audio_dev->wav_information->chunk_data_offset;
audio_dev->buff_data_size[!audio_dev->buff_using] = data_size;
uint8_t *p_dst = audio_dev->buff[!audio_dev->buff_using];
uint8_t *p_src = &(audio_dev->buff[!audio_dev->buff_using][audio_dev->wav_information->chunk_data_offset]);
memcpy(p_dst, p_src, data_size);
if (audio_dev->wav_information->chunk_format.bits_per_sample / 8 == 3) {
audio_dev->buff_data_size[!audio_dev->buff_using] = pcm_24bit_to_32bit(audio_dev->buff[!audio_dev->buff_using], data_size);
} else {
}
} else {
return 1;
}
return 0;
/* record mode config */
record_conf:
if (dma_ch3) {
device_close(dma_ch3);
} else {
dma_register(DMA0_CH3_INDEX, "i2s_ch3");
dma_ch3 = device_find("i2s_ch3");
}
if ((audio_dev->device) && dma_ch3) {
I2S_DEV(audio_dev->device)->iis_mode = I2S_MODE_MASTER;
I2S_DEV(audio_dev->device)->interface_mode = I2S_MODE_STD;
I2S_DEV(audio_dev->device)->channel_num = audio_dev->record_config->channel_num;
I2S_DEV(audio_dev->device)->data_size = audio_dev->record_config->data_size;
I2S_DEV(audio_dev->device)->fifo_threshold = 4;
switch (audio_dev->record_config->sampl_freq) {
case SAMPL_FREQ_8000:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 8000;
break;
case SAMPL_FREQ_16000:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 16000;
break;
case SAMPL_FREQ_44100:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 44100;
break;
case SAMPL_FREQ_48000:
I2S_DEV(audio_dev->device)->sampl_freq_hz = 48000;
break;
default:
break;
}
I2S_DEV(audio_dev->device)->frame_size = I2S_FRAME_LEN_32;
device_open(audio_dev->device, DEVICE_OFLAG_DMA_RX);
/* ES8388 Config */
// switch (I2S_DEV(audio_dev->device)->data_size) {
// case I2S_FRAME_LEN_16:
// ES8388Cfg.data_width = ES8388_DATA_LEN_16;
// break;
// case I2S_FRAME_LEN_24:
// ES8388Cfg.data_width = ES8388_DATA_LEN_24;
// break;
// case I2S_FRAME_LEN_32:
// ES8388Cfg.data_width = ES8388_DATA_LEN_32;
// break;
// default:
// return 1;
// break;
// }
// ES8388_Init(&ES8388Cfg);
/* DMA Config */
DMA_DEV(dma_ch3)->direction = DMA_PERIPH_TO_MEMORY;
DMA_DEV(dma_ch3)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch3)->src_req = DMA_REQUEST_I2S_RX;
DMA_DEV(dma_ch3)->dst_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch3)->src_burst_size = DMA_BURST_4BYTE;
DMA_DEV(dma_ch3)->dst_burst_size = DMA_BURST_4BYTE;
switch (I2S_DEV(audio_dev->device)->data_size * I2S_DEV(audio_dev->device)->channel_num) {
case 1:
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
break;
case 2:
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_16BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_16BIT;
break;
default:
DMA_DEV(dma_ch3)->src_width = DMA_TRANSFER_WIDTH_32BIT;
DMA_DEV(dma_ch3)->dst_width = DMA_TRANSFER_WIDTH_32BIT;
break;
}
device_open(dma_ch3, 0);
device_set_callback(dma_ch3, dma_ch3_irq_callback);
device_control(dma_ch3, DEVICE_CTRL_SET_INT, NULL);
device_control((audio_dev->device), DEVICE_CTRL_ATTACH_RX_DMA, (void *)dma_ch3);
}
return 0;
}
static int isp_wav_play_control(struct audio_dev *audio_dev, AUDIO_CMD_t cmd, void *args)
{
static uint32_t volume = 50;
int res = -1;
switch (cmd) {
case AUDIO_CMD_PLAY_START:
if (audio_dev->audio_state) {
audio_dev->buff_using = !audio_dev->buff_using;
res = device_write(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_data_size[audio_dev->buff_using]);
audio_dev->audio_state = 4;
res = 0;
}
break;
case AUDIO_CMD_PLAY_STOP:
if (audio_dev->audio_state) {
audio_dev->audio_state = 1;
res = 0;
}
break;
case AUDIO_CMD_RECORD_START:
if (audio_dev->audio_state >= 10) {
audio_dev->buff_using = !audio_dev->buff_using;
res = device_read(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_size_max);
audio_dev->audio_state = 12;
}
break;
case AUDIO_CMD_RECORD_STOP:
if (audio_dev->audio_state > 10) {
audio_dev->audio_state = 10;
res = 0;
}
break;
case AUDIO_CMD_SET_VOLUME:
if (audio_dev->audio_state) {
// res = ES8388_Set_Voice_Volume((uint32_t)args);
res = 0;
volume = (uint32_t)args;
}
break;
case AUDIO_CMD_GET_VOLUME:
if (audio_dev->audio_state) {
res = (int)volume;
}
break;
default:
break;
}
return res;
}
static int isp_wav_play_callback(audio_dev_t *audio_dev)
{
if (audio_dev->audio_state < 10) { /* play*/
if (audio_dev->buff_data_size[!audio_dev->buff_using] > 0 && isp_obj_uart.status.isp_state_mode == RECEIVE_WAIT_ACK) {
/* data ready, switch buff */
audio_dev->buff_using = !audio_dev->buff_using;
device_write(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_data_size[audio_dev->buff_using]);
audio_dev->buff_data_size[audio_dev->buff_using] = 0;
audio_dev->buff_data_size[!audio_dev->buff_using] = isp_obj_uart.length;
isp_obj_uart.file_data = audio_dev->buff[!audio_dev->buff_using];
isp_obj_uart.status.isp_state_mode = NO_TASK;
isp_uart_send_ack(&isp_obj_uart, REPLY_SUCCES);
} else {
/* Data not ready, wait data receive*/
audio_dev->audio_state = 3;
}
} else { /* record */
audio_dev->buff_data_size[audio_dev->buff_using] = audio_dev->buff_size_max;
if (audio_dev->audio_state == 12) {
if (isp_obj_uart.status.isp_state_mode == NO_TASK) {
/* Continue to the recording */
audio_dev->buff_using = !audio_dev->buff_using;
device_read(audio_dev->device, 0, audio_dev->buff[audio_dev->buff_using], audio_dev->buff_size_max);
/* send data to PC */
isp_obj_uart.file_data = audio_dev->buff[!audio_dev->buff_using];
isp_obj_uart.length = audio_dev->buff_data_size[!audio_dev->buff_using];
isp_obj_uart.cmd_id = FILE_DATA;
isp_obj_uart.file_type = 0x58;
isp_uart_send_data(&isp_obj_uart);
audio_dev->buff_data_size[!audio_dev->buff_using] = 0;
} else {
/* Data not ready, wait data transmit*/
audio_dev->audio_state = 11;
}
}
}
return 0;
}
int isp_wav_play_register(audio_dev_t *audio_dev)
{
p_Audio_Dev = audio_dev;
audio_dev->audio_init = isp_wav_play_init,
audio_dev->audio_control = isp_wav_play_control,
audio_dev->audio_callback = isp_wav_play_callback,
audio_dev->buff[0] = audio_buff[0];
audio_dev->buff[1] = audio_buff[1];
audio_dev->buff_data_size[0] = 0;
audio_dev->buff_data_size[1] = 0;
audio_dev->audio_state = 0;
audio_dev->buff_size_max = sizeof(audio_buff) / 2;
record_config.data_size = 2;
record_config.channel_num = 1;
record_config.sampl_freq = SAMPL_FREQ_16000;
audio_dev->record_config = &record_config;
return 0;
}

View File

@ -0,0 +1,132 @@
/**
* @file wav_play_form_sd_card.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef __MAV_PLAY_H__
#define __MAV_PLAY_H__
#include "hal_i2s.h"
//WAV文件块定义
/* RIFF (RIFF WAVE Chunk) */
typedef struct __attribute__((packed)) {
uint32_t chunk_id; /*chunk id:"RIFF",(0X46464952) */
uint32_t chunk_size; /*file size -8 */
uint32_t format; /* "WAVE" (0X45564157) */
} chunk_riff_t;
/* fmt (Format Chunk)*/
typedef struct __attribute__((packed)) {
uint32_t chunk_id; /* chunk id:"fmt",(0X20746D66) */
uint32_t chunk_size; /* fmt size -8 = 20*/
uint16_t audio_format; /* 音频格式;0X10,表示线性 PCM; 0X11 表示 IMA ADPCM */
uint16_t num_of_channels; /* 通道数量;1,表示单声道;2,表示双声道*/
uint32_t sample_rate; /* 采样率;0X1F40,表示 8Khz */
uint32_t byte_rate; /* 字节速率 */
uint16_t block_align; /*块对齐(字节)*/
uint16_t bits_per_sample; /*单个采样数据大小;4 位 ADPCM,设置为 4*/
} chunk_format_t;
//fact (Fact Chunk)
typedef struct __attribute__((packed)) {
uint32_t chunk_id; //chunk id;这里固定为"fact",即 0X74636166;
uint32_t chunk_size; //子集合大小(不包括 ID 和 Size);这里为:4.
uint32_t data_fact_size; //数据转换为 PCM 格式后的大小
} chunk_fact_t;
//data (Data Chunk)
typedef struct __attribute__((packed)) {
uint32_t chunk_id; //chunk id;这里固定为"data",即 0X61746164
uint32_t chunk_size; //子集合大小(不包括 ID 和 Size);文件大小-60.
} chunk_data_t;
//
typedef enum {
CHUNK_RIFF,
CHUNK_FORMAT,
CHUNK_FACT,
CHUNK_DATA,
} mav_chunk_t;
//.wav information
typedef struct
{
int chunk_riff_offset; //在数据里的位置偏移,-1表示没有此块
chunk_riff_t chunk_riff;
int chunk_format_offset;
chunk_format_t chunk_format;
int chunk_fact_offset;
chunk_fact_t chunk_fact;
int chunk_data_offset;
chunk_data_t chunk_data;
} wav_information_t;
typedef enum {
AUDIO_CMD_PLAY_START,
AUDIO_CMD_PLAY_STOP,
AUDIO_CMD_RECORD_START,
AUDIO_CMD_RECORD_STOP,
AUDIO_CMD_GET_VOLUME,
AUDIO_CMD_SET_VOLUME,
} AUDIO_CMD_t;
/* 频率索引*/
typedef enum {
SAMPL_FREQ_8000 = 0,
SAMPL_FREQ_16000 = 1,
SAMPL_FREQ_44100 = 2,
SAMPL_FREQ_48000 = 3,
} sampl_freq_t;
/* 录音设置参数 */
typedef struct
{
uint16_t data_size;
uint16_t channel_num;
sampl_freq_t sampl_freq;
} record_config_t;
/* 播放控制块 */
typedef struct audio_dev {
uint8_t *buff[2];
uint32_t buff_data_size[2]; //buff内数据长度
uint32_t buff_size_max; //buff的大小
uint8_t buff_using; //正在使用的buff
uint8_t audio_state; //状态 0:stop 1:暂停中,如果要播放,需要重新解析wav信息头 2:暂停中,可以接着播放(不用重新解析wav信息) 3:播放中,但在等待数据(数据不及时) 4:正常播放中,数据正常
// 11:录音模式(数据堆积,未及时发送完,在等待上位机ACK) 12录音模式(正常,数据及时发送)
uint8_t audio_type; //类型
int (*audio_init)(struct audio_dev *audio_dev, uint8_t mode, uint8_t *buff); //初始化函数播放需要传入wav文件头地址
int (*audio_control)(struct audio_dev *audio_dev, AUDIO_CMD_t cmd, void *args);
int (*audio_callback)(struct audio_dev *audio_dev); //中断回调函数用来重新装载buff
struct device *device; //i2s的device可以考虑换成指向其他外设
wav_information_t *wav_information; //播放wav信息结构体
record_config_t *record_config; //录音配置结构体
} audio_dev_t;
int isp_wav_play_register(audio_dev_t *audio_dev);
#endif