From 67bf5cea1f111dee750f1e7471611b9a688ce668 Mon Sep 17 00:00:00 2001 From: greedyhao Date: Sat, 19 Dec 2020 10:45:03 +0800 Subject: [PATCH] [bluetrum] add sound and romfs support --- bsp/bluetrum/ab32vg1-ab-prougen/.config | 32 +- bsp/bluetrum/ab32vg1-ab-prougen/README.md | 4 +- .../ab32vg1-ab-prougen/applications/mnt.c | 21 + .../ab32vg1-ab-prougen/applications/romfs.c | 17 + bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig | 19 +- .../ab32vg1-ab-prougen/board/SConscript | 3 + .../board/ports/audio/drv_sound.c | 485 ++++++++++++++++++ bsp/bluetrum/ab32vg1-ab-prougen/download.xm | Bin 0 -> 18 bytes bsp/bluetrum/ab32vg1-ab-prougen/link.lds | 31 +- bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h | 18 +- bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.py | 1 + bsp/bluetrum/libcpu/cpu/interrupt.c | 21 +- bsp/bluetrum/libcpu/cpu/interrupt.h | 7 + .../libraries/hal_drivers/drv_usart.c | 10 +- .../ab32vg1_hal/source/ab32vg1_hal.c | 2 - .../hal_libraries/bmsis/include/ab32vg1.h | 23 + .../hal_libraries/bmsis/source/startup.S | 37 ++ 17 files changed, 692 insertions(+), 39 deletions(-) create mode 100644 bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c create mode 100644 bsp/bluetrum/ab32vg1-ab-prougen/applications/romfs.c create mode 100644 bsp/bluetrum/ab32vg1-ab-prougen/board/ports/audio/drv_sound.c create mode 100644 bsp/bluetrum/ab32vg1-ab-prougen/download.xm create mode 100644 bsp/bluetrum/libcpu/cpu/interrupt.h diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/.config b/bsp/bluetrum/ab32vg1-ab-prougen/.config index b0ea6b0b1d..ae0ddcec8b 100644 --- a/bsp/bluetrum/ab32vg1-ab-prougen/.config +++ b/bsp/bluetrum/ab32vg1-ab-prougen/.config @@ -19,10 +19,10 @@ CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=1024 +CONFIG_IDLE_THREAD_STACK_SIZE=512 CONFIG_RT_USING_TIMER_SOFT=y CONFIG_RT_TIMER_THREAD_PRIO=4 -CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=256 CONFIG_RT_DEBUG=y # CONFIG_RT_DEBUG_COLOR is not set # CONFIG_RT_DEBUG_INIT_CONFIG is not set @@ -96,7 +96,7 @@ CONFIG_FINSH_USING_SYMTAB=y CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set CONFIG_FINSH_THREAD_PRIORITY=20 -CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_THREAD_STACK_SIZE=2048 CONFIG_FINSH_CMD_SIZE=80 # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_USING_MSH=y @@ -107,7 +107,18 @@ CONFIG_FINSH_ARG_MAX=10 # # Device virtual file system # -# CONFIG_RT_USING_DFS is not set +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=2 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=2 +CONFIG_DFS_FD_MAX=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +# CONFIG_RT_USING_DFS_DEVFS is not set +CONFIG_RT_USING_DFS_ROMFS=y +# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_UFFS is not set +# CONFIG_RT_USING_DFS_JFFS2 is not set # # Device Drivers @@ -134,7 +145,10 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_SDIO is not set # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set -# CONFIG_RT_USING_AUDIO is not set +CONFIG_RT_USING_AUDIO=y +CONFIG_RT_AUDIO_REPLAY_MP_BLOCK_SIZE=1024 +CONFIG_RT_AUDIO_REPLAY_MP_BLOCK_COUNT=2 +CONFIG_RT_AUDIO_RECORD_PIPE_SIZE=512 # CONFIG_RT_USING_SENSOR is not set # CONFIG_RT_USING_TOUCH is not set # CONFIG_RT_USING_HWCRYPTO is not set @@ -153,6 +167,7 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_LIBC=y # CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_POSIX is not set # CONFIG_RT_USING_MODULE is not set # @@ -325,6 +340,8 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_UMCN is not set # CONFIG_PKG_USING_LWRB2RTT is not set # CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set # # system packages @@ -419,6 +436,7 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_SSD1306 is not set # CONFIG_PKG_USING_QKEY is not set # CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_NES is not set # # miscellaneous packages @@ -430,8 +448,6 @@ CONFIG_RT_USING_LIBC=y # CONFIG_PKG_USING_QUICKLZ is not set # CONFIG_PKG_USING_LZMA is not set # CONFIG_PKG_USING_MULTIBUTTON is not set -# CONFIG_PKG_USING_MULTIBUTTON_V102 is not set -# CONFIG_PKG_USING_MULTIBUTTON_LATEST_VERSION is not set # CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set # CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_ZLIB is not set @@ -484,6 +500,8 @@ CONFIG_BSP_USING_USB_TO_USART=y # On-chip Peripheral Drivers # CONFIG_BSP_USING_UART0=y +CONFIG_BSP_USING_AUDIO=y +CONFIG_BSP_USING_AUDIO_PLAY=y # # Board extended module Drivers diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/README.md b/bsp/bluetrum/ab32vg1-ab-prougen/README.md index 49b13893f3..df58a01eda 100644 --- a/bsp/bluetrum/ab32vg1-ab-prougen/README.md +++ b/bsp/bluetrum/ab32vg1-ab-prougen/README.md @@ -102,7 +102,9 @@ msh > ## 注意事项 -波特率默认为 1.5M,需要使用 [Downloader](https://github.com/BLUETRUM/Downloader) 下载 `.dcf` 到芯片 +波特率默认为 1.5M,需要使用 [Downloader](https://github.com/BLUETRUM/Downloader) 下载 `.dcf` 到芯片,需要编译后自动下载,需要在 `Downloader` 中的下载的下拉窗中选择 `自动`;目前暂时屏蔽 uart1 打印 + +使用 `romfs` 时,需要自己生成 `romfs.c` 进行替换,操作参考[使用 RomFS](https://www.rt-thread.org/document/site/tutorial/qemu-network/filesystems/filesystems/#romfs) 编译报错的时候,如果出现重复定义的报错,可能需要在 `cconfig.h` 中手动添加以下配置 diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c b/bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c new file mode 100644 index 0000000000..005a86b41a --- /dev/null +++ b/bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c @@ -0,0 +1,21 @@ +#include + +#ifdef RT_USING_DFS +#include +#include "dfs_romfs.h" + +int mnt_init(void) +{ + if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) == 0) + { + rt_kprintf("ROM file system initializated!\n"); + } + else + { + rt_kprintf("ROM file system initializate failed!\n"); + } + + return 0; +} +INIT_ENV_EXPORT(mnt_init); +#endif diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/applications/romfs.c b/bsp/bluetrum/ab32vg1-ab-prougen/applications/romfs.c new file mode 100644 index 0000000000..42670bf6b3 --- /dev/null +++ b/bsp/bluetrum/ab32vg1-ab-prougen/applications/romfs.c @@ -0,0 +1,17 @@ +/* Generated by mkromfs. Edit with caution. */ +#include + +#ifdef RT_USING_DFS +#include + + + +static const struct romfs_dirent _romfs_root[] = { + {ROMFS_DIRENT_FILE, "ab32vg1", RT_NULL, 0} +}; + +const struct romfs_dirent romfs_root = { + ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_romfs_root, sizeof(_romfs_root)/sizeof(_romfs_root[0]) +}; + +#endif diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig b/bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig index 5d8b548f71..43dc3e8229 100644 --- a/bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig +++ b/bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig @@ -8,14 +8,25 @@ menu "Onboard Peripheral Drivers" select BSP_USING_UART0 default y + menuconfig BSP_USING_AUDIO + bool "Enable Audio Device" + select RT_USING_AUDIO + default n + + if BSP_USING_AUDIO + config BSP_USING_AUDIO_PLAY + bool "Enable Audio Play" + default y + endif + endmenu menu "On-chip Peripheral Drivers" -menuconfig BSP_USING_UART0 - bool "Enable UART0" - select RT_USING_SERIAL - default y + menuconfig BSP_USING_UART0 + bool "Enable UART0" + select RT_USING_SERIAL + default y endmenu diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/board/SConscript b/bsp/bluetrum/ab32vg1-ab-prougen/board/SConscript index 22d32eade7..d8696ae2da 100644 --- a/bsp/bluetrum/ab32vg1-ab-prougen/board/SConscript +++ b/bsp/bluetrum/ab32vg1-ab-prougen/board/SConscript @@ -9,6 +9,9 @@ ab32vg1_hal_msp.c ''') CPPPATH = [cwd] +if GetDepend(['RT_USING_AUDIO']): + src += Glob('ports/audio/drv_sound.c') + group = DefineGroup('Board', src, depend = [''], CPPPATH = CPPPATH) objs = [group] diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/board/ports/audio/drv_sound.c b/bsp/bluetrum/ab32vg1-ab-prougen/board/ports/audio/drv_sound.c new file mode 100644 index 0000000000..5f11f48f91 --- /dev/null +++ b/bsp/bluetrum/ab32vg1-ab-prougen/board/ports/audio/drv_sound.c @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2020-2020, Bluetrum Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2020-12-12 greedyhao first implementation + */ + +#include + +#define DBG_TAG "drv.snd_dev" +#define DBG_LVL DBG_INFO +#include + +#define SAI_AUDIO_FREQUENCY_44K ((uint32_t)44100u) +#define SAI_AUDIO_FREQUENCY_48K ((uint32_t)48000u) +#define TX_FIFO_SIZE (1024) + +struct sound_device +{ + struct rt_audio_device audio; + struct rt_audio_configure replay_config; + rt_uint8_t *tx_fifo; + rt_uint8_t *rx_fifo; + rt_uint8_t volume; +}; + +static struct sound_device snd_dev = {0}; + +//apll = 采样率*ADPLL_DIV*512 +//audio pll init +void adpll_init(uint8_t out_spr) +{ + PLL1CON &= ~(BIT(16) | BIT(17)); //PLL1 refclk select xosc26m + CLKCON2 &= ~(BIT(4)| BIT(5) | BIT(6) | BIT(7)); + + PLL1CON &= ~(BIT(3) | BIT(4) | BIT(5)); + PLL1CON |= BIT(3); //Select PLL/VCO frequency band (PLL大于206M vcos = 0x01, 否则为0) + + PLL1CON |= BIT(12); //enable pll1 ldo + hal_mdelay(1); + PLL1CON |= BIT(18); //pll1 sdm enable + + if (out_spr) { + CLKCON2 |= BIT(4) | BIT(7); //adpll_div = 10 + PLL1DIV = (245.76 * 65536) / 26; //245.76Mhz for 48K + // sys.aupll_type = 1; + } else { + CLKCON2 |= BIT(5) | BIT(7); //adpll_div = 11 + PLL1DIV = (248.3712 * 65536) / 26; //248.3712MHz for 44.1k + // sys.aupll_type = 0; + } + hal_mdelay(1); + PLL1CON |= BIT(20); //update pll1div + PLL1CON |= BIT(6); //enable analog pll1 + hal_mdelay(1); //wait pll1 stable +} + +void dac_start(void) +{ + AUANGCON0 |= BIT(0) | BIT(1) | BIT(3); // bg ldoh bias enable + + AUANGCON0 &= ~(BIT(6)|BIT(5)|BIT(4)); // LDOH voltage select:3bit + AUANGCON0 |= (3<<4); // 2.4/2.5/2.7/2.9/3.1/3.2 + + AUANGCON0 |= BIT(2); // LDOL enable + + AUANGCON0 |= BIT(9); //VCM enable + AUANGCON0 &= ~(BIT(13)|BIT(12)); // VCM voltage select, 2bit + AUANGCON0 |= (2<<12); + + AUANGCON0 |= BIT(15) | BIT(16) | BIT(17) | BIT(18); // d2a lpf audpa audpa_dly + + AUANGCON0 &= ~BIT(11); //VCM type: 0-->res divider with off-chip cap; 1-->internal VCM + //AUANGCON0 |= BIT(11); + + AUANGCON0 &= ~BIT(19); // dac type: 0-->SC; 1-->SR + //AUANGCON0 |= BIT(19); + + AUANGCON0 |= BIT(20); // pa type: 0-->diff; 1-->3.3V single + + AUANGCON3 &= ~(0x7<<4); //BIT[6:4]=PA_GF[2:0] + AUANGCON3 |= (0<<4); + AUANGCON3 &= ~(0xf); //BIT[3:0]=PA_GX[3:0] + AUANGCON3 |= 0; + + AUANGCON3 &= ~(0xF<<8); //BIT[11:8]=PA2_GX[3:0] + AUANGCON3 |= (0<<8); + AUANGCON3 &= ~(0x7<<12); //BIT[14:12]=PA2_GF[2:0] + AUANGCON3 |= (0<<12); + + AUANGCON1 |= BIT(0) | BIT(1); // dac enable: BIT(0)-->right channel; BIT(1)-->left channel + //AUANGCON1 &= ~BIT(1); //disable left channel + + AUANGCON1 |= BIT(12); // lpf2pa enable + + AUANGCON1 &= ~BIT(29); // vcmbuf enable: 0-->disable + //AUANGCON1 |= BIT(29); + + //AUANGCON1 |= BIT(30); // mirror enable + + //AUANGCON2 |= BIT(29) | BIT(30); // adc mute + + //AUANGCON1 |= BIT(3); // pa mute +} + +void saia_frequency_set(uint32_t frequency) +{ + if (frequency == SAI_AUDIO_FREQUENCY_48K) { + DACDIGCON0 |= BIT(1); + DACDIGCON0 &= ~(0xf << 2); + DACDIGCON0 |= BIT(6); + } else if (frequency == SAI_AUDIO_FREQUENCY_44K) { + DACDIGCON0 &= ~BIT(1); + DACDIGCON0 &= ~(0xf << 2); + DACDIGCON0 |= BIT(1); + DACDIGCON0 |= BIT(6); + } +} + +void saia_channels_set(uint8_t channels) +{ + LOG_D("saia_channels_set=%d", channels); + if (channels == 1) { + AU0LMIXCOEF = 0x00007FFF; + AU1LMIXCOEF = 0x00007FFF; + DACDIGCON0 |= BIT(7); + DACDIGCON0 |= BIT(8); + AUANGCON1 &= ~BIT(0); + } else { + AUANGCON1 |= BIT(0); + DACDIGCON0 &= ~BIT(7); + DACDIGCON0 &= ~BIT(8); + } +} + +void saia_volume_set(rt_uint8_t volume) +{ + if (volume > 100) + volume = 100; + + uint32_t dvol = volume * 327; // max is 0x7ffff + LOG_D("dvol=0x%x", dvol); + DACVOLCON = dvol | (0x02 << 16); // dac fade in +} + +uint8_t saia_volume_get(void) +{ + return ((DACVOLCON & 0xffff) / 327); +} + +static rt_err_t sound_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps) +{ + rt_err_t result = RT_EOK; + struct sound_device *snd_dev = RT_NULL; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + switch (caps->main_type) + { + case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */ + { + switch (caps->sub_type) + { + case AUDIO_TYPE_QUERY: + caps->udata.mask = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_MIXER; + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_OUTPUT: /* Provide capabilities of OUTPUT unit */ + { + switch (caps->sub_type) + { + case AUDIO_DSP_PARAM: + caps->udata.config.samplerate = snd_dev->replay_config.samplerate; + caps->udata.config.channels = snd_dev->replay_config.channels; + caps->udata.config.samplebits = snd_dev->replay_config.samplebits; + break; + + case AUDIO_DSP_SAMPLERATE: + caps->udata.config.samplerate = snd_dev->replay_config.samplerate; + break; + + case AUDIO_DSP_CHANNELS: + caps->udata.config.channels = snd_dev->replay_config.channels; + break; + + case AUDIO_DSP_SAMPLEBITS: + caps->udata.config.samplebits = snd_dev->replay_config.samplebits; + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_MIXER: /* report the Mixer Units */ + { + switch (caps->sub_type) + { + case AUDIO_MIXER_QUERY: + caps->udata.mask = AUDIO_MIXER_VOLUME; + break; + + case AUDIO_MIXER_VOLUME: + caps->udata.value = saia_volume_get(); + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + default: + result = -RT_ERROR; + break; + } + + return RT_EOK; +} + +static rt_err_t sound_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps) +{ + rt_err_t result = RT_EOK; + struct sound_device *snd_dev = RT_NULL; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + switch (caps->main_type) + { + case AUDIO_TYPE_MIXER: + { + switch (caps->sub_type) + { + case AUDIO_MIXER_VOLUME: + { + rt_uint8_t volume = caps->udata.value; + + saia_volume_set(volume); + snd_dev->volume = volume; + LOG_D("set volume %d", volume); + break; + } + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_OUTPUT: + { + switch (caps->sub_type) + { + case AUDIO_DSP_PARAM: + { + /* set samplerate */ + saia_frequency_set(caps->udata.config.samplerate); + /* set channels */ + saia_channels_set(caps->udata.config.channels); + + /* save configs */ + snd_dev->replay_config.samplerate = caps->udata.config.samplerate; + snd_dev->replay_config.channels = caps->udata.config.channels; + snd_dev->replay_config.samplebits = caps->udata.config.samplebits; + LOG_D("set samplerate %d", snd_dev->replay_config.samplerate); + break; + } + + case AUDIO_DSP_SAMPLERATE: + { + saia_frequency_set(caps->udata.config.samplerate); + snd_dev->replay_config.samplerate = caps->udata.config.samplerate; + LOG_D("set samplerate %d", snd_dev->replay_config.samplerate); + break; + } + + case AUDIO_DSP_CHANNELS: + { + saia_channels_set(caps->udata.config.channels); + snd_dev->replay_config.channels = caps->udata.config.channels; + LOG_D("set channels %d", snd_dev->replay_config.channels); + break; + } + + case AUDIO_DSP_SAMPLEBITS: + { + /* not support */ + snd_dev->replay_config.samplebits = caps->udata.config.samplebits; + break; + } + + default: + result = -RT_ERROR; + break; + } + + break; + } + + default: + break; + } + + return RT_EOK; +} + +static rt_err_t sound_init(struct rt_audio_device *audio) +{ + struct sound_device *snd_dev = RT_NULL; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + adpll_init(0); + dac_start(); + + /* set default params */ + saia_frequency_set(snd_dev->replay_config.samplerate); + saia_channels_set(snd_dev->replay_config.channels); + + return RT_EOK; +} + +static rt_err_t sound_start(struct rt_audio_device *audio, int stream) +{ + struct sound_device *snd_dev = RT_NULL; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + if (stream == AUDIO_STREAM_REPLAY) + { + LOG_D("open sound device"); + + AUBUFSIZE = (TX_FIFO_SIZE / 4 - 1); + AUBUFSIZE |= (TX_FIFO_SIZE / 8) << 16; + AUBUFSTARTADDR = DMA_ADR(snd_dev->rx_fifo); + + DACDIGCON0 = BIT(0) | BIT(10); // (0x01<<2) + DACVOLCON = 0x7fff; // -60DB + DACVOLCON |= BIT(20); + + AUBUFCON |= BIT(1) | BIT(4); + } + + return RT_EOK; +} + +static rt_err_t sound_stop(struct rt_audio_device *audio, int stream) +{ + struct sound_device *snd_dev = RT_NULL; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + if (stream == AUDIO_STREAM_REPLAY) + { + AUBUFCON &= ~BIT(4); + LOG_D("close sound device"); + } + + return RT_EOK; +} + +rt_size_t sound_transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size) +{ + struct sound_device *snd_dev = RT_NULL; + rt_size_t tmp_size = size / 4; + rt_size_t count = 0; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + while (tmp_size-- > 0) { + while(AUBUFCON & BIT(8)); // aubuf full + AUBUFDATA = ((const uint32_t *)writeBuf)[count++]; + } + + return size; +} + +static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info) +{ + struct sound_device *snd_dev = RT_NULL; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + /** + * TX_FIFO + * +----------------+----------------+ + * | block1 | block2 | + * +----------------+----------------+ + * \ block_size / + */ + info->buffer = snd_dev->tx_fifo; + info->total_size = TX_FIFO_SIZE; + info->block_size = TX_FIFO_SIZE / 2; + info->block_count = 2; +} + +static struct rt_audio_ops ops = +{ + .getcaps = sound_getcaps, + .configure = sound_configure, + .init = sound_init, + .start = sound_start, + .stop = sound_stop, + .transmit = sound_transmit, + .buffer_info = sound_buffer_info, +}; + +void audio_isr(int vector, void *param) +{ + rt_interrupt_enter(); + + //Audio buffer pend + if (AUBUFCON & BIT(5)) { + AUBUFCON |= BIT(1); //Audio Buffer Pend Clear + rt_audio_tx_complete(&snd_dev.audio); + } + rt_interrupt_leave(); +} + +static int rt_hw_sound_init(void) +{ + rt_uint8_t *tx_fifo = RT_NULL; + rt_uint8_t *rx_fifo = RT_NULL; + + /* 分配 DMA 搬运 buffer */ + tx_fifo = rt_calloc(1, TX_FIFO_SIZE); + if(tx_fifo == RT_NULL) + { + return -RT_ENOMEM; + } + + rt_memset(tx_fifo, 0, TX_FIFO_SIZE); + snd_dev.tx_fifo = tx_fifo; + + /* 分配 DMA 搬运 buffer */ + rx_fifo = rt_calloc(1, TX_FIFO_SIZE); + if(rx_fifo == RT_NULL) + { + return -RT_ENOMEM; + } + + rt_memset(rx_fifo, 0, TX_FIFO_SIZE); + snd_dev.rx_fifo = rx_fifo; + + /* init default configuration */ + { + snd_dev.replay_config.samplerate = 48000; + snd_dev.replay_config.channels = 2; + snd_dev.replay_config.samplebits = 16; + snd_dev.volume = 55; + } + + /* register snd_dev device */ + snd_dev.audio.ops = &ops; + rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev); + + rt_hw_interrupt_install(IRQ_AUBUF0_1_VECTOR, audio_isr, RT_NULL, "au_isr"); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_sound_init); diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/download.xm b/bsp/bluetrum/ab32vg1-ab-prougen/download.xm new file mode 100644 index 0000000000000000000000000000000000000000..c4ff90c582d8a83bee33b20a669d6679cfd81a7a GIT binary patch literal 18 YcmezWFNGnWp`0O)AqPk&GNdp706|s-RsaA1 literal 0 HcmV?d00001 diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/link.lds b/bsp/bluetrum/ab32vg1-ab-prougen/link.lds index 84b359925f..5545374c9d 100644 --- a/bsp/bluetrum/ab32vg1-ab-prougen/link.lds +++ b/bsp/bluetrum/ab32vg1-ab-prougen/link.lds @@ -1,12 +1,16 @@ /* Define the flash max size */ __max_flash_size = 768k; -__comm_ram_size = 104k; -__heap_ram_size = 14k; +__data_ram_size = 5k; +__stack_ram_size = 4k; +__comm_ram_size = 86k; +__heap_ram_size = 29k; __base = 0x10000000; -__comm_vma = 0x12800; +__data_vma = 0x11000; +__stack_vma = __data_vma + __data_ram_size; +__comm_vma = __stack_vma + __stack_ram_size; __heap_vma = __comm_vma + __comm_ram_size; __ram1_vma = 0x50000; @@ -17,8 +21,8 @@ MEMORY flash(rx) : org = __base + 512, len = __max_flash_size comm(rx) : org = __comm_vma, len = __comm_ram_size - data : org = 0x11000, len = 5k - stack : org = 0x12400, len = 1k + data : org = __data_vma, len = __data_ram_size + stack : org = __stack_vma, len = __stack_ram_size heap : org = __heap_vma, len = __heap_ram_size ram1(rx) : org = __ram1_vma, len = 0x7a00 } @@ -30,11 +34,10 @@ SECTIONS } > init .ram1 __ram1_vma : { - /*board\\ports\\*.o(.text*)*/ - *hal_drivers\\*.o(.text*) - *hal_libraries\\ab32vg1_hal\\*.o(.text*) - *components\\drivers\\*.o(.text* .rodata*) - *components\\libc\\*.o(.text*) + *hal_drivers**.o(.text*) + *hal_libraries*ab32vg1_hal**.o(.text*) + *components*drivers**.o(.text* .rodata*) + *components*libc**.o(.text*) *ab32vg1_hal_msp.o(.text*) *components.o(.text* .rodata*) *ipc.o(.text* .rodata*) @@ -63,8 +66,8 @@ SECTIONS .comm : { KEEP(*(.vector)) - *(.text*) - *(.rodata*) + EXCLUDE_FILE (*romfs.o *lib_a**.o) *(.text*) + EXCLUDE_FILE (*romfs.o *lib_a**.o) *(.rodata*) *(.srodata*) *(.rela*) *(.data*) @@ -73,6 +76,8 @@ SECTIONS } > comm AT > flash .flash : { + *romfs.o *(.text* .rodata*) + *lib_a**.o *(.text* .rodata*) . = ALIGN(512); } > flash @@ -89,7 +94,7 @@ SECTIONS .stack (NOLOAD) : { __irq_stack_start = .; - . = 0x400; + . = __stack_ram_size; __irq_stack = .; } > stack __irq_stack_size = __irq_stack - __irq_stack_start; diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h b/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h index 9a85525014..a123d38a5e 100644 --- a/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h +++ b/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h @@ -15,10 +15,10 @@ #define RT_USING_HOOK #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 -#define IDLE_THREAD_STACK_SIZE 1024 +#define IDLE_THREAD_STACK_SIZE 512 #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 4 -#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_TIMER_THREAD_STACK_SIZE 256 #define RT_DEBUG /* Inter-Thread communication */ @@ -64,7 +64,7 @@ #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION #define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_THREAD_STACK_SIZE 2048 #define FINSH_CMD_SIZE 80 #define FINSH_USING_MSH #define FINSH_USING_MSH_DEFAULT @@ -72,6 +72,12 @@ /* Device virtual file system */ +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 2 +#define DFS_FILESYSTEM_TYPES_MAX 2 +#define DFS_FD_MAX 16 +#define RT_USING_DFS_ROMFS /* Device Drivers */ @@ -80,6 +86,10 @@ #define RT_USING_SERIAL #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_PIN +#define RT_USING_AUDIO +#define RT_AUDIO_REPLAY_MP_BLOCK_SIZE 1024 +#define RT_AUDIO_REPLAY_MP_BLOCK_COUNT 2 +#define RT_AUDIO_RECORD_PIPE_SIZE 512 /* Using USB */ @@ -163,6 +173,8 @@ /* On-chip Peripheral Drivers */ #define BSP_USING_UART0 +#define BSP_USING_AUDIO +#define BSP_USING_AUDIO_PLAY /* Board extended module Drivers */ diff --git a/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.py b/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.py index 300d845047..b70a0dc654 100644 --- a/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.py +++ b/bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.py @@ -58,6 +58,7 @@ if PLATFORM == 'gcc': DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' POST_ACTION += './riscv32-elf-xmaker -b rtthread.xm\n' +POST_ACTION += './riscv32-elf-xmaker -b download.xm\n' def dist_handle(BSP_ROOT, dist_dir): import sys diff --git a/bsp/bluetrum/libcpu/cpu/interrupt.c b/bsp/bluetrum/libcpu/cpu/interrupt.c index 1903ec25ce..3e7dbdb553 100644 --- a/bsp/bluetrum/libcpu/cpu/interrupt.c +++ b/bsp/bluetrum/libcpu/cpu/interrupt.c @@ -13,8 +13,8 @@ #include #include "ab32vgx.h" -uint32_t irq_mask AT(.bss.irq_tbl); -void *tbl_irq_vector[IRQ_TOTAL_NUM] AT(.bss.irq_tbl); +uint32_t irq_mask; +void *tbl_irq_vector[IRQ_TOTAL_NUM]; void (*cpu_irq_comm_hook)(void); void set_cpu_irq_comm(void (*irq_hook)(void)) @@ -22,7 +22,6 @@ void set_cpu_irq_comm(void (*irq_hook)(void)) cpu_irq_comm_hook = irq_hook; } -AT(.com_text.irq) void cpu_irq_comm_do(void) { void (*pfnct)(void); @@ -37,6 +36,20 @@ void cpu_irq_comm_do(void) } } +void rt_hw_irq_enable(int vector) +{ + if (vector < IRQ_TOTAL_NUM) { + PICEN |= BIT(vector); + } +} + +void rt_hw_irq_disable(int vector) +{ + if (vector < IRQ_TOTAL_NUM) { + PICEN &= ~BIT(vector); + } +} + void rt_hw_interrupt_init(void) { } @@ -58,7 +71,7 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t old_handler = RT_NULL; if (vector < IRQ_TOTAL_NUM) { - uint32_t cpu_ie = PICCON&BIT(0); + uint32_t cpu_ie = PICCON & BIT(0); PICCON &= ~BIT(0); old_handler = tbl_irq_vector[vector]; tbl_irq_vector[vector] = handler; diff --git a/bsp/bluetrum/libcpu/cpu/interrupt.h b/bsp/bluetrum/libcpu/cpu/interrupt.h new file mode 100644 index 0000000000..d950f1f9b4 --- /dev/null +++ b/bsp/bluetrum/libcpu/cpu/interrupt.h @@ -0,0 +1,7 @@ +#ifndef INTERRUPT_H__ +#define INTERRUPT_H__ + +void rt_hw_irq_enable(int vector); +void rt_hw_irq_disable(int vector); + +#endif diff --git a/bsp/bluetrum/libraries/hal_drivers/drv_usart.c b/bsp/bluetrum/libraries/hal_drivers/drv_usart.c index f17e62f467..d066e155f4 100644 --- a/bsp/bluetrum/libraries/hal_drivers/drv_usart.c +++ b/bsp/bluetrum/libraries/hal_drivers/drv_usart.c @@ -136,8 +136,8 @@ static int ab32_getc(struct rt_serial_device *serial) ch = -1; if(hal_uart_getflag(uart->handle.instance, UART_FLAG_RXPND) != HAL_RESET) { - hal_uart_clrflag(uart->handle.instance, UART_FLAG_RXPND); ch = hal_uart_read(uart->handle.instance); + hal_uart_clrflag(uart->handle.instance, UART_FLAG_RXPND); } return ch; @@ -156,10 +156,10 @@ static void uart_isr(int vector, void *param) { rt_hw_serial_isr(&(uart_obj[UART0_INDEX].serial), RT_SERIAL_EVENT_RX_IND); } - if(hal_uart_getflag(UART1_BASE, UART_FLAG_RXPND)) //RX one byte finish - { - rt_hw_serial_isr(&(uart_obj[UART1_INDEX].serial), RT_SERIAL_EVENT_RX_IND); - } + // if(hal_uart_getflag(UART1_BASE, UART_FLAG_RXPND)) //RX one byte finish + // { + // rt_hw_serial_isr(&(uart_obj[UART1_INDEX].serial), RT_SERIAL_EVENT_RX_IND); + // } rt_interrupt_leave(); } diff --git a/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal.c b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal.c index 8b32dbf16e..0a2d5d9b7c 100644 --- a/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal.c +++ b/bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal.c @@ -2,8 +2,6 @@ static uint32_t hw_ticks = 0; -void timer0_cfg(uint32_t ticks); - static void (*tick_cfg_hook)(uint32_t ticks) = HAL_NULL; void hal_set_tick_hook(void (*hook)(uint32_t ticks)) diff --git a/bsp/bluetrum/libraries/hal_libraries/bmsis/include/ab32vg1.h b/bsp/bluetrum/libraries/hal_libraries/bmsis/include/ab32vg1.h index 203281403d..b5ab98aace 100644 --- a/bsp/bluetrum/libraries/hal_libraries/bmsis/include/ab32vg1.h +++ b/bsp/bluetrum/libraries/hal_libraries/bmsis/include/ab32vg1.h @@ -133,8 +133,29 @@ typedef enum #define TMR2CNT SFR_RW (SFR0_BASE + 0x3c*4) #define TMR2PR SFR_RW (SFR0_BASE + 0x3d*4) +//------------------------- SFR Group1 ---------------------------------------// +#define AUBUFDATA SFR_RW (SFR1_BASE + 0x01*4) +#define AUBUFCON SFR_RW (SFR1_BASE + 0x02*4) +#define AUBUFSTARTADDR SFR_RW (SFR1_BASE + 0x03*4) +#define AUBUFSIZE SFR_RW (SFR1_BASE + 0x04*4) +#define AUBUFFIFOCNT SFR_RW (SFR1_BASE + 0x05*4) +#define AUBUF1DATA SFR_RW (SFR1_BASE + 0x06*4) +#define AUBUF1CON SFR_RW (SFR1_BASE + 0x07*4) +#define AUBUF1STARTADDR SFR_RW (SFR1_BASE + 0x08*4) +#define AUBUF1SIZE SFR_RW (SFR1_BASE + 0x09*4) +#define AUBUF1FIFOCNT SFR_RW (SFR1_BASE + 0x0a*4) + #define DACDIGCON0 SFR_RW (SFR1_BASE + 0x10*4) #define DACVOLCON SFR_RW (SFR1_BASE + 0x11*4) +#define AU0LMIXCOEF SFR_RW (SFR1_BASE + 0x12*4) +#define AU0RMIXCOEF SFR_RW (SFR1_BASE + 0x13*4) +#define AU1LMIXCOEF SFR_RW (SFR1_BASE + 0x14*4) +#define AU1RMIXCOEF SFR_RW (SFR1_BASE + 0x15*4) + +#define AUANGCON0 SFR_RW (SFR1_BASE + 0x3c*4) +#define AUANGCON1 SFR_RW (SFR1_BASE + 0x3d*4) +#define AUANGCON2 SFR_RW (SFR1_BASE + 0x3e*4) +#define AUANGCON3 SFR_RW (SFR1_BASE + 0x3f*4) #define USBCON0 SFR_RW (SFR3_BASE + 0x00*4) #define USBCON1 SFR_RW (SFR3_BASE + 0x01*4) @@ -148,6 +169,7 @@ typedef enum #define PLL1DIV SFR_RW (SFR3_BASE + 0x24*4) #define PLL0CON SFR_RW (SFR3_BASE + 0x26*4) #define PLL1CON SFR_RW (SFR3_BASE + 0x27*4) +#define PLL2CON SFR_RW (SFR3_BASE + 0x28*4) #define XO26MCON SFR_RW (SFR3_BASE + 0x29*4) #define CLKCON2 SFR_RW (SFR3_BASE + 0x2a*4) #define CLKGAT0 SFR_RW (SFR3_BASE + 0x2c*4) @@ -174,6 +196,7 @@ typedef enum #define PICPR SFR_RW (SFR5_BASE + 0x12*4) #define PICADR SFR_RW (SFR5_BASE + 0x13*4) #define PICPND SFR_RW (SFR5_BASE + 0x14*4) +#define EPICCON SFR_RW (SFR5_BASE + 0x1e*4) #define EPC SFR_RW (SFR5_BASE + 0x1f*4) #define SADCDAT0 SFR_RO (SFR5_BASE + 0x20*4) diff --git a/bsp/bluetrum/libraries/hal_libraries/bmsis/source/startup.S b/bsp/bluetrum/libraries/hal_libraries/bmsis/source/startup.S index 0445641797..fe42435c07 100644 --- a/bsp/bluetrum/libraries/hal_libraries/bmsis/source/startup.S +++ b/bsp/bluetrum/libraries/hal_libraries/bmsis/source/startup.S @@ -56,6 +56,43 @@ _start: jal x0, low_prio_irq mret + .org 0x80 +#define METHOD 1 +#if METHOD == 1 + addi sp, sp, -6*4 + lw a0, PICEN(zero) + lw a1, EPC(zero) + lw a2, EPICCON(zero) + sw a0, 3*4(sp) + sw a1, 4*4(sp) + sw a2, 5*4(sp) + andi a0, a0, 1 + sw a0, PICEN(zero) + la a0, 0f + sw a0, EPC(zero) + j 0x84020 +0: + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + + lw a0, 3*4(sp) + lw a1, 4*4(sp) + lw a2, 5*4(sp) + sw a0, PICEN(zero) + sw a1, EPC(zero) + sw a2, EPICCON(zero) + + lw a0, 0(sp) + lw a1, 4(sp) + lw a2, 8(sp) + addi sp, sp, 6*4 + mret + .align 4 +1: .word 0, 0 + j 0x84020 +#endif + .global cpu_irq_comm cpu_irq_comm: la a5, __irq_stack