diff --git a/bsp/qemu-vexpress-a9/drivers/audio/audio_device.c b/bsp/qemu-vexpress-a9/drivers/audio/audio_device.c deleted file mode 100644 index a0f37ed62100bee0dbd1c12b9c6475e395c04b6f..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/drivers/audio/audio_device.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * File : audio_device.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-26 RT-Thread the first version - */ - -#include -#include -#include -#include -#include "drv_pl041.h" -#include "drv_ac97.h" -#include "audio_device.h" - -struct audio_device -{ - struct rt_device *snd; - struct rt_mempool mp; - - int state; - - void (*evt_handler)(void *parameter, int state); - void *parameter; -}; - -static struct audio_device *_audio_device = NULL; - -void *audio_device_get_buffer(int *bufsz) -{ - if (bufsz) - { - *bufsz = AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2; - } - - return rt_mp_alloc(&(_audio_device->mp), RT_WAITING_FOREVER); -} - -void audio_device_put_buffer(void *ptr) -{ - if (ptr) rt_mp_free(ptr); - return ; -} - -static rt_err_t audio_device_write_done(struct rt_device *device, void *ptr) -{ - if (!ptr) - { - rt_kprintf("device buf_release NULL\n"); - return -RT_ERROR; - } - - rt_mp_free(ptr); - return RT_EOK; -} - -void audio_device_write(void *buffer, int size) -{ - if (_audio_device->snd && size != 0) - { - if (_audio_device->state == AUDIO_DEVICE_IDLE) - { - if (_audio_device->evt_handler) - _audio_device->evt_handler(_audio_device->parameter, AUDIO_DEVICE_PLAYBACK); - - /* change audio device state */ - _audio_device->state = AUDIO_DEVICE_PLAYBACK; - } - - rt_device_write(_audio_device->snd, 0, buffer, size); - } - else - { - /* release buffer directly */ - rt_mp_free(buffer); - } - - return ; -} - -int audio_device_init(void) -{ - uint8_t *mempool_ptr; - - if (!_audio_device) - { - _audio_device = (struct audio_device *) rt_malloc(sizeof(struct audio_device) + AUDIO_DEVICE_DECODE_MP_SZ); - if (_audio_device == NULL) - { - rt_kprintf("malloc memeory for _audio_device failed! \n"); - return -RT_ERROR; - } - - _audio_device->evt_handler = NULL; - _audio_device->parameter = NULL; - - mempool_ptr = (uint8_t *)(_audio_device + 1); - rt_mp_init(&(_audio_device->mp), "adbuf", mempool_ptr, AUDIO_DEVICE_DECODE_MP_SZ, AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2); - - /* find snd device */ - _audio_device->snd = rt_device_find("sound"); - if (_audio_device->snd == NULL) - { - rt_kprintf("sound device not found \n"); - return -1; - } - - /* set tx complete call back function */ - rt_device_set_tx_complete(_audio_device->snd, audio_device_write_done); - } - - return RT_EOK; -} - -int audio_device_set_evt_handler(void (*handler)(void *parameter, int state), void *parameter) -{ - if (_audio_device) - { - _audio_device->evt_handler = handler; - _audio_device->parameter = parameter; - } - - return 0; -} - -void audio_device_set_rate(int sample_rate) -{ - if (_audio_device->snd) - { - int rate = sample_rate; - - rt_device_control(_audio_device->snd, CODEC_CMD_SAMPLERATE, &rate); - } -} - -void audio_device_set_volume(int value) -{ - if (_audio_device->snd) - { - rt_device_control(_audio_device->snd, CODEC_CMD_SET_VOLUME, &value); - } -} - -int audio_device_get_volume(void) -{ - int value = 0; - - if (_audio_device->snd) - { - rt_device_control(_audio_device->snd, CODEC_CMD_GET_VOLUME, &value); - } - - return value; -} - -void audio_device_open(void) -{ - _audio_device->state = AUDIO_DEVICE_IDLE; - rt_device_open(_audio_device->snd, RT_DEVICE_OFLAG_WRONLY); -} - -void audio_device_close(void) -{ - rt_device_close(_audio_device->snd); - - if (_audio_device->state == AUDIO_DEVICE_PLAYBACK) - { - if (_audio_device->evt_handler) - _audio_device->evt_handler(_audio_device->parameter, AUDIO_DEVICE_CLOSE); - } - - /* set to idle */ - _audio_device->state = AUDIO_DEVICE_CLOSE; -} diff --git a/bsp/qemu-vexpress-a9/drivers/audio/audio_device.h b/bsp/qemu-vexpress-a9/drivers/audio/audio_device.h deleted file mode 100644 index d0143c231b4c91bc4f3d2414579d049b6fac040d..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/drivers/audio/audio_device.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * File : audio_device.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-26 RT-Thread the first version - */ - -#ifndef AUDIO_DEVICE_H__ -#define AUDIO_DEVICE_H__ - -enum AUDIO_DEVICE_STATE -{ - AUDIO_DEVICE_IDLE, - AUDIO_DEVICE_PLAYBACK, - AUDIO_DEVICE_CLOSE, -}; - -void *audio_device_get_buffer(int *bufsz); -void audio_device_put_buffer(void *ptr); - -void audio_device_write(void *buffer, int size); - -int audio_device_init(void); -void audio_device_close(void); - -void audio_device_open(void); - -int audio_device_set_evt_handler(void (*handler)(void *parameter, int state), void *parameter); - -void audio_device_set_rate(int sample_rate); -void audio_device_set_volume(int volume); -void audio_device_wait_free(void); - -#endif \ No newline at end of file diff --git a/bsp/qemu-vexpress-a9/drivers/audio/drv_audio.c b/bsp/qemu-vexpress-a9/drivers/audio/drv_audio.c deleted file mode 100644 index 53161ef22bae810565927dc9f798e3ad704efbdd..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/drivers/audio/drv_audio.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * File : drv_audio.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-26 RT-Thread the first version - */ - -#include -#include -#include -#include -#include "drv_pl041.h" -#include "drv_ac97.h" -#include "drv_audio.h" - -#define DATA_NODE_MAX (10) -#define CODEC_TX_FIFO_SIZE (256) - -#define AUDIO_DEVICE_DECODE_MP_SIZE (4096) -#define AUDIO_DEVICE_DECODE_MP_CONUT (4) - -struct codec_data_node -{ - char *data_ptr; - rt_size_t data_size; -}; - -struct audio_buff_des -{ - struct codec_data_node *data_list; - void (*free_fun)(void *); - rt_uint32_t read_offset; - rt_uint16_t node_num; - rt_uint16_t read_index, put_index; -}; - -struct audio_device -{ - /* inherit from rt_device */ - struct rt_device parent; -}; - -static struct audio_device audio_device_drive; -static struct audio_buff_des *audio_buff; -static int irq_flag = 0; - -static void _audio_buff_cb(void *buff) -{ - if (audio_device_drive.parent.tx_complete != RT_NULL) - { - audio_device_drive.parent.tx_complete(&audio_device_drive.parent, buff); - } -} - -static rt_size_t _audio_buff_push(struct audio_buff_des *hdle, void *buff, int size) -{ - struct codec_data_node *node; - rt_uint16_t next_index; - rt_uint32_t level; - - if ((buff == RT_NULL) || (size == 0)) - { - return 0; - } - - next_index = hdle->put_index + 1; - if (next_index >= hdle->node_num) - next_index = 0; - /* check data_list full */ - if (next_index == hdle->read_index) - { - rt_kprintf("data_list full\n"); - rt_set_errno(-RT_EFULL); - return 0; - } - - level = rt_hw_interrupt_disable(); - node = &hdle->data_list[hdle->put_index]; - hdle->put_index = next_index; - - /* set node attribute */ - node->data_ptr = (char *) buff; - node->data_size = size; - rt_hw_interrupt_enable(level); - - return size; -} - -static rt_size_t _audio_buff_pop(struct audio_buff_des *hdle, void *buff, int size) -{ - struct codec_data_node *node; - rt_uint32_t next_index, count = 0, cp_size = 0, offset = 0; - - node = &hdle->data_list[hdle->read_index]; - if ((hdle->read_index == hdle->put_index) && (node->data_ptr == RT_NULL)) - { - memset(buff, 0xff, size); - return 0; - } - - while (count < size) - { - node = &hdle->data_list[hdle->read_index]; - offset = hdle->read_offset; - cp_size = (node->data_size - offset) > (size - count) ? (size - count) : (node->data_size - offset); - - if (node->data_ptr == RT_NULL) - { - memset(buff, 0, size - count); - return count; - } - - memcpy((rt_uint8_t *)buff + count, (rt_uint8_t *)(node->data_ptr) + offset, cp_size); - hdle->read_offset += cp_size; - count += cp_size; - - if (hdle->read_offset >= node->data_size) - { - /* notify transmitted complete. */ - if (hdle->free_fun != RT_NULL) - { - hdle->free_fun(node->data_ptr); - } - /* clear current node */ - memset(node, 0, sizeof(struct codec_data_node)); - next_index = hdle->read_index + 1; - if (next_index >= hdle->node_num) - { - next_index = 0; - } - hdle->read_offset = 0; - hdle->read_index = next_index; - } - } - - return count; -} - -static void transit_wav_data(rt_uint32_t status) -{ - rt_uint16_t sample[CODEC_TX_FIFO_SIZE]; - int i = 0, size; - - size = _audio_buff_pop(audio_buff, sample, CODEC_TX_FIFO_SIZE * sizeof(rt_uint16_t)); - if ((size == 0) && (irq_flag == 1)) - { - aaci_pl041_irq_disable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); - irq_flag = 0; - } - - for (i = 0; i < (size >> 1); i++) - { - aaci_pl041_channle_write(0, &sample[i], 1); - } -} - -static void rt_hw_aaci_isr(rt_uint32_t status, void *user_data) -{ - if (status & AACI_SR_TXHE) - { - transit_wav_data(status); - } -} - -static rt_err_t codec_init(rt_device_t dev) -{ - struct pl041_cfg _cfg; - - _cfg.itype = PL041_CHANNLE_LEFT_ADC | PL041_CHANNLE_RIGHT_ADC; - _cfg.otype = PL041_CHANNLE_LEFT_DAC | PL041_CHANNLE_RIGHT_DAC; - _cfg.vol = 50; - _cfg.rate = 8000; - - ac97_reset(); - aaci_pl041_channle_cfg(0, &_cfg); - aaci_pl041_irq_register(0, rt_hw_aaci_isr, RT_NULL); - - return RT_EOK; -} - -static rt_err_t codec_open(rt_device_t dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t codec_close(rt_device_t dev) -{ - rt_uint16_t temp = 0, i = 1024 * 10; - - while (PL041->sr1 & AACI_SR_TXB); - while (i) - { - if (aaci_pl041_channle_write(0, &temp, 1) != 0) - { - i--; - } - } - return RT_EOK; -} - -static rt_size_t codec_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - return 0; -} - -static rt_size_t codec_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - _audio_buff_push(audio_buff, (void *)buffer, size); - - if (irq_flag == 0) - { - //open irq - irq_flag = 1; - aaci_pl041_channle_enable(0); - aaci_pl041_irq_enable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); - } - return 0; -} - -static rt_err_t codec_control(rt_device_t dev, int cmd, void *args) -{ - rt_err_t result = RT_EOK; - - switch (cmd) - { - case CODEC_CMD_RESET: - { - break; - } - case CODEC_CMD_SET_VOLUME: - { - uint32_t v; - - v = *(rt_uint32_t *)args; - result = ac97_set_vol(v); - break; - } - case CODEC_CMD_GET_VOLUME: - { - int *v = args; - *v = ac97_get_vol(); - break; - } - case CODEC_CMD_SAMPLERATE: - { - int v; - - v = *(rt_uint32_t *)args; - ac97_set_rate(v); - break; - } - - default: - result = RT_ERROR; - } - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops codec_ops = -{ - codec_init, - codec_open, - codec_close, - codec_read, - codec_write, - codec_control -}; -#endif - -int audio_hw_init(void) -{ - struct audio_device *codec = &audio_device_drive; - - codec->parent.type = RT_Device_Class_Sound; - codec->parent.rx_indicate = RT_NULL; - codec->parent.tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - codec->parent.ops = &codec_ops; -#else - codec->parent.init = codec_init; - codec->parent.open = codec_open; - codec->parent.close = codec_close; - codec->parent.read = codec_read; - codec->parent.write = codec_write; - codec->parent.control = codec_control; -#endif - - codec->parent.user_data = RT_NULL; - - audio_buff = rt_malloc(sizeof(struct audio_buff_des) + sizeof(struct codec_data_node) * DATA_NODE_MAX); - if (audio_buff == RT_NULL) - { - rt_kprintf("audio buff malloc fail\n"); - return -1; - } - rt_memset(audio_buff, 0, sizeof(struct audio_buff_des) + sizeof(struct codec_data_node) * DATA_NODE_MAX); - audio_buff->data_list = (struct codec_data_node *)((rt_uint8_t *)audio_buff + sizeof(struct audio_buff_des)); - audio_buff->free_fun = _audio_buff_cb; - audio_buff->node_num = DATA_NODE_MAX; - /* register the device */ - rt_device_register(&codec->parent, "sound", RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX); - - aaci_pl041_init(); - rt_device_init(&codec->parent); - - return 0; -} -INIT_DEVICE_EXPORT(audio_hw_init); diff --git a/bsp/qemu-vexpress-a9/drivers/audio/drv_audio.h b/bsp/qemu-vexpress-a9/drivers/audio/drv_audio.h deleted file mode 100644 index b2c07b40e428d297ea22ff584b0d02ce7c82a0de..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/drivers/audio/drv_audio.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * File : drv_audio.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2018-05-26 RT-Thread the first version - */ - -#ifndef __DRV_AUDIO_H__ -#define __DRV_AUDIO_H__ - - -#endif diff --git a/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.c b/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.c index 51cf3710efacfcd48dee2acad599ce39285935dd..0b1ee9827d00752f6c11b8795fd1d02334c30c7d 100644 --- a/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.c +++ b/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.c @@ -302,7 +302,7 @@ static void aaci_pl041_irq_handle(int irqno, void *param) void *p_status; mask = PL041_READ(&PL041->allints); - PL041_WRITE(PL041->intclr, mask); + PL041_WRITE(&PL041->intclr, mask); for (channle = 0; (channle < PL041_CHANNLE_NUM) && (mask); channle++) { diff --git a/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.h b/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.h index d0bacd8c613c1118a0ff8d4da49f5446f2895b0e..5ea146e4360af3fa30a6d93e7ba12903baff4ada 100644 --- a/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.h +++ b/bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.h @@ -225,7 +225,7 @@ typedef void (*pl041_irq_fun_t)(rt_uint32_t status, void * user_data); rt_err_t aaci_pl041_init(void); void aaci_ac97_write(rt_uint16_t reg, rt_uint16_t val); rt_uint16_t aaci_ac97_read(rt_uint16_t reg); -int aaci_pl041_channle_cfg(int channle, pl041_cfg_t cgf); +int aaci_pl041_channle_cfg(int channle, pl041_cfg_t cfg); int aaci_pl041_channle_write(int channle, rt_uint16_t *buff, int count); int aaci_pl041_channle_read(int channle, rt_uint16_t *buff, int count); int aaci_pl041_channle_enable(int channle); diff --git a/bsp/qemu-vexpress-a9/drivers/audio/drv_sound.c b/bsp/qemu-vexpress-a9/drivers/audio/drv_sound.c new file mode 100644 index 0000000000000000000000000000000000000000..cee67b0a0b4a052a610b637dd1bb3205482c30ea --- /dev/null +++ b/bsp/qemu-vexpress-a9/drivers/audio/drv_sound.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-23 Zero-Free first implementation + */ + +#include +#include + +#include +#include +#include + +#define DBG_TAG "drv.sound" +#define DBG_LVL DBG_INFO +#include + +#define TX_FIFO_SIZE (3840) + +struct sound_device +{ + struct rt_audio_device audio; + struct rt_audio_configure replay_config; + rt_uint8_t *tx_fifo; + rt_uint8_t volume; +}; + +static struct sound_device snd_dev = {0}; + +static void rt_hw_aaci_isr(rt_uint32_t status, void *user_data) +{ + if (status & AACI_SR_TXHE) + { + rt_audio_tx_complete(&snd_dev.audio); + } +} + +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_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 = snd_dev->volume; + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + default: + result = -RT_ERROR; + break; + } + + return result; +} + +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; + struct rt_audio_replay *replay; + + 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; + + snd_dev->volume = volume; + ac97_set_vol(volume); + LOG_I("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 */ + ac97_set_rate(caps->udata.config.samplerate); + + /* update buffer fifo informaition according samplerate */ + replay = snd_dev->audio.replay; + replay->buf_info.total_size = caps->udata.config.samplerate / 50 * 4; + replay->buf_info.block_size = replay->buf_info.total_size / 2; + + /* 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: + { + ac97_set_rate(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: + { + /* not support */ + 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 result; +} + +static rt_err_t sound_init(struct rt_audio_device *audio) +{ + rt_err_t result = RT_EOK; + struct sound_device *snd_dev; + struct pl041_cfg _cfg; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + aaci_pl041_init(); + + _cfg.itype = PL041_CHANNLE_LEFT_ADC | PL041_CHANNLE_RIGHT_ADC; + _cfg.otype = PL041_CHANNLE_LEFT_DAC | PL041_CHANNLE_RIGHT_DAC; + _cfg.vol = snd_dev->volume; + _cfg.rate = snd_dev->replay_config.samplerate; + + ac97_reset(); + aaci_pl041_channle_cfg(0, &_cfg); + aaci_pl041_irq_register(0, rt_hw_aaci_isr, RT_NULL); + + return result; +} + +static rt_err_t sound_start(struct rt_audio_device *audio, int stream) +{ + RT_ASSERT(audio != RT_NULL); + + if (stream == AUDIO_STREAM_REPLAY) + { + LOG_D("open sound device"); + aaci_pl041_channle_enable(0); + aaci_pl041_irq_enable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); + } + + return RT_EOK; +} + +static rt_err_t sound_stop(struct rt_audio_device *audio, int stream) +{ + RT_ASSERT(audio != RT_NULL); + + if (stream == AUDIO_STREAM_REPLAY) + { + /* wait codec free */ + rt_thread_mdelay(100); + /* disable irq and channels 0 */ + aaci_pl041_irq_disable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC); + aaci_pl041_channle_disable(0); + LOG_D("close sound device"); + } + + return RT_EOK; +} + +static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info) +{ + struct sound_device *snd_dev; + + 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 rt_size_t sound_transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size) +{ + RT_ASSERT(audio != RT_NULL); + + /* write data to channel_0 fifo */ + aaci_pl041_channle_write(0, (rt_uint16_t *)writeBuf, size >> 1); + + return size; +} + +static struct rt_audio_ops snd_ops = +{ + .getcaps = sound_getcaps, + .configure = sound_configure, + .init = sound_init, + .start = sound_start, + .stop = sound_stop, + .transmit = sound_transmit, + .buffer_info = sound_buffer_info, +}; + +int rt_hw_audio_init(void) +{ + rt_uint8_t *tx_fifo; + + if (snd_dev.tx_fifo) + return RT_EOK; + + tx_fifo = rt_malloc(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; + + /* init default configuration */ + { + snd_dev.replay_config.samplerate = 44100; + snd_dev.replay_config.channels = 2; + snd_dev.replay_config.samplebits = 16; + snd_dev.volume = 55; + } + + /* register sound device */ + snd_dev.audio.ops = &snd_ops; + rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev); + + return RT_EOK; +} + +INIT_DEVICE_EXPORT(rt_hw_audio_init); diff --git a/bsp/qemu-vexpress-a9/drivers/audio/drv_sound.h b/bsp/qemu-vexpress-a9/drivers/audio/drv_sound.h new file mode 100644 index 0000000000000000000000000000000000000000..7cb47532bea7bae9ca1cc57015f8b81ce15a4aea --- /dev/null +++ b/bsp/qemu-vexpress-a9/drivers/audio/drv_sound.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-23 Zero-Free first implementation + */ + +#ifndef __DRV_SOUND_H__ +#define __DRV_SOUND_H__ + +int rt_hw_audio_init(void); + +#endif diff --git a/bsp/qemu-vexpress-a9/drivers/audio/wav_play.c b/bsp/qemu-vexpress-a9/drivers/audio/wav_play.c deleted file mode 100644 index c000a0b0850960200b8a18702f85281ba55ac6f9..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/drivers/audio/wav_play.c +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include "audio_device.h" - -#define BUFSZ 2048 - -struct RIFF_HEADER_DEF -{ - char riff_id[4]; // 'R','I','F','F' - uint32_t riff_size; - char riff_format[4]; // 'W','A','V','E' -}; - -struct WAVE_FORMAT_DEF -{ - uint16_t FormatTag; - uint16_t Channels; - uint32_t SamplesPerSec; - uint32_t AvgBytesPerSec; - uint16_t BlockAlign; - uint16_t BitsPerSample; -}; - -struct FMT_BLOCK_DEF -{ - char fmt_id[4]; // 'f','m','t',' ' - uint32_t fmt_size; - struct WAVE_FORMAT_DEF wav_format; -}; - -struct DATA_BLOCK_DEF -{ - char data_id[4]; // 'R','I','F','F' - uint32_t data_size; -}; - -struct wav_info -{ - struct RIFF_HEADER_DEF header; - struct FMT_BLOCK_DEF fmt_block; - struct DATA_BLOCK_DEF data_block; -}; - -static char file_name[32]; - -void wavplay_thread_entry(void *parameter) -{ - FILE *fp = NULL; - uint16_t *buffer = NULL; - struct wav_info *info = NULL; - - fp = fopen(file_name, "rb"); - if (!fp) - { - printf("open file failed!\n"); - goto __exit; - } - - info = (struct wav_info *) malloc(sizeof(*info)); - if (!info) goto __exit; - - if (fread(&(info->header), sizeof(struct RIFF_HEADER_DEF), 1, fp) != 1) goto __exit; - if (fread(&(info->fmt_block), sizeof(struct FMT_BLOCK_DEF), 1, fp) != 1) goto __exit; - if (fread(&(info->data_block), sizeof(struct DATA_BLOCK_DEF), 1, fp) != 1) goto __exit; - - printf("wav information:\n"); - printf("samplerate %u\n", info->fmt_block.wav_format.SamplesPerSec); - printf("channel %u\n", info->fmt_block.wav_format.Channels); - - audio_device_init(); - audio_device_open(); - audio_device_set_rate(info->fmt_block.wav_format.SamplesPerSec); - - while (!feof(fp)) - { - int length; - - buffer = (uint16_t *)audio_device_get_buffer(RT_NULL); - - length = fread(buffer, 1, BUFSZ, fp); - if (length) - { - if (info->fmt_block.wav_format.Channels == 1) - { - /* extend to stereo channels */ - int index; - uint16_t *ptr; - - ptr = (uint16_t *)((uint8_t *)buffer + BUFSZ * 2); - for (index = 1; index < BUFSZ / 2; index ++) - { - *ptr = *(ptr - 1) = buffer[BUFSZ / 2 - index]; - ptr -= 2; - } - - length = length * 2; - } - - audio_device_write((uint8_t *)buffer, length); - } - else - { - audio_device_put_buffer((uint8_t *)buffer); - break; - } - } - audio_device_close(); - -__exit: - if (fp) fclose(fp); - if (info) free(info); -} - -int wavplay(int argc, char **argv) -{ - rt_thread_t tid = RT_NULL; - - if (argc != 2) - { - printf("Usage:\n"); - printf("wavplay song.wav\n"); - return 0; - } - - memset(file_name, 0, sizeof(file_name)); - memcpy(file_name, argv[1], strlen(argv[1])); - - tid = rt_thread_create("wayplay", - wavplay_thread_entry, - RT_NULL, - 1024 * 8, - 22, - 10); - if (tid != RT_NULL) - rt_thread_startup(tid); -} - -MSH_CMD_EXPORT(wavplay, wavplay song.wav); diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject index 87900023d117857078b0b96e7bd69c16c1edbbd7..29431439f6800074692169217dd2c64f06178e90 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject +++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject @@ -1,16 +1,16 @@ [PreviousGenFiles] -HeaderPath=D:/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc +HeaderPath=D:/dev/others/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc HeaderFiles=stm32l4xx_it.h;stm32l4xx_hal_conf.h;main.h; -SourcePath=D:/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src +SourcePath=D:/dev/others/rt-thread/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src SourceFiles=stm32l4xx_it.c;stm32l4xx_hal_msp.c;main.c; [PreviousLibFiles] -LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l475xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c; +LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l475xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\stm32l4xx_it.c;..\Src\stm32l4xx_hal_msp.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;null; +SourceFiles=..\Src\main.c;..\Src\stm32l4xx_it.c;..\Src\stm32l4xx_hal_msp.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;../\Src/system_stm32l4xx.c;../Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;null; HeaderPath=..\Drivers\STM32L4xx_HAL_Driver\Inc;..\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\Drivers\CMSIS\Include;..\Inc; -CDefines=USE_HAL_DRIVER;STM32L475xx; +CDefines=USE_HAL_DRIVER;STM32L475xx;USE_HAL_DRIVER;STM32L475xx; [] SourceFiles=;; diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h index 54357c5f9b5817aa6db20e2673f0c05a8605c1bd..50ea5af90e44ff09c777c638f01e9f0f6c1bcba2 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h +++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h @@ -81,7 +81,7 @@ #define HAL_QSPI_MODULE_ENABLED /*#define HAL_RNG_MODULE_ENABLED */ #define HAL_RTC_MODULE_ENABLED -/*#define HAL_SAI_MODULE_ENABLED */ +#define HAL_SAI_MODULE_ENABLED /*#define HAL_SD_MODULE_ENABLED */ /*#define HAL_SMBUS_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc index c667ad5c3e44843519417a46d75b309c7353e9b8..cc3128d10fcbb83e557acb27ec662e32b444ab1b 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc +++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc @@ -11,65 +11,73 @@ KeepUserPlacement=false Mcu.Family=STM32L4 Mcu.IP0=ADC1 Mcu.IP1=IWDG -Mcu.IP10=TIM2 -Mcu.IP11=TIM4 -Mcu.IP12=TIM15 -Mcu.IP13=TIM16 -Mcu.IP14=TIM17 -Mcu.IP15=USART1 -Mcu.IP16=USART2 -Mcu.IP17=USB_OTG_FS +Mcu.IP10=TIM1 +Mcu.IP11=TIM2 +Mcu.IP12=TIM4 +Mcu.IP13=TIM15 +Mcu.IP14=TIM16 +Mcu.IP15=TIM17 +Mcu.IP16=USART1 +Mcu.IP17=USART2 +Mcu.IP18=USB_OTG_FS Mcu.IP2=NVIC Mcu.IP3=QUADSPI Mcu.IP4=RCC Mcu.IP5=RTC -Mcu.IP6=SPI1 -Mcu.IP7=SPI2 -Mcu.IP8=SYS -Mcu.IP9=TIM1 -Mcu.IPNb=18 +Mcu.IP6=SAI1 +Mcu.IP7=SPI1 +Mcu.IP8=SPI2 +Mcu.IP9=SYS +Mcu.IPNb=19 Mcu.Name=STM32L475V(C-E-G)Tx Mcu.Package=LQFP100 -Mcu.Pin0=PC14-OSC32_IN (PC14) -Mcu.Pin1=PC15-OSC32_OUT (PC15) -Mcu.Pin10=PE9 -Mcu.Pin11=PE10 -Mcu.Pin12=PE11 -Mcu.Pin13=PE12 -Mcu.Pin14=PE13 -Mcu.Pin15=PE14 -Mcu.Pin16=PE15 -Mcu.Pin17=PB10 -Mcu.Pin18=PB11 -Mcu.Pin19=PB13 -Mcu.Pin2=PH0-OSC_IN (PH0) -Mcu.Pin20=PB14 -Mcu.Pin21=PB15 -Mcu.Pin22=PA9 -Mcu.Pin23=PA10 -Mcu.Pin24=PA11 -Mcu.Pin25=PA12 -Mcu.Pin26=PA13 (JTMS-SWDIO) -Mcu.Pin27=PA14 (JTCK-SWCLK) -Mcu.Pin28=PB7 -Mcu.Pin29=PB8 -Mcu.Pin3=PH1-OSC_OUT (PH1) -Mcu.Pin30=VP_IWDG_VS_IWDG -Mcu.Pin31=VP_RTC_VS_RTC_Activate -Mcu.Pin32=VP_SYS_VS_Systick -Mcu.Pin33=VP_TIM1_VS_ClockSourceINT -Mcu.Pin34=VP_TIM2_VS_ClockSourceINT -Mcu.Pin35=VP_TIM4_VS_ClockSourceINT -Mcu.Pin36=VP_TIM15_VS_ClockSourceINT -Mcu.Pin37=VP_TIM16_VS_ClockSourceINT -Mcu.Pin38=VP_TIM17_VS_ClockSourceINT -Mcu.Pin4=PA2 -Mcu.Pin5=PA3 -Mcu.Pin6=PA5 -Mcu.Pin7=PA6 -Mcu.Pin8=PA7 -Mcu.Pin9=PC5 -Mcu.PinsNb=39 +Mcu.Pin0=PE2 +Mcu.Pin1=PE3 +Mcu.Pin10=PA3 +Mcu.Pin11=PA5 +Mcu.Pin12=PA6 +Mcu.Pin13=PA7 +Mcu.Pin14=PC5 +Mcu.Pin15=PE9 +Mcu.Pin16=PE10 +Mcu.Pin17=PE11 +Mcu.Pin18=PE12 +Mcu.Pin19=PE13 +Mcu.Pin2=PE4 +Mcu.Pin20=PE14 +Mcu.Pin21=PE15 +Mcu.Pin22=PB10 +Mcu.Pin23=PB11 +Mcu.Pin24=PB13 +Mcu.Pin25=PB14 +Mcu.Pin26=PB15 +Mcu.Pin27=PA9 +Mcu.Pin28=PA10 +Mcu.Pin29=PA11 +Mcu.Pin3=PE5 +Mcu.Pin30=PA12 +Mcu.Pin31=PA13 (JTMS-SWDIO) +Mcu.Pin32=PA14 (JTCK-SWCLK) +Mcu.Pin33=PB7 +Mcu.Pin34=PB8 +Mcu.Pin35=VP_IWDG_VS_IWDG +Mcu.Pin36=VP_RTC_VS_RTC_Activate +Mcu.Pin37=VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC +Mcu.Pin38=VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC +Mcu.Pin39=VP_SYS_VS_Systick +Mcu.Pin4=PE6 +Mcu.Pin40=VP_TIM1_VS_ClockSourceINT +Mcu.Pin41=VP_TIM2_VS_ClockSourceINT +Mcu.Pin42=VP_TIM4_VS_ClockSourceINT +Mcu.Pin43=VP_TIM15_VS_ClockSourceINT +Mcu.Pin44=VP_TIM16_VS_ClockSourceINT +Mcu.Pin45=VP_TIM17_VS_ClockSourceINT +Mcu.Pin5=PC14-OSC32_IN (PC14) +Mcu.Pin6=PC15-OSC32_OUT (PC15) +Mcu.Pin7=PH0-OSC_IN (PH0) +Mcu.Pin8=PH1-OSC_OUT (PH1) +Mcu.Pin9=PA2 +Mcu.PinsNb=46 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32L475VETx @@ -152,6 +160,16 @@ PE14.Signal=QUADSPI_BK1_IO2 PE15.Locked=true PE15.Mode=Single Bank PE15.Signal=QUADSPI_BK1_IO3 +PE2.Mode=SAI_A_MasterWithClock +PE2.Signal=SAI1_MCLK_A +PE3.Mode=SAI_B_SyncSlave +PE3.Signal=SAI1_SD_B +PE4.Mode=SAI_A_MasterWithClock +PE4.Signal=SAI1_FS_A +PE5.Mode=SAI_A_MasterWithClock +PE5.Signal=SAI1_SCK_A +PE6.Mode=SAI_A_MasterWithClock +PE6.Signal=SAI1_SD_A PE9.Signal=S_TIM1_CH1 PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN @@ -240,6 +258,20 @@ RCC.VCOInputFreq_Value=8000000 RCC.VCOOutputFreq_Value=160000000 RCC.VCOSAI1OutputFreq_Value=96000000 RCC.VCOSAI2OutputFreq_Value=64000000 +SAI1.AudioFrequency-SAI_A_MasterWithClock=SAI_AUDIO_FREQUENCY_44K +SAI1.ErrorAudioFreq-SAI_A_MasterWithClock=-72.09 % +SAI1.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,InitProtocol-SAI_A_MasterWithClock,VirtualProtocol-SAI_A_BASIC,AudioFrequency-SAI_A_MasterWithClock,OutputDrive-SAI_A_MasterWithClock,Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,InitProtocol-SAI_B_SyncSlave,VirtualProtocol-SAI_B_BASIC +SAI1.InitProtocol-SAI_A_MasterWithClock=Enable +SAI1.InitProtocol-SAI_B_SyncSlave=Enable +SAI1.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A +SAI1.Instance-SAI_B_SyncSlave=SAI$Index_Block_B +SAI1.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE +SAI1.OutputDrive-SAI_A_MasterWithClock=SAI_OUTPUTDRIVE_ENABLE +SAI1.RealAudioFreq-SAI_A_MasterWithClock=53.571 KHz +SAI1.VirtualMode-SAI_A_MasterWithClock=VM_MASTER +SAI1.VirtualMode-SAI_B_SyncSlave=VM_SLAVE +SAI1.VirtualProtocol-SAI_A_BASIC=VM_BASIC_PROTOCOL +SAI1.VirtualProtocol-SAI_B_BASIC=VM_BASIC_PROTOCOL SH.ADCx_IN14.0=ADC1_IN14,IN14-Single-Ended SH.ADCx_IN14.ConfNb=1 SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1 @@ -280,6 +312,10 @@ VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate +VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Mode=SAI_A_BASIC +VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIA_SAI_BASIC +VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Mode=SAI_B_BASIC +VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIB_SAI_BASIC VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_TIM15_VS_ClockSourceINT.Mode=Internal diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c index fce54d377564ae3e7f79c5b8ff63e11eba4c63ec..2deff2622d897b897df8d0ee81e4ab5aff9d101c 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c @@ -70,10 +70,14 @@ QSPI_HandleTypeDef hqspi; RTC_HandleTypeDef hrtc; +SAI_HandleTypeDef hsai_BlockA1; +SAI_HandleTypeDef hsai_BlockB1; + SPI_HandleTypeDef hspi1; SPI_HandleTypeDef hspi2; TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim4; TIM_HandleTypeDef htim15; TIM_HandleTypeDef htim16; @@ -105,6 +109,8 @@ static void MX_TIM16_Init(void); static void MX_TIM15_Init(void); static void MX_TIM4_Init(void); static void MX_TIM1_Init(void); +static void MX_SAI1_Init(void); +static void MX_TIM2_Init(void); static void MX_USB_OTG_FS_PCD_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ @@ -158,6 +164,8 @@ int main(void) MX_TIM15_Init(); MX_TIM4_Init(); MX_TIM1_Init(); + MX_SAI1_Init(); + MX_TIM2_Init(); MX_USB_OTG_FS_PCD_Init(); /* USER CODE BEGIN 2 */ @@ -222,10 +230,11 @@ void SystemClock_Config(void) Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1 - |RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_USB - |RCC_PERIPHCLK_ADC; + |RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_SAI1 + |RCC_PERIPHCLK_USB|RCC_PERIPHCLK_ADC; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; + PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1; PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; @@ -235,7 +244,8 @@ void SystemClock_Config(void) PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7; PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; - PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK|RCC_PLLSAI1_ADC1CLK; + PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK|RCC_PLLSAI1_48M2CLK + |RCC_PLLSAI1_ADC1CLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); @@ -409,6 +419,55 @@ static void MX_RTC_Init(void) } +/** + * @brief SAI1 Initialization Function + * @param None + * @retval None + */ +static void MX_SAI1_Init(void) +{ + + /* USER CODE BEGIN SAI1_Init 0 */ + + /* USER CODE END SAI1_Init 0 */ + + /* USER CODE BEGIN SAI1_Init 1 */ + + /* USER CODE END SAI1_Init 1 */ + hsai_BlockA1.Instance = SAI1_Block_A; + hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX; + hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS; + hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE; + hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; + hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; + hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K; + hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE; + hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE; + hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING; + hsai_BlockA1.Init.TriState = SAI_OUTPUT_NOTRELEASED; + if (HAL_SAI_InitProtocol(&hsai_BlockA1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK) + { + Error_Handler(); + } + hsai_BlockB1.Instance = SAI1_Block_B; + hsai_BlockB1.Init.AudioMode = SAI_MODESLAVE_RX; + hsai_BlockB1.Init.Synchro = SAI_SYNCHRONOUS; + hsai_BlockB1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE; + hsai_BlockB1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; + hsai_BlockB1.Init.SynchroExt = SAI_SYNCEXT_DISABLE; + hsai_BlockB1.Init.MonoStereoMode = SAI_STEREOMODE; + hsai_BlockB1.Init.CompandingMode = SAI_NOCOMPANDING; + hsai_BlockB1.Init.TriState = SAI_OUTPUT_NOTRELEASED; + if (HAL_SAI_InitProtocol(&hsai_BlockB1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SAI1_Init 2 */ + + /* USER CODE END SAI1_Init 2 */ + +} + /** * @brief SPI1 Initialization Function * @param None @@ -569,6 +628,69 @@ static void MX_TIM1_Init(void) } +/** + * @brief TIM2 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + htim2.Instance = TIM2; + htim2.Init.Prescaler = 0; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 0; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 0; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + HAL_TIM_MspPostInit(&htim2); + +} + /** * @brief TIM4 Initialization Function * @param None @@ -856,10 +978,10 @@ static void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); } diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c index 372cbadf67a1ea764febc5302b33e0259b8d063a..f5a7fbddc69a4c862ae8df948c947329acc2dd0a 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c +++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c @@ -814,6 +814,97 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd) } +static uint32_t SAI1_client =0; + +void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai) +{ + + GPIO_InitTypeDef GPIO_InitStruct; +/* SAI1 */ + if(hsai->Instance==SAI1_Block_A) + { + /* Peripheral clock enable */ + if (SAI1_client == 0) + { + __HAL_RCC_SAI1_CLK_ENABLE(); + } + SAI1_client ++; + + /**SAI1_A_Block_A GPIO Configuration + PE2 ------> SAI1_MCLK_A + PE4 ------> SAI1_FS_A + PE5 ------> SAI1_SCK_A + PE6 ------> SAI1_SD_A + */ + GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_SAI1; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + } + if(hsai->Instance==SAI1_Block_B) + { + /* Peripheral clock enable */ + if (SAI1_client == 0) + { + __HAL_RCC_SAI1_CLK_ENABLE(); + } + SAI1_client ++; + + /**SAI1_B_Block_B GPIO Configuration + PE3 ------> SAI1_SD_B + */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_SAI1; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + } +} + +void HAL_SAI_MspDeInit(SAI_HandleTypeDef* hsai) +{ + +/* SAI1 */ + if(hsai->Instance==SAI1_Block_A) + { + SAI1_client --; + if (SAI1_client == 0) + { + /* Peripheral clock disable */ + __HAL_RCC_SAI1_CLK_DISABLE(); + } + + /**SAI1_A_Block_A GPIO Configuration + PE2 ------> SAI1_MCLK_A + PE4 ------> SAI1_FS_A + PE5 ------> SAI1_SCK_A + PE6 ------> SAI1_SD_A + */ + HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6); + + } + if(hsai->Instance==SAI1_Block_B) + { + SAI1_client --; + if (SAI1_client == 0) + { + /* Peripheral clock disable */ + __HAL_RCC_SAI1_CLK_DISABLE(); + } + + /**SAI1_B_Block_B GPIO Configuration + PE3 ------> SAI1_SD_B + */ + HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3); + + } +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig index 62c2bc34a6c5b262c8f07e311c762873881bc98b..208a40c0262c4925a5b2aa27ca52953f2b643185 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig +++ b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig @@ -47,6 +47,23 @@ menu "Onboard Peripheral Drivers" select PKG_USING_AHT10_LATEST_VERSION default n + menuconfig BSP_USING_AUDIO + bool "Enable Audio Device" + select RT_USING_AUDIO + select BSP_USING_I2C + select BSP_USING_I2C3 + default n + + if BSP_USING_AUDIO + config BSP_USING_AUDIO_PLAY + bool "Enable Audio Play" + default y + + config BSP_USING_AUDIO_RECORD + bool "Enable Audio Record" + default n + endif + endmenu menu "On-chip Peripheral Drivers" diff --git a/bsp/stm32/stm32l475-atk-pandora/board/SConscript b/bsp/stm32/stm32l475-atk-pandora/board/SConscript index a525708b6516f3a46454f9b032dfb22081e496ea..859d01d6b1fd59e24cb9c61b6be1b6e379999680 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/SConscript +++ b/bsp/stm32/stm32l475-atk-pandora/board/SConscript @@ -21,10 +21,20 @@ if GetDepend(['BSP_USING_SDCARD']): if GetDepend(['BSP_USING_ICM20608']) or GetDepend(['BSP_USING_AHT10']): src += Glob('ports/sensor_port.c') +if GetDepend(['BSP_USING_AUDIO']): + src += Glob('ports/audio/drv_es8388.c') + src += Glob('ports/audio/drv_sound.c') + +if GetDepend(['BSP_USING_AUDIO_RECORD']): + src += Glob('ports/audio/drv_mic.c') + path = [cwd] path += [cwd + '/CubeMX_Config/Inc'] path += [cwd + '/ports'] +if GetDepend(['BSP_USING_AUDIO']): + path += [cwd + '/ports/audio'] + startup_path_prefix = SDK_LIB if rtconfig.CROSS_TOOL == 'gcc': diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.c b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.c new file mode 100644 index 0000000000000000000000000000000000000000..fe115eb5939ea01f0c26653cc0f71184cd7dea38 --- /dev/null +++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-31 Zero-Free first implementation + */ + +#include +#include +#include "drv_es8388.h" + +/* ES8388 address */ +#define ES8388_ADDR 0x10 /*0x11:CE=1;0x10:CE=0*/ + +struct es8388_device +{ + struct rt_i2c_bus_device *i2c; + rt_uint16_t pin; +}; + +static struct es8388_device es_dev = {0}; + +static rt_uint16_t reg_read(rt_uint8_t addr) +{ + struct rt_i2c_msg msg[2] = {0}; + uint8_t val = 0xff; + + RT_ASSERT(es_dev.i2c != RT_NULL); + + msg[0].addr = ES8388_ADDR; + msg[0].flags = RT_I2C_WR; + msg[0].len = 1; + msg[0].buf = &addr; + + msg[1].addr = ES8388_ADDR; + msg[1].flags = RT_I2C_RD; + msg[1].len = 1; + msg[1].buf = &val; + + if (rt_i2c_transfer(es_dev.i2c, msg, 2) != 2) + { + rt_kprintf("I2C read data failed, reg = 0x%02x. \n", addr); + return 0xff; + } + + return val; +} + +static void reg_write(rt_uint8_t addr, rt_uint8_t val) +{ + struct rt_i2c_msg msgs[1] = {0}; + rt_uint8_t buff[2] = {0}; + + RT_ASSERT(es_dev.i2c != RT_NULL); + + buff[0] = addr; + buff[1] = val; + + msgs[0].addr = ES8388_ADDR; + msgs[0].flags = RT_I2C_WR; + msgs[0].buf = buff; + msgs[0].len = 2; + + if (rt_i2c_transfer(es_dev.i2c, msgs, 1) != 1) + { + rt_kprintf("I2C write data failed, reg = 0x%2x. \n", addr); + return; + } +} + +static int es8388_set_adc_dac_volume(int mode, int volume, int dot) +{ + int res = 0; + if (volume < -96 || volume > 0) + { + if (volume < -96) + volume = -96; + else + volume = 0; + } + dot = (dot >= 5 ? 1 : 0); + volume = (-volume << 1) + dot; + if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC) + { + reg_write(ES8388_ADCCONTROL8, volume); + reg_write(ES8388_ADCCONTROL9, volume); //ADC Right Volume=0db + } + if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC) + { + reg_write(ES8388_DACCONTROL5, volume); + reg_write(ES8388_DACCONTROL4, volume); + } + return res; +} + +void es8388_set_voice_mute(rt_bool_t enable) +{ + uint8_t reg = 0; + + reg = reg_read(ES8388_DACCONTROL3); + reg = reg & 0xFB; + reg_write(ES8388_DACCONTROL3, reg | (((int)enable) << 2)); +} + +rt_err_t es8388_init(const char *i2c_name, rt_uint16_t pin) +{ + es_dev.i2c = rt_i2c_bus_device_find(i2c_name); + if (es_dev.i2c == RT_NULL) + { + rt_kprintf("%s bus not found\n", i2c_name); + return -RT_ERROR; + } + + es_dev.pin = pin; + + reg_write(ES8388_DACCONTROL3, 0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and disabled digital volume control soft ramp + /* Chip Control and Power Management */ + reg_write(ES8388_CONTROL2, 0x50); + reg_write(ES8388_CHIPPOWER, 0x00); //normal all and power up all + reg_write(ES8388_MASTERMODE, 0x00); //TODO:CODEC IN I2S SLAVE MODE + + /* dac */ + reg_write(ES8388_DACPOWER, 0xC0); //disable DAC and disable Lout/Rout/1/2 + reg_write(ES8388_CONTROL1, 0x12); //Enfr=0,Play&Record Mode,(0x17-both of mic&paly) + // reg_write(ES8388_CONTROL2, 0); //LPVrefBuf=0,Pdn_ana=0 + reg_write(ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24 + reg_write(ES8388_DACCONTROL2, 0x02); //DACFsMode,SINGLE SPEED; DACFsRatio,256 + reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 + reg_write(ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db + reg_write(ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db + reg_write(ES8388_DACCONTROL21, 0x80); //set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK + reg_write(ES8388_DACCONTROL23, 0x00); //vroi=0 + es8388_set_adc_dac_volume(ES_MODE_DAC, 0, 0); // 0db + + reg_write(ES8388_DACPOWER, 0x3c); //0x3c Enable DAC and Enable Lout/Rout/1/2 + /* adc */ + reg_write(ES8388_ADCPOWER, 0xFF); + reg_write(ES8388_ADCCONTROL1, 0xbb); // MIC Left and Right channel PGA gain + reg_write(ES8388_ADCCONTROL2, 0x00); //0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input; DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1 + reg_write(ES8388_ADCCONTROL3, 0x02); + reg_write(ES8388_ADCCONTROL4, 0x0d); // Left/Right data, Left/Right justified mode, Bits length, I2S format + reg_write(ES8388_ADCCONTROL5, 0x02); //ADCFsMode,singel SPEED,RATIO=256 + //ALC for Microphone + es8388_set_adc_dac_volume(ES_MODE_ADC, 0, 0); // 0db + reg_write(ES8388_ADCPOWER, 0x09); //Power on ADC, Enable LIN&RIN, Power off MICBIAS, set int1lp to low power mode + /* enable es8388 PA */ + es8388_pa_power(RT_TRUE); + + return RT_EOK; +} + +rt_err_t es8388_start(enum es8388_mode mode) +{ + int res = 0; + uint8_t prev_data = 0, data = 0; + + prev_data = reg_read(ES8388_DACCONTROL21); + if (mode == ES_MODE_LINE) + { + reg_write(ES8388_DACCONTROL16, 0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable + reg_write(ES8388_DACCONTROL17, 0x50); // left DAC to left mixer enable and LIN signal to left mixer enable 0db : bupass enable + reg_write(ES8388_DACCONTROL20, 0x50); // right DAC to right mixer enable and LIN signal to right mixer enable 0db : bupass enable + reg_write(ES8388_DACCONTROL21, 0xC0); //enable adc + } + else + { + reg_write(ES8388_DACCONTROL21, 0x80); //enable dac + } + data = reg_read(ES8388_DACCONTROL21); + + if (prev_data != data) + { + reg_write(ES8388_CHIPPOWER, 0xF0); //start state machine + // reg_write(ES8388_ADDR, ES8388_CONTROL1, 0x16); + // reg_write(ES8388_ADDR, ES8388_CONTROL2, 0x50); + reg_write(ES8388_CHIPPOWER, 0x00); //start state machine + } + if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE) + { + reg_write(ES8388_ADCPOWER, 0x00); //power up adc and line in + } + if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE) + { + reg_write(ES8388_DACPOWER, 0x3c); //power up dac and line out + es8388_set_voice_mute(RT_FALSE); + } + + return res; +} + +rt_err_t es8388_stop(enum es8388_mode mode) +{ + int res = 0; + if (mode == ES_MODE_LINE) + { + reg_write(ES8388_DACCONTROL21, 0x80); //enable dac + reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 + reg_write(ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db + reg_write(ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db + return res; + } + if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC) + { + reg_write(ES8388_DACPOWER, 0x00); + es8388_set_voice_mute(RT_TRUE); //res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); // 0db + // reg_write(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //power down dac and line out + } + if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC) + { + // Es8388SetAdcDacVolume(ES_MODULE_ADC, -96, 5); // 0db + reg_write(ES8388_ADCPOWER, 0xFF); //power down adc and line in + } + if (mode == ES_MODE_DAC_ADC) + { + reg_write(ES8388_DACCONTROL21, 0x9C); //disable mclk + // reg_write(ES8388_CONTROL1, 0x00); + // reg_write(ES8388_CONTROL2, 0x58); + // reg_write(ES8388_CHIPPOWER, 0xF3); //stop state machine + } + + return RT_EOK; +} + +rt_err_t es8388_fmt_set(enum es8388_mode mode, enum es8388_format fmt) +{ + uint8_t reg = 0; + + if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC) + { + reg = reg_read(ES8388_ADCCONTROL4); + reg = reg & 0xfc; + reg_write(ES8388_ADCCONTROL4, reg | fmt); + } + if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC) + { + reg = reg_read(ES8388_DACCONTROL1); + reg = reg & 0xf9; + reg_write(ES8388_DACCONTROL1, reg | (fmt << 1)); + } + + return RT_EOK; +} + +void es8388_volume_set(rt_uint8_t volume) +{ + if (volume > 100) + volume = 100; + volume /= 3; + + reg_write(ES8388_DACCONTROL24, volume); + reg_write(ES8388_DACCONTROL25, volume); +} + +rt_uint8_t es8388_volume_get(void) +{ + rt_uint8_t volume; + + volume = reg_read(ES8388_DACCONTROL24); + if (volume == 0xff) + { + volume = 0; + } + else + { + volume *= 3; + if (volume == 99) + volume = 100; + } + + return volume; +} + +void es8388_pa_power(rt_bool_t enable) +{ + rt_pin_mode(es_dev.pin, PIN_MODE_OUTPUT); + + if (enable) + { + rt_pin_write(es_dev.pin, PIN_HIGH); + } + else + { + rt_pin_write(es_dev.pin, PIN_LOW); + } +} diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.h b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.h new file mode 100644 index 0000000000000000000000000000000000000000..472c844fca8783fe29e39a7d9e94fff50f24689a --- /dev/null +++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_es8388.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-31 Zero-Free first implementation + */ + +#ifndef __DRV_ES8388_H__ +#define __DRV_ES8388_H__ + +/* ES8388 register space */ +#define ES8388_CONTROL1 0x00 +#define ES8388_CONTROL2 0x01 +#define ES8388_CHIPPOWER 0x02 +#define ES8388_ADCPOWER 0x03 +#define ES8388_DACPOWER 0x04 +#define ES8388_CHIPLOPOW1 0x05 +#define ES8388_CHIPLOPOW2 0x06 +#define ES8388_ANAVOLMANAG 0x07 +#define ES8388_MASTERMODE 0x08 +#define ES8388_ADCCONTROL1 0x09 +#define ES8388_ADCCONTROL2 0x0a +#define ES8388_ADCCONTROL3 0x0b +#define ES8388_ADCCONTROL4 0x0c +#define ES8388_ADCCONTROL5 0x0d +#define ES8388_ADCCONTROL6 0x0e +#define ES8388_ADCCONTROL7 0x0f +#define ES8388_ADCCONTROL8 0x10 +#define ES8388_ADCCONTROL9 0x11 +#define ES8388_ADCCONTROL10 0x12 +#define ES8388_ADCCONTROL11 0x13 +#define ES8388_ADCCONTROL12 0x14 +#define ES8388_ADCCONTROL13 0x15 +#define ES8388_ADCCONTROL14 0x16 + +#define ES8388_DACCONTROL1 0x17 +#define ES8388_DACCONTROL2 0x18 +#define ES8388_DACCONTROL3 0x19 +#define ES8388_DACCONTROL4 0x1a +#define ES8388_DACCONTROL5 0x1b +#define ES8388_DACCONTROL6 0x1c +#define ES8388_DACCONTROL7 0x1d +#define ES8388_DACCONTROL8 0x1e +#define ES8388_DACCONTROL9 0x1f +#define ES8388_DACCONTROL10 0x20 +#define ES8388_DACCONTROL11 0x21 +#define ES8388_DACCONTROL12 0x22 +#define ES8388_DACCONTROL13 0x23 +#define ES8388_DACCONTROL14 0x24 +#define ES8388_DACCONTROL15 0x25 +#define ES8388_DACCONTROL16 0x26 +#define ES8388_DACCONTROL17 0x27 +#define ES8388_DACCONTROL18 0x28 +#define ES8388_DACCONTROL19 0x29 +#define ES8388_DACCONTROL20 0x2a +#define ES8388_DACCONTROL21 0x2b +#define ES8388_DACCONTROL22 0x2c +#define ES8388_DACCONTROL23 0x2d +#define ES8388_DACCONTROL24 0x2e +#define ES8388_DACCONTROL25 0x2f +#define ES8388_DACCONTROL26 0x30 +#define ES8388_DACCONTROL27 0x31 +#define ES8388_DACCONTROL28 0x32 +#define ES8388_DACCONTROL29 0x33 +#define ES8388_DACCONTROL30 0x34 + +enum es8388_mode +{ + ES_MODE_NONE = 0x00, + ES_MODE_DAC = 0x01, + ES_MODE_ADC = 0x02, + ES_MODE_DAC_ADC = 0x03, + ES_MODE_LINE = 0x04, + ES_MODE_MAX = 0x06, +}; + +enum es8388_format +{ + ES_FMT_NORMAL = 0, + ES_FMT_LEFT = 1, + ES_FMT_RIGHT = 2, + ES_FMT_DSP = 3, +}; + +rt_err_t es8388_init(const char *i2c_name, rt_uint16_t pin); +rt_err_t es8388_start(enum es8388_mode mode); +rt_err_t es8388_stop(enum es8388_mode mode); +rt_err_t es8388_fmt_set(enum es8388_mode mode, enum es8388_format fmt); +void es8388_volume_set(rt_uint8_t volume); +rt_uint8_t es8388_volume_get(void); +void es8388_pa_power(rt_bool_t enable); + +#endif diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_mic.c b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_mic.c new file mode 100644 index 0000000000000000000000000000000000000000..c4ea570dd790ba8a19c13ec7e7f3e5f6e5408764 --- /dev/null +++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_mic.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-31 Zero-Free first implementation + */ + +#include + +#include "drv_es8388.h" + +#define DBG_TAG "drv.mic" +#define DBG_LVL DBG_INFO +#include + +#define RX_FIFO_SIZE (1024) + +struct mic_device +{ + struct rt_audio_device audio; + struct rt_audio_configure record_config; + rt_uint8_t *rx_fifo; + rt_uint8_t volume; +}; + +static struct mic_device mic_dev = {0}; +static rt_uint16_t zero_frame[2] = {0}; + +static SAI_HandleTypeDef SAI1B_Handler = {0}; +static DMA_HandleTypeDef SAI1_RXDMA_Handler = {0}; + +extern SAI_HandleTypeDef SAI1A_Handler; +extern DMA_HandleTypeDef SAI1_RXDMA_Handler; +extern void SAIA_Frequency_Set(uint32_t frequency); + +void SAIB_Init(void) +{ + HAL_SAI_DeInit(&SAI1B_Handler); + + SAI1B_Handler.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K; + SAI1B_Handler.Instance = SAI1_Block_B; + SAI1B_Handler.Init.AudioMode = SAI_MODESLAVE_RX; + SAI1B_Handler.Init.Synchro = SAI_SYNCHRONOUS; + SAI1B_Handler.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE; + SAI1B_Handler.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; + SAI1B_Handler.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; + SAI1B_Handler.Init.MonoStereoMode = SAI_MONOMODE; + SAI1B_Handler.Init.Protocol = SAI_FREE_PROTOCOL; + SAI1B_Handler.Init.DataSize = SAI_DATASIZE_16; + SAI1B_Handler.Init.FirstBit = SAI_FIRSTBIT_MSB; + SAI1B_Handler.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; + + SAI1B_Handler.FrameInit.FrameLength = 64; + SAI1B_Handler.FrameInit.ActiveFrameLength = 32; + SAI1B_Handler.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; + SAI1B_Handler.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; + SAI1B_Handler.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; + SAI1B_Handler.SlotInit.FirstBitOffset = 0; + SAI1B_Handler.SlotInit.SlotSize = SAI_SLOTSIZE_32B; + SAI1B_Handler.SlotInit.SlotNumber = 2; + SAI1B_Handler.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1; + + HAL_SAI_Init(&SAI1B_Handler); + __HAL_SAI_ENABLE(&SAI1B_Handler); + + /* Configure DMA used for SAI1 */ + __HAL_RCC_DMA2_CLK_ENABLE(); + + SAI1_RXDMA_Handler.Init.Request = DMA_REQUEST_1; + SAI1_RXDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY; + SAI1_RXDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; + SAI1_RXDMA_Handler.Init.MemInc = DMA_MINC_ENABLE; + SAI1_RXDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + SAI1_RXDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + SAI1_RXDMA_Handler.Init.Mode = DMA_CIRCULAR; + SAI1_RXDMA_Handler.Init.Priority = DMA_PRIORITY_HIGH; + SAI1_RXDMA_Handler.Instance = DMA2_Channel2; + __HAL_LINKDMA(&SAI1B_Handler, hdmarx, SAI1_RXDMA_Handler); + HAL_DMA_DeInit(&SAI1_RXDMA_Handler); + HAL_DMA_Init(&SAI1_RXDMA_Handler); + __HAL_DMA_ENABLE(&SAI1_RXDMA_Handler); + + HAL_NVIC_SetPriority(DMA2_Channel2_IRQn, 0x01, 0); + HAL_NVIC_EnableIRQ(DMA2_Channel2_IRQn); +} + +void SAIB_Channels_Set(uint8_t channels) +{ + if (channels == 1) + { + SAI1B_Handler.Init.MonoStereoMode = SAI_MONOMODE; + } + else + { + SAI1B_Handler.Init.MonoStereoMode = SAI_STEREOMODE; + } + + __HAL_SAI_DISABLE(&SAI1B_Handler); + HAL_SAI_Init(&SAI1B_Handler); + __HAL_SAI_ENABLE(&SAI1B_Handler); +} + +void DMA2_Channel2_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&SAI1_RXDMA_Handler); +} + +void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) +{ + rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[0], RX_FIFO_SIZE / 2); +} + +void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) +{ + rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[RX_FIFO_SIZE / 2], RX_FIFO_SIZE / 2); +} + +static rt_err_t mic_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps) +{ + rt_err_t result = RT_EOK; + struct mic_device *mic_dev; + + RT_ASSERT(audio != RT_NULL); + mic_dev = (struct mic_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_INPUT | AUDIO_TYPE_MIXER; + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_INPUT: /* Provide capabilities of INPUT unit */ + { + switch (caps->sub_type) + { + case AUDIO_DSP_PARAM: + caps->udata.config.samplerate = mic_dev->record_config.samplerate; + caps->udata.config.channels = mic_dev->record_config.channels; + caps->udata.config.samplebits = mic_dev->record_config.samplebits; + break; + + case AUDIO_DSP_SAMPLERATE: + caps->udata.config.samplerate = mic_dev->record_config.samplerate; + break; + + case AUDIO_DSP_CHANNELS: + caps->udata.config.channels = mic_dev->record_config.channels; + break; + + case AUDIO_DSP_SAMPLEBITS: + caps->udata.config.samplebits = mic_dev->record_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 | AUDIO_MIXER_LINE; + break; + + case AUDIO_MIXER_VOLUME: + caps->udata.value = mic_dev->volume; + break; + + case AUDIO_MIXER_LINE: + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + default: + result = -RT_ERROR; + break; + } + + return result; +} + +static rt_err_t mic_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps) +{ + rt_err_t result = RT_EOK; + struct mic_device *mic_dev; + + RT_ASSERT(audio != RT_NULL); + mic_dev = (struct mic_device *)audio->parent.user_data; + + switch (caps->main_type) + { + case AUDIO_TYPE_MIXER: + { + switch (caps->sub_type) + { + case AUDIO_MIXER_VOLUME: + { + rt_uint32_t volume = caps->udata.value; + mic_dev->volume = volume; + LOG_D("set volume %d", volume); + break; + } + + default: + result = -RT_ERROR; + break; + } + + break; + } + + case AUDIO_TYPE_INPUT: + { + switch (caps->sub_type) + { + case AUDIO_DSP_PARAM: + { + SAIA_Frequency_Set(caps->udata.config.samplerate); + HAL_SAI_DMAStop(&SAI1B_Handler); + SAIB_Channels_Set(caps->udata.config.channels); + HAL_SAI_Transmit(&SAI1A_Handler, (uint8_t *)&zero_frame[0], 2, 0); + HAL_SAI_Receive_DMA(&SAI1B_Handler, mic_dev->rx_fifo, RX_FIFO_SIZE / 2); + + /* save configs */ + mic_dev->record_config.samplerate = caps->udata.config.samplerate; + mic_dev->record_config.channels = caps->udata.config.channels; + mic_dev->record_config.samplebits = caps->udata.config.samplebits; + LOG_D("set samplerate %d", mic_dev->record_config.samplerate); + LOG_D("set channels %d", mic_dev->record_config.channels); + break; + } + + case AUDIO_DSP_SAMPLERATE: + { + mic_dev->record_config.samplerate = caps->udata.config.samplerate; + LOG_D("set channels %d", mic_dev->record_config.channels); + break; + } + + case AUDIO_DSP_CHANNELS: + { + mic_dev->record_config.channels = caps->udata.config.channels; + LOG_D("set channels %d", mic_dev->record_config.channels); + break; + } + + default: + break; + } + + break; + } + + default: + break; + } + + return result; +} + +static rt_err_t mic_init(struct rt_audio_device *audio) +{ + struct mic_device *mic_dev; + + RT_ASSERT(audio != RT_NULL); + mic_dev = (struct mic_device *)audio->parent.user_data; + + SAIB_Init(); + + /* set default params */ + SAIB_Channels_Set(mic_dev->record_config.channels); + + return RT_EOK; +} + +static rt_err_t mic_start(struct rt_audio_device *audio, int stream) +{ + struct mic_device *mic_dev; + + RT_ASSERT(audio != RT_NULL); + mic_dev = (struct mic_device *)audio->parent.user_data; + + if (stream == AUDIO_STREAM_RECORD) + { + es8388_start(ES_MODE_ADC); + HAL_SAI_Transmit(&SAI1A_Handler, (uint8_t *)&zero_frame[0], 2, 0); + HAL_SAI_Receive_DMA(&SAI1B_Handler, mic_dev->rx_fifo, RX_FIFO_SIZE / 2); + } + + return RT_EOK; +} + +static rt_err_t mic_stop(struct rt_audio_device *audio, int stream) +{ + if (stream == AUDIO_STREAM_RECORD) + { + HAL_SAI_DMAStop(&SAI1B_Handler); + HAL_SAI_Abort(&SAI1A_Handler); + es8388_stop(ES_MODE_ADC); + } + + return RT_EOK; +} + +static struct rt_audio_ops mic_ops = +{ + .getcaps = mic_getcaps, + .configure = mic_configure, + .init = mic_init, + .start = mic_start, + .stop = mic_stop, + .transmit = RT_NULL, + .buffer_info = RT_NULL, +}; + +int rt_hw_mic_init(void) +{ + rt_uint8_t *rx_fifo; + + if (mic_dev.rx_fifo) + return RT_EOK; + + rx_fifo = rt_malloc(RX_FIFO_SIZE); + if (rx_fifo == RT_NULL) + return -RT_ENOMEM; + rt_memset(rx_fifo, 0, RX_FIFO_SIZE); + mic_dev.rx_fifo = rx_fifo; + + /* init default configuration */ + { + mic_dev.record_config.samplerate = 44100; + mic_dev.record_config.channels = 2; + mic_dev.record_config.samplebits = 16; + mic_dev.volume = 55; + } + + /* register sound device */ + mic_dev.audio.ops = &mic_ops; + rt_audio_register(&mic_dev.audio, "mic0", RT_DEVICE_FLAG_RDONLY, &mic_dev); + + return RT_EOK; +} + +INIT_DEVICE_EXPORT(rt_hw_mic_init); diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c new file mode 100644 index 0000000000000000000000000000000000000000..bccf9c62db01b4ea50f97247bdcac001086f8075 --- /dev/null +++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.c @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-31 Zero-Free first implementation + */ + +#include + +#include "drv_sound.h" +#include "drv_es8388.h" + +#define DBG_TAG "drv.sound" +#define DBG_LVL DBG_INFO +#include + +#define TX_FIFO_SIZE (2048) + +struct sound_device +{ + struct rt_audio_device audio; + struct rt_audio_configure replay_config; + rt_uint8_t *tx_fifo; + rt_uint8_t volume; +}; + +static struct sound_device snd_dev = {0}; +SAI_HandleTypeDef SAI1A_Handler = {0}; +DMA_HandleTypeDef SAI1_TXDMA_Handler = {0}; + +static void SAIA_Init(void) +{ + RCC_PeriphCLKInitTypeDef PeriphClkInit; + + /* Configure and enable PLLSAI1 clock to generate 45.714286MHz */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1; + PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2; + PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_HSE; + PeriphClkInit.PLLSAI2.PLLSAI2M = 1; + PeriphClkInit.PLLSAI2.PLLSAI2N = 40; + PeriphClkInit.PLLSAI2.PLLSAI2P = RCC_PLLP_DIV7; + PeriphClkInit.PLLSAI2.PLLSAI2R = RCC_PLLR_DIV2; + PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + HAL_SAI_DeInit(&SAI1A_Handler); + SAI1A_Handler.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K; + SAI1A_Handler.Instance = SAI1_Block_A; + SAI1A_Handler.Init.AudioMode = SAI_MODEMASTER_TX; + SAI1A_Handler.Init.Synchro = SAI_ASYNCHRONOUS; + SAI1A_Handler.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE; + SAI1A_Handler.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; + SAI1A_Handler.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; + SAI1A_Handler.Init.MonoStereoMode = SAI_STEREOMODE; + SAI1A_Handler.Init.Protocol = SAI_FREE_PROTOCOL; + SAI1A_Handler.Init.DataSize = SAI_DATASIZE_16; + SAI1A_Handler.Init.FirstBit = SAI_FIRSTBIT_MSB; + SAI1A_Handler.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; + + SAI1A_Handler.FrameInit.FrameLength = 64; + SAI1A_Handler.FrameInit.ActiveFrameLength = 32; + SAI1A_Handler.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; + SAI1A_Handler.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; + SAI1A_Handler.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; + SAI1A_Handler.SlotInit.FirstBitOffset = 0; + SAI1A_Handler.SlotInit.SlotSize = SAI_SLOTSIZE_32B; + SAI1A_Handler.SlotInit.SlotNumber = 2; + SAI1A_Handler.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1; + + HAL_SAI_Init(&SAI1A_Handler); + __HAL_SAI_ENABLE(&SAI1A_Handler); + + /* Configure DMA used for SAI1 */ + __HAL_RCC_DMA2_CLK_ENABLE(); + + SAI1_TXDMA_Handler.Init.Request = DMA_REQUEST_1; + SAI1_TXDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH; + SAI1_TXDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; + SAI1_TXDMA_Handler.Init.MemInc = DMA_MINC_ENABLE; + SAI1_TXDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + SAI1_TXDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + SAI1_TXDMA_Handler.Init.Mode = DMA_CIRCULAR; + SAI1_TXDMA_Handler.Init.Priority = DMA_PRIORITY_HIGH; + SAI1_TXDMA_Handler.Instance = DMA2_Channel1; + __HAL_LINKDMA(&SAI1A_Handler, hdmatx, SAI1_TXDMA_Handler); + HAL_DMA_DeInit(&SAI1_TXDMA_Handler); + HAL_DMA_Init(&SAI1_TXDMA_Handler); + __HAL_DMA_ENABLE(&SAI1_TXDMA_Handler); + + HAL_NVIC_SetPriority(DMA2_Channel1_IRQn, 0x01, 0); + HAL_NVIC_EnableIRQ(DMA2_Channel1_IRQn); +} + +void DMA2_Channel1_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&SAI1_TXDMA_Handler); +} + +void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai) +{ + if (hsai == &SAI1A_Handler) + { + rt_audio_tx_complete(&snd_dev.audio); + } +} + +void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai) +{ + if (hsai == &SAI1A_Handler) + { + rt_audio_tx_complete(&snd_dev.audio); + } +} + +void SAIA_Frequency_Set(uint32_t frequency) +{ + RCC_PeriphCLKInitTypeDef PeriphClkInit; + + HAL_RCCEx_GetPeriphCLKConfig(&PeriphClkInit); + + if ((frequency == SAI_AUDIO_FREQUENCY_11K) || (frequency == SAI_AUDIO_FREQUENCY_22K) || (frequency == SAI_AUDIO_FREQUENCY_44K)) + { + /* Configure and enable PLLSAI1 clock to generate 45.714286MHz */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1; + PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2; + PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_HSE; + PeriphClkInit.PLLSAI2.PLLSAI2M = 1; + PeriphClkInit.PLLSAI2.PLLSAI2N = 40; + PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + } + else + { + /* Configure and enable PLLSAI1 clock to generate 49.142857MHz */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1; + PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2; + PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_HSE; + PeriphClkInit.PLLSAI2.PLLSAI2M = 1; + PeriphClkInit.PLLSAI2.PLLSAI2N = 43; + PeriphClkInit.PLLSAI2.PLLSAI2P = RCC_PLLP_DIV7; + PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + } + + /* Disable SAI peripheral to allow access to SAI internal registers */ + __HAL_SAI_DISABLE(&SAI1A_Handler); + /* Update the SAI audio frequency configuration */ + SAI1A_Handler.Init.AudioFrequency = frequency; + HAL_SAI_Init(&SAI1A_Handler); + /* Enable SAI peripheral to generate MCLK */ + __HAL_SAI_ENABLE(&SAI1A_Handler); +} + +void SAIA_Channels_Set(uint8_t channels) +{ + if (channels == 1) + { + SAI1A_Handler.Init.MonoStereoMode = SAI_MONOMODE; + } + else + { + SAI1A_Handler.Init.MonoStereoMode = SAI_STEREOMODE; + } + + __HAL_SAI_DISABLE(&SAI1A_Handler); + HAL_SAI_Init(&SAI1A_Handler); + __HAL_SAI_ENABLE(&SAI1A_Handler); +} + +/** + * RT-Thread Audio Device Driver Interface + */ +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_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 = es8388_volume_get(); + break; + + default: + result = -RT_ERROR; + break; + } + + break; + } + + default: + result = -RT_ERROR; + break; + } + + return result; +} + +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_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; + + es8388_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 result; +} + +static rt_err_t sound_init(struct rt_audio_device *audio) +{ + rt_err_t result = RT_EOK; + struct sound_device *snd_dev; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + es8388_init("i2c3", GET_PIN(A, 5)); + SAIA_Init(); + + /* set default params */ + SAIA_Frequency_Set(snd_dev->replay_config.samplerate); + SAIA_Channels_Set(snd_dev->replay_config.channels); + + return result; +} + +static rt_err_t sound_start(struct rt_audio_device *audio, int stream) +{ + struct sound_device *snd_dev; + + RT_ASSERT(audio != RT_NULL); + snd_dev = (struct sound_device *)audio->parent.user_data; + + if (stream == AUDIO_STREAM_REPLAY) + { + LOG_D("open sound device"); + es8388_start(ES_MODE_DAC); + HAL_SAI_Transmit_DMA(&SAI1A_Handler, snd_dev->tx_fifo, TX_FIFO_SIZE / 2); + } + + return RT_EOK; +} + +static rt_err_t sound_stop(struct rt_audio_device *audio, int stream) +{ + RT_ASSERT(audio != RT_NULL); + + if (stream == AUDIO_STREAM_REPLAY) + { + HAL_SAI_DMAStop(&SAI1A_Handler); + es8388_stop(ES_MODE_DAC); + LOG_D("close sound device"); + } + + return RT_EOK; +} + +static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info) +{ + struct sound_device *snd_dev; + + 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 snd_ops = +{ + .getcaps = sound_getcaps, + .configure = sound_configure, + .init = sound_init, + .start = sound_start, + .stop = sound_stop, + .transmit = RT_NULL, + .buffer_info = sound_buffer_info, +}; + +int rt_hw_sound_init(void) +{ + rt_uint8_t *tx_fifo; + + if (snd_dev.tx_fifo) + return RT_EOK; + + tx_fifo = rt_malloc(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; + + /* init default configuration */ + { + snd_dev.replay_config.samplerate = 44100; + snd_dev.replay_config.channels = 2; + snd_dev.replay_config.samplebits = 16; + snd_dev.volume = 55; + } + + /* register sound device */ + snd_dev.audio.ops = &snd_ops; + rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev); + + return RT_EOK; +} + +INIT_DEVICE_EXPORT(rt_hw_sound_init); diff --git a/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.h b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.h new file mode 100644 index 0000000000000000000000000000000000000000..4dc76631c753c09dd58de5c4046e674c77937fc5 --- /dev/null +++ b/bsp/stm32/stm32l475-atk-pandora/board/ports/audio/drv_sound.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2019-07-31 Zero-Free first implementation + */ + +#ifndef __DRV_SOUND_H__ +#define __DRV_SOUND_H__ + +int rt_hw_sound_init(void); +int rt_hw_mic_init(void); + +#endif