mirror of
https://github.com/Fishwaldo/bl_mcu_sdk.git
synced 2025-07-23 05:08:45 +00:00
[sync] sync from internal repo
* use nuttx libc, disable system libc * use tlsf as default * update lhal flash driver * add example readme * add flash ini for new flash tool * add fw header for new flash tool
This commit is contained in:
parent
89592fc9a3
commit
356f258e83
554 changed files with 79150 additions and 46596 deletions
9
examples/peripherals/i2s/i2s_dma/CMakeLists.txt
Executable file
9
examples/peripherals/i2s/i2s_dma/CMakeLists.txt
Executable file
|
@ -0,0 +1,9 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
include(proj.conf)
|
||||
|
||||
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
|
||||
|
||||
sdk_set_main_file(main.c)
|
||||
|
||||
project(spi_dma)
|
13
examples/peripherals/i2s/i2s_dma/Makefile
Executable file
13
examples/peripherals/i2s/i2s_dma/Makefile
Executable file
|
@ -0,0 +1,13 @@
|
|||
SDK_DEMO_PATH ?= .
|
||||
BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../..
|
||||
|
||||
export BL_SDK_BASE
|
||||
|
||||
CHIP ?= bl616
|
||||
BOARD ?= bl616dk
|
||||
CROSS_COMPILE ?= riscv64-unknown-elf-
|
||||
|
||||
# add custom cmake definition
|
||||
#cmake_definition+=-Dxxx=sss
|
||||
|
||||
include $(BL_SDK_BASE)/project.build
|
22
examples/peripherals/i2s/i2s_dma/README.md
Normal file
22
examples/peripherals/i2s/i2s_dma/README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# i2s_dma
|
||||
|
||||
|
||||
## Support CHIP
|
||||
|
||||
| CHIP | Remark |
|
||||
|:----------------:|:------:|
|
||||
|BL616/BL618 | |
|
||||
|
||||
## Compile
|
||||
|
||||
- BL616/BL618
|
||||
|
||||
```
|
||||
make CHIP=bl616 BOARD=bl616dk
|
||||
```
|
||||
|
||||
## Flash
|
||||
|
||||
```
|
||||
make flash CHIP=chip_name COMX=xxx # xxx is your com name
|
||||
```
|
11
examples/peripherals/i2s/i2s_dma/flash_prog_cfg.ini
Normal file
11
examples/peripherals/i2s/i2s_dma/flash_prog_cfg.ini
Normal file
|
@ -0,0 +1,11 @@
|
|||
[cfg]
|
||||
# 0: no erase, 1:programmed section erase, 2: chip erase
|
||||
erase = 1
|
||||
# skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated
|
||||
skip_mode = 0x0, 0x0
|
||||
# 0: not use isp mode, #1: isp mode
|
||||
boot2_isp_mode = 0
|
||||
|
||||
[FW]
|
||||
filedir = ./build/build_out/i2s*_$(CHIPNAME).bin
|
||||
address = 0x000000
|
128
examples/peripherals/i2s/i2s_dma/main.c
Executable file
128
examples/peripherals/i2s/i2s_dma/main.c
Executable file
|
@ -0,0 +1,128 @@
|
|||
#include "bflb_mtimer.h"
|
||||
#include "bflb_i2s.h"
|
||||
#include "bflb_dma.h"
|
||||
#include "bflb_gpio.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "bflb_clock.h"
|
||||
|
||||
struct bflb_device_s *i2s0;
|
||||
struct bflb_device_s *dma0_ch0;
|
||||
struct bflb_device_s *dma0_ch1;
|
||||
|
||||
static ATTR_NOCACHE_NOINIT_RAM_SECTION uint16_t tx_buffer[256];
|
||||
static ATTR_NOCACHE_NOINIT_RAM_SECTION uint16_t rx_buffer[256];
|
||||
|
||||
static volatile uint8_t dma_tc_flag0 = 0;
|
||||
static volatile uint8_t dma_tc_flag1 = 0;
|
||||
|
||||
void dma0_ch0_isr(void *arg)
|
||||
{
|
||||
dma_tc_flag0++;
|
||||
printf("tc done\r\n");
|
||||
}
|
||||
|
||||
void dma0_ch1_isr(void *arg)
|
||||
{
|
||||
dma_tc_flag1++;
|
||||
printf("rx done\r\n");
|
||||
}
|
||||
|
||||
void sram_init()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
tx_buffer[i] = i;
|
||||
rx_buffer[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct bflb_dma_channel_lli_pool_s tx_llipool[1];
|
||||
struct bflb_dma_channel_lli_transfer_s tx_transfers[1];
|
||||
struct bflb_dma_channel_lli_pool_s rx_llipool[1];
|
||||
struct bflb_dma_channel_lli_transfer_s rx_transfers[1];
|
||||
|
||||
struct bflb_i2s_config_s i2s_cfg = {
|
||||
.bclk_freq_hz = 32000 * 32 * 2, /* bclk = Sampling_rate * frame_width * channel_num */
|
||||
.role = I2S_ROLE_MASTER,
|
||||
.format_mode = I2S_MODE_LEFT_JUSTIFIED,
|
||||
.channel_mode = I2S_CHANNEL_MODE_NUM_2,
|
||||
.frame_width = I2S_SLOT_WIDTH_32,
|
||||
.data_width = I2S_SLOT_WIDTH_16,
|
||||
.fs_offset_cycle = 0,
|
||||
|
||||
.tx_fifo_threshold = 0,
|
||||
.rx_fifo_threshold = 0,
|
||||
};
|
||||
|
||||
struct bflb_dma_channel_config_s tx_config = {
|
||||
.direction = DMA_MEMORY_TO_PERIPH,
|
||||
.src_req = DMA_REQUEST_NONE,
|
||||
.dst_req = DMA_REQUEST_I2S_TX,
|
||||
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
|
||||
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
|
||||
.src_burst_count = DMA_BURST_INCR1,
|
||||
.dst_burst_count = DMA_BURST_INCR1,
|
||||
.src_width = DMA_DATA_WIDTH_16BIT,
|
||||
.dst_width = DMA_DATA_WIDTH_16BIT,
|
||||
};
|
||||
|
||||
struct bflb_dma_channel_config_s rx_config = {
|
||||
.direction = DMA_PERIPH_TO_MEMORY,
|
||||
.src_req = DMA_REQUEST_I2S_RX,
|
||||
.dst_req = DMA_REQUEST_NONE,
|
||||
.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
|
||||
.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
|
||||
.src_burst_count = DMA_BURST_INCR1,
|
||||
.dst_burst_count = DMA_BURST_INCR1,
|
||||
.src_width = DMA_DATA_WIDTH_16BIT,
|
||||
.dst_width = DMA_DATA_WIDTH_16BIT,
|
||||
};
|
||||
|
||||
board_init();
|
||||
sram_init();
|
||||
/* gpio init */
|
||||
board_i2s_gpio_init();
|
||||
|
||||
i2s0 = bflb_device_get_by_name("i2s0");
|
||||
/* i2s init */
|
||||
bflb_i2s_init(i2s0, &i2s_cfg);
|
||||
/* enable dma */
|
||||
bflb_i2s_link_txdma(i2s0, true);
|
||||
bflb_i2s_link_rxdma(i2s0, true);
|
||||
|
||||
printf("\n\ri2s dma test\n\r");
|
||||
|
||||
dma0_ch0 = bflb_device_get_by_name("dma0_ch0");
|
||||
dma0_ch1 = bflb_device_get_by_name("dma0_ch1");
|
||||
|
||||
bflb_dma_channel_init(dma0_ch0, &tx_config);
|
||||
bflb_dma_channel_init(dma0_ch1, &rx_config);
|
||||
|
||||
bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL);
|
||||
bflb_dma_channel_irq_attach(dma0_ch1, dma0_ch1_isr, NULL);
|
||||
|
||||
tx_transfers[0].src_addr = (uint32_t)tx_buffer;
|
||||
tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_I2S_TDR;
|
||||
tx_transfers[0].nbytes = 256 * 4;
|
||||
|
||||
rx_transfers[0].src_addr = (uint32_t)DMA_ADDR_I2S_RDR;
|
||||
rx_transfers[0].dst_addr = (uint32_t)rx_buffer;
|
||||
rx_transfers[0].nbytes = 256 * 4;
|
||||
|
||||
bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 1, tx_transfers, 1);
|
||||
bflb_dma_channel_lli_reload(dma0_ch1, rx_llipool, 1, rx_transfers, 1);
|
||||
bflb_dma_channel_start(dma0_ch0);
|
||||
bflb_dma_channel_start(dma0_ch1);
|
||||
|
||||
/* enable i2s tx and rx */
|
||||
bflb_i2s_feature_control(i2s0, I2S_CMD_DATA_ENABLE, I2S_CMD_DATA_ENABLE_TX | I2S_CMD_DATA_ENABLE_RX);
|
||||
|
||||
printf("\n\rtest end\n\r");
|
||||
|
||||
while (1) {
|
||||
}
|
||||
}
|
1
examples/peripherals/i2s/i2s_dma/proj.conf
Executable file
1
examples/peripherals/i2s/i2s_dma/proj.conf
Executable file
|
@ -0,0 +1 @@
|
|||
#set(CONFIG_XXX 1)
|
11
examples/peripherals/i2s/i2s_es8388/CMakeLists.txt
Executable file
11
examples/peripherals/i2s/i2s_es8388/CMakeLists.txt
Executable file
|
@ -0,0 +1,11 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
include(proj.conf)
|
||||
|
||||
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
|
||||
|
||||
target_sources(app PRIVATE bsp_es8388.c)
|
||||
|
||||
sdk_set_main_file(main.c)
|
||||
|
||||
project(i2s_es8388)
|
13
examples/peripherals/i2s/i2s_es8388/Makefile
Executable file
13
examples/peripherals/i2s/i2s_es8388/Makefile
Executable file
|
@ -0,0 +1,13 @@
|
|||
SDK_DEMO_PATH ?= .
|
||||
BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../..
|
||||
|
||||
export BL_SDK_BASE
|
||||
|
||||
CHIP ?= bl616
|
||||
BOARD ?= bl616dk
|
||||
CROSS_COMPILE ?= riscv64-unknown-elf-
|
||||
|
||||
# add custom cmake definition
|
||||
#cmake_definition+=-Dxxx=sss
|
||||
|
||||
include $(BL_SDK_BASE)/project.build
|
22
examples/peripherals/i2s/i2s_es8388/README.md
Normal file
22
examples/peripherals/i2s/i2s_es8388/README.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# i2s_es8388
|
||||
|
||||
|
||||
## Support CHIP
|
||||
|
||||
| CHIP | Remark |
|
||||
|:----------------:|:------:|
|
||||
|BL616/BL618 | |
|
||||
|
||||
## Compile
|
||||
|
||||
- BL616/BL618
|
||||
|
||||
```
|
||||
make CHIP=bl616 BOARD=bl616dk
|
||||
```
|
||||
|
||||
## Flash
|
||||
|
||||
```
|
||||
make flash CHIP=chip_name COMX=xxx # xxx is your com name
|
||||
```
|
496
examples/peripherals/i2s/i2s_es8388/bsp_es8388.c
Executable file
496
examples/peripherals/i2s/i2s_es8388/bsp_es8388.c
Executable file
|
@ -0,0 +1,496 @@
|
|||
/**
|
||||
* @file bsp_es8388.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bflb_i2c.h"
|
||||
#include "bsp_es8388.h"
|
||||
|
||||
/** @addtogroup BL702_STD_PERIPH_DRIVER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup ES8388
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ES8388_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define ES8388_I2C_SLAVE_ADDR 0x10
|
||||
|
||||
/*@} end of group ES8388_Private_Macros */
|
||||
|
||||
/** @defgroup ES8388_Private_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group ES8388_Private_Types */
|
||||
|
||||
/** @defgroup ES8388_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group ES8388_Private_Variables */
|
||||
|
||||
/** @defgroup ES8388_Global_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group ES8388_Global_Variables */
|
||||
|
||||
/** @defgroup ES8388_Private_Fun_Declaration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group ES8388_Private_Fun_Declaration */
|
||||
|
||||
/** @defgroup ES8388_Private_Functions_User_Define
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group ES8388_Private_Functions_User_Define */
|
||||
|
||||
/** @defgroup ES8388_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
static struct bflb_device_s *i2c0;
|
||||
static struct bflb_i2c_msg_s msgs[2];
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388_I2C_Init
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void ES8388_I2C_Init(void)
|
||||
{
|
||||
// i2c_register(I2C0_INDEX, "i2c");
|
||||
// es8388_i2c = device_find("i2c");
|
||||
|
||||
// if (es8388_i2c) {
|
||||
// device_open(es8388_i2c, 0);
|
||||
// }
|
||||
|
||||
i2c0 = bflb_device_get_by_name("i2c0");
|
||||
bflb_i2c_init(i2c0, 200000);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388 write register
|
||||
*
|
||||
* @param addr: Register address
|
||||
* @param data: data
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
int ES8388_Write_Reg(uint8_t addr, uint8_t data)
|
||||
{
|
||||
msgs[0].addr = ES8388_I2C_SLAVE_ADDR;
|
||||
msgs[0].flags = I2C_M_NOSTOP;
|
||||
msgs[0].buffer = &addr;
|
||||
msgs[0].length = 1;
|
||||
|
||||
msgs[1].flags = 0;
|
||||
msgs[1].buffer = &data;
|
||||
msgs[1].length = 1;
|
||||
|
||||
return bflb_i2c_transfer(i2c0, msgs, 2);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388_Read_Reg
|
||||
*
|
||||
* @param addr: Register address
|
||||
* @param rdata: data
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
int ES8388_Read_Reg(uint8_t addr, uint8_t *rdata)
|
||||
{
|
||||
msgs[0].addr = ES8388_I2C_SLAVE_ADDR;
|
||||
msgs[0].flags = I2C_M_NOSTOP;
|
||||
msgs[0].buffer = &addr;
|
||||
msgs[0].length = 1;
|
||||
|
||||
msgs[1].flags = I2C_M_READ;
|
||||
msgs[1].buffer = rdata;
|
||||
msgs[1].length = 1;
|
||||
|
||||
return bflb_i2c_transfer(i2c0, msgs, 2);
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388 codec mode
|
||||
*
|
||||
* @param cfg: None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void ES8388_Codec_Mode(ES8388_Cfg_Type *cfg)
|
||||
{
|
||||
uint8_t tempVal = 0;
|
||||
|
||||
ES8388_Write_Reg(0x01, 0x58); //power down whole chip analog
|
||||
ES8388_Write_Reg(0x01, 0x50); //power up whole chip analog
|
||||
|
||||
ES8388_Write_Reg(0x02, 0xf3); //power down ADC/DAC and reset ADC/DAC state machine
|
||||
ES8388_Write_Reg(0x02, 0xf0); //power on ADC/DAC
|
||||
|
||||
ES8388_Write_Reg(0x2B, 0x80); //set internal ADC and DAC use sanme LRCK clock
|
||||
|
||||
ES8388_Write_Reg(0x00, 0x36); //ADC clock is same as DAC . DACMCLK is the chip master clock source
|
||||
|
||||
if (cfg->role == ES8388_MASTER) {
|
||||
ES8388_Write_Reg(0x08, 0x8D);
|
||||
} else {
|
||||
ES8388_Write_Reg(0x08, 0x00);
|
||||
}
|
||||
|
||||
ES8388_Write_Reg(0x04, 0x00); //power up dac
|
||||
|
||||
ES8388_Write_Reg(0x05, 0x00); //stop lowpower mode
|
||||
ES8388_Write_Reg(0x06, 0xc3); //stop lowpower mode
|
||||
|
||||
if (cfg->mic_input_mode == ES8388_SINGLE_ENDED_MIC) {
|
||||
/*
|
||||
* default set LINPUT1 and RINPUT1 as single ended mic input
|
||||
* if user want to use LINPUT2 and RINPUT2 as input
|
||||
* please set 0x0a register as 0x50
|
||||
*/
|
||||
ES8388_Write_Reg(0x0A, 0xf8);
|
||||
ES8388_Write_Reg(0x0B, 0x88); //analog mono mix to left ADC
|
||||
} else {
|
||||
/*
|
||||
* defualt select LIN1 and RIN1 as Mic diff input
|
||||
* if user want to use LIN2 and RIN2 as input
|
||||
* please set 0x0b register as 0x82
|
||||
*/
|
||||
ES8388_Write_Reg(0x0A, 0xf8); // Fixed stereo problems
|
||||
ES8388_Write_Reg(0x0B, 0x82); // stereo
|
||||
}
|
||||
|
||||
tempVal = cfg->data_width;
|
||||
tempVal <<= 2;
|
||||
tempVal |= cfg->i2s_frame;
|
||||
|
||||
ES8388_Write_Reg(0x0C, tempVal); //ADC I2S Format sel as i2s_frame , data len as data_width
|
||||
|
||||
tempVal = cfg->data_width;
|
||||
tempVal <<= 2;
|
||||
tempVal |= cfg->i2s_frame;
|
||||
tempVal <<= 1;
|
||||
|
||||
ES8388_Write_Reg(0x17, tempVal); //DAC I2S Format sel as i2s_frame , data len as data_width
|
||||
|
||||
/* when work in master mode , BCLK is devided form MCLK
|
||||
* default divider is 256 , see datasheet reigster 13
|
||||
*/
|
||||
if (cfg->role == ES8388_MASTER) {
|
||||
ES8388_Write_Reg(0x0d, 0x06); //ADCLRCK = MCLK/256
|
||||
ES8388_Write_Reg(0x18, 0x06); //DACLRCK = MCLK/256
|
||||
}
|
||||
|
||||
/*set ADC/DAC default volume as 0 db */
|
||||
ES8388_Write_Reg(0x10, 0x00); //LADC volume as 0db
|
||||
ES8388_Write_Reg(0x11, 0x00); //RADC volume as 0db
|
||||
ES8388_Write_Reg(0x1A, 0x00); //LDAC volume as 0db
|
||||
ES8388_Write_Reg(0x1B, 0x00); //RDAC volume as 0db
|
||||
|
||||
tempVal = cfg->mic_pga;
|
||||
tempVal <<= 4;
|
||||
tempVal |= cfg->mic_pga;
|
||||
|
||||
ES8388_Write_Reg(0x09, tempVal); //set ADC PGA as mic pga
|
||||
|
||||
/*ADC ALC default Setting */
|
||||
ES8388_Write_Reg(0x12, 0xE2);
|
||||
ES8388_Write_Reg(0x13, 0xC0);
|
||||
ES8388_Write_Reg(0x14, 0x12);
|
||||
ES8388_Write_Reg(0x15, 0x06);
|
||||
ES8388_Write_Reg(0x16, 0xC3);
|
||||
|
||||
/*Mixer setting for LDAC to LOUT and RDAC TO ROUT
|
||||
* default close mixer
|
||||
*/
|
||||
ES8388_Write_Reg(0x27, 0xB8);
|
||||
ES8388_Write_Reg(0x2A, 0xB8);
|
||||
|
||||
ES8388_Write_Reg(0x02, 0x00); //startup FSM and DLL
|
||||
bflb_mtimer_delay_ms(500);
|
||||
|
||||
/* set LOUT1 ROUT1 LOUT2 ROUT2 volume */
|
||||
ES8388_Write_Reg(0x2e, 0x1E);
|
||||
ES8388_Write_Reg(0x2f, 0x1E);
|
||||
ES8388_Write_Reg(0x30, 0x1E);
|
||||
ES8388_Write_Reg(0x31, 0x1E);
|
||||
|
||||
//ES8388_Write_Reg(0x04,0x3C);//enable LOUT & ROUT
|
||||
ES8388_Write_Reg(0x04, 0x24);
|
||||
ES8388_Write_Reg(0x26, 0x01);
|
||||
ES8388_Write_Reg(0x03, 0x09); //power up ADC Enable LIN &RIN.
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388 recording mode
|
||||
*
|
||||
* @param cfg: None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void ES8388_Recording_Mode(ES8388_Cfg_Type *cfg)
|
||||
{
|
||||
uint8_t tempVal = 0;
|
||||
ES8388_Write_Reg(0x01, 0x58); //power down whole chip analog
|
||||
ES8388_Write_Reg(0x01, 0x50); //power up whole chip analog
|
||||
|
||||
ES8388_Write_Reg(0x02, 0xf3); //power down ADC/DAC and reset ADC/DAC state machine
|
||||
ES8388_Write_Reg(0x02, 0xf0); //power on ADC/DAC
|
||||
ES8388_Write_Reg(0x2B, 0x80); //set internal ADC and DAC use the same LRCK clock
|
||||
ES8388_Write_Reg(0x00, 0x16); //ADC clock is same as DAC. use ADC MCLK as internal MCLK
|
||||
|
||||
if (cfg->role == ES8388_MASTER) {
|
||||
ES8388_Write_Reg(0x08, 0x80);
|
||||
} else {
|
||||
ES8388_Write_Reg(0x08, 0x00);
|
||||
}
|
||||
|
||||
ES8388_Write_Reg(0x04, 0xc0);
|
||||
ES8388_Write_Reg(0x05, 0x00);
|
||||
ES8388_Write_Reg(0x06, 0xc3);
|
||||
|
||||
if (cfg->mic_input_mode == ES8388_SINGLE_ENDED_MIC) {
|
||||
/*
|
||||
* default set LINPUT1 and RINPUT1 as single ended mic input
|
||||
* if user want to use LINPUT2 and RINPUT2 as input
|
||||
* please set 0x0a register as 0x50
|
||||
*/
|
||||
//ES8388_Write_Reg(0x0A,0x00);//select lin1 and rin1 as micphone input
|
||||
ES8388_Write_Reg(0x0A, 0xf8);
|
||||
ES8388_Write_Reg(0x0B, 0x88); //analog mono mix to left ADC
|
||||
//ES8388_Write_Reg(0x0B,0x90); //analog mono mix to right ADC
|
||||
} else {
|
||||
/*
|
||||
* defualt select LIN1 and RIN1 as Mic diff input
|
||||
* if user want to use LIN2 and RIN2 as input
|
||||
* please set 0x0b register as 0x82
|
||||
*/
|
||||
//ES8388_Write_Reg(0x0A,0xf0);//set micphone input as difference mode
|
||||
//ES8388_Write_Reg(0x0B,0x02);//set LIN1 and RIN1 as micphone different input
|
||||
ES8388_Write_Reg(0x0A, 0xf8); // Fixed stereo problems
|
||||
ES8388_Write_Reg(0x0B, 0x82); // stereo
|
||||
}
|
||||
|
||||
tempVal = cfg->data_width;
|
||||
tempVal <<= 2;
|
||||
tempVal |= cfg->i2s_frame;
|
||||
|
||||
ES8388_Write_Reg(0x0C, tempVal); //ADC I2S Format sel as i2s_frame , data len as data_width
|
||||
|
||||
ES8388_Write_Reg(0x0d, 0x02); //ADC LRCK = MCLK/256
|
||||
|
||||
ES8388_Write_Reg(0x10, 0x00); //ADC VOLUME = 0 DB
|
||||
ES8388_Write_Reg(0x11, 0x00); //set ADC VOLUME as 0 DB
|
||||
|
||||
tempVal = cfg->mic_pga;
|
||||
tempVal <<= 4;
|
||||
tempVal |= cfg->mic_pga;
|
||||
|
||||
ES8388_Write_Reg(0x09, tempVal); //MIC PGA SEL
|
||||
|
||||
ES8388_Write_Reg(0x12, 0xe2); //MIC ALC SETTING
|
||||
|
||||
ES8388_Write_Reg(0x13, 0xc0);
|
||||
ES8388_Write_Reg(0x14, 0x12);
|
||||
ES8388_Write_Reg(0x15, 0x06);
|
||||
ES8388_Write_Reg(0x16, 0xc3);
|
||||
|
||||
ES8388_Write_Reg(0x02, 0x55); //startup FSM and DLL
|
||||
ES8388_Write_Reg(0x03, 0x09); //power up adc , enable LIN and RIN
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388 Playback mode
|
||||
*
|
||||
* @param cfg: None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void ES8388_Playback_Mode(ES8388_Cfg_Type *cfg)
|
||||
{
|
||||
uint8_t tempVal = 0;
|
||||
|
||||
ES8388_Write_Reg(0x00, 0x80); //Reset control port register to default
|
||||
ES8388_Write_Reg(0x00, 0x06); //Close reset
|
||||
bflb_mtimer_delay_ms(10);
|
||||
ES8388_Write_Reg(0x02, 0xF3); //Stop STM, DLL and digital block
|
||||
|
||||
if (cfg->role == ES8388_MASTER) {
|
||||
ES8388_Write_Reg(0x08, 0x80);
|
||||
} else {
|
||||
ES8388_Write_Reg(0x08, 0x00);
|
||||
}
|
||||
|
||||
ES8388_Write_Reg(0x2B, 0x80); //Set ADC and DAC have the same LRCK
|
||||
ES8388_Write_Reg(0x00, 0x05); //Start up reference
|
||||
ES8388_Write_Reg(0x01, 0x40); //Start up reference
|
||||
bflb_mtimer_delay_ms(30);
|
||||
ES8388_Write_Reg(0x03, 0x00); //Power on ADC and LIN/RIN input
|
||||
ES8388_Write_Reg(0x04, 0x3F); //Power on DAC and LOUT/ROUT input
|
||||
|
||||
/* Set ADC */
|
||||
ES8388_Write_Reg(0x09, 0x77); //MicBoost PGA = +21dB
|
||||
ES8388_Write_Reg(0x0A, 0xF0); //Differential input
|
||||
ES8388_Write_Reg(0x0B, 0x02); //Select LIN1 and RIN1 as differential input pairs
|
||||
|
||||
tempVal = cfg->data_width;
|
||||
tempVal <<= 2;
|
||||
tempVal |= cfg->i2s_frame;
|
||||
|
||||
ES8388_Write_Reg(0x0C, tempVal); //ADC I2S Format sel as i2s_frame , data len as data_width
|
||||
|
||||
ES8388_Write_Reg(0x0D, 0x04); //MCLK / LRCK = 512
|
||||
ES8388_Write_Reg(0x10, 0x00); //LADC volume = 0dB
|
||||
ES8388_Write_Reg(0x11, 0x00); //RADC volume = 0dB
|
||||
ES8388_Write_Reg(0x12, 0xE2); //ALC enable, PGA Max.Gain = 23.5dB, Min.Gain = 0dB
|
||||
ES8388_Write_Reg(0x13, 0xC0); //ALC target = -4.5dB, ALC hold time = 0 ms
|
||||
ES8388_Write_Reg(0x14, 0x12); //Decay time = 820us, attack time = 416us
|
||||
ES8388_Write_Reg(0x15, 0x06); //ALC mode
|
||||
ES8388_Write_Reg(0x16, 0xC3); //Nose gate =-40.5dB, NGG = 0x01(mute ADC)
|
||||
|
||||
tempVal = cfg->data_width;
|
||||
tempVal <<= 2;
|
||||
tempVal |= cfg->i2s_frame;
|
||||
tempVal <<= 1;
|
||||
|
||||
ES8388_Write_Reg(0x18, 0x04); //MCLK / LRCK = 512
|
||||
ES8388_Write_Reg(0x1A, 0x00); //LDAC volume = 0dB
|
||||
ES8388_Write_Reg(0x1B, 0x00); //RDAC volume = 0dB
|
||||
ES8388_Write_Reg(0x26, 0x00); //Setup mixer
|
||||
ES8388_Write_Reg(0x27, 0xB8); //Setup mixer
|
||||
ES8388_Write_Reg(0x28, 0x38); //Setup mixer
|
||||
ES8388_Write_Reg(0x29, 0x38); //Setup mixer
|
||||
ES8388_Write_Reg(0x2A, 0xB8); //Setup mixer
|
||||
ES8388_Write_Reg(0x2E, 0x1E); //Set Lout/Rout volume:0dB
|
||||
ES8388_Write_Reg(0x2F, 0x1E); //Set Lout/Rout volume:0dB
|
||||
ES8388_Write_Reg(0x30, 0x1E); //Set Lout/Rout volume:0dB
|
||||
ES8388_Write_Reg(0x31, 0x1E); //Set Lout/Rout volume:0dB
|
||||
ES8388_Write_Reg(0x02, 0x00); //Power up DEM and STM
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388_I2C_Init
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
int ES8388_Set_Voice_Volume(int volume)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (volume < 0) {
|
||||
volume = 0;
|
||||
} else if (volume > 100) {
|
||||
volume = 100;
|
||||
}
|
||||
|
||||
volume /= 3;
|
||||
res = ES8388_Write_Reg(0x2e, volume);
|
||||
res |= ES8388_Write_Reg(0x2f, volume);
|
||||
res |= ES8388_Write_Reg(0x30, volume);
|
||||
res |= ES8388_Write_Reg(0x31, volume);
|
||||
return res;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388_Reg_Dump
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void ES8388_Reg_Dump(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t tmp;
|
||||
|
||||
for (i = 0; i < 0X3F; i++) {
|
||||
if (ES8388_Read_Reg(i, &tmp) != 0) {
|
||||
printf("iic read err\r\n");
|
||||
}
|
||||
|
||||
printf("Reg[%02d]=0x%02x \n", i, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of group ES8388_Private_Functions */
|
||||
|
||||
/** @defgroup ES8388_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief ES8388 Init function
|
||||
*
|
||||
* @param cfg: None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void ES8388_Init(ES8388_Cfg_Type *cfg)
|
||||
{
|
||||
ES8388_I2C_Init();
|
||||
|
||||
switch (cfg->work_mode) {
|
||||
case ES8388_CODEC_MDOE:
|
||||
ES8388_Codec_Mode(cfg);
|
||||
break;
|
||||
|
||||
case ES8388_RECORDING_MODE:
|
||||
ES8388_Recording_Mode(cfg);
|
||||
break;
|
||||
|
||||
case ES8388_PLAY_BACK_MODE:
|
||||
ES8388_Playback_Mode(cfg);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of group ES8388_Public_Functions */
|
||||
|
||||
/*@} end of group ES8388 */
|
||||
|
||||
/*@} end of group BL702_STD_PERIPH_DRIVER */
|
191
examples/peripherals/i2s/i2s_es8388/bsp_es8388.h
Executable file
191
examples/peripherals/i2s/i2s_es8388/bsp_es8388.h
Executable file
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* @file bsp_es8388.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ES8388_H__
|
||||
#define __ES8388_H__
|
||||
|
||||
/** @addtogroup BL702_STD_PERIPH_DRIVER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup ES8388
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ES8388_Public_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ES8388 Role Matser Or Slave
|
||||
*/
|
||||
typedef enum {
|
||||
ES8388_MASTER, /*!< Master Mode */
|
||||
ES8388_SLAVE, /*!< Slave Mode */
|
||||
} ES8388_Role_Type;
|
||||
|
||||
/**
|
||||
* @brief ES8388 Work Mode
|
||||
*/
|
||||
typedef enum {
|
||||
ES8388_CODEC_MDOE, /*!< ES8388 work at codec mode */
|
||||
ES8388_RECORDING_MODE, /*!< ES8388 work at recording mode */
|
||||
ES8388_PLAY_BACK_MODE, /*!< ES8388 work at paly back mode */
|
||||
ES8388_BY_PASS_MODE, /*!< ES8388 work at by pass mode */
|
||||
} ES8388_Work_Mode;
|
||||
|
||||
/**
|
||||
* @brief ES8388 Microphone input type
|
||||
*/
|
||||
typedef enum {
|
||||
ES8388_SINGLE_ENDED_MIC, /*!< Mic Single Input Mode */
|
||||
ES8388_DIFF_ENDED_MIC, /*!< Mic Different Input Mode */
|
||||
} ES8388_MIC_Input_Type;
|
||||
|
||||
/**
|
||||
* @brief ES8388 Microphone pga sel type
|
||||
*/
|
||||
typedef enum {
|
||||
ES8388_MIC_PGA_0DB, /*!< Mic PGA as 0db */
|
||||
ES8388_MIC_PGA_3DB, /*!< Mic PGA as 3db */
|
||||
ES8388_MIC_PGA_6DB, /*!< Mic PGA as 6db */
|
||||
ES8388_MIC_PGA_9DB, /*!< Mic PGA as 9db */
|
||||
ES8388_MIC_PGA_12DB, /*!< Mic PGA as 12db */
|
||||
ES8388_MIC_PGA_15DB, /*!< Mic PGA as 15db */
|
||||
ES8388_MIC_PGA_18DB, /*!< Mic PGA as 18db */
|
||||
ES8388_MIC_PGA_21DB, /*!< Mic PGA as 21db */
|
||||
ES8388_MIC_PGA_24DB, /*!< Mic PGA as 24db */
|
||||
} ES8388_MIC_Input_PGA_Type;
|
||||
|
||||
/**
|
||||
* @brief ES8388 I2S Frame Type
|
||||
*/
|
||||
typedef enum {
|
||||
ES8388_STD_I2S_FRAME, /*!< Standard I2S Frame */
|
||||
ES8388_LEFT_JUSTIFY_FRAME, /*!< Left Justify Frame */
|
||||
ES8388_RIGHT_JUSTIFY_FRAME, /*!< Right Justify Frame */
|
||||
ES8388_DSP_FRAME, /*!< DSP Frame */
|
||||
} ES8388_I2S_Frame_Type;
|
||||
|
||||
/**
|
||||
* @brief ES8388 I2S Data Len Type
|
||||
*/
|
||||
typedef enum {
|
||||
ES8388_DATA_LEN_24, /*!< I2S Auido Data Len 24 */
|
||||
ES8388_DATA_LEN_20, /*!< I2S Auido Data Len 20 */
|
||||
ES8388_DATA_LEN_18, /*!< I2S Auido Data Len 18 */
|
||||
ES8388_DATA_LEN_16, /*!< I2S Auido Data Len 16 */
|
||||
ES8388_DATA_LEN_32, /*!< I2S Auido Data Len 32 */
|
||||
} ES8388_I2S_Data_Width;
|
||||
|
||||
/**
|
||||
* @brief ES8388_Cfg_Type
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ES8388_Work_Mode work_mode; /*!< ES8388 work mode */
|
||||
ES8388_Role_Type role; /*!< ES8388 role */
|
||||
ES8388_MIC_Input_Type mic_input_mode; /*!< ES8388 mic input mode */
|
||||
ES8388_MIC_Input_PGA_Type mic_pga; /*!< ES8388 mic PGA */
|
||||
ES8388_I2S_Frame_Type i2s_frame; /*!< ES8388 I2S frame */
|
||||
ES8388_I2S_Data_Width data_width; /*!< ES8388 I2S dataWitdh */
|
||||
} ES8388_Cfg_Type;
|
||||
|
||||
/*@} end of group ES8388_Public_Types */
|
||||
|
||||
/** @defgroup ES8388_Public_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ES8388_ROLE_TYPE
|
||||
* @{
|
||||
*/
|
||||
#define IS_ES8388_ROLE_TYPE(type) (((type) == ES8388_MASTER) || \
|
||||
((type) == ES8388_SLAVE))
|
||||
|
||||
/** @defgroup ES8388_WORK_MODE
|
||||
* @{
|
||||
*/
|
||||
#define IS_ES8388_WORK_MODE(type) (((type) == ES8388_CODEC_MDOE) || \
|
||||
((type) == ES8388_RECORDING_MODE) || \
|
||||
((type) == ES8388_PLAY_BACK_MODE) || \
|
||||
((type) == ES8388_BY_PASS_MODE))
|
||||
|
||||
/** @defgroup ES8388_MIC_INPUT_TYPE
|
||||
* @{
|
||||
*/
|
||||
#define IS_ES8388_MIC_INPUT_TYPE(type) (((type) == ES8388_SINGLE_ENDED_MIC) || \
|
||||
((type) == ES8388_DIFF_ENDED_MIC))
|
||||
|
||||
/** @defgroup ES8388_MIC_INPUT_PGA_TYPE
|
||||
* @{
|
||||
*/
|
||||
#define IS_ES8388_MIC_INPUT_PGA_TYPE(type) (((type) == ES8388_MIC_PGA_0DB) || \
|
||||
((type) == ES8388_MIC_PGA_3DB) || \
|
||||
((type) == ES8388_MIC_PGA_6DB) || \
|
||||
((type) == ES8388_MIC_PGA_9DB) || \
|
||||
((type) == ES8388_MIC_PGA_12DB) || \
|
||||
((type) == ES8388_MIC_PGA_15DB) || \
|
||||
((type) == ES8388_MIC_PGA_18DB) || \
|
||||
((type) == ES8388_MIC_PGA_21DB) || \
|
||||
((type) == ES8388_MIC_PGA_24DB))
|
||||
|
||||
/** @defgroup ES8388_I2S_FRAME_TYPE
|
||||
* @{
|
||||
*/
|
||||
#define IS_ES8388_I2S_FRAME_TYPE(type) (((type) == ES8388_STD_I2S_FRAME) || \
|
||||
((type) == ES8388_LEFT_JUSTIFY_FRAME) || \
|
||||
((type) == ES8388_RIGHT_JUSTIFY_FRAME) || \
|
||||
((type) == ES8388_DSP_FRAME))
|
||||
|
||||
/** @defgroup ES8388_I2S_DATA_WIDTH
|
||||
* @{
|
||||
*/
|
||||
#define IS_ES8388_I2S_DATA_WIDTH(type) (((type) == ES8388_DATA_LEN_24) || \
|
||||
((type) == ES8388_DATA_LEN_20) || \
|
||||
((type) == ES8388_DATA_LEN_18) || \
|
||||
((type) == ES8388_DATA_LEN_16) || \
|
||||
((type) == ES8388_DATA_LEN_32))
|
||||
|
||||
/*@} end of group ES8388_Public_Constants */
|
||||
|
||||
/** @defgroup ES8388_Public_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group ES8388_Public_Macros */
|
||||
|
||||
/** @defgroup ES8388_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
void ES8388_Init(ES8388_Cfg_Type *cfg);
|
||||
void ES8388_Reg_Dump(void);
|
||||
int ES8388_Set_Voice_Volume(int volume);
|
||||
|
||||
/*@} end of group ES8388_Public_Functions */
|
||||
|
||||
/*@} end of group ES8388 */
|
||||
|
||||
/*@} end of group BL702_STD_PERIPH_DRIVER */
|
||||
|
||||
#endif /* __ES8388_H__ */
|
40031
examples/peripherals/i2s/i2s_es8388/fhm_onechannel_16k_20.h
Executable file
40031
examples/peripherals/i2s/i2s_es8388/fhm_onechannel_16k_20.h
Executable file
File diff suppressed because it is too large
Load diff
11
examples/peripherals/i2s/i2s_es8388/flash_prog_cfg.ini
Normal file
11
examples/peripherals/i2s/i2s_es8388/flash_prog_cfg.ini
Normal file
|
@ -0,0 +1,11 @@
|
|||
[cfg]
|
||||
# 0: no erase, 1:programmed section erase, 2: chip erase
|
||||
erase = 1
|
||||
# skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated
|
||||
skip_mode = 0x0, 0x0
|
||||
# 0: not use isp mode, #1: isp mode
|
||||
boot2_isp_mode = 0
|
||||
|
||||
[FW]
|
||||
filedir = ./build/build_out/i2s*_$(CHIPNAME).bin
|
||||
address = 0x000000
|
155
examples/peripherals/i2s/i2s_es8388/main.c
Executable file
155
examples/peripherals/i2s/i2s_es8388/main.c
Executable file
|
@ -0,0 +1,155 @@
|
|||
#include "board.h"
|
||||
|
||||
#include "bflb_clock.h"
|
||||
#include "bflb_mtimer.h"
|
||||
#include "bflb_i2s.h"
|
||||
#include "bflb_i2c.h"
|
||||
#include "bflb_dma.h"
|
||||
#include "bflb_gpio.h"
|
||||
|
||||
#include "bl616_glb.h"
|
||||
|
||||
#include "fhm_onechannel_16k_20.h"
|
||||
#include "bsp_es8388.h"
|
||||
|
||||
struct bflb_device_s *i2s0;
|
||||
struct bflb_device_s *i2c0;
|
||||
struct bflb_device_s *dma0_ch0;
|
||||
|
||||
volatile uint8_t dma_tc_flag0 = 0;
|
||||
|
||||
static ES8388_Cfg_Type ES8388Cfg = {
|
||||
.work_mode = ES8388_CODEC_MDOE, /*!< ES8388 work mode */
|
||||
.role = ES8388_SLAVE, /*!< ES8388 role */
|
||||
.mic_input_mode = ES8388_DIFF_ENDED_MIC, /*!< ES8388 mic input mode */
|
||||
.mic_pga = ES8388_MIC_PGA_3DB, /*!< ES8388 mic PGA */
|
||||
.i2s_frame = ES8388_LEFT_JUSTIFY_FRAME, /*!< ES8388 I2S frame */
|
||||
.data_width = ES8388_DATA_LEN_16, /*!< ES8388 I2S dataWitdh */
|
||||
};
|
||||
|
||||
void dma0_ch0_isr(void *arg)
|
||||
{
|
||||
dma_tc_flag0++;
|
||||
printf("tc done\r\n");
|
||||
}
|
||||
|
||||
void i2s_gpio_init()
|
||||
{
|
||||
struct bflb_device_s *gpio;
|
||||
|
||||
gpio = bflb_device_get_by_name("gpio");
|
||||
|
||||
/* I2S_FS */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_13, GPIO_FUNC_I2S | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
|
||||
/* I2S_DI */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_14, GPIO_FUNC_I2S | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
|
||||
/* I2S_DO */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_15, GPIO_FUNC_I2S | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
|
||||
/* I2S_BCLK */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_20, GPIO_FUNC_I2S | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
|
||||
|
||||
/* MCLK CLKOUT */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_23, GPIO_FUNC_CLKOUT | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
|
||||
|
||||
/* I2C0_SCL */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_10, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
/* I2C0_SDA */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_11, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
}
|
||||
|
||||
void i2s_dma_init()
|
||||
{
|
||||
static struct bflb_dma_channel_lli_pool_s tx_llipool[100];
|
||||
static struct bflb_dma_channel_lli_transfer_s tx_transfers[1];
|
||||
|
||||
struct bflb_i2s_config_s i2s_cfg = {
|
||||
.bclk_freq_hz = 16000 * 32 * 2, /* bclk = Sampling_rate * frame_width * channel_num */
|
||||
.role = I2S_ROLE_MASTER,
|
||||
.format_mode = I2S_MODE_LEFT_JUSTIFIED,
|
||||
.channel_mode = I2S_CHANNEL_MODE_NUM_1,
|
||||
.frame_width = I2S_SLOT_WIDTH_32,
|
||||
.data_width = I2S_SLOT_WIDTH_16,
|
||||
.fs_offset_cycle = 0,
|
||||
|
||||
.tx_fifo_threshold = 0,
|
||||
.rx_fifo_threshold = 0,
|
||||
};
|
||||
|
||||
struct bflb_dma_channel_config_s tx_config = {
|
||||
.direction = DMA_MEMORY_TO_PERIPH,
|
||||
.src_req = DMA_REQUEST_NONE,
|
||||
.dst_req = DMA_REQUEST_I2S_TX,
|
||||
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
|
||||
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
|
||||
.src_burst_count = DMA_BURST_INCR1,
|
||||
.dst_burst_count = DMA_BURST_INCR1,
|
||||
.src_width = DMA_DATA_WIDTH_16BIT,
|
||||
.dst_width = DMA_DATA_WIDTH_16BIT,
|
||||
};
|
||||
|
||||
printf("i2s init\r\n");
|
||||
i2s0 = bflb_device_get_by_name("i2s0");
|
||||
/* i2s init */
|
||||
bflb_i2s_init(i2s0, &i2s_cfg);
|
||||
/* enable dma */
|
||||
bflb_i2s_link_txdma(i2s0, true);
|
||||
bflb_i2s_link_rxdma(i2s0, true);
|
||||
|
||||
printf("dma init\r\n");
|
||||
dma0_ch0 = bflb_device_get_by_name("dma0_ch0");
|
||||
bflb_dma_channel_init(dma0_ch0, &tx_config);
|
||||
bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL);
|
||||
|
||||
tx_transfers[0].src_addr = (uint32_t)fhm_onechannel_16k_20;
|
||||
tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_I2S_TDR;
|
||||
tx_transfers[0].nbytes = sizeof(fhm_onechannel_16k_20);
|
||||
|
||||
printf("dma lli init\r\n");
|
||||
uint32_t num = bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 100, tx_transfers, 1);
|
||||
bflb_dma_channel_lli_link_head(dma0_ch0, tx_llipool, num);
|
||||
printf("dma lli num: %d \r\n", num);
|
||||
bflb_dma_channel_start(dma0_ch0);
|
||||
}
|
||||
|
||||
void mclk_out_init()
|
||||
{
|
||||
#ifdef BL616
|
||||
/* output MCLK,
|
||||
Will change the clock source of i2s,
|
||||
It needs to be called before i2s is initialized
|
||||
clock source 25M
|
||||
*/
|
||||
GLB_Set_I2S_CLK(ENABLE, 2, GLB_I2S_DI_SEL_I2S_DI_INPUT, GLB_I2S_DO_SEL_I2S_DO_OUTPT);
|
||||
GLB_Set_Chip_Clock_Out3_Sel(GLB_CHIP_CLK_OUT_3_I2S_REF_CLK);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
printf("\n\ri2s dma test\n\r");
|
||||
|
||||
/* gpio init */
|
||||
i2s_gpio_init();
|
||||
|
||||
/* init ES8388 Codec */
|
||||
printf("es8388 init\n\r");
|
||||
ES8388_Init(&ES8388Cfg);
|
||||
ES8388_Set_Voice_Volume(90);
|
||||
|
||||
/* mclk clkout init */
|
||||
mclk_out_init();
|
||||
|
||||
/* i2s init */
|
||||
i2s_dma_init();
|
||||
|
||||
/* enable i2s tx and rx */
|
||||
bflb_i2s_feature_control(i2s0, I2S_CMD_DATA_ENABLE, I2S_CMD_DATA_ENABLE_TX | I2S_CMD_DATA_ENABLE_RX);
|
||||
|
||||
printf("test end\n\r");
|
||||
|
||||
while (1) {
|
||||
bflb_mtimer_delay_ms(10);
|
||||
}
|
||||
}
|
1
examples/peripherals/i2s/i2s_es8388/proj.conf
Executable file
1
examples/peripherals/i2s/i2s_es8388/proj.conf
Executable file
|
@ -0,0 +1 @@
|
|||
#set(CONFIG_XXX 1)
|
Loading…
Add table
Add a link
Reference in a new issue