mirror of
https://github.com/bouffalolab/bouffalo_sdk.git
synced 2025-05-09 03:11:58 +08:00
[update] add callback for single gpio, add cdc_msc, i2s_es8311 adc onechan, mjpeg with crop demo
This commit is contained in:
parent
4c12ce5324
commit
358a4176b3
@ -373,6 +373,10 @@ void bflb_gpio_uart_init(struct bflb_device_s *dev, uint8_t pin, uint8_t uart_fu
|
||||
|
||||
int bflb_gpio_feature_control(struct bflb_device_s *dev, int cmd, size_t arg);
|
||||
|
||||
void bflb_gpio_irq_attach(uint8_t pin, void (*callback)(uint8_t pin));
|
||||
|
||||
void bflb_gpio_irq_detach(uint8_t pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,6 +1,20 @@
|
||||
#include "bflb_gpio.h"
|
||||
#include "hardware/gpio_reg.h"
|
||||
|
||||
struct bflb_gpio_irq_callback {
|
||||
void (*handler)(uint8_t pin);
|
||||
};
|
||||
|
||||
#if defined(BL702) || defined(BL602) || defined(BL702L)
|
||||
struct bflb_gpio_irq_callback g_gpio_irq_callback[32] = { 0 };
|
||||
#elif defined(BL616)
|
||||
struct bflb_gpio_irq_callback g_gpio_irq_callback[35] = { 0 };
|
||||
#elif defined(BL606P) || defined(BL808)
|
||||
struct bflb_gpio_irq_callback g_gpio_irq_callback[46] = { 0 };
|
||||
#elif defined(BL628)
|
||||
struct bflb_gpio_irq_callback g_gpio_irq_callback[35] = { 0 };
|
||||
#endif
|
||||
|
||||
void bflb_gpio_init(struct bflb_device_s *dev, uint8_t pin, uint32_t cfgset)
|
||||
{
|
||||
uint32_t cfg = 0;
|
||||
@ -496,3 +510,31 @@ int bflb_gpio_feature_control(struct bflb_device_s *dev, int cmd, size_t arg)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct bflb_device_s *g_gpio_int = NULL;
|
||||
|
||||
void gpio_all_isr(int irq, void *arg)
|
||||
{
|
||||
for (uint8_t i = 0; i < sizeof(g_gpio_irq_callback) / sizeof(struct bflb_gpio_irq_callback); i++) {
|
||||
if (g_gpio_irq_callback[i].handler && bflb_gpio_get_intstatus(g_gpio_int, i)) {
|
||||
bflb_gpio_int_clear(g_gpio_int, i);
|
||||
g_gpio_irq_callback[i].handler(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bflb_gpio_irq_attach(uint8_t pin, void (*callback)(uint8_t pin))
|
||||
{
|
||||
g_gpio_int = bflb_device_get_by_name("gpio");
|
||||
bflb_gpio_int_mask(g_gpio_int, pin, true);
|
||||
g_gpio_irq_callback[pin].handler = callback;
|
||||
bflb_gpio_int_mask(g_gpio_int, pin, false);
|
||||
bflb_irq_attach(g_gpio_int->irq_num, gpio_all_isr, NULL);
|
||||
}
|
||||
|
||||
void bflb_gpio_irq_detach(uint8_t pin)
|
||||
{
|
||||
g_gpio_int = bflb_device_get_by_name("gpio");
|
||||
bflb_gpio_int_mask(g_gpio_int, pin, true);
|
||||
g_gpio_irq_callback[pin].handler = NULL;
|
||||
}
|
||||
|
@ -6,15 +6,17 @@
|
||||
#include <csi_core.h>
|
||||
#endif
|
||||
|
||||
#ifndef BL_IOT_SDK
|
||||
extern struct bflb_irq_info_s g_irqvector[];
|
||||
|
||||
static void irq_unexpected_isr(int irq, void *arg)
|
||||
{
|
||||
printf("irq :%d unregistered\r\n", irq);
|
||||
}
|
||||
|
||||
#endif
|
||||
void bflb_irq_initialize(void)
|
||||
{
|
||||
#ifndef BL_IOT_SDK
|
||||
int i;
|
||||
|
||||
/* Point all interrupt vectors to the unexpected interrupt */
|
||||
@ -22,6 +24,7 @@ void bflb_irq_initialize(void)
|
||||
g_irqvector[i].handler = irq_unexpected_isr;
|
||||
g_irqvector[i].arg = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ATTR_TCM_SECTION uintptr_t bflb_irq_save(void)
|
||||
@ -50,8 +53,13 @@ int bflb_irq_attach(int irq, irq_callback isr, void *arg)
|
||||
if (irq > CONFIG_IRQ_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifndef BL_IOT_SDK
|
||||
g_irqvector[irq].handler = isr;
|
||||
g_irqvector[irq].arg = arg;
|
||||
#else
|
||||
extern void bl_irq_register_with_ctx(int irqnum, void *handler, void *ctx);
|
||||
bl_irq_register_with_ctx(irq, (void *)isr, arg);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -60,8 +68,10 @@ int bflb_irq_detach(int irq)
|
||||
if (irq > CONFIG_IRQ_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifndef BL_IOT_SDK
|
||||
g_irqvector[irq].handler = irq_unexpected_isr;
|
||||
g_irqvector[irq].arg = NULL;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,69 @@ static const bflb_ef_ctrl_com_trim_cfg_t trim_list[] = {
|
||||
.parity_addr = 0x7C * 8 + 12,
|
||||
.value_addr = 0x7C * 8 + 0,
|
||||
.value_len = 12,
|
||||
},
|
||||
{
|
||||
.name = "xtal0",
|
||||
.en_addr = 0x0C * 8 + 9,
|
||||
.parity_addr = 0x0C * 8 + 8,
|
||||
.value_addr = 0x0C * 8 + 2,
|
||||
.value_len = 6,
|
||||
},
|
||||
{
|
||||
.name = "xtal1",
|
||||
.en_addr = 0x70 * 8 + 29,
|
||||
.parity_addr = 0x70 * 8 + 28,
|
||||
.value_addr = 0x70 * 8 + 22,
|
||||
.value_len = 6,
|
||||
},
|
||||
{
|
||||
.name = "xtal2",
|
||||
.en_addr = 0x08 * 8 + 29,
|
||||
.parity_addr = 0x08 * 8 + 28,
|
||||
.value_addr = 0x08 * 8 + 22,
|
||||
.value_len = 6,
|
||||
},
|
||||
{
|
||||
.name = "key_enable_dac_dvdd",
|
||||
.en_addr = 0x58 * 8 + 16,
|
||||
.parity_addr = 0x58 * 8 + 15,
|
||||
.value_addr = 0x58 * 8 + 13,
|
||||
.value_len = 2,
|
||||
},
|
||||
{
|
||||
.name = "key_enable_ldo11",
|
||||
.en_addr = 0x58 * 8 + 12,
|
||||
.parity_addr = 0x58 * 8 + 11,
|
||||
.value_addr = 0x58 * 8 + 7,
|
||||
.value_len = 4,
|
||||
},
|
||||
{
|
||||
.name = "key_enable_tx_power_res",
|
||||
.en_addr = 0x58 * 8 + 6,
|
||||
.parity_addr = 0x58 * 8 + 5,
|
||||
.value_addr = 0x58 * 8 + 0,
|
||||
.value_len = 5,
|
||||
},
|
||||
{
|
||||
.name = "key_disable_dac_dvdd",
|
||||
.en_addr = 0x68 * 8 + 16,
|
||||
.parity_addr = 0x68 * 8 + 15,
|
||||
.value_addr = 0x68 * 8 + 13,
|
||||
.value_len = 2,
|
||||
},
|
||||
{
|
||||
.name = "key_disable_ldo11",
|
||||
.en_addr = 0x68 * 8 + 12,
|
||||
.parity_addr = 0x68 * 8 + 11,
|
||||
.value_addr = 0x68 * 8 + 7,
|
||||
.value_len = 4,
|
||||
},
|
||||
{
|
||||
.name = "key_disable_tx_power_res",
|
||||
.en_addr = 0x68 * 8 + 6,
|
||||
.parity_addr = 0x68 * 8 + 5,
|
||||
.value_addr = 0x68 * 8 + 0,
|
||||
.value_len = 5,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -405,7 +405,7 @@ int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
mbedtls_aes_self_test(1);
|
||||
// mbedtls_aes_self_test(1); /* mbedtls aes test uses dynamic iv(modifies last iv) but hardware does not support */
|
||||
mbedtls_sha1_self_test(1);
|
||||
mbedtls_sha256_self_test(1);
|
||||
mbedtls_sha512_self_test(1);
|
||||
|
9
examples/peripherals/adc/adc_poll_onechan/CMakeLists.txt
Normal file
9
examples/peripherals/adc/adc_poll_onechan/CMakeLists.txt
Normal 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(adc_poll_onechan)
|
13
examples/peripherals/adc/adc_poll_onechan/Makefile
Normal file
13
examples/peripherals/adc/adc_poll_onechan/Makefile
Normal 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
|
51
examples/peripherals/adc/adc_poll_onechan/README.md
Normal file
51
examples/peripherals/adc/adc_poll_onechan/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# adc_poll_onechan
|
||||
|
||||
|
||||
## Support CHIP
|
||||
|
||||
| CHIP | Remark |
|
||||
|:----------------:|:------:|
|
||||
|BL602/BL604 | |
|
||||
|BL702/BL704/BL706 | |
|
||||
|BL702L/BL704L | |
|
||||
|BL616/BL618 | |
|
||||
|BL808 | |
|
||||
|
||||
## Compile
|
||||
|
||||
- BL602/BL604
|
||||
|
||||
```
|
||||
make CHIP=bl602 BOARD=bl602dk
|
||||
```
|
||||
|
||||
- BL702/BL704/BL706
|
||||
|
||||
```
|
||||
make CHIP=bl702 BOARD=bl702dk
|
||||
```
|
||||
|
||||
- BL702L/BL704L
|
||||
|
||||
```
|
||||
make CHIP=bl702l BOARD=bl702ldk
|
||||
```
|
||||
|
||||
- BL616/BL618
|
||||
|
||||
```
|
||||
make CHIP=bl616 BOARD=bl616dk
|
||||
```
|
||||
|
||||
- BL808
|
||||
|
||||
```
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=d0
|
||||
```
|
||||
|
||||
## Flash
|
||||
|
||||
```
|
||||
make flash CHIP=chip_name COMX=xxx # xxx is your com name
|
||||
```
|
11
examples/peripherals/adc/adc_poll_onechan/flash_prog_cfg.ini
Normal file
11
examples/peripherals/adc/adc_poll_onechan/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/adc*_$(CHIPNAME).bin
|
||||
address = 0x000000
|
71
examples/peripherals/adc/adc_poll_onechan/main.c
Normal file
71
examples/peripherals/adc/adc_poll_onechan/main.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include "bflb_adc.h"
|
||||
#include "bflb_mtimer.h"
|
||||
#include "board.h"
|
||||
|
||||
#define TEST_ADC_CHANNEL_x ADC_CHANNEL_8
|
||||
|
||||
static struct bflb_adc_channel_s chan[1] = {
|
||||
{ .pos_chan = TEST_ADC_CHANNEL_x,
|
||||
.neg_chan = ADC_CHANNEL_GND }
|
||||
};
|
||||
|
||||
#define TEST_COUNT 10
|
||||
|
||||
static struct bflb_device_s *adc;
|
||||
|
||||
static uint32_t raw_data;
|
||||
|
||||
void test_adc_poll(void)
|
||||
{
|
||||
struct bflb_adc_result_s result;
|
||||
|
||||
board_adc_gpio_init();
|
||||
|
||||
adc = bflb_device_get_by_name("adc");
|
||||
|
||||
/* adc clock = XCLK / 2 / 32 */
|
||||
struct bflb_adc_config_s cfg;
|
||||
cfg.clk_div = ADC_CLK_DIV_32;
|
||||
cfg.scan_conv_mode = false;
|
||||
cfg.continuous_conv_mode = true; /* do not support single mode */
|
||||
cfg.differential_mode = false;
|
||||
cfg.resolution = ADC_RESOLUTION_16B;
|
||||
cfg.vref = ADC_VREF_3P2V;
|
||||
|
||||
bflb_adc_init(adc, &cfg);
|
||||
bflb_adc_channel_config(adc, chan, 1);
|
||||
|
||||
bflb_adc_start_conversion(adc);
|
||||
|
||||
raw_data = 0;
|
||||
for (uint16_t i = 0; i < TEST_COUNT; i++) {
|
||||
while (bflb_adc_get_count(adc) == 0) {
|
||||
bflb_mtimer_delay_ms(1);
|
||||
}
|
||||
|
||||
if (i > 4) {
|
||||
raw_data += bflb_adc_read_raw(adc);
|
||||
}
|
||||
}
|
||||
|
||||
raw_data = raw_data / 5;
|
||||
|
||||
bflb_adc_stop_conversion(adc);
|
||||
|
||||
bflb_adc_parse_result(adc, &raw_data, &result, 1);
|
||||
|
||||
printf("raw data:%08x\r\n", raw_data);
|
||||
printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt);
|
||||
|
||||
bflb_adc_deinit(adc);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
while (1) {
|
||||
test_adc_poll();
|
||||
bflb_mtimer_delay_ms(1000);
|
||||
}
|
||||
}
|
1
examples/peripherals/adc/adc_poll_onechan/proj.conf
Normal file
1
examples/peripherals/adc/adc_poll_onechan/proj.conf
Normal file
@ -0,0 +1 @@
|
||||
set(CONFIG_COMPONENT1 1)
|
@ -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(auadc_audac_loopback)
|
13
examples/peripherals/audio/auadc_audac_loopback/Makefile
Normal file
13
examples/peripherals/audio/auadc_audac_loopback/Makefile
Normal 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/audio/auadc_audac_loopback/README.md
Normal file
22
examples/peripherals/audio/auadc_audac_loopback/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# audac_play_from_mem
|
||||
|
||||
|
||||
## 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
|
||||
```
|
@ -0,0 +1,12 @@
|
||||
[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/auadc*_$(CHIPNAME).bin
|
||||
address = 0x000000
|
||||
|
208
examples/peripherals/audio/auadc_audac_loopback/main.c
Normal file
208
examples/peripherals/audio/auadc_audac_loopback/main.c
Normal file
@ -0,0 +1,208 @@
|
||||
#include "bflb_auadc.h"
|
||||
#include "bflb_audac.h"
|
||||
#include "bflb_gpio.h"
|
||||
#include "bflb_dma.h"
|
||||
|
||||
#include "bl616_glb.h"
|
||||
#include "board.h"
|
||||
|
||||
struct bflb_device_s *auadc_dma_hd;
|
||||
struct bflb_device_s *audac_dma_hd;
|
||||
|
||||
struct bflb_device_s *auadc_hd;
|
||||
struct bflb_device_s *audac_hd;
|
||||
|
||||
struct bflb_dma_channel_lli_pool_s auadc_dma_lli_pool[10];
|
||||
struct bflb_dma_channel_lli_pool_s audac_dma_lli_pool[10];
|
||||
uint16_t audio_loopback_buff[8 * 1000];
|
||||
|
||||
void auadc_dma_callback(void *arg)
|
||||
{
|
||||
static uint16_t num = 0;
|
||||
num++;
|
||||
printf("scyle_n:%d\r\n", num);
|
||||
}
|
||||
|
||||
/* audio gpio init*/
|
||||
void audio_gpio_init(void)
|
||||
{
|
||||
struct bflb_device_s *gpio;
|
||||
|
||||
gpio = bflb_device_get_by_name("gpio");
|
||||
|
||||
/* auadc input */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_27, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0); /* ain_ch4 */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_28, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0); /* ain_ch5 */
|
||||
|
||||
/* audac pwm output mode */
|
||||
// bflb_gpio_init(gpio, GPIO_PIN_14, GPIO_FUNC_AUDAC_PWM | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
// bflb_gpio_init(gpio, GPIO_PIN_15, GPIO_FUNC_AUDAC_PWM | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
|
||||
// bflb_gpio_init(gpio, GPIO_PIN_22, GPIO_FUNC_AUDAC_PWM | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
// bflb_gpio_init(gpio, GPIO_PIN_23, GPIO_FUNC_AUDAC_PWM | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
|
||||
// bflb_gpio_init(gpio, GPIO_PIN_27, GPIO_FUNC_AUDAC_PWM | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
// bflb_gpio_init(gpio, GPIO_PIN_28, GPIO_FUNC_AUDAC_PWM | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||
|
||||
/* audac gpdac output mode */
|
||||
bflb_gpio_init(gpio, GPIO_PIN_2, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
|
||||
bflb_gpio_init(gpio, GPIO_PIN_3, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
|
||||
}
|
||||
|
||||
/* audio adc init */
|
||||
static void auadc_init(void)
|
||||
{
|
||||
/* audio adc config */
|
||||
struct bflb_auadc_init_config_s auadc_init_cfg = {
|
||||
.sampling_rate = AUADC_SAMPLING_RATE_32K,
|
||||
.input_mode = AUADC_INPUT_MODE_ADC,
|
||||
.data_format = AUADC_DATA_FORMAT_16BIT,
|
||||
.fifo_threshold = 3,
|
||||
};
|
||||
|
||||
/* audio adc analog config */
|
||||
struct bflb_auadc_adc_init_config_s auadc_analog_init_cfg = {
|
||||
.auadc_analog_en = true,
|
||||
.adc_mode = AUADC_ADC_MODE_AUDIO,
|
||||
.adc_pga_mode = AUADC_ADC_PGA_MODE_AC_DIFFER,
|
||||
.adc_pga_posi_ch = AUADC_ADC_ANALOG_CH_4,
|
||||
.adc_pga_nega_ch = AUADC_ADC_ANALOG_CH_5,
|
||||
.adc_pga_gain = 21,
|
||||
};
|
||||
|
||||
/* clock cfg */
|
||||
GLB_Config_AUDIO_PLL_To_491P52M();
|
||||
GLB_PER_Clock_UnGate(GLB_AHB_CLOCK_AUDIO);
|
||||
|
||||
/* auadc init */
|
||||
auadc_hd = bflb_device_get_by_name("auadc");
|
||||
bflb_auadc_init(auadc_hd, &auadc_init_cfg);
|
||||
bflb_auadc_adc_init(auadc_hd, &auadc_analog_init_cfg);
|
||||
/* auadc enable dma */
|
||||
bflb_auadc_link_rxdma(auadc_hd, true);
|
||||
}
|
||||
|
||||
/* audio adc dma init */
|
||||
void auadc_dma_init(void)
|
||||
{
|
||||
uint32_t dma_lli_cnt;
|
||||
struct bflb_dma_channel_lli_transfer_s transfers[1];
|
||||
struct bflb_dma_channel_config_s auadc_dma_cfg;
|
||||
|
||||
auadc_dma_cfg.direction = DMA_PERIPH_TO_MEMORY;
|
||||
auadc_dma_cfg.src_req = DMA_REQUEST_AUADC_RX;
|
||||
auadc_dma_cfg.dst_req = DMA_REQUEST_NONE;
|
||||
auadc_dma_cfg.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
|
||||
auadc_dma_cfg.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
|
||||
auadc_dma_cfg.src_burst_count = DMA_BURST_INCR4;
|
||||
auadc_dma_cfg.dst_burst_count = DMA_BURST_INCR4;
|
||||
auadc_dma_cfg.src_width = DMA_DATA_WIDTH_16BIT;
|
||||
auadc_dma_cfg.dst_width = DMA_DATA_WIDTH_16BIT;
|
||||
|
||||
auadc_dma_hd = bflb_device_get_by_name("dma0_ch0");
|
||||
bflb_dma_channel_init(auadc_dma_hd, &auadc_dma_cfg);
|
||||
bflb_dma_channel_irq_attach(auadc_dma_hd, auadc_dma_callback, NULL);
|
||||
|
||||
transfers[0].src_addr = (uint32_t)DMA_ADDR_AUADC_RDR;
|
||||
transfers[0].dst_addr = (uint32_t)audio_loopback_buff;
|
||||
transfers[0].nbytes = sizeof(audio_loopback_buff);
|
||||
|
||||
dma_lli_cnt = bflb_dma_channel_lli_reload(auadc_dma_hd, auadc_dma_lli_pool, 10, transfers, 1);
|
||||
bflb_dma_channel_lli_link_head(auadc_dma_hd, auadc_dma_lli_pool, dma_lli_cnt);
|
||||
}
|
||||
|
||||
/* audio dac init */
|
||||
static void audac_init(void)
|
||||
{
|
||||
/* audio dac config */
|
||||
struct bflb_audac_init_config_s audac_init_cfg = {
|
||||
.sampling_rate = AUDAC_SAMPLING_RATE_32K,
|
||||
.output_mode = AUDAC_OUTPUT_MODE_GPDAC_CH_A_B, /* gpdac output */
|
||||
.source_channels_num = AUDAC_SOURCE_CHANNEL_SINGLE,
|
||||
.mixer_mode = AUDAC_MIXER_MODE_ONLY_L,
|
||||
.data_format = AUDAC_DATA_FORMAT_16BIT,
|
||||
.fifo_threshold = 3,
|
||||
};
|
||||
|
||||
/* audio dac volume config */
|
||||
struct bflb_audac_volume_config_s audac_volume_cfg = {
|
||||
.mute_ramp_en = true,
|
||||
.mute_up_ramp_rate = AUDAC_RAMP_RATE_FS_32,
|
||||
.mute_down_ramp_rate = AUDAC_RAMP_RATE_FS_8,
|
||||
.volume_update_mode = AUDAC_VOLUME_UPDATE_MODE_RAMP,
|
||||
.volume_ramp_rate = AUDAC_RAMP_RATE_FS_128,
|
||||
.volume_zero_cross_timeout = AUDAC_RAMP_RATE_FS_128,
|
||||
};
|
||||
|
||||
/* clock cfg */
|
||||
GLB_Config_AUDIO_PLL_To_491P52M();
|
||||
GLB_PER_Clock_UnGate(GLB_AHB_CLOCK_AUDIO);
|
||||
|
||||
/* audac init */
|
||||
audac_hd = bflb_device_get_by_name("audac");
|
||||
bflb_audac_init(audac_hd, &audac_init_cfg);
|
||||
bflb_audac_feature_control(audac_hd, AUDAC_CMD_SET_VOLUME_VAL, (size_t)(-5 * 2));
|
||||
bflb_audac_volume_init(audac_hd, &audac_volume_cfg);
|
||||
/* audac enable dma */
|
||||
bflb_audac_link_rxdma(audac_hd, true);
|
||||
}
|
||||
|
||||
/* audio dac dma init */
|
||||
void audac_dma_init(void)
|
||||
{
|
||||
uint32_t dma_lli_cnt;
|
||||
struct bflb_dma_channel_lli_transfer_s transfers[1];
|
||||
struct bflb_dma_channel_config_s audac_dma_cfg;
|
||||
|
||||
audac_dma_cfg.direction = DMA_MEMORY_TO_PERIPH;
|
||||
audac_dma_cfg.src_req = DMA_REQUEST_NONE;
|
||||
audac_dma_cfg.dst_req = DMA_REQUEST_AUDAC_TX;
|
||||
audac_dma_cfg.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
|
||||
audac_dma_cfg.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
|
||||
audac_dma_cfg.src_burst_count = DMA_BURST_INCR4;
|
||||
audac_dma_cfg.dst_burst_count = DMA_BURST_INCR4;
|
||||
audac_dma_cfg.src_width = DMA_DATA_WIDTH_16BIT;
|
||||
audac_dma_cfg.dst_width = DMA_DATA_WIDTH_16BIT;
|
||||
|
||||
audac_dma_hd = bflb_device_get_by_name("dma0_ch1");
|
||||
bflb_dma_channel_init(audac_dma_hd, &audac_dma_cfg);
|
||||
|
||||
transfers[0].src_addr = (uint32_t)audio_loopback_buff;
|
||||
transfers[0].dst_addr = (uint32_t)DMA_ADDR_AUDAC_TDR;
|
||||
transfers[0].nbytes = sizeof(audio_loopback_buff);
|
||||
|
||||
dma_lli_cnt = bflb_dma_channel_lli_reload(audac_dma_hd, audac_dma_lli_pool, 10, transfers, 1);
|
||||
bflb_dma_channel_lli_link_head(audac_dma_hd, audac_dma_lli_pool, dma_lli_cnt);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* board init */
|
||||
board_init();
|
||||
|
||||
printf("audac case start \r\n");
|
||||
|
||||
/* gpio init */
|
||||
audio_gpio_init();
|
||||
|
||||
/* auadc init */
|
||||
auadc_init();
|
||||
auadc_dma_init();
|
||||
bflb_dma_channel_start(auadc_dma_hd);
|
||||
bflb_auadc_feature_control(auadc_hd, AUADC_CMD_RECORD_START, 0);
|
||||
|
||||
/* delay 10ms */
|
||||
bflb_mtimer_delay_ms(10);
|
||||
|
||||
/* audac init */
|
||||
audac_init();
|
||||
audac_dma_init();
|
||||
bflb_dma_channel_start(audac_dma_hd);
|
||||
bflb_audac_feature_control(audac_hd, AUDAC_CMD_PLAY_START, 0);
|
||||
|
||||
printf("audac case end \r\n");
|
||||
|
||||
while (1) {
|
||||
bflb_mtimer_delay_ms(1);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
set(CONFIG_BFLOG 0)
|
||||
|
||||
set(CONFIG_VSNPRINTF_FLOAT 1)
|
||||
set(CONFIG_VSNPRINTF_FLOAT_EX 1)
|
||||
set(CONFIG_VSNPRINTF_LONG_LONG 1)
|
51
examples/peripherals/flash/flash_get_image_hash/README.md
Normal file
51
examples/peripherals/flash/flash_get_image_hash/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# flash_get_image_hash
|
||||
|
||||
|
||||
## Support CHIP
|
||||
|
||||
| CHIP | Remark |
|
||||
|:----------------:|:------:|
|
||||
|BL602/BL604 | |
|
||||
|BL702/BL704/BL706 | |
|
||||
|BL702L/BL704L | |
|
||||
|BL616/BL618 | |
|
||||
|BL808 | |
|
||||
|
||||
## Compile
|
||||
|
||||
- BL602/BL604
|
||||
|
||||
```
|
||||
make CHIP=bl602 BOARD=bl602dk
|
||||
```
|
||||
|
||||
- BL702/BL704/BL706
|
||||
|
||||
```
|
||||
make CHIP=bl702 BOARD=bl702dk
|
||||
```
|
||||
|
||||
- BL702L/BL704L
|
||||
|
||||
```
|
||||
make CHIP=bl702l BOARD=bl702ldk
|
||||
```
|
||||
|
||||
- BL616/BL618
|
||||
|
||||
```
|
||||
make CHIP=bl616 BOARD=bl616dk
|
||||
```
|
||||
|
||||
- BL808
|
||||
|
||||
```
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=d0
|
||||
```
|
||||
|
||||
## Flash
|
||||
|
||||
```
|
||||
make flash CHIP=chip_name COMX=xxx # xxx is your com name
|
||||
```
|
@ -7,13 +7,11 @@
|
||||
struct bflb_device_s *gpio;
|
||||
struct bflb_device_s *uart0;
|
||||
|
||||
void gpio_isr(int irq, void *arg)
|
||||
void gpio0_isr(uint8_t pin)
|
||||
{
|
||||
static int i = 0;
|
||||
bool intstatus = bflb_gpio_get_intstatus(gpio, GPIO_PIN_0);
|
||||
if (intstatus) {
|
||||
bflb_gpio_int_clear(gpio, GPIO_PIN_0);
|
||||
printf("%d\r\n", i++);
|
||||
static uint32_t i = 0;
|
||||
if (pin == GPIO_PIN_0) {
|
||||
printf("i:%d\r\n", i++);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,10 +31,9 @@ int set_int_mode(int argc, char **argv)
|
||||
}
|
||||
|
||||
bflb_irq_disable(gpio->irq_num);
|
||||
bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_INPUT | GPIO_FLOAT | GPIO_SMT_EN);
|
||||
bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN);
|
||||
bflb_gpio_int_init(gpio, GPIO_PIN_0, atoi(argv[1]));
|
||||
bflb_gpio_int_mask(gpio, GPIO_PIN_0, false);
|
||||
bflb_irq_attach(gpio->irq_num, gpio_isr, NULL);
|
||||
bflb_gpio_irq_attach(GPIO_PIN_0, gpio0_isr);
|
||||
bflb_irq_enable(gpio->irq_num);
|
||||
|
||||
return 0;
|
||||
|
@ -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(gpio_output_with_input)
|
13
examples/peripherals/gpio/gpio_output_with_input/Makefile
Normal file
13
examples/peripherals/gpio/gpio_output_with_input/Makefile
Normal 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
|
51
examples/peripherals/gpio/gpio_output_with_input/README.md
Normal file
51
examples/peripherals/gpio/gpio_output_with_input/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# gpio_output_with_input
|
||||
|
||||
|
||||
## Support CHIP
|
||||
|
||||
| CHIP | Remark |
|
||||
|:----------------:|:------:|
|
||||
|BL602/BL604 | |
|
||||
|BL702/BL704/BL706 | |
|
||||
|BL702L/BL704L | |
|
||||
|BL616/BL618 | |
|
||||
|BL808 | |
|
||||
|
||||
## Compile
|
||||
|
||||
- BL602/BL604
|
||||
|
||||
```
|
||||
make CHIP=bl602 BOARD=bl602dk
|
||||
```
|
||||
|
||||
- BL702/BL704/BL706
|
||||
|
||||
```
|
||||
make CHIP=bl702 BOARD=bl702dk
|
||||
```
|
||||
|
||||
- BL702L/BL704L
|
||||
|
||||
```
|
||||
make CHIP=bl702l BOARD=bl702ldk
|
||||
```
|
||||
|
||||
- BL616/BL618
|
||||
|
||||
```
|
||||
make CHIP=bl616 BOARD=bl616dk
|
||||
```
|
||||
|
||||
- BL808
|
||||
|
||||
```
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=d0
|
||||
```
|
||||
|
||||
## Flash
|
||||
|
||||
```
|
||||
make flash CHIP=chip_name COMX=xxx # xxx is your com name
|
||||
```
|
@ -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/gpio*_$(CHIPNAME).bin
|
||||
address = 0x000000
|
23
examples/peripherals/gpio/gpio_output_with_input/main.c
Normal file
23
examples/peripherals/gpio/gpio_output_with_input/main.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "bflb_gpio.h"
|
||||
#include "board.h"
|
||||
|
||||
struct bflb_device_s *gpio;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
gpio = bflb_device_get_by_name("gpio");
|
||||
printf("gpio output\r\n");
|
||||
bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_OUTPUT | GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
|
||||
|
||||
while (1) {
|
||||
bflb_gpio_set(gpio, GPIO_PIN_0);
|
||||
printf("GPIO_PIN_0=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_0));
|
||||
bflb_mtimer_delay_ms(2000);
|
||||
|
||||
bflb_gpio_reset(gpio, GPIO_PIN_0);
|
||||
printf("GPIO_PIN_0=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_0));
|
||||
bflb_mtimer_delay_ms(2000);
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
set(CONFIG_COMPONENT1 1)
|
11
examples/peripherals/i2s/i2s_es8311/CMakeLists.txt
Normal file
11
examples/peripherals/i2s/i2s_es8311/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
include(proj.conf)
|
||||
|
||||
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
|
||||
|
||||
sdk_add_include_directories(.)
|
||||
target_sources(app PRIVATE bsp_es8311.c)
|
||||
sdk_set_main_file(main.c)
|
||||
|
||||
project(i2s_es8311)
|
13
examples/peripherals/i2s/i2s_es8311/Makefile
Normal file
13
examples/peripherals/i2s/i2s_es8311/Makefile
Normal 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_es8311/README.md
Normal file
22
examples/peripherals/i2s/i2s_es8311/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# i2s_es8311
|
||||
|
||||
|
||||
## 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
|
||||
```
|
751
examples/peripherals/i2s/i2s_es8311/bsp_es8311.c
Normal file
751
examples/peripherals/i2s/i2s_es8311/bsp_es8311.c
Normal file
@ -0,0 +1,751 @@
|
||||
/**
|
||||
* @file bsp_es8311.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2023 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_es8311.h"
|
||||
|
||||
// ES8311 I2C addr 0x18 0x19
|
||||
#define ES8311_I2C_SLAVE_ADDR 0x18
|
||||
|
||||
/*
|
||||
* to define the clock soure of MCLK
|
||||
*/
|
||||
#define FROM_MCLK_PIN (0)
|
||||
#define FROM_SCLK_PIN (1)
|
||||
/*
|
||||
* to define whether to reverse the clock
|
||||
*/
|
||||
#define INVERT_MCLK 0 // do not invert
|
||||
#define INVERT_SCLK 0
|
||||
|
||||
#define IS_DMIC 0 // Is it a digital microphone
|
||||
|
||||
#define MCLK_DIV_FRE 256
|
||||
|
||||
/*
|
||||
* Clock coefficient structer
|
||||
*/
|
||||
struct _coeff_div {
|
||||
uint32_t mclk; /* mclk frequency */
|
||||
uint32_t rate; /* sample rate */
|
||||
uint8_t pre_div; /* the pre divider with range from 1 to 8 */
|
||||
uint8_t pre_multi; /* the pre multiplier with x1, x2, x4 and x8 selection */
|
||||
uint8_t adc_div; /* adcclk divider */
|
||||
uint8_t dac_div; /* dacclk divider */
|
||||
uint8_t fs_mode; /* double speed or single speed, =0, ss, =1, ds */
|
||||
uint8_t lrck_h; /* adclrck divider and daclrck divider */
|
||||
uint8_t lrck_l;
|
||||
uint8_t bclk_div; /* sclk divider */
|
||||
uint8_t adc_osr; /* adc osr */
|
||||
uint8_t dac_osr; /* dac osr */
|
||||
};
|
||||
|
||||
/* codec hifi mclk clock divider coefficients */
|
||||
static const struct _coeff_div coeff_div[] = {
|
||||
//mclk rate pre_div mult adc_div dac_div fs_mode lrch lrcl bckdiv osr
|
||||
/* 8k */
|
||||
{12288000, 8000 , 0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{18432000, 8000 , 0x03, 0x02, 0x03, 0x03, 0x00, 0x05, 0xff, 0x18, 0x10, 0x20},
|
||||
{16384000, 8000 , 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{8192000 , 8000 , 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{6144000 , 8000 , 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{4096000 , 8000 , 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{3072000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{2048000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{1536000 , 8000 , 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{1024000 , 8000 , 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
/* 11.025k */
|
||||
{11289600, 11025, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{5644800 , 11025, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{2822400 , 11025, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{1411200 , 11025, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
/* 12k */
|
||||
{12288000, 12000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{6144000 , 12000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{3072000 , 12000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{1536000 , 12000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
/* 16k */
|
||||
{12288000, 16000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{18432000, 16000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x20},
|
||||
{16384000, 16000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{8192000 , 16000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{6144000 , 16000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{4096000 , 16000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{3072000 , 16000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{2048000 , 16000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{1536000 , 16000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
{1024000 , 16000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x20},
|
||||
|
||||
/* 22.05k */
|
||||
{11289600, 22050, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{5644800 , 22050, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{2822400 , 22050, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1411200 , 22050, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
/* 24k */
|
||||
{12288000, 24000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 24000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{6144000 , 24000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{3072000 , 24000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1536000 , 24000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
/* 32k */
|
||||
{12288000, 32000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 32000, 0x03, 0x04, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10},
|
||||
{16384000, 32000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{8192000 , 32000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{6144000 , 32000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{4096000 , 32000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{3072000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{2048000 , 32000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1536000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
{1024000 , 32000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
/* 44.1k */
|
||||
{11289600, 44100, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{5644800 , 44100, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{2822400 , 44100, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1411200 , 44100, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
/* 48k */
|
||||
{12288000, 48000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 48000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{6144000 , 48000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{3072000 , 48000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1536000 , 48000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
|
||||
/* 64k */
|
||||
{12288000, 64000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 64000, 0x03, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
|
||||
{16384000, 64000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{8192000 , 64000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{6144000 , 64000, 0x01, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
|
||||
{4096000 , 64000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{3072000 , 64000, 0x01, 0x08, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
|
||||
{2048000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1536000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0xbf, 0x03, 0x18, 0x18},
|
||||
{1024000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
|
||||
/* 88.2k */
|
||||
{11289600, 88200, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{5644800 , 88200, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{2822400 , 88200, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1411200 , 88200, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
|
||||
/* 96k */
|
||||
{12288000, 96000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{18432000, 96000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{6144000 , 96000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{3072000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
|
||||
{1536000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
|
||||
};
|
||||
|
||||
static int get_es8311_mclk_src(void)
|
||||
{
|
||||
return FROM_SCLK_PIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* look for the coefficient in coeff_div[] table
|
||||
*/
|
||||
static int get_coeff(uint32_t mclk, uint32_t rate)
|
||||
{
|
||||
for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) {
|
||||
if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static struct bflb_device_s *i2c0;
|
||||
static struct bflb_i2c_msg_s msgs[2];
|
||||
|
||||
|
||||
int es8311_i2c_init(void)
|
||||
{
|
||||
i2c0 = bflb_device_get_by_name("i2c0");
|
||||
if (i2c0 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
bflb_i2c_init(i2c0, 200000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int es8311_write_reg(uint8_t addr, uint8_t data)
|
||||
{
|
||||
msgs[0].addr = ES8311_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);
|
||||
}
|
||||
|
||||
int es8311_read_reg(uint8_t addr, uint8_t *rdata)
|
||||
{
|
||||
msgs[0].addr = ES8311_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);
|
||||
}
|
||||
|
||||
/*
|
||||
* set es8311 dac mute or not
|
||||
* if mute = 0, dac un-mute
|
||||
* if mute = 1, dac mute
|
||||
*/
|
||||
static void es8311_mute(int mute)
|
||||
{
|
||||
uint8_t regv;
|
||||
printf("Enter into es8311_mute(), mute = %d\r\n", mute);
|
||||
es8311_read_reg(ES8311_DAC_REG31, ®v);
|
||||
regv &= 0x9f;
|
||||
if (mute) {
|
||||
es8311_write_reg(ES8311_SYSTEM_REG12, 0x02);
|
||||
es8311_write_reg(ES8311_DAC_REG31, (regv | 0x60));
|
||||
es8311_write_reg(ES8311_DAC_REG32, 0x00);
|
||||
es8311_write_reg(ES8311_DAC_REG37, 0x08);
|
||||
} else {
|
||||
es8311_write_reg(ES8311_DAC_REG31, regv);
|
||||
es8311_write_reg(ES8311_SYSTEM_REG12, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set es8311 into suspend mode
|
||||
*/
|
||||
static void es8311_suspend(void)
|
||||
{
|
||||
printf("Enter into es8311_suspend()\r\n");
|
||||
es8311_write_reg(ES8311_DAC_REG32, 0x00);
|
||||
es8311_write_reg(ES8311_ADC_REG17, 0x00);
|
||||
es8311_write_reg(ES8311_SYSTEM_REG0E, 0xFF);
|
||||
es8311_write_reg(ES8311_SYSTEM_REG12, 0x02);
|
||||
es8311_write_reg(ES8311_SYSTEM_REG14, 0x00);
|
||||
es8311_write_reg(ES8311_SYSTEM_REG0D, 0xFA);
|
||||
es8311_write_reg(ES8311_ADC_REG15, 0x00);
|
||||
es8311_write_reg(ES8311_DAC_REG37, 0x08);
|
||||
es8311_write_reg(ES8311_GP_REG45, 0x01);
|
||||
}
|
||||
|
||||
void es8311_reg_dump(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t tmp;
|
||||
|
||||
// es8311_read_reg(ES8311_CHIP_ID1, &tmp);
|
||||
// printf("Reg[%02d]=0x%02x \n", ES8311_CHIP_ID1, tmp);
|
||||
|
||||
for (i = 0; i < 0X45; i++) {
|
||||
if (es8311_read_reg(i, &tmp) != 0) {
|
||||
printf("iic read err\r\n");
|
||||
}
|
||||
|
||||
printf("Reg[%02d]=0x%02x \r\n", i, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
int es8311_config_fmt(i2s_es8311_format_t fmt)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t adc_iface = 0, dac_iface = 0;
|
||||
ret |= es8311_read_reg(ES8311_SDPIN_REG09, &dac_iface);
|
||||
ret |= es8311_read_reg(ES8311_SDPOUT_REG0A, &dac_iface);
|
||||
switch (fmt) {
|
||||
case ES8311_I2S_NORMAL:
|
||||
printf("ES8311 in I2S Format\r\n");
|
||||
dac_iface &= 0xFC;
|
||||
adc_iface &= 0xFC;
|
||||
break;
|
||||
case ES8311_I2S_LEFT:
|
||||
case ES8311_I2S_RIGHT:
|
||||
printf("ES8311 in LJ Format\r\n");
|
||||
adc_iface &= 0xFC;
|
||||
dac_iface &= 0xFC;
|
||||
adc_iface |= 0x01;
|
||||
dac_iface |= 0x01;
|
||||
break;
|
||||
case ES8311_I2S_DSP:
|
||||
printf("ES8311 in DSP-A Format\r\n");
|
||||
adc_iface &= 0xDC;
|
||||
dac_iface &= 0xDC;
|
||||
adc_iface |= 0x03;
|
||||
dac_iface |= 0x03;
|
||||
break;
|
||||
default:
|
||||
dac_iface &= 0xFC;
|
||||
adc_iface &= 0xFC;
|
||||
break;
|
||||
}
|
||||
ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
|
||||
ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int es8311_set_bits_per_sample(i2s_es8311_bits_t bits)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t adc_iface = 0, dac_iface = 0;
|
||||
ret |= es8311_read_reg(ES8311_SDPIN_REG09, &dac_iface);
|
||||
ret |= es8311_read_reg(ES8311_SDPOUT_REG0A, &dac_iface);
|
||||
switch (bits) {
|
||||
case ES8311_BIT_LENGTH_16BITS:
|
||||
dac_iface |= 0x0c;
|
||||
adc_iface |= 0x0c;
|
||||
break;
|
||||
case ES8311_BIT_LENGTH_24BITS:
|
||||
break;
|
||||
case ES8311_BIT_LENGTH_32BITS:
|
||||
dac_iface |= 0x10;
|
||||
adc_iface |= 0x10;
|
||||
break;
|
||||
default:
|
||||
dac_iface |= 0x0c;
|
||||
adc_iface |= 0x0c;
|
||||
break;
|
||||
|
||||
}
|
||||
ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
|
||||
ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int es8311_init(i2s_es8311_t *i2s_cfg)
|
||||
{
|
||||
int ret = 0;
|
||||
int coeff;
|
||||
uint8_t read_data, datmp;
|
||||
|
||||
ret = es8311_i2c_init();
|
||||
if (ret < 0) {
|
||||
printf("es8311 i2c init failed!\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret |= es8311_read_reg(ES8311_CHIP_ID1, &read_data);
|
||||
if (read_data != ES8311_DEFAULT_ID1) {
|
||||
printf("read chip id failed!\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* reset 8311 to its default */
|
||||
ret |= es8311_write_reg(ES8311_RESET_REG00, RST_DIG | RST_CMG | RST_MST | RST_ADC_DIG | RST_DAC_DIG);
|
||||
|
||||
bflb_mtimer_delay_ms(20);
|
||||
|
||||
ret |= es8311_write_reg(ES8311_RESET_REG00, 0x00);
|
||||
ret |= es8311_write_reg(ES8311_RESET_REG00, CSM_ON); // power on cmd
|
||||
|
||||
// /* setup clock: source BCLK, polarities defaults, ADC and DAC clocks on */
|
||||
// ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, MCLK_SEL | BCLK_ON | CLKADC_ON | CLKDAC_ON | ANACLKADC_ON | ANACLKDAC_ON);
|
||||
|
||||
// /* Frecuency config with BCLK = 32 * LRCK (automatic from uC frame) => IMCLK = 8 * BCLK
|
||||
// * Simple math ==> IMCLK = (32 * 8 * LRCK) , where LRCK = Sample Rate*/
|
||||
// ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, MULT_PRE | DIV_PRE);
|
||||
|
||||
// /* register ES8311_CLK_MANAGER_REG03 as default after POR */
|
||||
// /* register ES8311_CLK_MANAGER_REG04 as default after POR */
|
||||
// /* Oversampling as POR defaults on REG03 and REG04 */
|
||||
|
||||
// /* DIV_CLKADC=0 and DIV_CLKDAC=0 as defaults, but just for reasurement*/
|
||||
// ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, DIV_CLKADC | DIV_CLKDAC);
|
||||
|
||||
// /* register ES8311_CLK_MANAGER_REG06 as default after POR */
|
||||
// /* register ES8311_CLK_MANAGER_REG07 as default after POR */
|
||||
// /* register ES8311_CLK_MANAGER_REG08 as default after POR */
|
||||
// /**
|
||||
// * REG06, REG07 and REG08 has no use in slave operation as DIV_BCLK and DIV_LRCK are disabled
|
||||
// */
|
||||
|
||||
// /* Setup audio format (fmt): master/slave, resolution, I2S
|
||||
// *
|
||||
// * Beware, example code has a new reset on REG00 with 0xBF value
|
||||
// * Not sure if needed here*/
|
||||
// // ret |= es8311_write_reg(ES8311_RESET_REG00, 0xBF);
|
||||
|
||||
// /* Setup SDP In and Out resolution 16bits both */
|
||||
// ret |= es8311_write_reg(ES8311_SDPIN_REG09, SDP_IN_WL_16BIT);
|
||||
// ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, SDP_IN_WL_16BIT);
|
||||
// /**
|
||||
// * SDP_IN_FMT (REG09 [1:0]) have a default value (00) so its config as I2S serial audio data format
|
||||
// * Check if Left Justify is needed (01). Not sure about this
|
||||
// *
|
||||
// * Same with SDP_OUT_FMT
|
||||
// *
|
||||
// */
|
||||
|
||||
// ret |= es8311_write_reg(ES8311_SYSTEM_REG0D, REG_0D_DEFAULT); // Power up analog circuitry - NOT default
|
||||
// ret |= es8311_write_reg(ES8311_SYSTEM_REG0E, REG_0E_DEFAULT); // Enable analog PGA, enable ADC modulator - NOT default
|
||||
// ret |= es8311_write_reg(ES8311_SYSTEM_REG12, REG_12_DEFAULT); // power-up DAC - NOT default
|
||||
// ret |= es8311_write_reg(ES8311_SYSTEM_REG13, HPSW); // Enable output to HP drive - NOT default
|
||||
// ret |= es8311_write_reg(ES8311_ADC_REG1C, REG_1C_DEFAULT); // ADC Equalizer bypass, cancel DC offset in digital domain
|
||||
|
||||
// /* DAC ramprate and bypass DAC equalizer - NOT default */
|
||||
// ret |= es8311_write_reg(ES8311_DAC_REG37, DAC_RAMPRATE_DEFAULT | DAC_EQBYPASS_DEFAULT);
|
||||
|
||||
// /* Set DAC Volume */
|
||||
// ret |= es8311_write_reg(ES8311_DAC_REG32, DAC_VOL_PERCENT_LEVEL(80));
|
||||
|
||||
// /* Set ADC Volume */
|
||||
// ret |= es8311_write_reg(ES8311_ADC_REG17, ADC_VOL_PERCENT_LEVEL(70));
|
||||
|
||||
// /* Set max PGA Gain for Mic (differential input) and turn DIG_MIC off */
|
||||
// ret |= es8311_write_reg(ES8311_SYSTEM_REG14, LINSEL | PGAGAIN_15DB);
|
||||
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x10);
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, 0x00);
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, 0x10);
|
||||
ret |= es8311_write_reg(ES8311_ADC_REG16, 0x04);
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, 0x10);
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, 0x00);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG0B, 0x00);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG0C, 0x20);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG10, 0x13);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG11, 0x7C);
|
||||
ret |= es8311_write_reg(ES8311_RESET_REG00, 0x80);
|
||||
|
||||
ret |= es8311_read_reg(ES8311_RESET_REG00, &read_data);
|
||||
switch (i2s_cfg->mode) {
|
||||
case ES8311_MODE_MASTER: /* MASTER MODE */
|
||||
read_data |= 0x40;
|
||||
break;
|
||||
case ES8311_MODE_SLAVE: /* SLAVE MODE */
|
||||
read_data &= 0xBF;
|
||||
break;
|
||||
default:
|
||||
read_data &= 0xBF;
|
||||
break;
|
||||
}
|
||||
ret |= es8311_write_reg(ES8311_RESET_REG00, read_data);
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x1F);
|
||||
|
||||
/* select clock source for internal mclk */
|
||||
switch(get_es8311_mclk_src()) {
|
||||
case FROM_MCLK_PIN:
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG01, &read_data);
|
||||
read_data &= 0x7F;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, read_data);
|
||||
break;
|
||||
case FROM_SCLK_PIN:
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG01, &read_data);
|
||||
read_data |= 0x80;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, read_data);
|
||||
break;
|
||||
default:
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG01, &read_data);
|
||||
read_data &= 0x7F;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, read_data);
|
||||
break;
|
||||
}
|
||||
|
||||
int sample_fre = 0;
|
||||
int mclk_fre = 0;
|
||||
switch (i2s_cfg->samples) {
|
||||
case ES8311_08K_SAMPLES:
|
||||
sample_fre = 8000;
|
||||
break;
|
||||
case ES8311_11K_SAMPLES:
|
||||
sample_fre = 11025;
|
||||
break;
|
||||
case ES8311_16K_SAMPLES:
|
||||
sample_fre = 16000;
|
||||
break;
|
||||
case ES8311_22K_SAMPLES:
|
||||
sample_fre = 22050;
|
||||
break;
|
||||
case ES8311_24K_SAMPLES:
|
||||
sample_fre = 24000;
|
||||
break;
|
||||
case ES8311_32K_SAMPLES:
|
||||
sample_fre = 32000;
|
||||
break;
|
||||
case ES8311_44K_SAMPLES:
|
||||
sample_fre = 44100;
|
||||
break;
|
||||
case ES8311_48K_SAMPLES:
|
||||
sample_fre = 48000;
|
||||
break;
|
||||
default:
|
||||
printf("Unable to configure sample rate %dHz\r\n", sample_fre);
|
||||
break;
|
||||
}
|
||||
|
||||
mclk_fre = sample_fre * MCLK_DIV_FRE;
|
||||
coeff = get_coeff(mclk_fre, sample_fre);
|
||||
if (coeff < 0) {
|
||||
printf("Unable to configure sample rate %dHz with %dHz MCLK\r\n", sample_fre, mclk_fre);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set clock parammeters
|
||||
*/
|
||||
if (coeff >= 0) {
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG02, &read_data);
|
||||
read_data &= 0x07;
|
||||
read_data |= (coeff_div[coeff].pre_div - 1) << 5;
|
||||
datmp = 0;
|
||||
switch (coeff_div[coeff].pre_multi) {
|
||||
case 1:
|
||||
datmp = 0;
|
||||
break;
|
||||
case 2:
|
||||
datmp = 1;
|
||||
break;
|
||||
case 4:
|
||||
datmp = 2;
|
||||
break;
|
||||
case 8:
|
||||
datmp = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_es8311_mclk_src() == FROM_SCLK_PIN) {
|
||||
datmp = 3; /* DIG_MCLK = LRCK * 256 = BCLK * 8 */
|
||||
}
|
||||
|
||||
read_data |= (datmp) << 3;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, read_data);
|
||||
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG05, &read_data);
|
||||
read_data &= 0x00;
|
||||
read_data |= (coeff_div[coeff].adc_div - 1) << 4;
|
||||
read_data |= (coeff_div[coeff].dac_div - 1) << 0;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, read_data);
|
||||
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG03, &read_data);
|
||||
read_data &= 0x80;
|
||||
read_data |= coeff_div[coeff].fs_mode << 6;
|
||||
read_data |= coeff_div[coeff].adc_osr << 0;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, read_data);
|
||||
|
||||
ret = es8311_read_reg(ES8311_CLK_MANAGER_REG04, &read_data);
|
||||
read_data &= 0x80;
|
||||
read_data |= coeff_div[coeff].dac_osr << 0;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, read_data);
|
||||
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG07, &read_data);
|
||||
read_data &= 0xC0;
|
||||
read_data |= coeff_div[coeff].lrck_h << 0;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG07, read_data);
|
||||
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG08, &read_data);
|
||||
read_data &= 0x00;
|
||||
read_data |= coeff_div[coeff].lrck_l << 0;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG08, read_data);
|
||||
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG06, &read_data);
|
||||
read_data &= 0xE0;
|
||||
if (coeff_div[coeff].bclk_div < 19) {
|
||||
read_data |= (coeff_div[coeff].bclk_div - 1) << 0;
|
||||
} else {
|
||||
read_data |= (coeff_div[coeff].bclk_div) << 0;
|
||||
}
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, read_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* mclk inverted or not
|
||||
*/
|
||||
if (INVERT_MCLK) {
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG01, &read_data);
|
||||
read_data |= 0x40;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, read_data);
|
||||
} else {
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG01, &read_data);
|
||||
read_data &= ~(0x40);
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, read_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* sclk inverted or not
|
||||
*/
|
||||
if (INVERT_SCLK) {
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG06, &read_data);
|
||||
read_data |= 0x20;
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, read_data);
|
||||
} else {
|
||||
ret |= es8311_read_reg(ES8311_CLK_MANAGER_REG06, &read_data);
|
||||
read_data &= ~(0x20);
|
||||
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, read_data);
|
||||
}
|
||||
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG13, 0x10);
|
||||
ret |= es8311_write_reg(ES8311_ADC_REG1B, 0x0A);
|
||||
ret |= es8311_write_reg(ES8311_ADC_REG1C, 0x6A);
|
||||
|
||||
es8311_config_fmt(i2s_cfg->fmt);
|
||||
es8311_set_bits_per_sample(i2s_cfg->bits);
|
||||
|
||||
// es8311_reg_dump();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int es8311_codec_deinit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef BIT
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
#endif
|
||||
|
||||
int es8311_start(es_module_t mode)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t adc_iface = 0, dac_iface = 0;
|
||||
|
||||
ret |= es8311_read_reg(ES8311_SDPIN_REG09, &dac_iface);
|
||||
dac_iface &= 0xBF;
|
||||
ret |= es8311_read_reg(ES8311_SDPOUT_REG0A, &adc_iface);
|
||||
adc_iface &= 0xBF;
|
||||
adc_iface |= BIT(6);
|
||||
dac_iface |= BIT(6);
|
||||
|
||||
if (mode == ES_MODULE_LINE) {
|
||||
return -1;
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
||||
adc_iface &= ~(BIT(6));
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
||||
dac_iface &= ~(BIT(6));
|
||||
}
|
||||
|
||||
ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
|
||||
ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
|
||||
|
||||
ret |= es8311_write_reg(ES8311_ADC_REG17, 0xBF);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG0E, 0x02);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG12, 0x00);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG14, 0x15);
|
||||
|
||||
/*
|
||||
* pdm dmic enable or disable
|
||||
*/
|
||||
uint8_t regv = 0;
|
||||
if (IS_DMIC) {
|
||||
ret |= es8311_read_reg(ES8311_SYSTEM_REG14, ®v);
|
||||
regv |= 0x40;
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv);
|
||||
} else {
|
||||
ret |= es8311_read_reg(ES8311_SYSTEM_REG14, ®v);
|
||||
regv &= ~(0x40);
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv);
|
||||
}
|
||||
|
||||
ret |= es8311_write_reg(ES8311_SYSTEM_REG0D, REG_0D_DEFAULT);
|
||||
ret |= es8311_write_reg(ES8311_ADC_REG15, 0x40);
|
||||
ret |= es8311_write_reg(ES8311_DAC_REG37, 0x48);
|
||||
ret |= es8311_write_reg(ES8311_GP_REG45, 0x00);
|
||||
|
||||
/* set internal reference signal (ADCL + DACR) */
|
||||
ret |= es8311_write_reg(ES8311_GPIO_REG44, 0x50);
|
||||
|
||||
// es8311_reg_dump();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int es8311_stop(es_module_t mode)
|
||||
{
|
||||
int ret = 0;
|
||||
es8311_suspend();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int es8311_codec_set_voice_volume(int volume)
|
||||
{
|
||||
int res = 0;
|
||||
if (volume < 0) {
|
||||
volume = 0;
|
||||
} else if (volume > 100) {
|
||||
volume = 100;
|
||||
}
|
||||
int vol = (volume) * 2550 / 1000;
|
||||
printf("SET: volume:%d%%\r\n", volume);
|
||||
es8311_write_reg(ES8311_DAC_REG32, vol);
|
||||
return res;
|
||||
}
|
||||
|
||||
int es8311_codec_get_voice_volume(int *volume)
|
||||
{
|
||||
int ret = 0;
|
||||
int regv = 0;
|
||||
ret = es8311_read_reg(ES8311_DAC_REG32, ®v);
|
||||
if (regv != 0) {
|
||||
*volume = 0;
|
||||
ret = -1;
|
||||
} else {
|
||||
*volume = regv * 100 / 256;
|
||||
}
|
||||
printf("GET: res:%d, volume:%d\r\n", regv, *volume);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int es8311_set_voice_mute(bool enable)
|
||||
{
|
||||
int ret = 0;
|
||||
printf("Es8311SetVoiceMute volume:%d\r\n", enable);
|
||||
es8311_mute(enable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int es8311_get_voice_mute(int *mute)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t reg = 0;
|
||||
ret = es8311_read_reg(ES8311_DAC_REG31, ®);
|
||||
if (ret == 0) {
|
||||
reg = (ret & 0x20) >> 5;
|
||||
}
|
||||
*mute = reg;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int es8311_set_mic_gain(i2s_es8311_mic_gain_t gain_db)
|
||||
{
|
||||
int res = 0;
|
||||
res = es8311_write_reg(ES8311_ADC_REG16, gain_db); // MIC gain scale
|
||||
return res;
|
||||
}
|
||||
|
280
examples/peripherals/i2s/i2s_es8311/bsp_es8311.h
Normal file
280
examples/peripherals/i2s/i2s_es8311/bsp_es8311.h
Normal file
@ -0,0 +1,280 @@
|
||||
/**
|
||||
* @file bsp_es8311.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2023 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 __ES8311_H__
|
||||
#define __ES8311_H__
|
||||
|
||||
typedef enum {
|
||||
ES_MODULE_MIN = -1,
|
||||
ES_MODULE_ADC = 0x01,
|
||||
ES_MODULE_DAC = 0x02,
|
||||
ES_MODULE_ADC_DAC = 0x03,
|
||||
ES_MODULE_LINE = 0x04,
|
||||
ES_MODULE_MAX
|
||||
} es_module_t;
|
||||
|
||||
typedef enum {
|
||||
ES8311_MODE_SLAVE = 0x00, /*!< set slave mode */
|
||||
ES8311_MODE_MASTER = 0x01, /*!< set master mode */
|
||||
} i2s_es8311_mode_t;
|
||||
|
||||
typedef enum {
|
||||
ES8311_I2S_NORMAL = 0, /*!< set normal I2S format */
|
||||
ES8311_I2S_LEFT, /*!< set all left format */
|
||||
ES8311_I2S_RIGHT, /*!< set all right format */
|
||||
ES8311_I2S_DSP, /*!< set dsp/pcm format */
|
||||
} i2s_es8311_format_t;
|
||||
|
||||
typedef enum {
|
||||
ES8311_08K_SAMPLES, /*!< set to 8k samples per second */
|
||||
ES8311_11K_SAMPLES, /*!< set to 11.025k samples per second */
|
||||
ES8311_16K_SAMPLES, /*!< set to 16k samples in per second */
|
||||
ES8311_22K_SAMPLES, /*!< set to 22.050k samples per second */
|
||||
ES8311_24K_SAMPLES, /*!< set to 24k samples in per second */
|
||||
ES8311_32K_SAMPLES, /*!< set to 32k samples in per second */
|
||||
ES8311_44K_SAMPLES, /*!< set to 44.1k samples per second */
|
||||
ES8311_48K_SAMPLES, /*!< set to 48k samples per second */
|
||||
} i2s_es8311_samples_t;
|
||||
|
||||
typedef enum {
|
||||
ES8311_BIT_LENGTH_16BITS = 1, /*!< set 16 bits per sample */
|
||||
ES8311_BIT_LENGTH_24BITS, /*!< set 24 bits per sample */
|
||||
ES8311_BIT_LENGTH_32BITS, /*!< set 32 bits per sample */
|
||||
} i2s_es8311_bits_t;
|
||||
|
||||
typedef enum {
|
||||
ES8311_MIC_GAIN_MIN = -1,
|
||||
ES8311_MIC_GAIN_0DB,
|
||||
ES8311_MIC_GAIN_6DB,
|
||||
ES8311_MIC_GAIN_12DB,
|
||||
ES8311_MIC_GAIN_18DB,
|
||||
ES8311_MIC_GAIN_24DB,
|
||||
ES8311_MIC_GAIN_30DB,
|
||||
ES8311_MIC_GAIN_36DB,
|
||||
ES8311_MIC_GAIN_42DB,
|
||||
ES8311_MIC_GAIN_MAX
|
||||
} i2s_es8311_mic_gain_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
i2s_es8311_mode_t mode; /*!< audio codec chip mode */
|
||||
i2s_es8311_format_t fmt; /*!< I2S interface format */
|
||||
i2s_es8311_samples_t samples; /*!< I2S interface samples per second */
|
||||
i2s_es8311_bits_t bits; /*!< i2s interface number of bits per sample */
|
||||
} i2s_es8311_t;
|
||||
|
||||
/******************************************************************************
|
||||
* DEFINICIONES DE REGISTROS PARA ES8311
|
||||
*****************************************************************************/
|
||||
#define ES8311_RESET_REG00 0x00 /* reset digital,csm,clock manager etc.*/
|
||||
#define ES8311_CLK_MANAGER_REG01 0x01 /* select clk src for mclk, enable clock for codec */
|
||||
#define ES8311_CLK_MANAGER_REG02 0x02 /* clk divider and clk multiplier */
|
||||
#define ES8311_CLK_MANAGER_REG03 0x03 /* adc fsmode and osr */
|
||||
#define ES8311_CLK_MANAGER_REG04 0x04 /* dac osr */
|
||||
#define ES8311_CLK_MANAGER_REG05 0x05 /* clk divier for adc and dac */
|
||||
#define ES8311_CLK_MANAGER_REG06 0x06 /* bclk inverter and divider */
|
||||
#define ES8311_CLK_MANAGER_REG07 0x07 /* tri-state, lrck divider */
|
||||
#define ES8311_CLK_MANAGER_REG08 0x08 /* lrck divider */
|
||||
#define ES8311_SDPIN_REG09 0x09 /* dac serial digital port */
|
||||
#define ES8311_SDPOUT_REG0A 0x0A /* adc serial digital port */
|
||||
#define ES8311_SYSTEM_REG0B 0x0B /* system */
|
||||
#define ES8311_SYSTEM_REG0C 0x0C /* system */
|
||||
#define ES8311_SYSTEM_REG0D 0x0D /* system, power up/down */
|
||||
#define ES8311_SYSTEM_REG0E 0x0E /* system, power up/down */
|
||||
#define ES8311_SYSTEM_REG0F 0x0F /* system, low power */
|
||||
#define ES8311_SYSTEM_REG10 0x10 /* system */
|
||||
#define ES8311_SYSTEM_REG11 0x11 /* system */
|
||||
#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */
|
||||
#define ES8311_SYSTEM_REG13 0x13 /* system */
|
||||
#define ES8311_SYSTEM_REG14 0x14 /* system, select DMIC, select analog pga gain */
|
||||
#define ES8311_ADC_REG15 0x15 /* ADC, adc ramp rate, dmic sense */
|
||||
#define ES8311_ADC_REG16 0x16 /* ADC */
|
||||
#define ES8311_ADC_REG17 0x17 /* ADC, volume */
|
||||
#define ES8311_ADC_REG18 0x18 /* ADC, alc enable and winsize */
|
||||
#define ES8311_ADC_REG19 0x19 /* ADC, alc maxlevel */
|
||||
#define ES8311_ADC_REG1A 0x1A /* ADC, alc automute */
|
||||
#define ES8311_ADC_REG1B 0x1B /* ADC, alc automute, adc hpf s1 */
|
||||
#define ES8311_ADC_REG1C 0x1C /* ADC, equalizer, hpf s2 */
|
||||
#define ES8311_DAC_REG31 0x31 /* DAC, mute */
|
||||
#define ES8311_DAC_REG32 0x32 /* DAC, volume */
|
||||
#define ES8311_DAC_REG33 0x33 /* DAC, offset */
|
||||
#define ES8311_DAC_REG34 0x34 /* DAC, drc enable, drc winsize */
|
||||
#define ES8311_DAC_REG35 0x35 /* DAC, drc maxlevel, minilevel */
|
||||
#define ES8311_DAC_REG37 0x37 /* DAC, ramprate */
|
||||
#define ES8311_GPIO_REG44 0x44 /* GPIO, dac2adc for test */
|
||||
#define ES8311_GP_REG45 0x45 /* GP CONTROL */
|
||||
#define ES8311_CHIP_ID1 0xFD /* CHIP ID1 */
|
||||
#define ES8311_CHIP_ID2 0xFE /* CHIP ID2 */
|
||||
#define ES8311_CHIP_VER 0xFF /* VERSION */
|
||||
#define ES8311_MAX_REGISTER 0xFF
|
||||
|
||||
#define ES8311_DEFAULT_ID1 0x83
|
||||
#define ES8311_DEFAULT_ID2 0x11
|
||||
#define ES8311_DEFAULT_VER 0x00
|
||||
|
||||
/******************************************************************************
|
||||
* DEFINICIONES DE BITS PARA ES8311
|
||||
*****************************************************************************/
|
||||
|
||||
//------------------------- RESET REG 0x00 -----------------------------------
|
||||
|
||||
#define CSM_ON 0x80 //<--- Mask of CSM_ON bit
|
||||
#define MSC 0x40 //<--- Mask of MSC bit
|
||||
#define SEQ_DIS 0x20 //<--- Mask of SEQ_DIS bit
|
||||
#define RST_DIG 0x10 //<--- Mask of RST_DIG bit
|
||||
#define RST_CMG 0x08 //<--- Mask of RST_CMG bit
|
||||
#define RST_MST 0x04 //<--- Mask of RST_MST bit
|
||||
#define RST_ADC_DIG 0x02 //<--- Mask of RST_ADC_DIG bit
|
||||
#define RST_DAC_DIG 0x01 //<--- Mask of RST_DAC_DIG bit
|
||||
|
||||
//------------------------- CLK MANAGER REG 0x01 -----------------------------
|
||||
|
||||
#define MCLK_SEL 0x80 //<--- Mask of MCLK_SEL bit
|
||||
#define MCLK_INV 0x40 //<--- Mask of MCLK_INV bit
|
||||
#define MCLK_ON 0x20 //<--- Mask of MCLK_ON bit
|
||||
#define BCLK_ON 0x10 //<--- Mask of BCLK_ON bit
|
||||
#define CLKADC_ON 0x08 //<--- Mask of CLKADC_ON bit
|
||||
#define CLKDAC_ON 0x04 //<--- Mask of CLKDAC_ON bit
|
||||
#define ANACLKADC_ON 0x02 //<--- Mask of ANACLKADC_ON bit
|
||||
#define ANACLKDAC_ON 0x01 //<--- Mask of ANACLKDAC_ON bit
|
||||
|
||||
//------------------------- CLK MANAGER REG 0x06 -----------------------------
|
||||
|
||||
#define BCLK_CON 0x40 //<--- Mask of BCLK_CON bit
|
||||
#define BCLK_INV 0x20 //<--- Mask of BCLK_INV bit
|
||||
|
||||
//Valid values for BCLK divider at Master mode DIV_BCLK[4:0]
|
||||
|
||||
#define DIV_BCLK_DEFAULT 0x03 //<--- Default value MCLK/4
|
||||
#define DIV_BCLK_MCLK22 0x14 //<--- MCLK/22
|
||||
#define DIV_BCLK_MCLK24 0x15 //<--- MCLK/24
|
||||
#define DIV_BCLK_MCLK25 0x16 //<--- MCLK/25
|
||||
#define DIV_BCLK_MCLK30 0x17 //<--- MCLK/30
|
||||
#define DIV_BCLK_MCLK32 0x18 //<--- MCLK/32
|
||||
#define DIV_BCLK_MCLK33 0x19 //<--- MCLK/33
|
||||
#define DIV_BCLK_MCLK34 0x1A //<--- MCLK/34
|
||||
#define DIV_BCLK_MCLK36 0x1B //<--- MCLK/36
|
||||
#define DIV_BCLK_MCLK44 0x1C //<--- MCLK/44
|
||||
#define DIV_BCLK_MCLK48 0x1D //<--- MCLK/48
|
||||
#define DIV_BCLK_MCLK66 0x1E //<--- MCLK/66
|
||||
#define DIV_BCLK_MCLK72 0x1F //<--- MCLK/72
|
||||
|
||||
//------------------------- SDP REG 0x09 -------------------------------------
|
||||
/**
|
||||
* NOTA: El software esta preparado para resolucion de 16 bits, asi que esa
|
||||
* configuracion se hace hardcoded.
|
||||
*/
|
||||
|
||||
#define SDP_IN_MUTE 0x40 //<--- Mask of SDP_IN_MUTE bit
|
||||
#define SDP_IN_WL_16BIT 0x0C //<--- Value IN Word Length 16 bits
|
||||
#define SDP_IN_FMT_LEFT 0x01 //<--- Value for left justify serial audio data format
|
||||
|
||||
//------------------------- SDP REG 0x0A -------------------------------------
|
||||
/**
|
||||
* NOTA: El software esta preparado para resolucion de 16 bits, asi que esa
|
||||
* configuracion se hace hardcoded.
|
||||
*/
|
||||
|
||||
#define SDP_OUT_MUTE 0x40 //<--- Mask of SDP_OUT_MUTE bit
|
||||
#define SDP_OUT_WL_16BIT 0x0C //<--- Value OUT Word Length 16 bits
|
||||
#define SDP_OUT_FMT_LEFT 0x01 //<--- Value for left justify serial audio data format
|
||||
|
||||
//------------------------- SYSTEM REG 0x0D ----------------------------------
|
||||
|
||||
#define REG_0D_DEFAULT 0x01 //<--- Value Start Up normal for automatic startup
|
||||
|
||||
//------------------------- SYSTEM REG 0x0E ----------------------------------
|
||||
|
||||
#define REG_0E_DEFAULT 0x02 //<--- Value for default startup
|
||||
|
||||
//------------------------- SYSTEM REG 0x12 ----------------------------------
|
||||
|
||||
#define REG_12_DEFAULT 0x00 //<--- Value for default startup
|
||||
|
||||
//------------------------- SYSTEM REG 0x13 ----------------------------------
|
||||
|
||||
#define HPSW 0x10 //<--- Mask of HPSW bit
|
||||
|
||||
//------------------------- SYSTEM REG 0x14 ----------------------------------
|
||||
|
||||
#define REG_14_DEFAULT 0x1A //<---- Value for max PGA gain and DMIC off
|
||||
|
||||
#define LINSEL 0x10 //<---- Value for Mic1p-1n select
|
||||
|
||||
#define PGAGAIN_0DB 0x00
|
||||
#define PGAGAIN_3DB 0x01
|
||||
#define PGAGAIN_6DB 0x02
|
||||
#define PGAGAIN_9DB 0x03
|
||||
#define PGAGAIN_12DB 0x04
|
||||
#define PGAGAIN_15DB 0x05
|
||||
#define PGAGAIN_18DB 0x06
|
||||
#define PGAGAIN_21DB 0x07
|
||||
#define PGAGAIN_24DB 0x08
|
||||
#define PGAGAIN_27DB 0x09
|
||||
#define PGAGAIN_30DB 0x0A
|
||||
|
||||
//------------------------- ADC REG 0x1C -------------------------------------
|
||||
|
||||
#define REG_1C_DEFAULT 0x6A //<--- Value for default startup
|
||||
|
||||
//------------------------ DAC VOL REG 0x32 ---------------------------------
|
||||
|
||||
#define DAC_VOLUME_0DB 0xBF //<--- 0 dB for DAC volume (not default)
|
||||
|
||||
//------------------------- DAC REG 0x37 -------------------------------------
|
||||
|
||||
#define DAC_RAMPRATE_DEFAULT 0x40 //<--- Value for 0.25dB/32LRCK
|
||||
#define DAC_EQBYPASS_DEFAULT 0x08 //<--- Value for DAC_EQ bypass
|
||||
|
||||
/******************************************************************************
|
||||
* DEFINICIONES ESPECIFICAS PARA UTILIZAR BCLK EN VEZ DE MCLK
|
||||
*****************************************************************************/
|
||||
/* INTERNAL MASTER CLOCK = 8 * BCLK */
|
||||
|
||||
#define MULT_PRE 0x18 //<--- Value mask for MULT_PRE = 8 bits [4:3]
|
||||
#define DIV_PRE 0x00 //<--- Value mask for DIV_PRE = 0 bits [7:5]
|
||||
#define DIV_CLKADC 0x00 //<--- Value mask for DIV_CLKADC = 0 bits [7:4]
|
||||
#define DIV_CLKDAC 0x00 //<--- Value mask for DIV_CLKDAC = 0 bits [3:0]
|
||||
|
||||
/**
|
||||
* @brief This is a translation of volume levels from percentage to uint8_t
|
||||
*
|
||||
* The volume of DAC goes in steps of 0.5dB from -95.5dB to +32dB
|
||||
* This function translates a percentage to a decimal value of one byte
|
||||
* corresponding to a level as Datasheets shows
|
||||
*/
|
||||
#define DAC_VOL_PERCENT_LEVEL(x) ((255 * x) / 100)
|
||||
|
||||
#define ADC_VOL_PERCENT_LEVEL(x) DAC_VOL_PERCENT_LEVEL(x)
|
||||
|
||||
int es8311_init(i2s_es8311_t *i2s_cfg);
|
||||
int es8311_start(es_module_t mode);
|
||||
int es8311_stop(es_module_t mode);
|
||||
int es8311_codec_set_voice_volume(int volume);
|
||||
int es8311_codec_get_voice_volume(int *volume);
|
||||
int es8311_set_voice_mute(bool enable);
|
||||
int es8311_get_voice_mute(int *mute);
|
||||
|
||||
int es8311_set_mic_gain(i2s_es8311_mic_gain_t gain_db);
|
||||
|
||||
#endif /* __ES8311_H__ */
|
40031
examples/peripherals/i2s/i2s_es8311/fhm_onechannel_16k_20.h
Normal file
40031
examples/peripherals/i2s/i2s_es8311/fhm_onechannel_16k_20.h
Normal file
File diff suppressed because it is too large
Load Diff
12
examples/peripherals/i2s/i2s_es8311/flash_prog_cfg.ini
Normal file
12
examples/peripherals/i2s/i2s_es8311/flash_prog_cfg.ini
Normal file
@ -0,0 +1,12 @@
|
||||
[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
|
||||
|
254
examples/peripherals/i2s/i2s_es8311/main.c
Normal file
254
examples/peripherals/i2s/i2s_es8311/main.c
Normal file
@ -0,0 +1,254 @@
|
||||
/**
|
||||
* @file main.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2023 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 "board.h"
|
||||
#include "bflb_gpio.h"
|
||||
#include "bflb_l1c.h"
|
||||
#include "bflb_mtimer.h"
|
||||
|
||||
#include "bflb_i2c.h"
|
||||
|
||||
#include "bl616_glb.h"
|
||||
#include "bflb_dma.h"
|
||||
#include "bsp_es8311.h"
|
||||
#include "bflb_i2s.h"
|
||||
|
||||
#include "fhm_onechannel_16k_20.h"
|
||||
|
||||
// 8311
|
||||
struct bflb_device_s *i2s0;
|
||||
struct bflb_device_s *dma0_ch0;
|
||||
struct bflb_device_s *dma0_ch1;
|
||||
|
||||
ATTR_NOCACHE_RAM_SECTION uint8_t rx_buffer[16000];
|
||||
|
||||
void dma0_ch0_isr(void *arg)
|
||||
{
|
||||
printf("tc done\r\n");
|
||||
}
|
||||
|
||||
void dma0_ch1_isr(void *arg)
|
||||
{
|
||||
printf("rx 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_2);
|
||||
|
||||
/* 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 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];
|
||||
static struct bflb_dma_channel_lli_pool_s rx_llipool[100];
|
||||
static struct bflb_dma_channel_lli_transfer_s rx_transfers[1];
|
||||
|
||||
struct bflb_i2s_config_s i2s_cfg = {
|
||||
.bclk_freq_hz = 16000 * 16 * 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_16,
|
||||
.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
|
||||
};
|
||||
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");
|
||||
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)rx_buffer;
|
||||
tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_I2S_TDR;
|
||||
tx_transfers[0].nbytes = sizeof(rx_buffer);
|
||||
|
||||
rx_transfers[0].src_addr = (uint32_t)DMA_ADDR_I2S_RDR;
|
||||
rx_transfers[0].dst_addr = (uint32_t)rx_buffer;
|
||||
rx_transfers[0].nbytes = sizeof(rx_buffer);
|
||||
|
||||
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("tx dma lli num: %d \r\n", num);
|
||||
num = bflb_dma_channel_lli_reload(dma0_ch1, rx_llipool, 100, rx_transfers, 1);
|
||||
printf("rx dma lli num: %d \r\n", num);
|
||||
bflb_dma_channel_lli_link_head(dma0_ch1, rx_llipool, num);
|
||||
bflb_dma_channel_start(dma0_ch0);
|
||||
bflb_dma_channel_start(dma0_ch1);
|
||||
}
|
||||
|
||||
void mclk_out_init()
|
||||
{
|
||||
/* 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, 0, GLB_I2S_DI_SEL_I2S_DI_INPUT, GLB_I2S_DO_SEL_I2S_DO_OUTPT);
|
||||
/* ES8311 do not mclk */
|
||||
// GLB_Set_Chip_Clock_Out3_Sel(GLB_CHIP_CLK_OUT_3_I2S_REF_CLK);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
/* gpio init */
|
||||
i2s_gpio_init();
|
||||
/* mclk clkout init */
|
||||
mclk_out_init();
|
||||
|
||||
i2s_es8311_t es8311_cfg;
|
||||
es8311_cfg.mode = ES8311_MODE_SLAVE;
|
||||
es8311_cfg.fmt = ES8311_I2S_NORMAL;
|
||||
es8311_cfg.samples = ES8311_16K_SAMPLES;
|
||||
es8311_cfg.bits = ES8311_BIT_LENGTH_16BITS;
|
||||
/* init ES8311 Codec */
|
||||
printf("es8311 init\n\r");
|
||||
es8311_init(&es8311_cfg);
|
||||
es8311_codec_set_voice_volume(70);
|
||||
es8311_start(ES_MODULE_ADC_DAC);
|
||||
|
||||
/* 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);
|
||||
|
||||
while (1) {
|
||||
bflb_mtimer_delay_ms(10);
|
||||
}
|
||||
}
|
1
examples/peripherals/i2s/i2s_es8311/proj.conf
Normal file
1
examples/peripherals/i2s/i2s_es8311/proj.conf
Normal file
@ -0,0 +1 @@
|
||||
#set(CONFIG_XXX 1)
|
10
examples/peripherals/mjpeg/mjpeg_cam_crop/CMakeLists.txt
Normal file
10
examples/peripherals/mjpeg/mjpeg_cam_crop/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
include(proj.conf)
|
||||
|
||||
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
|
||||
|
||||
target_sources(app PRIVATE jpeg_head.c)
|
||||
sdk_set_main_file(main.c)
|
||||
|
||||
project(mjpeg_cam_crop)
|
13
examples/peripherals/mjpeg/mjpeg_cam_crop/Makefile
Normal file
13
examples/peripherals/mjpeg/mjpeg_cam_crop/Makefile
Normal 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
|
43
examples/peripherals/mjpeg/mjpeg_cam_crop/README.md
Normal file
43
examples/peripherals/mjpeg/mjpeg_cam_crop/README.md
Normal file
@ -0,0 +1,43 @@
|
||||
# mjpeg_cam_crop
|
||||
|
||||
|
||||
## Support CHIP
|
||||
|
||||
| CHIP | Remark |
|
||||
|:----------------:|:------:|
|
||||
|BL702/BL704/BL706 | |
|
||||
|BL616/BL618 | |
|
||||
|BL808 | |
|
||||
|
||||
## Compile
|
||||
|
||||
- BL602/BL604
|
||||
|
||||
```
|
||||
make CHIP=bl602 BOARD=bl602dk
|
||||
```
|
||||
|
||||
- BL702/BL704/BL706
|
||||
|
||||
```
|
||||
make CHIP=bl702 BOARD=bl702dk
|
||||
```
|
||||
|
||||
- BL616/BL618
|
||||
|
||||
```
|
||||
make CHIP=bl616 BOARD=bl616dk
|
||||
```
|
||||
|
||||
- BL808
|
||||
|
||||
```
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=d0
|
||||
```
|
||||
|
||||
## Flash
|
||||
|
||||
```
|
||||
make flash CHIP=chip_name COMX=xxx # xxx is your com name
|
||||
```
|
11
examples/peripherals/mjpeg/mjpeg_cam_crop/flash_prog_cfg.ini
Normal file
11
examples/peripherals/mjpeg/mjpeg_cam_crop/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/mjpeg*_$(CHIPNAME).bin
|
||||
address = 0x000000
|
185
examples/peripherals/mjpeg/mjpeg_cam_crop/jpeg_head.c
Normal file
185
examples/peripherals/mjpeg/mjpeg_cam_crop/jpeg_head.c
Normal file
@ -0,0 +1,185 @@
|
||||
#include "jpeg_head.h"
|
||||
|
||||
static const uint8_t tableQy[] = {
|
||||
16, 11, 12, 14, 12, 10, 16, 14,
|
||||
13, 14, 18, 17, 16, 19, 24, 40,
|
||||
26, 24, 22, 22, 24, 49, 35, 37,
|
||||
29, 40, 58, 51, 61, 60, 57, 51,
|
||||
56, 55, 64, 72, 92, 78, 64, 68,
|
||||
87, 69, 55, 56, 80, 109, 81, 87,
|
||||
95, 98, 103, 104, 103, 62, 77, 113,
|
||||
121, 112, 100, 120, 92, 101, 103, 99
|
||||
};
|
||||
|
||||
static const uint8_t tableQuv[] = {
|
||||
17, 18, 18, 24, 21, 24, 47, 26,
|
||||
26, 47, 99, 66, 56, 66, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99
|
||||
};
|
||||
|
||||
static const uint8_t tableHuffman[] = {
|
||||
0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
|
||||
0x0B,
|
||||
|
||||
0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
|
||||
0x04, 0x00, 0x00, 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41,
|
||||
0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1,
|
||||
0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
|
||||
0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
|
||||
0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
|
||||
0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84,
|
||||
0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2,
|
||||
0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
|
||||
0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
|
||||
0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
|
||||
0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
|
||||
|
||||
0xFF, 0xC4, 0x00, 0x1F, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
|
||||
0x0B,
|
||||
|
||||
0xFF, 0xC4, 0x00, 0xB5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
|
||||
0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12,
|
||||
0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
|
||||
0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1,
|
||||
0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0X2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43,
|
||||
0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63,
|
||||
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82,
|
||||
0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
|
||||
0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
|
||||
0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5,
|
||||
0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3,
|
||||
0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
|
||||
};
|
||||
|
||||
static void QCalc(const uint8_t *in, uint8_t *out, uint8_t q)
|
||||
{
|
||||
float tq, result;
|
||||
int i;
|
||||
|
||||
if (q < 1)
|
||||
tq = 5000.0f;
|
||||
else if (q <= 50)
|
||||
tq = 5000.0f / q;
|
||||
else if (q <= 100)
|
||||
tq = 200.0f - 2.0f * q;
|
||||
else
|
||||
tq = 0.0f;
|
||||
tq = tq / 100.0f;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
result = in[i] * tq;
|
||||
if (result > 255.0f)
|
||||
out[i] = 255;
|
||||
else if (result < 1.0f)
|
||||
out[i] = 1;
|
||||
else
|
||||
out[i] = (uint8_t)(result + 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t JpegHeadCreate(uint8_t type, uint8_t q, int width, int height, uint8_t *out)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
uint32_t i;
|
||||
/* start of jpeg file */
|
||||
out[index++] = 0xFF;
|
||||
out[index++] = 0xD8;
|
||||
|
||||
/* define quality table */
|
||||
out[index++] = 0xFF;
|
||||
out[index++] = 0xDB;
|
||||
out[index++] = 0x00;
|
||||
out[index++] = 0x43; //=3+N, N=64
|
||||
out[index++] = 0x00;
|
||||
QCalc(tableQy, out + index, q); //Y quality table
|
||||
index += 64;
|
||||
out[index++] = 0xFF;
|
||||
out[index++] = 0xDB;
|
||||
out[index++] = 0x00;
|
||||
out[index++] = 0x43; //=3+N, N=64
|
||||
out[index++] = 0x01;
|
||||
QCalc(tableQuv, out + index, q); //UV quality table
|
||||
index += 64;
|
||||
|
||||
/* basic information of mjpeg */
|
||||
out[index++] = 0xFF;
|
||||
out[index++] = 0xC0;
|
||||
out[index++] = 0x00;
|
||||
if (type == YUV_MODE_400)
|
||||
out[index++] = 0x0B; //length:2 + bits:1 + height:2 + width:2 + num:1 + 3 * part=1
|
||||
else
|
||||
out[index++] = 0x11; //length:2 + bits:1 + height:2 + width:2 + num:1 + 3 * part=3
|
||||
out[index++] = 0x08;
|
||||
out[index++] = (uint8_t)((height >> 8) & 0xFF);
|
||||
out[index++] = (uint8_t)(height & 0xFF);
|
||||
out[index++] = (uint8_t)((width >> 8) & 0xFF);
|
||||
out[index++] = (uint8_t)(width & 0xFF);
|
||||
if (type == YUV_MODE_400) {
|
||||
out[index++] = 0x01; //number of part
|
||||
out[index++] = 0x01; //the first part id
|
||||
out[index++] = 0x11; //[0:3]vertical sample coefficient, [4:7]horizontal sample coefficient
|
||||
out[index++] = 0x00; //id of quality tab
|
||||
} else if (type == YUV_MODE_420) {
|
||||
out[index++] = 0x03; //number of part
|
||||
out[index++] = 0x01; //the first part id
|
||||
out[index++] = 0x22; //[0:3]vertical sample coefficient, [4:7]horizontal sample coefficient
|
||||
out[index++] = 0x00; //id of quality tab
|
||||
out[index++] = 0x02; //the second part id
|
||||
out[index++] = 0x11; //[0:3]vertical sample coefficient, [4:7]horizontal sample coefficient
|
||||
out[index++] = 0x01; //id of quality tab
|
||||
out[index++] = 0x03; //the third part id
|
||||
out[index++] = 0x11; //[0:3]vertical sample coefficient, [4:7]horizontal sample coefficient
|
||||
out[index++] = 0x01; //id of quality tab
|
||||
} else if (type == YUV_MODE_422) {
|
||||
out[index++] = 0x03; //number of part
|
||||
out[index++] = 0x01; //the first part id
|
||||
out[index++] = 0x21; //[0:3]vertical sample coefficient, [4:7]horizontal sample coefficient
|
||||
out[index++] = 0x00; //id of quality tab
|
||||
out[index++] = 0x02; //the second part id
|
||||
out[index++] = 0x11; //[0:3]vertical sample coefficient, [4:7]horizontal sample coefficient
|
||||
out[index++] = 0x01; //id of quality tab
|
||||
out[index++] = 0x03; //the third part id
|
||||
out[index++] = 0x11; //[0:3]vertical sample coefficient, [4:7]horizontal sample coefficient
|
||||
out[index++] = 0x01; //id of quality tab
|
||||
}
|
||||
|
||||
/* define Huffman table */
|
||||
for (i = 0; i < sizeof(tableHuffman); i++) {
|
||||
out[index++] = tableHuffman[i];
|
||||
}
|
||||
|
||||
/* start of scan*/
|
||||
out[index++] = 0xFF;
|
||||
out[index++] = 0xDA;
|
||||
if (type == YUV_MODE_400) {
|
||||
out[index++] = 0x00;
|
||||
out[index++] = 0x08; //length
|
||||
out[index++] = 0x01;
|
||||
out[index++] = 0x01;
|
||||
out[index++] = 0x00;
|
||||
out[index++] = 0x02;
|
||||
out[index++] = 0x3F;
|
||||
out[index++] = 0x00;
|
||||
} else {
|
||||
out[index++] = 0x00;
|
||||
out[index++] = 0x0C; //length
|
||||
out[index++] = 0x03;
|
||||
out[index++] = 0x01;
|
||||
out[index++] = 0x00;
|
||||
out[index++] = 0x02;
|
||||
out[index++] = 0x11;
|
||||
out[index++] = 0x03;
|
||||
out[index++] = 0x11;
|
||||
out[index++] = 0x00;
|
||||
out[index++] = 0x3F;
|
||||
out[index++] = 0x00;
|
||||
}
|
||||
return index;
|
||||
}
|
12
examples/peripherals/mjpeg/mjpeg_cam_crop/jpeg_head.h
Normal file
12
examples/peripherals/mjpeg/mjpeg_cam_crop/jpeg_head.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef __JPEG_HEAD_H__
|
||||
#define __JPEG_HEAD_H__
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define YUV_MODE_400 1
|
||||
#define YUV_MODE_420 2
|
||||
#define YUV_MODE_422 3
|
||||
|
||||
extern uint32_t JpegHeadCreate(uint8_t type, uint8_t q, int width, int height, uint8_t *out);
|
||||
|
||||
#endif /* __JPEG_HEAD_H__ */
|
150
examples/peripherals/mjpeg/mjpeg_cam_crop/main.c
Normal file
150
examples/peripherals/mjpeg/mjpeg_cam_crop/main.c
Normal file
@ -0,0 +1,150 @@
|
||||
#include "bflb_mtimer.h"
|
||||
#include "bflb_i2c.h"
|
||||
#include "bflb_cam.h"
|
||||
#include "bflb_mjpeg.h"
|
||||
#include "image_sensor.h"
|
||||
#include "board.h"
|
||||
#include "jpeg_head.h"
|
||||
|
||||
#define BLOCK_NUM 2
|
||||
#define ROW_NUM (8 * BLOCK_NUM)
|
||||
#define CAM_FRAME_COUNT_USE 5
|
||||
#define CROP_WQVGA_X 416
|
||||
#define CROP_WQVGA_Y 240
|
||||
|
||||
static struct bflb_device_s *i2c0;
|
||||
static struct bflb_device_s *cam0;
|
||||
|
||||
static struct bflb_device_s *mjpeg;
|
||||
|
||||
volatile uint32_t pic_count = 0;
|
||||
volatile uint32_t pic_addr[CAM_FRAME_COUNT_USE] = { 0 };
|
||||
volatile uint32_t pic_len[CAM_FRAME_COUNT_USE] = { 0 };
|
||||
|
||||
static __attribute__((aligned(32))) ATTR_NOINIT_PSRAM_SECTION uint8_t dvp_buffer[CROP_WQVGA_X * 2 * ROW_NUM];
|
||||
static __attribute__((aligned(32))) ATTR_NOINIT_PSRAM_SECTION uint8_t mjpeg_buffer[50 * 1024 * CAM_FRAME_COUNT_USE];
|
||||
|
||||
void mjpeg_isr(int irq, void *arg)
|
||||
{
|
||||
uint8_t *pic;
|
||||
uint32_t jpeg_len;
|
||||
|
||||
uint32_t intstatus = bflb_mjpeg_get_intstatus(mjpeg);
|
||||
if (intstatus & MJPEG_INTSTS_ONE_FRAME) {
|
||||
bflb_mjpeg_int_clear(mjpeg, MJPEG_INTCLR_ONE_FRAME);
|
||||
jpeg_len = bflb_mjpeg_get_frame_info(mjpeg, &pic);
|
||||
pic_addr[pic_count] = (uint32_t)pic;
|
||||
pic_len[pic_count] = jpeg_len;
|
||||
pic_count++;
|
||||
bflb_mjpeg_pop_one_frame(mjpeg);
|
||||
if (pic_count == CAM_FRAME_COUNT_USE) {
|
||||
bflb_cam_stop(cam0);
|
||||
bflb_mjpeg_stop(mjpeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t jpg_head_buf[800] = { 0 };
|
||||
uint32_t jpg_head_len;
|
||||
|
||||
uint8_t MJPEG_QUALITY = 50;
|
||||
|
||||
#define SIZE_BUFFER (4 * 1024 * 1024)
|
||||
|
||||
void bflb_mjpeg_dump_hex(uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i % 16 == 0) {
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
printf("%02x ", data[i]);
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct bflb_cam_config_s cam_config;
|
||||
struct image_sensor_config_s *sensor_config;
|
||||
|
||||
board_init();
|
||||
board_dvp_gpio_init();
|
||||
|
||||
i2c0 = bflb_device_get_by_name("i2c0");
|
||||
cam0 = bflb_device_get_by_name("cam0");
|
||||
|
||||
if (image_sensor_scan(i2c0, &sensor_config)) {
|
||||
printf("\r\nSensor name: %s\r\n", sensor_config->name);
|
||||
} else {
|
||||
printf("\r\nError! Can't identify sensor!\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Crop resolution_x, should be set before init */
|
||||
bflb_cam_crop_hsync(cam0, 112, 112 + CROP_WQVGA_X);
|
||||
/* Crop resolution_y, should be set before init */
|
||||
bflb_cam_crop_vsync(cam0, 120, 120 + CROP_WQVGA_Y);
|
||||
|
||||
memcpy(&cam_config, sensor_config, IMAGE_SENSOR_INFO_COPY_SIZE);
|
||||
cam_config.with_mjpeg = true;
|
||||
cam_config.input_source = CAM_INPUT_SOURCE_DVP;
|
||||
cam_config.output_format = CAM_OUTPUT_FORMAT_AUTO;
|
||||
cam_config.output_bufaddr = (uint32_t)dvp_buffer;
|
||||
cam_config.output_bufsize = CROP_WQVGA_X * 2 * ROW_NUM;
|
||||
|
||||
bflb_cam_init(cam0, &cam_config);
|
||||
bflb_cam_start(cam0);
|
||||
|
||||
cam_config.resolution_x = CROP_WQVGA_X;
|
||||
cam_config.resolution_y = CROP_WQVGA_Y;
|
||||
|
||||
mjpeg = bflb_device_get_by_name("mjpeg");
|
||||
|
||||
struct bflb_mjpeg_config_s config;
|
||||
|
||||
config.format = MJPEG_FORMAT_YUV422_YUYV;
|
||||
config.quality = MJPEG_QUALITY;
|
||||
config.rows = ROW_NUM;
|
||||
config.resolution_x = cam_config.resolution_x;
|
||||
config.resolution_y = cam_config.resolution_y;
|
||||
config.input_bufaddr0 = (uint32_t)dvp_buffer;
|
||||
config.input_bufaddr1 = 0;
|
||||
config.output_bufaddr = (uint32_t)mjpeg_buffer;
|
||||
config.output_bufsize = sizeof(mjpeg_buffer);
|
||||
config.input_yy_table = NULL; /* use default table */
|
||||
config.input_uv_table = NULL; /* use default table */
|
||||
|
||||
bflb_mjpeg_init(mjpeg, &config);
|
||||
|
||||
jpg_head_len = JpegHeadCreate(YUV_MODE_422, MJPEG_QUALITY, cam_config.resolution_x, cam_config.resolution_y, jpg_head_buf);
|
||||
bflb_mjpeg_fill_jpeg_header_tail(mjpeg, jpg_head_buf, jpg_head_len);
|
||||
|
||||
bflb_mjpeg_tcint_mask(mjpeg, false);
|
||||
bflb_irq_attach(mjpeg->irq_num, mjpeg_isr, NULL);
|
||||
bflb_irq_enable(mjpeg->irq_num);
|
||||
|
||||
bflb_mjpeg_start(mjpeg);
|
||||
|
||||
while (pic_count < CAM_FRAME_COUNT_USE) {
|
||||
printf("pic count:%d\r\n", pic_count);
|
||||
bflb_mtimer_delay_ms(200);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < CAM_FRAME_COUNT_USE; i++) {
|
||||
if ((pic_addr[i] + pic_len[i]) > ((uint32_t)mjpeg_buffer + sizeof(mjpeg_buffer))) {
|
||||
printf("drop invalid pic\r\n");
|
||||
continue;
|
||||
}
|
||||
printf("jpg addr:%08x ,jpg size:%d\r\n", pic_addr[i], pic_len[i]);
|
||||
// bflb_mjpeg_dump_hex((uint8_t *)pic_addr[i], pic_len[i]);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
bflb_mtimer_delay_ms(1000);
|
||||
}
|
||||
}
|
2
examples/peripherals/mjpeg/mjpeg_cam_crop/proj.conf
Normal file
2
examples/peripherals/mjpeg/mjpeg_cam_crop/proj.conf
Normal file
@ -0,0 +1,2 @@
|
||||
set(CONFIG_BSP_IMAGE_SENSOR 1)
|
||||
set(CONFIG_PSRAM 1)
|
12
examples/peripherals/usbdev/usbd_cdc_acm_msc/CMakeLists.txt
Normal file
12
examples/peripherals/usbdev/usbd_cdc_acm_msc/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
include(proj.conf)
|
||||
|
||||
find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
|
||||
|
||||
sdk_add_include_directories(.)
|
||||
|
||||
target_sources(app PRIVATE cdc_acm_msc_template.c)
|
||||
sdk_set_main_file(main.c)
|
||||
|
||||
project(usbd_cdc_acm_msc)
|
13
examples/peripherals/usbdev/usbd_cdc_acm_msc/Makefile
Normal file
13
examples/peripherals/usbdev/usbd_cdc_acm_msc/Makefile
Normal 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
|
37
examples/peripherals/usbdev/usbd_cdc_acm_msc/README.md
Normal file
37
examples/peripherals/usbdev/usbd_cdc_acm_msc/README.md
Normal file
@ -0,0 +1,37 @@
|
||||
# usbd_cdc_acm_msc
|
||||
|
||||
|
||||
## Support CHIP
|
||||
|
||||
| CHIP | Remark |
|
||||
|:----------------:|:------:|
|
||||
|BL702/BL704/BL706 | |
|
||||
|BL616/BL618 | |
|
||||
|BL808 | D0 has no irq |
|
||||
|
||||
## Compile
|
||||
|
||||
- BL702/BL704/BL706
|
||||
|
||||
```
|
||||
make CHIP=bl702 BOARD=bl702dk
|
||||
```
|
||||
|
||||
- BL616/BL618
|
||||
|
||||
```
|
||||
make CHIP=bl616 BOARD=bl616dk
|
||||
```
|
||||
|
||||
- BL808
|
||||
|
||||
```
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=m0
|
||||
make CHIP=bl808 BOARD=bl808dk CPU_ID=d0
|
||||
```
|
||||
|
||||
## Flash
|
||||
|
||||
```
|
||||
make flash CHIP=chip_name COMX=xxx # xxx is your com name
|
||||
```
|
@ -0,0 +1,250 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_msc.h"
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x86
|
||||
|
||||
#define MSC_IN_EP 0x83
|
||||
#define MSC_OUT_EP 0x04
|
||||
|
||||
#define USBD_VID 0xFFFF
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN + MSC_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define MSC_MAX_MPS 512
|
||||
#else
|
||||
#define MSC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_msc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x00),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x26, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'C', 0x00, /* wcChar10 */
|
||||
'-', 0x00, /* wcChar11 */
|
||||
'M', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
|
||||
/* setup next out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
|
||||
|
||||
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(CDC_IN_EP, NULL, 0);
|
||||
} else {
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*!< endpoint call back */
|
||||
struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = CDC_OUT_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = CDC_IN_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
struct usbd_interface intf2;
|
||||
|
||||
void cdc_acm_msc_init(void)
|
||||
{
|
||||
const uint8_t data[10] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
|
||||
|
||||
memcpy(&write_buffer[0], data, 10);
|
||||
memset(&write_buffer[10], 'a', 2038);
|
||||
|
||||
usbd_desc_register(cdc_msc_descriptor);
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf0));
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf1));
|
||||
usbd_add_endpoint(&cdc_out_ep);
|
||||
usbd_add_endpoint(&cdc_in_ep);
|
||||
usbd_add_interface(usbd_msc_init_intf(&intf2, MSC_OUT_EP, MSC_IN_EP));
|
||||
|
||||
usbd_initialize();
|
||||
}
|
||||
|
||||
volatile uint8_t dtr_enable = 0;
|
||||
|
||||
void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
|
||||
{
|
||||
if (dtr) {
|
||||
dtr_enable = 1;
|
||||
} else {
|
||||
dtr_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_acm_data_send_with_dtr_test(void)
|
||||
{
|
||||
if (dtr_enable) {
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(CDC_IN_EP, write_buffer, 2048);
|
||||
while (ep_tx_busy_flag) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define BLOCK_SIZE 512
|
||||
#define BLOCK_COUNT 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t BlockSpace[BLOCK_SIZE];
|
||||
} BLOCK_TYPE;
|
||||
|
||||
BLOCK_TYPE mass_block[BLOCK_COUNT];
|
||||
|
||||
void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
|
||||
{
|
||||
*block_num = 1000; //Pretend having so many buffer,not has actually.
|
||||
*block_size = BLOCK_SIZE;
|
||||
}
|
||||
int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
if (sector < 10)
|
||||
memcpy(buffer, mass_block[sector].BlockSpace, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
if (sector < 10)
|
||||
memcpy(mass_block[sector].BlockSpace, buffer, length);
|
||||
return 0;
|
||||
}
|
@ -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/usbd*_$(CHIPNAME).bin
|
||||
address = 0x000000
|
17
examples/peripherals/usbdev/usbd_cdc_acm_msc/main.c
Normal file
17
examples/peripherals/usbdev/usbd_cdc_acm_msc/main.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "usbd_core.h"
|
||||
#include "bflb_mtimer.h"
|
||||
#include "board.h"
|
||||
|
||||
extern void cdc_acm_msc_init(void);
|
||||
extern void cdc_acm_data_send_with_dtr_test(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
cdc_acm_msc_init();
|
||||
while (1) {
|
||||
cdc_acm_data_send_with_dtr_test();
|
||||
bflb_mtimer_delay_ms(500);
|
||||
}
|
||||
}
|
7
examples/peripherals/usbdev/usbd_cdc_acm_msc/proj.conf
Normal file
7
examples/peripherals/usbdev/usbd_cdc_acm_msc/proj.conf
Normal file
@ -0,0 +1,7 @@
|
||||
set(CONFIG_CHERRYUSB 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_CDC 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_HID 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_MSC 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_AUDIO 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_VIDEO 1)
|
160
examples/peripherals/usbdev/usbd_cdc_acm_msc/usb_config.h
Normal file
160
examples/peripherals/usbdev/usbd_cdc_acm_msc/usb_config.h
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
#define CHERRYUSB_VERSION 0x001000
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__)
|
||||
|
||||
#define usb_malloc(size) malloc(size)
|
||||
#define usb_free(ptr) free(ptr)
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
|
||||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
/* data align size when use dma */
|
||||
#ifndef CONFIG_USB_ALIGN_SIZE
|
||||
#define CONFIG_USB_ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
/* attribute data into no cache ram */
|
||||
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
|
||||
|
||||
/* ================= USB Device Stack Configuration ================ */
|
||||
|
||||
/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
|
||||
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
|
||||
|
||||
/* Setup packet log for debug */
|
||||
// #define CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
|
||||
/* Check if the input descriptor is correct */
|
||||
// #define CONFIG_USBDEV_DESC_CHECK
|
||||
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
//#define CONFIG_USBDEV_TX_THREAD
|
||||
//#define CONFIG_USBDEV_RX_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
#ifndef CONFIG_USBDEV_TX_PRIO
|
||||
#define CONFIG_USBDEV_TX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_TX_STACKSIZE
|
||||
#define CONFIG_USBDEV_TX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
#ifndef CONFIG_USBDEV_RX_PRIO
|
||||
#define CONFIG_USBDEV_RX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_RX_STACKSIZE
|
||||
#define CONFIG_USBDEV_RX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
|
||||
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
|
||||
#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
|
||||
#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1536
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
|
||||
#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC
|
||||
#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
|
||||
#endif
|
||||
|
||||
#define CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
|
||||
/* ================ USB HOST Stack Configuration ================== */
|
||||
|
||||
#define CONFIG_USBHOST_MAX_RHPORTS 1
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 0
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 4
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_HID_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_MSC_CLASS 2
|
||||
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_RNDIS_CLASS 1
|
||||
|
||||
#define CONFIG_USBHOST_DEV_NAMELEN 16
|
||||
|
||||
#ifndef CONFIG_USBHOST_PSC_PRIO
|
||||
#define CONFIG_USBHOST_PSC_PRIO 28
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
|
||||
/* Ep0 max transfer buffer */
|
||||
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
|
||||
|
||||
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 1000
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_MSC_TIMEOUT
|
||||
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
//#define USBD_IRQHandler USBD_IRQHandler
|
||||
//#define USB_BASE (0x40080000UL)
|
||||
//#define USB_NUM_BIDIR_ENDPOINTS 4
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
|
||||
/* ================ EHCI Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
|
||||
#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
// #define CONFIG_USB_EHCI_INFO_ENABLE
|
||||
#define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
// #define CONFIG_USB_EHCI_PORT_POWER
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user