[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:
jzlv 2023-01-17 20:54:15 +08:00
parent 89592fc9a3
commit 356f258e83
554 changed files with 79150 additions and 46596 deletions

View 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)

View 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

View 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
```

View 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

View 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) {
}
}

View file

@ -0,0 +1 @@
#set(CONFIG_XXX 1)

View 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)

View 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

View 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
```

View 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 */

View 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__ */

File diff suppressed because it is too large Load diff

View 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

View 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);
}
}

View file

@ -0,0 +1 @@
#set(CONFIG_XXX 1)