From 4e8ec04b3490338fc6eb5ffce95e9d9333370c91 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sat, 4 Feb 2023 10:31:16 +1100 Subject: [PATCH 1/2] Drop SDMMC --- apps/Makefile | 4 - apps/sdmmc/Makefile | 14 - apps/sdmmc/app_sdmmc.cpp | 186 -- apps/sdmmc/app_sdmmc.h | 39 - platform/hal/best2300p/hal_cmu_best2300p.c | 2 - platform/hal/hal_sdmmc.c | 2789 -------------------- platform/hal/hal_sdmmc.h | 46 - platform/hal/reg_sdmmcip.h | 149 -- 8 files changed, 3229 deletions(-) delete mode 100644 apps/sdmmc/Makefile delete mode 100644 apps/sdmmc/app_sdmmc.cpp delete mode 100644 apps/sdmmc/app_sdmmc.h delete mode 100644 platform/hal/hal_sdmmc.c delete mode 100644 platform/hal/hal_sdmmc.h delete mode 100644 platform/hal/reg_sdmmcip.h diff --git a/apps/Makefile b/apps/Makefile index 79e9e6e..bfef2e6 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -12,9 +12,6 @@ obj-y += btusbaudio/ obj-y += usbaudio/ endif -ifeq ($(APP_TEST_SDMMC),1) -obj-y += sdmmc/ -endif ifeq ($(ANC_APP),1) obj-y += anc/ @@ -35,7 +32,6 @@ endif subdir-ccflags-y += -Iapps/apptester \ -Iapps/audioplayers \ -Iapps/common \ - -Iapps/sdmmc \ -Iapps/main \ -Iapps/cmd \ -Iapps/key \ diff --git a/apps/sdmmc/Makefile b/apps/sdmmc/Makefile deleted file mode 100644 index d15ef32..0000000 --- a/apps/sdmmc/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) -obj-y := $(obj-y:.c=.o) -obj-y := $(obj-y:.cpp=.o) -obj-y := $(obj-y:.S=.o) - -subdir-ccflags-y += -Iservices/fs/sd \ - -Iservices/fs/fat \ - -Iservices/fs/fat/ChaN - -ifeq ($(APP_TEST_SDMMC),1) -ccflags-y += -D__APP_TEST_SDMMC__ -endif diff --git a/apps/sdmmc/app_sdmmc.cpp b/apps/sdmmc/app_sdmmc.cpp deleted file mode 100644 index f612292..0000000 --- a/apps/sdmmc/app_sdmmc.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "cmsis_os.h" -#include "hal_trace.h" -//#include "app_thread.h" - -//#include "hal_sdmmc.h" -#include "SDFileSystem.h" -#include "app_sdmmc.h" -#include "audiobuffer.h" -#include "audioflinger.h" - -#define APP_TEST_PLAYBACK_BUFF_SIZE (120 * 20) -#define APP_TEST_CAPTURE_BUFF_SIZE (120 * 20) -extern uint8_t app_test_playback_buff[APP_TEST_PLAYBACK_BUFF_SIZE] - __attribute__((aligned(4))); -extern uint8_t app_test_capture_buff[APP_TEST_CAPTURE_BUFF_SIZE] - __attribute__((aligned(4))); -SDFileSystem sdfs("sd"); - -int sd_open() { - DIR *d = opendir("/sd"); - if (!d) { - TRACE(0, "sd file system borked\n"); - return -1; - } - - TRACE(0, "---------root---------\n"); - struct dirent *p; - while ((p = readdir(d))) { - int len = sizeof(dirent); - TRACE(2, "%s %d\n", p->d_name, len); - } - closedir(d); - TRACE(0, "--------root end-------\n"); -} - -extern uint32_t play_wav_file(char *file_path); -extern uint32_t stop_wav_file(void); -extern uint32_t wav_file_audio_more_data(uint8_t *buf, uint32_t len); - -void test_wave_play(bool on) { - struct AF_STREAM_CONFIG_T stream_cfg; - uint32_t reallen; - uint32_t totalreadsize; - uint32_t stime, etime; - - char wave[] = "/sd/test_music.wav"; - - static bool isRun = false; - - if (isRun == on) - return; - else - isRun = on; - - TRACE(2, "%s %d\n", __func__, on); - memset(&stream_cfg, 0, sizeof(stream_cfg)); - if (on) { - play_wav_file(wave); - - stream_cfg.bits = AUD_BITS_16; - stream_cfg.channel_num = AUD_CHANNEL_NUM_2; - stream_cfg.sample_rate = AUD_SAMPRATE_48000; - - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; - stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; - stream_cfg.vol = 0x03; - - stream_cfg.handler = wav_file_audio_more_data; - stream_cfg.data_ptr = app_test_playback_buff; - stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; - - af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); - af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - } else { - stop_wav_file(); - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - } - - return; -} - -FIL pcm_fil; -FRESULT pcm_res; -UINT pcm_num; -uint32_t pcm_save_more_data(uint8_t *buf, uint32_t len) { - // TRACE(2,"%s\n len:%d", __func__, len); - - audio_buffer_set_stereo2mono_16bits(buf, len, 1); - pcm_res = f_write(&pcm_fil, (uint8_t *)buf, len >> 1, &pcm_num); - if (pcm_res != FR_OK) { - TRACE(2, "[%s]:error-->res = %d", __func__, pcm_res); - } - return 0; -} - -void ad_tester(bool run) { - char filename[] = "/sd/audio_dump.bin"; - - struct AF_STREAM_CONFIG_T stream_cfg; - - TRACE(2, "%s %d\n", __func__, run); - - if (run) { - memset(&stream_cfg, 0, sizeof(stream_cfg)); - pcm_res = f_open(&pcm_fil, "test2.bin", FA_CREATE_ALWAYS | FA_WRITE); - if (pcm_res) { - TRACE(2, "[%s]:Cannot creat test2.bin...%d", __func__, pcm_res); - return; - } - - stream_cfg.bits = AUD_BITS_16; - stream_cfg.channel_num = AUD_CHANNEL_NUM_2; - stream_cfg.sample_rate = AUD_SAMPRATE_48000; - - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; - stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; - stream_cfg.vol = 0x03; - - stream_cfg.handler = pcm_save_more_data; - stream_cfg.data_ptr = app_test_playback_buff; - stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; - - af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); - af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - } else { - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - osDelay(1000); - - f_close(&pcm_fil); - } -} - -// if dump data into sd, buffer length should make sd card speed enough -// Bench32.exe can test sd card speed in PC, then make sure bufer length, buffer -// length < 16k(sd driver) -void dump_data2sd(enum APP_SDMMC_DUMP_T opt, uint8_t *buf, uint32_t len) { - static FIL sd_fil; - FRESULT res; - - ASSERT(opt < APP_SDMMC_DUMP_NUM, "[%s] opt(%d) >= APP_SDMMC_DUMP_NUM", - __func__, opt); - - if (opt == APP_SDMMC_DUMP_OPEN) { - // res = f_open(&sd_fil,"dump.bin",FA_CREATE_ALWAYS | FA_WRITE); - res = f_open(&sd_fil, "test.txt", FA_READ); - - // ASSERT(pcm_res == FR_OK,"[%s]:Cannot creat dump.bin, res = - // %d",__func__, pcm_res); - } - if (opt == APP_SDMMC_DUMP_READ) { - res = f_read(&sd_fil, buf, len, &pcm_num); - - // ASSERT(pcm_res == FR_OK,"[%s]:Cannot creat dump.bin, res = - // %d",__func__, pcm_res); - } else if (opt == APP_SDMMC_DUMP_WRITE) { - res = f_write(&sd_fil, buf, len, &pcm_num); - - // ASSERT(pcm_res == FR_OK,"[%s]:Write dump.bin failed, res = %d", - // __func__, pcm_res); - } else if (opt == APP_SDMMC_DUMP_CLOSE) { - res = f_close(&sd_fil); - } - - if (res == FR_OK) { - TRACE(3, "[%s] SUCESS: opt = %d, res = %d", __func__, opt, res); - } else { - TRACE(3, "[%s] ERROR: opt = %d, res = %d", __func__, opt, res); - } -} diff --git a/apps/sdmmc/app_sdmmc.h b/apps/sdmmc/app_sdmmc.h deleted file mode 100644 index 01dced3..0000000 --- a/apps/sdmmc/app_sdmmc.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __APP_SDMMC_H__ -#define __APP_SDMMC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -enum APP_SDMMC_DUMP_T{ - APP_SDMMC_DUMP_OPEN = 0, - APP_SDMMC_DUMP_READ, - APP_SDMMC_DUMP_WRITE, - APP_SDMMC_DUMP_CLOSE, - APP_SDMMC_DUMP_NUM -}; - -int sd_open(); - -void dump_data2sd(enum APP_SDMMC_DUMP_T opt, uint8_t *buf, uint32_t len); - -#ifdef __cplusplus - } -#endif - -#endif//__FMDEC_H__ diff --git a/platform/hal/best2300p/hal_cmu_best2300p.c b/platform/hal/best2300p/hal_cmu_best2300p.c index 6a5d2ff..2b01473 100644 --- a/platform/hal/best2300p/hal_cmu_best2300p.c +++ b/platform/hal/best2300p/hal_cmu_best2300p.c @@ -1826,7 +1826,6 @@ PERPH_SET_DIV_FUNC(uart1, UART1, UART_CLK); PERPH_SET_DIV_FUNC(uart2, UART2, UART_CLK); PERPH_SET_DIV_FUNC(spi, SPI1, SYS_DIV); PERPH_SET_DIV_FUNC(slcd, SPI0, SYS_DIV); -PERPH_SET_DIV_FUNC(sdmmc, SDMMC, PERIPH_CLK); PERPH_SET_DIV_FUNC(i2c, I2C, I2C_CLK); #define PERPH_SET_FREQ_FUNC(f, F, r) \ @@ -1851,7 +1850,6 @@ PERPH_SET_FREQ_FUNC(uart1, UART1, UART_CLK); PERPH_SET_FREQ_FUNC(uart2, UART2, UART_CLK); PERPH_SET_FREQ_FUNC(spi, SPI1, SYS_DIV); PERPH_SET_FREQ_FUNC(slcd, SPI0, SYS_DIV); -PERPH_SET_FREQ_FUNC(sdmmc, SDMMC, PERIPH_CLK); PERPH_SET_FREQ_FUNC(i2c, I2C, I2C_CLK); int hal_cmu_ispi_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq) { diff --git a/platform/hal/hal_sdmmc.c b/platform/hal/hal_sdmmc.c deleted file mode 100644 index 134655a..0000000 --- a/platform/hal/hal_sdmmc.c +++ /dev/null @@ -1,2789 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifdef CHIP_HAS_SDMMC - -#include "hal_sdmmc.h" -#include "cmsis_nvic.h" -#include "errno.h" -#include "hal_cmu.h" -#include "hal_dma.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hal_uart.h" -#include "plat_addr_map.h" -#include "reg_sdmmcip.h" -#include "stdarg.h" -#include "stdio.h" -#include "string.h" - -#ifndef ETIMEDOUT -#define ETIMEDOUT 110 /* Connection timed out */ -#endif - -#define HAL_SDMMC_USE_DMA 1 -// #define __BUS_WIDTH_SUPPORT_4BIT__ 1 - -#define HAL_SDMMC_TRACE(...) -// #define HAL_SDMMC_TRACE TRACE -#define HAL_SDMMC_ASSERT(...) -// #define HAL_SDMMC_ASSERT ASSERT - -#define _SDMMC_CLOCK 52000000 - -#define _SDMMC_DMA_MINALIGN 32 - -#define _sdmmc_be32_to_cpu(x) \ - ((uint32_t)((((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))) - -#define _SDMMC_DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) -#define _SDMMC_ROUND(a, b) (((a) + (b)-1) & ~((b)-1)) - -#define _SDMMC_PAD_COUNT(s, pad) (((s)-1) / (pad) + 1) -#define _SDMMC_PAD_SIZE(s, pad) (_SDMMC_PAD_COUNT(s, pad) * pad) -#define _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \ - char __##name[_SDMMC_ROUND(_SDMMC_PAD_SIZE((size) * sizeof(type), pad), \ - align) + \ - (align - 1)]; \ - type *name = (type *)ALIGN((uint32_t)__##name, align) - -#define _SDMMC_ALLOC_ALIGN_BUFFER(type, name, size, align) \ - _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1) -#define _SDMMC_ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \ - _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, _SDMMC_DMA_MINALIGN, pad) -#define _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \ - _SDMMC_ALLOC_ALIGN_BUFFER(type, name, size, _SDMMC_DMA_MINALIGN) - -typedef struct block_dev_desc { - int if_type; /* type of the interface */ - int dev; /* device number */ - unsigned char part_type; /* partition type */ - unsigned char target; /* target SCSI ID */ - unsigned char lun; /* target LUN */ - unsigned char type; /* device type */ - unsigned char removable; /* removable device */ -#ifdef CONFIG_LBA48 - unsigned char lba48; /* device can use 48bit addr (ATA/ATAPI v7) */ -#endif - uint32_t lba; /* number of blocks */ - unsigned long blksz; /* block size */ - int log2blksz; /* for convenience: log2(blksz) */ - char vendor[40 + 1]; /* IDE model, SCSI Vendor */ - char product[20 + 1]; /* IDE Serial no, SCSI product */ - char revision[8 + 1]; /* firmware revision */ - void *priv; /* driver private struct pointer */ -} block_dev_desc_t; - -/* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */ -#define SD_VERSION_SD (1U << 31) -#define MMC_VERSION_MMC (1U << 30) - -#define MAKE_SDMMC_VERSION(a, b, c) \ - ((((uint32_t)(a)) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(c)) -#define MAKE_SD_VERSION(a, b, c) (SD_VERSION_SD | MAKE_SDMMC_VERSION(a, b, c)) -#define MAKE_MMC_VERSION(a, b, c) \ - (MMC_VERSION_MMC | MAKE_SDMMC_VERSION(a, b, c)) - -#define EXTRACT_SDMMC_MAJOR_VERSION(x) (((uint32_t)(x) >> 16) & 0xff) -#define EXTRACT_SDMMC_MINOR_VERSION(x) (((uint32_t)(x) >> 8) & 0xff) -#define EXTRACT_SDMMC_CHANGE_VERSION(x) ((uint32_t)(x)&0xff) - -#define SD_VERSION_3 MAKE_SD_VERSION(3, 0, 0) -#define SD_VERSION_2 MAKE_SD_VERSION(2, 0, 0) -#define SD_VERSION_1_0 MAKE_SD_VERSION(1, 0, 0) -#define SD_VERSION_1_10 MAKE_SD_VERSION(1, 10, 0) - -#define MMC_VERSION_UNKNOWN MAKE_MMC_VERSION(0, 0, 0) -#define MMC_VERSION_1_2 MAKE_MMC_VERSION(1, 2, 0) -#define MMC_VERSION_1_4 MAKE_MMC_VERSION(1, 4, 0) -#define MMC_VERSION_2_2 MAKE_MMC_VERSION(2, 2, 0) -#define MMC_VERSION_3 MAKE_MMC_VERSION(3, 0, 0) -#define MMC_VERSION_4 MAKE_MMC_VERSION(4, 0, 0) -#define MMC_VERSION_4_1 MAKE_MMC_VERSION(4, 1, 0) -#define MMC_VERSION_4_2 MAKE_MMC_VERSION(4, 2, 0) -#define MMC_VERSION_4_3 MAKE_MMC_VERSION(4, 3, 0) -#define MMC_VERSION_4_41 MAKE_MMC_VERSION(4, 4, 1) -#define MMC_VERSION_4_5 MAKE_MMC_VERSION(4, 5, 0) -#define MMC_VERSION_5_0 MAKE_MMC_VERSION(5, 0, 0) - -#define MMC_MODE_HS (1 << 0) -#define MMC_MODE_HS_52MHz (1 << 1) -#define MMC_MODE_4BIT (1 << 2) -#define MMC_MODE_8BIT (1 << 3) -#define MMC_MODE_SPI (1 << 4) -#define MMC_MODE_DDR_52MHz (1 << 5) - -#define SD_DATA_4BIT 0x00040000 - -#define IS_SD(x) ((x)->version & SD_VERSION_SD) -#define IS_MMC(x) ((x)->version & MMC_VERSION_MMC) - -#define MMC_DATA_READ 1 -#define MMC_DATA_WRITE 2 - -#define NO_CARD_ERR -16 /* No SD/MMC card inserted */ -#define UNUSABLE_ERR -17 /* Unusable Card */ -#define COMM_ERR -18 /* Communications Error */ -#define TIMEOUT -19 -#define SWITCH_ERR -20 /* Card reports failure to switch mode */ - -#define MMC_CMD_GO_IDLE_STATE 0 -#define MMC_CMD_SEND_OP_COND 1 -#define MMC_CMD_ALL_SEND_CID 2 -#define MMC_CMD_SET_RELATIVE_ADDR 3 -#define MMC_CMD_SET_DSR 4 -#define MMC_CMD_SWITCH 6 -#define MMC_CMD_SELECT_CARD 7 -#define MMC_CMD_SEND_EXT_CSD 8 -#define MMC_CMD_SEND_CSD 9 -#define MMC_CMD_SEND_CID 10 -#define MMC_CMD_STOP_TRANSMISSION 12 -#define MMC_CMD_SEND_STATUS 13 -#define MMC_CMD_SET_BLOCKLEN 16 -#define MMC_CMD_READ_SINGLE_BLOCK 17 -#define MMC_CMD_READ_MULTIPLE_BLOCK 18 -#define MMC_CMD_SET_BLOCK_COUNT 23 -#define MMC_CMD_WRITE_SINGLE_BLOCK 24 -#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25 -#define MMC_CMD_ERASE_GROUP_START 35 -#define MMC_CMD_ERASE_GROUP_END 36 -#define MMC_CMD_ERASE 38 -#define MMC_CMD_APP_CMD 55 -#define MMC_CMD_SPI_READ_OCR 58 -#define MMC_CMD_SPI_CRC_ON_OFF 59 -#define MMC_CMD_RES_MAN 62 - -#define MMC_CMD62_ARG1 0xefac62ec -#define MMC_CMD62_ARG2 0xcbaea7 - -#define SD_CMD_SEND_RELATIVE_ADDR 3 -#define SD_CMD_SWITCH_FUNC 6 -#define SD_CMD_SEND_IF_COND 8 -#define SD_CMD_SWITCH_UHS18V 11 - -#define SD_CMD_APP_SET_BUS_WIDTH 6 -#define SD_CMD_ERASE_WR_BLK_START 32 -#define SD_CMD_ERASE_WR_BLK_END 33 -#define SD_CMD_APP_SEND_OP_COND 41 -#define SD_CMD_APP_SEND_SCR 51 - -/* SCR definitions in different words */ -#define SD_HIGHSPEED_BUSY 0x00020000 -#define SD_HIGHSPEED_SUPPORTED 0x00020000 - -#define OCR_BUSY 0x80000000 -#define OCR_HCS 0x40000000 -#define OCR_VOLTAGE_MASK 0x007FFF80 -#define OCR_ACCESS_MODE 0x60000000 - -#define SECURE_ERASE 0x80000000 - -#define MMC_STATUS_MASK (~0x0206BF7F) -#define MMC_STATUS_SWITCH_ERROR (1 << 7) -#define MMC_STATUS_RDY_FOR_DATA (1 << 8) -#define MMC_STATUS_CURR_STATE (0xf << 9) -#define MMC_STATUS_ERROR (1 << 19) - -#define MMC_STATE_PRG (7 << 9) - -#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ -#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ -#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ -#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ -#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ -#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ -#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ -#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ -#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ -#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ -#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ -#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ -#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ -#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ -#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ -#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ -#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ - -#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ -#define MMC_SWITCH_MODE_SET_BITS \ - 0x01 /* Set bits in EXT_CSD byte \ -addressed by index which are \ -1 in value field */ -#define MMC_SWITCH_MODE_CLEAR_BITS \ - 0x02 /* Clear bits in EXT_CSD byte \ - addressed by index, which are \ - 1 in value field */ -#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target byte to value */ - -#define SD_SWITCH_CHECK 0 -#define SD_SWITCH_SWITCH 1 - -/* - * EXT_CSD fields - */ -#define EXT_CSD_ENH_START_ADDR 136 /* R/W */ -#define EXT_CSD_ENH_SIZE_MULT 140 /* R/W */ -#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ -#define EXT_CSD_PARTITION_SETTING 155 /* R/W */ -#define EXT_CSD_PARTITIONS_ATTRIBUTE 156 /* R/W */ -#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* R */ -#define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ -#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ -#define EXT_CSD_WR_REL_PARAM 166 /* R */ -#define EXT_CSD_WR_REL_SET 167 /* R/W */ -#define EXT_CSD_RPMB_MULT 168 /* RO */ -#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ -#define EXT_CSD_BOOT_BUS_WIDTH 177 -#define EXT_CSD_PART_CONF 179 /* R/W */ -#define EXT_CSD_BUS_WIDTH 183 /* R/W */ -#define EXT_CSD_HS_TIMING 185 /* R/W */ -#define EXT_CSD_REV 192 /* RO */ -#define EXT_CSD_CARD_TYPE 196 /* RO */ -#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ -#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ -#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ -#define EXT_CSD_BOOT_MULT 226 /* RO */ - -/* - * EXT_CSD field definitions - */ - -#define EXT_CSD_CMD_SET_NORMAL (1 << 0) -#define EXT_CSD_CMD_SET_SECURE (1 << 1) -#define EXT_CSD_CMD_SET_CPSECURE (1 << 2) - -#define EXT_CSD_CARD_TYPE_26 (1 << 0) /* Card can run at 26MHz */ -#define EXT_CSD_CARD_TYPE_52 (1 << 1) /* Card can run at 52MHz */ -#define EXT_CSD_CARD_TYPE_DDR_1_8V (1 << 2) -#define EXT_CSD_CARD_TYPE_DDR_1_2V (1 << 3) -#define EXT_CSD_CARD_TYPE_DDR_52 \ - (EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_DDR_1_2V) - -#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ -#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ -#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ -#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ -#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ - -#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) -#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) -#define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) -#define EXT_CSD_PARTITION_ACCESS_DISABLE (0 << 0) - -#define EXT_CSD_BOOT_ACK(x) (x << 6) -#define EXT_CSD_BOOT_PART_NUM(x) (x << 3) -#define EXT_CSD_PARTITION_ACCESS(x) (x << 0) - -#define EXT_CSD_BOOT_BUS_WIDTH_MODE(x) (x << 3) -#define EXT_CSD_BOOT_BUS_WIDTH_RESET(x) (x << 2) -#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x) (x) - -#define EXT_CSD_PARTITION_SETTING_COMPLETED (1 << 0) - -#define EXT_CSD_ENH_USR (1 << 0) /* user data area is enhanced */ -#define EXT_CSD_ENH_GP(x) (1 << ((x) + 1)) /* GP part (x+1) is enhanced */ - -#define EXT_CSD_HS_CTRL_REL (1 << 0) /* host controlled WR_REL_SET */ - -#define EXT_CSD_WR_DATA_REL_USR (1 << 0) /* user data area WR_REL */ -#define EXT_CSD_WR_DATA_REL_GP(x) (1 << ((x) + 1)) /* GP part (x+1) WR_REL */ - -#define R1_ILLEGAL_COMMAND (1 << 22) -#define R1_APP_CMD (1 << 5) - -#define MMC_RSP_PRESENT (1 << 0) -#define MMC_RSP_136 (1 << 1) /* 136 bit response */ -#define MMC_RSP_CRC (1 << 2) /* expect valid crc */ -#define MMC_RSP_BUSY (1 << 3) /* card may send busy */ -#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ - -#define MMC_RSP_NONE (0) -#define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R1b \ - (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY) -#define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC) -#define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R4 (MMC_RSP_PRESENT) -#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) - -#define MMCPART_NOAVAILABLE (0xff) -#define PART_ACCESS_MASK (0x7) -#define PART_SUPPORT (0x1) -#define ENHNCD_SUPPORT (0x2) -#define PART_ENH_ATTRIB (0x1f) - -/* Maximum block size for MMC */ -#define MMC_MAX_BLOCK_LEN 512 - -/* The number of MMC physical partitions. These consist of: - * boot partitions (2), general purpose partitions (4) in MMC v4.4. - */ -#define MMC_NUM_BOOT_PARTITION 2 -#define MMC_PART_RPMB 3 /* RPMB partition number */ - -struct mmc_cid { - unsigned long psn; - unsigned short oid; - uint8_t mid; - uint8_t prv; - uint8_t mdt; - char pnm[7]; -}; - -struct mmc_cmd { - u16 cmdidx; - uint32_t resp_type; - uint32_t cmdarg; - uint32_t response[4]; -}; - -struct mmc_data { - union { - char *dest; - const char *src; /* src buffers don't get written to */ - }; - uint32_t flags; - uint32_t blocks; - uint32_t blocksize; -}; - -/* forward decl. */ -struct mmc; - -struct mmc_ops { - int (*send_cmd)(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data); - void (*set_ios)(struct mmc *mmc); - int (*init)(struct mmc *mmc); - int (*getcd)(struct mmc *mmc); - int (*getwp)(struct mmc *mmc); -}; - -struct mmc_config { - const struct mmc_ops *ops; - uint32_t host_caps; - uint32_t voltages; - uint32_t f_min; - uint32_t f_max; - uint32_t b_max; - uint8_t part_type; -}; - -/* TODO struct mmc should be in mmc_private but it's hard to fix right now */ -struct mmc { - const struct mmc_config *cfg; /* provided configuration */ - uint32_t version; - void *priv; - uint32_t has_init; - int high_capacity; - uint32_t bus_width; - uint32_t clock; - uint32_t card_caps; - uint32_t ocr; - uint32_t dsr; - uint32_t dsr_imp; - uint32_t scr[2]; - uint32_t csd[4]; - uint32_t cid[4]; - u16 rca; - u8 part_support; - u8 part_attr; - u8 wr_rel_set; - char part_config; - char part_num; - uint32_t tran_speed; - uint32_t read_bl_len; - uint32_t write_bl_len; - uint32_t erase_grp_size; /* in 512-byte sectors */ - uint32_t hc_wp_grp_size; /* in 512-byte sectors */ - uint64_t capacity; - uint64_t capacity_user; - uint64_t capacity_boot; - uint64_t capacity_rpmb; - uint64_t capacity_gp[4]; - uint64_t enh_user_start; - uint64_t enh_user_size; - block_dev_desc_t block_dev; - char op_cond_pending; /* 1 if we are waiting on an op_cond command */ - char init_in_progress; /* 1 if we have done mmc_start_init() */ - char preinit; /* start init as early as possible */ - int ddr_mode; -}; - -struct mmc_hwpart_conf { - struct { - uint32_t enh_start; /* in 512-byte sectors */ - uint32_t enh_size; /* in 512-byte sectors, if 0 no enh area */ - unsigned wr_rel_change : 1; - unsigned wr_rel_set : 1; - } user; - struct { - uint32_t size; /* in 512-byte sectors */ - unsigned enhanced : 1; - unsigned wr_rel_change : 1; - unsigned wr_rel_set : 1; - } gp_part[4]; -}; - -enum mmc_hwpart_conf_mode { - MMC_HWPART_CONF_CHECK, - MMC_HWPART_CONF_SET, - MMC_HWPART_CONF_COMPLETE, -}; - -struct sdmmcip_host { - void *ioaddr; - unsigned int quirks; - unsigned int caps; - unsigned int version; - unsigned int clock; - unsigned int bus_hz; - unsigned int div; - int dev_index; - int dev_id; - int buswidth; - uint32_t fifoth_val; - bool detect_enb; - struct mmc *mmc; - void *priv; - - void (*clksel)(struct sdmmcip_host *host); - void (*board_init)(struct sdmmcip_host *host); - unsigned int (*get_mmc_clk)(struct sdmmcip_host *host); - - struct mmc_config cfg; - -#ifdef HAL_SDMMC_USE_DMA - /* TODO : os and non-os condition */ - uint8_t dma_ch; - volatile uint32_t sdmmc_dma_lock; - HAL_DMA_IRQ_HANDLER_T tx_dma_handler; - HAL_DMA_IRQ_HANDLER_T rx_dma_handler; -#endif -}; - -struct sdmmcip_idmac { - uint32_t flags; - uint32_t cnt; - uint32_t addr; - uint32_t next_addr; -}; - -static void hal_sdmmc_delay(uint32_t ms); - -static HAL_SDMMC_DELAY_FUNC sdmmc_delay = NULL; - -static inline void sdmmcip_writel(struct sdmmcip_host *host, int reg, - uint32_t val) { - *((volatile uint32_t *)(host->ioaddr + reg)) = val; -} - -static inline uint32_t sdmmcip_readl(struct sdmmcip_host *host, int reg) { - return *((volatile uint32_t *)(host->ioaddr + reg)); -} - -#ifdef CONFIG_MMC_SPI -#define sdmmc_host_is_spi(mmc) ((mmc)->cfg->host_caps & MMC_MODE_SPI) -#else -#define sdmmc_host_is_spi(mmc) 0 -#endif - -#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT -#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535 -#endif - -static void (*sdmmc_detected_callback)(uint8_t) = NULL; -static uint32_t sdmmc_ip_base[HAL_SDMMC_ID_NUM] = { - SDMMC_BASE, -}; -static struct sdmmcip_host sdmmc_host[HAL_SDMMC_ID_NUM]; -static struct mmc sdmmc_devices[HAL_SDMMC_ID_NUM]; -// static const char * const invalid_id = "Invalid SDMMC ID: %d\n"; - -#ifdef HAL_SDMMC_USE_DMA -static void sdmmcip0_ext_dma_tx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli); -static void sdmmcip0_ext_dma_rx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli); -static HAL_DMA_IRQ_HANDLER_T - sdmmcip_ext_dma_irq_handlers[HAL_SDMMC_ID_NUM * 2] = { - sdmmcip0_ext_dma_tx_handler, - sdmmcip0_ext_dma_rx_handler, -}; -#endif - -uint32_t _sdmmc_div64_32(uint64_t *n, uint32_t base) { - uint64_t rem = *n; - uint64_t b = base; - uint64_t res, d = 1; - uint32_t high = rem >> 32; - - /* Reduce the thing a bit first */ - res = 0; - if (high >= base) { - high /= base; - res = (uint64_t)high << 32; - rem -= (uint64_t)(high * base) << 32; - } - - while ((int64_t)b > 0 && b < rem) { - b = b + b; - d = d + d; - } - - do { - if (rem >= b) { - rem -= b; - res += d; - } - b >>= 1; - d >>= 1; - } while (d); - - *n = res; - return rem; -} - -/* The unnecessary pointer compare is there - * * to check for type safety (n must be 64bit) - * */ -#define _sdmmc_do_div(n, base) \ - ({ \ - uint32_t __base = (base); \ - uint32_t __rem; \ - (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ - if (((n) >> 32) == 0) { \ - __rem = (uint32_t)(n) % __base; \ - (n) = (uint32_t)(n) / __base; \ - } else \ - __rem = _sdmmc_div64_32(&(n), __base); \ - __rem; \ - }) - -/* Wrapper for _sdmmc_do_div(). Doesn't modify dividend and returns - * * the result, not reminder. - * */ -static inline uint64_t _sdmmc_lldiv(uint64_t dividend, uint32_t divisor) { - uint64_t __res = dividend; - _sdmmc_do_div(__res, divisor); - return (__res); -} - -static void mmc_udelay(int cnt) { - volatile uint32_t i = 0, c = 0; - for (i = 0; i < cnt; ++i) { - c++; - __asm("nop"); - } -} - -static int sdmmcip_wait_reset(struct sdmmcip_host *host, uint32_t value) { - uint32_t ctrl; - unsigned long timeout = 1000; - - sdmmcip_writel(host, SDMMCIP_REG_CTRL, value); - - while (timeout--) { - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - if (!(ctrl & SDMMCIP_REG_RESET_ALL)) - return 1; - } - return 0; -} - -#ifdef HAL_SDMMC_USE_DMA -static void sdmmcip0_ext_dma_tx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli) { - uint32_t ip_raw_int_status = 0; - struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; - HAL_SDMMC_TRACE(2, "%s:%d\n", __func__, __LINE__); - ip_raw_int_status = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - HAL_SDMMC_TRACE(3, "%s:%d, tx ip_raw_int_status 0x%x\n", __func__, __LINE__, - ip_raw_int_status); - if (ip_raw_int_status & (SDMMCIP_REG_DATA_ERR | SDMMCIP_REG_DATA_TOUT)) { - HAL_SDMMC_TRACE(3, "%s:%d, sdmmcip0 tx dma error 0x%x\n", __func__, - __LINE__, ip_raw_int_status); - } - - /* TODO : os and non-os condition */ - host->sdmmc_dma_lock = 0; -} - -static void sdmmcip0_ext_dma_rx_handler(uint8_t chan, uint32_t remain_tsize, - uint32_t error, - struct HAL_DMA_DESC_T *lli) { - uint32_t ip_raw_int_status = 0; - struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; - HAL_SDMMC_TRACE(2, "%s:%d\n", __func__, __LINE__); - ip_raw_int_status = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - HAL_SDMMC_TRACE(3, "%s:%d, ip_raw_int_status 0x%x\n", __func__, __LINE__, - ip_raw_int_status); - if (ip_raw_int_status & (SDMMCIP_REG_DATA_ERR | SDMMCIP_REG_DATA_TOUT)) { - HAL_SDMMC_TRACE(3, "%s:%d, sdmmcip0 rx dma error 0x%x\n", __func__, - __LINE__, ip_raw_int_status); - } - - /* TODO : os and non-os condition */ - host->sdmmc_dma_lock = 0; -} -#endif - -static void sdmmcip_prepare_data(struct sdmmcip_host *host, - struct mmc_data *data, - struct sdmmcip_idmac *cur_idmac, - void *bounce_buffer) { -#ifdef HAL_SDMMC_USE_DMA - uint32_t ctrl = 0; - struct HAL_DMA_CH_CFG_T dma_cfg; -#endif - sdmmcip_writel(host, SDMMCIP_REG_BLKSIZ, data->blocksize); - sdmmcip_writel(host, SDMMCIP_REG_BYTCNT, data->blocksize * data->blocks); - - /* use dma */ -#ifdef HAL_SDMMC_USE_DMA - - HAL_SDMMC_TRACE(0, "sdmmc use dma\n"); - /* enable sdmmcip e-dma */ - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl |= (SDMMCIP_REG_DMA_EN); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - host->sdmmc_dma_lock = 1; - - memset(&dma_cfg, 0, sizeof(dma_cfg)); - if (data->flags & MMC_DATA_READ) { - HAL_SDMMC_TRACE(0, "sdmmc use dma read\n"); - dma_cfg.dst = (uint32_t)data->dest; - // HAL_SDMMC_TRACE(2,"sddma :len %d, buf 0x%x\n", - // data->blocksize*data->blocks, dma_cfg.dst); - if ((dma_cfg.dst % 4) != 0) { - dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE; - } else { - dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; - } - dma_cfg.dst_bsize = HAL_DMA_BSIZE_1; - dma_cfg.dst_periph = 0; // useless - // dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; - dma_cfg.handler = host->rx_dma_handler; - dma_cfg.src_bsize = HAL_DMA_BSIZE_1; - dma_cfg.src_periph = HAL_GPDMA_SDMMC; - dma_cfg.src_tsize = data->blocks * data->blocksize / 4; - HAL_SDMMC_TRACE(1, "sdmmc use dma tsize %d\n", dma_cfg.src_tsize); - dma_cfg.src_width = HAL_DMA_WIDTH_WORD; - dma_cfg.try_burst = 1; - dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; - dma_cfg.src = (uint32_t)0; // useless - dma_cfg.ch = hal_gpdma_get_chan(dma_cfg.src_periph, HAL_DMA_HIGH_PRIO); - HAL_SDMMC_TRACE(1, "sdmmc use dma get ch %d\n", dma_cfg.ch); - } else { - HAL_SDMMC_TRACE(0, "sdmmc use dma write\n"); - dma_cfg.dst = 0; // useless - dma_cfg.dst_bsize = HAL_DMA_BSIZE_1; - dma_cfg.dst_periph = HAL_GPDMA_SDMMC; - dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; - dma_cfg.handler = host->tx_dma_handler; - dma_cfg.src_bsize = HAL_DMA_BSIZE_1; - dma_cfg.src_periph = 0; // useless - // dma_cfg.src_tsize = data->blocks*data->blocksize/4; - HAL_SDMMC_TRACE(1, "sdmmc use dma tsize %d\n", dma_cfg.src_tsize); - // dma_cfg.src_width = HAL_DMA_WIDTH_WORD; - dma_cfg.try_burst = 1; - dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; - dma_cfg.src = (uint32_t)data->src; - // uart_printf("sddma :len %d, buf 0x%x\n", data->blocksize*data->blocks, - // dma_cfg.src); - if ((dma_cfg.src % 4) != 0) { - dma_cfg.src_width = HAL_DMA_WIDTH_BYTE; - dma_cfg.src_tsize = data->blocks * data->blocksize; - } else { - dma_cfg.src_width = HAL_DMA_WIDTH_WORD; - dma_cfg.src_tsize = data->blocks * data->blocksize / 4; - } - dma_cfg.ch = hal_gpdma_get_chan(dma_cfg.dst_periph, HAL_DMA_HIGH_PRIO); - HAL_SDMMC_TRACE(1, "sdmmc use dma get ch %d\n", dma_cfg.ch); - - // uart_printf("%s:%d src 0x%x\n", __func__, __LINE__, dma_cfg.src); - } - - host->dma_ch = dma_cfg.ch; - - hal_gpdma_start(&dma_cfg); -#endif -} - -static int sdmmcip_set_transfer_mode(struct sdmmcip_host *host, - struct mmc_data *data) { - unsigned long mode; - - mode = SDMMCIP_REG_CMD_DATA_EXP; - if (data->flags & MMC_DATA_WRITE) - mode |= SDMMCIP_REG_CMD_RW; - - return mode; -} - -static int sdmmcip_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) { - int ret = 0; - int flags = 0, i; - uint32_t retry = 1000000; - uint32_t mask, ctrl; - int busy_tmo = MS_TO_TICKS(1000), busy_t = 0; -#ifndef HAL_SDMMC_USE_DMA - uint32_t status = 0, fifo_data = 0; -#endif - struct sdmmcip_host *host = mmc->priv; - - busy_t = hal_sys_timer_get(); - - while ((sdmmcip_readl(host, SDMMCIP_REG_STATUS) & SDMMCIP_REG_BUSY) && - hal_sys_timer_get() < (busy_t + busy_tmo)) { - HAL_SDMMC_TRACE(0, "[sdmmc]busy\n"); - } - - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CD); - - if (data) { - sdmmcip_prepare_data(host, data, 0, 0); - } - - sdmmcip_writel(host, SDMMCIP_REG_CMDARG, cmd->cmdarg); - - if (data) - flags = sdmmcip_set_transfer_mode(host, data); - - if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) - return -1; - - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) - flags |= SDMMCIP_REG_CMD_ABORT_STOP; - else - flags |= SDMMCIP_REG_CMD_PRV_DAT_WAIT; - - if (cmd->resp_type & MMC_RSP_PRESENT) { - flags |= SDMMCIP_REG_CMD_RESP_EXP; - if (cmd->resp_type & MMC_RSP_136) - flags |= SDMMCIP_REG_CMD_RESP_LENGTH; - } - - if (cmd->resp_type & MMC_RSP_CRC) - flags |= SDMMCIP_REG_CMD_CHECK_CRC; - - flags |= (cmd->cmdidx | SDMMCIP_REG_CMD_START | SDMMCIP_REG_CMD_USE_HOLD_REG); - - sdmmcip_writel(host, SDMMCIP_REG_CMD, flags); - - for (i = 0; i < retry; i++) { - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - if (mask & SDMMCIP_REG_INTMSK_CDONE) { - if (!data) - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CDONE); - break; - } - } - - if (i == retry) { - HAL_SDMMC_TRACE(1, "%s: Timeout.\n", __func__); - return TIMEOUT; - } - - if (mask & SDMMCIP_REG_INTMSK_RTO) { - /* - * Timeout here is not necessarily fatal. (e)MMC cards - * will splat here when they receive CMD55 as they do - * not support this command and that is exactly the way - * to tell them apart from SD cards. Thus, this output - * below shall be TRACE(). eMMC cards also do not favor - * CMD8, please keep that in mind. - */ - HAL_SDMMC_TRACE(1, "%s: Response Timeout.\n", __func__); - return TIMEOUT; - } else if (mask & SDMMCIP_REG_INTMSK_RE) { - HAL_SDMMC_TRACE(1, "%s: Response Error.\n", __func__); - return -1; - } - - if (cmd->resp_type & MMC_RSP_PRESENT) { - if (cmd->resp_type & MMC_RSP_136) { - cmd->response[0] = sdmmcip_readl(host, SDMMCIP_REG_RESP3); - cmd->response[1] = sdmmcip_readl(host, SDMMCIP_REG_RESP2); - cmd->response[2] = sdmmcip_readl(host, SDMMCIP_REG_RESP1); - cmd->response[3] = sdmmcip_readl(host, SDMMCIP_REG_RESP0); - } else { - cmd->response[0] = sdmmcip_readl(host, SDMMCIP_REG_RESP0); - } - } - -#ifndef HAL_SDMMC_USE_DMA - if (data) { - i = 0; - while (1) { - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - if (mask & (SDMMCIP_REG_DATA_ERR | SDMMCIP_REG_DATA_TOUT)) { - HAL_SDMMC_TRACE(1, "%s: READ DATA ERROR!\n", __func__); - ret = -1; - goto out; - } - status = sdmmcip_readl(host, SDMMCIP_REG_STATUS); - if (data->flags == MMC_DATA_READ) { - if (status & SDMMCIP_REG_FIFO_COUNT_MASK) { - fifo_data = sdmmcip_readl(host, SDMMCIP_REG_FIFO_OFFSET); - // HAL_SDMMC_TRACE(3,"%s: count %d, read -> 0x%x\n", __func__, i, - // fifo_data); - /* FIXME: now we just deal with 32bit width fifo one time */ - if (i < data->blocks * data->blocksize) { - memcpy(data->dest + i, &fifo_data, sizeof(fifo_data)); - i += sizeof(fifo_data); - } else { - HAL_SDMMC_TRACE(1, "%s: fifo data too much\n", __func__); - ret = -1; - goto out; - } - } - /* nothing to read from fifo and DTO is set */ - else if (mask & SDMMCIP_REG_INTMSK_DTO) { - if (i != data->blocks * data->blocksize) { - HAL_SDMMC_TRACE(3, "%s: need to read %d, actually read %d\n", - __func__, data->blocks * data->blocksize, i); - } - ret = 0; - goto out; - } - } else { - /* nothing to write to fifo and DTO is set */ - if (mask & SDMMCIP_REG_INTMSK_DTO) { - /* check if number is right */ - if (i != data->blocks * data->blocksize) { - HAL_SDMMC_TRACE(3, "%s: need to write %d, actually written %d\n", - __func__, data->blocks * data->blocksize, i); - } - ret = 0; - goto out; - } else if (!(status & SDMMCIP_REG_FIFO_COUNT_MASK)) { - /* FIXME: now we just deal with 32bit width fifo one time */ - if (i < data->blocks * data->blocksize) { - memcpy(&fifo_data, data->src + i, sizeof(fifo_data)); - // HAL_SDMMC_TRACE(4,"%s: fifo %d, count %d, write -> 0x%x\n", - // __func__, ((status & - // SDMMCIP_REG_FIFO_COUNT_MASK)>>SDMMCIP_REG_FIFO_COUNT_SHIFT), i, - // fifo_data); - i += sizeof(fifo_data); - sdmmcip_writel(host, SDMMCIP_REG_FIFO_OFFSET, fifo_data); - } else { - HAL_SDMMC_TRACE(1, "%s: no data to write to fifo, do nothing\n", - __func__); - } - } - } - } - } -#endif - -#ifdef HAL_SDMMC_USE_DMA - while (host->sdmmc_dma_lock) - ; - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl |= SDMMCIP_REG_CTRL_DMA_RESET; - sdmmcip_wait_reset(host, ctrl); - if (data) { - hal_gpdma_free_chan(host->dma_ch); -#if 0 - if (data->flags & MMC_DATA_READ) { - for (int ccc = 0; ccc < 400; ++ccc) { - HAL_SDMMC_TRACE(2,"%d-0x%x ", ccc, data->dest[ccc]); - } - HAL_SDMMC_TRACE(0,"\n"); - } -#endif - } -#endif - -#ifndef HAL_SDMMC_USE_DMA -out: -#endif - - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, mask & (~SDMMCIP_REG_INTMSK_CD)); - - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl &= ~(SDMMCIP_REG_DMA_EN); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - mmc_udelay(100); - - return ret; -} - -static int sdmmcip_setup_bus(struct sdmmcip_host *host, uint32_t freq) { - uint32_t div, status; - int timeout = 10000; - unsigned long sclk; - - if ((freq == host->clock) || (freq == 0)) - return 0; - /* - * If host->get_mmc_clk isn't defined, - * then assume that host->bus_hz is source clock value. - * host->bus_hz should be set by user. - */ - if (host->get_mmc_clk) - sclk = host->get_mmc_clk(host); - else if (host->bus_hz) - sclk = host->bus_hz; - else { - HAL_SDMMC_TRACE(1, "%s: Didn't get source clock value.\n", __func__); - return -EINVAL; - } - - if (sclk == freq) - div = 0; /* bypass mode */ - else - div = _SDMMC_DIV_ROUND_UP(sclk, 2 * freq); - - HAL_SDMMC_TRACE(4, "%s : freq %d, sclk %ld, div %d\n", __func__, freq, sclk, - div); - - sdmmcip_writel(host, SDMMCIP_REG_CLKENA, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x03000000); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x11000000); - - sdmmcip_writel(host, SDMMCIP_REG_CLKDIV, div); - sdmmcip_writel(host, SDMMCIP_REG_CMD, - SDMMCIP_REG_CMD_PRV_DAT_WAIT | SDMMCIP_REG_CMD_UPD_CLK | - SDMMCIP_REG_CMD_START); - - do { - status = sdmmcip_readl(host, SDMMCIP_REG_CMD); - if (timeout-- < 0) { - HAL_SDMMC_TRACE(1, "%s: Timeout!\n", __func__); - return -ETIMEDOUT; - } - } while (status & SDMMCIP_REG_CMD_START); - - sdmmcip_writel(host, SDMMCIP_REG_CLKENA, - SDMMCIP_REG_CLKEN_ENABLE | SDMMCIP_REG_CLKEN_LOW_PWR); - // sdmmcip_writel(host, SDMMCIP_REG_CLKENA, SDMMCIP_REG_CLKEN_ENABLE); - - sdmmcip_writel(host, SDMMCIP_REG_CMD, - SDMMCIP_REG_CMD_PRV_DAT_WAIT | SDMMCIP_REG_CMD_UPD_CLK | - SDMMCIP_REG_CMD_START); - - timeout = 10000; - do { - status = sdmmcip_readl(host, SDMMCIP_REG_CMD); - if (timeout-- < 0) { - HAL_SDMMC_TRACE(1, "%s: Timeout!\n", __func__); - return -ETIMEDOUT; - } - } while (status & SDMMCIP_REG_CMD_START); - - host->clock = freq; - - return 0; -} - -static void sdmmcip_set_ios(struct mmc *mmc) { - struct sdmmcip_host *host = (struct sdmmcip_host *)mmc->priv; - uint32_t ctype, regs; - - HAL_SDMMC_TRACE(2, "Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock); - - sdmmcip_setup_bus(host, mmc->clock); - - switch (mmc->bus_width) { - case 8: - ctype = SDMMCIP_REG_CTYPE_8BIT; - break; - case 4: - ctype = SDMMCIP_REG_CTYPE_4BIT; - break; - default: - ctype = SDMMCIP_REG_CTYPE_1BIT; - break; - } - - sdmmcip_writel(host, SDMMCIP_REG_CTYPE, ctype); - - regs = sdmmcip_readl(host, SDMMCIP_REG_UHS_REG); - if (mmc->ddr_mode) - regs |= SDMMCIP_REG_DDR_MODE; - else - regs &= ~SDMMCIP_REG_DDR_MODE; - - sdmmcip_writel(host, SDMMCIP_REG_UHS_REG, regs); - - if (host->clksel) - host->clksel(host); -} - -static int sdmmcip_init(struct mmc *mmc) { - struct sdmmcip_host *host = mmc->priv; - - if (host->board_init) - host->board_init(host); - - HAL_SDMMC_TRACE(2, "host->ioaddr %x, SDMMCIP_REG_PWREN %x\n", host->ioaddr, - SDMMCIP_REG_PWREN); - sdmmcip_writel(host, SDMMCIP_REG_PWREN, 1); - - if (!sdmmcip_wait_reset(host, SDMMCIP_REG_RESET_ALL)) { - HAL_SDMMC_TRACE(2, "%s[%d] Fail-reset!!\n", __func__, __LINE__); - return -1; - } - - /* Enumerate at 400KHz */ - sdmmcip_setup_bus(host, mmc->cfg->f_min); - - if (host->detect_enb) { - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, - SDMMCIP_REG_INTMSK_ALL & (~SDMMCIP_REG_INTMSK_CD)); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, SDMMCIP_REG_INTMSK_CD); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, SDMMCIP_REG_INT_EN); - } else { - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_ALL); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, ~SDMMCIP_REG_INTMSK_ALL); - } - - sdmmcip_writel(host, SDMMCIP_REG_TMOUT, 0xFFFFFFFF); - - sdmmcip_writel(host, SDMMCIP_REG_IDINTEN, 0); - sdmmcip_writel(host, SDMMCIP_REG_BMOD, 1); - - sdmmcip_writel(host, SDMMCIP_REG_FIFOTH, host->fifoth_val); - - sdmmcip_writel(host, SDMMCIP_REG_CLKENA, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x03000000); - // sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x11000000); - - sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 0); - mmc_udelay(1000); - sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 1); - mmc_udelay(1000); - mmc_udelay(1000); - sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 0); - // sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 1); - - return 0; -} - -static const struct mmc_ops sdmmcip_ops = { - .send_cmd = sdmmcip_send_cmd, - .set_ios = sdmmcip_set_ios, - .init = sdmmcip_init, -}; - -int board_mmc_getcd(struct mmc *mmc) { return -1; } - -int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { - int ret; - - int i; - uint8_t *ptr; - - HAL_SDMMC_TRACE(1, "CMD_SEND:%d\n", cmd->cmdidx); - HAL_SDMMC_TRACE(1, "\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); - ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); - HAL_SDMMC_TRACE(0, "send cmd end..."); - switch (cmd->resp_type) { - case MMC_RSP_NONE: - HAL_SDMMC_TRACE(0, "\t\tMMC_RSP_NONE\n"); - break; - case MMC_RSP_R1: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n", cmd->response[0]); - break; - case MMC_RSP_R1b: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R1b\t\t 0x%08X \n", cmd->response[0]); - break; - case MMC_RSP_R2: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R2\t\t 0x%08X \n", cmd->response[0]); - HAL_SDMMC_TRACE(1, "\t\t \t\t 0x%08X \n", cmd->response[1]); - HAL_SDMMC_TRACE(1, "\t\t \t\t 0x%08X \n", cmd->response[2]); - HAL_SDMMC_TRACE(1, "\t\t \t\t 0x%08X \n", cmd->response[3]); - HAL_SDMMC_TRACE(0, "\n"); - HAL_SDMMC_TRACE(0, "\t\t\t\t\tDUMPING DATA\n"); - for (i = 0; i < 4; i++) { - int j; - HAL_SDMMC_TRACE(1, "\t\t\t\t\t%03d - ", i * 4); - ptr = (uint8_t *)&cmd->response[i]; - ptr += 3; - for (j = 0; j < 4; j++) - HAL_SDMMC_TRACE(1, "%02X ", *ptr--); - HAL_SDMMC_TRACE(0, "\n"); - } - break; - case MMC_RSP_R3: - HAL_SDMMC_TRACE(1, "\t\tMMC_RSP_R3,4\t\t 0x%08X \n", cmd->response[0]); - break; - default: - HAL_SDMMC_TRACE(0, "\t\tERROR MMC rsp not supported\n"); - break; - } - return ret; -} - -int mmc_send_status(struct mmc *mmc, int timeout) { - struct mmc_cmd cmd; - int err, retries = 5; - int POSSIBLY_UNUSED status; - - cmd.cmdidx = MMC_CMD_SEND_STATUS; - cmd.resp_type = MMC_RSP_R1; - if (!sdmmc_host_is_spi(mmc)) - cmd.cmdarg = mmc->rca << 16; - - while (1) { - err = mmc_send_cmd(mmc, &cmd, NULL); - if (!err) { - if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) && - (cmd.response[0] & MMC_STATUS_CURR_STATE) != MMC_STATE_PRG) - break; - else if (cmd.response[0] & MMC_STATUS_MASK) { - return COMM_ERR; - } - } else if (--retries < 0) - return err; - - if (timeout-- <= 0) - break; - - mmc_udelay(1000); - } - - status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; - HAL_SDMMC_TRACE(1, "CURR STATE:%d\n", status); - if (timeout <= 0) { - return TIMEOUT; - } - if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR) - return SWITCH_ERR; - - return 0; -} - -int mmc_set_blocklen(struct mmc *mmc, int len) { - struct mmc_cmd cmd; - - if (mmc->ddr_mode) - return 0; - - cmd.cmdidx = MMC_CMD_SET_BLOCKLEN; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = len; - - return mmc_send_cmd(mmc, &cmd, NULL); -} - -struct mmc *find_mmc_device(int dev_num) { return &sdmmc_devices[dev_num]; } - -static int mmc_read_blocks(struct mmc *mmc, void *dst, uint32_t start, - uint32_t blkcnt) { - struct mmc_cmd cmd; - struct mmc_data data; - - if (blkcnt > 1) - cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; - else - cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK; - - if (mmc->high_capacity) - cmd.cmdarg = start; - else - cmd.cmdarg = start * mmc->read_bl_len; - - cmd.resp_type = MMC_RSP_R1; - - data.dest = dst; - data.blocks = blkcnt; - data.blocksize = mmc->read_bl_len; - data.flags = MMC_DATA_READ; - - if (mmc_send_cmd(mmc, &cmd, &data)) - return 0; - - if (blkcnt > 1) { - cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_R1b; - if (mmc_send_cmd(mmc, &cmd, NULL)) { - return 0; - } - } - - return blkcnt; -} - -static unsigned long mmc_bread(int dev_num, uint32_t start, uint32_t blkcnt, - void *dst) { - uint32_t cur, blocks_todo = blkcnt; - - if (blkcnt == 0) - return 0; - - struct mmc *mmc = find_mmc_device(dev_num); - if (!mmc) - return 0; - - if ((start + blkcnt) > mmc->block_dev.lba) { - return 0; - } - - if (mmc_set_blocklen(mmc, mmc->read_bl_len)) - return 0; - - do { - cur = (blocks_todo > mmc->cfg->b_max) ? mmc->cfg->b_max : blocks_todo; - if (mmc_read_blocks(mmc, dst, start, cur) != cur) - return 0; - blocks_todo -= cur; - start += cur; - dst += cur * mmc->read_bl_len; - } while (blocks_todo > 0); - - return blkcnt; -} - -static unsigned long mmc_erase_t(struct mmc *mmc, unsigned long start, - uint32_t blkcnt) { - struct mmc_cmd cmd; - unsigned long end; - int err, start_cmd, end_cmd; - - if (mmc->high_capacity) { - end = start + blkcnt - 1; - } else { - end = (start + blkcnt - 1) * mmc->write_bl_len; - start *= mmc->write_bl_len; - } - - if (IS_SD(mmc)) { - start_cmd = SD_CMD_ERASE_WR_BLK_START; - end_cmd = SD_CMD_ERASE_WR_BLK_END; - } else { - start_cmd = MMC_CMD_ERASE_GROUP_START; - end_cmd = MMC_CMD_ERASE_GROUP_END; - } - - cmd.cmdidx = start_cmd; - cmd.cmdarg = start; - cmd.resp_type = MMC_RSP_R1; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - cmd.cmdidx = end_cmd; - cmd.cmdarg = end; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - cmd.cmdidx = MMC_CMD_ERASE; - cmd.cmdarg = SECURE_ERASE; - cmd.resp_type = MMC_RSP_R1b; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - goto err_out; - - return 0; - -err_out: - // puts("mmc erase failed\n"); - return err; -} - -unsigned long mmc_berase(int dev_num, uint32_t start, uint32_t blkcnt) { - int err = 0; - struct mmc *mmc = find_mmc_device(dev_num); - uint32_t blk = 0, blk_r = 0; - int timeout = 1000; - - if (!mmc) - return -1; - - if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size)) - // printf("\n\nCaution! Your devices Erase group is 0x%x\n" - // "The erase range would be change to " - // "0x" LBAF "~0x" LBAF "\n\n", - // mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), - // ((start + blkcnt + mmc->erase_grp_size) - // & ~(mmc->erase_grp_size - 1)) - 1); - - while (blk < blkcnt) { - blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? mmc->erase_grp_size - : (blkcnt - blk); - err = mmc_erase_t(mmc, start + blk, blk_r); - if (err) - break; - - blk += blk_r; - - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return 0; - } - - return blk; -} - -static unsigned long mmc_write_blocks(struct mmc *mmc, uint32_t start, - uint32_t blkcnt, const void *src) { - struct mmc_cmd cmd; - struct mmc_data data; - int timeout = 1000; - - if ((start + blkcnt) > mmc->block_dev.lba) { - return 0; - } - - if (blkcnt == 0) - return 0; - else if (blkcnt == 1) - cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; - else - cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; - - if (mmc->high_capacity) - cmd.cmdarg = start; - else - cmd.cmdarg = start * mmc->write_bl_len; - - cmd.resp_type = MMC_RSP_R1; - - data.src = src; - data.blocks = blkcnt; - data.blocksize = mmc->write_bl_len; - data.flags = MMC_DATA_WRITE; - - if (mmc_send_cmd(mmc, &cmd, &data)) { - HAL_SDMMC_TRACE(0, "mmc write failed\n"); - return 0; - } - - /* SPI multiblock writes terminate using a special - * token, not a STOP_TRANSMISSION request. - */ - if (!sdmmc_host_is_spi(mmc) && blkcnt > 1) { - cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_R1b; - if (mmc_send_cmd(mmc, &cmd, NULL)) { - HAL_SDMMC_TRACE(0, "mmc fail to send stop cmd\n"); - return 0; - } - } - - /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return 0; - - return blkcnt; -} - -unsigned long mmc_bwrite(int dev_num, uint32_t start, uint32_t blkcnt, - const void *src) { - uint32_t cur, blocks_todo = blkcnt; - - struct mmc *mmc = find_mmc_device(dev_num); - if (!mmc) - return 0; - - if (mmc_set_blocklen(mmc, mmc->write_bl_len)) - return 0; - - do { - cur = (blocks_todo > mmc->cfg->b_max) ? mmc->cfg->b_max : blocks_todo; - if (mmc_write_blocks(mmc, start, cur, src) != cur) - return 0; - blocks_todo -= cur; - start += cur; - src += cur * mmc->write_bl_len; - } while (blocks_todo > 0); - - return blkcnt; -} - -static int mmc_go_idle(struct mmc *mmc) { - struct mmc_cmd cmd; - int err; - - mmc_udelay(1000); - - cmd.cmdidx = MMC_CMD_GO_IDLE_STATE; - cmd.cmdarg = 0; - cmd.resp_type = MMC_RSP_NONE; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - mmc_udelay(2000); - - return 0; -} - -static int sd_send_op_cond(struct mmc *mmc) { - int timeout = 1000; - int err; - struct mmc_cmd cmd; - - while (1) { - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SEND_OP_COND; - cmd.resp_type = MMC_RSP_R3; - - /* - * Most cards do not answer if some reserved bits - * in the ocr are set. However, Some controller - * can set bit 7 (reserved for low voltages), but - * how to manage low voltages SD card is not yet - * specified. - */ - cmd.cmdarg = sdmmc_host_is_spi(mmc) ? 0 : (mmc->cfg->voltages & 0xff8000); - - if (mmc->version == SD_VERSION_2) - cmd.cmdarg |= OCR_HCS; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if (cmd.response[0] & OCR_BUSY) - break; - - if (timeout-- <= 0) - return UNUSABLE_ERR; - - mmc_udelay(1000); - } - - if (mmc->version != SD_VERSION_2) - mmc->version = SD_VERSION_1_0; - - if (sdmmc_host_is_spi(mmc)) { /* read OCR for spi */ - cmd.cmdidx = MMC_CMD_SPI_READ_OCR; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } - - mmc->ocr = cmd.response[0]; - - mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); - mmc->rca = 0; - - return 0; -} - -static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg) { - struct mmc_cmd cmd; - int err; - - cmd.cmdidx = MMC_CMD_SEND_OP_COND; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - if (use_arg && !sdmmc_host_is_spi(mmc)) - cmd.cmdarg = OCR_HCS | - (mmc->cfg->voltages & (mmc->ocr & OCR_VOLTAGE_MASK)) | - (mmc->ocr & OCR_ACCESS_MODE); - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - mmc->ocr = cmd.response[0]; - return 0; -} - -static int mmc_send_op_cond(struct mmc *mmc) { - int err, i; - - /* Some cards seem to need this */ - // mmc_go_idle(mmc); - - /* Asking to the card its capabilities */ - for (i = 0; i < 2; i++) { - err = mmc_send_op_cond_iter(mmc, i != 0); - if (err) - return err; - - /* exit if not busy (flag seems to be inverted) */ - if (mmc->ocr & OCR_BUSY) - break; - } - mmc->op_cond_pending = 1; - return 0; -} - -static int mmc_complete_op_cond(struct mmc *mmc) { - struct mmc_cmd cmd; - int err; - - mmc->op_cond_pending = 0; - if (!(mmc->ocr & OCR_BUSY)) { - while (1) { - err = mmc_send_op_cond_iter(mmc, 1); - if (err) - return err; - if (mmc->ocr & OCR_BUSY) - break; - mmc_udelay(100); - } - } - - if (sdmmc_host_is_spi(mmc)) { /* read OCR for spi */ - cmd.cmdidx = MMC_CMD_SPI_READ_OCR; - cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - mmc->ocr = cmd.response[0]; - } - - mmc->version = MMC_VERSION_UNKNOWN; - - mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); - mmc->rca = 1; - - return 0; -} - -static int mmc_send_ext_csd(struct mmc *mmc, uint8_t *ext_csd) { - struct mmc_cmd cmd; - struct mmc_data data; - int err; - - /* Get the Card Status Register */ - cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - data.dest = (char *)ext_csd; - data.blocks = 1; - data.blocksize = MMC_MAX_BLOCK_LEN; - data.flags = MMC_DATA_READ; - - HAL_SDMMC_TRACE(1, "[%s] start...", __func__); - err = mmc_send_cmd(mmc, &cmd, &data); - HAL_SDMMC_TRACE(2, "[%s] err = %d", __func__, err); - - return err; -} - -static int mmc_switch(struct mmc *mmc, uint8_t set, uint8_t index, - uint8_t value) { - struct mmc_cmd cmd; - int timeout = 1000; - int ret; - - cmd.cmdidx = MMC_CMD_SWITCH; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = - (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (index << 16) | (value << 8); - - ret = mmc_send_cmd(mmc, &cmd, NULL); - - /* Waiting for the ready status */ - if (!ret) - ret = mmc_send_status(mmc, timeout); - - return ret; -} - -static int mmc_change_freq(struct mmc *mmc) { - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, ext_csd, MMC_MAX_BLOCK_LEN); - char cardtype; - int err; - - mmc->card_caps = 0; - - if (sdmmc_host_is_spi(mmc)) - return 0; - - /* Only version 4 supports high-speed */ - if (mmc->version < MMC_VERSION_4) - return 0; - - mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT; - - err = mmc_send_ext_csd(mmc, ext_csd); - - if (err) - return err; - - cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); - - if (err) - return err == SWITCH_ERR ? 0 : err; - - /* Now check to see that it worked */ - err = mmc_send_ext_csd(mmc, ext_csd); - - if (err) - return err; - - /* No high-speed support */ - if (!ext_csd[EXT_CSD_HS_TIMING]) - return 0; - - /* High Speed is set, there are two types: 52MHz and 26MHz */ - if (cardtype & EXT_CSD_CARD_TYPE_52) { - if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V) - mmc->card_caps |= MMC_MODE_DDR_52MHz; - mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; - } else { - mmc->card_caps |= MMC_MODE_HS; - } - - return 0; -} - -static int mmc_set_capacity(struct mmc *mmc, int part_num) { - switch (part_num) { - case 0: - mmc->capacity = mmc->capacity_user; - break; - case 1: - case 2: - mmc->capacity = mmc->capacity_boot; - break; - case 3: - mmc->capacity = mmc->capacity_rpmb; - break; - case 4: - case 5: - case 6: - case 7: - mmc->capacity = mmc->capacity_gp[part_num - 4]; - break; - default: - return -1; - } - - mmc->block_dev.lba = _sdmmc_lldiv(mmc->capacity, mmc->read_bl_len); - - return 0; -} - -int mmc_getcd(struct mmc *mmc) { - int cd; - - cd = board_mmc_getcd(mmc); - - if (cd < 0) { - if (mmc->cfg->ops->getcd) - cd = mmc->cfg->ops->getcd(mmc); - else - cd = 1; - } - - return cd; -} - -static int sd_switch(struct mmc *mmc, int mode, int group, uint8_t value, - uint8_t *resp) { - struct mmc_cmd cmd; - struct mmc_data data; - - /* Switch the frequency */ - cmd.cmdidx = SD_CMD_SWITCH_FUNC; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = (mode << 31) | 0xffffff; - cmd.cmdarg &= ~(0xf << (group * 4)); - cmd.cmdarg |= value << (group * 4); - - data.dest = (char *)resp; - data.blocksize = 64; - data.blocks = 1; - data.flags = MMC_DATA_READ; - - hal_sdmmc_delay(1); - - return mmc_send_cmd(mmc, &cmd, &data); -} - -static int sd_change_freq(struct mmc *mmc) { - int err; - struct mmc_cmd cmd; - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint32_t, scr, 2); - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint32_t, switch_status, 16); - struct mmc_data data; - int timeout; - - mmc->card_caps = 0; - - if (sdmmc_host_is_spi(mmc)) - return 0; - - /* Read the SCR to find out if this card supports higher speeds */ - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SEND_SCR; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 0; - - timeout = 3; - -retry_scr: - data.dest = (char *)scr; - data.blocksize = 8; - data.blocks = 1; - data.flags = MMC_DATA_READ; - - err = mmc_send_cmd(mmc, &cmd, &data); - - if (err) { - if (timeout--) - goto retry_scr; - - return err; - } - - mmc->scr[0] = _sdmmc_be32_to_cpu(scr[0]); - mmc->scr[1] = _sdmmc_be32_to_cpu(scr[1]); - - switch ((mmc->scr[0] >> 24) & 0xf) { - case 0: - mmc->version = SD_VERSION_1_0; - break; - case 1: - mmc->version = SD_VERSION_1_10; - break; - case 2: - mmc->version = SD_VERSION_2; - if ((mmc->scr[0] >> 15) & 0x1) - mmc->version = SD_VERSION_3; - break; - default: - mmc->version = SD_VERSION_1_0; - break; - } - - if (mmc->scr[0] & SD_DATA_4BIT) - mmc->card_caps |= MMC_MODE_4BIT; - - /* Version 1.0 doesn't support switching */ - if (mmc->version == SD_VERSION_1_0) - return 0; - - timeout = 4; - while (timeout--) { - err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1, (uint8_t *)switch_status); - - if (err) - return err; - - /* The high-speed function is busy. Try again */ - if (!(_sdmmc_be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY)) - break; - } - - /* If high-speed isn't supported, we return */ - if (!(_sdmmc_be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)) - return 0; - - /* - * If the host doesn't support SD_HIGHSPEED, do not switch card to - * HIGHSPEED mode even if the card support SD_HIGHSPPED. - * This can avoid furthur problem when the card runs in different - * mode between the host. - */ - if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) && - (mmc->cfg->host_caps & MMC_MODE_HS))) - return 0; - - err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (uint8_t *)switch_status); - - if (err) - return err; - - if ((_sdmmc_be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000) - mmc->card_caps |= MMC_MODE_HS; - - return 0; -} - -/* frequency bases */ -/* divided by 10 to be nice to platforms without floating point */ -static const int fbase[] = { - 10000, - 100000, - 1000000, - 10000000, -}; - -/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice - * to platforms without floating point. - */ -static const int multipliers[] = { - 0, /* reserved */ - 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, -}; - -static void mmc_set_ios(struct mmc *mmc) { - if (mmc->cfg->ops->set_ios) - mmc->cfg->ops->set_ios(mmc); -} - -void mmc_set_clock(struct mmc *mmc, uint32_t clock) { - if (clock > mmc->cfg->f_max) - clock = mmc->cfg->f_max; - - if (clock < mmc->cfg->f_min) - clock = mmc->cfg->f_min; - - mmc->clock = clock; - - mmc_set_ios(mmc); -} - -static void mmc_set_bus_width(struct mmc *mmc, uint32_t width) { - mmc->bus_width = width; - - mmc_set_ios(mmc); -} - -static int mmc_startup(struct mmc *mmc) { - int err, i; - uint32_t mult, freq; - uint32_t cmult, csize, capacity; - struct mmc_cmd cmd; - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, ext_csd, MMC_MAX_BLOCK_LEN); - _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, test_csd, MMC_MAX_BLOCK_LEN); - int timeout = 1000; - bool has_parts = false; - bool part_completed; - -#ifdef CONFIG_MMC_SPI_CRC_ON - if (sdmmc_host_is_spi(mmc)) { /* enable CRC check for spi */ - cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 1; - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } -#endif - - /* Put the Card in Identify Mode */ - cmd.cmdidx = sdmmc_host_is_spi(mmc) - ? MMC_CMD_SEND_CID - : MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */ - cmd.resp_type = MMC_RSP_R2; - cmd.cmdarg = 0; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - memcpy(mmc->cid, cmd.response, 16); - - /* - * For MMC cards, set the Relative Address. - * For SD cards, get the Relatvie Address. - * This also puts the cards into Standby State - */ - if (!sdmmc_host_is_spi(mmc)) { /* cmd not supported in spi */ - cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR; - cmd.cmdarg = mmc->rca << 16; - cmd.resp_type = MMC_RSP_R6; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if (IS_SD(mmc)) - mmc->rca = (cmd.response[0] >> 16) & 0xffff; - } - - /* Get the Card-Specific Data */ - cmd.cmdidx = MMC_CMD_SEND_CSD; - cmd.resp_type = MMC_RSP_R2; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - /* Waiting for the ready status */ - mmc_send_status(mmc, timeout); - - if (err) - return err; - - mmc->csd[0] = cmd.response[0]; - mmc->csd[1] = cmd.response[1]; - mmc->csd[2] = cmd.response[2]; - mmc->csd[3] = cmd.response[3]; - - if (mmc->version == MMC_VERSION_UNKNOWN) { - int version = (cmd.response[0] >> 26) & 0xf; - - switch (version) { - case 0: - mmc->version = MMC_VERSION_1_2; - break; - case 1: - mmc->version = MMC_VERSION_1_4; - break; - case 2: - mmc->version = MMC_VERSION_2_2; - break; - case 3: - mmc->version = MMC_VERSION_3; - break; - case 4: - mmc->version = MMC_VERSION_4; - break; - default: - mmc->version = MMC_VERSION_1_2; - break; - } - } - - /* divide frequency by 10, since the mults are 10x bigger */ - freq = fbase[(cmd.response[0] & 0x7)]; - mult = multipliers[((cmd.response[0] >> 3) & 0xf)]; - - mmc->tran_speed = freq * mult; - - mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1); - mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf); - - if (IS_SD(mmc)) - mmc->write_bl_len = mmc->read_bl_len; - else - mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf); - - if (mmc->high_capacity) { - csize = (mmc->csd[1] & 0x3f) << 16 | (mmc->csd[2] & 0xffff0000) >> 16; - cmult = 8; - } else { - csize = (mmc->csd[1] & 0x3ff) << 2 | (mmc->csd[2] & 0xc0000000) >> 30; - cmult = (mmc->csd[2] & 0x00038000) >> 15; - } - - mmc->capacity_user = (csize + 1) << (cmult + 2); - mmc->capacity_user *= mmc->read_bl_len; - mmc->capacity_boot = 0; - mmc->capacity_rpmb = 0; - for (i = 0; i < 4; i++) - mmc->capacity_gp[i] = 0; - - if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) - mmc->read_bl_len = MMC_MAX_BLOCK_LEN; - - if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) - mmc->write_bl_len = MMC_MAX_BLOCK_LEN; - - if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) { - cmd.cmdidx = MMC_CMD_SET_DSR; - cmd.cmdarg = (mmc->dsr & 0xffff) << 16; - cmd.resp_type = MMC_RSP_NONE; - if (mmc_send_cmd(mmc, &cmd, NULL)) { - HAL_SDMMC_TRACE(0, "MMC: SET_DSR failed\n"); - } - } - - /* Select the card, and put it into Transfer Mode */ - if (!sdmmc_host_is_spi(mmc)) { /* cmd not supported in spi */ - cmd.cmdidx = MMC_CMD_SELECT_CARD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - } - - /* - * For SD, its erase group is always one sector - */ - mmc->erase_grp_size = 1; - mmc->part_config = MMCPART_NOAVAILABLE; - if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { - /* check ext_csd version and capacity */ - err = mmc_send_ext_csd(mmc, ext_csd); - if (err) - return err; - if (ext_csd[EXT_CSD_REV] >= 2) { - /* - * According to the JEDEC Standard, the value of - * ext_csd's capacity is valid if the value is more - * than 2GB - */ - capacity = ext_csd[EXT_CSD_SEC_CNT] << 0 | - ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | - ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | - ext_csd[EXT_CSD_SEC_CNT + 3] << 24; - capacity *= MMC_MAX_BLOCK_LEN; - if ((capacity >> 20) > 2 * 1024) - mmc->capacity_user = capacity; - } - - switch (ext_csd[EXT_CSD_REV]) { - case 1: - mmc->version = MMC_VERSION_4_1; - break; - case 2: - mmc->version = MMC_VERSION_4_2; - break; - case 3: - mmc->version = MMC_VERSION_4_3; - break; - case 5: - mmc->version = MMC_VERSION_4_41; - break; - case 6: - mmc->version = MMC_VERSION_4_5; - break; - case 7: - mmc->version = MMC_VERSION_5_0; - break; - } - - /* The partition data may be non-zero but it is only - * effective if PARTITION_SETTING_COMPLETED is set in - * EXT_CSD, so ignore any data if this bit is not set, - * except for enabling the high-capacity group size - * definition (see below). */ - part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] & - EXT_CSD_PARTITION_SETTING_COMPLETED); - - /* store the partition info of emmc */ - mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT]; - if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || - ext_csd[EXT_CSD_BOOT_MULT]) - mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; - if (part_completed && - (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT)) - mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE]; - - mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17; - - mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17; - - for (i = 0; i < 4; i++) { - int idx = EXT_CSD_GP_SIZE_MULT + i * 3; - uint32_t mult = - (ext_csd[idx + 2] << 16) + (ext_csd[idx + 1] << 8) + ext_csd[idx]; - if (mult) - has_parts = true; - if (!part_completed) - continue; - mmc->capacity_gp[i] = mult; - mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; - mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - mmc->capacity_gp[i] <<= 19; - } - - if (part_completed) { - mmc->enh_user_size = (ext_csd[EXT_CSD_ENH_SIZE_MULT + 2] << 16) + - (ext_csd[EXT_CSD_ENH_SIZE_MULT + 1] << 8) + - ext_csd[EXT_CSD_ENH_SIZE_MULT]; - mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; - mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - mmc->enh_user_size <<= 19; - mmc->enh_user_start = (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24) + - (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) + - (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) + - ext_csd[EXT_CSD_ENH_START_ADDR]; - if (mmc->high_capacity) - mmc->enh_user_start <<= 9; - } - - /* - * Host needs to enable ERASE_GRP_DEF bit if device is - * partitioned. This bit will be lost every time after a reset - * or power off. This will affect erase size. - */ - if (part_completed) - has_parts = true; - if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) && - (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) - has_parts = true; - if (has_parts) { - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1); - - if (err) - return err; - else - ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1; - } - - if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) { - /* Read out group size from ext_csd */ - mmc->erase_grp_size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024; - /* - * if high capacity and partition setting completed - * SEC_COUNT is valid even if it is smaller than 2 GiB - * JEDEC Standard JESD84-B45, 6.2.4 - */ - if (mmc->high_capacity && part_completed) { - capacity = (ext_csd[EXT_CSD_SEC_CNT]) | - (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) | - (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) | - (ext_csd[EXT_CSD_SEC_CNT + 3] << 24); - capacity *= MMC_MAX_BLOCK_LEN; - mmc->capacity_user = capacity; - } - } else { - /* Calculate the group size from the csd value. */ - int erase_gsz, erase_gmul; - erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10; - erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; - mmc->erase_grp_size = (erase_gsz + 1) * (erase_gmul + 1); - } - - mmc->hc_wp_grp_size = 1024 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * - ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; - - mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; - } - - err = mmc_set_capacity(mmc, mmc->part_num); - if (err) - return err; - - if (IS_SD(mmc)) - err = sd_change_freq(mmc); - else - err = mmc_change_freq(mmc); - - if (err) - return err; - - /* Restrict card's capabilities by what the host can do */ - mmc->card_caps &= mmc->cfg->host_caps; - - if (IS_SD(mmc)) { -#ifdef __BUS_WIDTH_SUPPORT_4BIT__ - if (mmc->card_caps & MMC_MODE_4BIT) { - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 2; - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - mmc_set_bus_width(mmc, 4); - } -#endif - if (mmc->card_caps & MMC_MODE_HS) - mmc->tran_speed = 50000000; - else - mmc->tran_speed = 25000000; - } else if (mmc->version >= MMC_VERSION_4) { - /* Only version 4 of MMC supports wider bus widths */ - int idx; - - /* An array of possible bus widths in order of preference */ - static unsigned ext_csd_bits[] = { - EXT_CSD_DDR_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_4, EXT_CSD_BUS_WIDTH_8, - EXT_CSD_BUS_WIDTH_4, EXT_CSD_BUS_WIDTH_1, - }; - - /* An array to map CSD bus widths to host cap bits */ - static unsigned ext_to_hostcaps[] = { - [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz | MMC_MODE_4BIT, - [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz | MMC_MODE_8BIT, - [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT, - [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT, - }; - - /* An array to map chosen bus width to an integer */ - static unsigned widths[] = { - 8, 4, 8, 4, 1, - }; - - for (idx = 0; idx < ARRAY_SIZE(ext_csd_bits); idx++) { - unsigned int extw = ext_csd_bits[idx]; - unsigned int caps = ext_to_hostcaps[extw]; - - /* - * If the bus width is still not changed, - * don't try to set the default again. - * Otherwise, recover from switch attempts - * by switching to 1-bit bus width. - */ - if (extw == EXT_CSD_BUS_WIDTH_1 && mmc->bus_width == 1) { - err = 0; - break; - } - - /* - * Check to make sure the card and controller support - * these capabilities - */ - if ((mmc->card_caps & caps) != caps) - continue; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, extw); - - if (err) - continue; - - mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0; - mmc_set_bus_width(mmc, widths[idx]); - - err = mmc_send_ext_csd(mmc, test_csd); - - if (err) - continue; - - /* Only compare read only fields */ - if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] == - test_csd[EXT_CSD_PARTITIONING_SUPPORT] && - ext_csd[EXT_CSD_HC_WP_GRP_SIZE] == test_csd[EXT_CSD_HC_WP_GRP_SIZE] && - ext_csd[EXT_CSD_REV] == test_csd[EXT_CSD_REV] && - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] == - test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] && - memcmp(&ext_csd[EXT_CSD_SEC_CNT], &test_csd[EXT_CSD_SEC_CNT], 4) == 0) - break; - else - err = SWITCH_ERR; - } - - if (err) - return err; - - if (mmc->card_caps & MMC_MODE_HS) { - if (mmc->card_caps & MMC_MODE_HS_52MHz) - mmc->tran_speed = 52000000; - else - mmc->tran_speed = 26000000; - } - } - - mmc_set_clock(mmc, mmc->tran_speed); - - /* Fix the block length for DDR mode */ - if (mmc->ddr_mode) { - mmc->read_bl_len = MMC_MAX_BLOCK_LEN; - mmc->write_bl_len = MMC_MAX_BLOCK_LEN; - } - - /* fill in device description */ - mmc->block_dev.lun = 0; - mmc->block_dev.type = 0; - mmc->block_dev.blksz = mmc->read_bl_len; - // mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz); - mmc->block_dev.lba = _sdmmc_lldiv(mmc->capacity, mmc->read_bl_len); -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x", - (unsigned)(mmc->cid[0] >> 24), (unsigned)(mmc->cid[2] & 0xffff), - (unsigned)((mmc->cid[3] >> 16) & 0xffff)); - sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", (char)mmc->cid[0], - (char)(mmc->cid[1] >> 24), (char)(mmc->cid[1] >> 16), - (char)(mmc->cid[1] >> 8), (char)mmc->cid[1], - (char)(mmc->cid[2] >> 24)); - sprintf(mmc->block_dev.revision, "%d.%d", - (unsigned)((mmc->cid[2] >> 20) & 0xf), - (unsigned)((mmc->cid[2] >> 16) & 0xf)); -#else - mmc->block_dev.vendor[0] = 0; - mmc->block_dev.product[0] = 0; - mmc->block_dev.revision[0] = 0; -#endif - - HAL_SDMMC_TRACE(1, "%s done\n", __func__); - return 0; -} - -static int mmc_send_if_cond(struct mmc *mmc) { - struct mmc_cmd cmd; - int err; - - cmd.cmdidx = SD_CMD_SEND_IF_COND; - /* We set the bit if the host supports voltages between 2.7 and 3.6 V */ - cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa; - cmd.resp_type = MMC_RSP_R7; - - err = mmc_send_cmd(mmc, &cmd, NULL); - - if (err) - return err; - - if ((cmd.response[0] & 0xff) != 0xaa) - return UNUSABLE_ERR; - else - mmc->version = SD_VERSION_2; - - return 0; -} - -struct mmc *mmc_create(int id, const struct mmc_config *cfg, void *priv) { - struct mmc *mmc; - - /* quick validation */ - if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL || - cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0) - return NULL; - - mmc = &sdmmc_devices[id]; - if (mmc == NULL) - return NULL; - - mmc->cfg = cfg; - mmc->priv = priv; - - /* the following chunk was mmc_register() */ - - /* Setup dsr related values */ - mmc->dsr_imp = 0; - mmc->dsr = 0xffffffff; - /* Setup the universal parts of the block interface just once */ - mmc->block_dev.removable = 1; - /* setup initial part type */ - mmc->block_dev.part_type = mmc->cfg->part_type; - - return mmc; -} - -int mmc_start_init(struct mmc *mmc) { - int err; - - /* we pretend there's no card when init is NULL */ - if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) { - mmc->has_init = 0; - HAL_SDMMC_TRACE(1, "%s : no card present\n", __func__); - return NO_CARD_ERR; - } - - if (mmc->has_init) - return 0; - - /* made sure it's not NULL earlier */ - err = mmc->cfg->ops->init(mmc); - HAL_SDMMC_TRACE(1, "%s : init done\n", __func__); - - if (err) - return err; - - mmc->ddr_mode = 0; - mmc_set_bus_width(mmc, 1); - mmc_set_clock(mmc, 1); - - /* Reset the Card */ - err = mmc_go_idle(mmc); - HAL_SDMMC_TRACE(1, "%s : idle done\n", __func__); - - if (err) - return err; - - /* The internal partition reset to user partition(0) at every CMD0*/ - mmc->part_num = 0; - - /* Test for SD version 2 */ - err = mmc_send_if_cond(mmc); - - /* Now try to get the SD card's operating condition */ - err = sd_send_op_cond(mmc); - - /* If the command timed out, we check for an MMC card */ - if (err == TIMEOUT) { - err = mmc_send_op_cond(mmc); - - if (err) { -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - HAL_SDMMC_TRACE(1, "%s : Card did not respond to voltage select!\n", - __func__); -#endif - return UNUSABLE_ERR; - } - } - - if (!err) - mmc->init_in_progress = 1; - - HAL_SDMMC_TRACE(1, "%s : done\n", __func__); - return err; -} - -static int mmc_complete_init(struct mmc *mmc) { - int err = 0; - - mmc->init_in_progress = 0; - if (mmc->op_cond_pending) - err = mmc_complete_op_cond(mmc); - - if (!err) - err = mmc_startup(mmc); - if (err) - mmc->has_init = 0; - else - mmc->has_init = 1; - return err; -} - -void hal_sdmmc_irq_handler(void) { - uint32_t cdetect, mask; - struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; - mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); - - if (mask & SDMMCIP_REG_INTMSK_CD) { - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CD); - cdetect = sdmmcip_readl(host, SDMMCIP_REG_CDETECT); - HAL_SDMMC_TRACE(3, "%s cdetect:%d mask:%x\n", __func__, cdetect, mask); - if (sdmmc_detected_callback) - sdmmc_detected_callback(cdetect & 0x01 ? 0 : 1); - } -} - -int hal_sdmmc_enable_detecter(enum HAL_SDMMC_ID_T id, void (*cb)(uint8_t)) { - uint32_t ctrl; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_TRACE(1, "%s\n", __func__); - - sdmmc_detected_callback = cb; - - host = &sdmmc_host[id]; - host->ioaddr = (void *)sdmmc_ip_base[id]; - - if (!sdmmcip_wait_reset(host, SDMMCIP_REG_RESET_ALL)) { - HAL_SDMMC_TRACE(2, "%s[%d] Fail-reset!!\n", __func__, __LINE__); - return -1; - } - - host->detect_enb = true; - - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, 0xFFFFFFFF); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, SDMMCIP_REG_INTMSK_CD); - - ctrl = SDMMCIP_REG_INT_EN; - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - NVIC_SetVector(SDMMC_IRQn, (uint32_t)hal_sdmmc_irq_handler); - NVIC_SetPriority(SDMMC_IRQn, IRQ_PRIORITY_NORMAL); - NVIC_ClearPendingIRQ(SDMMC_IRQn); - NVIC_EnableIRQ(SDMMC_IRQn); - return 0; -} - -void hal_sdmmc_disable_detecter(enum HAL_SDMMC_ID_T id) { - uint32_t ctrl = 0; - struct sdmmcip_host *host = NULL; - host = &sdmmc_host[id]; - - NVIC_DisableIRQ(SDMMC_IRQn); - NVIC_SetVector(SDMMC_IRQn, (uint32_t)NULL); - - sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, 0xFFFFFFFF); - sdmmcip_writel(host, SDMMCIP_REG_INTMASK, ~SDMMCIP_REG_INTMSK_ALL); - - ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); - ctrl |= (SDMMCIP_REG_DMA_EN); - sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); - - host->detect_enb = false; - sdmmc_detected_callback = NULL; -} - -int mmc_init(struct mmc *mmc) { - int err = 0; - if (mmc->has_init) - return 0; - - if (!mmc->init_in_progress) - err = mmc_start_init(mmc); - - if (!err) - err = mmc_complete_init(mmc); - - return err; -} - -/* hal api */ -static void hal_sdmmc_delay(uint32_t ms) { - if (sdmmc_delay) { - sdmmc_delay(ms); - } else { - hal_sys_timer_delay(MS_TO_TICKS(ms)); - } -} - -HAL_SDMMC_DELAY_FUNC hal_sdmmc_set_delay_func(HAL_SDMMC_DELAY_FUNC new_func) { - HAL_SDMMC_DELAY_FUNC old_func = sdmmc_delay; - sdmmc_delay = new_func; - return old_func; -} - -int32_t hal_sdmmc_open(enum HAL_SDMMC_ID_T id) { - int32_t ret = 0; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - hal_cmu_sdmmc_set_freq(HAL_CMU_PERIPH_FREQ_52M); - - hal_cmu_clock_enable(HAL_CMU_MOD_O_SDMMC); - hal_cmu_clock_enable(HAL_CMU_MOD_H_SDMMC); - hal_cmu_reset_clear(HAL_CMU_MOD_O_SDMMC); - hal_cmu_reset_clear(HAL_CMU_MOD_H_SDMMC); - - host = &sdmmc_host[id]; - - host->ioaddr = (void *)sdmmc_ip_base[id]; - // host->buswidth = 4; - host->buswidth = 1; - host->clksel = 0; - host->bus_hz = _SDMMC_CLOCK; - host->dev_index = id; - /* fifo threshold : MSIZE 0 - 1 transter, rx water mark 0 - greater than 0 - * word triiger dma-req, tx water mark 1 - less than or equal 1 word triiger - * dma-req */ - host->fifoth_val = MSIZE(0) | RX_WMARK(0) | TX_WMARK(1); - - host->cfg.ops = &sdmmcip_ops; - host->cfg.f_min = 400000; - // host->cfg.f_min = 1000000; - // host->cfg.f_min = 25000000; - // host->cfg.f_min = 52000000; - // host->cfg.f_max = 1000000; - host->cfg.f_max = 26000000; - // host->cfg.f_max = 52000000; - host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - host->cfg.host_caps = 0; - -#ifdef HAL_SDMMC_USE_DMA - host->tx_dma_handler = sdmmcip_ext_dma_irq_handlers[id * 2]; - host->rx_dma_handler = sdmmcip_ext_dma_irq_handlers[id * 2 + 1]; -#endif - - if (host->buswidth == 8) { - host->cfg.host_caps |= MMC_MODE_8BIT; - host->cfg.host_caps &= ~MMC_MODE_4BIT; - } else if (host->buswidth == 4) { - host->cfg.host_caps |= MMC_MODE_4BIT; - host->cfg.host_caps &= ~MMC_MODE_8BIT; - } else { - // host->cfg.host_caps &= ~MMC_MODE_4BIT; - host->cfg.host_caps |= MMC_MODE_4BIT; - host->cfg.host_caps &= ~MMC_MODE_8BIT; - } - - host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz; - - host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - host->mmc = mmc_create(host->dev_index, &host->cfg, host); - - ret = mmc_init(host->mmc); - - hal_sdmmc_dump(HAL_SDMMC_ID_0); - - return ret; -} -uint32_t hal_sdmmc_read_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, - uint32_t block_count, uint8_t *dest) { - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - return mmc_bread(id, start_block, block_count, dest); -} - -uint32_t hal_sdmmc_write_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, - uint32_t block_count, uint8_t *src) { - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - return mmc_bwrite(id, start_block, block_count, src); -} - -void hal_sdmmc_close(enum HAL_SDMMC_ID_T id) { - struct sdmmcip_host *host = NULL; - - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - HAL_SDMMC_TRACE(1, "%s\n", __func__); - - host = &sdmmc_host[id]; - while (host->mmc->init_in_progress) - hal_sdmmc_delay(1); - - host->mmc->has_init = 0; - - hal_cmu_reset_set(HAL_CMU_MOD_H_SDMMC); - hal_cmu_reset_set(HAL_CMU_MOD_O_SDMMC); - hal_cmu_clock_disable(HAL_CMU_MOD_H_SDMMC); - hal_cmu_clock_disable(HAL_CMU_MOD_O_SDMMC); -} - -void hal_sdmmc_dump(enum HAL_SDMMC_ID_T id) { - struct mmc *mmc = NULL; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - host = &sdmmc_host[id]; - mmc = host->mmc; - - HAL_SDMMC_TRACE(0, "-----------hal_sdmmc_dump-------------\n"); - HAL_SDMMC_TRACE(1, " [sdmmc id] : %d\n", id); - HAL_SDMMC_TRACE(1, " [io register address] : 0x%x\n", - sdmmc_ip_base[id]); - HAL_SDMMC_TRACE(1, " [ddr mode] : %d\n", - mmc->ddr_mode); - switch (mmc->version) { - case SD_VERSION_1_0: - HAL_SDMMC_TRACE(0, - " [version] : SD_VERSION_1_0\n"); - break; - case SD_VERSION_1_10: - HAL_SDMMC_TRACE(0, - " [version] : SD_VERSION_1_10\n"); - break; - case SD_VERSION_2: - HAL_SDMMC_TRACE(0, " [version] : SD_VERSION_2\n"); - break; - case SD_VERSION_3: - HAL_SDMMC_TRACE(0, " [version] : SD_VERSION_3\n"); - break; - case MMC_VERSION_5_0: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_5_0\n"); - break; - case MMC_VERSION_4_5: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_5\n"); - break; - case MMC_VERSION_4_41: - HAL_SDMMC_TRACE( - 0, " [version] : MMC_VERSION_4_41\n"); - break; - case MMC_VERSION_4_3: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_3\n"); - break; - case MMC_VERSION_4_2: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_2\n"); - break; - case MMC_VERSION_4_1: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4_1\n"); - break; - case MMC_VERSION_4: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_4\n"); - break; - case MMC_VERSION_3: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_3\n"); - break; - case MMC_VERSION_2_2: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_2_2\n"); - break; - case MMC_VERSION_1_4: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_1_4\n"); - break; - case MMC_VERSION_1_2: - HAL_SDMMC_TRACE(0, - " [version] : MMC_VERSION_1_2\n"); - break; - default: - HAL_SDMMC_TRACE(0, - " [version] : unkown version\n"); - break; - } - HAL_SDMMC_TRACE(1, " [is SD card] : 0x%x\n", - IS_SD(mmc)); - HAL_SDMMC_TRACE(1, " [high_capacity] : 0x%x\n", - mmc->high_capacity); - HAL_SDMMC_TRACE(1, " [bus_width] : 0x%x\n", - mmc->bus_width); - HAL_SDMMC_TRACE(1, " [clock] : %d\n", mmc->clock); - HAL_SDMMC_TRACE(1, " [card_caps] : 0x%x\n", - mmc->card_caps); - HAL_SDMMC_TRACE(1, " [ocr] : 0x%x\n", mmc->ocr); - HAL_SDMMC_TRACE(1, " [dsr] : 0x%x\n", mmc->dsr); - HAL_SDMMC_TRACE(1, " [capacity_user/1024] : %d(K)\n", - (uint32_t)(mmc->capacity_user / 1024)); - HAL_SDMMC_TRACE(1, " [capacity_user/1024/1024] : %d(M)\n", - (uint32_t)(mmc->capacity_user / 1024 / 1024)); - HAL_SDMMC_TRACE(1, " [capacity_user/1024/1024/1024] : %d(G)\n", - (uint32_t)(mmc->capacity_user / 1024 / 1024 / 1024)); - HAL_SDMMC_TRACE(1, " [read_bl_len] : %d\n", - mmc->read_bl_len); - HAL_SDMMC_TRACE(1, " [write_bl_len] : %d\n", - mmc->write_bl_len); - HAL_SDMMC_TRACE(0, "--------------------------------------\n"); -} -void hal_sdmmc_info(enum HAL_SDMMC_ID_T id, uint32_t *sector_count, - uint32_t *sector_size) { - struct mmc *mmc = NULL; - struct sdmmcip_host *host = NULL; - HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); - - host = &sdmmc_host[id]; - mmc = host->mmc; - - if (sector_size) { - *sector_size = mmc->read_bl_len; - HAL_SDMMC_TRACE(1, "[sdmmc] sector_size %d\n", *sector_size); - } - if (sector_count) { - if (mmc->read_bl_len != 0) - *sector_count = mmc->capacity_user / mmc->read_bl_len; - else - *sector_count = 0; - HAL_SDMMC_TRACE(1, "[sdmmc] sector_count %d\n", *sector_count); - } -} - -#endif // CHIP_HAS_SDMMC diff --git a/platform/hal/hal_sdmmc.h b/platform/hal/hal_sdmmc.h deleted file mode 100644 index 5c64fb4..0000000 --- a/platform/hal/hal_sdmmc.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef _HAL_SDMMC_H_ -#define _HAL_SDMMC_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" - -enum HAL_SDMMC_ID_T { - HAL_SDMMC_ID_0 = 0, - HAL_SDMMC_ID_NUM, -}; - -typedef void (*HAL_SDMMC_DELAY_FUNC)(uint32_t ms); - -/* hal api */ -HAL_SDMMC_DELAY_FUNC hal_sdmmc_set_delay_func(HAL_SDMMC_DELAY_FUNC new_func); -int32_t hal_sdmmc_open(enum HAL_SDMMC_ID_T id); -void hal_sdmmc_info(enum HAL_SDMMC_ID_T id, uint32_t *sector_count, uint32_t *sector_size); -uint32_t hal_sdmmc_read_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* dest); -uint32_t hal_sdmmc_write_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* src); -void hal_sdmmc_close(enum HAL_SDMMC_ID_T id); -void hal_sdmmc_dump(enum HAL_SDMMC_ID_T id); -int hal_sdmmc_enable_detecter(enum HAL_SDMMC_ID_T id,void (* cb)(uint8_t)); - -#ifdef __cplusplus -} -#endif - -#endif /* _HAL_SDMMC_H_ */ diff --git a/platform/hal/reg_sdmmcip.h b/platform/hal/reg_sdmmcip.h deleted file mode 100644 index cd69b0a..0000000 --- a/platform/hal/reg_sdmmcip.h +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __SDMMCIP_REG_HW_H -#define __SDMMCIP_REG_HW_H - -#include "plat_types.h" - -#define SDMMCIP_REG_CTRL 0x000 -#define SDMMCIP_REG_PWREN 0x004 -#define SDMMCIP_REG_CLKDIV 0x008 -#define SDMMCIP_REG_CLKSRC 0x00C -#define SDMMCIP_REG_CLKENA 0x010 -#define SDMMCIP_REG_TMOUT 0x014 -#define SDMMCIP_REG_CTYPE 0x018 -#define SDMMCIP_REG_BLKSIZ 0x01C -#define SDMMCIP_REG_BYTCNT 0x020 -#define SDMMCIP_REG_INTMASK 0x024 -#define SDMMCIP_REG_CMDARG 0x028 -#define SDMMCIP_REG_CMD 0x02C -#define SDMMCIP_REG_RESP0 0x030 -#define SDMMCIP_REG_RESP1 0x034 -#define SDMMCIP_REG_RESP2 0x038 -#define SDMMCIP_REG_RESP3 0x03C -#define SDMMCIP_REG_MINTSTS 0x040 -#define SDMMCIP_REG_RINTSTS 0x044 -#define SDMMCIP_REG_STATUS 0x048 -#define SDMMCIP_REG_FIFOTH 0x04C -#define SDMMCIP_REG_CDETECT 0x050 -#define SDMMCIP_REG_WRTPRT 0x054 -#define SDMMCIP_REG_GPIO 0x058 -#define SDMMCIP_REG_TCMCNT 0x05C -#define SDMMCIP_REG_TBBCNT 0x060 -#define SDMMCIP_REG_DEBNCE 0x064 -#define SDMMCIP_REG_USRID 0x068 -#define SDMMCIP_REG_VERID 0x06C -#define SDMMCIP_REG_HCON 0x070 -#define SDMMCIP_REG_UHS_REG 0x074 -#define SDMMCIP_REG_RESET_CARD 0x078 -#define SDMMCIP_REG_BMOD 0x080 -#define SDMMCIP_REG_PLDMND 0x084 -#define SDMMCIP_REG_DBADDR 0x088 -#define SDMMCIP_REG_IDSTS 0x08C -#define SDMMCIP_REG_IDINTEN 0x090 -#define SDMMCIP_REG_DSCADDR 0x094 -#define SDMMCIP_REG_BUFADDR 0x098 -#define SDMMCIP_REG_DATA 0x200 - -/* Interrupt Mask register */ -#define SDMMCIP_REG_INTMSK_ALL 0xffffffff -#define SDMMCIP_REG_INTMSK_CD (1 << 0) -#define SDMMCIP_REG_INTMSK_RE (1 << 1) -#define SDMMCIP_REG_INTMSK_CDONE (1 << 2) -#define SDMMCIP_REG_INTMSK_DTO (1 << 3) -#define SDMMCIP_REG_INTMSK_TXDR (1 << 4) -#define SDMMCIP_REG_INTMSK_RXDR (1 << 5) -#define SDMMCIP_REG_INTMSK_DCRC (1 << 7) -#define SDMMCIP_REG_INTMSK_RTO (1 << 8) -#define SDMMCIP_REG_INTMSK_DRTO (1 << 9) -#define SDMMCIP_REG_INTMSK_HTO (1 << 10) -#define SDMMCIP_REG_INTMSK_FRUN (1 << 11) -#define SDMMCIP_REG_INTMSK_HLE (1 << 12) -#define SDMMCIP_REG_INTMSK_SBE (1 << 13) -#define SDMMCIP_REG_INTMSK_ACD (1 << 14) -#define SDMMCIP_REG_INTMSK_EBE (1 << 15) - -/* Raw interrupt Regsiter */ -#define SDMMCIP_REG_DATA_ERR (SDMMCIP_REG_INTMSK_EBE | SDMMCIP_REG_INTMSK_SBE | SDMMCIP_REG_INTMSK_HLE |\ - SDMMCIP_REG_INTMSK_FRUN | SDMMCIP_REG_INTMSK_EBE | SDMMCIP_REG_INTMSK_DCRC) -#define SDMMCIP_REG_DATA_TOUT (SDMMCIP_REG_INTMSK_HTO | SDMMCIP_REG_INTMSK_DRTO) -/* CTRL register */ -#define SDMMCIP_REG_CTRL_RESET (1 << 0) -#define SDMMCIP_REG_CTRL_FIFO_RESET (1 << 1) -#define SDMMCIP_REG_CTRL_DMA_RESET (1 << 2) -#define SDMMCIP_REG_INT_EN (1 << 4) -#define SDMMCIP_REG_DMA_EN (1 << 5) -#define SDMMCIP_REG_CTRL_SEND_AS_CCSD (1 << 10) -#define SDMMCIP_REG_IDMAC_EN (1 << 25) -#define SDMMCIP_REG_RESET_ALL (SDMMCIP_REG_CTRL_RESET | SDMMCIP_REG_CTRL_FIFO_RESET |\ - SDMMCIP_REG_CTRL_DMA_RESET) - -/* CMD register */ -#define SDMMCIP_REG_CMD_RESP_EXP (1 << 6) -#define SDMMCIP_REG_CMD_RESP_LENGTH (1 << 7) -#define SDMMCIP_REG_CMD_CHECK_CRC (1 << 8) -#define SDMMCIP_REG_CMD_DATA_EXP (1 << 9) -#define SDMMCIP_REG_CMD_RW (1 << 10) -#define SDMMCIP_REG_CMD_SEND_STOP (1 << 12) -#define SDMMCIP_REG_CMD_ABORT_STOP (1 << 14) -#define SDMMCIP_REG_CMD_PRV_DAT_WAIT (1 << 13) -#define SDMMCIP_REG_CMD_UPD_CLK (1 << 21) -#define SDMMCIP_REG_CMD_USE_HOLD_REG (1 << 29) -#define SDMMCIP_REG_CMD_START (1 << 31) - -/* CLKENA register */ -#define SDMMCIP_REG_CLKEN_ENABLE (1 << 0) -#define SDMMCIP_REG_CLKEN_LOW_PWR (1 << 16) - -/* Card-type registe */ -#define SDMMCIP_REG_CTYPE_1BIT 0 -#define SDMMCIP_REG_CTYPE_4BIT (1 << 0) -#define SDMMCIP_REG_CTYPE_8BIT (1 << 16) - -/* Status Register */ -#define SDMMCIP_REG_BUSY (1 << 9) -#define SDMMCIP_REG_FIFO_FULL (1 << 3) -#define SDMMCIP_REG_FIFO_EMPTY (1 << 2) -#define SDMMCIP_REG_FIFO_COUNT_SHIFT (17) -#define SDMMCIP_REG_FIFO_COUNT_MASK (0x1fff << SDMMCIP_REG_FIFO_COUNT_SHIFT) - -/* FIFOTH Register */ -#define MSIZE(x) ((x) << 28) -#define RX_WMARK(x) ((x) << 16) -#define TX_WMARK(x) (x) -#define RX_WMARK_SHIFT 16 -#define RX_WMARK_MASK (0xfff << RX_WMARK_SHIFT) - -#define SDMMCIP_REG_IDMAC_OWN (1 << 31) -#define SDMMCIP_REG_IDMAC_CH (1 << 4) -#define SDMMCIP_REG_IDMAC_FS (1 << 3) -#define SDMMCIP_REG_IDMAC_LD (1 << 2) - -/* Bus Mode Register */ -#define SDMMCIP_REG_BMOD_IDMAC_RESET (1 << 0) -#define SDMMCIP_REG_BMOD_IDMAC_FB (1 << 1) -#define SDMMCIP_REG_BMOD_IDMAC_EN (1 << 7) - -/* UHS register */ -#define SDMMCIP_REG_DDR_MODE (1 << 16) - -/* quirks */ -#define SDMMCIP_REG_QUIRK_DISABLE_SMU (1 << 0) - -/* FIFO Register */ -#define SDMMCIP_REG_FIFO_OFFSET 0x200 - -#endif /* __SDMMCIP_REG_HW_H */ From 22ba33ecfe6f572fa36e6a06084fee0bbd74deff Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sat, 4 Feb 2023 10:36:08 +1100 Subject: [PATCH 2/2] Remove USB --- apps/apptester/Makefile | 5 - apps/btusbaudio/Makefile | 41 - apps/btusbaudio/btusb_audio.c | 260 - apps/btusbaudio/btusb_audio.h | 40 - apps/btusbaudio/usbaudio_thread.c | 131 - apps/btusbaudio/usbaudio_thread.h | 49 - apps/factory/Makefile | 1 - apps/mic_alg/Makefile | 1 - apps/usbaudio/Makefile | 193 - apps/usbaudio/usbaudio_entry.c | 363 - apps/usbhost/Makefile | 7 - apps/usbhost/app_usbhost.c | 18 - apps/usbhost/app_usbhost.h | 27 - config/Makefile | 1 - platform/drivers/Makefile | 4 - platform/drivers/usb/Makefile | 1 - platform/drivers/usb/usb_dev/Makefile | 130 - .../drivers/usb/usb_dev/cfg/usb_dev_desc.c | 499 -- platform/drivers/usb/usb_dev/inc/usb_audio.h | 157 - .../drivers/usb/usb_dev/inc/usb_audio_sync.h | 72 - platform/drivers/usb/usb_dev/inc/usb_cdc.h | 126 - .../drivers/usb/usb_dev/inc/usb_descriptor.h | 144 - .../drivers/usb/usb_dev/inc/usb_dev_desc.h | 65 - platform/drivers/usb/usb_dev/lib/libusbdev.a | Bin 189600 -> 0 bytes .../drivers/usb/usb_dev/uaud_cfg_flags.mk | 110 - platform/drivers/usb/usb_host/Makefile | 20 - platform/drivers/usb/usb_host/inc/USBHost.h | 193 - .../drivers/usb/usb_host/inc/usb_tester.h | 49 - platform/hal/Makefile | 1 - platform/hal/hal_usb.c | 2725 ------- platform/hal/hal_usb.h | 232 - platform/hal/hal_usbhost.c | 1119 --- platform/hal/hal_usbhost.h | 173 - platform/main/Makefile | 1 - services/communication/Makefile | 1 - .../comminication_knowles/Makefile | 1 - tests/anc_usb/Makefile | 292 - tests/anc_usb/adda_loop_app.c | 210 - tests/anc_usb/adda_loop_app.h | 33 - tests/anc_usb/anc_usb_app.c | 1047 --- tests/anc_usb/anc_usb_app.h | 45 - tests/anc_usb/dualadc_audio_app.c | 321 - tests/anc_usb/dualadc_audio_app.h | 38 - tests/anc_usb/main.c | 519 -- tests/anc_usb/memutils.c | 87 - tests/anc_usb/memutils.h | 32 - tests/anc_usb/mic_key.c | 149 - tests/anc_usb/safe_queue.c | 156 - tests/anc_usb/safe_queue.h | 44 - tests/anc_usb/speech_process.c | 279 - tests/anc_usb/speech_process.h | 40 - tests/anc_usb/usb_audio_app.c | 6410 ----------------- tests/anc_usb/usb_audio_app.h | 66 - tests/anc_usb/usb_audio_frm_defs.h | 232 - tests/anc_usb/usb_vendor_msg.c | 261 - tests/anc_usb/usb_vendor_msg.h | 17 - 56 files changed, 17238 deletions(-) delete mode 100644 apps/btusbaudio/Makefile delete mode 100644 apps/btusbaudio/btusb_audio.c delete mode 100644 apps/btusbaudio/btusb_audio.h delete mode 100644 apps/btusbaudio/usbaudio_thread.c delete mode 100644 apps/btusbaudio/usbaudio_thread.h delete mode 100644 apps/usbaudio/Makefile delete mode 100644 apps/usbaudio/usbaudio_entry.c delete mode 100644 apps/usbhost/Makefile delete mode 100644 apps/usbhost/app_usbhost.c delete mode 100644 apps/usbhost/app_usbhost.h delete mode 100644 platform/drivers/usb/Makefile delete mode 100644 platform/drivers/usb/usb_dev/Makefile delete mode 100644 platform/drivers/usb/usb_dev/cfg/usb_dev_desc.c delete mode 100644 platform/drivers/usb/usb_dev/inc/usb_audio.h delete mode 100644 platform/drivers/usb/usb_dev/inc/usb_audio_sync.h delete mode 100644 platform/drivers/usb/usb_dev/inc/usb_cdc.h delete mode 100644 platform/drivers/usb/usb_dev/inc/usb_descriptor.h delete mode 100644 platform/drivers/usb/usb_dev/inc/usb_dev_desc.h delete mode 100644 platform/drivers/usb/usb_dev/lib/libusbdev.a delete mode 100644 platform/drivers/usb/usb_dev/uaud_cfg_flags.mk delete mode 100644 platform/drivers/usb/usb_host/Makefile delete mode 100644 platform/drivers/usb/usb_host/inc/USBHost.h delete mode 100644 platform/drivers/usb/usb_host/inc/usb_tester.h delete mode 100644 platform/hal/hal_usb.c delete mode 100644 platform/hal/hal_usb.h delete mode 100644 platform/hal/hal_usbhost.c delete mode 100644 platform/hal/hal_usbhost.h delete mode 100644 tests/anc_usb/Makefile delete mode 100644 tests/anc_usb/adda_loop_app.c delete mode 100644 tests/anc_usb/adda_loop_app.h delete mode 100644 tests/anc_usb/anc_usb_app.c delete mode 100644 tests/anc_usb/anc_usb_app.h delete mode 100644 tests/anc_usb/dualadc_audio_app.c delete mode 100644 tests/anc_usb/dualadc_audio_app.h delete mode 100644 tests/anc_usb/main.c delete mode 100644 tests/anc_usb/memutils.c delete mode 100644 tests/anc_usb/memutils.h delete mode 100644 tests/anc_usb/mic_key.c delete mode 100644 tests/anc_usb/safe_queue.c delete mode 100644 tests/anc_usb/safe_queue.h delete mode 100644 tests/anc_usb/speech_process.c delete mode 100644 tests/anc_usb/speech_process.h delete mode 100644 tests/anc_usb/usb_audio_app.c delete mode 100644 tests/anc_usb/usb_audio_app.h delete mode 100644 tests/anc_usb/usb_audio_frm_defs.h delete mode 100644 tests/anc_usb/usb_vendor_msg.c delete mode 100644 tests/anc_usb/usb_vendor_msg.h diff --git a/apps/apptester/Makefile b/apps/apptester/Makefile index 0453beb..100f46f 100644 --- a/apps/apptester/Makefile +++ b/apps/apptester/Makefile @@ -23,8 +23,6 @@ subdir-ccflags-y += \ -Iservices/multimedia/speech/inc \ -Iservices/nv_section/include \ -Iservices/nv_section/aud_section \ - -Iplatform/drivers/usb/usb_dev/inc \ - -Itests/anc_usb \ -Iutils/hwtimer_list CFLAGS_usb_audio_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) @@ -58,9 +56,6 @@ ifeq ($(ADC_CH_SEP_BUFF),1) ANC_USB_CFG_FLAGS += -DADC_CH_SEP_BUFF endif -include platform/drivers/usb/usb_dev/uaud_cfg_flags.mk - -platform/drivers/usb/usb_dev/uaud_cfg_flags.mk: ; ANC_USB_CFG_FLAGS += $(UAUD_CFG_FLAGS) diff --git a/apps/btusbaudio/Makefile b/apps/btusbaudio/Makefile deleted file mode 100644 index e29b52a..0000000 --- a/apps/btusbaudio/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) - - -obj-y := $(obj-y:.c=.o) -obj-y := $(obj-y:.cpp=.o) -obj-y := $(obj-y:.S=.o) - -ccflags-y += \ - $(BT_IF_INCLUDES) \ - $(BT_PROFILES_INCLUDES) \ - -Iservices/bt_app \ - -Iservices/bt_app/a2dp_codecs/include \ - -Iservices/audioflinger \ - -Iservices/nvrecord \ - -Iservices/overlay \ - -Iservices/resources \ - -Iservices/audio_process \ - -Iapps/apptester \ - -Iapps/factory \ - -Iutils/crc32 \ - -Iplatform/drivers/bt \ - -Iplatform/drivers/ana \ - -Iapps/audioplayers/rbplay \ - -Itests/anc_usb \ - -Iapps/anc/inc \ - -Iapps/ota \ - -Ithirdparty/userapi \ - -Iservices/voicepath \ - -Iservices/voicepath/gsound/gsound_service \ - -Iservices/voicepath/gsound/gsound_target \ - -Iservices/communication \ - -Iutils/cqueue \ - -Iservices/ai_voice/ama/ama_manager \ - -Iservices/ai_voice/manager \ - -Iservices/multimedia/audio/codec/sbc/inc \ - -Iservices/multimedia/audio/codec/sbc/src/inc \ - -Iservices/interconnection - - diff --git a/apps/btusbaudio/btusb_audio.c b/apps/btusbaudio/btusb_audio.c deleted file mode 100644 index 5769820..0000000 --- a/apps/btusbaudio/btusb_audio.c +++ /dev/null @@ -1,260 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "app_audio.h" -#include "cmsis_os.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "stdio.h" - -#include "a2dp_api.h" -#include "app_bt.h" -#include "btapp.h" -#include "btusb_audio.h" -#include "usb_audio_app.h" - -extern void btusbaudio_entry(void); -extern void btusbaudio_exit(void); -extern a2dp_stream_t *app_bt_get_steam(enum BT_DEVICE_ID_T id); -extern int app_bt_get_bt_addr(enum BT_DEVICE_ID_T id, bt_bdaddr_t *bdaddr); -extern bool app_bt_a2dp_service_is_connected(void); -int app_bt_A2DP_OpenStream(a2dp_stream_t *Stream, bt_bdaddr_t *Addr); -int app_bt_A2DP_CloseStream(a2dp_stream_t *Stream); - -extern bool btapp_hfp_is_call_active(void); -static bool btusb_usb_is_on = false; -static enum BTUSB_MODE btusb_mode = BTUSB_MODE_INVALID; -static bool btusb_bt_audio_is_suspend = false; - -#define BT_USB_DEBUG() // TRACE(2,"_debug: %s,%d",__func__,__LINE__) -extern struct BT_DEVICE_T app_bt_device; - -static void _btusb_stream_open(unsigned int timeout_ms) { - a2dp_stream_t *stream = NULL; - bt_bdaddr_t bdaddr; - uint32_t stime = 0; - uint32_t etime = 0; - - stime = hal_sys_timer_get(); - // BT_USB_DEBUG(); - stream = (a2dp_stream_t *)app_bt_get_steam(BT_DEVICE_ID_1); - - app_bt_get_bt_addr(BT_DEVICE_ID_1, &bdaddr); - if (stream) { - // struct BT_DEVICE_T *bt_dev = &app_bt_device; - // A2DP_Register((a2dp_stream_t - // *)bt_dev->a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream, &a2dp_avdtpcodec, - // NULL, (A2dpCallback) a2dp_callback); AVRCP_Register((AvrcpChannel - // *)bt_dev->avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle, - // (AvrcpCallback)avrcp_callback_CT, BTIF_AVRCP_CT_CATEGORY_1 | - // BTIF_AVRCP_CT_CATEGORY_2 | BTIF_AVRCP_TG_CATEGORY_2); - BT_USB_DEBUG(); - osDelay(10); - app_bt_A2DP_OpenStream(stream, &bdaddr); - } else { - BT_USB_DEBUG(); - return; - } - while (1) { - if (app_bt_a2dp_service_is_connected()) { - etime = hal_sys_timer_get(); - TRACE(1, "_debug: a2dp service connected, wait time = 0x%x.", - TICKS_TO_MS(etime - stime)); - break; - } else { - etime = hal_sys_timer_get(); - if (TICKS_TO_MS(etime - stime) >= timeout_ms) { - TRACE(1, "_debug: a2dp service connect timeout = 0x%x.", - TICKS_TO_MS(etime - stime)); - break; - } - osDelay(10); - } - } - // BT_USB_DEBUG(); -} - -static void _btusb_stream_close(unsigned int timeout_ms) { - a2dp_stream_t *stream = NULL; - uint32_t stime = 0; - uint32_t etime = 0; - - stime = hal_sys_timer_get(); - BT_USB_DEBUG(); - stream = (a2dp_stream_t *)app_bt_get_steam(BT_DEVICE_ID_1); - if (stream) { - BT_USB_DEBUG(); - app_bt_A2DP_CloseStream(stream); - } else { - BT_USB_DEBUG(); - return; - } - stime = hal_sys_timer_get(); - while (1) { - if (!app_bt_a2dp_service_is_connected()) { - // struct BT_DEVICE_T *bt_dev = &app_bt_device; - // AVRCP_Deregister(bt_dev->avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle); - // A2DP_Deregister(stream); - etime = hal_sys_timer_get(); - TRACE(1, "a2dp service diconnected, wait time = 0x%x.", - TICKS_TO_MS(etime - stime)); - break; - } else { - etime = hal_sys_timer_get(); - if (TICKS_TO_MS(etime - stime) >= timeout_ms) { - TRACE(1, "a2dp service diconnect timeout = 0x%x.", - TICKS_TO_MS(etime - stime)); - break; - } - osDelay(10); - } - } - BT_USB_DEBUG(); -} - -static void btusb_usbaudio_entry(void) { - BT_USB_DEBUG(); - btusbaudio_entry(); - btusb_usb_is_on = true; -} - -void btusb_usbaudio_open(void) { - BT_USB_DEBUG(); - if (!btusb_usb_is_on) { - btusb_usbaudio_entry(); - BT_USB_DEBUG(); - } else { - usb_audio_app(1); - } - BT_USB_DEBUG(); -} - -void btusb_usbaudio_close(void) { - BT_USB_DEBUG(); - if (btusb_usb_is_on) { - usb_audio_app(0); - BT_USB_DEBUG(); - } else { - BT_USB_DEBUG(); - } -} - -void btusb_btaudio_close(bool is_wait) { - BT_USB_DEBUG(); - // if(!btusb_bt_audio_is_suspend) - { - BT_USB_DEBUG(); - if (is_wait) { - app_audio_sendrequest(APP_PLAY_BACK_AUDIO, - (uint8_t)APP_BT_SETTING_CLOSEALL, 0); - _btusb_stream_close(BTUSB_OUTTIME_MS); - } else { - _btusb_stream_close(0); - } - btusb_bt_audio_is_suspend = true; - } -} - -void btusb_btaudio_open(bool is_wait) { - BT_USB_DEBUG(); - // if(btusb_bt_audio_is_suspend) - { - TRACE(2, "%s: %d.", __func__, __LINE__); - if (is_wait) { - _btusb_stream_open(BTUSB_OUTTIME_MS); - app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, - 0); - app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_SETUP, - 0); - } else { - _btusb_stream_open(0); - } - TRACE(2, "%s: %d.", __func__, __LINE__); - btusb_bt_audio_is_suspend = false; - } -} - -void btusb_switch(enum BTUSB_MODE mode) { - // BT_USB_DEBUG(); - if (mode != BTUSB_MODE_BT && mode != BTUSB_MODE_USB) { - ASSERT(0, "%s:%d, mode = %d.", __func__, __LINE__, mode); - } - - if (btusb_mode == mode) { - BT_USB_DEBUG(); - return; - } - - if (btusb_mode == BTUSB_MODE_INVALID) { - if (mode == BTUSB_MODE_BT) { - TRACE(1, "%s: switch to BT mode.", __func__); - btusb_mode = BTUSB_MODE_BT; - } else { - TRACE(1, "%s: switch to USB mode.", __func__); - // btusb_btaudio_close(true); - osDelay(500); - btusb_usbaudio_open(); - btusb_mode = BTUSB_MODE_USB; - } - } else { - if (mode == BTUSB_MODE_BT) { - TRACE(1, "%s: switch to BT mode.", __func__); - if (btusb_usb_is_on) { - TRACE(1, "%s: btusb_usbaudio_close.", __func__); - btusb_usbaudio_close(); - TRACE(1, "%s: btusb_usbaudio_close done.", __func__); - osDelay(500); - } - btusb_mode = BTUSB_MODE_BT; - btusb_btaudio_open(true); - TRACE(1, "%s: switch to BT mode done.", __func__); - } else { - if (btapp_hfp_is_call_active() == 1) { - TRACE(1, "%s: hfp is call active.", __func__); - return; - } - TRACE(1, "%s: switch to USB mode.", __func__); - btusb_btaudio_close(true); - TRACE(1, "%s: btusb_btaudio_close done.", __func__); - osDelay(500); - btusb_usbaudio_open(); - btusb_mode = BTUSB_MODE_USB; - TRACE(1, "%s: switch to USB mode done.", __func__); - } - } -} - -bool btusb_is_bt_mode(void) { - BT_USB_DEBUG(); - return btusb_mode == BTUSB_MODE_BT ? true : false; -} - -bool btusb_is_usb_mode(void) { - return btusb_mode == BTUSB_MODE_USB ? true : false; -} - -#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) -void test_btusb_switch(void) { - if (btusb_mode == BTUSB_MODE_BT) { - btusb_switch(BTUSB_MODE_USB); - } else { - btusb_switch(BTUSB_MODE_BT); - } -} - -void test_btusb_switch_to_bt(void) { btusb_switch(BTUSB_MODE_BT); } - -void test_btusb_switch_to_usb(void) { btusb_switch(BTUSB_MODE_USB); } -#endif diff --git a/apps/btusbaudio/btusb_audio.h b/apps/btusbaudio/btusb_audio.h deleted file mode 100644 index 134cae9..0000000 --- a/apps/btusbaudio/btusb_audio.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef _BTUSB_AUDIO_H_ -#define _BTUSB_AUDIO_H_ -#ifdef __cplusplus -extern "C" { -#endif - -#define BTUSB_OUTTIME_MS 1000 -enum BTUSB_MODE{ - BTUSB_MODE_BT, - BTUSB_MODE_USB, - BTUSB_MODE_INVALID -}; - -void btusb_usbaudio_open(void); -void btusb_usbaudio_close(void); -void btusb_btaudio_open(bool is_wait); -void btusb_btaudio_close(bool is_wait); -void btusb_switch(enum BTUSB_MODE mode); -bool btusb_is_bt_mode(void); -bool btusb_is_usb_mode(void); -#ifdef __cplusplus -} -#endif -#endif // _BTUSB_AUDIO_H_ - diff --git a/apps/btusbaudio/usbaudio_thread.c b/apps/btusbaudio/usbaudio_thread.c deleted file mode 100644 index ce537d1..0000000 --- a/apps/btusbaudio/usbaudio_thread.c +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "usbaudio_thread.h" -#include "app_utils.h" -#include "cmsis_os.h" -#include "hal_trace.h" -#include "usb_audio_app.h" - -static void usb_thread(void const *argument); -osThreadDef(usb_thread, osPriorityHigh, 1, 2048, "usb"); - -osMailQDef(usb_mailbox, USB_MAILBOX_MAX, USB_MESSAGE); -static osMailQId usb_mailbox = NULL; -static uint8_t usb_mailbox_cnt = 0; -#define USBAUDIO_DEBUG TRACE -static int usb_mailbox_init(void) { - USBAUDIO_DEBUG("%s,%d", __func__, __LINE__); - usb_mailbox = osMailCreate(osMailQ(usb_mailbox), NULL); - if (usb_mailbox == NULL) { - USBAUDIO_DEBUG("Failed to Create usb_mailbox\n"); - return -1; - } - usb_mailbox_cnt = 0; - return 0; -} - -int usb_mailbox_put(USB_MESSAGE *msg_src) { - osStatus status; - USB_MESSAGE *msg_p = NULL; - - USBAUDIO_DEBUG("%s,%d", __func__, __LINE__); - if (usb_mailbox_cnt >= 1) { - USBAUDIO_DEBUG("%s,%d usb_mailbox_cnt = %d.", __func__, __LINE__, - usb_mailbox_cnt); - return 0; - } - msg_p = (USB_MESSAGE *)osMailAlloc(usb_mailbox, 0); - ASSERT(msg_p, "osMailAlloc error"); - msg_p->id = msg_src->id; - msg_p->ptr = msg_src->ptr; - msg_p->param0 = msg_src->param0; - msg_p->param1 = msg_src->param1; - - status = osMailPut(usb_mailbox, msg_p); - if (osOK == status) - usb_mailbox_cnt++; - USBAUDIO_DEBUG("%s,%d,usb_mailbox_cnt = %d.", __func__, __LINE__, - usb_mailbox_cnt); - return (int)status; -} - -int usb_mailbox_free(USB_MESSAGE *msg_p) { - osStatus status; - - USBAUDIO_DEBUG("%s,%d", __func__, __LINE__); - status = osMailFree(usb_mailbox, msg_p); - if (osOK == status) - usb_mailbox_cnt--; - USBAUDIO_DEBUG("%s,%d,usb_mailbox_cnt = %d.", __func__, __LINE__, - usb_mailbox_cnt); - return (int)status; -} - -int usb_mailbox_get(USB_MESSAGE **msg_p) { - osEvent evt; - evt = osMailGet(usb_mailbox, osWaitForever); - if (evt.status == osEventMail) { - *msg_p = (USB_MESSAGE *)evt.value.p; - return 0; - } - return -1; -} - -static void usb_thread(void const *argument) { - // USB_FUNC_T usb_funcp; - USBAUDIO_DEBUG("%s,%d", __func__, __LINE__); - while (1) { - USB_MESSAGE *msg_p = NULL; - - if (!usb_mailbox_get(&msg_p)) { - // TRACE(2,"_debug: %s,%d",__func__,__LINE__); - USBAUDIO_DEBUG( - "usb_thread: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", - msg_p->id, msg_p->ptr, msg_p->param0, msg_p->param1); - usb_mailbox_free(msg_p); - usb_audio_app_loop(); - } - } -} - -static void usb_enqueue_cmd(uint32_t data) { - USB_MESSAGE usb_msg; - - usb_msg.id = 0; - usb_msg.param0 = 0; - usb_msg.param1 = 0; - usb_msg.ptr = 0; - usb_mailbox_put(&usb_msg); -} - -int usb_os_init(void) { - osThreadId usb_tid; - - USBAUDIO_DEBUG("%s,%d", __func__, __LINE__); - if (usb_mailbox_init()) { - USBAUDIO_DEBUG("_debug: %s,%d", __func__, __LINE__); - return -1; - } - usb_tid = osThreadCreate(osThread(usb_thread), NULL); - if (usb_tid == NULL) { - USBAUDIO_DEBUG("Failed to Create usb_thread\n"); - return 0; - } - - usb_audio_set_enqueue_cmd_callback(usb_enqueue_cmd); - - return 0; -} diff --git a/apps/btusbaudio/usbaudio_thread.h b/apps/btusbaudio/usbaudio_thread.h deleted file mode 100644 index c9ecc07..0000000 --- a/apps/btusbaudio/usbaudio_thread.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_THREAD_H__ -#define __USB_THREAD_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define USB_MAILBOX_MAX (20) - -typedef struct { - uint32_t id; - uint32_t ptr; - uint32_t param0; - uint32_t param1; -} USB_MESSAGE; - - -//typedef int (*USB_MOD_HANDLER_T)(USB_MESSAGE_BODY *); -typedef void (*USB_FUNC_T)(uint32_t, uint32_t); - -int usb_mailbox_put(USB_MESSAGE* msg_src); - -int usb_mailbox_free(USB_MESSAGE* msg_p); - -int usb_mailbox_get(USB_MESSAGE** msg_p); - -int usb_os_init(void); - -#ifdef __cplusplus - } -#endif - -#endif // __USB_THREAD_H__ - diff --git a/apps/factory/Makefile b/apps/factory/Makefile index 03130f6..71d6a07 100644 --- a/apps/factory/Makefile +++ b/apps/factory/Makefile @@ -18,7 +18,6 @@ ccflags-y += \ -Iapps/key \ -Iplatform/drivers/bt \ -Iplatform/drivers/ana \ - -Iplatform/drivers/usb/usb_dev/inc \ -Iapps/battery \ -Iservices/multimedia/audio/codec/sbc/inc \ -Iservices/multimedia/audio/codec/sbc/src/inc \ diff --git a/apps/mic_alg/Makefile b/apps/mic_alg/Makefile index e1c5fd2..5beade3 100644 --- a/apps/mic_alg/Makefile +++ b/apps/mic_alg/Makefile @@ -30,7 +30,6 @@ ccflags-y += \ -Iapps/i2c_sensor \ -Iplatform/drivers/bt \ -Iplatform/drivers/ana \ - -Iplatform/drivers/usb/usb_dev/inc \ -Iapps/battery ifeq ($(AUDIO_RESAMPLE),1) diff --git a/apps/usbaudio/Makefile b/apps/usbaudio/Makefile deleted file mode 100644 index 64ee009..0000000 --- a/apps/usbaudio/Makefile +++ /dev/null @@ -1,193 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) - -obj-y += ../../tests/anc_usb/usb_audio_app.c -obj-y += ../../tests/anc_usb/safe_queue.c -obj-y += ../../tests/anc_usb/memutils.c - -ifeq ($(USB_AUDIO_SPEECH),1) -obj-y += ../../tests/anc_usb/speech_process.c -endif - -ifeq ($(ANC_APP),1) -obj-y += ../../tests/anc_usb/anc_usb_app.c -endif - -obj-y := $(obj-y:.c=.o) -obj-y := $(obj-y:.cpp=.o) -obj-y := $(obj-y:.S=.o) - - -ccflags-y += \ - -Iutils/boot_struct \ - -Iutils/crc32 \ - -Iutils/hexdump \ - -Iutils/hwtimer_list \ - -Itests/programmer \ - -Iplatform/drivers/usb/usb_dev/inc \ - -Iplatform/drivers/ana \ - -Iservices/multimedia/audio/process/adp/include \ - -Iservices/multimedia/audio/process/anc/include \ - -Iservices/multimedia/audio/process/filters/include \ - -Iservices/multimedia/audio/process/resample/include \ - -Iservices/multimedia/speech/inc \ - -Iservices/audio_process \ - -Iservices/nv_section/aud_section \ - -Iservices/nv_section/include \ - -Iservices/overlay \ - -Itests/anc_usb - -CFLAGS_usbaudio_entry.o += -DUSB_AUDIO_APP -CFLAGS_usb_audio_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) -CFLAGS_adda_loop_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) - -ANC_USB_CFG_FLAGS := - -# ANC option -ifeq ($(ANC_APP),1) -ANC_USB_CFG_FLAGS += -DANC_APP -endif - -# USB audio option -ifeq ($(USB_AUDIO_APP),1) -ANC_USB_CFG_FLAGS += -DUSB_AUDIO_APP -endif - -ifeq ($(USB_HIGH_SPEED),1) -ANC_USB_CFG_FLAGS += -DUSB_HIGH_SPEED -endif - -ifeq ($(AUDIO_RESAMPLE),1) -ANC_USB_CFG_FLAGS += -D__AUDIO_RESAMPLE__ -endif - -ifeq ($(ADC_CH_SEP_BUFF),1) -ANC_USB_CFG_FLAGS += -DADC_CH_SEP_BUFF -endif - -include platform/drivers/usb/usb_dev/uaud_cfg_flags.mk - -platform/drivers/usb/usb_dev/uaud_cfg_flags.mk: ; - -ANC_USB_CFG_FLAGS += $(UAUD_CFG_FLAGS) - -# USB audio configuration -ifeq ($(USB_AUDIO_DYN_CFG),1) -ifneq ($(AUDIO_RESAMPLE),1) -SW_CAPTURE_RESAMPLE ?= 1 -endif -endif - -ifeq ($(AUDIO_PLAYBACK_24BIT),1) -ANC_USB_CFG_FLAGS += -DAUDIO_PLAYBACK_24BIT -endif - -# DSD configuration -ifeq ($(HW_FIR_DSD_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__HW_FIR_DSD_PROCESS__ -endif - -# EQ configuration -ifeq ($(HW_FIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__HW_FIR_EQ_PROCESS__ -endif - -ifeq ($(HW_IIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__HW_IIR_EQ_PROCESS__ -endif - -ifeq ($(SW_IIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__SW_IIR_EQ_PROCESS__ -endif - -ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__HW_DAC_IIR_EQ_PROCESS__ -endif - -ifeq ($(SW_CAPTURE_RESAMPLE),1) -ANC_USB_CFG_FLAGS += -DSW_CAPTURE_RESAMPLE -endif - -CFLAGS_usbaudio_entry.o += $(ANC_USB_CFG_FLAGS) -CFLAGS_usb_audio_app.o += $(ANC_USB_CFG_FLAGS) -CFLAGS_anc_usb_app.o += $(ANC_USB_CFG_FLAGS) - -ifeq ($(ANC_KEY_DOUBLE_CLICK_ON_OFF),1) -CFLAGS_anc_usb_app.o += -DANC_KEY_DOUBLE_CLICK_ON_OFF -endif - -ifeq ($(ANC_FF_ENABLED),1) -CFLAGS_anc_usb_app.o += -DANC_FF_ENABLED -endif - -ifeq ($(ANC_FB_ENABLED),1) -CFLAGS_anc_usb_app.o += -DANC_FB_ENABLED -endif - -ifeq ($(AUDIO_SECTION_SUPPT),1) -CFLAGS_anc_usb_app.o += -D__AUDIO_SECTION_SUPPT__ -endif - -ifeq ($(ANC_INIT_OFF),1) -CFLAGS_anc_usb_app.o += -DANC_INIT_OFF -endif - -ifeq ($(PC_CMD_UART),1) -CFLAGS_usbaudio_entry.o += -D__PC_CMD_UART__ -endif - -ifeq ($(DELAY_STREAM_OPEN),1) -CFLAGS_usb_audio_app.o += -DDELAY_STREAM_OPEN -endif - -ifeq ($(NOISE_GATING),1) -CFLAGS_usb_audio_app.o += -DNOISE_GATING -endif - -ifeq ($(NOISE_REDUCTION),1) -CFLAGS_usb_audio_app.o += -DNOISE_REDUCTION -endif - -ifeq ($(ANC_L_R_MISALIGN_WORKAROUND),1) -CFLAGS_usb_audio_app.o += -DANC_L_R_MISALIGN_WORKAROUND -endif - -ifeq ($(ANDROID_ACCESSORY_SPEC),1) -CFLAGS_usb_audio_app.o += -DANDROID_ACCESSORY_SPEC -ifeq ($(ANDROID_VOICE_CMD_KEY),1) -CFLAGS_usb_audio_app.o += -DANDROID_VOICE_CMD_KEY -endif -endif - -ifeq ($(DUAL_AUX_MIC_MORE_FILTER),1) -CFLAGS_usb_audio_app.o += -DDUAL_AUX_MIC_MORE_FILTER -endif - -ifeq ($(FREQ_RESP_EQ),1) -CFLAGS_usb_audio_app.o += -DFREQ_RESP_EQ -endif - -ifeq ($(KEEP_SAME_LATENCY),1) -CFLAGS_usb_audio_app.o += -DKEEP_SAME_LATENCY -CFLAGS_speech_process.o += -DKEEP_SAME_LATENCY -endif - -ifeq ($(USB_AUDIO_PWRKEY_TEST),1) -CFLAGS_usb_audio_app.o += -DUSB_AUDIO_PWRKEY_TEST -endif - -ifeq ($(AUDIO_RESAMPLE),1) -# If neither best1000 nor best2000 -ifeq ($(filter best1000 best2000,$(CHIP)),) -PLL_TUNE_SAMPLE_RATE ?= 1 -endif -ifeq ($(PLL_TUNE_SAMPLE_RATE),1) -CFLAGS_usb_audio_app.o += -DPLL_TUNE_SAMPLE_RATE -endif -endif - -ifeq ($(USB_AUDIO_SPEECH),1) -CFLAGS_usbaudio_entry.o += -DUSB_AUDIO_SPEECH -CFLAGS_usb_audio_app.o += -DUSB_AUDIO_SPEECH -endif diff --git a/apps/usbaudio/usbaudio_entry.c b/apps/usbaudio/usbaudio_entry.c deleted file mode 100644 index ec4703d..0000000 --- a/apps/usbaudio/usbaudio_entry.c +++ /dev/null @@ -1,363 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "analog.h" -#include "audioflinger.h" -#include "cmsis.h" -#include "hal_cmu.h" -#include "hal_dma.h" -#include "hal_gpadc.h" -#include "hal_iomux.h" -#include "hal_key.h" -#include "hal_sleep.h" -#include "hal_sysfreq.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hwtimer_list.h" -#include "plat_addr_map.h" -#include "pmu.h" -#include "string.h" -#if defined(ANC_APP) -#include "anc_usb_app.h" -#endif -#include "audio_process.h" -#include "dualadc_audio_app.h" -#include "tgt_hardware.h" -#include "usb_audio_app.h" -#include "usb_audio_frm_defs.h" - -#ifdef RTOS -#include "cmsis_os.h" -#endif -#ifdef __PC_CMD_UART__ -#include "hal_cmd.h" -#endif - -#ifdef USB_AUDIO_SPEECH -#define CODEC_BUFF_FRAME_NUM (2 * 16) -#define USB_BUFF_FRAME_NUM (CODEC_BUFF_FRAME_NUM * 2) -#else -#define CODEC_BUFF_FRAME_NUM 4 -#define USB_BUFF_FRAME_NUM 8 -#endif - -#if (CODEC_BUFF_FRAME_NUM >= USB_BUFF_FRAME_NUM) -#error \ - "Codec buffer frame num should be less than usb buffer frame num (on the requirement of conflict ctrl)" -#endif - -#ifdef USB_AUDIO_DYN_CFG -#define USB_AUDIO_PLAYBACK_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_PLAYBACK *CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) -#define USB_AUDIO_CAPTURE_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_CAPTURE *CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) - -#define USB_AUDIO_RECV_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_RECV *USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) -#define USB_AUDIO_SEND_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_SEND *USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) - -#if defined(CHIP_BEST1000) -// FIR EQ is working on 16-bit -// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int16_t) -#define USB_AUDIO_FIR_EQ_BUFF_SIZE USB_AUDIO_PLAYBACK_BUFF_SIZE -#elif defined(CHIP_BEST2000) -// FIR EQ is working on 32-bit -// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) -#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * 2) -#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) -// FIR EQ is working on 32-bit -// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) -#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * 2) -#endif - -#else -#define USB_AUDIO_PLAYBACK_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_PLAYBACK *CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) -#define USB_AUDIO_CAPTURE_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_CAPTURE *CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) - -#define USB_AUDIO_RECV_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_RECV *USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) -#define USB_AUDIO_SEND_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_SEND *USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) - -#if defined(CHIP_BEST1000) -// FIR EQ is working on 16-bit -#define USB_AUDIO_FIR_EQ_BUFF_SIZE \ - (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int16_t) / SAMPLE_SIZE_PLAYBACK) -#elif defined(CHIP_BEST2000) -// FIR EQ is working on 16-bit -#define USB_AUDIO_FIR_EQ_BUFF_SIZE \ - (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int32_t) / SAMPLE_SIZE_PLAYBACK) -#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) -// FIR EQ is working on 16-bit -#define USB_AUDIO_FIR_EQ_BUFF_SIZE \ - (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int32_t) / SAMPLE_SIZE_PLAYBACK) -#endif -#endif - -#if (defined(CHIP_BEST1000) && \ - (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) && \ - (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) -// Resample input buffer size should be (half_of_max_sample_num * -// SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE). half_of_max_sample_num = 48000 / -// 1000 * CODEC_BUFF_FRAME_NUM / 2 * 48 / 44 -#define RESAMPLE_INPUT_BUFF_SIZE \ - ALIGN(48000 / 1000 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE * \ - CODEC_BUFF_FRAME_NUM / 2 * 48 / 44, \ - 4) -#else -#define RESAMPLE_INPUT_BUFF_SIZE 0 -#endif -// Resample history buffer size should be -// sizeof(struct RESAMPLE_CTRL_T) + ((SAMPLE_NUM + phase_coef_num) * -// SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) -#define RESAMPLE_HISTORY_BUFF_SIZE \ - (50 + (256 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE)) -#define USB_AUDIO_RESAMPLE_BUFF_SIZE \ - (RESAMPLE_INPUT_BUFF_SIZE + RESAMPLE_HISTORY_BUFF_SIZE) - -#define ALIGNED4 ALIGNED(4) - -#if defined(USB_AUDIO_APP) || defined(DUALADC_AUDIO_TEST) - -#ifdef AUDIO_ANC_FB_MC -static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE * - 9]; // max 48->384 or 44.1->44.1*8; -#else -static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE]; -#endif - -static uint8_t ALIGNED4 capture_buff[USB_AUDIO_CAPTURE_BUFF_SIZE]; - -#endif - -#ifdef USB_AUDIO_APP -#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) -static uint8_t ALIGNED4 - eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE + USB_AUDIO_IIR_EQ_BUFF_SIZE]; -#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__) -static uint8_t ALIGNED4 eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE]; -#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) -static uint8_t ALIGNED4 eq_buff[USB_AUDIO_IIR_EQ_BUFF_SIZE]; -#else -static uint8_t ALIGNED4 eq_buff[0]; -#endif - -#ifdef SW_CAPTURE_RESAMPLE -static uint8_t ALIGNED4 resample_buff[USB_AUDIO_RESAMPLE_BUFF_SIZE]; -#else -static uint8_t ALIGNED4 resample_buff[0]; -#endif - -static uint8_t ALIGNED4 recv_buff[USB_AUDIO_RECV_BUFF_SIZE]; -static uint8_t ALIGNED4 send_buff[USB_AUDIO_SEND_BUFF_SIZE]; -#endif - -#ifdef CFG_HW_KEY_LED_PIN -const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_key_led[1] = { - {CFG_HW_KEY_LED_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, - HAL_IOMUX_PIN_NOPULL}, -}; -#endif - -#ifdef CFG_MIC_KEY -extern void mic_key_open(void); -#endif - -static void uart_i2c_switch(void) { - static int flag = 0; - - flag ^= 1; - - if (flag) { - hal_iomux_set_analog_i2c(); - } else { - hal_iomux_set_uart0(); - } -} - -static int POSSIBLY_UNUSED key_event_process(uint32_t key_code, - uint8_t key_event) { - TRACE(3, "%s: code=0x%X, event=%u", __FUNCTION__, key_code, key_event); - -#ifdef CFG_HW_KEY_LED_PIN - if (key_event == HAL_KEY_EVENT_DOWN) { - hal_gpio_pin_set(CFG_HW_KEY_LED_PIN); - } else if (key_event == HAL_KEY_EVENT_UP) { - hal_gpio_pin_clr(CFG_HW_KEY_LED_PIN); - } -#endif - -#ifdef USB_AUDIO_APP - if (usb_audio_app_key(key_code, key_event) == 0) { - return 0; - } -#endif - -#ifdef ANC_APP - if (anc_usb_app_key(key_code, key_event) == 0) { - return 0; - } -#endif - - if (key_event == HAL_KEY_EVENT_CLICK) { - if (key_code == HAL_KEY_CODE_FN9) { - uart_i2c_switch(); - } - } - - return 0; -} - -void anc_usb_open(void) { - TRACE(1, "%s", __FUNCTION__); - -#ifdef __AUDIO_RESAMPLE__ - hal_cmu_audio_resample_enable(); -#endif - -#ifdef USB_AUDIO_APP - struct USB_AUDIO_BUF_CFG cfg; - - memset(&cfg, 0, sizeof(cfg)); - cfg.play_buf = playback_buff; -#ifdef AUDIO_ANC_FB_MC - cfg.play_size = sizeof(playback_buff) / 9; -#else - cfg.play_size = sizeof(playback_buff); -#endif - cfg.cap_buf = capture_buff; - cfg.cap_size = sizeof(capture_buff); - cfg.recv_buf = recv_buff; - cfg.recv_size = sizeof(recv_buff); - cfg.send_buf = send_buff; - cfg.send_size = sizeof(send_buff); - cfg.eq_buf = eq_buff; - cfg.eq_size = sizeof(eq_buff); - cfg.resample_buf = resample_buff; - cfg.resample_size = sizeof(resample_buff); - - usb_audio_app_init(&cfg); - usb_audio_app(1); -#endif - -#ifdef ANC_APP - anc_usb_app_init(AUD_INPUT_PATH_MAINMIC, SAMPLE_RATE_PLAYBACK, - SAMPLE_RATE_CAPTURE); -#endif - -#ifdef DUALADC_AUDIO_TEST - dualadc_audio_app_init(playback_buff, USB_AUDIO_PLAYBACK_BUFF_SIZE, - capture_buff, USB_AUDIO_CAPTURE_BUFF_SIZE); - dualadc_audio_app(1); -#endif - -#if defined(CFG_MIC_KEY) - mic_key_open(); -#endif -#ifdef BT_USB_AUDIO_DUAL_MODE - return; -#endif - // Allow sleep - hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_32K); - - while (1) { -#ifdef USB_AUDIO_APP - usb_audio_app_loop(); -#endif - -#ifdef ANC_APP - anc_usb_app_loop(); -#endif - -#ifdef RTOS - // Let the task sleep - osDelay(20); -#else // !RTOS - -#ifdef __PC_CMD_UART__ - hal_cmd_run(); -#endif - - hal_sleep_enter_sleep(); - -#endif // !RTOS - } -} - -void anc_usb_close(void) { usb_audio_app(0); } - -#ifdef CFG_HW_GPADCKEY -void gpadc_key_handler(uint16_t irq_val, HAL_GPADC_MV_T volt) { - static uint16_t stable_cnt = 0; - static uint16_t click_cnt = 0; - static uint32_t click_time; - uint32_t time; - enum HAL_KEY_EVENT_T event; - bool send_event = false; - - time = hal_sys_timer_get(); - - if (volt < 100) { - stable_cnt++; - // TRACE(5,"adc_key down: volt=%u stable=%u click_cnt=%u click_time=%u - // time=%u", volt, stable_cnt, click_cnt, click_time, time); - } else { - if (stable_cnt > 1) { - // TRACE(5,"adc_key up: volt=%u stable=%u click_cnt=%u click_time=%u - // time=%u", volt, stable_cnt, click_cnt, click_time, time); - if (click_cnt == 0 || (time - click_time) < MS_TO_TICKS(500)) { - click_time = time; - click_cnt++; - if (click_cnt >= 3) { - send_event = true; - } - } else { - send_event = true; - } - } - stable_cnt = 0; - - if (click_cnt > 0 && (time - click_time) >= MS_TO_TICKS(500)) { - send_event = true; - } - - if (send_event) { - // TRACE(5,"adc_key click: volt=%u stable=%u click_cnt=%u click_time=%u - // time=%u", volt, stable_cnt, click_cnt, click_time, time); - if (click_cnt == 1) { - event = HAL_KEY_EVENT_CLICK; - } else if (click_cnt == 2) { - event = HAL_KEY_EVENT_DOUBLECLICK; - } else { - event = HAL_KEY_EVENT_TRIPLECLICK; - } - key_event_process(CFG_HW_GPADCKEY, event); - click_cnt = 0; - } - } -} -#endif - -// GDB can set a breakpoint on the main function only if it is -// declared as below, when linking with STD libraries. -int btusbaudio_entry(void) { - anc_usb_open(); - return 0; -} - -void btusbaudio_exit(void) { anc_usb_close(); } diff --git a/apps/usbhost/Makefile b/apps/usbhost/Makefile deleted file mode 100644 index a2b6b88..0000000 --- a/apps/usbhost/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) -obj-y := $(obj-y:.c=.o) -obj-y := $(obj-y:.cpp=.o) -obj-y := $(obj-y:.S=.o) - diff --git a/apps/usbhost/app_usbhost.c b/apps/usbhost/app_usbhost.c deleted file mode 100644 index 35c02c1..0000000 --- a/apps/usbhost/app_usbhost.c +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "app_thread.h" -#include "cmsis_os.h" -#include "hal_trace.h" diff --git a/apps/usbhost/app_usbhost.h b/apps/usbhost/app_usbhost.h deleted file mode 100644 index c12f1ee..0000000 --- a/apps/usbhost/app_usbhost.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __APP_USBHOST_H__ -#define __APP_USBHOST_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus - } -#endif - -#endif//__FMDEC_H__ diff --git a/config/Makefile b/config/Makefile index 90dd8d5..7c6d917 100644 --- a/config/Makefile +++ b/config/Makefile @@ -19,7 +19,6 @@ obj-y := $(obj-y:.S=.o) ccflags-y += \ -Iplatform/hal \ - -Iplatform/drivers/usb/usb_dev/inc \ -Iservices/nv_section/aud_section \ -Iservices/nv_section/include \ -Iservices/multimedia/speech/inc \ diff --git a/platform/drivers/Makefile b/platform/drivers/Makefile index d45fd5a..8bc5f8b 100644 --- a/platform/drivers/Makefile +++ b/platform/drivers/Makefile @@ -1,9 +1,5 @@ obj-y := ana/ codec/ norflash/ bt/ btpcm/ sbcacc/ -ifeq ($(CHIP_HAS_USB),1) -obj-y += usb/ -endif - subdir-ccflags-y += -Iplatform/drivers/ana \ -Iplatform/drivers/bt diff --git a/platform/drivers/usb/Makefile b/platform/drivers/usb/Makefile deleted file mode 100644 index 7f54e96..0000000 --- a/platform/drivers/usb/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y := usb_dev/ diff --git a/platform/drivers/usb/usb_dev/Makefile b/platform/drivers/usb/usb_dev/Makefile deleted file mode 100644 index fe0a98d..0000000 --- a/platform/drivers/usb/usb_dev/Makefile +++ /dev/null @@ -1,130 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -src_obj := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c $(cur_dir)src/*.S)) -src_obj := $(src_obj:.c=.o) -src_obj := $(src_obj:.S=.o) - -cfg_obj := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)cfg/*.c $(cur_dir)cfg/*.S)) -cfg_obj := $(cfg_obj:.c=.o) -cfg_obj := $(cfg_obj:.S=.o) - -USB_DEV_LIB_NAME := libusbdev - -ccflags-y += -Iplatform/drivers/usb/usb_dev/inc - -ifeq ($(USB_HIGH_SPEED),1) -ccflags-y += -DUSB_HIGH_SPEED -endif - -CFLAGS_usb_cdc.o += -Itests/programmer/inc - -CFLAGS_usb_audio.o += -Iutils/hwtimer_list - -CFLAGS_usb_audio_sync.o += -Iplatform/drivers/ana - -USB_AUDIO_NO_START_ERR ?= 1 -ifeq ($(USB_AUDIO_NO_START_ERR),1) -CFLAGS_usb_audio.o += -DUSB_AUDIO_NO_START_ERR -endif - -ifneq ($(USYNC_TRACE_VERBOSE),) -CFLAGS_usb_audio_sync.o += -DUSYNC_TRACE_VERBOSE=$(USYNC_TRACE_VERBOSE) -endif - -ifneq ($(USB_CDC_VENDOR_ID),) -CFLAGS_usb_dev_desc.o += -DUSB_CDC_VENDOR_ID=$(USB_CDC_VENDOR_ID) -endif - -ifneq ($(USB_CDC_PRODUCT_ID),) -CFLAGS_usb_dev_desc.o += -DUSB_CDC_PRODUCT_ID=$(USB_CDC_PRODUCT_ID) -endif - -ifneq ($(USB_AUDIO_VENDOR_ID),) -CFLAGS_usb_dev_desc.o += -DUSB_AUDIO_VENDOR_ID=$(USB_AUDIO_VENDOR_ID) -endif - -ifneq ($(USB_AUDIO_PRODUCT_ID),) -CFLAGS_usb_dev_desc.o += -DUSB_AUDIO_PRODUCT_ID=$(USB_AUDIO_PRODUCT_ID) -endif - -ifeq ($(USB_LPM),1) -CFLAGS_usb_dev_desc.o += -DUSB_LPM -ifeq ($(USB_LPM_DEEP_BESL),1) -CFLAGS_usb_dev_desc.o += -DUSB_LPM_DEEP_BESL -endif -endif - -include $(cur_dir)uaud_cfg_flags.mk - -$(cur_dir)uaud_cfg_flags.mk: ; - -ifeq ($(USB_AUDIO_DYN_CFG),1) - -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_dyn - -else # USB_AUDIO_DYN_CFG != 1 - -ifeq ($(USB_AUDIO_384K),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_384k -else ifeq ($(USB_AUDIO_352_8K),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_352p8k -else ifeq ($(USB_AUDIO_192K),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_192k -else ifeq ($(USB_AUDIO_176_4K),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_176p4k -else ifeq ($(USB_AUDIO_96K),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_96k -else ifeq ($(USB_AUDIO_44_1K),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_44p1k -else ifeq ($(USB_AUDIO_16K),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_16k -endif - -ifeq ($(USB_AUDIO_32BIT),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_32b -else -ifeq ($(USB_AUDIO_24BIT),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_24b -endif -endif - -endif # USB_AUDIO_DYN_CFG != 1 - -ifneq ($(USB_AUDIO_SEND_CHAN),) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_s$(USB_AUDIO_SEND_CHAN) -endif - -ifeq ($(USB_AUDIO_UAC2),1) -USB_DEV_LIB_NAME := $(USB_DEV_LIB_NAME)_uac2 -endif - -CFLAGS_usb_audio.o += $(UAUD_CFG_FLAGS) -CFLAGS_usb_dev_desc.o += $(UAUD_CFG_FLAGS) - -ifeq ($(SIMU_UAUD_MAX_PKT),1) -CFLAGS_usb_audio.o += -DSIMU_UAUD_MAX_PKT -endif - -ifeq ($(ANDROID_ACCESSORY_SPEC),1) -CFLAGS_usb_audio.o += -DANDROID_ACCESSORY_SPEC -ifeq ($(STRICT_ANDROID_ACCESSORY_SPEC),1) -CFLAGS_usb_audio.o += -DSTRICT_ANDROID_ACCESSORY_SPEC -ifeq ($(ANDROID_VOICE_CMD_KEY),1) -CFLAGS_usb_audio.o += -DANDROID_VOICE_CMD_KEY -endif -endif -endif - -ifneq ($(USB_AUDIO_RECV_ENABLE),0) -CFLAGS_usb_audio.o += -DUSB_AUDIO_RECV_ENABLE -CFLAGS_usb_audio_sync.o += -DUSB_AUDIO_RECV_ENABLE -endif -ifneq ($(USB_AUDIO_SEND_ENABLE),0) -CFLAGS_usb_audio.o += -DUSB_AUDIO_SEND_ENABLE -CFLAGS_usb_audio_sync.o += -DUSB_AUDIO_SEND_ENABLE -endif - -$(USB_DEV_LIB_NAME)-y := $(src_obj) - -obj-y := $(USB_DEV_LIB_NAME).a $(cfg_obj) - diff --git a/platform/drivers/usb/usb_dev/cfg/usb_dev_desc.c b/platform/drivers/usb/usb_dev/cfg/usb_dev_desc.c deleted file mode 100644 index 3865dc6..0000000 --- a/platform/drivers/usb/usb_dev/cfg/usb_dev_desc.c +++ /dev/null @@ -1,499 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "usb_dev_desc.h" -#include "hal_usb.h" -#include "tgt_hardware.h" -#include "usb_descriptor.h" - -#ifdef USB_HIGH_SPEED -#define DEV_QUAL_USB_VER 0x0200 -#define USB_CDC_USB_VER 0x0200 -#define USB_AUDIO_USB_VER 0x0201 -#define USB_CDC_PRODUCT_ID_BASE 0x0120 -#ifdef USB_AUDIO_UAC2 -#define USB_AUDIO_PRODUCT_ID_BASE 0x0400 -#else -#define USB_AUDIO_PRODUCT_ID_BASE 0x0300 -#endif -#else -#define DEV_QUAL_USB_VER 0x0200 -#define USB_CDC_USB_VER 0x0200 // 0x0110 -#define USB_AUDIO_USB_VER 0x0200 // 0x0110 -#define USB_CDC_PRODUCT_ID_BASE 0x0100 -#define USB_AUDIO_PRODUCT_ID_BASE 0x0200 -#ifdef USB_AUDIO_UAC2 -#error "USB_AUDIO_UAC2 should run on USB_HIGH_SPEED" -#endif -#endif - -#ifndef USB_CDC_VENDOR_ID -#define USB_CDC_VENDOR_ID 0xBE57 -#endif - -#ifndef USB_CDC_PRODUCT_ID -#define USB_CDC_PRODUCT_ID (USB_CDC_PRODUCT_ID_BASE + 0x01) -#endif - -#ifndef USB_AUDIO_VENDOR_ID -#define USB_AUDIO_VENDOR_ID 0xBE57 -#endif - -#ifndef USB_AUDIO_PRODUCT_ID - -#ifdef USB_AUDIO_DYN_CFG - -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x31) -#ifdef USB_AUDIO_32BIT -#define USB_AUDIO_PRODUCT_32BIT_FLAG 0x0004 -#else -#define USB_AUDIO_PRODUCT_32BIT_FLAG 0 -#endif -#ifdef USB_AUDIO_24BIT -#define USB_AUDIO_PRODUCT_24BIT_FLAG 0x0002 -#else -#define USB_AUDIO_PRODUCT_24BIT_FLAG 0 -#endif -#ifdef USB_AUDIO_16BIT -#define USB_AUDIO_PRODUCT_16BIT_FLAG 0x0001 -#else -#define USB_AUDIO_PRODUCT_16BIT_FLAG 0 -#endif - -#define USB_AUDIO_PRODUCT_ID \ - (USB_AUDIO_PRODUCT_ID_STEM + USB_AUDIO_PRODUCT_32BIT_FLAG + \ - USB_AUDIO_PRODUCT_24BIT_FLAG + USB_AUDIO_PRODUCT_16BIT_FLAG) - -#else // !USB_AUDIO_DYN_CFG - -#ifdef USB_AUDIO_384K -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x08) -#elif defined(USB_AUDIO_352_8K) -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x07) -#elif defined(USB_AUDIO_192K) -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x06) -#elif defined(USB_AUDIO_176_4K) -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x05) -#elif defined(USB_AUDIO_96K) -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x04) -#elif defined(USB_AUDIO_44_1K) -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x03) -#elif defined(USB_AUDIO_16K) -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x02) -#else // 48K -#define USB_AUDIO_PRODUCT_ID_STEM (USB_AUDIO_PRODUCT_ID_BASE + 0x01) -#endif - -#define USB_AUDIO_PRODUCT_32BIT_FLAG 0x0020 -#define USB_AUDIO_PRODUCT_24BIT_FLAG 0x0010 - -#ifdef USB_AUDIO_32BIT -#define USB_AUDIO_PRODUCT_ID \ - (USB_AUDIO_PRODUCT_ID_STEM + USB_AUDIO_PRODUCT_32BIT_FLAG) -#elif defined(USB_AUDIO_24BIT) -#define USB_AUDIO_PRODUCT_ID \ - (USB_AUDIO_PRODUCT_ID_STEM + USB_AUDIO_PRODUCT_24BIT_FLAG) -#else -#define USB_AUDIO_PRODUCT_ID (USB_AUDIO_PRODUCT_ID_STEM) -#endif - -#endif // !USB_AUDIO_DYN_CFG - -#endif // !USB_AUDIO_PRODUCT_ID - -//---------------------------------------------------------------- -// USB device common string descriptions -//---------------------------------------------------------------- - -static const uint8_t stringLangidDescriptor[] = { - 0x04, /*bLength*/ - STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ - 0x09, 0x04, /*bString Lang ID - 0x0409 - English*/ -}; - -static const uint8_t stringIconfigurationDescriptor[] = { - 0x06, /*bLength*/ - STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ - '0', - 0, - '1', - 0, /*bString iConfiguration - 01*/ -}; - -#ifdef USB_HIGH_SPEED -static const uint8_t deviceQualifierDescriptor[] = { - 10, - QUALIFIER_DESCRIPTOR, - LSB(DEV_QUAL_USB_VER), - MSB(DEV_QUAL_USB_VER), - 0, // bDeviceClass - 0, // bDeviceSubClass - 0, // bDeviceProtocol - USB_MAX_PACKET_SIZE_CTRL, // bMaxPacketSize0 - 0, - 0, -}; - -static const uint8_t bosDescriptor[] = { - 5, - BOS_DESCRIPTOR, - 12, - 0, // wTotalLength - 1, // bNumDeviceCaps - 7, // bLength - 0x10, // bDescriptorType - 0x02, // bDevCapabilityType -#ifdef USB_LPM -#ifdef USB_LPM_DEEP_BESL - 0x1E, // bmAttributes: LPM, BESL, Baseline BESL, Deep BESL -#else - 0x0E, // bmAttributes: LPM, BESL, Baseline BESL -#endif - (USB_L1_DEEP_SLEEP_BESL << 4) | USB_L1_LIGHT_SLEEP_BESL, -#else - 0x00, // bmAttributes: none - 0x00, -#endif - 0x00, - 0x00}; -#endif - -//---------------------------------------------------------------- -// USB CDC device description and string descriptions -//---------------------------------------------------------------- - -const uint8_t *cdc_dev_desc(uint8_t type) { - static const uint8_t deviceDescriptor[] = { - 18, // bLength - DEVICE_DESCRIPTOR, // bDescriptorType - LSB(USB_CDC_USB_VER), - MSB(USB_CDC_USB_VER), // bcdUSB - 2, // bDeviceClass - 0, // bDeviceSubClass - 0, // bDeviceProtocol - USB_MAX_PACKET_SIZE_CTRL, // bMaxPacketSize0 - LSB(USB_CDC_VENDOR_ID), - MSB(USB_CDC_VENDOR_ID), // idVendor - LSB(USB_CDC_PRODUCT_ID), - MSB(USB_CDC_PRODUCT_ID), // idProduct - 0x00, - 0x01, // bcdDevice - STRING_OFFSET_IMANUFACTURER, // iManufacturer - STRING_OFFSET_IPRODUCT, // iProduct - STRING_OFFSET_ISERIAL, // iSerialNumber - 1 // bNumConfigurations - }; - - if (type == DEVICE_DESCRIPTOR) { - return deviceDescriptor; -#ifdef USB_HIGH_SPEED - } else if (type == QUALIFIER_DESCRIPTOR) { - return deviceQualifierDescriptor; - } else if (type == BOS_DESCRIPTOR) { - return bosDescriptor; -#endif - } else { - return NULL; - } -} - -const uint8_t *cdc_string_desc(uint8_t index) { - static const uint8_t stringImanufacturerDescriptor[] = -#ifdef USB_CDC_STR_DESC_MANUFACTURER - USB_CDC_STR_DESC_MANUFACTURER; -#else - { - 0x16, /*bLength*/ - STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ - 'b', - 0, - 'e', - 0, - 's', - 0, - 't', - 0, - 'e', - 0, - 'c', - 0, - 'h', - 0, - 'n', - 0, - 'i', - 0, - 'c', - 0 /*bString iManufacturer - bestechnic*/ - }; -#endif - - static const uint8_t stringIserialDescriptor[] = -#ifdef USB_CDC_STR_DESC_SERIAL - USB_CDC_STR_DESC_SERIAL; -#else - { - 0x16, /*bLength*/ - STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ - '2', - 0, - '0', - 0, - '1', - 0, - '5', - 0, - '1', - 0, - '0', - 0, - '0', - 0, - '6', - 0, - '.', - 0, - '1', - 0, /*bString iSerial - 20151006.1*/ - }; -#endif - - static const uint8_t stringIinterfaceDescriptor[] = -#ifdef USB_CDC_STR_DESC_INTERFACE - USB_CDC_STR_DESC_INTERFACE; -#else - { - 0x08, STRING_DESCRIPTOR, 'C', 0, 'D', 0, 'C', 0, - }; -#endif - - static const uint8_t stringIproductDescriptor[] = -#ifdef USB_CDC_STR_DESC_PRODUCT - USB_CDC_STR_DESC_PRODUCT; -#else - {0x16, STRING_DESCRIPTOR, - 'C', 0, - 'D', 0, - 'C', 0, - ' ', 0, - 'D', 0, - 'E', 0, - 'V', 0, - 'I', 0, - 'C', 0, - 'E', 0}; -#endif - - const uint8_t *data = NULL; - - switch (index) { - case STRING_OFFSET_LANGID: - data = stringLangidDescriptor; - break; - case STRING_OFFSET_IMANUFACTURER: - data = stringImanufacturerDescriptor; - break; - case STRING_OFFSET_IPRODUCT: - data = stringIproductDescriptor; - break; - case STRING_OFFSET_ISERIAL: - data = stringIserialDescriptor; - break; - case STRING_OFFSET_ICONFIGURATION: - data = stringIconfigurationDescriptor; - break; - case STRING_OFFSET_IINTERFACE: - data = stringIinterfaceDescriptor; - break; - } - - return data; -} - -//---------------------------------------------------------------- -// USB audio device description and string descriptions -//---------------------------------------------------------------- - -const uint8_t *uaud_dev_desc(uint8_t type) { - static const uint8_t deviceDescriptor[] = { - 18, // bLength - DEVICE_DESCRIPTOR, // bDescriptorType - LSB(USB_AUDIO_USB_VER), - MSB(USB_AUDIO_USB_VER), // bcdUSB - 0, // bDeviceClass - 0, // bDeviceSubClass - 0, // bDeviceProtocol - USB_MAX_PACKET_SIZE_CTRL, // bMaxPacketSize0 - LSB(USB_AUDIO_VENDOR_ID), - MSB(USB_AUDIO_VENDOR_ID), // idVendor - LSB(USB_AUDIO_PRODUCT_ID), - MSB(USB_AUDIO_PRODUCT_ID), // idProduct - 0x00, - 0x01, // bcdDevice - STRING_OFFSET_IMANUFACTURER, // iManufacturer - STRING_OFFSET_IPRODUCT, // iProduct - STRING_OFFSET_ISERIAL, // iSerialNumber - 1 // bNumConfigurations - }; - - if (type == DEVICE_DESCRIPTOR) { - return deviceDescriptor; -#ifdef USB_HIGH_SPEED - } else if (type == QUALIFIER_DESCRIPTOR) { - return deviceQualifierDescriptor; - } else if (type == BOS_DESCRIPTOR) { - return bosDescriptor; -#endif - } else { - return NULL; - } -} - -const uint8_t *uaud_string_desc(uint8_t index) { - static const uint8_t stringImanufacturerDescriptor[] = -#ifdef USB_AUDIO_STR_DESC_MANUFACTURER - USB_AUDIO_STR_DESC_MANUFACTURER; -#else - { - 0x16, /*bLength*/ - STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ - 'b', - 0, - 'e', - 0, - 's', - 0, - 't', - 0, - 'e', - 0, - 'c', - 0, - 'h', - 0, - 'n', - 0, - 'i', - 0, - 'c', - 0 /*bString iManufacturer - bestechnic*/ - }; -#endif - - static const uint8_t stringIserialDescriptor[] = -#ifdef USB_AUDIO_STR_DESC_SERIAL - USB_AUDIO_STR_DESC_SERIAL; -#else - { - 0x16, /*bLength*/ - STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ - '2', - 0, - '0', - 0, - '1', - 0, - '6', - 0, - '0', - 0, - '4', - 0, - '0', - 0, - '6', - 0, - '.', - 0, - '1', - 0, /*bString iSerial - 20160406.1*/ - }; -#endif - - static const uint8_t stringIinterfaceDescriptor[] = -#ifdef USB_AUDIO_STR_DESC_INTERFACE - USB_AUDIO_STR_DESC_INTERFACE; -#else - { - 0x0c, // bLength - STRING_DESCRIPTOR, // bDescriptorType 0x03 - 'A', - 0, - 'u', - 0, - 'd', - 0, - 'i', - 0, - 'o', - 0 // bString iInterface - Audio - }; -#endif - - static const uint8_t stringIproductDescriptor[] = -#ifdef USB_AUDIO_STR_DESC_PRODUCT - USB_AUDIO_STR_DESC_PRODUCT; -#else - { - 0x16, // bLength - STRING_DESCRIPTOR, // bDescriptorType 0x03 - 'B', - 0, - 'e', - 0, - 's', - 0, - 't', - 0, - ' ', - 0, - 'A', - 0, - 'u', - 0, - 'd', - 0, - 'i', - 0, - 'o', - 0 // bString iProduct - Best Audio - }; -#endif - - const uint8_t *data = NULL; - - switch (index) { - case STRING_OFFSET_LANGID: - data = stringLangidDescriptor; - break; - case STRING_OFFSET_IMANUFACTURER: - data = stringImanufacturerDescriptor; - break; - case STRING_OFFSET_IPRODUCT: - data = stringIproductDescriptor; - break; - case STRING_OFFSET_ISERIAL: - data = stringIserialDescriptor; - break; - case STRING_OFFSET_ICONFIGURATION: - data = stringIconfigurationDescriptor; - break; - case STRING_OFFSET_IINTERFACE: - data = stringIinterfaceDescriptor; - break; - } - - return data; -} diff --git a/platform/drivers/usb/usb_dev/inc/usb_audio.h b/platform/drivers/usb/usb_dev/inc/usb_audio.h deleted file mode 100644 index 5e4f855..0000000 --- a/platform/drivers/usb/usb_dev/inc/usb_audio.h +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_AUDIO_H__ -#define __USB_AUDIO_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stdint.h" -#include "hal_usb.h" - -enum USB_AUDIO_ITF_ID_T { - USB_AUDIO_ITF_ID_RECV, - USB_AUDIO_ITF_ID_SEND, -#ifdef USB_AUDIO_MULTIFUNC - USB_AUDIO_ITF_ID_RECV2, -#endif - - USB_AUDIO_ITF_ID_QTY -}; - -enum USB_AUDIO_ITF_CMD_T { - USB_AUDIO_ITF_STOP, - USB_AUDIO_ITF_START_16BIT, - USB_AUDIO_ITF_START_24BIT, - USB_AUDIO_ITF_START_32BIT, - - USB_AUDIO_ITF_CMD_QTY -}; - -enum USB_AUDIO_STATE_EVENT_T { - USB_AUDIO_STATE_RESET, // RESET event should be processed as quickly as possible - USB_AUDIO_STATE_DISCONNECT, - USB_AUDIO_STATE_SLEEP, - USB_AUDIO_STATE_WAKEUP, - USB_AUDIO_STATE_CONFIG, - USB_AUDIO_STATE_RECV_PAUSE, - USB_AUDIO_STATE_RECV_CONTINUE, - USB_AUDIO_STATE_SET_RECV_RATE, - USB_AUDIO_STATE_SET_SEND_RATE, - USB_AUDIO_STATE_RECV2_PAUSE, - USB_AUDIO_STATE_RECV2_CONTINUE, - - USB_AUDIO_STATE_EVENT_QTY -}; - -enum USB_AUDIO_HID_EVENT_T { - USB_AUDIO_HID_VOL_UP = (1 << 0), - USB_AUDIO_HID_VOL_DOWN = (1 << 1), - USB_AUDIO_HID_PLAY_PAUSE = (1 << 2), - USB_AUDIO_HID_SCAN_NEXT = (1 << 3), - USB_AUDIO_HID_SCAN_PREV = (1 << 4), - USB_AUDIO_HID_STOP = (1 << 5), - USB_AUDIO_HID_FAST_FWD = (1 << 6), - USB_AUDIO_HID_REWIND = (1 << 7), - USB_AUDIO_HID_VOL_MUTE = (1 << 8), - USB_AUDIO_HID_VOICE_CMD = (1 << 9), - USB_AUDIO_HID_REDIAL = (1 << 10), - USB_AUDIO_HID_HOOK_SWITCH = (1 << 11), - USB_AUDIO_HID_MIC_MUTE = (1 << 12), - USB_AUDIO_HID_VOICE_MAIL = (1 << 13), - USB_AUDIO_HID_RESERVED_14 = (1 << 14), - USB_AUDIO_HID_RESERVED_15 = (1 << 15), -}; - -struct USB_AUDIO_XFER_INFO_T { - const uint8_t *data; - uint32_t size; - uint32_t next_size; - bool pool_enabled; - int8_t cur_compl_err; - int8_t next_xfer_err; -}; - -struct USB_AUDIO_VENDOR_MSG_T { - const struct SETUP_PACKET *pkt; - uint8_t *data; - uint16_t length; -}; - -typedef void (*USB_AUDIO_ITF_CALLBACK)(enum USB_AUDIO_ITF_ID_T id, enum USB_AUDIO_ITF_CMD_T cmd); -typedef void (*USB_AUDIO_MUTE_CALLBACK)(enum USB_AUDIO_ITF_ID_T id, uint32_t mute); -typedef void (*USB_AUDIO_SET_VOLUME)(enum USB_AUDIO_ITF_ID_T id, uint32_t percent); -typedef uint32_t (*USB_AUDIO_GET_VOLUME)(enum USB_AUDIO_ITF_ID_T id); -typedef void (*USB_AUDIO_XFER_CALLBACK)(enum USB_AUDIO_ITF_ID_T id, const struct USB_AUDIO_XFER_INFO_T *info); -typedef void (*USB_AUDIO_STATE_CALLBACK)(enum USB_AUDIO_STATE_EVENT_T event, uint32_t param); -typedef void (*HID_XFER_CALLBACK)(enum USB_AUDIO_HID_EVENT_T event, int error); -typedef int (*USB_AUDIO_VENDOR_MSG_CALLBACK)(struct USB_AUDIO_VENDOR_MSG_T *msg); - -struct USB_AUDIO_CFG_T { - uint32_t recv_sample_rate; - uint32_t send_sample_rate; - uint8_t *vendor_rx_buf; - uint16_t vendor_rx_size; - USB_AUDIO_ITF_CALLBACK itf_callback; - USB_AUDIO_MUTE_CALLBACK mute_callback; - USB_AUDIO_SET_VOLUME set_volume; - USB_AUDIO_GET_VOLUME get_volume; - USB_AUDIO_STATE_CALLBACK state_callback; - USB_AUDIO_XFER_CALLBACK xfer_callback; - HID_XFER_CALLBACK hid_send_callback; - USB_AUDIO_VENDOR_MSG_CALLBACK vendor_msg_callback; -}; - -int usb_audio_open(const struct USB_AUDIO_CFG_T *cfg); - -void usb_audio_close(void); - -int usb_audio_recv_ready(void); - -int usb_audio_send_ready(void); - -int usb_audio_start_recv(uint8_t *buf, uint32_t pos, uint32_t size); - -void usb_audio_stop_recv(void); - -int usb_audio_start_send(const uint8_t *buf, uint32_t pos, uint32_t size); - -void usb_audio_stop_send(void); - -void usb_audio_pause_send(void); - -int usb_audio_continue_send(uint32_t pos); - -int usb_audio_set_recv_pos(uint32_t pos); - -int usb_audio_set_send_pos(uint32_t pos); - -void usb_audio_hid_set_event(enum USB_AUDIO_HID_EVENT_T event, int state); - -const char *usb_audio_get_hid_event_name(enum USB_AUDIO_HID_EVENT_T event); - -int usb_audio_start_recv2(uint8_t *buf, uint32_t pos, uint32_t size); - -void usb_audio_stop_recv2(void); - -int usb_audio_set_recv2_pos(uint32_t pos); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/drivers/usb/usb_dev/inc/usb_audio_sync.h b/platform/drivers/usb/usb_dev/inc/usb_audio_sync.h deleted file mode 100644 index 8f42f09..0000000 --- a/platform/drivers/usb/usb_dev/inc/usb_audio_sync.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_AUDIO_SYNC_H__ -#define __USB_AUDIO_SYNC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" - -typedef uint32_t (*USB_AUDIO_SYNC_TIME_TO_MS)(uint32_t time); - -enum UAUD_SYNC_RET_T { - UAUD_SYNC_IDLE, - UAUD_SYNC_START, - UAUD_SYNC_ERR, -}; - -struct USB_AUDIO_STREAM_INFO_T { - // Difference error threshold - uint16_t err_thresh; - // Difference synchronization threshold - uint16_t sync_thresh; - // Sample rate - uint32_t samp_rate; - // Total sample count of the buffer - uint32_t samp_cnt; - // The number of value to calculate the average - uint8_t diff_avg_cnt; - // The stream info ID - uint8_t id; - // Whether to enable diff_target - uint8_t diff_target_enabled; - // The Max adjust ratio moving to diff_target - float max_target_ratio; - // The abosulte difference value between current diff and diff_target to apply max_target_ratio - uint32_t max_target_thresh; - // The target of the difference - int diff_target; - // Function to convert timestamp to ms. If NULL, default timer will be used. - USB_AUDIO_SYNC_TIME_TO_MS time_to_ms; - // Current timestamp. If time_to_ms is NULL, this member will be ignored. - uint32_t time; - // Internal control block - uint32_t ctrl_block[8]; -}; - -void usb_audio_sync_reset(struct USB_AUDIO_STREAM_INFO_T *info); - -int usb_audio_sync_normalize_diff(int diff, uint32_t size); - -enum UAUD_SYNC_RET_T usb_audio_sync(uint32_t pos_a, uint32_t pos_b, struct USB_AUDIO_STREAM_INFO_T *info, float *p_ratio); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/drivers/usb/usb_dev/inc/usb_cdc.h b/platform/drivers/usb/usb_dev/inc/usb_cdc.h deleted file mode 100644 index c76eba6..0000000 --- a/platform/drivers/usb/usb_dev/inc/usb_cdc.h +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_CDC_H__ -#define __USB_CDC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" - -enum USB_SERIAL_API_MODE { - USB_SERIAL_API_NONBLOCKING, - USB_SERIAL_API_BLOCKING, -}; - -enum USB_SERIAL_STATE_EVENT_T { - USB_SERIAL_STATE_RESET, // RESET event should be processed as quickly as possible - USB_SERIAL_STATE_DISCONNECT, - USB_SERIAL_STATE_SLEEP, - USB_SERIAL_STATE_WAKEUP, - USB_SERIAL_STATE_CONFIG, - USB_SERIAL_STATE_STALL_RECV, - USB_SERIAL_STATE_STALL_SEND, - USB_SERIAL_STATE_STALL_INTR, - USB_SERIAL_STATE_UNSTALL_RECV, - USB_SERIAL_STATE_UNSTALL_SEND, - USB_SERIAL_STATE_UNSTALL_INTR, -}; - -enum USB_SERIAL_RET_VALUE { - USB_ERR_OK = 0, - USB_ERR_RXTX_DATA = -1, - USB_ERR_NOT_DONE = -2, - USB_ERR_NOT_IDLE = -3, - USB_ERR_NOT_LOCK = -9, - USB_ERR_NOT_CONNECT = -10, - USB_ERR_INV_PARAM = -11, - USB_ERR_UNALIGNED = -12, - USB_ERR_RX_SIZE = -13, - USB_ERR_RXTX_CANCEL = -14, -}; - -enum USB_SERIAL_STOP_BITS_T { - USB_SERIAL_STOP_BITS_1 = 0, - USB_SERIAL_STOP_BITS_1P5 = 1, - USB_SERIAL_STOP_BITS_2 = 2, -}; - -enum USB_SERIAL_PARITY_T { - USB_SERIAL_PARITY_NONE = 0, - USB_SERIAL_PARITY_ODD = 1, - USB_SERIAL_PARITY_EVEN = 2, - USB_SERIAL_PARITY_MARK = 3, - USB_SERIAL_PARITY_SPACE = 4, -}; - -struct USB_SERIAL_LINE_CODING_T { - uint32_t rate; - uint8_t stop_bits; - uint8_t parity; - uint8_t data_bits; -}; - -typedef void (*USB_SERIAL_STATE_CALLBACK)(enum USB_SERIAL_STATE_EVENT_T event); -typedef void (*USB_SERIAL_BREAK_CALLBACK)(uint16_t ms); -typedef int (*USB_SERIAL_GET_LINE_CODING_CALLBACK)(struct USB_SERIAL_LINE_CODING_T *coding); -typedef int (*USB_SERIAL_SET_LINE_CODING_CALLBACK)(const struct USB_SERIAL_LINE_CODING_T *coding); -typedef void (*USB_SERIAL_XFER_CALLBACK)(const uint8_t *data, uint32_t size, int error); - -struct USB_SERIAL_CFG_T { - USB_SERIAL_STATE_CALLBACK state_callback; - USB_SERIAL_BREAK_CALLBACK break_callback; - USB_SERIAL_GET_LINE_CODING_CALLBACK get_line_coding_callback; - USB_SERIAL_SET_LINE_CODING_CALLBACK set_line_coding_callback; - enum USB_SERIAL_API_MODE mode; -}; - -int usb_serial_open(const struct USB_SERIAL_CFG_T *cfg); - -int usb_serial_reopen(USB_SERIAL_BREAK_CALLBACK break_handler); - -void usb_serial_close(void); - -int usb_serial_ready(void); - -int usb_serial_connected(void); - -void usb_serial_init_xfer(void); - -void usb_serial_cancel_recv(void); - -int usb_serial_flush_recv_buffer(void); - -int usb_serial_recv(uint8_t *buf, uint32_t size); - -int usb_serial_direct_recv(uint8_t *dma_buf, uint32_t size, uint32_t expect, uint32_t *recv, - USB_SERIAL_XFER_CALLBACK callback); - -void usb_serial_cancel_send(void); - -int usb_serial_send(const uint8_t *buf, uint32_t size); - -int usb_serial_direct_send(const uint8_t *dma_buf, uint32_t size, USB_SERIAL_XFER_CALLBACK callback); - -int usb_serial_send_break(void); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/platform/drivers/usb/usb_dev/inc/usb_descriptor.h b/platform/drivers/usb/usb_dev/inc/usb_descriptor.h deleted file mode 100644 index a5ee527..0000000 --- a/platform/drivers/usb/usb_dev/inc/usb_descriptor.h +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_DESCRIPTOR_H__ -#define __USB_DESCRIPTOR_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Standard requests */ -#define GET_STATUS (0) -#define CLEAR_FEATURE (1) -#define SET_FEATURE (3) -#define SET_ADDRESS (5) -#define GET_DESCRIPTOR (6) -#define SET_DESCRIPTOR (7) -#define GET_CONFIGURATION (8) -#define SET_CONFIGURATION (9) -#define GET_INTERFACE (10) -#define SET_INTERFACE (11) - -/* bmRequestType.direction */ -#define HOST_TO_DEVICE (0) -#define DEVICE_TO_HOST (1) - -/* bmRequestType.type*/ -#define STANDARD_TYPE (0) -#define CLASS_TYPE (1) -#define VENDOR_TYPE (2) -#define RESERVED_TYPE (3) - -/* bmRequestType.recipient */ -#define DEVICE_RECIPIENT (0) -#define INTERFACE_RECIPIENT (1) -#define ENDPOINT_RECIPIENT (2) -#define OTHER_RECIPIENT (3) - -/* Descriptors */ -#define DESCRIPTOR_TYPE(wValue) (wValue >> 8) -#define DESCRIPTOR_INDEX(wValue) (wValue & 0xff) - -/* Device status */ -#define DEVICE_STATUS_SELF_POWERED (1U<<0) -#define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1) - -/* Endpoint status */ -#define ENDPOINT_STATUS_HALT (1U<<0) - -/* Standard feature selectors */ -#define DEVICE_REMOTE_WAKEUP (1) -#define ENDPOINT_HALT (0) -#define TEST_MODE (2) - -/* Test mode selectors */ -#define TEST_MODE_TEST_J (1) -#define TEST_MODE_TEST_K (2) -#define TEST_MODE_TEST_SE0_NAK (3) -#define TEST_MODE_TEST_PACKET (4) -#define TEST_MODE_FORCE_ENABLE (5) - -/* Standard descriptor types */ -#define DEVICE_DESCRIPTOR (1) -#define CONFIGURATION_DESCRIPTOR (2) -#define STRING_DESCRIPTOR (3) -#define INTERFACE_DESCRIPTOR (4) -#define ENDPOINT_DESCRIPTOR (5) -#define QUALIFIER_DESCRIPTOR (6) -#define BOS_DESCRIPTOR (0xF) - -/* Standard descriptor lengths */ -#define DEVICE_DESCRIPTOR_LENGTH (0x12) -#define CONFIGURATION_DESCRIPTOR_LENGTH (0x09) -#define INTERFACE_DESCRIPTOR_LENGTH (0x09) -#define ENDPOINT_DESCRIPTOR_LENGTH (0x07) -#define QUALIFIER_DESCRIPTOR_LENGTH (0x0A) -#define BOS_DESCRIPTOR_LENGTH (0x05) - -/*string offset*/ -#define STRING_OFFSET_LANGID (0) -#define STRING_OFFSET_IMANUFACTURER (1) -#define STRING_OFFSET_IPRODUCT (2) -#define STRING_OFFSET_ISERIAL (3) -#define STRING_OFFSET_ICONFIGURATION (4) -#define STRING_OFFSET_IINTERFACE (5) - -/* USB Specification Release Number */ -#define USB_VERSION_2_0 (0x0200) -#define USB_VERSION_1_1 (0x0101) - -/* Least/Most significant byte of short integer */ -#define LSB(n) ((n)&0xff) -#define MSB(n) (((n)&0xff00)>>8) - -#define LSB0(n) ((n) & 0xFF) -#define LSB1(n) (((n) >> 8) & 0xFF) -#define LSB2(n) (((n) >> 16) & 0xFF) -#define LSB3(n) (((n) >> 24) & 0xFF) - -/* Convert physical endpoint number to descriptor endpoint number */ -#define PHY_TO_DESC(endpoint, dir) (((endpoint) & 0xF) | ((dir == EP_OUT) ? 0 : 0x80)) - -/* bmAttributes in configuration descriptor */ -/* C_RESERVED must always be set */ -#define C_RESERVED (1U<<7) -#define C_SELF_POWERED (1U<<6) -#define C_REMOTE_WAKEUP (1U<<5) - -/* bMaxPower in configuration descriptor */ -#define C_POWER(mA) ((mA)/2) - -/* bmAttributes in endpoint descriptor */ -#define E_CONTROL (0x00) -#define E_ISOCHRONOUS (0x01) -#define E_BULK (0x02) -#define E_INTERRUPT (0x03) - -/* For isochronous endpoints only: */ -#define E_NO_SYNCHRONIZATION (0x00) -#define E_ASYNCHRONOUS (0x04) -#define E_ADAPTIVE (0x08) -#define E_SYNCHRONOUS (0x0C) -#define E_DATA (0x00) -#define E_FEEDBACK (0x10) -#define E_IMPLICIT_FEEDBACK (0x20) - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/platform/drivers/usb/usb_dev/inc/usb_dev_desc.h b/platform/drivers/usb/usb_dev/inc/usb_dev_desc.h deleted file mode 100644 index 7cfd428..0000000 --- a/platform/drivers/usb/usb_dev/inc/usb_dev_desc.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_DEV_DESC_H__ -#define __USB_DEV_DESC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" - -#ifdef USB_AUDIO_32BIT -#if defined(USB_AUDIO_192K) && !defined(USB_HIGH_SPEED) -#error "192K 32BIT stream can run on USB_HIGH_SPEED only" -#endif -#if defined(USB_AUDIO_176_4K) && !defined(USB_HIGH_SPEED) -#error "176.4K 32BIT stream can run on USB_HIGH_SPEED only" -#endif -#elif defined(USB_AUDIO_24BIT) -#if defined(USB_AUDIO_192K) && !defined(USB_HIGH_SPEED) -#error "192K 24BIT stream can run on USB_HIGH_SPEED only" -#endif -#if defined(USB_AUDIO_176_4K) && !defined(USB_HIGH_SPEED) -#error "176.4K 24BIT stream can run on USB_HIGH_SPEED only" -#endif -#endif - -#if defined(USB_AUDIO_384K) && !(defined(USB_HIGH_SPEED) && defined(USB_AUDIO_UAC2)) -#error "384K stream can run on USB_HIGH_SPEED and USB_AUDIO_UAC2 only" -#endif -#if defined(USB_AUDIO_352_8K) && !(defined(USB_HIGH_SPEED) && defined(USB_AUDIO_UAC2)) -#error "352.8K stream can run on USB_HIGH_SPEED and USB_AUDIO_UAC2 only" -#endif - -#if defined(USB_AUDIO_UAC2) && !defined(USB_HIGH_SPEED) -#error "USB_AUDIO_UAC2 should run on USB_HIGH_SPEED" -#endif - -const uint8_t *cdc_dev_desc(uint8_t type); - -const uint8_t *cdc_string_desc(uint8_t index); - -const uint8_t *uaud_dev_desc(uint8_t type); - -const uint8_t *uaud_string_desc(uint8_t index); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/platform/drivers/usb/usb_dev/lib/libusbdev.a b/platform/drivers/usb/usb_dev/lib/libusbdev.a deleted file mode 100644 index 316c44fd962355402b4dce9b77c6b1833d2833e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189600 zcmdSC34D~*)jxjkJo8LuGBe2}laQUvWPw1)WFZiiumuQY!V=6K5P^<78eNJt)o2?ya;u3f*eBaWtP#iorNgBz|~zpi`Dx=lym zH+E=YmUpe+7{`NXC4M5hbImHCyO(!t?pW6yM}7)$tW)^q>sFi|FVDs^*R90h&@Qfp zLatlC;q(=2*PPX{eASxOs|VGp;>L~*YgVis(6&|H&=J$Wg&9ynjKnsEO|gF6x{j6I z9a^0ha?QFm-OGDccWj97ZS~qs8#|RbmbY(OJ*aZ!ighbH)(#je)}3WgtGsFrOdMxt zTL|4cWnjH^D6nb#oUE>` zt_4QFtE$G1MQQx#x;ji(JZ;J6&z#dJrNq?Kj}&EMpd`fIi&V+1Rn=wUR&k4v&DmXD zv%~>~nvEQug>b3RnsuAu5UWCJl7&`pfG364cC0(4yK_RQbdw@Kw0H9C$<5#1EjrCB z=N}RxyHk`+>CI@I5S=(T*cs`3{qV;JpU4)YCiU((EDk>Mfk<7@`}*OR4%(&qUbOQ4 z5_PX1?mhS#($O^V4MR$p4@$WA#!78{{2KmFp%(&oI*)Ao$) zG_Dp!-#wfzo_$Ad{_f$lsoy;u2+2ESX#1?3=G;#6#uKKN^~q4u?nC?MACf6o92Rf9 zez+~x^UwPRN;1`VVE&9q@4kLYkTjcbrGWq7HE!?U zKMGtJJS3f>Z^OR8-143q_oOxlqIs7Fnu1%h9a9fU;ci0@MNTz7_nz{ei4Qp+YTq|* zKl_ozH{XVuG5gpwV=p4~>qa4}DvKaMd@0w=&g_x7pW}-RUUWQmlKut@pNm*X*Pw(RrgJ=GA^{9t>78%6iTuR*c(Q z1aHh}{CrP18g2|+x_wr>yakY~c)Hn_AI-6(&F#x=&h5#4$b_b3Xxx5Ll&h@zNxvBR zW*^(Wn&f?9!#;m=YBcB4;HBSbNa=0g_ktSHTm9~4kA;1vPn18^o3Z7Ieo_A4NZ&t( z+_dwWRXvlcdP=KmdqSAcc6LL@w^X*Kha)20td8!`%1!VXEKc2LPAc6L+PvN(?_3I+ zNs}gpj+@pxuW8<_38BT)7S9MRnK^I9{MJzG%mrWHOQ`$It`4h5MiKA_&n7FxbaYjP z)^F+#oiS%{e7U~)vfX)|N#DoZG>o&2Lv4=GNM~bFZ|k0^BU^h#=qk+hB+T`xhqAYN zFxQPkg@!Euuuq<2jQD%sw6k3!-tT+tvWB+g%d(SY+5Wy)?~~;}due0y#-@TxH_j{CTJD&BNE*%}Z`+tHE82>>e$qef@`kg; z)reEoYny&?nd9ek%U9!dT!TILj?lUT;e6sr9trLuqQ$A_G_w~0Ohf!6bcT{#hNkyBiW{QETb;%2ZKR&q zFG`&s_>5=YagO=P;p`UY?N`ncW#@lfd9NB_dGf0+HHzWz*DpUQxp(E|qWmAdh5h>v zXIGgw*nIxGzwK;UHnMjsTBhGy9v#(Gy45WA9SAmh8=XaEjVqx|SO4(npD!CeFS92v zd32Yk_-$Y5{BfO}yNoo?^p5K+iba*j`wOBWOU8HqY7~bsvcDoN-5O{t?t1gDY?b}B zv3w3E$T6O>W8mY_yR5?Dy=l#9bFw?r=BCe2pU1w_XQxL+adDf`mNqASc6nEEm(i6r zm-)1wiCv?+%C{76F}mbKhxZ4&_P>32D%u=4c6^HOGd|C`&7j}4w_;vJG}2@=IvaI_ zr3~dw<HJN<2zBkB|M8aASNc6oxsBc}FCHVV6<++_g7`7o zc@^)vS7VV2tytTw*Se~`7w$G2eU0KOqcJa<-=uxG^q~j-dC{S%9%Faaep%t{lcVxq z79o}#760rDHj5(T1CKP`_)fz|y}`q>@|uRv`ce^<^E$&rvk%B{T9ufeLk{&AReor4L)6aPj0>h@zER<9}9Y? zj!Z&yTw?8n&h2yU?%KZyRuSdPdc_Am$JEa7Wj{F_2t50aBjmV!J7#NtpPr*{_3Ie= zdY{4gCtmFZdz9h?6cIF;9p=T)m_vg#zzZ)#hKG68CW0)+j zM1=Y|qNOZ9&^JChzDZnL-l#QhR@6l&_SQ9LbdJ4m=$1$JjERcyeV++Y^O<9cF~fN8 z`HlPDTbb(kgRD*+@nPSpV&il9QPSvCc*y;qfAGOBX!^ST?8a^VtIn3AuIl^fKJoo< zw6tk}dvWt8_l@W+h8>2$3jMvI#%lO-sPP=NdJeVv6{BA1&2JJ#d(dhO*|h)duBjpJ zM+VL9#p_O6xBiTEA)FAnqr>)2o#@nLc9eDPo!IPbEbHYCqU9mZr*X=AhKs-(P!ERQe|+*RFnFbGFh-Ib?gP?|1!7U+8lyn%>^G2I>3jRNaareW-oKSDsxe z-Z?aDesjz0p`Dk+&MzX;g!9SltuGxGU73xp_mVtfWK-{KB}FG{YHzyXu&9#dp1v8) zIX%@69W0vNm^I^I3H2}D5G7NZpG3>N&W9VWIPgi1D8{M6QQbKIkRi4oKus0t>M$pb z#yj_bQ$UWuuHc%wzN#iqj~L-Qa4;+oDUGXeo@v3^rV3{oA@8_y)-Y=xPsNGGwR`{D zhra##;oEl=%?6JUPB*^xnZCv?IIU##y^Ir6C3c)?Jqz{>ZOZIQ?yT7}qS1wzozcuu z4edNwcUQj%KhvK&CJ zH}oi8Ydb<4Fj4gJ^w8cJb1&TOY!qdSdK>0Vj}Bi`*VZualr>px4bdMXKW$z=^3$Tj zPpxY^<!DG=H1eH(`DstvaP0VvOW?GZj zR^HhB$(9-&*>rw1u)18_$-3`1H1w^&Uar0`GFzw>&)GP2&nWC_immlG)M#MGDjP>A zZI(4>xBb1paCTNxb~L+rR9p63XPd7rqbp@nWe< ziSH1Kr5l9^?9GT~==l02MztjX4j$evAWr1&$#0`|F2xx$u-^xa7>Uz(iN=bukFi1+ zSRn#xKgm3)-;VXq9&LN5ORlf52V&^73zS8S#w1uIvvG9HA`jCdb84EMpSwQ1ANpVP z{5`ZtMYQ+U&&}GmJkIxKIQPDHQAUG0_u_uUos1C-hrDMgJJ2!?#=5OVz>TzQqcKCH zg>C6QLz{=rmLuH<4q|Kt(Sqh7Z3S&bjrns$i4*qXoy{oAUR4i0h`9DUj9j-j8Z%r z*l6>%1>4eQr!}QVdG=swV%zAp^0xo^8H3|@@AXIh13rnH3^!(4vN{QPnz^fJ-{;=% zQoEFY_L>TVsBuJ0Vyw^sLI}*6y~WXzCi}!v)La}jK6id}A7*$R=ko>WhoplyQbWPl zxF0tzojV$a{5Bt}bK1k}54i>B0CpUmckLO1_bm^wV$FqLj>NTfq!lj@- zhp7Ffz8plvJ!4IGXJ~`EPF$|96PI_aThWeSOio>UFW7A~mPW-@&PG4>^~FuLmx;2` zy^OE$co*;LhDL*z{@|hFcb(4s=8P?QJvTm-*PM6hEe&RGZZyxj3oPn&Ax1fHGRdDF zR8*q;z21yD{%CPehIMaOjD6sHy=iI(*01)8Z}pqe6!;lua+iu>l;P!s_+{HDKDF=f z@_}rfxo~Fdl9@ADzjV*;e{MN+@Pk5e@V=BXXLH$sl+eP%Ay~)3+whowE}1{4VsVQQ zOlQnLZXVmV%$at4Ma#6s3uofaeEPI`74v2;T?D+!x3tb&!u+E7XeC7Bw1tZ*8jn+b zw$41RX&!RmwS4a4MQF`@)AX6kr_Uup>&zKV({S-Hd;a|9iiO8DEt)=C%x#)Jh<5I@ zCeU!*jQb82S04BdqwCeZu>M+tJ_g!t{OT`WN78axh-)ABkt>0A(048f!4Fm|SDzv_ zS@|{HtA&=0v>Vp1CBddHZUYA4SFOOMHqo)R7FnDeiC@H6Qg`6XSFTvQwtdCQ(}eIi z-V{zLcGY;CkW^xgO)il_&Jzyl@Rc~EbO?um8h?ok80PSJN(=*}4gm@$GZuyEjH7TN zZwe2X3ou~@4>Cz5(!eJeFPJ+V0lDR2;W01tALLh=q*A;{3NqaW0$6RFgWDK`+JGs= z@PyMKf6)SwWL{(#f}=8h9(j|zSZ0b+xk+x5D8IAS;dvME>{gd&FJK?wr-1tb4*>oI zcy6o9^m#_*On=?UK(NeBlyLcE03ejLuEu_;)I9!P^~M`Ur-4(SR&)5bv< z&MePvRw(ycqV5U;RhNA-Q4TYl3Dip_P~&sHrBF!=vVnRTFLQ48ML;>7<{EsyHHP?r zS`aQJmD_AZ$>C1=7=1dNrhug(#;dRZZ7y6H>7$Ss`RLJ=9mFVv$uMQCLVvDMu$72j zB2G>Rq9mh(h&PG&C0?#k!5$_b5^+)%a#b1MLEbdzl(k@*Bsr#}YS(CB+*80rxKF`b zilkAwvFfp|R#yKZmDT%(sOs-QVypE;*MG6P7Go9eUwcvQeii=XaL=To+#}G;=`Mw8 zO*ctgB55wFt;RE5_ptGwRpT#RiuZMJ6{|YxdY08cg=&TSXUIabOpL^;p6?34H0~@_ zJp??Y``gr^`*Nz#{cUvWbf1q})4dOZx!l#rCkc;C+Ga-4GWk)oNxC+TN|mM|lEXkI zU8lys#h@NL34lWs^+tbC8K=EjsaQQ`27 zgGQ5fsDjgX9Xb9$6_n^Rcf^c_bwx2TqG z-wPOK(ygkH?88hGNk7Wrh=OW^!Y3{9kD;6+GfJ&@1fZ4763cLat3 z?{|(O*+jeusSS8BUY0{=e&-Lt$T%ISq&pS0@dRbNE6@g%-?K(i=<8%aRDsFyH87<|%C0zXz%KfycjASo^ag)p{p$oB*uSCvn*@)cInCsOIe zaD2E-(!GJdDvI~eBBjALu zmW2mY!Rdo)MbchXaQj@e=}$ws=)~u{pM?htXQL4C{SDrh^iaVf6f%6dV3YK-0xBZg zH^Yy@!zCPazV9UJ`jKLeFXY?6aX%U+pAz5aoDc`Xzd&J}Fw>BvaiA=xmqIG1NaK*6 zA1EU<9Y?<=%J9S1?xLLckoP-3z&rRH0-GV=+@4V>KjPq*V7_`bsC>qs5xbI4mRaPS z>Ga%YOaiANKY`qy+kGj_uO#&yLE=SPGhTC%Q<50MFU_q>E55e53L5 z+-c^a!YPcs=)!ZC!DhyV%-@^$I^@c7`khMR#gN!LBo11;;nOE37qdd6ujd-Y%F}Q!==3wRKe-n0PT4vs)F0+f$wZ0~U{4$|p63(dSsJr$^N`?kQry~l@Upl~VlMRsYEP#{=*{m$tq>a(g$qHvs1gz_Q-WY0L{BgNOGF-3eIHYrOkW6Y^f~eh+E(@-E@MAzcw?FW(@% zH)_jfFF!+gcc{GEcOLcp0}q!~7#3Rc{!kTCvX{577T%p{QE&?Qe!>CmQf;z*F1pOk z>7%i*=L@q31o{7V3eo26mTn>oBweRRDsoW}<}l8c-ZO!97CcOKpDQz1au-Zu_vgx? zEcptiQ&Z;mf5yGxIKQNb+A zd6UcvfO2WU6iRlp=CTY1#K~Bg)SvgK7;C3@uX`&}WyO7QR{Uw46(5YZ;zRLP{8_ve zAC9-;Bk@)|psncJ%Q5^SnI0bUT~48YS+Enmm-rrK;faE$P$=`2AxwFn_WuoqQNBBA zt!F$*7)Dk0@=fi+`y16yEef!}b4uoV6ySQjs?({yI@F2n((QlY6FS1SETFLQn;HLGZTkw~M8Yzuq5f)4%8ACc05rW|w}H==BA&)M9l zivb$6{s=WHo^z0Demiuz!Y;$Nub`_H%G}AEP&?ooK5wyfZv;hwiq54njRjF~HGONC z_E%@YwV?D4*S_UOU-US?lZ^B4hyJp?Q>6P>Wa6gPrpj~{M8Pml@@cx{DyU@8ZIJ2T zLY1%JR4R0)Ecqcy0g*=Ji)dsCoa1*`xM5&jKf=tekWwvZD(q<>= zI(I=2B|TYYuo?GDTx|0Hi3TlL8{EGpv*W3Q4m}w}K|bYJEtO@R1q)d^MVEX9w{bL` zx|C6{lm4(qGs!P-U=Qs*RSQv4@F7Qfnx-r(=w=UVb*ZZ0Nsjw;T^d)=i+!tioi0r+ zIE6gd>(XqI#`W_x$f&fCB!Xqoir-0$-%0HR7+RFof%uz3pAWR($u-dL)Elj0;0sH@ z$@{b{VstLdV4u%eg+uTY@2{q!1~gCD)i)VKZ96pxW{2xbGlCjE7P5UQ0{WC!uXR!8h2|CqNN%e zI=C5mzi{V#0X|6|!-%?rlw8-lf{mBYOrk{WK#CnvVzsJ0qZxHhxFB%jxR|@|0N&#skA)!F{Wg~ak@P+X<)GK5Omcld*2PK{wP@^ce~P@*JrPXZ z?smKb?shN=xwnDoRQCz!cuV*pG!ioWd-N|H;R6_=aEAX3y$N^Ng|Uc0_-QZ`q42E~ zdTRJlCR>Epi!_kZ;+_j%Ri}uQ1sU8AKdw-vA zCK{$J_T7&re%~r+IAw_{qzIEE@wP!EU&`_BZ-Xwo>$Gl>azcoCtG5&5&MYa*^qB?D z$5WH>3n)HidEk0b`<*-S4%~}Z>Mt>#RGJm4W`AvghZV(Rr09!L=xzTZ$dIx^Q5aPm zM0>_Niu&((tMPncw-Cnnp`w(Pfn<1#-x2yzo zHGFq)0Be-g!q>nyr&{*e34NuUrgZ7{jbdS~(xuNg0`8V_dj5C8EZ}<@9+9%HfNIR} zJx2!XbE&ax-$Hbm(v{1jd%iD1(|>E|Fc5@%V=z%tHWW}zCB9y$J!NAShg;^`%r@P{ z9N8#gUWLSX1`?)bsdcO9K2*!I9a*WsefeeaU%*tJ>ln_H6pxug6jL^NzN3)BStv>< zw>Ux+(Lzy9xz$lXK`j)el@~Y)D6WN~%<@7QAKlw>E}_dX0hkiv-le6jvDW z<7|VHrICPo7oFqgD4yzFy1y#{^&=`MDFHQ!R30NZ6<q&)+v_n}v%jTT|vhJ5jQ zdPYz35LRfqVQ<0l9UsVS70}TJiwE2y9o8GZ40%*VXdLvZp5p0n8^=d7w+IxPg;0I5 ztonLGm~36P67+JLAL>EupcQuHVhJ1mTkHma9>#6!7*v%4Mx)*~o7K+%Q#A#=%2X4+6|XtqRnBecSqjg^M&9L5Yk~PHScptQ-Djx#6re^- zLZ@gW;iZ1xpV4OxM@+O!y}6oW)M~&fAoBr6bHF5Vt2gw>K|h1WYP_5iVSpa)MaW3O zcWk(7v^Og}&oT09zgYtj)o5!tTGkorjbN5I;@ea+zGEY`)6`HFd0S| z3n+e@*68tPlR^)00)D8E71ZzNB%SyPY{Q2xi$xlMs_c3<+~FKFr7|X$>rth!7 zCvN%cVDd%x=ptj>o`}?oohjO-C_lrF9#^MV5O-@EVsB9jg?z$21z$SyM>wwYCb?B z%Pk&-Pt~9Vhh)#w{hqhcxOO&B&(ns=Z^kKtgCv;cH|xM>z;9S*s1KS)_{{{>jBnMS z3j18Y<|+J3WH;WQaX;9p^^0gjya6;Kc?DAy&c6fsFSCbA8dEW_hI#{9tD)`!$q!>g zU81_+J2q53lr5^_F#De5_kUpzMXg?}Gt@LnSiM%MCVZ5@p+Eenir~Dp>-vN}T zJcK5(^`D}E&rq!Y=peTK^V_i2A5*2j_tE}cKy3YYix6qB{-b3D^GbpE8$0nO=qzWU zw@Kx5aTxjAv*Dv<$m)L z5Dd5z>zqQr(NBCB(q71S%$>$mq4XYlMs$(2@xeuoMqrWE)|98}ltHl3rRJx$aH6MS z%1@n=jhu&*e-RWQZ}r6{KYrZ+LoEr}lmAvqM6sCg1V`uqh7TLfxD+jh(~~x z>OF+Hr+fwfM&tU+QNbSZhAH(75wsP@c|W^XCG?hq)5A3uO! z;5dV!*s&RJ8l?6U(0mG-G5K1ZHgFnB~Ws=H)eyi$_A8K2jJaaWrK?$;Z}gQ z!EUdz!9gHyBU0I5w^!L<1J?6)fVRPXUS)%~fcPUo+u(k$Qg;x`q934b@PI~61)?4h zQ}^sLn5iRdt9pp7>N(~2L&(c1zL*LUnd=+65M)hnT4+PG5nbv{o<+(l6eZul3R&z; z6Ep8dj>f7|#+rlaL`p_yhrrL^g>?Fc{1`lEktfkk_4bhg_%@Lmip3LPSL9j#7;rBD z;}AW>Ieh*hz|=pF*V!1?X#gc6X`Es=Y2HsxZlEDQLRS=LEXBdv+z^rAgN8(o5n~!q z9Av+`7NGpFX_Y2(oC)GqM##Dz)MTS(zQq78vp_jTtHXUz)N#|!>UHtex;3h6>rqXo z5z+ndLiv5Kx?Yg<&*pCj6sD5r_0ol`-saUeKXcY{ns3qWBP10q*3kq5f$BGAYd5uL;c_cxC= z+bf`GK7$m0^HlN26{WnJl7IIomiSt^Aq@cIr)J{9T8e4oWAiCA-&1vygHm2 z1#dXDEhn$5l&bJ_5&3Lc$K^ zbINqEF~n?2cef|+L$s+s8R%QUl;6cFSQ9x77=GD%3=ru-!Q>^IMFfq9hoEsG(-?_{^?8!Ty zgw?3(0MQCSWHJihM&?35>)(s;u}C%Qgb4B^kEcEvPIwpUehjGpH|qP4c@_W#e2E^n zDDo{Nzr~YwEBU8^<)@(dh*V1AOOSC0zMUk$)06!y2`O(HJ7@L#q3?I(`O<&pxPkeV+1`t+RSNomNm_&?77N$&+>#0uu=3}Fp{TQ z^)$GyKh;yJ>%WhMST3>Z>8*O2F41#GPt&D(&WPxxFpZ2@#NUq*N8;ynl_oBI5h|0_ zdJdIdnt?)%E{N!j*(g2d)}etW)qOta9zPHo`rIlsl&V<&Ten&#N;BZ2@_Dxk4Qf7e z1Fz>}OQ|~ez2#1Slj9aqFE?YYRwtWbMBPcNd%{2`i>yu*-^Fo!2W|pdO7~Dh7rR5` zF<~Ws$0#px=Q8@2-prbByK~QB&6-uX^Ky^pryQ;;G_&8ys2$zSIQ0ip5BE_@QtVck zB8u9)kdg2Y=2#Zgpnd}qD`=}b8kUvKy~1Sk=v6MXc*0_sHWD_)9|99If;@`PfZNKa z%-k?)G@l7;pl?%!SAG4-D#g-+pIjk7>^_=gn`Q|f>XK3J$RCART0vpAnPK|N3=Cx| zV8lea)pe%&B6A859YoHfKCUyfDFuJcat>h7h|0;b2=!8ABR0#OX3Cf7zdi!=bs+yf zpn^4#3Bd3x*iQkGStz`U%*!k+LP0`l|7KwY3Kb}f05q;cVJ6tA>8FCB>aS7tH;(=7 zGSk+TTm4b-a{(2sQT<(r()j?@-z~`8!~*+!1{waSN%iN!oHGErzd5=;o?%2CoKDT| z8_Yj%z|EYETXqVWAa2(efp8VAb(YVqFKfIW;L@; zG-r^_Ts5;!G#7DZ>E2GVJa)VZlx#Fj>V!`{K<@BV;8!U8=b}(m%2v~0k}-f0x3hk> zmgv8L_zpmfe-Zk|56K2`nIGeltGVn4@tzo$e9eWyB#E{iKZ;8Ehcm|I0VT^l5nGmj zIEPV|F(9r0=>5f~PBr&70I?RJuT>8_m1awnw4dq1K{Z_lqK~>p7|JfhxFoz?rf&ke zQr8GX8-fQPUc)d|*9be&!4CjOzlaQ@wYo)k03`PTj(HKOuVLC%CrjCPrfFV`*6IpC zUBj>r-!Uja{PDj5Xes!1uraS;#=s8-*3V;42{GyQ6g2*;69G<$*#NoYnMzw>Z)+VX z6}<|qj%`XsK9D-ZlZ=b+JAEgiQmKe&r|1QmDq^Zs^c2SZgsmddxYYd#_Z_%xnSs_y zMSlbdKaOb?VFkmm_*TOj_|8(KD&A(_A3Dw3(Rx5dtix|n2dju^mkNW5mr@bsh;1Cw454mGXwXLxi<1{uO*dsL7MX6tL`u?jbL1R6Z z#+WLNeFQapa7>MDMr)-pH;!8_fYun}o1}PyHP)&s_?t@kXQ%lJS`TQ9b%xkY0pgu% zm}U#}0!^}*HBBRbfx}6S;qs16@O?)g^B1EbMn5t7c z4+@jY9nYHvxqToA1Q?)pTm$+=_zPfGjo|4r3{~U-bd=ietYc)D2SgMw{EallWG0bk z0kIaK!^I6cT=2KbF9Y;VO*NW&<$;pkv7o;$z96iPDHMO7S2U z>b*|iB{i1Wi8cf;W;jupDzl#ho;?5+OGsm?^MW-|PDg8H_8lO(0iey^f{av01ZAp$ ziE^i^;Gc@f=bUCAS`V0=b@(9Z8f5lmstMmQvzPOd>1KuDkJsg|oH-ezu_o|RY!8IE z7f`_(bu-q)n+H;xqJ`AF6%)J|S95J18Y<5@%1)iDEN;a3y#rTbj&q&rE8cBr$&0h~ zx+Ry=1?CxIvnbNHW@8?=SSz*(kxnhUykZfP`XQs76hCMGRcqUMiniWUAo(RgMZ2TU z-8L$6y3^N;rg71Zmx44RQ)R^Wz=a(uBOVd$YS3C4(Ti&q58ywVyIa`z9H)6LS`QeJ z6UY#|D8PR@cOL|K$(^_rn*-|H5W2JS}W5w zgQN+dP1}f!RPz`^kN?5Ic2yCeX~#LuZ=v;oX<3KO#$eOZ;!^OfcyS@C<2?cwvb(_G zKc8IPXn6@*@^0~2-7;Zv>Dxz&LEitcdFvS#0@~i#s!Pm$7N@K_CBu=N#yn|pikqi{ zxrp(T`k>`+|Bjk6{< zzj^3|dDeHaM!~V6Qoctr_YcFY!=6Zu`W-!*_=~xL?SVQ@@M@@*(QP&|b!EtKK?|ZQ zjMF*+;1UUVE>`L%3~yi)QOoWYfpYO`WOybKx&xjuzYNLA}5O)Gp@EW)?YvTB58Y%c8MeZ{^wI^5|)}4wBP5ZJI*1l!|mZmk5 zw>->ztti$1N@qWY%gkO9^eTOy1GtG&_qAvrbEAosJU&54i zZp|~6U4TO>pKAbe$IyCgIj#YUzj*sAp#CNlQlUUE;3N{ml=`LvS3fVIhiZ~nlkBAD zt!mgq$bXrokFfeLKt@bV`mx|p1rRe&#)}h|hksvnH~#FnDpH0mHH44-X2T0fR1iz> zuK|y>W(<6D=4Q=~lSqFK7t45c&u2HZEqCw(L;dAI{TI4F0}#0mh3Xuvf`G`aD4c=J zCP3pJ6i$8=ud!$z0-OOsmLC9u*Yo9MOz|=0uqg0Dz)3c9{ut(RKm}_W*+U~aN67ID z;PH=2iOIamY(s0Q-i({_Q%~9(R6FmEC*|T&A0S$J4aum5AKI~_e|hrie+1MrRJH&r zh>hF_%wCl41w;;@(2vZUEc_aU>O6QcVBy;+>>~X;$g~4<0-%i-BL~Sl+cSOhB#_?@ zMD>k)eGjh+)-zuzYtPu3fzq}))j!JLe zhRqcr>DT5;9I^z#H(tv26_}8Oq+gls(}v)(2axoXt33tLf{^sIt33}g5RzUuSB*mN zgq4p%(*)m1GPPqRg1|P!pa6PB03sy)(QJPO6PS?nnydXUhy#Sws`U29&RGM0%&RvGa`51;LD81eRJif^d zF!g%XjAQCJ&CF(rpGhY}QPaSAKNqN}3#2Khh~$0Hnwj3x01+M+ZbflWpP zO2=TpnHo)#>8`2S*EJ|r4#&TCVAVAR9a%qZfNzw=(OI~(PHAOSBG!8xWUTN?{`GOBR#e;lRvtk{l~xsiLb0SMV5*u|o5121 z4Y4Nim7|Y>C9B%YF2En`LPBg!kj1oMcI@TAId~-Tjix**jLBd#oZH?(_K%9kMSeGugD82)0ng!b?#;)>E02~!05)JUOl21{;R3ANGKa$*X_#D~vWuBK0MInd zy{0ReWW&&j9phi#!D@+MuZR{7@LULldeB4(d~6CKIUs@*am_9P;?lv$^NvIcNhBez zIZCkydj}4Z33nlS0Lo|I=B9?Ic;LqeqK%#6W`!A|B*))h=_h6{Ew*R3m<>;mXTRz(-ll?_N|Kj23^5q7l7vu?pSNh-9wL;;kP27dh$3$2F7c$2fzKLec@X6UHWoX2S82K?@W9%2gZG zt{j|dBQIcb8$hd`xwiqZB9l*I70i9EE11~q7sRv)qt`4HkN!$+}Bq{ju@yLRZun){+#uzl?|e}rvZ6rn8^%)Ry}jA z0DRXtxRV*Wmaby%Zh#bv9!2to$}V666tPTPD!YIQKQQT*%vIJ&aFCbWn$|s-a$aGg7*!o zeG8MjRCeLNkZ_k1|z2&r43aLh;dy?_aOWP=59eJ_abd%@0uz8A#zy;WY7f!zu{dMDEm7&}DG5i=K6 zu_uHa9EwSe$}VDZg37iqX;axnOuAIIg~_i}b`cYX2ykGceo{Ixk?08)ppvU%5x^m; zcCrsn0OpzcRK9vA)8ANlroXlDOiy-bdj9B-9kDIg#2)^T^l1QOc>~EIosCr|WVWDm z1puoJ6Ar^6x&!Q2`zM~x!n;;kNtG}EV z3z<;fgn9}-4}h+iP~L=kB9`cSCX_#+K0$7)(11SI0T3&hP}+RGP$_E;45UWi?5pwc zUuHuCCLCHuT!W3mCbTCp2q~C0{(^WJ*thnSB?A;o;wj?ulRrx%%)UC5FI65y>KDI!Q& zAHYgeTT)!}X{meFr=@wHidZD@ptcCWo?KejvEJ-5s?-xt>k!jobj;f{lw5z@UxgfJ zBXS1j$L0;2kI@JpZ@)_CX4ag9#T&L@g%QsO%ypR9xaTpy>_eY>kSnr5(v?0KNPQ zq~EjhNYtZmBB+MAbx26MEFli5uZhwXav|RO;qSE71~6`I)07#gh(n5_QCdupWGm_x zCj3~2hD-u*_qc;3FzV5)7ckKj$BcRQ9YE_4&@KbuW`+q>Ld~`AWbRsB!Q@8(+*0DL zvcE>E>6p`<#jbWpq#v6l7U$c5*$sf&RQI8Cu6q55kJ+J#z~Q1dVb z6K?smxtU|6Lj{vlV-?J8))h=H23Y>W>r{3j6G{t$eMlZx*%l^GsO&-} z6cYq^tB1xWTmay>2m7S03)?5}0}aPLn9kOPO$QS7=--#mKt9ehg=_$V5RX*!_G_G~ zY+<4Ys^TPvMHRK|WR7zY8ep;vV~86SFzUG)?`r{|V!~ApR7~#HSSDn3l(y-bf(a$i z-6E6laGqdW$HXQYI9vniaLCC>8UY?0n2ay+>iOMcwGSYI+mYvK+w7Qw>j#Yq4J*)%Z zNdbfaT(c-ttCeTEMCGe@G93nT(vUUzF%Pu$P%ZRV2xX%Z)00vBx{-Yhnz-SxM?K`P z9gf{s8!{UJa9Jj|0(e5V88gogz5uxCqQyA*#6}@y8}O?EaUQQ0C!qMSY99cO$Yj7I zHh)x*{WlQY1i5BRZqzAxeU+|VY@kHp=sY+s>%*IB$ll{nEOM+qHCCGth`5JqAN$5y zZFh~VZRNOcE2M!%#Fc>eRf8pL@K2p(!WG+vc#Yq|C^uP+GH#Di6aUCZP&x?UXqmnM z!2D$LBES&ek~^7UyagWb_(zTf*9ibNXF5;y(#oU-V2BNJCo}vHm&fg>D62y;a>m&C zteo3QOVET*n|kXHc+Bpy%D>hO)G>#sw=DcMR?2z7XOvFV4I8s-Ej%M2pKP7PQm!g| z+SFSsGQPaS!q2wS2dtElgO8m)sf+6KoRvKy;Sf0I2S3DX-_kXt$pDadqeiKB4c=od zT${q^7jZUBh{F%gQu_e_b!6))o`&_dJ%}F`2P2Vhi-Xn3-yR3|AWzS+;Wgy#hkWez zb~~Fsp6)Er*>E%R1olB%>YcRNmc5XT(X!1YL|BjA)^2a((~+@(OM?ASuUtu|0vJv0 zhd3K(3;UUej15bXUuS_`zY3X7z?MO9Da!GHqIw3?+cb842$>?l<$zxSG93Eu5n1)L z;JpNJ0$`cK=+_n`)Qf#Br?CSUZ-<~un-}jW?1vHPPJn&aV&jSH1-t=ZTl=A}4gt`o zA^_@a0)RT33}^uK0PKfd(bsYT`G6t-Y3!#F8S3PAz&(K7fcpUSfwutmb22iA03QPw zx9!Mj*RTGXddl=w?H@t?qkw~e_5l~avGu{R!~ZA8CPIKMa{N z0Q-%HW7XUEMr3SYyVVxh^~;bs8E|JD&_}6n8>n;piKn;e;_G`rcoyIsz=lat-DmQjkS5=;}awVZ+#fH->)~#RHQPHuYeNDyqikhnG z@fF{ytvG$fsp~gXCe)I}+D)rEDogD)@Cg^_S z%19?sO5Mo9fGWEjYSu*%tzNNdZTIr-GrKxA0%zb)9yWHb!hhWi1t+#I`oHmu0**;* z*RMQHqhs_S0Xet;@4~^aqa(g$_l6ZKJ9OKX>o;^PUwL{hN)RLVpD{!+3BAM(2pG(z z`u0t0)^=B{SvOhD8~lR_CYr$wcVtM@44Qc^Y063m{)>Ck=@_W}z+kPh+l^XRFyz30 za1S}V?X5Wy%{+!TVoGCEC}f(h=3p?GV|svghmcg7xvr2oBy8pu;$32ws#q+OHDs=z6g@zl`J0Dd^6h>G&7n^U)anjWHZwrL}z&t6-Ed9&5H{Bw+KV# z8YE6v#Pl%D2sm3j11FntYOBi0|WOcGhhsf znD|R3M>pGVtj{ph&?*o@QfU?{2_{n&?6%p=074qS6wn_8G+ah|M5XnPj0EjppG(^W zGn|H5XxzUV1tV1=J71a(!z=OM)GIU|ci`XO&d6}me8%=HA`Rp1&XB9pCDG2|G9IMJ z=+SUZLS>%OE7*c{#_sb&pklT0ryQus8dMIb-OAWTR)}IxDg;T`ECGHb5D}D$OfO0% zjOj*7+d(Q%FvbH|k{Q{QBF}heHKq4RWEWF<V#vPCZ9@7@8G$BYm z@;S^Pt#m~ko&*hTgRhvDf*yp&e4T=>$(A9dq4!Vu#u|DJ)=+K_H^gwYgAY^242EFW zO8C1(akQC*)O3wi1K+Ep`i}*fiqsgx@@391N;L%8I#@D-yBE(y+Ww7(75XY)f;InzUJ;-pm`>o1SbX*B z`T@s)Kw(BD8Y4%|PUEwVdKEJh+nQByiCC;JQiK2T5rYS(Dwpy1ocML&ShNoO{TLKt zuf*Gem@)P6YOKGR;DQKUk6?LL$aD{bdW_tVnF^%ORi;wY_~bmUXU0A-f%J1PuyojL zG{97u)|{DyCgY3=2nMbxu;Pv9(~KErIaaj{&aEPw4wWBarGeAwuwQ8=qiK$D)wv-v zGtW#mK6Y@*g@HtGmt)DnQf?06ih$Uy7j6Wb@p`(@h%B(6h$A-*swOLqD2tMIpP_;$Qo6UR``K( zj#Y;8x1GFe zsA*<6Z#CGBhPBh(>E=Wi*8edfb7X}%qR1>OG)ES~#NnVh0t{3p>`F6p(0V9tTN zHI?J)M9OW}CWYeBVNi_FHbOIL z+=Y2;t^HjQ$C!jD(+e?hR*Dc{;O^8wjN5Zr=9>$(0-FR$m z$n+J5&Ac)*i1*MilA^Gg9yZ;^JuwRI9r5RGj3>byx)u)wMB1sY48vXT3Ze#EY7j`{ z1#pK${{)Qm1~3fCjNh(>qk?kpFvBz3*`wIYGH-@bHe0+K{DnCWZ^l7!ZPJVf>fSJ5XY1>Ziq9nHLg&Z zNjP&D=^Pv;yfK?&i81qJA+E$CuO9p$ej~vT%(4s363huO2ESATDsc}-dM1S(uH-RY zC6EDly%#m72eVE&^)w}#40B+scwocma*U~=ddQR~jcQFBo!#Hc`O&6&}2~jtq1Y_93Oz|22#y?~r!w}fG)~Yg%#oZLQ(yU1{ z)3{VY9j?(@o5SeW#xppY*sLg%(IMFA zC|l)7O&G@CzGmUf)C*^_v6?C?S6y`R7zYW}DKSGul_8a8cGw&;k-caKwu8FgRjuME z%b8dx6o=&;pBht7lu^Q7$Uef9)hn5@97qsUE`!?r#`8K-)AN8%2-PVDGzUx?BLu9@ zE-KZOstcJbLgt)^nI1AnVU|rq%_N*tLs2tlGWV%#T*zTr$u*17GF)U94~4YD5Q<7sU88*L`V|C+QAcUR=rtX5Yh9JcTHu3S*LlanzeabL>E@ zDsUN}o*PkzPf(R43j8ci@(>vP(`A11p9mZ_?nw&GAlu_3W|>w4RvTLj?0bfzfIj56 zH(xw(crsyn1eRj6u*mcbbxl_1dQaFa)K?c0nMx)>k#&P!UuG-q=8QJwJ2S31N1e$1H)d$0f zIZ;nTH5<8RPJ*+vQ$x!lR=1-~UuGt@XK}5=_OUXd^%OLp%q{-!Oo*#TLhrMVO$YKh)wNNZ>0LiD0c2q#Ps#?*GoIFmOYQdMz1fi*E7Hbs=PW<=CB zN6v@SQ-DjTFWlEqL24uL&Y7!C{~XnKE!ixvjwX)$1S9Ou;;u4wiNzcvSL`}VZ7iW2 zUS(lEE=9Il%|S*T?j*4OKy_2gEOAT1PK_s&chxQJl{gKx&)&S*~j~4_}UO&ft@MM)Zu2fapqDpb-L-V zGE+x^tjLNixYBatSc0gLWgNtLjPWPUxNMMga4w~*rx99XvYCMboDUDnsF|OSb|siX z8Mvn^M_yfo@gA(s*mLfc<`Cnr2wP@CxQuttjkxL^nF-$Uqa;*e8gSQ; zRbt9~(_IX)CShoqW)?zzA-4@#d>5M8aEL-PtBOl>R;8JTMZxH)=k}){Y~~xA5zxY< zp$MhcY!53V7Axn6#6{}vA|G2Qz0c!*)^wG*pa3vM61ngqo~3XV z%(DXL4$caygfk&aL-3EqBVjw0&N1D(%r~rnM7nrO3JX>vxxT;d;?z6ZLhE=h{ zhk8$hPZ{6QPM!hXrWbLO7r@RX55jR#&N4HYEwXlZdQYRPD1R7+f@z@P1mk^{1Y*5k#U*kWixf$*BI!gn z54z9(;v3Rmh--1&z+yYdeUNb$O0{q&1Uz#XQw*V&GyNp)jB<>BoF^f4CN@8Eh~@GO z?;PkFRp!+-^s5ech!w7>>PBNv5BUDa7d2mbqXEsmg)uT5BS!j-An##tt8raVWZ+f< z*AN&C7J1a+g80H7eWP(?TT|B35jyL^5cdJ}Y84NQ%s`=;UTkLM69*HcI|imy7p@^x z6!*AFGwlV+idT~)wjwxms=JZ9)sV3-hgKT?KHCND4(@!ANmrP(;|T zjIJ!6in9au2ul(0A$Fnhy>DbGDE_Oi+`o-}bR0yYF9@h%y_%ytnC;>oURUSwC?C5Y ze>%y!CjQ`z*fntit4YfIWErgsHV1#u?=L4Rm?Ln}#@- z|M*;)m1$h;_-cnQhu`C_Q29NSY5Dz*Gro!6e~mUjgEnJspJ}=MmNSlU`{&%2+rPg# zYJdC~)YfwQ)lsbN#;^V0Ydo-l>vb5D*mw$vEaPz?g4jb~VgC^4<1FL)4Y-@)$sGaG z`kJLSMQD`jLR7%KI0H=zXzL83JO~5|=Wz|g_aft2@Qwepd$e31yt2KA!3Dj+w{Mqh}v;hGL>}WTZ03xQ&j2alq(z)A&;c z?X6x=UUJmA^6BPpV%@L1^Zy|_`kKk|-G#QTTCVEJI|5@dFjsUPD+@+i={!m^6)h4D_rQ?PtD`roPU- zpN2eE^zvD!4qVpwaLObWS%0No5e{rVBBE{cSP|{E0VRDcKb~>aS{{p5dJ)HJZe}VA zJ$HnKpiCTTo`9%w7#w&bZkD9s#|9mDOUUsXKO>^#&jqk;K)ADd@E4izTW%G;nmbnI z2XO~2aW5Wn1QM2`8*mfHZ911U>}>uIX>S5wMUlSY*2xJWWCI~cfCynVEP=2J2ueZ{ z$PgAG2q@#pN)pIs7Fk3EML=Z~6-QJ?K^?_qTv2h<5l2QDMaOMi22@nU1wm9sQBm*v zR=<6gCeGh`Z~t=g^jG!OS8G>ScUO1$25^{;+hG2E%bYRSm415);sLS178(YG7^U#= z;Qf?#NbVrs{q_y>JVSo&*DUW^##7s0{=eFN6E_Wl_aj>ku{R=zV615Gq9xnsC%Aow zJ76g7?*7B}F(sd*w)A-a|K-EF+Yxmq9Qm;sD0JsWLz^Lp%DG3^CT4_vfP_0KUC{62 z(y@?8YnA1oRgBZ?ef4WkPLF?P{}rC1p~mZ+y9;Oy0)ihkT{a_$*a@md!nTP(%S9?tF6zP07u5q(HE|54l{ z_VX5D465Fb3tT*{8gw(Cx9NgvY#{QGq5qYsb#L3E&&DwOD>^W?@$0 zteJuQsR8Uw%r$`k=JFI*mqRxYIIp<6xjZx_Cs0{c7HBMQ3Y4FR$vmb4dsyV8xuzVd zjq?qCo#{s~P+d}7y3jzctgaz|b;ANdw?IRAaTz8fHJ4$p^t?c6T}^#;pt88Oth&6x z6jxVO)Yj0v)o5y{DQ;Y70*e}|n#v7QJZvaZ*04Ch748DXjirn*z?BFBrRO!#ab|Ae ztm%R2SraDb7MegsbzKQ2Dit@CFRp?~OguxpRdqHOjYwR8tEwOq6Pg={!n*0@4W*2I z*39fc)~uZTX@QBkg@H4t70jBFYii3EHw7B2mX@1>X%hnlxo74U1SZVLFU+5iRe&;R zszE|a8ylMHYDyY0Sqib5K&?$2{19hpnAr(=69a{2Q9*faMN_2-RF529Z1Z8uq_G%f zQXXiag*kb-GXfK)O_^R0$el4`+6*&kc47V$xaH?yR#kmngEL19v#qGTuzU$(Zh%2d z$uebCFxOO7S8Gsh&Gmu$g-xcWs`Sk8oWh6eXmOsG3DjW9ms@KnWt&%~ zXDa{1~drO zLv>wkMH(!aKvhkBGiIFCvydDsfrY`4^D$2i^W0d)&VdkYUk&9obxq}gMa2ut!?K!R znCE1bjlZlJ6~@AL^OuuVm^CAJ!kNL027S&76+%3$y1GtmBL3%VtvpgPd&V z9Ja-cjpeBEvgVq4)1>1d)K+0NXWERwl$jGlQ3h(N8cUH=wrbl7Sf8d5hgo@9T4`l* zg9(-_j^e<4WYC%D7ffu{^!&h-X*s!u`3X#$g@oI_!XBaaD2hCWn`^_Zm(^dy%6zOA4a<-+@CE85$ zkg(;~P_u&F=Qlq#ZdY10Gu>!+T_5@+4+SNCIwqJy5+j?KFC_n zpPDxfJ(21h^Kz?7%bgUtb49}}JMGgcr_$zz09qh>P`9w0#%}wnVEwShODoGu7orwy zZ{^gr?N!hj1hAkRPc&GLD>4I&WX74fIe{U=f7NFM>bbm@B^9V@I5(Kj=6bXpoWd%d z!@r@)oK-MAkdr?%E4v^Uy(SV}+}wyJ#)5K+SUr)g6rR|WR!)@-KW(5z;tYWH8I~lc zOxPLP?0Y&xr-#UzQ5YCDG&{dAta%iM*w%^y4aH$t2TW`?wK@e6RV>y*jAiFu3$(Y zCpUL`U}gdShuLrnb;7i%dHEBap#W=zO%A0Kj5$z0q7jpi(X|Kr9QN_Z6&G#@C7hLj z5-v0or_M^7FnV;FooSuM3FJdEhmJ@~Zz!)WFK#UFmv(m6j45_1`RI(2hT_`N%CrU? z5sm28(}tdM%81dUf1j37(^T19Qv#OOH;=>gWehGdYKB9e4|#t5dBZar>odxRjHF9- zU2#(ermK%bM_UGm;)c@7ahUae-YMl7H3R0?r)5;6WlS5ImVwFA<0@*Kk+zKawRIWj zQPJ^ZzoxvgvACi<1E(?!6vkyb-sOu+%jWbkiB^#2mB56%{xoHe#xNMs;0XeMTMPsHs|N&uWYb39D+X!<>H1!Eb25 zRQ$T;#*F&nrpm^Qvhs%V`S{hAmRrlU71f9eN4YILCZ^275GL45g?g|l)8IZkYjQ4zkwI@BXtg*A^Ek1mJ-0QoFL93pJ3L&B zLSS5`yuKE_h&#Y_LZNWkirwLH0QNAMy{a~#b4MV%s)7wTP*c2^hq;?7=UACF)j4s@ z&dTS&i{o54*g<<3x=7otFSmtUUMIF?FE4 zro5p7)whI&%_>5#y%0rMRef9sXwS;_unP{WLdROz7^DzGl;YY(lt|=2%{kB2R@Id> z8mIf#xBvrkr{fJ3vOU$J*jcQhivuLFg4ZUYXxW3FIW2zz>U7HSBPyppJ?c~PCj{6E zFfb^tsVTN~jJ>ezqSc~ynlV0Mm(RKj8wMU%+^7t6^FxQTo3Gb(M1Uho`#MJGiic-C zb?~+b&@&<{`Gr#gGZtstoN@?SQ5z}*_Inr~@KOs6j*ZY6N1?oejme&8q34`lp*^D< zrE9O$&}Hh1qPVoQxrUi2uHu+F>=>zQZgMXM!$x@SNRExtIV#VSmqjP0v z&+JZpsl-`rEOMt{oH2D-@e-$W%g^J{h5>|opidz3}! zzG^UHbuRR9&FAc($(IG#7nl-_eAQ4qn1ih~6dg(#0N#;TNVDxRp25@}kpb9Nk56 zZ3Tqp(o&p5(7JH(vWNxE8g&nAXJke*OjpGCme-U{9-O8gXsQdihY@0cX=`!`O|njP zK%i*`nrrQFNbe*$?G62}V=W?eXc-vyxr){GxGb+OFRu@jRW;fHH~km78FKq+Ta>}e z5nRnON35B^e2jiE^scI%Ux(D;sTGdE;FhX3=IaveKOXX2?kPH};a%rqk^ZG%z}TbmSZ-?AjV|$$^qo zlM5MlkF;6S&7yoexO0zNUJ6c~HZ{9o+JwpZQzsf{RAR3n?KMcaUQmfm&bA)*2!XQ3 zI^FFFwKjV@VZx-WsT0Fa$+-PdTQ+=@J^I)?h3>gH_dxPW?=jo0g(u0vuC@k***^a;t#B6xmbvyCWX5>wa#!3w2(@=!QJtA#C9EyzB z$vpcyXKrf%gD$mfj!Ai#+G0Ace+XcMq=a!jsX2o48)YJT0`^F_> zvcq-f5-YOOXXNJO67lc{_p~4qGdB1Az$zXW@UNJ&&X7 zE?tZRfZZ3`x7%AenYDv#r}o{BKTyN7vCWOWvyBcKH`8=$kmsXW1-Nvv-Jcyqhswe+ zY5NnW!*S!{?c|)?nYe8{y%4wRg6Dq}m%XFel8K?}w8AQp11#rU;x;1N;LGbh$3OZH zT%V#{;bI@1L&$=?tLi4oxxNUi?Lcu^nL$U7o4oe8a*jdg)`z_SGtTi6aoHVePtF}U zG|0+2bPcxcv(L0=KvYEJSU&Q66g`gh3Z46AwmaoPX73l<@kCW)8G3HCK-_mMt(sp|j*+YL2*jS%Tdofr70x-r zc};y0Mm|d`tIi#qoja3PwhM4&J9uJ#VQ_yjF1gOd1#EF`#*kr|Lo=#yW*A&k+MLn2 zD5I{rEMozDDyURaHyG!-!6mp~I&@fOW_^H~0o;hNw?jiMHn)%u5JIiT-YLeI-kV$} z_qIMz11MY^I2g&=(FDq~stLn0=S^;>kL6K?qb?^OpS74cVZxZSblx&4L{HP0h8OwM zvKngAa%)P;@n&~f+VqAx4)y998q+*)R;vc+vEus9ydSX5D|BF(x_QZ)DdZ1Y;B}mf;YC@R2IGb{B!@< z@oZ8=8uvMI1=BGQvb(LvPF7NallrWr6l5_WD?ZQupKJdcljbUe4@BlEJ1Ko;TvEHN z_;4NC56k!Dmyx6-xP`}?20PiIvY8&|C}qW8q`jQ@2z`D&COau@W$dM`SH-MuwI=#9 z|K%vtoTO1vv*VJ|viU*W@G|7*ay(_27B$@|#AN8Y8|yMFDfSZ9&#$?syUJj+*KSr) z+5&5KqWzy5rdx!4*j@?SC2=pK2$0ImFn@j?Cp#%+Wz40mRz?6^(KV&-X?fXGEK*ciTjG{w6tTJ1*Z_;hycJIpX*j3-|Ejg>raa zc3OMEwvLumW!uHs_@C|6t*xVQ8!XqXVfa_fFL4+jmh&{NPRY%fVqy|oPiYes7t=mE z+1Jt639rR>_I2@f^`-i{MfF6fMQ-5^(dMgP!hP|9hHw$zpRk{K2)gidJC^uvvh@!+ zhGL?dAK(6C_|V3WT!%J4J_{Wgf4u!n7UO5176pHXKNbuUzM>ZGCwjss+E3Fkd=Y+8 z@MU;@uEyCSWAo$7%8}^{E=OS1{V2`I5bdm8+Gl?m1%HPB!ZD8j?SgyU@tgLZ@a?tW zjq?e=DEKq{+F+>m!9DKyag;}?A!0etfDovV1z58{oy@?C+!C&+wD*b2fg{H?;XpS5Nx++2_#a$A{1& z?WfvLpV2G{$nxRGj6$2=bobcrZvF~y+Fy@f6#N-}8Gg>z z-QBVDn;stfJv{zBJ^npC{=Gf%_truj&bccJy`_zx39?&w@5%i2^@Q(hKS4(If%rwi zpW)N+bGE+jj-?+T0*fr4bdP^OkNtl3vvRbbhJR6}pACN`7>d1OX!Dx^9{U4Ap4jsv zm67o?)uGLg59dYJ{~&{}DA@YpIW`LZ44=aU*^M9C3vGV%`jPg-&jO5ph{ygAtDhXS zHzZ^Xdww&_qd&~i4{GrQ5!(D_ghzjbM}I^}8GC-L5)_%HPNPA;E{-=8Eooe+9gIcEs_qgLX<2?4TIC0qK$A|7B>+3YDzc;Ake89*R{bsyJ zf4nFD@vf>Rzil6BKile82DP$-d))EkgJ_ZZIaWVZN;w|=JnJ8F%nR*WdlNnOCR%;= z70x!%-LdqWe2;#<)ep7ue2@NQkN#wj{$!8-6i<4mc>Je&>`k@$8-rR?gL~ZZ<4hUZ zUP5P1$NvnEy)&$S8a?e6`Egu7)`N_+7g{=i>VA9(GSa`$bkniNF^Bg9+kPyp7^y$Y z^o!7+WmDn)^Wy`ck@{zv;Su_0x~i6btXdbTKiixxeVzinixK$E95Y4!gb#9L_&FZ? zb3OiZ%~=ul=X&(d^5~ys7t5iNQ$FDzl4Nc|1bD$fIB6(J%J+7n|o4 z-l^YWkA8{$v@0E{=EKJoBkQ-sqhIRrFE#JWzEl3C9{n=&hWs7-WuEY59{qBUf4Mmr zVZYp?Ki~WqVSm0S{Ctmog*kx*fz3%zg-5@_@zj4mKIj`+9+l?L3h(4M)H5@P-&A?@ zAxG#}dF(GRgCf$iz!QFfM}MIi6`{Y-qrcFjU+wX)HdztrsrKmCc=T)Ra%WU>@>}E4 zul4BHnzJM9*Lw8pJoG(Uuup>pI3T5 z`+?k05WhL!qkq1M(Jg~ytABn-8GC+Q*+k}dnMskpV?T7|!+?Hsfk*!W(?7!g1s?ks zdh{9{n{Q{Wa!@^f?mr*$*~{g80p49{tNq96L^IWAXFB zKYa6>D?IvFm`>79v-($rtD}9c_2@&Eeu33r>(Rf`qkp9tDg8LBf2BwNDv$nEX0r5o zSo+LW9{qJ5{dH!B^m|(UbsqhzJ@U04Idr8#55HZfCZyuG9}o|hZwv`mKQ!{Ehu^Na z8B+0^KZOMAzsUrYUV5;PI@cp#?2)ha$ai_X46_@uyD|RHJaXu9E2dlb)+NF2%$bbJDGJV0QCEjkr`>({ zI{Ti-vd2%`7=-z_O@lHOk~87l31QZjee@fd8$PAy^x4P<_IysPnO!y;oI7Oa)lmw* zVM8G_<%g0cm~q#c?BPDc54!M~C+B`a!+Dr*CwjPQR=_+gCNww>iNUYOz>7tiY| zk#Azyc}F&CPIHQw(h{7c5$Wnan@1toAi?=H!C59@)7)$!gz8zdb^r$DWC!Ps2JC6V zNyNJ}Exm{*H$=v{5h2OWyg(H&$B{FD!e6QxG-@>GW`(_G1D6p)y)Gk<(>Z0BS7+4m zF2{u$?a>*XnVA`BXLRPUAzqi^!@VveJt-WWIm#Pq$WX7&(9F>uJ41&KJ8nMgpwUBz zp7JX*U-ViYRE7*Y?hQP9fVk7F@H!%2hH>UfaL()?WNZZA4&r=XAoPx6_&n{3X1rf; z{GY9x>AcF7j z*!TBbm52#HuA@8IMf2ueXWPp}P7Jd1TwH%g&^P6A?M>;u1V)||V;h%#b%vU9ebgTuV?r>IwW4<_A zW_%mSO;|mgM0jq&dO^D1hRpPHscSMFgZa2KeP#@ad~+En)>j#c`r`A@s6JQ%g3Lg< zkiCp)B70ylYH|~v8{T4 z^YSRP<3h?0shyx**>-~VSwwe~V;PC~SpKZfY7+TmduRTeNTeeh?1p+u0$IN8$-yWW za<RA%#WG@N9#)o*9 zQN}^DoIC~fLE^jBYsmZ6evsdFl#yRnV-tK|S>*QSRv^>a`2l z4ehiY$Z{P{;`n9#vHccF=G~UKIX-haiTc<@PIQ*6qWvR~gU2Px?HFa$pJ6%>Uo?sM z?Qw~CZNG$eV2{gu9haNbFQFaSehKY}<<|}6#*O7!0LIPr+4d2K2Ox3qB1e%ZSFTmh z<17bcdz?h#h5~|`D6FrAF3m)}j`m5S5g<#pf1F1m-9_Xyv`-S3)RiRal}~$EKJ!Tg zK2PLTejEbdEE!oealiN3WxS}5s+?meyB#tAS z?sA_!PMJ?0r*XwPua^4kT(r3P&UuT+6Ow>Ba?Y=`-$WVhXfcU)w2VYMT27);R+4CM zYe-~zEs6HEjzqgcR&Bf5K%zaNs7yDsW4As=(Y>uRK45&~DI-5QB+4rRWPYrj_D;VX zwN%U3LT?N8P>x8t)qjA5@<0;p!rDi>url0bM!N!a8jExuli;Wlk(^l%CAKFGfuk!}NZKsTWYX=GW8j$@^8f6@Oy-9Y4 z3c*R@mbK>pijK`uT zpkJl`2=p)Hsm}6{_)3|Rk0~nWS*l0e*v+9{4`=z*s0p%%&f^5SgB?W-p-fbs&p_2g zO?28R{WIi`sI2~Yk;g6lXNtw*e6dMfBCZutRW{sa(bgmE+%I{nxLtfzMANb1z7g&5 z%k=vkcMKJ+KZanI!$oAt%JzK0^h(AdY26o!=ZcHO3&cyr%fxl!t>PB(e(@RcdGTd& zuee|QLi}1hD*h}+M>*+>6T680MUF>V{*%QyV!7BLUL@M_CG>BRY{!d`AD8@`_`0}P zwXI zwfLRrZ{?(;t=LB#BF+}e#0K#~@fz`F@g8x9_^SAxm=vS(6Vt^JVzxLj!t49@pQ3Xyg(Bx5a)>Jh-Kmev0hvx zUM5~8UMJopZWiwp{~|stJ}zz-pBG;i|1ItjKN3F|zZQQH6WTiE(^>2*4im?VGsPNl zsd%OMfcTpDp7@J+G6q;|uleFa@fz_K@m}$9@j3Bzaj$q#{6TDufe-B`i#^0aVwN~X zoF^_IaotrX`2zBOEJZAN9f|Szb&_u*F;3qi`B4(%@+Tz!lf?M_WyyO;jMqPq{3Uq@ zu45!eVZhAsdutNu??`@y>wU@TsB%eyYgmIwcspQqh%#>VAzJlvt$xY(L;#K0G zNR0DumHYs?-k3)uKTCdy`!JHZlt_KfEK1P0w%P@>hZNEg~Ix$&tPx4b^ zPL@1^d-$t%e3uuQn*^&~D1?vwl^iTf*WO5R7} zzRYKmzaw!GeoS&)GUVHgX-lFWP9ia=?I}5v++@rM$rH%CaNk1mnIx`L&X!z7K5tB| z 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⚠u~;k@ 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 E2TlwiasU7T diff --git a/platform/drivers/usb/usb_dev/uaud_cfg_flags.mk b/platform/drivers/usb/usb_dev/uaud_cfg_flags.mk deleted file mode 100644 index bb7d926..0000000 --- a/platform/drivers/usb/usb_dev/uaud_cfg_flags.mk +++ /dev/null @@ -1,110 +0,0 @@ - -UAUD_CFG_FLAGS := - -ifeq ($(USB_AUDIO_DYN_CFG),1) - -UAUD_CFG_FLAGS += -DUSB_AUDIO_DYN_CFG - -USB_AUDIO_32BIT ?= 1 -USB_AUDIO_24BIT ?= 1 -USB_AUDIO_16BIT ?= 1 - -USB_AUDIO_16K ?= 1 -USB_AUDIO_44_1K ?= 1 -USB_AUDIO_48K ?= 1 -USB_AUDIO_96K ?= 1 -ifeq ($(USB_HIGH_SPEED),1) -USB_AUDIO_176_4K ?= 1 -USB_AUDIO_192K ?= 1 -ifeq ($(USB_AUDIO_UAC2),1) -USB_AUDIO_352_8K ?= 1 -USB_AUDIO_384K ?= 1 -endif -endif - -else # USB_AUDIO_DYN_CFG != 1 - -ifeq ($(filter 1,$(USB_AUDIO_384K) $(USB_AUDIO_352_8K) $(USB_AUDIO_192K) $(USB_AUDIO_176_4K) \ - $(USB_AUDIO_96K) $(USB_AUDIO_44_1K) $(USB_AUDIO_16K)),) -USB_AUDIO_48K := 1 -endif - -ifeq ($(filter 1,$(USB_AUDIO_32BIT) $(USB_AUDIO_24BIT)),) -USB_AUDIO_16BIT := 1 -endif - -endif # USB_AUDIO_DYN_CFG != 1 - -ifeq ($(filter 1,$(USB_AUDIO_384K) $(USB_AUDIO_352_8K) $(USB_AUDIO_192K) $(USB_AUDIO_176_4K) \ - $(USB_AUDIO_96K) $(USB_AUDIO_48K) $(USB_AUDIO_44_1K) $(USB_AUDIO_16K)),) -$(error None of usb audio sample rates is enabled) -endif - -ifeq ($(USB_AUDIO_384K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_384K -endif -ifeq ($(USB_AUDIO_352_8K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_352_8K -endif -ifeq ($(USB_AUDIO_192K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_192K -endif -ifeq ($(USB_AUDIO_176_4K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_176_4K -endif -ifeq ($(USB_AUDIO_96K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_96K -endif -ifeq ($(USB_AUDIO_48K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_48K -endif -ifeq ($(USB_AUDIO_44_1K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_44_1K -endif -ifeq ($(USB_AUDIO_16K),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_16K -endif - -ifeq ($(filter 1,$(USB_AUDIO_32BIT) $(USB_AUDIO_24BIT) $(USB_AUDIO_16BIT)),) -$(error None of USB_AUDIO_32BIT/USB_AUDIO_24BIT/USB_AUDIO_16BIT is enabled) -endif - -ifeq ($(USB_AUDIO_32BIT),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_32BIT -endif -ifeq ($(USB_AUDIO_24BIT),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_24BIT -endif -ifeq ($(USB_AUDIO_16BIT),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_16BIT -endif - -ifeq ($(filter 1,$(USB_AUDIO_SEND_32BIT) $(USB_AUDIO_SEND_24BIT)),) -USB_AUDIO_SEND_16BIT := 1 -ifneq ($(USB_AUDIO_SEND_16BIT),1) -$(error None of USB_AUDIO_SEND_32BIT/USB_AUDIO_SEND_24BIT/USB_AUDIO_SEND_16BIT is enabled) -endif -endif - -ifeq ($(USB_AUDIO_SEND_32BIT),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_32BIT -endif -ifeq ($(USB_AUDIO_SEND_24BIT),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_24BIT -endif -ifeq ($(USB_AUDIO_SEND_16BIT),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_16BIT -endif - -ifneq ($(USB_AUDIO_SEND_CHAN),) -UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_CHAN=$(USB_AUDIO_SEND_CHAN) -endif - -ifeq ($(USB_AUDIO_UAC2),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_UAC2 -endif - -ifeq ($(USB_AUDIO_MULTIFUNC),1) -UAUD_CFG_FLAGS += -DUSB_AUDIO_MULTIFUNC -endif - diff --git a/platform/drivers/usb/usb_host/Makefile b/platform/drivers/usb/usb_host/Makefile deleted file mode 100644 index d361ecd..0000000 --- a/platform/drivers/usb/usb_host/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -src_obj := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) -src_obj := $(src_obj:.c=.o) -src_obj := $(src_obj:.cpp=.o) -src_obj := $(src_obj:.S=.o) - -libusbhost-y := $(src_obj) - -obj-y := libusbhost.a - -ccflags-y := -Iplatform-Iplatform/drivers/usb/usb_host/inc -Iplatform/drivers/ana - -ifeq ($(USB_WAKEUP_OPEN),1) -CFLAGS_USBHost.o += -DUSB_WAKEUP_OPEN -endif - -ifeq ($(USB_WAKEUP_RESET),1) -CFLAGS_USBHost.o += -DUSB_WAKEUP_RESET -endif diff --git a/platform/drivers/usb/usb_host/inc/USBHost.h b/platform/drivers/usb/usb_host/inc/USBHost.h deleted file mode 100644 index 36b9f24..0000000 --- a/platform/drivers/usb/usb_host/inc/USBHost.h +++ /dev/null @@ -1,193 +0,0 @@ - -/* -Copyright (c) 2010 Peter Barrett - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef USBHOST_H -#define USBHOST_H - -#include "plat_types.h" - -#define ENDPOINT_CONTROL 0 -#define ENDPOINT_ISOCRONOUS 1 -#define ENDPOINT_BULK 2 -#define ENDPOINT_INTERRUPT 3 - -#define DESCRIPTOR_TYPE_DEVICE 1 -#define DESCRIPTOR_TYPE_CONFIGURATION 2 -#define DESCRIPTOR_TYPE_STRING 3 -#define DESCRIPTOR_TYPE_INTERFACE 4 -#define DESCRIPTOR_TYPE_ENDPOINT 5 - -#define DESCRIPTOR_TYPE_HID 0x21 -#define DESCRIPTOR_TYPE_REPORT 0x22 -#define DESCRIPTOR_TYPE_PHYSICAL 0x23 -#define DESCRIPTOR_TYPE_HUB 0x29 - -enum USB_CLASS_CODE -{ - CLASS_DEVICE, - CLASS_AUDIO, - CLASS_COMM_AND_CDC_CONTROL, - CLASS_HID, - CLASS_PHYSICAL = 0x05, - CLASS_STILL_IMAGING, - CLASS_PRINTER, - CLASS_MASS_STORAGE, - CLASS_HUB, - CLASS_CDC_DATA, - CLASS_SMART_CARD, - CLASS_CONTENT_SECURITY = 0x0D, - CLASS_VIDEO = 0x0E, - CLASS_DIAGNOSTIC_DEVICE = 0xDC, - CLASS_WIRELESS_CONTROLLER = 0xE0, - CLASS_MISCELLANEOUS = 0xEF, - CLASS_APP_SPECIFIC = 0xFE, - CLASS_VENDOR_SPECIFIC = 0xFF -}; - -#define DEVICE_TO_HOST 0x80 -#define HOST_TO_DEVICE 0x00 -#define REQUEST_TYPE_CLASS 0x20 -#define RECIPIENT_DEVICE 0x00 -#define RECIPIENT_INTERFACE 0x01 -#define RECIPIENT_ENDPOINT 0x02 -#define RECIPIENT_OTHER 0x03 - -#define GET_STATUS 0 -#define CLEAR_FEATURE 1 -#define SET_FEATURE 3 -#define SET_ADDRESS 5 -#define GET_DESCRIPTOR 6 -#define SET_DESCRIPTOR 7 -#define GET_CONFIGURATION 8 -#define SET_CONFIGURATION 9 -#define GET_INTERFACE 10 -#define SET_INTERFACE 11 -#define SYNCH_FRAME 11 - -// -5 is nak -/* -0010 ACK Handshake -1010 NAK Handshake -1110 STALL Handshake -0110 NYET (No Response Yet) -*/ - -#define IO_PENDING -100 -#define ERR_ENDPOINT_NONE_LEFT -101 -#define ERR_ENDPOINT_NOT_FOUND -102 -#define ERR_DEVICE_NOT_FOUND -103 -#define ERR_DEVICE_NONE_LEFT -104 -#define ERR_HUB_INIT_FAILED -105 -#define ERR_INTERFACE_NOT_FOUND -106 - -typedef struct -{ - u8 bLength; - u8 bDescriptorType; - u16 bcdUSB; - u8 bDeviceClass; - u8 bDeviceSubClass; - u8 bDeviceProtocol; - u8 bMaxPacketSize; - u16 idVendor; - u16 idProduct; - u16 bcdDevice; // version - u8 iManufacturer; - u8 iProduct; - u8 iSerialNumber; - u8 bNumConfigurations; -} DeviceDescriptor; // 16 bytes - -typedef struct -{ - u8 bLength; - u8 bDescriptorType; - u16 wTotalLength; - u8 bNumInterfaces; - u8 bConfigurationValue; // Value to use as an argument to select this configuration - u8 iConfiguration; // Index of String Descriptor describing this configuration - u8 bmAttributes; // Bitmap D7 Reserved, set to 1. (USB 1.0 Bus Powered),D6 Self Powered,D5 Remote Wakeup,D4..0 = 0 - u8 bMaxPower; // Maximum Power Consumption in 2mA units -} ConfigurationDescriptor; - -typedef struct -{ - u8 bLength; - u8 bDescriptorType; - u8 bInterfaceNumber; - u8 bAlternateSetting; - u8 bNumEndpoints; - u8 bInterfaceClass; - u8 bInterfaceSubClass; - u8 bInterfaceProtocol; - u8 iInterface; // Index of String Descriptor Describing this interface -} InterfaceDescriptor; - -typedef struct -{ - u8 bLength; - u8 bDescriptorType; - u8 bEndpointAddress; // Bits 0:3 endpoint, Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints) - u8 bmAttributes; // Bits 0:1 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt - u16 wMaxPacketSize; - u8 bInterval; // Interval for polling endpoint data transfers. -} EndpointDescriptor; - -typedef struct { - u8 bLength; - u8 bDescriptorType; - u16 bcdHID; - u8 bCountryCode; - u8 bNumDescriptors; - u8 bDescriptorType2; - u16 wDescriptorLength; -} HIDDescriptor; - -//============================================================================ -//============================================================================ - - -void USBInit(); -void USBLoop(); -u8* USBGetBuffer(u32* len); - -// Optional callback for transfers, called at interrupt time -typedef void (*USBCallback)(int device, int endpoint, int status, u8* data, int len, void* userData); - -// Transfers -int USBControlTransfer(int device, int request_type, int request, int value, int index, u8* data, int length, USBCallback callback = 0, void* userData = 0); -int USBInterruptTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0); -int USBBulkTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0); - -// Standard Device methods -int GetDescriptor(int device, int descType, int descIndex, u8* data, int length); -int GetString(int device, int index, char* dst, int length); -int SetAddress(int device, int new_addr); -int SetConfiguration(int device, int configNum); -int SetInterface(int device, int ifNum, int altNum); - -// Implemented to notify app of the arrival of a device -void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc, u8 *itfDescEnd); -void OnUnloadDevice(int device); - -#endif diff --git a/platform/drivers/usb/usb_host/inc/usb_tester.h b/platform/drivers/usb/usb_host/inc/usb_tester.h deleted file mode 100644 index f89d50c..0000000 --- a/platform/drivers/usb/usb_host/inc/usb_tester.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef USB_TESTER_H -#define USB_TESTER_H - -#include "FATFileSystem.h" -#include - - -class USBFileSystem : public FATFileSystem -{ - -public: - USBFileSystem(); - - void SetDevice(int device); - - int GetDevice(void); - - virtual int disk_initialize(); - - virtual int disk_write(const uint8_t * buffer, uint64_t sector, uint8_t count); - - virtual int disk_read(uint8_t * buffer, uint64_t sector, uint8_t count); - - virtual uint64_t disk_sectors(); - -protected: - int _device; - u32 _blockSize; - u32 _blockCount; - -}; - - -#endif diff --git a/platform/hal/Makefile b/platform/hal/Makefile index 2f69682..c46fa66 100644 --- a/platform/hal/Makefile +++ b/platform/hal/Makefile @@ -357,7 +357,6 @@ ifneq ($(DEBUG_PORT),) CFLAGS_hal_uart.o += -DDEBUG_PORT=$(DEBUG_PORT) endif -CFLAGS_hal_usb.o += -Iplatform/drivers/usb/usb_dev/inc -Iutils/hwtimer_list ifeq ($(USB_ISO),1) CFLAGS_hal_usb.o += -DUSB_ISO diff --git a/platform/hal/hal_usb.c b/platform/hal/hal_usb.c deleted file mode 100644 index d4bcdc5..0000000 --- a/platform/hal/hal_usb.c +++ /dev/null @@ -1,2725 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifdef CHIP_HAS_USB - -#include "hal_usb.h" -#include "cmsis_nvic.h" -#include "hal_chipid.h" -#include "hal_cmu.h" -#include "hal_sysfreq.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hwtimer_list.h" -#include "plat_addr_map.h" -#include "pmu.h" -#include "reg_usb.h" -#include "string.h" -#include "usb_descriptor.h" -#ifdef CHIP_HAS_USBPHY -#include "usbphy.h" -#endif - -// TODO List: -// 1) Thread-safe issue (race condition) - -// Hardware configuration: -// GHWCFG1 = 0x00000000 -// GHWCFG2 = 0x228a5512 -// GHWCFG3 = 0x03f404e8 -// GHWCFG4 = 0x16108020 - -#define USB_TRACE(n, mask, str, ...) \ - { \ - if (usb_trmask & (1 << mask)) { \ - TRACE(n, str, ##__VA_ARGS__); \ - } \ - } -#define USB_FUNC_ENTRY_TRACE(mask) \ - { \ - if (usb_trmask & (1 << mask)) { \ - FUNC_ENTRY_TRACE(); \ - } \ - } - -#ifndef CHIP_BEST1000 -#define CHIP_HAS_USBIF -#endif - -#ifdef USB_HIGH_SPEED -#ifndef USB_ISO_INTERVAL -#define USB_ISO_INTERVAL 8 // ANY value larger than 1 -#endif -#if (USB_ISO_INTERVAL <= 1) -#error "Invalid USB_ISO_INTERVAL" -#endif -#else -#undef USB_ISO_INTERVAL -#define USB_ISO_INTERVAL 1 -#endif - -#ifdef SIMU_UAUD_MAX_PKT -// SEND/RECV with mps = USB_MAX_PACKET_SIZE_ISO -#define USB_FIFO_MPS_ISO_RECV USB_FIFO_MPS_ISO_SEND -#else -#ifdef USB_HIGH_SPEED -// 384K sample rate, 32 bits, 2 channels = 3072 bytes/ms -#define USB_FIFO_MPS_ISO_RECV 1200 -#else -// 192K sample rate, 16 bits, 2 channels = 768 bytes/ms -#define USB_FIFO_MPS_ISO_RECV USB_FIFO_MPS_ISO_SEND -#endif -#endif - -#define PIN_CHECK_ENABLE_INTERVAL MS_TO_TICKS(1) -#define PIN_CHECK_WAIT_RESUME_INTERVAL MS_TO_TICKS(30) -#define LPM_CHECK_INTERVAL MS_TO_TICKS(100) //(US_TO_TICKS(8 + 50) + 2) - -#define USB_SYS_FREQ HAL_CMU_FREQ_52M - -enum DEVICE_STATE { - ATTACHED, - POWERED, - DEFAULT, - ADDRESS, - CONFIGURED, -}; - -struct EPN_OUT_TRANSFER { - uint8_t *data; - uint32_t length; - bool enabled; -}; - -struct EPN_IN_TRANSFER { - const uint8_t *data; - uint32_t length; - uint16_t pkt_cnt; - bool zero_len_pkt; - bool enabled; -}; - -enum DATA_PID_T { - DATA_PID_DATA0 = 0, - DATA_PID_DATA1 = 2, - DATA_PID_DATA2 = 1, - DATA_PID_MDATA = 3, -}; - -enum USB_SLEEP_T { - USB_SLEEP_NONE, - USB_SLEEP_SUSPEND, - USB_SLEEP_L1, -}; - -static const uint32_t usb_trmask = (1 << 0); //(1 << 2) | (1 << 6) | (1 << 8); - -static struct USBC_T *const usbc = (struct USBC_T *)USB_BASE; -#ifdef CHIP_HAS_USBIF -static struct USBIF_T *const usbif = (struct USBIF_T *)(USB_BASE + 0x00040000); -#endif - -static uint16_t fifo_addr; - -static uint32_t ep0_out_buffer[USB_MAX_PACKET_SIZE_CTRL / 4]; -static uint32_t ep0_in_buffer[USB_MAX_PACKET_SIZE_CTRL / 4]; - -static struct EPN_OUT_TRANSFER epn_out_transfer[EPNUM - 1]; -static struct EPN_IN_TRANSFER epn_in_transfer[EPNUM - 1]; -#ifdef USB_HIGH_SPEED -static uint8_t epn_in_mc[EPNUM - 1]; -#endif - -static struct EP0_TRANSFER ep0_transfer; - -static struct HAL_USB_CALLBACKS callbacks; - -static volatile enum DEVICE_STATE device_state = ATTACHED; -static uint8_t device_cfg = 0; -static uint8_t currentAlternate; -static uint16_t currentInterface; - -static enum USB_SLEEP_T device_sleep_status; -static uint8_t device_pwr_wkup_status; -static uint8_t device_test_mode; - -#if defined(USB_SUSPEND) && (defined(PMU_USB_PIN_CHECK) || defined(USB_LPM)) -#ifdef USB_LPM -static bool lpm_entry; -#endif -static bool usbdev_timer_active; -static HWTIMER_ID usbdev_timer; - -static void hal_usb_stop_usbdev_timer(void); -#endif - -static void hal_usb_irq_handler(void); - -static void hal_usb_init_ep0_transfer(void) { - ep0_transfer.stage = NONE_STAGE; - ep0_transfer.data = NULL; - ep0_transfer.length = 0; - ep0_transfer.trx_len = 0; -} - -static void hal_usb_init_epn_transfer(void) { - memset(&epn_out_transfer[0], 0, sizeof(epn_out_transfer)); - memset(&epn_in_transfer[0], 0, sizeof(epn_in_transfer)); -} - -static void get_setup_packet(uint8_t *data, struct SETUP_PACKET *packet) { - packet->bmRequestType.direction = (data[0] & 0x80) >> 7; - packet->bmRequestType.type = (data[0] & 0x60) >> 5; - packet->bmRequestType.recipient = data[0] & 0x1f; - packet->bRequest = data[1]; - packet->wValue = (data[2] | data[3] << 8); - packet->wIndex = (data[4] | data[5] << 8); - packet->wLength = (data[6] | data[7] << 8); -} - -static void reset_epn_out_transfer(uint8_t ep) { - bool enabled; - - enabled = epn_out_transfer[ep - 1].enabled; - - // Clear epn_out_transfer[] before invoking the callback, - // so that ep can be restarted in the callback - memset(&epn_out_transfer[ep - 1], 0, sizeof(epn_out_transfer[0])); - - if (enabled && callbacks.epn_recv_compl[ep - 1]) { - callbacks.epn_recv_compl[ep - 1](NULL, 0, XFER_COMPL_ERROR); - } -} - -static void reset_epn_in_transfer(uint8_t ep) { - bool enabled; - - enabled = epn_in_transfer[ep - 1].enabled; - - // Clear epn_in_transfer[] before invoking the callback, - // so that ep can be restarted in the callback - memset(&epn_in_transfer[ep - 1], 0, sizeof(epn_in_transfer[0])); - - if (enabled && callbacks.epn_send_compl[ep - 1]) { - callbacks.epn_send_compl[ep - 1](NULL, 0, XFER_COMPL_ERROR); - } -} - -static uint32_t get_ep_type(enum EP_DIR dir, uint8_t ep) { - uint32_t type; - - if (ep == 0) { - return E_CONTROL; - } - - if (dir == EP_OUT) { - type = GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPTYPE); - } else { - type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); - } - - return type; -} - -static void _set_global_out_nak(void) { - uint32_t start; - uint32_t sts; - uint32_t ep; - - usbc->DCTL |= USBC_SGOUTNAK; - - start = hal_sys_timer_get(); - while (((usbc->GINTSTS & USBC_GOUTNAKEFF) == 0) && - (hal_sys_timer_get() - start < MS_TO_TICKS(5))) { - if (hal_sys_timer_get() - start >= US_TO_TICKS(60)) { - if ((usbc->GRSTCTL & USBC_DMAREQ) == 0) { - break; - } - } - } - - if (usbc->GINTSTS & USBC_GOUTNAKEFF) { - return; - } - - start = hal_sys_timer_get(); - while ((usbc->GINTSTS & USBC_RXFLVL) && - (hal_sys_timer_get() - start < MS_TO_TICKS(5))) { - sts = usbc->GRXSTSP; - - ep = GET_BITFIELD(sts, USBC_EPNUM); - ASSERT(ep == 0, - "Global OUT NAK: Only ep0 packets can be dropped: ep=%u sts=0x%08X", - ep, sts); - - // NOTE: - // Global OUT NAK pattern cannot be read out from GRXSTSP -- consumed by - // controller automatically when poping? - - hal_sys_timer_delay(US_TO_TICKS(60)); - if (usbc->GINTSTS & USBC_GOUTNAKEFF) { - return; - } - } - - ASSERT((usbc->GINTSTS & USBC_GOUTNAKEFF), - "Global OUT NAK: Failed to recover"); -} - -static void _disable_out_ep(uint8_t ep, uint32_t set, uint32_t clr) { - volatile uint32_t *ctrl; - volatile uint32_t *intr; - uint32_t doepctl; - - if (ep >= EPNUM) { - return; - } - - if (ep == 0) { - ctrl = &usbc->DOEPCTL0; - intr = &usbc->DOEPINT0; - } else { - ctrl = &usbc->DOEPnCONFIG[ep - 1].DOEPCTL; - intr = &usbc->DOEPnCONFIG[ep - 1].DOEPINT; - } - - doepctl = *ctrl; - - if ((doepctl & (USBC_EPENA | USBC_USBACTEP)) == 0) { - goto _exit; - } - if ((doepctl & (USBC_EPENA | USBC_NAKSTS)) == USBC_NAKSTS && - set == USBC_SNAK && clr == 0) { - goto _exit; - } - - _set_global_out_nak(); - - *ctrl |= USBC_SNAK | USBC_USBACTEP | set; - - if (clr) { - *ctrl &= ~clr; - } - - // EP0 out cannot be disabled, but stalled - if (ep != 0) { - if (doepctl & USBC_EPENA) { - *intr = USBC_EPDISBLD; - *ctrl |= USBC_EPDIS; - while ((*intr & USBC_EPDISBLD) == 0) - ; - } - - if ((doepctl & USBC_USBACTEP) == 0) { - *ctrl &= ~USBC_USBACTEP; - } - } - - usbc->DCTL |= USBC_CGOUTNAK; - -_exit: - if (ep > 0) { - reset_epn_out_transfer(ep); - } -} - -static void _disable_in_ep(uint8_t ep, uint32_t set, uint32_t clr) { - volatile uint32_t *ctrl; - volatile uint32_t *intr; - uint32_t diepctl; - - if (ep >= EPNUM) { - return; - } - - if (ep == 0) { - ctrl = &usbc->DIEPCTL0; - intr = &usbc->DIEPINT0; - } else { - ctrl = &usbc->DIEPnCONFIG[ep - 1].DIEPCTL; - intr = &usbc->DIEPnCONFIG[ep - 1].DIEPINT; - } - - diepctl = *ctrl; - - if ((diepctl & (USBC_EPENA | USBC_USBACTEP)) == 0) { - goto _exit; - } - if ((diepctl & (USBC_EPENA | USBC_NAKSTS)) == USBC_NAKSTS && - set == USBC_SNAK && clr == 0) { - goto _exit; - } - - *intr = USBC_INEPNAKEFF; - *ctrl |= USBC_SNAK | USBC_USBACTEP | set; - if ((diepctl & USBC_EPENA) && (diepctl & USBC_NAKSTS) == 0) { - while ((*intr & USBC_INEPNAKEFF) == 0) - ; - *intr = USBC_INEPNAKEFF; - } - - if (clr) { - *ctrl &= ~clr; - } - - if (diepctl & USBC_EPENA) { - *intr = USBC_EPDISBLD; - *ctrl |= USBC_EPDIS; - while ((*intr & USBC_EPDISBLD) == 0) - ; - } - - usbc->GRSTCTL = USBC_TXFNUM(ep) | USBC_TXFFLSH; - while ((usbc->GRSTCTL & USBC_TXFFLSH) != 0) - ; - - if ((diepctl & USBC_USBACTEP) == 0) { - *ctrl &= ~USBC_USBACTEP; - } - -_exit: - if (ep > 0) { - reset_epn_in_transfer(ep); - } -} - -void hal_usb_disable_ep(enum EP_DIR dir, uint8_t ep) { - USB_TRACE(3, 14, "%s: %d ep%d", __FUNCTION__, dir, ep); - - if (dir == EP_OUT) { - _disable_out_ep(ep, USBC_SNAK, 0); - } else { - _disable_in_ep(ep, USBC_SNAK, 0); - } -} - -void hal_usb_stall_ep(enum EP_DIR dir, uint8_t ep) { - uint32_t set; - uint32_t clr; - - USB_TRACE(3, 13, "%s: %d ep%d", __FUNCTION__, dir, ep); - - set = USBC_STALL; - clr = 0; - - if (dir == EP_OUT) { - _disable_out_ep(ep, set, clr); - } else { - _disable_in_ep(ep, set, clr); - } -} - -void hal_usb_unstall_ep(enum EP_DIR dir, uint8_t ep) { - uint32_t set; - uint32_t clr; - uint8_t type; - - USB_TRACE(3, 12, "%s: %d ep%d", __FUNCTION__, dir, ep); - - set = USBC_SNAK; - clr = USBC_STALL; - - type = get_ep_type(dir, ep); - if (type == E_INTERRUPT || type == E_BULK) { - set |= USBC_SETD0PID; - } - - if (hal_usb_get_ep_stall_state(dir, ep) == 0) { - // Ep not in stall state - if (ep != 0 && (type == E_INTERRUPT || type == E_BULK)) { - if (dir == EP_OUT) { - usbc->DOEPnCONFIG[ep - 1].DOEPCTL |= USBC_SETD0PID; - } else { - usbc->DIEPnCONFIG[ep - 1].DIEPCTL |= USBC_SETD0PID; - } - } - return; - } - - if (dir == EP_OUT) { - _disable_out_ep(ep, set, clr); - } else { - _disable_in_ep(ep, set, clr); - } -} - -int hal_usb_get_ep_stall_state(enum EP_DIR dir, uint8_t ep) { - volatile uint32_t *ctrl; - - if (ep >= EPNUM) { - return 0; - } - - // Select ctl register - if (ep == 0) { - if (dir == EP_IN) { - ctrl = &usbc->DIEPCTL0; - } else { - ctrl = &usbc->DOEPCTL0; - } - } else { - if (dir == EP_IN) { - ctrl = &usbc->DIEPnCONFIG[ep - 1].DIEPCTL; - } else { - ctrl = &usbc->DOEPnCONFIG[ep - 1].DOEPCTL; - } - } - - return ((*ctrl & USBC_STALL) != 0); -} - -void hal_usb_stop_ep(enum EP_DIR dir, uint8_t ep) { - USB_TRACE(3, 11, "%s: %d ep%d", __FUNCTION__, dir, ep); - - hal_usb_disable_ep(dir, ep); -} - -static void hal_usb_stop_all_out_eps(void) { - int i; - volatile uint32_t *ctrl; - volatile uint32_t *intr; - uint32_t doepctl; - - USB_FUNC_ENTRY_TRACE(11); - - // Enable global out nak - _set_global_out_nak(); - - for (i = 0; i < EPNUM; i++) { - if (i == 0) { - ctrl = &usbc->DOEPCTL0; - intr = &usbc->DOEPINT0; - } else { - ctrl = &usbc->DOEPnCONFIG[i - 1].DOEPCTL; - intr = &usbc->DOEPnCONFIG[i - 1].DOEPINT; - } - - doepctl = *ctrl; - - // BUS RESET will clear USBC_USBACTEP but keep USBC_EPENA in ep ctrl - if (doepctl & (USBC_EPENA | USBC_USBACTEP)) { - *ctrl |= USBC_SNAK | USBC_USBACTEP; - // EP0 out cannot be disabled, but stalled - if (i != 0) { - if (doepctl & USBC_EPENA) { - *intr = USBC_EPDISBLD; - *ctrl |= USBC_EPDIS; - while ((*intr & USBC_EPDISBLD) == 0) - ; - } - if ((doepctl & USBC_USBACTEP) == 0) { - *ctrl &= ~USBC_USBACTEP; - } - } - } - } - - // Disable global out nak - usbc->DCTL |= USBC_CGOUTNAK; -} - -static void hal_usb_stop_all_in_eps(void) { - int i; - volatile uint32_t *ctrl; - volatile uint32_t *intr; - uint32_t diepctl; - - USB_FUNC_ENTRY_TRACE(11); - - usbc->DCTL |= USBC_SGNPINNAK; - while ((usbc->GINTSTS & USBC_GINNAKEFF) == 0) - ; - - for (i = 0; i < EPNUM; i++) { - if (i == 0) { - ctrl = &usbc->DIEPCTL0; - intr = &usbc->DIEPINT0; - } else { - ctrl = &usbc->DIEPnCONFIG[i - 1].DIEPCTL; - intr = &usbc->DIEPnCONFIG[i - 1].DIEPINT; - } - - diepctl = *ctrl; - - // BUS RESET will clear USBC_USBACTEP but keep USBC_EPENA in ep ctrl - if (diepctl & (USBC_EPENA | USBC_USBACTEP)) { - *intr = USBC_INEPNAKEFF; - *ctrl |= USBC_SNAK | USBC_USBACTEP; - if ((diepctl & USBC_EPENA) && (diepctl & USBC_NAKSTS) == 0) { - while ((*intr & USBC_INEPNAKEFF) == 0) - ; - *intr = USBC_INEPNAKEFF; - } - if (diepctl & USBC_EPENA) { - *intr = USBC_EPDISBLD; - *ctrl |= USBC_EPDIS; - while ((*intr & USBC_EPDISBLD) == 0) - ; - } - if ((diepctl & USBC_USBACTEP) == 0) { - *ctrl &= ~USBC_USBACTEP; - } - } - } - - // Flush Tx Fifo - usbc->GRSTCTL = USBC_TXFNUM(0x10) | USBC_TXFFLSH | USBC_RXFFLSH; - while ((usbc->GRSTCTL & (USBC_TXFFLSH | USBC_RXFFLSH)) != 0) - ; - - usbc->DCTL |= USBC_CGNPINNAK; -} - -static void hal_usb_flush_tx_fifo(uint8_t ep) { - usbc->DCTL |= USBC_SGNPINNAK; - while ((usbc->GINTSTS & USBC_GINNAKEFF) == 0) - ; - - while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0) - ; - - // while ((usbc->GRSTCTL & USBC_TXFFLSH) != 0); - - usbc->GRSTCTL = USBC_TXFNUM(ep) | USBC_TXFFLSH; - while ((usbc->GRSTCTL & USBC_TXFFLSH) != 0) - ; - - usbc->DCTL |= USBC_CGNPINNAK; -} - -static void hal_usb_flush_all_tx_fifos(void) { hal_usb_flush_tx_fifo(0x10); } - -static void POSSIBLY_UNUSED hal_usb_flush_rx_fifo(void) { - _set_global_out_nak(); - - usbc->GRSTCTL |= USBC_RXFFLSH; - while ((usbc->GRSTCTL & USBC_RXFFLSH) != 0) - ; - - usbc->DCTL |= USBC_CGOUTNAK; -} - -static void hal_usb_alloc_ep0_fifo(void) { - uint32_t ram_size; - uint32_t ram_avail; - - if ((usbc->GHWCFG2 & USBC_DYNFIFOSIZING) == 0) { - return; - } - - // All endpoints have been stopped in hal_usb_irq_reset() - - // Configure FIFOs - - // RX FIFO Calculation - // ------------------- - // SETUP Packets : 4 * n + 6 - // Global OUT NAK : 1 - // DATA Packets + Status Info : (MPS / 4 + 1) * m - // OutEp XFER COMPL : 1 * outEpNum - // OutEp Disable : 1 * outEpNum - -#ifdef USB_ISO -#define RXFIFOSIZE \ - ((4 * CTRL_EPNUM + 6) + 1 + (2 * (USB_FIFO_MPS_ISO_RECV / 4 + 1)) + \ - (EPNUM * 2)) -#else -#define RXFIFOSIZE \ - ((4 * CTRL_EPNUM + 6) + 1 + (2 * (USB_MAX_PACKET_SIZE_BULK / 4 + 1)) + \ - (EPNUM * 2)) -#endif -#define EP0_TXFIFOSIZE (2 * (USB_MAX_PACKET_SIZE_CTRL + 3) / 4) - -#if (RXFIFOSIZE + EP0_TXFIFOSIZE > SPFIFORAM_SIZE) -#error "Invalid FIFO size configuration" -#endif - - ram_size = GET_BITFIELD(usbc->GDFIFOCFG, USBC_GDFIFOCFG); - ram_avail = GET_BITFIELD(usbc->GDFIFOCFG, USBC_EPINFOBASEADDR); - - ASSERT(SPFIFORAM_SIZE == ram_size, "Bad dfifo size: %u (should be %u)", - ram_size, SPFIFORAM_SIZE); - ASSERT(RXFIFOSIZE + EP0_TXFIFOSIZE <= ram_avail, - "Bad dfifo size cfg: rx=%u ep0=%u avail=%u", RXFIFOSIZE, - EP0_TXFIFOSIZE, ram_avail); - - // Rx Fifo Size (and init fifo_addr) - usbc->GRXFSIZ = USBC_RXFDEP(RXFIFOSIZE); - fifo_addr = RXFIFOSIZE; - - // EP0 / Non-periodic Tx Fifo Size - usbc->GNPTXFSIZ = - USBC_NPTXFSTADDR(fifo_addr) | USBC_NPTXFDEPS(EP0_TXFIFOSIZE); - fifo_addr += EP0_TXFIFOSIZE; - - // Flush Tx FIFOs - hal_usb_flush_all_tx_fifos(); -} - -static void hal_usb_alloc_epn_fifo(uint8_t ep, uint16_t mps) { - uint16_t size; - uint32_t ram_avail; - - if (ep == 0 || ep >= EPNUM) { - return; - } - - size = (mps + 3) / 4 * 2; - - ram_avail = GET_BITFIELD(usbc->GDFIFOCFG, USBC_EPINFOBASEADDR); - - ASSERT(fifo_addr + size <= ram_avail, - "Fifo overflow: fifo_addr=%u, size=%u, avail=%u", fifo_addr, size, - ram_avail); - - usbc->DTXFSIZE[ep - 1].DIEPTXFn = - USBC_INEPNTXFSTADDR(fifo_addr) | USBC_INEPNTXFDEP(size); - fifo_addr += size; -} - -static void hal_usb_soft_reset(void) { - usbc->GRSTCTL |= USBC_CSFTRST; - while ((usbc->GRSTCTL & USBC_CSFTRST) != 0) - ; - while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0) - ; -} - -static void hal_usb_init_phy(void) { -#ifdef USB_HIGH_SPEED - usbc->GUSBCFG |= - USBC_FORCEDEVMODE | USBC_ULPIAUTORES | USBC_ULPIFSLS | USBC_ULPI_UTMI_SEL; - usbc->GUSBCFG &= - ~(USBC_FSINTF | USBC_PHYIF | USBC_PHYSEL | USBC_USBTRDTIM_MASK); -#else - usbc->GUSBCFG |= USBC_FORCEDEVMODE | USBC_ULPIAUTORES | USBC_ULPIFSLS | - USBC_PHYSEL | USBC_ULPI_UTMI_SEL; - usbc->GUSBCFG &= ~(USBC_FSINTF | USBC_PHYIF | USBC_USBTRDTIM_MASK); -#endif - // USB turnaround time = 4 * AHB Clock + 1 PHY Clock, in terms of PHY clocks. - // If AHB Clock >= PHY Clock, time can be set to 5. - // If AHB Clock * 2 == PHY Clock, time should be set to 9. - usbc->GUSBCFG |= USBC_USBTRDTIM(5); -} - -static void hal_usb_device_init(void) { - int i; - uint8_t speed; - -#ifdef CHIP_HAS_USBPHY - usbphy_open(); -#endif - -#ifdef USB_HIGH_SPEED -#ifdef CHIP_HAS_USBIF - usbif->USBIF_00 &= ~(USBIF_00_CFG_DR_SUSPEND | USBIF_00_CFG_REG_SUSPEND); - usbif->USBIF_08 &= ~USBIF_08_CFG_SEL48M; -#endif - speed = 0; -#else -#ifdef CHIP_HAS_USBIF - usbif->USBIF_00 |= USBIF_00_CFG_DR_SUSPEND | USBIF_00_CFG_REG_SUSPEND; - usbif->USBIF_08 |= USBIF_08_CFG_SEL48M; -#endif - speed = 3; -#endif - -#ifdef CHIP_BEST2000 - if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { - // dr_suspend and reg_suspend are inverted since metal 1 - usbif->USBIF_00 ^= USBIF_00_CFG_DR_SUSPEND | USBIF_00_CFG_REG_SUSPEND; - } -#endif - -#ifdef USB_HIGH_SPEED - // Wait until usbphy clock is ready - hal_sys_timer_delay(US_TO_TICKS(60)); -#endif - - hal_usb_soft_reset(); - hal_usb_init_phy(); - // Reset after selecting PHY - hal_usb_soft_reset(); - // Some core cfg (except for PHY selection) will also be reset during soft - // reset - hal_usb_init_phy(); - - usbc->DCFG &= ~(USBC_DEVSPD_MASK | USBC_PERFRINT_MASK); - usbc->DCFG |= USBC_DEVSPD(speed) | USBC_NZSTSOUTHSHK | USBC_PERFRINT(0); - - // Clear previous interrupts - usbc->GINTMSK = 0; - usbc->GINTSTS = ~0UL; - usbc->DAINTMSK = 0; - usbc->DOEPMSK = 0; - usbc->DIEPMSK = 0; - for (i = 0; i < EPNUM; ++i) { - if (i == 0) { - usbc->DOEPINT0 = ~0UL; - usbc->DIEPINT0 = ~0UL; - } else { - usbc->DOEPnCONFIG[i - 1].DOEPINT = ~0UL; - usbc->DIEPnCONFIG[i - 1].DIEPINT = ~0UL; - } - } - usbc->GINTMSK = USBC_USBRST | USBC_ENUMDONE | USBC_ERLYSUSP | USBC_USBSUSP; - - usbc->DCTL &= ~USBC_SFTDISCON; -#if (USB_ISO_INTERVAL > 1) - // Not to check frame number and ignore ISO incomplete interrupts - usbc->DCTL |= USBC_IGNRFRMNUM; -#endif - - // Enable DMA mode - // Burst size 16 words - usbc->GAHBCFG = USBC_DMAEN | USBC_HBSTLEN(7); - usbc->GAHBCFG |= USBC_GLBLINTRMSK; -} - -static void hal_usb_soft_disconnect(void) { - // Disable global interrupt - usbc->GAHBCFG &= ~USBC_GLBLINTRMSK; - // Soft disconnection - usbc->DCTL |= USBC_SFTDISCON; - - hal_usb_device_init(); -} - -static void enable_usb_irq(void) { - NVIC_SetVector(USB_IRQn, (uint32_t)hal_usb_irq_handler); -#ifdef USB_ISO - NVIC_SetPriority(USB_IRQn, IRQ_PRIORITY_HIGH); -#else - NVIC_SetPriority(USB_IRQn, IRQ_PRIORITY_NORMAL); -#endif - NVIC_ClearPendingIRQ(USB_IRQn); - NVIC_EnableIRQ(USB_IRQn); -} - -int hal_usb_open(const struct HAL_USB_CALLBACKS *c, enum HAL_USB_API_MODE m) { - if (c == NULL) { - return 1; - } - if (c->device_desc == NULL || c->cfg_desc == NULL || c->string_desc == NULL || - c->setcfg == NULL) { - return 2; - } - - if (device_state != ATTACHED) { - return 3; - } - device_state = POWERED; - device_sleep_status = USB_SLEEP_NONE; - - hal_sysfreq_req(HAL_SYSFREQ_USER_USB, USB_SYS_FREQ); - -#if defined(USB_SUSPEND) && (defined(PMU_USB_PIN_CHECK) || defined(USB_LPM)) - if (usbdev_timer == NULL) { - usbdev_timer = hwtimer_alloc(NULL, NULL); - ASSERT(usbdev_timer, "Failed to alloc usbdev_timer"); - } -#endif - - hal_cmu_usb_set_device_mode(); - hal_cmu_usb_clock_enable(); - - memcpy(&callbacks, c, sizeof(callbacks)); - - if (usbc->GAHBCFG & USBC_GLBLINTRMSK) { - hal_usb_soft_disconnect(); - } else { - hal_usb_device_init(); - } - - enable_usb_irq(); - - if (m == HAL_USB_API_BLOCKING) { - while (device_state != CONFIGURED) - ; - } - - return 0; -} - -int hal_usb_reopen(const struct HAL_USB_CALLBACKS *c, uint8_t dcfg, uint8_t alt, - uint16_t itf) { - if (c == NULL) { - return 1; - } - if (c->device_desc == NULL || c->cfg_desc == NULL || c->string_desc == NULL || - c->setcfg == NULL) { - return 2; - } - - hal_sysfreq_req(HAL_SYSFREQ_USER_USB, USB_SYS_FREQ); - - memcpy(&callbacks, c, sizeof(callbacks)); - - device_state = CONFIGURED; - device_cfg = dcfg; - currentAlternate = alt; - currentInterface = itf; - - enable_usb_irq(); - - return 0; -} - -void hal_usb_close(void) { -#ifdef USB_SUSPEND -#if defined(PMU_USB_PIN_CHECK) || defined(USB_LPM) - // Stop pin check timer - hal_usb_stop_usbdev_timer(); -#ifdef PMU_USB_PIN_CHECK - // Disabe PMU pin status check - pmu_usb_disable_pin_status_check(); -#endif -#endif -#endif - - NVIC_DisableIRQ(USB_IRQn); - - device_state = ATTACHED; - - // Disable global interrupt - usbc->GAHBCFG &= ~USBC_GLBLINTRMSK; - // Soft disconnection - usbc->DCTL |= USBC_SFTDISCON; - // Soft reset - usbc->GRSTCTL |= USBC_CSFTRST; - usbc->DCTL |= USBC_SFTDISCON; - usbc->GRSTCTL |= USBC_CSFTRST; - // while ((usbc->GRSTCTL & USBC_CSFTRST) != 0); - // while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0); - -#ifdef CHIP_HAS_USBPHY - usbphy_close(); -#endif - - hal_cmu_usb_clock_disable(); - - memset(&callbacks, 0, sizeof(callbacks)); - - hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_32K); -} - -void hal_usb_detect_disconn(void) { - // NOTE: - // PHY detects the disconnection event by DP/DN voltage level change. - // But DP/DN voltages are provided by vusb ldo inside chip, which has nothing - // to do with VBUS. That is why USB controller cannot generate the - // disconnection interrupt. Meanwhile VBUS detection or charger detection can - // help to generate USB disconnection event via this function. - - USB_FUNC_ENTRY_TRACE(26); - - if (device_state != ATTACHED && callbacks.state_change) { - callbacks.state_change(HAL_USB_EVENT_DISCONNECT, 0); - } -} - -int hal_usb_configured(void) { return (device_state == CONFIGURED); } - -int hal_usb_suspended(void) { - return (device_sleep_status == USB_SLEEP_SUSPEND); -} - -uint32_t hal_usb_get_soffn(void) { - return GET_BITFIELD(usbc->DSTS, USBC_SOFFN); -} - -#ifdef USB_HIGH_SPEED -uint32_t hal_usb_calc_hshb_ep_mps(uint32_t pkt_size) { - // For high speed, high bandwidth endpoints - if (pkt_size <= USB_MAX_PACKET_SIZE_ISO) { - return pkt_size; - } else if (pkt_size > USB_MAX_PACKET_SIZE_ISO && - pkt_size <= USB_MAX_PACKET_SIZE_ISO * 2) { - return ALIGN(pkt_size / 2, 4); - } else { - // if (pkt_size > USB_MAX_PACKET_SIZE_ISO * 2 && pkt_size <= - // USB_MAX_PACKET_SIZE_ISO * 3) - return ALIGN(pkt_size / 3, 4); - } -} -#endif - -int hal_usb_activate_epn(enum EP_DIR dir, uint8_t ep, uint8_t type, - uint16_t mps) { - uint32_t fifo_mps; - - USB_TRACE(3, 10, "%s: %d ep%d", __FUNCTION__, dir, ep); - - if (ep == 0 || ep >= EPNUM) { - return 1; - } - - if (dir == EP_OUT) { - // Stop ep out - if (usbc->DOEPnCONFIG[ep - 1].DOEPCTL & (USBC_EPENA | USBC_USBACTEP)) { - hal_usb_stop_ep(dir, ep); - } - // Config ep out - usbc->DOEPnCONFIG[ep - 1].DOEPCTL = USBC_EPN_MPS(mps) | USBC_EPTYPE(type) | - USBC_USBACTEP | USBC_SNAK | - USBC_SETD0PID; - // Unstall ep out - usbc->DOEPnCONFIG[ep - 1].DOEPCTL &= ~USBC_STALL; - // Unmask ep out interrupt - usbc->DAINTMSK |= USBC_OUTEPMSK(1 << ep); - } else { - fifo_mps = mps; -#ifdef USB_HIGH_SPEED - if (type == E_ISOCHRONOUS || type == E_INTERRUPT) { - if (mps > USB_FIFO_MPS_ISO_SEND) { - fifo_mps = USB_FIFO_MPS_ISO_SEND; - } - epn_in_mc[ep - 1] = 1; - } -#endif - // Stop ep in - if (usbc->DIEPnCONFIG[ep - 1].DIEPCTL & (USBC_EPENA | USBC_USBACTEP)) { - hal_usb_stop_ep(dir, ep); - } - // Config ep in - usbc->DIEPnCONFIG[ep - 1].DIEPCTL = USBC_EPN_MPS(mps) | USBC_EPTYPE(type) | - USBC_USBACTEP | USBC_EPTXFNUM(ep) | - USBC_SNAK | USBC_SETD0PID; - // Allocate tx fifo - hal_usb_alloc_epn_fifo(ep, fifo_mps); - // Unstall ep in - usbc->DIEPnCONFIG[ep - 1].DIEPCTL &= ~USBC_STALL; - // Unmask ep in interrupt - usbc->DAINTMSK |= USBC_INEPMSK(1 << ep); - } - - return 0; -} - -int hal_usb_deactivate_epn(enum EP_DIR dir, uint8_t ep) { - USB_TRACE(3, 9, "%s: %d ep%d", __FUNCTION__, dir, ep); - - if (ep == 0 || ep >= EPNUM) { - return 1; - } - - hal_usb_stop_ep(dir, ep); - - if (dir == EP_OUT) { - usbc->DOEPnCONFIG[ep - 1].DOEPCTL &= ~USBC_USBACTEP; - // Mask ep out interrupt - usbc->DAINTMSK &= ~USBC_OUTEPMSK(1 << ep); - } else { - usbc->DIEPnCONFIG[ep - 1].DIEPCTL &= ~USBC_USBACTEP; - // Mask ep in interrupt - usbc->DAINTMSK &= ~USBC_INEPMSK(1 << ep); - } - - return 0; -} - -// NOTE: Not support send epn mps change, which will involve tx fifo -// reallocation -int hal_usb_update_recv_epn_mps(uint8_t ep, uint16_t mps) { - uint8_t type; - - USB_TRACE(3, 9, "%s: ep%d mps=%u", __FUNCTION__, ep, mps); - - if (ep == 0 || ep >= EPNUM) { - return 1; - } - - if ((usbc->DOEPnCONFIG[ep - 1].DOEPCTL & USBC_USBACTEP) == 0) { - return 2; - } - - hal_usb_stop_ep(EP_OUT, ep); - - usbc->DOEPnCONFIG[ep - 1].DOEPCTL &= ~USBC_USBACTEP; - // Mask ep out interrupt - usbc->DAINTMSK &= ~USBC_OUTEPMSK(1 << ep); - // Config ep out - type = GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPTYPE); - usbc->DOEPnCONFIG[ep - 1].DOEPCTL = USBC_EPN_MPS(mps) | USBC_EPTYPE(type) | - USBC_USBACTEP | USBC_SNAK | USBC_SETD0PID; - // Unmask ep out interrupt - usbc->DAINTMSK |= USBC_OUTEPMSK(1 << ep); - - return 0; -} - -int hal_usb_update_send_epn_mc(uint8_t ep, uint8_t mc) { -#ifdef USB_HIGH_SPEED - uint8_t type; - - USB_TRACE(3, 9, "%s: ep%d mc=%u", __FUNCTION__, ep, mc); - - if (ep == 0 || ep >= EPNUM) { - return 1; - } - - if (mc < 1 || mc > 3) { - return 3; - } - - if ((usbc->DIEPnCONFIG[ep - 1].DIEPCTL & USBC_USBACTEP) == 0) { - return 2; - } - - type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); - if (type == E_INTERRUPT || type == E_ISOCHRONOUS) { - epn_in_mc[ep - 1] = mc; - return 0; - } -#endif - - return 4; -} - -static void hal_usb_recv_ep0(void) { - USB_FUNC_ENTRY_TRACE(8); - - // Enable EP0 to receive a new setup packet - usbc->DOEPTSIZ0 = USBC_SUPCNT(3) | - USBC_OEPXFERSIZE0(USB_MAX_PACKET_SIZE_CTRL) | - USBC_OEPPKTCNT0; - usbc->DOEPDMA0 = (uint32_t)ep0_out_buffer; - usbc->DOEPINT0 = usbc->DOEPINT0; - usbc->DOEPCTL0 |= USBC_CNAK | USBC_EPENA; -} - -static void hal_usb_send_ep0(const uint8_t *data, uint16_t size) { - USB_TRACE(2, 8, "%s: %d", __FUNCTION__, size); - ASSERT(size <= USB_MAX_PACKET_SIZE_CTRL, "Invalid ep0 send size: %d", size); - - if (data && size) { - memcpy(ep0_in_buffer, data, size); - } - - // Enable EP0 to send one packet - usbc->DIEPTSIZ0 = USBC_IEPXFERSIZE0(size) | USBC_IEPPKTCNT0(1); - usbc->DIEPDMA0 = (uint32_t)ep0_in_buffer; - usbc->DIEPINT0 = usbc->DIEPINT0; - usbc->DIEPCTL0 |= USBC_CNAK | USBC_EPENA; -} - -int hal_usb_recv_epn(uint8_t ep, uint8_t *buffer, uint32_t size) { - uint16_t mps; - uint32_t pkt; - uint32_t xfer; - uint32_t fn = 0; -#ifdef USB_ISO - bool isoEp; - uint32_t lock; -#endif - - USB_TRACE(3, 7, "%s: ep%d %d", __FUNCTION__, ep, size); - - if (device_state != CONFIGURED) { - return 1; - } - if (ep == 0 || ep > EPNUM) { - return 2; - } - if (((uint32_t)buffer & 0x3) != 0) { - return 3; - } - if (epn_out_transfer[ep - 1].data != NULL) { - return 4; - } - if ((usbc->DOEPnCONFIG[ep - 1].DOEPCTL & USBC_USBACTEP) == 0) { - return 5; - } - mps = GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPN_MPS); - mps = ALIGN(mps, 4); - if (size < mps) { - return 6; - } - - if (size > EPN_MAX_XFERSIZE) { - return 7; - } - pkt = size / mps; - if (pkt > EPN_MAX_PKTCNT) { - return 8; - } - xfer = pkt * mps; - if (size != xfer) { - return 9; - } - - usbc->DOEPnCONFIG[ep - 1].DOEPTSIZ = - USBC_OEPXFERSIZE(xfer) | USBC_OEPPKTCNT(pkt); - usbc->DOEPnCONFIG[ep - 1].DOEPDMA = (uint32_t)buffer; - usbc->DOEPnCONFIG[ep - 1].DOEPINT = usbc->DOEPnCONFIG[ep - 1].DOEPINT; - - epn_out_transfer[ep - 1].data = buffer; - epn_out_transfer[ep - 1].length = xfer; - epn_out_transfer[ep - 1].enabled = true; - -#ifdef USB_ISO - if (GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPTYPE) == - E_ISOCHRONOUS) { - isoEp = true; - } else { - isoEp = false; - } - if (isoEp) { - // Set the frame number in time - lock = int_lock(); - // Get next frame number - if (GET_BITFIELD(usbc->DSTS, USBC_SOFFN) & 0x1) { - fn = USBC_SETD0PID; - } else { - fn = USBC_SETD1PID; - } - } -#endif - - usbc->DOEPnCONFIG[ep - 1].DOEPCTL |= USBC_EPENA | USBC_CNAK | fn; - -#ifdef USB_ISO - if (isoEp) { - int_unlock(lock); - } -#endif - - return 0; -} - -int hal_usb_send_epn(uint8_t ep, const uint8_t *buffer, uint32_t size, - enum ZLP_STATE zlp) { - uint16_t mps; - uint8_t type; - uint32_t pkt; - uint32_t fn = 0; -#ifdef USB_ISO - bool isoEp; - uint32_t lock; -#endif - - USB_TRACE(3, 6, "%s: ep%d %d", __FUNCTION__, ep, size); - - if (device_state != CONFIGURED) { - return 1; - } - if (ep == 0 || ep > EPNUM) { - return 2; - } - if (((uint32_t)buffer & 0x3) != 0) { - return 3; - } - if (epn_in_transfer[ep - 1].data != NULL) { - return 4; - } - if ((usbc->DIEPnCONFIG[ep - 1].DIEPCTL & USBC_USBACTEP) == 0) { - return 5; - } - if (size > EPN_MAX_XFERSIZE) { - return 7; - } - mps = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPN_MPS); - if (size <= mps) { - // Also taking care of 0 size packet - pkt = 1; - } else { - // If mps is not aligned in 4 bytes, application should add padding at the - // end of each packet to make sure a new packet always starts at 4-byte - // boundary - pkt = (size + mps - 1) / mps; - if (pkt > EPN_MAX_PKTCNT) { - return 8; - } - } - - type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); - if (type == E_INTERRUPT || type == E_ISOCHRONOUS) { -#ifdef USB_HIGH_SPEED - if (pkt != epn_in_mc[ep - 1] && (pkt % epn_in_mc[ep - 1])) { - // MC is the pkt cnt must be sent in every (micro)frame. - // The total pkt cnt should be integral multiple of MC value. - return 9; - } -#endif - // Never send a zero length packet at the end of transfer - epn_in_transfer[ep - 1].zero_len_pkt = false; - usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ = USBC_IEPXFERSIZE(size) | - USBC_IEPPKTCNT(pkt) | -#ifdef USB_HIGH_SPEED - USBC_MC(epn_in_mc[ep - 1]); -#else - USBC_MC(1); -#endif - } else { - // Check if a zero length packet is needed at the end of transfer - if (zlp == ZLP_AUTO) { - epn_in_transfer[ep - 1].zero_len_pkt = ((size % mps) == 0); - } else { - epn_in_transfer[ep - 1].zero_len_pkt = false; - } - usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ = - USBC_IEPXFERSIZE(size) | USBC_IEPPKTCNT(pkt); - } - usbc->DIEPnCONFIG[ep - 1].DIEPDMA = (uint32_t)buffer; - usbc->DIEPnCONFIG[ep - 1].DIEPINT = usbc->DIEPnCONFIG[ep - 1].DIEPINT; - - epn_in_transfer[ep - 1].data = buffer; - epn_in_transfer[ep - 1].length = size; - epn_in_transfer[ep - 1].pkt_cnt = pkt; - epn_in_transfer[ep - 1].enabled = true; - -#ifdef USB_ISO - if (GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE) == - E_ISOCHRONOUS) { - isoEp = true; - } else { - isoEp = false; - } - if (isoEp) { - // Set the frame number in time - lock = int_lock(); - // Get next frame number - if (GET_BITFIELD(usbc->DSTS, USBC_SOFFN) & 0x1) { - fn = USBC_SETD0PID; - } else { - fn = USBC_SETD1PID; - } - } -#endif - - usbc->DIEPnCONFIG[ep - 1].DIEPCTL |= USBC_EPENA | USBC_CNAK | fn; - -#ifdef USB_ISO - if (isoEp) { - int_unlock(lock); - } -#endif - - return 0; -} - -static void hal_usb_recv_epn_complete(uint8_t ep, uint32_t statusEp) { - uint8_t *data; - uint32_t size; - uint32_t doeptsiz; - enum XFER_COMPL_STATE state = XFER_COMPL_SUCCESS; - - USB_TRACE(3, 5, "%s: ep%d 0x%08x", __FUNCTION__, ep, statusEp); - - if (!epn_out_transfer[ep - 1].enabled) { - return; - } - - doeptsiz = usbc->DOEPnCONFIG[ep - 1].DOEPTSIZ; - - data = epn_out_transfer[ep - 1].data; - size = GET_BITFIELD(doeptsiz, USBC_OEPXFERSIZE); - ASSERT(size <= epn_out_transfer[ep - 1].length, - "Invalid xfer size: size=%d, len=%d", size, - epn_out_transfer[ep - 1].length); - size = epn_out_transfer[ep - 1].length - size; - -#ifdef USB_ISO - uint32_t doepctl = usbc->DOEPnCONFIG[ep - 1].DOEPCTL; - - if (GET_BITFIELD(doepctl, USBC_EPTYPE) == E_ISOCHRONOUS) { -#if (USB_ISO_INTERVAL == 1) -#if 1 - if (GET_BITFIELD(doeptsiz, USBC_OEPPKTCNT) != 0) { - state = XFER_COMPL_ERROR; - } -#else - uint32_t rxdpid = GET_BITFIELD(doeptsiz, USBC_RXDPID); - uint32_t pkt = - epn_out_transfer[ep - 1].length / GET_BITFIELD(doepctl, USBC_EPN_MPS) - - GET_BITFIELD(doeptsiz, USBC_OEPPKTCNT); - if ((rxdpid == DATA_PID_DATA0 && pkt != 1) || - (rxdpid == DATA_PID_DATA1 && pkt != 2) || - (rxdpid == DATA_PID_DATA2 && pkt != 3)) { - state = XFER_COMPL_ERROR; - } -#endif -#else // USB_ISO_INTERVAL != 1 - if (statusEp & USBC_PKTDRPSTS) { - state = XFER_COMPL_ERROR; - } -#endif // USB_ISO_INTERVAL != 1 - } -#endif // USB_ISO - - // Clear epn_out_transfer[] before invoking the callback, - // so that ep can be restarted in the callback - memset(&epn_out_transfer[ep - 1], 0, sizeof(epn_out_transfer[0])); - - if (callbacks.epn_recv_compl[ep - 1]) { - callbacks.epn_recv_compl[ep - 1](data, size, state); - } -} - -static void hal_usb_send_epn_complete(uint8_t ep, uint32_t statusEp) { - const uint8_t *data; - uint32_t size; - uint16_t pkt, mps; - uint8_t type; - uint32_t mc; - enum XFER_COMPL_STATE state = XFER_COMPL_SUCCESS; - - USB_TRACE(3, 4, "%s: ep%d 0x%08x", __FUNCTION__, ep, statusEp); - - if (!epn_in_transfer[ep - 1].enabled) { - return; - } - - if ((statusEp & USBC_XFERCOMPLMSK) == 0) { - state = XFER_COMPL_ERROR; - } - - pkt = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ, USBC_IEPPKTCNT); - if (pkt != 0) { - state = XFER_COMPL_ERROR; - mps = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPN_MPS); - ASSERT(pkt <= epn_in_transfer[ep - 1].pkt_cnt, - "Invalid pkt cnt: pkt=%d, pkt_cnt=%d", pkt, - epn_in_transfer[ep - 1].pkt_cnt); - size = (epn_in_transfer[ep - 1].pkt_cnt - pkt) * mps; - } else { - size = epn_in_transfer[ep - 1].length; - } - - if (state == XFER_COMPL_SUCCESS && epn_in_transfer[ep - 1].zero_len_pkt) { - epn_in_transfer[ep - 1].zero_len_pkt = false; - // Send the last zero length packet, except for isochronous/interrupt - // endpoints - type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); - if (type == E_INTERRUPT || type == E_ISOCHRONOUS) { -#ifdef USB_HIGH_SPEED - mc = USBC_MC(epn_in_mc[ep - 1]); -#else - mc = USBC_MC(1); -#endif - } else { - mc = 0; - } - usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ = - USBC_IEPXFERSIZE(0) | USBC_IEPPKTCNT(1) | mc; - usbc->DIEPnCONFIG[ep - 1].DIEPCTL |= USBC_EPENA | USBC_CNAK; - } else { - data = epn_in_transfer[ep - 1].data; - - // Clear epn_in_transfer[] before invoking the callback, - // so that ep can be restarted in the callback - memset(&epn_in_transfer[ep - 1], 0, sizeof(epn_in_transfer[0])); - - if (state != XFER_COMPL_SUCCESS) { - // The callback will not be invoked when stopping ep, - // for epn_in_transfer[] has been cleared - hal_usb_stop_ep(EP_IN, ep); - } - - if (callbacks.epn_send_compl[ep - 1]) { - callbacks.epn_send_compl[ep - 1](data, size, state); - } - } -} - -static bool requestSetAddress(void) { - USB_FUNC_ENTRY_TRACE(25); - - /* Set the device address */ - usbc->DCFG = - SET_BITFIELD(usbc->DCFG, USBC_DEVADDR, ep0_transfer.setup_pkt.wValue); - ep0_transfer.stage = STATUS_IN_STAGE; - - if (ep0_transfer.setup_pkt.wValue == 0) { - device_state = DEFAULT; - } else { - device_state = ADDRESS; - } - - return true; -} - -static bool requestSetConfiguration(void) { - USB_FUNC_ENTRY_TRACE(24); - - device_cfg = ep0_transfer.setup_pkt.wValue; - /* Set the device configuration */ - if (device_cfg == 0) { - /* Not configured */ - device_state = ADDRESS; - } else { - if (callbacks.setcfg && callbacks.setcfg(device_cfg)) { - /* Valid configuration */ - device_state = CONFIGURED; - ep0_transfer.stage = STATUS_IN_STAGE; - } else { - return false; - } - } - - return true; -} - -static bool requestGetConfiguration(void) { - USB_FUNC_ENTRY_TRACE(23); - - /* Send the device configuration */ - ep0_transfer.data = &device_cfg; - ep0_transfer.length = sizeof(device_cfg); - ep0_transfer.stage = DATA_IN_STAGE; - return true; -} - -static bool requestGetInterface(void) { - USB_FUNC_ENTRY_TRACE(22); - - /* Return the selected alternate setting for an interface */ - if (device_state != CONFIGURED) { - return false; - } - - /* Send the alternate setting */ - ep0_transfer.setup_pkt.wIndex = currentInterface; - ep0_transfer.data = ¤tAlternate; - ep0_transfer.length = sizeof(currentAlternate); - ep0_transfer.stage = DATA_IN_STAGE; - return true; -} - -static bool requestSetInterface(void) { - bool success = false; - - USB_FUNC_ENTRY_TRACE(21); - - if (callbacks.setitf && callbacks.setitf(ep0_transfer.setup_pkt.wIndex, - ep0_transfer.setup_pkt.wValue)) { - success = true; - currentInterface = ep0_transfer.setup_pkt.wIndex; - currentAlternate = ep0_transfer.setup_pkt.wValue; - ep0_transfer.stage = STATUS_IN_STAGE; - } - return success; -} - -static bool requestSetFeature(void) { - bool success = false; - - USB_FUNC_ENTRY_TRACE(20); - - if (device_state != CONFIGURED) { - /* Endpoint or interface must be zero */ - if (ep0_transfer.setup_pkt.wIndex != 0) { - return false; - } - } - - switch (ep0_transfer.setup_pkt.bmRequestType.recipient) { - case DEVICE_RECIPIENT: - if (ep0_transfer.setup_pkt.wValue == TEST_MODE) { - // TODO: Check test mode - device_test_mode = (ep0_transfer.setup_pkt.wIndex >> 8); - success = true; - } -#ifdef USB_SUSPEND - else if (ep0_transfer.setup_pkt.wValue == DEVICE_REMOTE_WAKEUP) { - if (callbacks.set_remote_wakeup) { - callbacks.set_remote_wakeup(1); - device_pwr_wkup_status |= DEVICE_STATUS_REMOTE_WAKEUP; - success = true; - } - } -#endif - break; - case ENDPOINT_RECIPIENT: - if (ep0_transfer.setup_pkt.wValue == ENDPOINT_HALT) { - // TODO: Check endpoint number - hal_usb_stall_ep((ep0_transfer.setup_pkt.wIndex & 0x80) ? EP_IN : EP_OUT, - ep0_transfer.setup_pkt.wIndex & 0xF); - if (callbacks.state_change) { - callbacks.state_change(HAL_USB_EVENT_STALL, - ep0_transfer.setup_pkt.wIndex & 0xFF); - } - success = true; - } - break; - default: - break; - } - - ep0_transfer.stage = STATUS_IN_STAGE; - - return success; -} - -static bool requestClearFeature(void) { - bool success = false; - - USB_FUNC_ENTRY_TRACE(19); - - if (device_state != CONFIGURED) { - /* Endpoint or interface must be zero */ - if (ep0_transfer.setup_pkt.wIndex != 0) { - return false; - } - } - - switch (ep0_transfer.setup_pkt.bmRequestType.recipient) { - case DEVICE_RECIPIENT: -#ifdef USB_SUSPEND - if (ep0_transfer.setup_pkt.wValue == DEVICE_REMOTE_WAKEUP) { - if (callbacks.set_remote_wakeup) { - callbacks.set_remote_wakeup(0); - device_pwr_wkup_status &= ~DEVICE_STATUS_REMOTE_WAKEUP; - success = true; - } - } -#endif - break; - case ENDPOINT_RECIPIENT: - /* TODO: We should check that the endpoint number is valid */ - if (ep0_transfer.setup_pkt.wValue == ENDPOINT_HALT) { - hal_usb_unstall_ep((ep0_transfer.setup_pkt.wIndex & 0x80) ? EP_IN - : EP_OUT, - ep0_transfer.setup_pkt.wIndex & 0xF); - if (callbacks.state_change) { - callbacks.state_change(HAL_USB_EVENT_UNSTALL, - ep0_transfer.setup_pkt.wIndex & 0xFF); - } - success = true; - } - break; - default: - break; - } - - ep0_transfer.stage = STATUS_IN_STAGE; - - return success; -} - -static bool requestGetStatus(void) { - static uint16_t status; - bool success = false; - - USB_FUNC_ENTRY_TRACE(18); - - if (device_state != CONFIGURED) { - /* Endpoint or interface must be zero */ - if (ep0_transfer.setup_pkt.wIndex != 0) { - return false; - } - } - - switch (ep0_transfer.setup_pkt.bmRequestType.recipient) { - case DEVICE_RECIPIENT: - status = device_pwr_wkup_status; - success = true; - break; - case INTERFACE_RECIPIENT: - status = 0; - success = true; - break; - case ENDPOINT_RECIPIENT: - /* TODO: We should check that the endpoint number is valid */ - if (hal_usb_get_ep_stall_state( - (ep0_transfer.setup_pkt.wIndex & 0x80) ? EP_IN : EP_OUT, - ep0_transfer.setup_pkt.wIndex & 0xF)) { - status = ENDPOINT_STATUS_HALT; - } else { - status = 0; - } - success = true; - break; - default: - break; - } - - if (success) { - /* Send the status */ - ep0_transfer.data = (uint8_t *)&status; /* Assumes little endian */ - ep0_transfer.length = sizeof(status); - ep0_transfer.stage = DATA_IN_STAGE; - } - - return success; -} - -static bool requestGetDescriptor(void) { - bool success = false; - uint8_t type; - uint8_t index; - uint8_t *desc; - - type = DESCRIPTOR_TYPE(ep0_transfer.setup_pkt.wValue); - index = DESCRIPTOR_INDEX(ep0_transfer.setup_pkt.wValue); - - USB_TRACE(3, 3, "%s: %d %d", __FUNCTION__, type, index); - - switch (type) { - case DEVICE_DESCRIPTOR: - desc = (uint8_t *)callbacks.device_desc(type); - if (desc != NULL) { - if ((desc[0] == DEVICE_DESCRIPTOR_LENGTH) && - (desc[1] == DEVICE_DESCRIPTOR)) { - ep0_transfer.length = desc[0]; - ep0_transfer.data = desc; - success = true; - } - } - break; - case CONFIGURATION_DESCRIPTOR: - desc = (uint8_t *)callbacks.cfg_desc(index); - if (desc != NULL) { - if ((desc[0] == CONFIGURATION_DESCRIPTOR_LENGTH) && - (desc[1] == CONFIGURATION_DESCRIPTOR)) { - /* Get wTotalLength */ - ep0_transfer.length = desc[2] | (desc[3] << 8); - ep0_transfer.data = desc; - // Get self-powered status - if ((desc[7] >> 6) & 0x01) { - device_pwr_wkup_status |= DEVICE_STATUS_SELF_POWERED; - } else { - device_pwr_wkup_status &= ~DEVICE_STATUS_SELF_POWERED; - } - success = true; - } - } - break; - case STRING_DESCRIPTOR: - ep0_transfer.data = (uint8_t *)callbacks.string_desc(index); - if (ep0_transfer.data) { - ep0_transfer.length = ep0_transfer.data[0]; - success = true; - } - break; - case INTERFACE_DESCRIPTOR: - case ENDPOINT_DESCRIPTOR: - /* TODO: Support is optional, not implemented here */ - break; - case QUALIFIER_DESCRIPTOR: -#ifdef USB_HIGH_SPEED - desc = (uint8_t *)callbacks.device_desc(type); - if (desc != NULL) { - if (desc[0] == QUALIFIER_DESCRIPTOR_LENGTH && desc[1] == type) { - ep0_transfer.length = desc[0]; - ep0_transfer.data = desc; - success = true; - } - } -#endif - break; - case BOS_DESCRIPTOR: -#ifdef USB_HIGH_SPEED - desc = (uint8_t *)callbacks.device_desc(type); - if (desc != NULL) { - if (desc[0] == BOS_DESCRIPTOR_LENGTH && desc[1] == type) { - // Total length - ep0_transfer.length = desc[2]; - ep0_transfer.data = desc; - success = true; - } - } -#endif - break; - default: - // Might be a class or vendor specific descriptor, which - // should be handled in setuprecv callback - USB_TRACE(1, 0, "*** Error: Unknown desc type: %d", type); - break; - } - - if (success) { - ep0_transfer.stage = DATA_IN_STAGE; - } - - return success; -} - -static void hal_usb_reset_all_transfers(void) { - int ep; - - USB_FUNC_ENTRY_TRACE(31); - - for (ep = 1; ep < EPNUM; ep++) { - reset_epn_out_transfer(ep); - reset_epn_in_transfer(ep); - } -} - -static bool hal_usb_handle_setup(void) { - bool success = false; - enum DEVICE_STATE old_state; - - USB_FUNC_ENTRY_TRACE(17); - - old_state = device_state; - - /* Process standard requests */ - if (ep0_transfer.setup_pkt.bmRequestType.type == STANDARD_TYPE) { - switch (ep0_transfer.setup_pkt.bRequest) { - case GET_STATUS: - success = requestGetStatus(); - break; - case CLEAR_FEATURE: - success = requestClearFeature(); - break; - case SET_FEATURE: - success = requestSetFeature(); - break; - case SET_ADDRESS: - success = requestSetAddress(); - break; - case GET_DESCRIPTOR: - success = requestGetDescriptor(); - break; - case SET_DESCRIPTOR: - /* TODO: Support is optional, not implemented here */ - success = false; - break; - case GET_CONFIGURATION: - success = requestGetConfiguration(); - break; - case SET_CONFIGURATION: - success = requestSetConfiguration(); - break; - case GET_INTERFACE: - success = requestGetInterface(); - break; - case SET_INTERFACE: - success = requestSetInterface(); - break; - default: - break; - } - } - - if (old_state == CONFIGURED && device_state != CONFIGURED) { - hal_usb_reset_all_transfers(); - } - - return success; -} - -static int hal_usb_ep0_setup_stage(uint32_t statusEp) { - uint8_t *data; - uint8_t setup_cnt; - uint16_t pkt_len; - - // Skip the check on IN/OUT tokens - usbc->DOEPMSK &= ~USBC_OUTTKNEPDISMSK; - usbc->DIEPMSK &= ~USBC_INTKNTXFEMPMSK; - - if (statusEp & USBC_BACK2BACKSETUP) { - data = (uint8_t *)(usbc->DOEPDMA0 - 8); - } else { - setup_cnt = GET_BITFIELD(usbc->DOEPTSIZ0, USBC_SUPCNT); - if (setup_cnt >= 3) { - setup_cnt = 2; - } - data = (uint8_t *)((uint32_t)ep0_out_buffer + 8 * (2 - setup_cnt)); - } - // Init new transfer - hal_usb_init_ep0_transfer(); - ep0_transfer.stage = SETUP_STAGE; - get_setup_packet(data, &ep0_transfer.setup_pkt); - - USB_TRACE(5, 2, "Got SETUP type=%d, req=0x%x, val=0x%x, idx=0x%x, len=%d", - ep0_transfer.setup_pkt.bmRequestType.type, - ep0_transfer.setup_pkt.bRequest, ep0_transfer.setup_pkt.wValue, - ep0_transfer.setup_pkt.wIndex, ep0_transfer.setup_pkt.wLength); - - if (ep0_transfer.setup_pkt.wLength == 0 && - ep0_transfer.setup_pkt.bmRequestType.direction != EP_OUT) { - USB_TRACE(0, 0, "*** Error: Ep0 dir should be out if wLength=0"); - return 1; - } - - if (callbacks.setuprecv == NULL || !callbacks.setuprecv(&ep0_transfer)) { - if (!hal_usb_handle_setup()) { - return 1; - } - } - -#if 0 - if (ep0_transfer.setup_pkt.wLength == 0) { - ep0_transfer.setup_pkt.bmRequestType.direction = EP_OUT; - } -#endif - - if (ep0_transfer.stage == DATA_OUT_STAGE) { - if (ep0_transfer.data == NULL) { - ep0_transfer.data = (uint8_t *)ep0_out_buffer; - } - } else if (ep0_transfer.stage == DATA_IN_STAGE) { - if (ep0_transfer.length > ep0_transfer.setup_pkt.wLength) { - ep0_transfer.length = ep0_transfer.setup_pkt.wLength; - } - pkt_len = ep0_transfer.length; - if (pkt_len > USB_MAX_PACKET_SIZE_CTRL) { - pkt_len = USB_MAX_PACKET_SIZE_CTRL; - } - hal_usb_send_ep0(ep0_transfer.data, pkt_len); - } else if (ep0_transfer.stage == STATUS_IN_STAGE) { - hal_usb_send_ep0(NULL, 0); - } else { - USB_TRACE(1, 0, "*** Setup stage switches to invalid stage: %d", - ep0_transfer.stage); - return 1; - } - - return 0; -} - -static int hal_usb_ep0_data_out_stage(void) { - uint16_t pkt_len; - uint16_t reg_size; - - reg_size = GET_BITFIELD(usbc->DOEPTSIZ0, USBC_OEPXFERSIZE0); - - ASSERT(reg_size <= USB_MAX_PACKET_SIZE_CTRL, "Invalid ep0 recv size"); - - pkt_len = MIN(USB_MAX_PACKET_SIZE_CTRL - reg_size, - (uint16_t)(ep0_transfer.length - ep0_transfer.trx_len)); - - ASSERT(ep0_transfer.length >= ep0_transfer.trx_len + pkt_len, - "Invalid ep0 recv len: length=%u trx_len=%u pkt_len=%u", - ep0_transfer.length, ep0_transfer.trx_len, pkt_len); - - memcpy(ep0_transfer.data + ep0_transfer.trx_len, ep0_out_buffer, pkt_len); - ep0_transfer.trx_len += pkt_len; - - // Always enable setup packet receiving - // CAUTION: Start ep0 recv before invoking datarecv callbacks to handle all - // kinds of endpoints. - // Some USBC events are triggered by patterns in receive FIFO, only - // when these patterns are popped by the core (DMA reading) or the - // application (usbc->GRXSTSP reading). E.g., Global OUT NAK - // (DCTL.SGOUTNak) triggers GINTSTS.GOUTNakEff, but the interrupt - // will never raise in data out stage without DMA or usbc->GRXSTSP - // reading. - hal_usb_recv_ep0(); - - pkt_len = ep0_transfer.length - ep0_transfer.trx_len; - if (pkt_len == 0) { - if (callbacks.datarecv == NULL || !callbacks.datarecv(&ep0_transfer)) { - // hal_usb_stall_ep(EP_OUT, 0); - // hal_usb_stall_ep(EP_IN, 0); - // return; - } - ep0_transfer.stage = STATUS_IN_STAGE; - // Check error on IN/OUT tokens - usbc->DOEPMSK |= USBC_OUTTKNEPDISMSK; - // Send status packet - hal_usb_send_ep0(NULL, 0); - } else { - // Receive next data packet - } - - return 0; -} - -static int hal_usb_ep0_data_in_stage(void) { - uint16_t pkt_len; - bool zero_len_pkt = false; - - ASSERT(GET_BITFIELD(usbc->DIEPTSIZ0, USBC_IEPPKTCNT0) == 0, - "Invalid ep0 sent pkt cnt"); - ASSERT(ep0_transfer.length >= ep0_transfer.trx_len, - "Invalid ep0 sent len 1: length=%u trx_len=%u", ep0_transfer.length, - ep0_transfer.trx_len); - - pkt_len = ep0_transfer.length - ep0_transfer.trx_len; - if (pkt_len == 0) { - // The last zero length packet was sent successfully - ep0_transfer.stage = STATUS_OUT_STAGE; - // Receive status packet (receiving is always enabled) - } else { - // Update sent count - if (pkt_len == USB_MAX_PACKET_SIZE_CTRL) { - zero_len_pkt = true; - } else if (pkt_len > USB_MAX_PACKET_SIZE_CTRL) { - pkt_len = USB_MAX_PACKET_SIZE_CTRL; - } - ep0_transfer.trx_len += pkt_len; - - ASSERT(ep0_transfer.length >= ep0_transfer.trx_len, - "Invalid ep0 sent len 2: length=%u trx_len=%u", ep0_transfer.length, - ep0_transfer.trx_len); - - // Send next packet - pkt_len = ep0_transfer.length - ep0_transfer.trx_len; - if (pkt_len > USB_MAX_PACKET_SIZE_CTRL) { - pkt_len = USB_MAX_PACKET_SIZE_CTRL; - } - if (pkt_len == 0) { - if (zero_len_pkt) { - // Send the last zero length packet - hal_usb_send_ep0(NULL, 0); - } else { - ep0_transfer.stage = STATUS_OUT_STAGE; - // Check error on IN/OUT tokens - usbc->DIEPMSK |= USBC_INTKNTXFEMPMSK; - // Receive status packet (receiving is always enabled) - } - } else { - hal_usb_send_ep0(ep0_transfer.data + ep0_transfer.trx_len, pkt_len); - } - } - - return 0; -} - -static int hal_usb_ep0_status_stage(void) { - // Done with status packet - ep0_transfer.stage = NONE_STAGE; - // Skip the check on IN/OUT tokens - usbc->DOEPMSK &= ~USBC_OUTTKNEPDISMSK; - usbc->DIEPMSK &= ~USBC_INTKNTXFEMPMSK; - - return 0; -} - -static void hal_usb_ep0_test_mode_check(void) { - if (device_test_mode) { - usbc->DCTL = SET_BITFIELD(usbc->DCTL, USBC_TSTCTL, device_test_mode); - device_test_mode = 0; - } -} - -static void hal_usb_handle_ep0_packet(enum EP_DIR dir, uint32_t statusEp) { - int ret; - - USB_TRACE(3, 16, "%s: dir=%d, statusEp=0x%08x", __FUNCTION__, dir, statusEp); - - if (dir == EP_OUT) { - if ((statusEp & (USBC_XFERCOMPL | USBC_STSPHSERCVD)) == - (USBC_XFERCOMPL | USBC_STSPHSERCVD)) { - // From Linux driver - if (GET_BITFIELD(usbc->DOEPTSIZ0, USBC_OEPXFERSIZE0) == - USB_MAX_PACKET_SIZE_CTRL && - (usbc->DOEPTSIZ0 & USBC_OEPPKTCNT0)) { - // Abnormal case - USB_TRACE( - 2, 0, - "*** EP0 OUT empty compl with stsphsercvd: stage=%d, size=0x%08x", - ep0_transfer.stage, usbc->DOEPTSIZ0); - // Always enable setup packet receiving - hal_usb_recv_ep0(); - return; - } - } - - if (statusEp & USBC_XFERCOMPL) { - // New packet received - if (statusEp & USBC_SETUP) { - // Clean previous transfer - if (ep0_transfer.stage != NONE_STAGE) { - USB_TRACE(1, 0, "*** Setup stage breaks previous stage %d", - ep0_transfer.stage); - hal_usb_stop_ep(EP_IN, 0); - } - // New setup packet - ep0_transfer.stage = SETUP_STAGE; - } else if (statusEp & USBC_STUPPKTRCVD) { - // Clean previous transfer - if (ep0_transfer.stage != NONE_STAGE) { - USB_TRACE(1, 0, "*** Wait setup stage breaks previous stage %d", - ep0_transfer.stage); - hal_usb_stop_ep(EP_IN, 0); - } - // New setup packet received, and wait for USBC h/w state machine - // finished CAUTION: Enabling data receipt before getting USBC_SETUP - // interrupt might cause - // race condition in h/w, which leads to missing USBC_XFERCOMPL - // interrupt after the data has been received and acked - ep0_transfer.stage = WAIT_SETUP_STAGE; - return; - } - } else { - // No packet received - if (statusEp & USBC_SETUP) { - if (ep0_transfer.stage == WAIT_SETUP_STAGE) { - // Previous packet is setup packet - ep0_transfer.stage = SETUP_STAGE; - } else { - USB_TRACE(1, 0, "*** Setup interrupt occurs in stage %d", - ep0_transfer.stage); - // The setup packet has been processed - return; - } - } - } - } - - if (ep0_transfer.stage == SETUP_STAGE) { - ASSERT(dir == EP_OUT, "Invalid dir for setup stage"); - - ret = hal_usb_ep0_setup_stage(statusEp); - if (ret) { - // Error - ep0_transfer.stage = NONE_STAGE; - hal_usb_stall_ep(EP_OUT, 0); - hal_usb_stall_ep(EP_IN, 0); - // H/w will unstall EP0 automatically when a setup token is received - // hal_usb_recv_ep0(); - } - // Always enable setup packet receiving - hal_usb_recv_ep0(); - - return; - } - - if (statusEp & USBC_XFERCOMPL) { - if (dir == EP_OUT) { - if (ep0_transfer.stage == DATA_OUT_STAGE) { - hal_usb_ep0_data_out_stage(); - } else if (ep0_transfer.stage == STATUS_OUT_STAGE) { - hal_usb_ep0_status_stage(); - // Always enable setup packet receiving - hal_usb_recv_ep0(); - } else { - // Abnormal case - USB_TRACE(2, 0, "*** EP0 OUT compl in stage %d with size 0x%08x", - ep0_transfer.stage, usbc->DOEPTSIZ0); - // Always enable setup packet receiving - hal_usb_recv_ep0(); - } - } else { - if (ep0_transfer.stage == DATA_IN_STAGE) { - hal_usb_ep0_data_in_stage(); - } else if (ep0_transfer.stage == STATUS_IN_STAGE) { - hal_usb_ep0_status_stage(); - hal_usb_ep0_test_mode_check(); - } else { - // Abnormal case - USB_TRACE(2, 0, "*** EP0 IN compl in stage %d with size 0x%08x", - ep0_transfer.stage, usbc->DIEPTSIZ0); - } - } - } -} - -static void hal_usb_irq_reset(void) { - USB_FUNC_ENTRY_TRACE(2); - - device_state = DEFAULT; - device_pwr_wkup_status = 0; - device_sleep_status = USB_SLEEP_NONE; - - usbc->PCGCCTL &= ~USBC_STOPPCLK; - usbc->DCTL &= ~USBC_RMTWKUPSIG; - - hal_usb_reset_all_transfers(); - hal_usb_stop_all_out_eps(); - hal_usb_stop_all_in_eps(); - - // Unmask ep0 interrupts - usbc->DAINTMSK = USBC_INEPMSK(1 << 0) | USBC_OUTEPMSK(1 << 0); - usbc->DOEPMSK = USBC_XFERCOMPLMSK | USBC_SETUPMSK; - usbc->DIEPMSK = USBC_XFERCOMPLMSK | USBC_TIMEOUTMSK; - usbc->GINTMSK |= USBC_OEPINT | USBC_IEPINT -#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) - | USBC_INCOMPISOOUT | USBC_INCOMPISOIN -#endif - ; -#ifdef USB_SUSPEND - usbc->GINTMSK &= ~USBC_WKUPINT; -#endif -#ifdef USB_LPM - usbc->GINTMSK |= USBC_LPM_INT; - usbc->PCGCCTL |= USBC_ENBL_L1GATING; - usbc->GLPMCFG = - SET_BITFIELD(usbc->GLPMCFG, USBC_HIRD_THRES, USB_L1_LIGHT_SLEEP_BESL) | - USBC_HIRD_THRES_BIT4 | USBC_LPMCAP | USBC_APPL1RES | - USBC_ENBESL; // | USBC_ENBLSLPM; -#ifdef CHIP_HAS_USBIF - usbif->USBIF_04 = SET_BITFIELD(usbif->USBIF_04, USBIF_04_CFG_SLEEP_THSD, - USB_L1_LIGHT_SLEEP_BESL); -#endif -#endif - - // Config ep0 size - hal_usb_alloc_ep0_fifo(); - // Reset device address - usbc->DCFG &= ~USBC_DEVADDR_MASK; - - hal_usb_init_ep0_transfer(); - hal_usb_init_epn_transfer(); - - if (callbacks.state_change) { - callbacks.state_change(HAL_USB_EVENT_RESET, 0); - } -} - -static void hal_usb_irq_enum_done(void) { - uint8_t speed; - uint8_t mps = 0; - - USB_FUNC_ENTRY_TRACE(2); - - speed = GET_BITFIELD(usbc->DSTS, USBC_ENUMSPD); - if (speed == 0) { - // High speed -- ERROR! - mps = 0; // 64 bytes - } else if (speed == 1 || speed == 3) { - // Full speed - mps = 0; // 64 bytes - } else { - // Low speed -- ERROR! - mps = 3; // 8 bytes - } - // Only support 64-byte MPS ! - mps = 0; - // Config max packet size - usbc->DIEPCTL0 = - USBC_EP0_MPS(mps) | USBC_USBACTEP | USBC_EPTXFNUM(0) | USBC_SNAK; - usbc->DOEPCTL0 = USBC_EP0_MPS(mps) | USBC_USBACTEP | USBC_SNAK; - - hal_usb_recv_ep0(); -} - -#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) -static void hal_usb_irq_incomp_iso_out(void) { - int i; - uint32_t ctrl; - uint32_t sof_fn; - uint32_t statusEp; - - sof_fn = GET_BITFIELD(usbc->DSTS, USBC_SOFFN); - - for (i = 0; i < EPNUM - 1; i++) { - ctrl = usbc->DOEPnCONFIG[i].DOEPCTL; - if ((ctrl & USBC_EPENA) && - ((ctrl >> USBC_EPDPID_SHIFT) & 1) == (sof_fn & 1) && - GET_BITFIELD(ctrl, USBC_EPTYPE) == E_ISOCHRONOUS) { - statusEp = usbc->DOEPnCONFIG[i].DOEPINT; - hal_usb_disable_ep(EP_OUT, i + 1); - break; - } - } - - if (i < EPNUM - 1) { - USB_TRACE(4, 17, "%s ep%d: INT=0x%08x, SOF=0x%04x", __FUNCTION__, i + 1, - statusEp, sof_fn); - } else { - USB_TRACE(1, 17, "%s: No valid ISO ep", __FUNCTION__); - } -} - -static void hal_usb_irq_incomp_iso_in(void) { - int i; - uint32_t ctrl; - uint32_t sof_fn; - uint32_t statusEp; - - sof_fn = GET_BITFIELD(usbc->DSTS, USBC_SOFFN); - - for (i = 0; i < EPNUM - 1; i++) { - ctrl = usbc->DIEPnCONFIG[i].DIEPCTL; - if ((ctrl & USBC_EPENA) && - ((ctrl >> USBC_EPDPID_SHIFT) & 1) == (sof_fn & 1) && - GET_BITFIELD(ctrl, USBC_EPTYPE) == E_ISOCHRONOUS) { - statusEp = usbc->DIEPnCONFIG[i].DIEPINT; - hal_usb_disable_ep(EP_IN, i + 1); - break; - } - } - - if (i < EPNUM - 1) { - USB_TRACE(4, 17, "%s ep%d: INT=0x%08x, SOF=0x%04x", __FUNCTION__, i + 1, - statusEp, sof_fn); - } else { - USB_TRACE(1, 17, "%s: No valid ISO ep", __FUNCTION__); - } -} -#endif - -#ifdef USB_SUSPEND -static void hal_usb_restore_clock(void) { - hal_sysfreq_req(HAL_SYSFREQ_USER_USB, USB_SYS_FREQ); - -#ifdef PMU_USB_PIN_CHECK -#ifdef CHIP_HAS_USBPHY - // Enable dig phy clock - usbphy_wakeup(); -#endif - - hal_cmu_clock_enable(HAL_CMU_MOD_H_USBC); - hal_cmu_clock_enable(HAL_CMU_MOD_O_USB); -#endif - - usbc->PCGCCTL &= ~USBC_STOPPCLK; - -#ifdef PMU_USB_PIN_CHECK - NVIC_ClearPendingIRQ(USB_IRQn); - NVIC_EnableIRQ(USB_IRQn); -#endif -} - -static void hal_usb_stop_clock(void) { -#ifdef PMU_USB_PIN_CHECK - // Disable USB IRQ to avoid errors when RESET/RESUME is detected before - // stopping USB clock - NVIC_DisableIRQ(USB_IRQn); -#endif - - usbc->PCGCCTL |= USBC_STOPPCLK; - -#ifdef PMU_USB_PIN_CHECK - hal_cmu_clock_disable(HAL_CMU_MOD_O_USB); - hal_cmu_clock_disable(HAL_CMU_MOD_H_USBC); - -#ifdef CHIP_HAS_USBPHY - // Disable dig phy clock - usbphy_sleep(); -#endif -#endif - - hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_32K); -} - -#ifdef PMU_USB_PIN_CHECK -static void hal_usb_pin_status_resume(enum PMU_USB_PIN_CHK_STATUS_T status); - -static void hal_usb_pin_check_enable_check(void *param) { - pmu_usb_enable_pin_status_check(); -} - -static void hal_usb_pin_check_cancel_resume(void *param) { - USB_TRACE(3, 18, "[%X] %s: DSTS=0x%08x", hal_sys_timer_get(), __FUNCTION__, - usbc->DSTS); - - if (usbc->DSTS & USBC_SUSPSTS) { - hal_usb_stop_clock(); - pmu_usb_enable_pin_status_check(); - } -} - -static void hal_usb_pin_status_resume(enum PMU_USB_PIN_CHK_STATUS_T status) { - USB_TRACE(2, 18, "%s: %d", __FUNCTION__, status); - - // Start timer to check resume status, so as to avoid fake pin resume signal - if (usbdev_timer_active) { - hwtimer_stop(usbdev_timer); - } - hwtimer_update_then_start(usbdev_timer, hal_usb_pin_check_cancel_resume, NULL, - PIN_CHECK_WAIT_RESUME_INTERVAL); - usbdev_timer_active = 1; - - hal_usb_restore_clock(); -} -#endif - -#if defined(PMU_USB_PIN_CHECK) || defined(USB_LPM) -static void hal_usb_stop_usbdev_timer(void) { - if (usbdev_timer_active) { - hwtimer_stop(usbdev_timer); - usbdev_timer_active = 0; - } -} -#endif - -static void hal_usb_sleep(enum USB_SLEEP_T cause) { - USB_FUNC_ENTRY_TRACE(18); - - device_sleep_status = cause; - - if (callbacks.state_change) { - callbacks.state_change((cause == USB_SLEEP_SUSPEND) - ? HAL_USB_EVENT_SUSPEND - : HAL_USB_EVENT_L1_DEEP_SLEEP, - 0); - } - - usbc->GINTMSK |= USBC_WKUPINT; -#ifdef USB_LPM - usbc->GINTMSK &= ~USBC_LPM_INT; -#endif - - hal_usb_stop_clock(); - -#ifdef PMU_USB_PIN_CHECK - pmu_usb_config_pin_status_check(PMU_USB_PIN_CHK_HOST_RESUME, - hal_usb_pin_status_resume, false); - // Stat timer to check current pin status - if (usbdev_timer_active) { - hwtimer_stop(usbdev_timer); - } - hwtimer_update_then_start(usbdev_timer, hal_usb_pin_check_enable_check, NULL, - PIN_CHECK_ENABLE_INTERVAL); - usbdev_timer_active = 1; -#endif -} - -static void hal_usb_wakeup(void) { - USB_FUNC_ENTRY_TRACE(18); - - device_sleep_status = USB_SLEEP_NONE; - -#ifndef PMU_USB_PIN_CHECK - hal_usb_restore_clock(); -#endif - - usbc->GINTMSK &= ~USBC_WKUPINT; -#ifdef USB_LPM - usbc->GINTMSK |= USBC_LPM_INT; -#endif - - if (callbacks.state_change) { - callbacks.state_change(HAL_USB_EVENT_RESUME, 0); - } -} - -static void hal_usb_send_resume_signal(int enable) { - if (enable) { -#ifdef PMU_USB_PIN_CHECK - // Stop pin check timer - hal_usb_stop_usbdev_timer(); - // Disabe PMU pin status check - pmu_usb_disable_pin_status_check(); -#endif - - // Restore USB clock and IRQ - hal_usb_restore_clock(); - - usbc->GINTMSK &= ~USBC_WKUPINT; - - usbc->DCTL |= USBC_RMTWKUPSIG; - } else { - usbc->DCTL &= ~USBC_RMTWKUPSIG; - } -} -#endif - -int hal_usb_remote_wakeup(int signal) { -#ifdef USB_SUSPEND - USB_TRACE(2, 15, "%s: %d", __FUNCTION__, signal); - - if (signal) { - if (device_sleep_status != USB_SLEEP_SUSPEND) { - return 1; - } - if ((device_pwr_wkup_status & DEVICE_STATUS_REMOTE_WAKEUP) == 0) { - return 2; - } - - hal_usb_send_resume_signal(1); - } else { - hal_usb_send_resume_signal(0); - - // USBC will NOT generate resume IRQ in case of remote wakeup, so fake one - // here - hal_usb_wakeup(); - } -#endif - - return 0; -} - -void hal_usb_lpm_sleep_enable(void) { -#ifdef USB_LPM - if (usbc->GLPMCFG & USBC_ENBESL) { - // usbc->GLPMCFG &= ~USBC_RSTRSLPSTS; - } - usbc->GLPMCFG |= (USBC_APPL1RES | USBC_HIRD_THRES_BIT4); - - usbc->PCGCCTL |= USBC_ENBL_L1GATING; -#endif -} - -void hal_usb_lpm_sleep_disable(void) { -#ifdef USB_LPM - uint32_t cnt; - uint32_t lock; - uint32_t lpm; - bool POSSIBLY_UNUSED rmtWake = false; - - usbc->PCGCCTL &= ~USBC_ENBL_L1GATING; - - usbc->GLPMCFG &= ~(USBC_APPL1RES | USBC_HIRD_THRES_BIT4 | USBC_ENBLSLPM); - if (usbc->GLPMCFG & USBC_ENBESL) { - usbc->GLPMCFG |= USBC_RSTRSLPSTS; - } - - lpm_entry = false; - - // Resume if in L1 state - if (usbc->GLPMCFG & USBC_SLPSTS) { - cnt = 0; - while ( - (usbc->GLPMCFG & (USBC_BREMOTEWAKE | USBC_SLPSTS | USBC_L1RESUMEOK)) == - (USBC_BREMOTEWAKE | USBC_SLPSTS)) { - hal_sys_timer_delay(US_TO_TICKS(0)); - if (++cnt > 3) { - break; - } - } - - lock = int_lock(); - - lpm = usbc->GLPMCFG; - - if (lpm & USBC_SLPSTS) { - if ((lpm & (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) == - (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) { - hal_usb_send_resume_signal(1); - rmtWake = true; -#if 0 - // Detect race condition between remote wake and L1 state change - if ((usbc->GLPMCFG & USBC_SLPSTS) == 0) { - usbc->DCTL &= ~USBC_RMTWKUPSIG; - } -#endif -#ifdef USB_SUSPEND - if (device_sleep_status == USB_SLEEP_L1) { - // USBC will NOT generate resume IRQ in case of remote wakeup, so fake - // one here - hal_usb_wakeup(); - } -#endif - } else if ((lpm & (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) == - USBC_BREMOTEWAKE) { - TRACE(1, - "\n*** ERROR: LPM Disable: Failed to wait L1 resume OK: 0x%08X\n", - lpm); - } - } - - int_unlock(lock); - - if (rmtWake) { - USB_TRACE(1, 0, "LPM RmtWake: 0x%08X", lpm); - } - } -#endif -} - -#ifdef USB_LPM -#ifdef USB_SUSPEND -static void hal_usb_lpm_check(void *param) { - uint32_t lpm; - uint32_t lock; - - // TODO: Disable USB irq only (might conflict with hal_usb_stop_clock) - lock = int_lock(); - - lpm = usbc->GLPMCFG; - - if (lpm_entry && GET_BITFIELD(lpm, USBC_HIRD) >= USB_L1_DEEP_SLEEP_BESL) { - if ((lpm & USBC_SLPSTS) && - (lpm & (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) != USBC_BREMOTEWAKE) { - lpm_entry = false; - hal_usb_sleep(USB_SLEEP_L1); - } else { - hwtimer_update_then_start(usbdev_timer, hal_usb_lpm_check, NULL, - LPM_CHECK_INTERVAL); - usbdev_timer_active = 1; - } - } - - int_unlock(lock); -} -#endif - -static void hal_usb_irq_lpm(void) { - static const uint32_t lpm_trace_interval = MS_TO_TICKS(2000); - static uint32_t last_lpm_irq_time; - static uint32_t cnt = 0; - uint32_t time; - uint32_t lpm; - - cnt++; - lpm = usbc->GLPMCFG; - -#ifdef USB_SUSPEND - if (GET_BITFIELD(lpm, USBC_HIRD) >= USB_L1_DEEP_SLEEP_BESL) { - // Stat timer to check L1 sleep state - if (usbdev_timer_active) { - hwtimer_stop(usbdev_timer); - } - hwtimer_update_then_start(usbdev_timer, hal_usb_lpm_check, NULL, - LPM_CHECK_INTERVAL); - usbdev_timer_active = 1; - lpm_entry = true; - } -#endif - - time = hal_sys_timer_get(); - if (time - last_lpm_irq_time >= lpm_trace_interval || - GET_BITFIELD(lpm, USBC_HIRD) >= USB_L1_DEEP_SLEEP_BESL) { - last_lpm_irq_time = time; - USB_TRACE(6, 0, - "LPM IRQ: 0x%08X rmtWake=%d hird=0x%x l1Res=%d slpSts=%d cnt=%u", - lpm, !!(lpm & USBC_BREMOTEWAKE), GET_BITFIELD(lpm, USBC_HIRD), - GET_BITFIELD(lpm, USBC_COREL1RES), !!(lpm & USBC_SLPSTS), cnt); - } -} -#endif - -static void hal_usb_irq_handler(void) { - uint32_t status, rawStatus; - uint32_t statusEp, rawStatusEp; - uint32_t data; - uint8_t i; - - // Store interrupt flag and reset it - rawStatus = usbc->GINTSTS; - usbc->GINTSTS = rawStatus; - - status = rawStatus & - (usbc->GINTMSK & (USBC_USBRST | USBC_ENUMDONE -#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) - | USBC_INCOMPISOOUT | USBC_INCOMPISOIN -#endif - | USBC_IEPINT | USBC_OEPINT | USBC_ERLYSUSP | - USBC_USBSUSP | USBC_WKUPINT | USBC_LPM_INT)); - - USB_TRACE(3, 1, "%s: 0x%08x / 0x%08x", __FUNCTION__, status, rawStatus); - -#if defined(USB_SUSPEND) && (defined(PMU_USB_PIN_CHECK) || defined(USB_LPM)) - bool stop_timer = true; - -#ifdef USB_LPM - if (lpm_entry && status == USBC_ERLYSUSP && - (usbc->DSTS & USBC_ERRTICERR) == 0) { - // LPM TL1TokenRetry (8 us) timer has expired. L1 state transition will be - // finished after TL1Residency (50 us) timer from now. - stop_timer = false; - } else { - lpm_entry = false; - } -#endif - - if (stop_timer) { - hal_usb_stop_usbdev_timer(); - } -#endif - - if (status & USBC_USBRST) { - // Usb reset - hal_usb_irq_reset(); - - // We got a reset, and reseted the soft state machine: Discard all other - // interrupt causes. - status &= USBC_ENUMDONE; - } - - if (status & USBC_ENUMDONE) { - // Enumeration done - hal_usb_irq_enum_done(); - } - -#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) - if (status & USBC_INCOMPISOOUT) { - // Incomplete ISO OUT - hal_usb_irq_incomp_iso_out(); - } - - if (status & USBC_INCOMPISOIN) { - // Incomplete ISO IN - hal_usb_irq_incomp_iso_in(); - } -#endif - - if (status & USBC_IEPINT) { - // Tx - data = usbc->DAINT & usbc->DAINTMSK; - for (i = 0; i < EPNUM; ++i) { - if (data & USBC_INEPMSK(1 << i)) { - if (i == 0) { - // EP0 - rawStatusEp = usbc->DIEPINT0; - usbc->DIEPINT0 = rawStatusEp; - statusEp = rawStatusEp & usbc->DIEPMSK; - - if ((statusEp & USBC_TIMEOUT) || (statusEp & USBC_INTKNTXFEMP)) { - usbc->DIEPMSK &= ~USBC_INTKNTXFEMPMSK; - hal_usb_stall_ep(EP_IN, i); - } else if (statusEp & USBC_XFERCOMPL) { - // Handle ep0 command - hal_usb_handle_ep0_packet(EP_IN, rawStatusEp); - } - } else { - rawStatusEp = usbc->DIEPnCONFIG[i - 1].DIEPINT; - usbc->DIEPnCONFIG[i - 1].DIEPINT = rawStatusEp; - statusEp = rawStatusEp & usbc->DIEPMSK; - - if ((statusEp & USBC_TIMEOUT) || (statusEp & USBC_XFERCOMPL)) { - hal_usb_send_epn_complete(i, rawStatusEp); - } - } - } - } - } - - if (status & USBC_OEPINT) { - // Rx - data = usbc->DAINT & usbc->DAINTMSK; - for (i = 0; i < EPNUM; ++i) { - if (data & USBC_OUTEPMSK(1 << i)) { - if (i == 0) { - rawStatusEp = usbc->DOEPINT0; - usbc->DOEPINT0 = rawStatusEp; - statusEp = rawStatusEp & usbc->DOEPMSK; - - if (statusEp & USBC_OUTTKNEPDIS) { - usbc->DOEPMSK &= ~USBC_OUTTKNEPDISMSK; - hal_usb_stall_ep(EP_OUT, i); - if (statusEp & USBC_XFERCOMPL) { - // Always enable setup packet receiving - hal_usb_recv_ep0(); - } - } else if (statusEp & (USBC_XFERCOMPL | USBC_SETUP)) { - // Handle ep0 command - hal_usb_handle_ep0_packet(EP_OUT, rawStatusEp); - } - } else { - rawStatusEp = usbc->DOEPnCONFIG[i - 1].DOEPINT; - usbc->DOEPnCONFIG[i - 1].DOEPINT = rawStatusEp; - statusEp = rawStatusEp & usbc->DOEPMSK; - - if (statusEp & USBC_XFERCOMPL) { - hal_usb_recv_epn_complete(i, rawStatusEp); - } - } - } - } - } - -#ifdef USB_SUSPEND - if (status & USBC_ERLYSUSP) { - if (usbc->DSTS & USBC_ERRTICERR) { - hal_usb_soft_disconnect(); - return; - } - } - - if (status & USBC_USBSUSP) { - hal_usb_sleep(USB_SLEEP_SUSPEND); - } - - if (status & USBC_WKUPINT) { - hal_usb_wakeup(); - } -#endif - -#ifdef USB_LPM - if (status & USBC_LPM_INT) { - hal_usb_irq_lpm(); - } -#endif -} - -#endif // CHIP_HAS_USB diff --git a/platform/hal/hal_usb.h b/platform/hal/hal_usb.h deleted file mode 100644 index 4533273..0000000 --- a/platform/hal/hal_usb.h +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __HAL_USB_H__ -#define __HAL_USB_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stdint.h" -#include "stdbool.h" - -#define USB_MAX_PACKET_SIZE_CTRL 64 -#ifdef USB_HIGH_SPEED -#define USB_MAX_PACKET_SIZE_BULK 512 -#define USB_MAX_PACKET_SIZE_INT 1024 -#define USB_MAX_PACKET_SIZE_ISO 1024 -#define USB_FIFO_MPS_ISO_SEND 800 -#else -#define USB_MAX_PACKET_SIZE_BULK 64 -#define USB_MAX_PACKET_SIZE_INT 64 -#define USB_MAX_PACKET_SIZE_ISO 1023 -#define USB_FIFO_MPS_ISO_SEND 768 -#endif - -// H/w register bit field width limitation -#define EPN_MAX_PKTCNT ((1 << 10) - 1) -#define EPN_MAX_XFERSIZE ((1 << 19) - 1) - -#define EPNUM 6 -#define CTRL_EPNUM 2 - -#define USB_L1_LIGHT_SLEEP_BESL USB_BESL_125US -#define USB_L1_DEEP_SLEEP_BESL USB_BESL_6000US - -enum HAL_USB_API_MODE { - HAL_USB_API_NONBLOCKING, - HAL_USB_API_BLOCKING, -}; - -enum EP_DIR { - EP_OUT, - EP_IN, -}; - -enum CTRL_STAGE { - NONE_STAGE, - WAIT_SETUP_STAGE, - SETUP_STAGE, - DATA_OUT_STAGE, - DATA_IN_STAGE, - STATUS_OUT_STAGE, - STATUS_IN_STAGE, -}; - -enum ZLP_STATE { - ZLP_AUTO, - ZLP_DISABLED, -}; - -enum XFER_COMPL_STATE { - XFER_COMPL_SUCCESS, - XFER_COMPL_ERROR, -}; - -enum HAL_USB_STATE_EVENT { - HAL_USB_EVENT_RESET, // RESET event should be processed as quickly as possible - HAL_USB_EVENT_DISCONNECT, - HAL_USB_EVENT_SUSPEND, - HAL_USB_EVENT_L1_DEEP_SLEEP, - HAL_USB_EVENT_RESUME, - HAL_USB_EVENT_STALL, - HAL_USB_EVENT_UNSTALL, - - HAL_USB_EVENT_QTY -}; - -enum USB_BESL_T { - USB_BESL_125US = 0, - USB_BESL_150US, - USB_BESL_200US, - USB_BESL_300US, - USB_BESL_400US, - USB_BESL_500US, - USB_BESL_1000US, - USB_BESL_2000US, - USB_BESL_3000US, - USB_BESL_4000US, - USB_BESL_5000US, - USB_BESL_6000US, - USB_BESL_7000US, - USB_BESL_8000US, - USB_BESL_9000US, - USB_BESL_10000US, -}; - -enum USB_BESL_HIRD_T { - USB_BESL_HIRD_75US, - USB_BESL_HIRD_100US, - USB_BESL_HIRD_150US, - USB_BESL_HIRD_250US, - USB_BESL_HIRD_350US, - USB_BESL_HIRD_450US, - USB_BESL_HIRD_950US, - USB_BESL_HIRD_1950US, - USB_BESL_HIRD_2950US, - USB_BESL_HIRD_3950US, - USB_BESL_HIRD_4950US, - USB_BESL_HIRD_5950US, - USB_BESL_HIRD_6950US, - USB_BESL_HIRD_7950US, - USB_BESL_HIRD_8950US, - USB_BESL_HIRD_9950US, -}; - -enum USB_HIRD_T { - USB_HIRD_50US, - USB_HIRD_125US, - USB_HIRD_200US, - USB_HIRD_275US, - USB_HIRD_350US, - USB_HIRD_425US, - USB_HIRD_500US, - USB_HIRD_575US, - USB_HIRD_650US, - USB_HIRD_725US, - USB_HIRD_800US, - USB_HIRD_875US, - USB_HIRD_950US, - USB_HIRD_1025US, - USB_HIRD_1100US, - USB_HIRD_1175US, -}; - -struct SETUP_PACKET { - struct { - uint8_t recipient : 5; - uint8_t type : 2; - uint8_t direction : 1; - } bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -}; - -struct EP0_TRANSFER { - enum CTRL_STAGE stage; - uint8_t *data; - uint16_t length; - uint16_t trx_len; - struct SETUP_PACKET setup_pkt; -}; - -typedef const uint8_t *(*HAL_USB_GET_DESCRIPTOR_CALLBACK)(uint8_t); -typedef bool (*HAL_USB_SETUPRECV_CALLBACK)(struct EP0_TRANSFER *); -typedef bool (*HAL_USB_DATARECV_CALLBACK)(struct EP0_TRANSFER *); -typedef bool (*HAL_USB_SETCFG_CALLBACK)(uint8_t); -typedef bool (*HAL_USB_SETITF_CALLBACK)(uint16_t, uint16_t); -typedef void (*HAL_USB_REMOTE_WAKEUP_CALLBACK)(int enable); -typedef void (*HAL_USB_STATE_CHANGE_CALLBACK)(enum HAL_USB_STATE_EVENT, uint32_t); -typedef bool (*HAL_USB_RECV_COMPL_CALLBACK)(const uint8_t *, uint32_t, enum XFER_COMPL_STATE); -typedef bool (*HAL_USB_SEND_COMPL_CALLBACK)(const uint8_t *, uint32_t, enum XFER_COMPL_STATE); - -struct HAL_USB_CALLBACKS { - HAL_USB_GET_DESCRIPTOR_CALLBACK device_desc; - HAL_USB_GET_DESCRIPTOR_CALLBACK cfg_desc; - HAL_USB_GET_DESCRIPTOR_CALLBACK string_desc; - - HAL_USB_SETUPRECV_CALLBACK setuprecv; - HAL_USB_DATARECV_CALLBACK datarecv; - HAL_USB_SETCFG_CALLBACK setcfg; - HAL_USB_SETITF_CALLBACK setitf; - HAL_USB_REMOTE_WAKEUP_CALLBACK set_remote_wakeup; - HAL_USB_STATE_CHANGE_CALLBACK state_change; - - HAL_USB_RECV_COMPL_CALLBACK epn_recv_compl[EPNUM - 1]; - HAL_USB_SEND_COMPL_CALLBACK epn_send_compl[EPNUM - 1]; -}; - -int hal_usb_open(const struct HAL_USB_CALLBACKS *c, enum HAL_USB_API_MODE m); -int hal_usb_reopen(const struct HAL_USB_CALLBACKS *c, uint8_t dcfg, uint8_t alt, uint16_t itf); -void hal_usb_close(void); - -int hal_usb_remote_wakeup(int signal); -void hal_usb_detect_disconn(void); - -void hal_usb_lpm_sleep_enable(void); -void hal_usb_lpm_sleep_disable(void); - -int hal_usb_configured(void); -int hal_usb_suspended(void); - -uint32_t hal_usb_calc_hshb_ep_mps(uint32_t pkt_size); - -int hal_usb_activate_epn(enum EP_DIR dir, uint8_t ep, uint8_t type, uint16_t mps); -int hal_usb_deactivate_epn(enum EP_DIR dir, uint8_t ep); -int hal_usb_update_recv_epn_mps(uint8_t ep, uint16_t mps); -int hal_usb_update_send_epn_mc(uint8_t ep, uint8_t mc); - -void hal_usb_disable_ep(enum EP_DIR dir, uint8_t ep); - -void hal_usb_stall_ep(enum EP_DIR dir, uint8_t ep); -void hal_usb_unstall_ep(enum EP_DIR dir, uint8_t ep); -int hal_usb_get_ep_stall_state(enum EP_DIR dir, uint8_t ep); - -void hal_usb_stop_ep(enum EP_DIR dir, uint8_t ep); - -int hal_usb_recv_epn(uint8_t ep, uint8_t *buffer, uint32_t size); -int hal_usb_send_epn(uint8_t ep, const uint8_t *buffer, uint32_t size, enum ZLP_STATE zlp); - -uint32_t hal_usb_get_soffn(void); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/platform/hal/hal_usbhost.c b/platform/hal/hal_usbhost.c deleted file mode 100644 index 3e36894..0000000 --- a/platform/hal/hal_usbhost.c +++ /dev/null @@ -1,1119 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifdef CHIP_HAS_USB - -#include "hal_usbhost.h" -#include "cmsis_nvic.h" -#include "hal_cmu.h" -#include "hal_sysfreq.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hwtimer_list.h" -#include "plat_addr_map.h" -#include "pmu.h" -#include "reg_usb.h" -#include "string.h" - -#define MAX_CHAN_NUM 10 -#define MAX_EP_NUM 16 - -#define MAX_XFER_SIZE \ - (USBC_HCTSIZN_XFERSIZE_MASK >> USBC_HCTSIZN_XFERSIZE_SHIFT) -#define MAX_XFER_PKT (USBC_HCTSIZN_PKTCNT_MASK >> USBC_HCTSIZN_PKTCNT_SHIFT) - -#define HAL_USBC_PHY_FREQ_MHZ 48 -#define HAL_USBC_PHY_FREQ_MHZ_HS 60 -#define HAL_USBC_HPRT_WC_MASK \ - (USBC_HPRT_PRTSUSP | USBC_HPRT_PRTOVRCURRCHNG | USBC_HPRT_PRTENCHNG | \ - USBC_HPRT_PRTENA | USBC_HPRT_PRTCONNDET) - -#define HAL_USBHOST_TIMEOUT_TICKS MS_TO_TICKS(200) - -#define USBHOST_TRACE(n, mask, str, ...) \ - { \ - if (usbhost_trmask & (1 << mask)) { \ - TRACE(n, str, ##__VA_ARGS__); \ - } \ - } -#define USBHOST_FUNC_ENTRY_TRACE(mask) \ - { \ - if (usbhost_trmask & (1 << mask)) { \ - FUNC_ENTRY_TRACE(); \ - } \ - } - -enum HAL_USBHOST_CHAN_STATE_T { - HAL_USBHOST_CHAN_IDLE, - HAL_USBHOST_CHAN_ALLOC, - HAL_USBHOST_CHAN_INIT, - HAL_USBHOST_CHAN_XFER, - - HAL_USBHOST_CHAN_QTY -}; - -struct HAL_USBHOST_CHAN_DESC_T { - enum HAL_USBHOST_CHAN_STATE_T state; - uint32_t start_xfer_size; - uint16_t start_pkt_cnt; - uint8_t err_cnt; - struct HAL_USBHOST_CHAN_TYPE_T type; - struct HAL_USBHOST_XFER_T xfer; -}; - -static const uint32_t usbhost_trmask = (1 << 0); //~0UL; //(1 << 3) | (1 << 4); - -static struct USBC_T *const usbc = (struct USBC_T *)USB_BASE; - -static HAL_USBHOST_PORT_HANDLER port_handler; -static HAL_USBHOST_DELAY_FUNC delay_func; - -static struct HAL_USBHOST_CHAN_DESC_T chan_desc[MAX_CHAN_NUM]; - -static struct HAL_USBHOST_SETUP_XFER_T setup_xfer; - -static volatile bool in_setup = false; - -static bool usbhost_opened = false; - -static enum HAL_USBHOST_SETUP_STAGE_T cur_setup_stage; - -static HWTIMER_ID usbhost_timer[MAX_CHAN_NUM]; - -#ifdef PMU_USB_PIN_CHECK -static HAL_USBHOST_PLUG_HANDLER plug_handler; -#endif - -static uint32_t hal_usbhost_get_xfer_size(uint8_t chan, int complete); -static void hal_usbhost_irq_handler(void); -static void hal_usbhost_timeout(void *param); - -void hal_usbhost_halt_chan(uint8_t chan) { - uint32_t mask; - - USBHOST_TRACE(2, 17, "%s: %d", __FUNCTION__, chan); - - if (chan >= MAX_CHAN_NUM) { - return; - } - - hwtimer_stop(usbhost_timer[chan]); - - mask = usbc->HCSR[chan].HCINTMSKn; - usbc->HCSR[chan].HCINTMSKn = 0; - if ((usbc->HCSR[chan].HCCHARn & USBC_HCCHARN_CHENA) == 0) { - goto _exit; - } - usbc->HCSR[chan].HCINTn = USBC_HCINTN_CHHLTD; - usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_CHENA | USBC_HCCHARN_CHDIS; - while ((usbc->HCSR[chan].HCINTn & USBC_HCINTN_CHHLTD) == 0) - ; - -_exit: - usbc->HCSR[chan].HCINTn = ~0UL; - usbc->HCSR[chan].HCINTMSKn = mask; -} - -static void hal_usbhost_soft_reset(void) { - usbc->GRSTCTL |= USBC_CSFTRST; - while ((usbc->GRSTCTL & USBC_CSFTRST) != 0) - ; - while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0) - ; -} - -static void hal_usbhost_init_phy(void) { - usbc->GUSBCFG |= USBC_FORCEHSTMODE | USBC_ULPIAUTORES | USBC_ULPIFSLS | - USBC_PHYSEL | USBC_ULPI_UTMI_SEL; - usbc->GUSBCFG &= ~(USBC_FSINTF | USBC_PHYIF | USBC_USBTRDTIM_MASK); - // USBC_USBTRDTIM(9) if AHB bus is 26M - usbc->GUSBCFG |= USBC_USBTRDTIM(5); -} - -int hal_usbhost_open(HAL_USBHOST_PORT_HANDLER port_cb, - HAL_USBHOST_DELAY_FUNC delay_fn) { - int i; - - USBHOST_FUNC_ENTRY_TRACE(16); - - for (i = 0; i < MAX_CHAN_NUM; i++) { - chan_desc[i].state = HAL_USBHOST_CHAN_IDLE; - } - - hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_52M); - - hal_cmu_usb_set_host_mode(); - hal_cmu_usb_clock_enable(); - - hal_usbhost_soft_reset(); - hal_usbhost_init_phy(); - // Reset after selecting PHY - hal_usbhost_soft_reset(); - // Some core cfg (except for PHY selection) will also be reset during soft - // reset - hal_usbhost_init_phy(); - -#ifdef USB_HIGH_SPEED - usbc->HCFG = USBC_HCFG_FSLSPCLKSEL(0); -#else - usbc->HCFG = USBC_HCFG_FSLSSUPP | USBC_HCFG_FSLSPCLKSEL(1); -#endif - - usbc->HPRT = USBC_HPRT_PRTPWR; - - // Clear previous interrupts - usbc->GINTMSK = 0; - usbc->GINTSTS = ~0UL; - usbc->HAINTMSK = 0; - for (i = 0; i < MAX_CHAN_NUM; i++) { - usbc->HCSR[i].HCINTMSKn = 0; - usbc->HCSR[i].HCINTn = ~0UL; - } - usbc->GINTMSK = USBC_PRTINT | USBC_HCHINT | USBC_DISCONNINT; - - // Enable DMA mode - // Burst size 16 words - usbc->GAHBCFG = USBC_DMAEN | USBC_HBSTLEN(7); - usbc->GAHBCFG |= USBC_GLBLINTRMSK; - - port_handler = port_cb; - delay_func = delay_fn; - - usbhost_opened = true; - - NVIC_SetVector(USB_IRQn, (uint32_t)hal_usbhost_irq_handler); - NVIC_SetPriority(USB_IRQn, IRQ_PRIORITY_NORMAL); - NVIC_ClearPendingIRQ(USB_IRQn); - NVIC_EnableIRQ(USB_IRQn); - - // usbc->TPORTDBG1 = 0x11; - - return 0; -} - -void hal_usbhost_close(void) { - uint8_t chan; - - USBHOST_FUNC_ENTRY_TRACE(15); - -#ifdef PMU_USB_PIN_CHECK - pmu_usb_disable_pin_status_check(); -#endif - - NVIC_DisableIRQ(USB_IRQn); - - usbhost_opened = false; - - hal_cmu_usb_clock_disable(); - - for (chan = 0; chan < MAX_CHAN_NUM; chan++) { - hal_usbhost_free_chan(chan); - } - - hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_32K); -} - -static void hal_usbhost_delay(uint32_t ms) { - if (delay_func) { - delay_func(ms); - } else { - hal_sys_timer_delay(MS_TO_TICKS(ms)); - } -} - -void hal_usbhost_port_reset(uint32_t ms) { - int lock; - - USBHOST_TRACE(2, 14, "%s: %d", __FUNCTION__, ms); - - lock = int_lock(); - usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) | USBC_HPRT_PRTRST; - int_unlock(lock); - - hal_usbhost_delay(ms); - - lock = int_lock(); - usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) & ~USBC_HPRT_PRTRST; - int_unlock(lock); -} - -static void hal_usbhost_port_suspend(void) { - int lock; - - USBHOST_FUNC_ENTRY_TRACE(22); - - lock = int_lock(); - usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) | USBC_HPRT_PRTSUSP; - int_unlock(lock); - - hal_usbhost_delay(3); -} - -static void hal_usbhost_port_resume(void) { - int lock; - - USBHOST_FUNC_ENTRY_TRACE(22); - - lock = int_lock(); - usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) | USBC_HPRT_PRTRES; - int_unlock(lock); - - hal_usbhost_delay(20); - - lock = int_lock(); - usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) & ~USBC_HPRT_PRTRES; - int_unlock(lock); -} - -int hal_usbhost_get_chan(uint8_t *chan) { - int i; - uint32_t lock; - - lock = int_lock(); - for (i = 0; i < MAX_CHAN_NUM; i++) { - if (chan_desc[i].state == HAL_USBHOST_CHAN_IDLE) { - chan_desc[i].state = HAL_USBHOST_CHAN_ALLOC; - break; - } - } - int_unlock(lock); - - USBHOST_TRACE(2, 13, "%s: %d", __FUNCTION__, i); - - if (i == MAX_CHAN_NUM) { - return 1; - } - - *chan = i; - - ASSERT(usbhost_timer[i] == NULL, "%s: Prev hwtimer not released: 0x%08x", - __FUNCTION__, (uint32_t)usbhost_timer[i]); - usbhost_timer[i] = hwtimer_alloc(hal_usbhost_timeout, (void *)(uint32_t)i); - if (usbhost_timer[i] == NULL) { - USBHOST_TRACE(2, 0, "%s: WARNING: Failed to alloc hwtimer for chan=%d", - __FUNCTION__, i); - // Continue even if usbhost_timer is null - } - - return 0; -} - -int hal_usbhost_free_chan(uint8_t chan) { - USBHOST_TRACE(2, 12, "%s: %d", __FUNCTION__, chan); - - if (chan >= MAX_CHAN_NUM) { - return 1; - } - - hwtimer_stop(usbhost_timer[chan]); - hwtimer_free(usbhost_timer[chan]); - usbhost_timer[chan] = NULL; - - chan_desc[chan].state = HAL_USBHOST_CHAN_IDLE; - - return 0; -} - -int hal_usbhost_init_chan(uint8_t chan, - const struct HAL_USBHOST_CHAN_TYPE_T *type) { - USBHOST_TRACE(7, 11, "%s: chan=%d mps=%d ep=%d in=%d type=%d addr=%d", - __FUNCTION__, chan, type->mps, type->ep_num, type->ep_in, - type->ep_type, type->dev_addr); - - if (chan >= MAX_CHAN_NUM) { - return 1; - } - if (chan_desc[chan].state != HAL_USBHOST_CHAN_ALLOC) { - return 2; - } - if (usbc->HCSR[chan].HCCHARn & USBC_HCCHARN_CHENA) { - return 3; - } - if ((type->dev_addr & (USBC_HCCHARN_DEVADDR_MASK >> - USBC_HCCHARN_DEVADDR_SHIFT)) != type->dev_addr) { - return 4; - } - if (type->ep_num >= MAX_EP_NUM) { - return 5; - } - if (type->ep_type >= HAL_USBHOST_EP_QTY) { - return 6; - } - if ((type->mps & (USBC_HCCHARN_MPS_MASK >> USBC_HCCHARN_MPS_SHIFT)) != - type->mps) { - return 7; - } - if (type->mps == 0) { - return 8; - } - - memcpy(&chan_desc[chan].type, type, sizeof(chan_desc[chan].type)); - chan_desc[chan].err_cnt = 0; - - usbc->HCSR[chan].HCINTMSKn = 0; - usbc->HCSR[chan].HCINTn = ~0UL; - - usbc->HCSR[chan].HCCHARn = - USBC_HCCHARN_MPS(type->mps) | USBC_HCCHARN_EPNUM(type->ep_num) | - (type->ep_in ? USBC_HCCHARN_EPDIR : 0) | - USBC_HCCHARN_EPTYPE(type->ep_type) | USBC_HCCHARN_DEVADDR(type->dev_addr); - - usbc->HCSR[chan].HCINTMSKn = USBC_HCINTN_AHBERR | USBC_HCINTN_CHHLTD; - usbc->HAINTMSK |= (1 << chan); - usbc->GINTMSK |= USBC_HCHINT; - - chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; - - return 0; -} - -int hal_usbhost_update_chan_dev_addr(uint8_t chan, uint8_t dev_addr) { - USBHOST_TRACE(3, 10, "%s: chan=%d dev_addr=%d", __FUNCTION__, chan, dev_addr); - - if (chan >= MAX_CHAN_NUM) { - return 1; - } - if (chan_desc[chan].state != HAL_USBHOST_CHAN_INIT) { - return 2; - } - - chan_desc[chan].type.dev_addr = dev_addr; - - usbc->HCSR[chan].HCCHARn = - SET_BITFIELD(usbc->HCSR[chan].HCCHARn, USBC_HCCHARN_DEVADDR, dev_addr); - - chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; - - return 0; -} - -int hal_usbhost_update_chan_mps(uint8_t chan, uint16_t mps) { - USBHOST_TRACE(3, 9, "%s: chan=%d mps=%d", __FUNCTION__, chan, mps); - - if (chan >= MAX_CHAN_NUM) { - return 1; - } - if (chan_desc[chan].state != HAL_USBHOST_CHAN_INIT) { - return 2; - } - - chan_desc[chan].type.mps = mps; - - usbc->HCSR[chan].HCCHARn = - SET_BITFIELD(usbc->HCSR[chan].HCCHARn, USBC_HCCHARN_MPS, mps); - - chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; - - return 0; -} - -int hal_usbhost_start_xfer(uint8_t chan, - const struct HAL_USBHOST_XFER_T *xfer) { - uint32_t max_periodic_len; - uint32_t pkt_cnt; - uint32_t size; - enum HAL_USBHOST_PID_TYPE_T pid; - uint8_t multi_cnt; - - USBHOST_TRACE(5, 7, "%s: chan=%d size=%u mc=%d pid=%d", __FUNCTION__, chan, - xfer->size, xfer->multi_cnt, xfer->pid); - - if (chan >= MAX_CHAN_NUM) { - return 1; - } - if (chan_desc[chan].state != HAL_USBHOST_CHAN_INIT) { - return 2; - } - if (usbc->HCSR[chan].HCCHARn & USBC_HCCHARN_CHENA) { - return 3; - } - if (((uint32_t)xfer->buf & 0x3) != 0) { - return 4; - } - if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_ISO || - chan_desc[chan].type.ep_type == HAL_USBHOST_EP_INT) { - max_periodic_len = xfer->multi_cnt * chan_desc[chan].type.mps; - if (max_periodic_len < xfer->size) { - return 5; - } - } else { - if (xfer->size > MAX_XFER_SIZE) { - return 6; - } - } - - pkt_cnt = - (xfer->size + (chan_desc[chan].type.mps - 1)) / chan_desc[chan].type.mps; - if (pkt_cnt > MAX_XFER_PKT) { - return 7; - } - if (pkt_cnt == 0) { - pkt_cnt = 1; - } - - if (chan_desc[chan].type.ep_in) { - size = pkt_cnt * chan_desc[chan].type.mps; - } else { - size = xfer->size; - } - - chan_desc[chan].start_xfer_size = size; - chan_desc[chan].start_pkt_cnt = pkt_cnt; - memcpy(&chan_desc[chan].xfer, xfer, sizeof(chan_desc[chan].xfer)); - - pid = xfer->pid; - if (pid == HAL_USBHOST_PID_AUTO) { - pid = GET_BITFIELD(usbc->HCSR[chan].HCTSIZn, USBC_HCTSIZN_PID); - } - multi_cnt = xfer->multi_cnt; - - if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_ISO || - chan_desc[chan].type.ep_type == HAL_USBHOST_EP_INT) { - multi_cnt = pkt_cnt; - - if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_ISO) { - pid = HAL_USBHOST_PID_DATA0; // Full speed - } - - if (usbc->HFNUM & 0x1) { - usbc->HCSR[chan].HCCHARn &= ~USBC_HCCHARN_ODDFRM; - } else { - usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_ODDFRM; - } - } - - chan_desc[chan].state = HAL_USBHOST_CHAN_XFER; - - usbc->HCSR[chan].HCTSIZn = USBC_HCTSIZN_PID(pid) | - USBC_HCTSIZN_PKTCNT(pkt_cnt) | - USBC_HCTSIZN_XFERSIZE(size); - usbc->HCSR[chan].HCDMAn = (uint32_t)xfer->buf; - - usbc->HCSR[chan].HCINTn = ~0UL; - - usbc->HCSR[chan].HCCHARn = - SET_BITFIELD(usbc->HCSR[chan].HCCHARn, USBC_HCCHARN_EC, multi_cnt); - usbc->HCSR[chan].HCCHARn &= ~USBC_HCCHARN_CHDIS; - usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_CHENA; - - if (xfer->handler) { - hwtimer_start(usbhost_timer[chan], HAL_USBHOST_TIMEOUT_TICKS); - } - - return 0; -} - -static void hal_usbhost_setup_xfer_handler(uint8_t chan, uint8_t *buf, - uint32_t len, - enum HAL_USBHOST_XFER_ERR_T error) { - int ret; - struct HAL_USBHOST_XFER_T xfer; - enum HAL_USBHOST_SETUP_STAGE_T handler_stage; - uint8_t handler_chan; - - ret = 1; - if (error != HAL_USBHOST_XFER_ERR_NONE) { - goto _exit; - } - - USBHOST_TRACE(5, 6, "%s: chan=%d cur=%d next=%d error=%d", __FUNCTION__, chan, - cur_setup_stage, setup_xfer.next_stage, error); - - handler_stage = setup_xfer.next_stage; - handler_chan = HAL_USBHOST_CHAN_NONE; - - switch (handler_stage) { - case HAL_USBHOST_SETUP_DATA_IN: - case HAL_USBHOST_SETUP_DATA_OUT: - xfer.buf = setup_xfer.data_buf; - xfer.size = setup_xfer.setup_pkt.wLength; - xfer.pid = HAL_USBHOST_PID_DATA1; - xfer.multi_cnt = 0; - xfer.handler = hal_usbhost_setup_xfer_handler; - if (handler_stage == HAL_USBHOST_SETUP_DATA_IN) { - handler_chan = setup_xfer.chan_in; - setup_xfer.next_stage = HAL_USBHOST_SETUP_STATUS_OUT; - } else { - handler_chan = setup_xfer.chan_out; - setup_xfer.next_stage = HAL_USBHOST_SETUP_STATUS_IN; - } - ret = hal_usbhost_start_xfer(handler_chan, &xfer); - if (ret) { - goto _exit; - } - break; - case HAL_USBHOST_SETUP_STATUS_IN: - case HAL_USBHOST_SETUP_STATUS_OUT: - if (cur_setup_stage == HAL_USBHOST_SETUP_DATA_IN) { - if (setup_xfer.setup_pkt.wLength != len) { - USBHOST_TRACE(2, 0, "Invalid setup data length: %d expect=%d", len, - setup_xfer.setup_pkt.wLength); - // Update received len - setup_xfer.setup_pkt.wLength = len; - } - } - xfer.buf = NULL; - xfer.size = 0; - xfer.pid = HAL_USBHOST_PID_DATA1; - xfer.multi_cnt = 0; - xfer.handler = hal_usbhost_setup_xfer_handler; - if (handler_stage == HAL_USBHOST_SETUP_STATUS_IN) { - handler_chan = setup_xfer.chan_in; - } else { - handler_chan = setup_xfer.chan_out; - } - setup_xfer.next_stage = HAL_USBHOST_SETUP_DONE; - ret = hal_usbhost_start_xfer(handler_chan, &xfer); - if (ret) { - goto _exit; - } - break; - case HAL_USBHOST_SETUP_DONE: - ret = 0; - goto _exit; - break; - default: - ASSERT(false, "Invalid setup next stage %d for chan %d", - setup_xfer.next_stage, chan); - ret = 1; - goto _exit; - } - - cur_setup_stage = handler_stage; - - return; - -_exit: - if (error != HAL_USBHOST_XFER_ERR_NONE) { - setup_xfer.next_stage = HAL_USBHOST_SETUP_ERROR; - } - - { - struct HAL_USBHOST_SETUP_XFER_T setup; - - memcpy(&setup, &setup_xfer, sizeof(setup)); - in_setup = false; - if (setup.handler) { - setup.handler(&setup, ret); - } - } - - return; -} - -int hal_usbhost_start_setup_xfer(const struct HAL_USBHOST_SETUP_XFER_T *setup, - uint32_t *recv_len) { - int ret; - struct HAL_USBHOST_XFER_T xfer; - - USBHOST_TRACE(7, 6, - "%s: out=%d in=%d type=0x%02x req=0x%02x wlen=%d next_stage=%d", - __FUNCTION__, setup->chan_out, setup->chan_in, - setup->setup_pkt.bmRequestType, setup->setup_pkt.bRequest, - setup->setup_pkt.wLength, setup->next_stage); - - if (setup->next_stage >= HAL_USBHOST_SETUP_STATUS_OUT) { - return -1; - } - - if (in_setup) { - return -2; - } - in_setup = true; - - memcpy(&setup_xfer, setup, sizeof(setup_xfer)); - cur_setup_stage = HAL_USBHOST_SETUP_STAGE_QTY; - - xfer.buf = (uint8_t *)&setup_xfer.setup_pkt; - xfer.size = sizeof(setup_xfer.setup_pkt); - xfer.pid = HAL_USBHOST_PID_SETUP; - xfer.multi_cnt = 0; - xfer.handler = hal_usbhost_setup_xfer_handler; - - ret = hal_usbhost_start_xfer(setup_xfer.chan_out, &xfer); - if (ret) { - in_setup = false; - return ret; - } - - if (setup->handler == NULL) { - while (in_setup) - ; - if (setup_xfer.next_stage != HAL_USBHOST_SETUP_DONE) { - return -3; - } - if (recv_len) { - if (setup->next_stage == HAL_USBHOST_SETUP_DATA_IN) { - *recv_len = setup_xfer.setup_pkt.wLength; - } else { - *recv_len = 0; - } - } - } - - return 0; -} - -static void hal_usbhost_stop_all_chans(void) { - int i; - uint32_t xfer; - HAL_USBHOST_XFER_COMPL_HANDLER handler; - uint8_t *buf; - - usbc->HAINTMSK = 0; - - for (i = 0; i < MAX_CHAN_NUM; i++) { - hal_usbhost_halt_chan(i); - - if (chan_desc[i].state != HAL_USBHOST_CHAN_XFER) { - continue; - } - - if (chan_desc[i].xfer.handler) { - // TODO: Check whether HCTSIZn is reset after channel is halted - xfer = hal_usbhost_get_xfer_size(i, 0); - - // Reset the chan_desc to INIT state so that it can be reused in callback - handler = chan_desc[i].xfer.handler; - buf = chan_desc[i].xfer.buf; - chan_desc[i].state = HAL_USBHOST_CHAN_INIT; - - handler(i, buf, xfer, HAL_USBHOST_XFER_ERR_DISCONN); - } - } - - usbc->HAINT = ~0UL; -} - -static void hal_usbhost_disconn_handler(void) { - USBHOST_FUNC_ENTRY_TRACE(5); - - usbc->GINTMSK &= ~USBC_HCHINT; - - hal_usbhost_stop_all_chans(); - - if (port_handler) { - port_handler(HAL_USBHOST_PORT_DISCONN); - } -} - -static void hal_usbhost_alloc_fifo(void) { - // FIFO configuration should be started after port enabled, or 60 ms after - // soft reset - - hal_usbhost_stop_all_chans(); - - // RX FIFO Calculation - // ------------------- - // DATA Packets + Status Info : (MPS / 4 + 1) * m - // OutEp XFER COMPL : 1 * m - // NAK/NYET Handling : 1 * outEpNum - -#define RXFIFOSIZE (2 * (MAX_USBHOST_PACKET_SIZE / 4 + 1 + 1) + USBHOST_EPNUM) -#define TXFIFOSIZE (2 * (MAX_USBHOST_PACKET_SIZE / 4)) - - // Rx Fifo Size (and init fifo_addr) - usbc->GRXFSIZ = USBC_RXFDEP(RXFIFOSIZE); - - // EP0 / Non-periodic Tx Fifo Size - usbc->GNPTXFSIZ = USBC_NPTXFSTADDR(RXFIFOSIZE) | USBC_NPTXFDEPS(TXFIFOSIZE); - - // Flush all FIFOs - usbc->GRSTCTL = USBC_TXFNUM(0x10) | USBC_TXFFLSH | USBC_RXFFLSH; - while ((usbc->GRSTCTL & (USBC_TXFFLSH | USBC_RXFFLSH)) != 0) - ; -} - -static void hal_usbhost_port_handler(void) { - uint32_t prt; - uint32_t speed; - enum HAL_USBHOST_PORT_EVENT_T event; - - prt = usbc->HPRT; - // USBC_HPRT_PRTENA also controls the port status - usbc->HPRT = prt & ~(USBC_HPRT_PRTENA | USBC_HPRT_PRTSUSP); - - USBHOST_TRACE(2, 4, "%s: 0x%08x", __FUNCTION__, prt); - - if (prt & USBC_HPRT_PRTCONNDET) { - if (port_handler) { - port_handler(HAL_USBHOST_PORT_CONN); - } - } - - if (prt & USBC_HPRT_PRTENCHNG) { - if (prt & USBC_HPRT_PRTENA) { - speed = GET_BITFIELD(usbc->HPRT, USBC_HPRT_PRTSPD); - if (speed == 1 || -#ifdef USB_HIGH_SPEED - speed == 0 || -#endif - 0) { -#ifdef USB_HIGH_SPEED - if (speed == 0) { - // High speed - usbc->HFIR = SET_BITFIELD(usbc->HFIR, USBC_HFIR_FRINT, - 125 * HAL_USBC_PHY_FREQ_MHZ_HS); - event = HAL_USBHOST_PORT_EN_HS; - } else -#else - { - // Full speed - usbc->HFIR = SET_BITFIELD(usbc->HFIR, USBC_HFIR_FRINT, - 1000 * HAL_USBC_PHY_FREQ_MHZ); - event = HAL_USBHOST_PORT_EN_FS; - } -#endif - // Config FIFOs - hal_usbhost_alloc_fifo(); - // Notify upper layer - if (port_handler) { - port_handler(event); - } - } else { - // High (0) or low (2) speed not supported - if (port_handler) { - port_handler(HAL_USBHOST_PORT_EN_BAD); - } - } - } - } -} - -static void hal_usbhost_retry_chan(uint8_t chan, uint32_t size) { - uint32_t pkt_cnt; - - USBHOST_TRACE(3, 20, "%s: chan=%d size=%u", __FUNCTION__, chan, size); - -#if 0 - if (chan_desc[chan].state != HAL_USBHOST_CHAN_XFER) { - return; - } -#endif - - hal_usbhost_halt_chan(chan); - - pkt_cnt = (size + chan_desc[chan].type.mps - 1) / chan_desc[chan].type.mps; - if (pkt_cnt == 0) { - pkt_cnt = 1; - } - - usbc->HCSR[chan].HCTSIZn = - (usbc->HCSR[chan].HCTSIZn & - ~(USBC_HCTSIZN_PKTCNT_MASK | USBC_HCTSIZN_XFERSIZE_MASK)) | - USBC_HCTSIZN_PKTCNT(pkt_cnt) | USBC_HCTSIZN_XFERSIZE(size); - usbc->HCSR[chan].HCDMAn = (uint32_t)chan_desc[chan].xfer.buf + - (chan_desc[chan].start_xfer_size - size); - - usbc->HCSR[chan].HCINTn = ~0UL; - - // usbc->HCSR[chan].HCCHARn = SET_BITFIELD(usbc->HCSR[chan].HCCHARn, - // USBC_HCCHARN_EC, multi_cnt); - usbc->HCSR[chan].HCCHARn &= ~USBC_HCCHARN_CHDIS; - usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_CHENA; -} - -static uint32_t hal_usbhost_get_xfer_size(uint8_t chan, int complete) { - uint32_t xfer; - - if (complete) { - if (chan_desc[chan].type.ep_in) { - xfer = GET_BITFIELD(usbc->HCSR[chan].HCTSIZn, USBC_HCTSIZN_XFERSIZE); - if (chan_desc[chan].start_xfer_size > xfer) { - xfer = chan_desc[chan].start_xfer_size - xfer; - } else { - xfer = 0; - } - } else { - xfer = chan_desc[chan].start_xfer_size; - } - } else { - xfer = GET_BITFIELD(usbc->HCSR[chan].HCTSIZn, USBC_HCTSIZN_PKTCNT); - if (chan_desc[chan].start_pkt_cnt > xfer) { - xfer = (chan_desc[chan].start_pkt_cnt - xfer) * chan_desc[chan].type.mps; - } else { - xfer = 0; - } - } - - return xfer; -} - -static enum HAL_USBHOST_XFER_ERR_T hal_usbhost_get_xfer_error(uint32_t irq) { - if (irq & USBC_HCINTN_XFERCOMPL) - return HAL_USBHOST_XFER_ERR_NONE; - if (irq & USBC_HCINTN_AHBERR) - return HAL_USBHOST_XFER_ERR_AHB; - if (irq & USBC_HCINTN_STALL) - return HAL_USBHOST_XFER_ERR_STALL; - if (irq & USBC_HCINTN_XACTERR) - return HAL_USBHOST_XFER_ERR_TRANSACTION; - if (irq & USBC_HCINTN_BBLERR) - return HAL_USBHOST_XFER_ERR_BABBLE; - if (irq & USBC_HCINTN_FRMOVRUN) - return HAL_USBHOST_XFER_ERR_FRAME_OVERRUN; - if (irq & USBC_HCINTN_DATATGLERR) - return HAL_USBHOST_XFER_ERR_DATA_TOGGLE; - - return HAL_USBHOST_XFER_ERR_QTY; -} - -static void hal_usbhost_chan_n_handler(uint8_t chan) { - uint32_t raw_irq; - uint32_t irq; - uint32_t xfer; - enum HAL_USBHOST_XFER_ERR_T error; - HAL_USBHOST_XFER_COMPL_HANDLER handler; - uint8_t *buf; - - USBHOST_TRACE(2, 3, "%s: %d", __FUNCTION__, chan); - - if (chan_desc[chan].state != HAL_USBHOST_CHAN_XFER) { - return; - } - - raw_irq = usbc->HCSR[chan].HCINTn; - usbc->HCSR[chan].HCINTn = raw_irq; - irq = raw_irq & usbc->HCSR[chan].HCINTMSKn; - - xfer = hal_usbhost_get_xfer_size(chan, (raw_irq & USBC_HCINTN_XFERCOMPL)); - - USBHOST_TRACE(4, 18, "%s: chan=%d HCINTn=0x%08x xfer=%u", __FUNCTION__, chan, - raw_irq, xfer); - - error = HAL_USBHOST_XFER_ERR_QTY; - - if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_BULK || - chan_desc[chan].type.ep_type == HAL_USBHOST_EP_CTRL) { - if (chan_desc[chan].type.ep_in) { - if (raw_irq & USBC_HCINTN_CHHLTD) { - if (raw_irq & - (USBC_HCINTN_XFERCOMPL | USBC_HCINTN_STALL | USBC_HCINTN_BBLERR)) { - chan_desc[chan].err_cnt = 0; - usbc->HCSR[chan].HCINTMSKn &= - ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR); - error = hal_usbhost_get_xfer_error(raw_irq); - } else if (raw_irq & USBC_HCINTN_XACTERR) { - if (chan_desc[chan].err_cnt >= 2) { - error = HAL_USBHOST_XFER_ERR_TRANSACTION; - } else { - chan_desc[chan].err_cnt++; - usbc->HCSR[chan].HCINTMSKn |= - USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR; - hal_usbhost_retry_chan(chan, - chan_desc[chan].start_xfer_size - xfer); - return; - } - } - } else if (raw_irq & - (USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR)) { - chan_desc[chan].err_cnt = 0; - usbc->HCSR[chan].HCINTMSKn &= - ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR); - return; - } - } else { - if (raw_irq & USBC_HCINTN_CHHLTD) { - if (raw_irq & (USBC_HCINTN_XFERCOMPL | USBC_HCINTN_STALL)) { - chan_desc[chan].err_cnt = 0; - usbc->HCSR[chan].HCINTMSKn &= - ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); - error = hal_usbhost_get_xfer_error(raw_irq); - } else if (raw_irq & USBC_HCINTN_XACTERR) { - if (chan_desc[chan].err_cnt >= 2) { - usbc->HCSR[chan].HCINTMSKn &= - ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); - error = HAL_USBHOST_XFER_ERR_TRANSACTION; - } else { - chan_desc[chan].err_cnt++; - usbc->HCSR[chan].HCINTMSKn |= - (USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); - hal_usbhost_retry_chan(chan, - chan_desc[chan].start_xfer_size - xfer); - return; - } - } - } else if (raw_irq & - (USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET)) { - chan_desc[chan].err_cnt = 0; - usbc->HCSR[chan].HCINTMSKn &= - ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); - return; - } - } - } - - if (error == HAL_USBHOST_XFER_ERR_QTY) { - error = hal_usbhost_get_xfer_error(raw_irq); - } - - if (error == HAL_USBHOST_XFER_ERR_QTY) { - // Unknown IRQ - usbc->HCSR[chan].HCINTMSKn &= ~irq; - USBHOST_TRACE(3, 19, "%s: Got unknown IRQ chan=%d irq=0x%08x", __FUNCTION__, - chan, irq); - } else { - // Stop xfer timer - hwtimer_stop(usbhost_timer[chan]); - - // Reset the chan_desc to INIT state so that it can be reused in callback - handler = chan_desc[chan].xfer.handler; - buf = chan_desc[chan].xfer.buf; - chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; - - if (error != HAL_USBHOST_XFER_ERR_NONE) { - usbc->HAINTMSK &= ~(1 << chan); - if ((raw_irq & USBC_HCINTN_CHHLTD) == 0) { - hal_usbhost_halt_chan(chan); - } - } - if (handler) { - handler(chan, buf, xfer, error); - } - } -} - -static void hal_usbhost_chan_handler(void) { - uint8_t i; - - USBHOST_FUNC_ENTRY_TRACE(2); - - for (i = 0; i < MAX_CHAN_NUM; i++) { - if (usbc->HAINT & (1 << i)) { - hal_usbhost_chan_n_handler(i); - } - } -} - -static void hal_usbhost_irq_handler(void) { - uint32_t status; - - // Store interrupt flag and reset it - status = usbc->GINTSTS; - usbc->GINTSTS = status; - - status &= (usbc->GINTMSK & (USBC_PRTINT | USBC_HCHINT | USBC_DISCONNINT)); - - USBHOST_TRACE(2, 1, "%s: 0x%08x", __FUNCTION__, status); - - if (status & USBC_DISCONNINT) { - hal_usbhost_disconn_handler(); - return; - } - if (status & USBC_PRTINT) { - hal_usbhost_port_handler(); - } - if (status & USBC_HCHINT) { - hal_usbhost_chan_handler(); - } -} - -static void hal_usbhost_timeout(void *param) { - uint8_t chan = (uint8_t)(uint32_t)param; - uint32_t xfer; - HAL_USBHOST_XFER_COMPL_HANDLER handler; - uint8_t *buf; - - USBHOST_TRACE(2, 21, "%s: %d", __FUNCTION__, chan); - - if (chan_desc[chan].state != HAL_USBHOST_CHAN_XFER) { - return; - } - - hal_usbhost_halt_chan(chan); - - if (chan_desc[chan].xfer.handler) { - // TODO: Check whether HCTSIZn is reset after channel is halted - xfer = hal_usbhost_get_xfer_size(chan, 0); - - // Reset the chan_desc to INIT state so that it can be reused in callback - handler = chan_desc[chan].xfer.handler; - buf = chan_desc[chan].xfer.buf; - chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; - - handler(chan, buf, xfer, HAL_USBHOST_XFER_ERR_TIMEOUT); - } -} - -#ifdef PMU_USB_PIN_CHECK -static void -hal_usbhost_pin_status_change(enum PMU_USB_PIN_CHK_STATUS_T status) { - USBHOST_TRACE(2, 24, "%s: %d", __FUNCTION__, status); - - if (plug_handler) { - if (status == PMU_USB_PIN_CHK_DEV_CONN) { - plug_handler(HAL_USBHOST_PLUG_IN); - } else if (status == PMU_USB_PIN_CHK_DEV_DISCONN) { - plug_handler(HAL_USBHOST_PLUG_OUT); - } - } -} -#endif - -void hal_usbhost_detect(enum HAL_USBHOST_PLUG_STATUS_T status, - HAL_USBHOST_PLUG_HANDLER handler) { -#ifdef PMU_USB_PIN_CHECK - enum PMU_USB_PIN_CHK_STATUS_T pmu_status; - - USBHOST_FUNC_ENTRY_TRACE(23); - - if (status == HAL_USBHOST_PLUG_IN) { - pmu_status = PMU_USB_PIN_CHK_DEV_CONN; - } else if (status == HAL_USBHOST_PLUG_OUT) { - pmu_status = PMU_USB_PIN_CHK_DEV_DISCONN; - } else { - pmu_status = PMU_USB_PIN_CHK_NONE; - } - - plug_handler = handler; - if (handler && pmu_status != PMU_USB_PIN_CHK_NONE) { - pmu_usb_config_pin_status_check(pmu_status, hal_usbhost_pin_status_change, - true); - } else { - pmu_usb_disable_pin_status_check(); - } -#else - ASSERT(false, "No aux usb pin status check support"); -#endif -} - -void hal_usbhost_sleep(void) { - USBHOST_FUNC_ENTRY_TRACE(22); - - if (usbhost_opened) { - hal_usbhost_port_suspend(); -#ifdef PMU_USB_PIN_CHECK - hal_cmu_clock_disable(HAL_CMU_MOD_H_USBC); - hal_cmu_clock_disable(HAL_CMU_MOD_O_USB); - pmu_usb_config_pin_status_check(PMU_USB_PIN_CHK_DEV_DISCONN, - hal_usbhost_pin_status_change, true); -#endif - } -} - -void hal_usbhost_wakeup(void) { - USBHOST_FUNC_ENTRY_TRACE(22); - - if (usbhost_opened) { -#ifdef PMU_USB_PIN_CHECK - pmu_usb_disable_pin_status_check(); - hal_cmu_clock_enable(HAL_CMU_MOD_H_USBC); - hal_cmu_clock_enable(HAL_CMU_MOD_O_USB); -#endif - hal_usbhost_port_resume(); - } -} - -#endif // CHIP_HAS_USB diff --git a/platform/hal/hal_usbhost.h b/platform/hal/hal_usbhost.h deleted file mode 100644 index bb348cf..0000000 --- a/platform/hal/hal_usbhost.h +++ /dev/null @@ -1,173 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __HAL_USB_H__ -#define __HAL_USB_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stdint.h" -#include "stdbool.h" - -#ifdef USB_HIGH_SPEED -#define MAX_USBHOST_PACKET_SIZE 512 -#else -#define MAX_USBHOST_PACKET_SIZE 64 -#endif - -#define USBHOST_EPNUM 6 - -#define HAL_USBHOST_CHAN_NONE 0xFF - -enum HAL_USBHOST_EP_TYPE_T { - HAL_USBHOST_EP_CTRL, - HAL_USBHOST_EP_ISO, - HAL_USBHOST_EP_BULK, - HAL_USBHOST_EP_INT, - - HAL_USBHOST_EP_QTY -}; - -enum HAL_USBHOST_PID_TYPE_T { - HAL_USBHOST_PID_DATA0 = 0, - HAL_USBHOST_PID_DATA2 = 1, - HAL_USBHOST_PID_DATA1 = 2, - HAL_USBHOST_PID_MDATA = 3, - HAL_USBHOST_PID_SETUP = 3, - - HAL_USBHOST_PID_QTY, - HAL_USBHOST_PID_AUTO = 0xFF, -}; - -enum HAL_USBHOST_PORT_EVENT_T { - HAL_USBHOST_PORT_CONN, - HAL_USBHOST_PORT_EN_LS, - HAL_USBHOST_PORT_EN_FS, - HAL_USBHOST_PORT_EN_HS, - HAL_USBHOST_PORT_EN_BAD, - HAL_USBHOST_PORT_DISCONN, - - HAL_USBHOST_PORT_QTY -}; - -enum HAL_USBHOST_SETUP_STAGE_T { - HAL_USBHOST_SETUP_DATA_IN, - HAL_USBHOST_SETUP_DATA_OUT, - HAL_USBHOST_SETUP_STATUS_IN, - HAL_USBHOST_SETUP_STATUS_OUT, - HAL_USBHOST_SETUP_DONE, - HAL_USBHOST_SETUP_ERROR, - - HAL_USBHOST_SETUP_STAGE_QTY -}; - -enum HAL_USBHOST_XFER_ERR_T { - HAL_USBHOST_XFER_ERR_NONE, - HAL_USBHOST_XFER_ERR_AHB, - HAL_USBHOST_XFER_ERR_STALL, - HAL_USBHOST_XFER_ERR_TRANSACTION, - HAL_USBHOST_XFER_ERR_BABBLE, - HAL_USBHOST_XFER_ERR_FRAME_OVERRUN, - HAL_USBHOST_XFER_ERR_DATA_TOGGLE, - HAL_USBHOST_XFER_ERR_TIMEOUT, - HAL_USBHOST_XFER_ERR_DISCONN, - - HAL_USBHOST_XFER_ERR_QTY -}; - -struct HAL_USBHOST_SETUP_XFER_T; - -typedef void (*HAL_USBHOST_DELAY_FUNC)(uint32_t ms); -typedef void (*HAL_USBHOST_PORT_HANDLER)(enum HAL_USBHOST_PORT_EVENT_T evt); -typedef void (*HAL_USBHOST_XFER_COMPL_HANDLER)(uint8_t chan, uint8_t *buf, uint32_t len, enum HAL_USBHOST_XFER_ERR_T error); -typedef void (*HAL_USBHOST_SETUP_COMPL_HANDLER)(struct HAL_USBHOST_SETUP_XFER_T *setup, int error); - -enum HAL_USBHOST_PLUG_STATUS_T { - HAL_USBHOST_PLUG_UNKNOWN, - HAL_USBHOST_PLUG_IN, - HAL_USBHOST_PLUG_OUT, -}; - -typedef void (*HAL_USBHOST_PLUG_HANDLER)(enum HAL_USBHOST_PLUG_STATUS_T status); - -struct HAL_USBHOST_CHAN_TYPE_T { - uint16_t mps; - uint8_t ep_num; - uint8_t ep_in; - enum HAL_USBHOST_EP_TYPE_T ep_type; - uint8_t dev_addr; -}; - -struct HAL_USBHOST_XFER_T { - uint8_t *buf; - uint32_t size; - uint8_t multi_cnt; - enum HAL_USBHOST_PID_TYPE_T pid; - HAL_USBHOST_XFER_COMPL_HANDLER handler; -}; - -struct HAL_USBHOST_SETUP_PKT_T { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -}; - -struct HAL_USBHOST_SETUP_XFER_T { - struct HAL_USBHOST_SETUP_PKT_T setup_pkt; - enum HAL_USBHOST_SETUP_STAGE_T next_stage; - HAL_USBHOST_SETUP_COMPL_HANDLER handler; - uint8_t *data_buf; - uint8_t chan_out; - uint8_t chan_in; -}; - -int hal_usbhost_open(HAL_USBHOST_PORT_HANDLER port_cb, HAL_USBHOST_DELAY_FUNC delay_fn); - -void hal_usbhost_close(void); - -void hal_usbhost_halt_chan(uint8_t chan); - -void hal_usbhost_port_reset(uint32_t ms); - -int hal_usbhost_get_chan(uint8_t *chan); - -int hal_usbhost_free_chan(uint8_t chan); - -int hal_usbhost_init_chan(uint8_t chan, const struct HAL_USBHOST_CHAN_TYPE_T *type); - -int hal_usbhost_update_chan_dev_addr(uint8_t chan, uint8_t dev_addr); - -int hal_usbhost_update_chan_mps(uint8_t chan, uint16_t mps); - -int hal_usbhost_start_xfer(uint8_t chan, const struct HAL_USBHOST_XFER_T *xfer); - -int hal_usbhost_start_setup_xfer(const struct HAL_USBHOST_SETUP_XFER_T *setup, uint32_t *recv_len); - -void hal_usbhost_detect(enum HAL_USBHOST_PLUG_STATUS_T status, HAL_USBHOST_PLUG_HANDLER handler); - -void hal_usbhost_sleep(void); - -void hal_usbhost_wakeup(void); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/platform/main/Makefile b/platform/main/Makefile index 6994838..63af99f 100644 --- a/platform/main/Makefile +++ b/platform/main/Makefile @@ -202,7 +202,6 @@ ccflags-y += \ -Iutils/hwtimer_list \ -Iplatform/drivers/ana \ -Iplatform/drivers/security_engine \ - -Iplatform/drivers/usb/usb_dev/inc \ -Iapps/main \ -Iapps/factory \ -Iutils/list \ diff --git a/services/communication/Makefile b/services/communication/Makefile index eab9024..de84a64 100644 --- a/services/communication/Makefile +++ b/services/communication/Makefile @@ -11,7 +11,6 @@ endif ccflags-y += \ -Iapps/common \ - -Iplatform/drivers/usb/usb_dev/inc \ -Iplatform/drivers/ana \ $(BT_IF_INCLUDES) \ -Iservices/communication/comminication_knowles \ diff --git a/services/communication/comminication_knowles/Makefile b/services/communication/comminication_knowles/Makefile index fb3fafc..1fb369c 100644 --- a/services/communication/comminication_knowles/Makefile +++ b/services/communication/comminication_knowles/Makefile @@ -10,7 +10,6 @@ obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) subdir-ccflags-y += \ -Iapps/common \ - -Iplatform/drivers/usb/usb_dev/inc \ -Iplatform/drivers/ana \ -Iutils/crc32 \ -Iservices/bt_app \ diff --git a/tests/anc_usb/Makefile b/tests/anc_usb/Makefile deleted file mode 100644 index 590b75b..0000000 --- a/tests/anc_usb/Makefile +++ /dev/null @@ -1,292 +0,0 @@ -cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) - -#obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) -obj-y := - -ifeq ($(ROM_BUILD),1) -obj-y += ../../tests/rom/startup_ARMCM.S -else -obj-y += ../../platform/main/startup_main.S -endif - -obj-y += main.c -ifeq ($(ANC_APP),1) -obj-y += anc_usb_app.c -endif -obj-y += usb_audio_app.c -obj-y += dualadc_audio_app.c -obj-y += adda_loop_app.c -obj-y += safe_queue.c -obj-y += memutils.c -ifeq ($(MIC_KEY),1) -obj-y += mic_key.c -endif -ifeq ($(VENDOR_MSG_SUPPT),1) -obj-y += usb_vendor_msg.c -endif - -obj-y += ../../services/audio_process/ -obj-y += ../../services/multimedia/ -obj-y += ../../services/nv_section/ -obj-y += ../../utils/crc32/ - -ifeq ($(USB_AUDIO_SPEECH),1) -obj-y += speech_process.c -obj-y += ../../apps/audioplayers/bt_sco_chain.c -obj-y += ../../apps/audioplayers/bt_sco_chain_cfg_default.c -obj-y += ../../apps/audioplayers/bt_sco_chain_tuning.cpp -obj-y += ../../services/audio_dump/ -obj-y += ../../utils/heap/ - -ccflags-y += \ - -Iapps/audioplayers \ - -Iapps/common -endif - -obj-y := $(obj-y:.c=.o) -obj-y := $(obj-y:.cpp=.o) -obj-y := $(obj-y:.S=.o) - -ifeq ($(INTSRAM_RUN),1) -asflags-y += -DINTSRAM_RUN -ccflags-y += -DINTSRAM_RUN -endif - -ccflags-y += \ - -Iutils/boot_struct \ - -Iutils/crc32 \ - -Iutils/heap \ - -Iutils/hexdump \ - -Iutils/hwtimer_list \ - -Iplatform/drivers/usb/usb_dev/inc \ - -Iplatform/drivers/ana \ - -Iservices/multimedia/audio/process/adp/include \ - -Iservices/multimedia/audio/process/anc/include \ - -Iservices/multimedia/audio/process/filters/include \ - -Iservices/multimedia/audio/process/resample/include \ - -Iservices/audio_dump/include \ - -Iservices/multimedia/speech/inc \ - -Iservices/audio_process \ - -Iservices/nv_section/aud_section \ - -Iservices/nv_section/include - -CFLAGS_usb_audio_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) -CFLAGS_adda_loop_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) - -ifneq ($(DEBUG_PORT),) -CFLAGS_main.o += -DDEBUG_PORT=$(DEBUG_PORT) -endif - -ifeq ($(USB_AUDIO_SPEECH),1) -CFLAGS_main.o += -DUSB_AUDIO_SPEECH -endif - -ANC_USB_CFG_FLAGS := - -# ANC option -ifeq ($(ANC_APP),1) -ANC_USB_CFG_FLAGS += -DANC_APP -endif - -# USB audio option -ifeq ($(USB_AUDIO_APP),1) -ANC_USB_CFG_FLAGS += -DUSB_AUDIO_APP -endif - -ifeq ($(USB_I2S_APP),1) -ANC_USB_CFG_FLAGS += -DUSB_I2S_APP -ifneq ($(USB_I2S_ID),) -ANC_USB_CFG_FLAGS += -DUSB_I2S_ID=$(USB_I2S_ID) -endif -endif - -ifeq ($(USB_HIGH_SPEED),1) -ANC_USB_CFG_FLAGS += -DUSB_HIGH_SPEED -endif - -ifeq ($(AUDIO_RESAMPLE),1) -ANC_USB_CFG_FLAGS += -D__AUDIO_RESAMPLE__ -endif - -ifeq ($(ADC_CH_SEP_BUFF),1) -ANC_USB_CFG_FLAGS += -DADC_CH_SEP_BUFF -endif - -include platform/drivers/usb/usb_dev/uaud_cfg_flags.mk - -platform/drivers/usb/usb_dev/uaud_cfg_flags.mk: ; - -ANC_USB_CFG_FLAGS += $(UAUD_CFG_FLAGS) - -# USB audio configuration -ifeq ($(USB_AUDIO_DYN_CFG),1) -ifneq ($(USB_AUDIO_RECV_ENABLE),0) -ifneq ($(AUDIO_RESAMPLE),1) -SW_CAPTURE_RESAMPLE ?= 1 -endif -endif -endif - -ifeq ($(AUDIO_PLAYBACK_24BIT),1) -ANC_USB_CFG_FLAGS += -DAUDIO_PLAYBACK_24BIT -endif - -# DSD configuration -ifeq ($(HW_FIR_DSD_PROCESS),1) -ifeq ($(HW_FIR_DSD_BUF_MID_ADDR),) -$(error HW_FIR_DSD_BUF_MID_ADDR must be defined with HW_FIR_DSD_PROCESS) -endif -ANC_USB_CFG_FLAGS += -D__HW_FIR_DSD_PROCESS__ -DHW_FIR_DSD_BUF_MID_ADDR=$(HW_FIR_DSD_BUF_MID_ADDR) -endif - -ifeq ($(CODEC_DSD),1) -ANC_USB_CFG_FLAGS += -DCODEC_DSD -endif - -# EQ configuration -ifeq ($(HW_FIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__HW_FIR_EQ_PROCESS__ -endif - -ifeq ($(HW_IIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__HW_IIR_EQ_PROCESS__ -endif - -ifeq ($(SW_IIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__SW_IIR_EQ_PROCESS__ -endif - -ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) -ANC_USB_CFG_FLAGS += -D__HW_DAC_IIR_EQ_PROCESS__ -endif - -ifeq ($(AUDIO_RESAMPLE),1) -ifeq ($(SW_PLAYBACK_RESAMPLE),1) -ANC_USB_CFG_FLAGS += -DSW_PLAYBACK_RESAMPLE -endif -endif - -ifeq ($(SW_CAPTURE_RESAMPLE),1) -ANC_USB_CFG_FLAGS += -DSW_CAPTURE_RESAMPLE -endif - -CFLAGS_main.o += $(ANC_USB_CFG_FLAGS) -CFLAGS_usb_audio_app.o += $(ANC_USB_CFG_FLAGS) -CFLAGS_anc_usb_app.o += $(ANC_USB_CFG_FLAGS) - -ifeq ($(ANC_KEY_DOUBLE_CLICK_ON_OFF),1) -CFLAGS_anc_usb_app.o += -DANC_KEY_DOUBLE_CLICK_ON_OFF -endif - -ifeq ($(ANC_FF_ENABLED),1) -CFLAGS_anc_usb_app.o += -DANC_FF_ENABLED -endif - -ifeq ($(ANC_FB_ENABLED),1) -CFLAGS_anc_usb_app.o += -DANC_FB_ENABLED -endif - -ifeq ($(AUDIO_SECTION_SUPPT),1) -CFLAGS_anc_usb_app.o += -D__AUDIO_SECTION_SUPPT__ -endif - -ifeq ($(ANC_INIT_OFF),1) -CFLAGS_anc_usb_app.o += -DANC_INIT_OFF -endif - -ifeq ($(ADDA_LOOP_APP),1) -CFLAGS_main.o += -DADDA_LOOP_APP -endif - -ifeq ($(PC_CMD_UART),1) -CFLAGS_main.o += -D__PC_CMD_UART__ -endif - -ifeq ($(JTAG_ENABLE),1) -CFLAGS_main.o += -DJTAG_ENABLE -endif - -ifeq ($(DEBUG_MODE_USB_DOWNLOAD),1) -CFLAGS_main.o += -DDEBUG_MODE_USB_DOWNLOAD -endif - -ifeq ($(DELAY_STREAM_OPEN),1) -CFLAGS_usb_audio_app.o += -DDELAY_STREAM_OPEN -endif - -ifeq ($(NOISE_GATING),1) -CFLAGS_usb_audio_app.o += -DNOISE_GATING -endif - -ifeq ($(NOISE_REDUCTION),1) -CFLAGS_usb_audio_app.o += -DNOISE_REDUCTION -endif - -ifeq ($(ANC_L_R_MISALIGN_WORKAROUND),1) -CFLAGS_usb_audio_app.o += -DANC_L_R_MISALIGN_WORKAROUND -endif - -ifeq ($(ANDROID_ACCESSORY_SPEC),1) -CFLAGS_usb_audio_app.o += -DANDROID_ACCESSORY_SPEC -ifeq ($(ANDROID_VOICE_CMD_KEY),1) -CFLAGS_usb_audio_app.o += -DANDROID_VOICE_CMD_KEY -endif -endif - -ifeq ($(DUAL_AUX_MIC_MORE_FILTER),1) -CFLAGS_usb_audio_app.o += -DDUAL_AUX_MIC_MORE_FILTER -endif - -ifeq ($(FREQ_RESP_EQ),1) -CFLAGS_usb_audio_app.o += -DFREQ_RESP_EQ -endif - -ifeq ($(KEEP_SAME_LATENCY),1) -CFLAGS_usb_audio_app.o += -DKEEP_SAME_LATENCY -CFLAGS_speech_process.o += -DKEEP_SAME_LATENCY -endif - -ifeq ($(USB_AUDIO_PWRKEY_TEST),1) -CFLAGS_usb_audio_app.o += -DUSB_AUDIO_PWRKEY_TEST -endif - -ifeq ($(AUDIO_RESAMPLE),1) -# If neither best1000 nor best2000 -ifeq ($(filter best1000 best2000,$(CHIP)),) -PLL_TUNE_SAMPLE_RATE ?= 1 -endif -ifeq ($(PLL_TUNE_SAMPLE_RATE),1) -CFLAGS_usb_audio_app.o += -DPLL_TUNE_SAMPLE_RATE -endif -ifeq ($(PLL_TUNE_XTAL),1) -CFLAGS_usb_audio_app.o += -DPLL_TUNE_XTAL -endif -endif - -ifeq ($(TARGET_TO_MAX_DIFF),1) -CFLAGS_usb_audio_app.o += -DTARGET_TO_MAX_DIFF -endif - -ifneq ($(USB_AUDIO_RECV_ENABLE),0) -CFLAGS_usb_audio_app.o += -DUSB_AUDIO_RECV_ENABLE -endif -ifneq ($(USB_AUDIO_SEND_ENABLE),0) -CFLAGS_usb_audio_app.o += -DUSB_AUDIO_SEND_ENABLE -endif - -ifeq ($(USB_EQ_TUNING), 1) -CFLAGS_main.o += -DUSB_EQ_TUNING -CFLAGS_usb_vendor_msg.o += -DUSB_EQ_TUNING -endif - -ifeq ($(VENDOR_MSG_SUPPT), 1) -CFLAGS_main.o += -D_VENDOR_MSG_SUPPT_ -CFLAGS_usb_vendor_msg.o += -D_VENDOR_MSG_SUPPT_ -CFLAGS_usb_audio_app.o += -D_VENDOR_MSG_SUPPT_ -endif - -ifeq ($(CHIP_HAS_DCO), 1) -CFLAGS_main.o += -DCHIP_HAS_DCO -CFLAGS_usb_vendor_msg.o += -DCHIP_HAS_DCO -CFLAGS_usb_audio_app.o += -DCHIP_HAS_DCO -endif \ No newline at end of file diff --git a/tests/anc_usb/adda_loop_app.c b/tests/anc_usb/adda_loop_app.c deleted file mode 100644 index 4972a92..0000000 --- a/tests/anc_usb/adda_loop_app.c +++ /dev/null @@ -1,210 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "adda_loop_app.h" -#include "audioflinger.h" -#include "hal_aud.h" -#include "hal_sysfreq.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "string.h" -#include "tgt_hardware.h" - -#define ADDA_SAMPLE_RATE 48000 -#define ADDA_SAMPLE_SIZE 2 - -#define ADDA_PLAYBACK_CHAN 2 -#define ADDA_CAPTURE_CHAN 2 - -#define RATE_TO_SIZE(n) (((n) + (1000 - 1)) / 1000) - -#define ADDA_PLAYBACK_FRAME_SIZE \ - (RATE_TO_SIZE(ADDA_SAMPLE_RATE) * ADDA_SAMPLE_SIZE * ADDA_PLAYBACK_CHAN) -#define ADDA_CAPTURE_FRAME_SIZE \ - (RATE_TO_SIZE(ADDA_SAMPLE_RATE) * ADDA_SAMPLE_SIZE * ADDA_CAPTURE_CHAN) - -#define PLAYBACK_FRAME_NUM 4 -#define CAPTURE_FRAME_NUM 8 - -#define ADDA_NON_EXP_ALIGN(val, exp) (((val) + ((exp)-1)) / (exp) * (exp)) -#define BUFF_ALIGN (4 * 4) - -#define PLAYBACK_SIZE \ - ADDA_NON_EXP_ALIGN(ADDA_PLAYBACK_FRAME_SIZE *PLAYBACK_FRAME_NUM, BUFF_ALIGN) -#define CAPTURE_SIZE \ - ADDA_NON_EXP_ALIGN(ADDA_CAPTURE_FRAME_SIZE *CAPTURE_FRAME_NUM, BUFF_ALIGN) - -#define ALIGNED4 ALIGNED(4) - -static uint8_t ALIGNED4 adda_playback_buf[PLAYBACK_SIZE]; -static uint8_t ALIGNED4 adda_capture_buf[CAPTURE_SIZE]; - -static uint32_t cap_rpos; -static uint32_t cap_wpos; - -static enum AUD_BITS_T sample_size_to_enum(uint32_t size) { - if (size == 2) { - return AUD_BITS_16; - } else if (size == 4) { - return AUD_BITS_24; - } else { - ASSERT(false, "%s: Invalid sample size: %u", __FUNCTION__, size); - } - - return 0; -} - -static enum AUD_CHANNEL_NUM_T chan_num_to_enum(uint32_t num) { - if (num == 2) { - return AUD_CHANNEL_NUM_2; - } else if (num == 1) { - return AUD_CHANNEL_NUM_1; - } else { - ASSERT(false, "%s: Invalid channel num: %u", __FUNCTION__, num); - } - - return 0; -} - -static uint32_t adda_data_playback(uint8_t *buf, uint32_t len) { - uint32_t cur_time; - int16_t *src; - int16_t *dst; - int16_t *src_end; - int16_t *dst_end; - uint32_t avail; - - cur_time = hal_sys_timer_get(); - - if (cap_wpos >= cap_rpos) { - avail = cap_wpos - cap_rpos; - } else { - avail = sizeof(adda_capture_buf) + cap_wpos - cap_rpos; - } - - if (avail * ADDA_PLAYBACK_CHAN / ADDA_CAPTURE_CHAN >= len) { - src = (int16_t *)(adda_capture_buf + cap_rpos); - src_end = (int16_t *)(adda_capture_buf + sizeof(adda_capture_buf)); - dst = (int16_t *)buf; - dst_end = (int16_t *)(buf + len); - - while (dst < dst_end) { - *dst++ = *src++; - if (src == src_end) { - src = (int16_t *)adda_capture_buf; - } -#if (ADDA_PLAYBACK_CHAN == 2) && (ADDA_CAPTURE_CHAN == 1) - *dst = *(dst - 1); - dst++; -#endif - } - - cap_rpos = (uint32_t)src - (uint32_t)adda_capture_buf; - } else { - memset(buf, 0, len); - } - - TRACE(5, "[%X] playback: len=%4u wpos=%4u rpos=%4u avail=%4u", cur_time, len, - cap_wpos, cap_rpos, avail); - return 0; -} - -static uint32_t adda_data_capture(uint8_t *buf, uint32_t len) { - uint32_t cur_time; - - cur_time = hal_sys_timer_get(); - - cap_wpos += len; - if (cap_wpos >= sizeof(adda_capture_buf)) { - cap_wpos = 0; - } - - TRACE(4, "[%X] capture : len=%4u wpos=%4u rpos=%4u", cur_time, len, cap_wpos, - cap_rpos); - return 0; -} - -static void adda_loop_start(void) { - int ret = 0; - struct AF_STREAM_CONFIG_T stream_cfg; - - hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, HAL_CMU_FREQ_52M); - - memset(&stream_cfg, 0, sizeof(stream_cfg)); - - stream_cfg.bits = sample_size_to_enum(ADDA_SAMPLE_SIZE); - stream_cfg.channel_num = chan_num_to_enum(ADDA_PLAYBACK_CHAN); - stream_cfg.sample_rate = ADDA_SAMPLE_RATE; - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; - stream_cfg.vol = AUDIO_OUTPUT_VOLUME_DEFAULT; - stream_cfg.handler = adda_data_playback; - stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; - stream_cfg.data_ptr = adda_playback_buf; - stream_cfg.data_size = sizeof(adda_playback_buf); - - TRACE(3, "[%s] playback sample_rate: %d, bits = %d", __func__, - stream_cfg.sample_rate, stream_cfg.bits); - - ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); - ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); - - memset(&stream_cfg, 0, sizeof(stream_cfg)); - - stream_cfg.bits = sample_size_to_enum(ADDA_SAMPLE_SIZE); - stream_cfg.channel_num = chan_num_to_enum(ADDA_CAPTURE_CHAN); - stream_cfg.sample_rate = ADDA_SAMPLE_RATE; - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; - stream_cfg.vol = CODEC_SADC_VOL; - stream_cfg.handler = adda_data_capture; - stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; - stream_cfg.data_ptr = adda_capture_buf; - stream_cfg.data_size = sizeof(adda_capture_buf); - - TRACE(3, "[%s] capture sample_rate: %d, bits = %d", __func__, - stream_cfg.sample_rate, stream_cfg.bits); - - ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); - ASSERT(ret == 0, "af_stream_open catpure failed: %d", ret); - - ret = af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - ASSERT(ret == 0, "af_stream_start playback failed: %d", ret); - - ret = af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - ASSERT(ret == 0, "af_stream_start catpure failed: %d", ret); -} - -static void adda_loop_stop(void) { - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - - hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, HAL_CMU_FREQ_32K); -} - -void adda_loop_app(bool on) { - if (on) { - adda_loop_start(); - } else { - adda_loop_stop(); - } -} - -void adda_loop_app_loop(void) { -#ifndef RTOS - extern void af_thread(void const *argument); - af_thread(NULL); -#endif -} diff --git a/tests/anc_usb/adda_loop_app.h b/tests/anc_usb/adda_loop_app.h deleted file mode 100644 index 057868d..0000000 --- a/tests/anc_usb/adda_loop_app.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __ADDA_LOOP_APP_H__ -#define __ADDA_LOOP_APP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" - -void adda_loop_app(bool on); - -void adda_loop_app_loop(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tests/anc_usb/anc_usb_app.c b/tests/anc_usb/anc_usb_app.c deleted file mode 100644 index 18157b5..0000000 --- a/tests/anc_usb/anc_usb_app.c +++ /dev/null @@ -1,1047 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "anc_usb_app.h" -#include "anc_process.h" -#include "audioflinger.h" -#include "cmsis.h" -#include "hal_codec.h" -#include "hal_key.h" -#include "hal_sleep.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hwtimer_list.h" -#include "pmu.h" -#include "tgt_hardware.h" -#include "usb_audio_app.h" - -#ifdef ANC_SWITCH_GPADC_CHAN -#include "hal_gpadc.h" -#endif - -#define ANC_KEY_CPU_WAKE_USER HAL_CPU_WAKE_LOCK_USER_4 -#define ANC_STATE_CPU_WAKE_USER HAL_CPU_WAKE_LOCK_USER_5 - -#define ANC_FADE_IN_OUT -#define ANC_FADE_GAIN_STEP 1 -#define ANC_MODE_SWITCH_WITHOUT_FADE - -#ifndef ANC_INIT_ON_TIMEOUT_MS -#ifdef CHIP_BEST1000 -#define ANC_INIT_ON_TIMEOUT_MS 1200 -#else -#define ANC_INIT_ON_TIMEOUT_MS 200 -#endif -#endif -#ifndef ANC_SHUTDOWN_TIMEOUT_MS -#define ANC_SHUTDOWN_TIMEOUT_MS 5000 -#endif - -#ifndef ANC_SWITCH_CHECK_INTERVAL -#define ANC_SWITCH_CHECK_INTERVAL MS_TO_TICKS(500) -#endif - -#ifdef ANC_COEF_NUM -#if (ANC_COEF_NUM < 1) -#error "Invalid ANC_COEF_NUM configuration" -#endif -#else -#define ANC_COEF_NUM (1) -#endif - -#define KEY_PROCESS_TIMER_INTERVAL (MS_TO_TICKS(1) / 2) -#define FADE_TIMER_INTERVAL (MS_TO_TICKS(1) / 2) - -enum ANC_STATUS_T { - ANC_STATUS_NULL = 0, - ANC_STATUS_INIT, - ANC_STATUS_FADEIN, - ANC_STATUS_ENABLE, - ANC_STATUS_FADEOUT, - ANC_STATUS_DISABLE, - ANC_STATUS_INIT_CLOSE, -}; - -enum ANC_KEY_STATE_T { - ANC_KEY_STATE_NULL = 0, - ANC_KEY_STATE_CLOSE, - ANC_KEY_STATE_OPEN, - ANC_KEY_STATE_DEBOUNCE, -}; - -enum ANC_CTRL_SM_T { - ANC_CTRL_SM_OFF = 0, - ANC_CTRL_SM_COEF_0, - ANC_CTRL_SM_COEF_N = ANC_CTRL_SM_COEF_0 + ANC_COEF_NUM - 1, - - ANC_CTRL_SM_QTY -}; - -static enum ANC_STATUS_T anc_status = ANC_STATUS_NULL; -static enum ANC_KEY_STATE_T prev_key_state = ANC_KEY_STATE_NULL; -static enum HAL_KEY_EVENT_T anc_key_event = HAL_KEY_EVENT_NONE; -static enum ANC_CTRL_SM_T anc_ctrl_sm = ANC_CTRL_SM_OFF; -#ifdef ANC_TALK_THROUGH -static bool talk_through = false; -#endif - -static uint32_t anc_init_time; -static uint32_t anc_close_time; - -static enum ANC_INDEX cur_coef_index = ANC_INDEX_0; - -static enum AUD_SAMPRATE_T anc_sample_rate[AUD_STREAM_NUM]; - -static bool anc_running = false; - -#ifdef ANC_SWITCH_GPIO_PIN -static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_anc = { - ANC_SWITCH_GPIO_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, - HAL_IOMUX_PIN_PULLUP_ENABLE}; -static bool gpio_pending; -static bool gpio_irq_en; -static enum HAL_GPIO_IRQ_POLARITY_T gpio_irq_polarity; -#endif - -// ANC_SWITCH_GPADC_CHAN -static HWTIMER_ID gpadc_timer; - -// ANC_FADE_IN_OUT -static uint8_t fadein_cnt = 0; -static uint8_t fadeout_cnt = 0; -static uint32_t prev_fade_time = 0; - -#ifdef CFG_HW_ANC_LED_PIN -const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_anc_led[] = { - {CFG_HW_ANC_LED_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, - HAL_IOMUX_PIN_NOPULL}, -}; -#endif -#ifdef CFG_HW_ANC_LED_PIN2 -const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_anc_led2[] = { - {CFG_HW_ANC_LED_PIN2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, - HAL_IOMUX_PIN_NOPULL}, -}; -#endif - -static void anc_full_open(void); -static void anc_full_close(void); - -// ANC_FADE_IN_OUT -int anc_usb_app_fadein(enum ANC_TYPE_T anc_type) { - - int32_t gain0_curr, gain1_curr; - int32_t gain0_tg, gain1_tg; - - anc_get_gain(&gain0_curr, &gain1_curr, anc_type); - anc_get_cfg_gain(&gain0_tg, &gain1_tg, anc_type); - - /* - anc_set_gain(gain0_tg, gain1_tg,anc_type); - - return 0; - */ - if (gain0_tg > 0) { - if (gain0_curr < gain0_tg) { - if (gain0_curr + ANC_FADE_GAIN_STEP < gain0_tg) { - gain0_curr += ANC_FADE_GAIN_STEP; - } else { - gain0_curr = gain0_tg; - } - } - } else { - if (gain0_curr > gain0_tg) { - if (gain0_curr - ANC_FADE_GAIN_STEP > gain0_tg) { - gain0_curr -= ANC_FADE_GAIN_STEP; - } else { - gain0_curr = gain0_tg; - } - } - } - - if (gain1_tg > 0) { - if (gain1_curr < gain1_tg) { - if (gain1_curr + ANC_FADE_GAIN_STEP < gain1_tg) { - gain1_curr += ANC_FADE_GAIN_STEP; - } else { - gain1_curr = gain1_tg; - } - } - } else { - if (gain1_curr > gain1_tg) { - if (gain1_curr - ANC_FADE_GAIN_STEP > gain1_tg) { - gain1_curr -= ANC_FADE_GAIN_STEP; - } else { - gain1_curr = gain1_tg; - } - } - } - - // TRACE(3,"[%s] cur gain: %d %d", __func__, gain0_curr, gain1_curr); - anc_set_gain(gain0_curr, gain1_curr, anc_type); - - if ((gain0_curr == gain0_tg) && (gain1_curr == gain1_tg)) { - return 0; - } - - return 1; -} - -int anc_usb_app_fadeout(enum ANC_TYPE_T anc_type) { - - /* - anc_set_gain(0, 0,anc_type); - - return 0; - */ - - int32_t gain0_curr, gain1_curr; - - anc_get_gain(&gain0_curr, &gain1_curr, anc_type); - - if (gain0_curr > 0) { - if (gain0_curr > ANC_FADE_GAIN_STEP) { - gain0_curr -= ANC_FADE_GAIN_STEP; - } else { - gain0_curr = 0; - } - } else if (gain0_curr < 0) { - if (gain0_curr < -ANC_FADE_GAIN_STEP) { - gain0_curr += ANC_FADE_GAIN_STEP; - } else { - gain0_curr = 0; - } - } - - if (gain1_curr > 0) { - if (gain1_curr > ANC_FADE_GAIN_STEP) { - gain1_curr -= ANC_FADE_GAIN_STEP; - } else { - gain1_curr = 0; - } - } else if (gain1_curr < 0) { - if (gain1_curr < -ANC_FADE_GAIN_STEP) { - gain1_curr += ANC_FADE_GAIN_STEP; - } else { - gain1_curr = 0; - } - } - - // TRACE(3,"[%s] gain: %d, %d", __func__, gain0_curr, gain1_curr); - anc_set_gain(gain0_curr, gain1_curr, anc_type); - - if ((gain0_curr == 0) && (gain1_curr == 0)) { - return 0; - } - - return 1; -} - -void anc_usb_app(bool on) { - TRACE(2, "%s: on=%d", __func__, on); - - if (anc_running == on) - return; - else - anc_running = on; - - if (on) { - anc_enable(); - } else { - anc_disable(); - } - -#ifdef CFG_HW_ANC_LED_PIN - if (on) { - hal_gpio_pin_set(CFG_HW_ANC_LED_PIN); - } else { - hal_gpio_pin_clr(CFG_HW_ANC_LED_PIN); - } -#endif -#ifdef CFG_HW_ANC_LED_PIN2 - if (on) { - hal_gpio_pin_set(CFG_HW_ANC_LED_PIN2); - } else { - hal_gpio_pin_clr(CFG_HW_ANC_LED_PIN2); - } -#endif -} - -bool anc_usb_app_get_status() { return anc_running; } - -#ifdef ANC_SWITCH_GPIO_PIN -static void anc_key_gpio_handler(enum HAL_GPIO_PIN_T pin) { - struct HAL_GPIO_IRQ_CFG_T gpiocfg; - - gpiocfg.irq_enable = false; - hal_gpio_setup_irq((enum HAL_GPIO_PIN_T)pinmux_anc.pin, &gpiocfg); - - gpio_irq_en = false; - gpio_pending = true; - - hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); -} - -static void anc_key_gpio_irq_setup(enum HAL_GPIO_IRQ_POLARITY_T polarity) { - struct HAL_GPIO_IRQ_CFG_T gpiocfg; - - if (gpio_irq_en && gpio_irq_polarity == polarity) { - return; - } - - gpio_irq_polarity = polarity; - gpio_irq_en = true; - - gpiocfg.irq_enable = true; - gpiocfg.irq_debounce = true; - gpiocfg.irq_polarity = polarity; - gpiocfg.irq_handler = anc_key_gpio_handler; - gpiocfg.irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE; - - hal_gpio_setup_irq((enum HAL_GPIO_PIN_T)pinmux_anc.pin, &gpiocfg); -} -#endif - -static enum ANC_KEY_STATE_T anc_key_level_to_state(bool level) { - enum ANC_KEY_STATE_T key_state; - -#ifdef ANC_SWITCH_GPIO_PIN - anc_key_gpio_irq_setup(level ? HAL_GPIO_IRQ_POLARITY_LOW_FALLING - : HAL_GPIO_IRQ_POLARITY_HIGH_RISING); -#endif - - key_state = level ? ANC_KEY_STATE_OPEN : ANC_KEY_STATE_CLOSE; - - return key_state; -} - -enum ANC_KEY_STATE_T anc_key_get_state(bool init_state) { - enum ANC_KEY_STATE_T key_state = ANC_KEY_STATE_NULL; - uint8_t level; - -#if defined(ANC_SWITCH_GPIO_PIN) - level = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)pinmux_anc.pin); - - level = level ? true : false; - -#elif defined(ANC_SWITCH_GPADC_CHAN) - HAL_GPADC_MV_T volt = 0; - - if (hal_gpadc_get_volt(ANC_SWITCH_GPADC_CHAN, &volt)) { - level = volt > ANC_SWITCH_VOLTAGE_THRESHOLD ? ANC_SWITCH_LEVEL_HIGH - : ANC_SWITCH_LEVEL_LOW; - // TRACE(3,"[%s] level = %d, volt = %d", __func__, level, volt); - } else { - // TRACE(1,"[%s] else...", __func__); - return ANC_KEY_STATE_NULL; - } -#else - return key_state; -#endif - - static uint32_t s_time; - static bool key_trigger = false; - static bool key_level = false; - - if (init_state) { - key_level = level; - return anc_key_level_to_state(level); - } - - if (key_trigger) { - if (key_level == level) { - key_trigger = false; - } else { - uint32_t diff_time_ms; - - diff_time_ms = TICKS_TO_MS(hal_sys_timer_get() - s_time); - - if (diff_time_ms >= 200) { - key_level = level; - key_trigger = false; - } - } - } else { - if (key_level != level) { - s_time = hal_sys_timer_get(); - key_trigger = true; - } - } - - if (key_trigger) { - key_state = ANC_KEY_STATE_DEBOUNCE; - } else { - key_state = anc_key_level_to_state(level); - } - - return key_state; -} - -static void anc_key_proc_open(bool from_key) { - int POSSIBLY_UNUSED ret; - uint32_t POSSIBLY_UNUSED time; - - time = hal_sys_timer_get(); - - if (anc_status == ANC_STATUS_INIT_CLOSE) { - TRACE(1, "[ANC KEY PROC] ANC INIT_CLOSE => INIT T:%u", time); - - anc_status = ANC_STATUS_INIT; - } else if (anc_status == ANC_STATUS_NULL) { - TRACE(1, "[ANC KEY PROC] ANC NULL => INIT T:%u", time); - - anc_full_open(); -#ifdef ANC_MODE_SWITCH_WITHOUT_FADE - } else if (anc_status == ANC_STATUS_ENABLE) { -#ifdef ANC_FF_ENABLED - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_FEEDFORWARD, ANC_GAIN_NO_DELAY); - TRACE(2, "[ANC KEY PROC] updata coefs ff %d: ret=%d", cur_coef_index, ret); -#endif -#ifdef ANC_FB_ENABLED - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_FEEDBACK, ANC_GAIN_NO_DELAY); - TRACE(2, "[ANC KEY PROC] updata coefs fb %d: ret=%d", cur_coef_index, ret); -#endif -#if defined(AUDIO_ANC_FB_MC_HW) - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_MUSICCANCLE, ANC_GAIN_NO_DELAY); - TRACE(2, "[ANC KEY PROC] anc_select_coef mc %d: ret=%d", cur_coef_index, - ret); -#endif -#if defined(AUDIO_ANC_TT_HW) - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_TALKTHRU, ANC_GAIN_NO_DELAY); - TRACE(2, "[ANC KEY PROC] anc_select_coef tt %d: ret=%d", cur_coef_index, - ret); -#endif - -#endif - } else { - if (from_key && anc_status == ANC_STATUS_INIT) { - TRACE(1, "[ANC KEY PROC] ANC ON2 T:%u", time); - // Let state machine enable ANC - return; - } - - TRACE(1, "[ANC KEY PROC] ANC ON T:%u", time); - -#ifdef ANC_FF_ENABLED - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_FEEDFORWARD, ANC_GAIN_DELAY); - TRACE(2, "[ANC KEY PROC] anc_select_coef ff %d: ret=%d", cur_coef_index, - ret); -#endif -#ifdef ANC_FB_ENABLED - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_FEEDBACK, ANC_GAIN_DELAY); - TRACE(2, "[ANC KEY PROC] anc_select_coef fb %d: ret=%d", cur_coef_index, - ret); -#endif -#if defined(AUDIO_ANC_FB_MC_HW) - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_MUSICCANCLE, ANC_GAIN_DELAY); - TRACE(2, "[ANC KEY PROC] anc_select_coef mc %d: ret=%d", cur_coef_index, - ret); -#endif -#if defined(AUDIO_ANC_TT_HW) - ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK], cur_coef_index, - ANC_TALKTHRU, ANC_GAIN_DELAY); - TRACE(2, "[ANC KEY PROC] anc_select_coef tt %d: ret=%d", cur_coef_index, - ret); -#endif - - anc_usb_app(true); -#ifdef ANC_FADE_IN_OUT - fadein_cnt = 0; - anc_status = ANC_STATUS_FADEIN; -#else - { - int32_t gain_ch_l, gain_ch_r; -#if defined(AUDIO_ANC_TT_HW) - anc_get_cfg_gain(&gain_ch_l, &gain_ch_r, ANC_TALKTHRU); - anc_set_gain(gain_ch_l, gain_ch_r, ANC_TALKTHRU); -#endif -#ifdef ANC_FF_ENABLED - anc_get_cfg_gain(&gain_ch_l, &gain_ch_r, ANC_FEEDFORWARD); - anc_set_gain(gain_ch_l, gain_ch_r, ANC_FEEDFORWARD); -#endif -#ifdef ANC_FB_ENABLED - anc_get_cfg_gain(&gain_ch_l, &gain_ch_r, ANC_FEEDBACK); - anc_set_gain(gain_ch_l, gain_ch_r, ANC_FEEDBACK); -#endif -#ifdef AUDIO_ANC_FB_MC_HW - anc_get_cfg_gain(&gain_ch_l, &gain_ch_r, ANC_MUSICCANCLE); - anc_set_gain(gain_ch_l, gain_ch_r, ANC_MUSICCANCLE); -#endif - } - anc_status = ANC_STATUS_ENABLE; -#endif - } -} - -static void anc_key_proc_close(bool from_key) { - uint32_t time; - - time = hal_sys_timer_get(); - anc_close_time = time; - - if (anc_status == ANC_STATUS_INIT) { - TRACE(1, "[ANC KEY PROC] ANC INIT => INIT_CLOSE T:%u", time); - - anc_status = ANC_STATUS_INIT_CLOSE; - } else if (anc_status == ANC_STATUS_INIT_CLOSE || - anc_status == ANC_STATUS_DISABLE) { - if (from_key) { - TRACE(1, "[ANC KEY PROC] ANC OFF2 T:%u", time); - // Let state machine to shutdown ANC - return; - } - - TRACE(1, "[ANC KEY PROC] ANC CLOSE => NULL T:%u", time); - - anc_full_close(); - } else { - TRACE(1, "[ANC KEY PROC] ANC OFF T:%u", time); - -#ifdef ANC_FADE_IN_OUT - fadeout_cnt = 0; - anc_status = ANC_STATUS_FADEOUT; -#else - anc_usb_app(false); - anc_status = ANC_STATUS_DISABLE; -#endif - } -} - -void anc_switch_on_off_ctrl(void) { - uint32_t lock; - enum ANC_KEY_STATE_T key_state = ANC_KEY_STATE_NULL; - - lock = int_lock(); - // Check if there is a state change - if (anc_key_event != HAL_KEY_EVENT_NONE) { - key_state = prev_key_state; - anc_key_event = HAL_KEY_EVENT_NONE; - } - int_unlock(lock); - - if (key_state == ANC_KEY_STATE_OPEN) { - anc_key_proc_open(true); - } else if (key_state == ANC_KEY_STATE_CLOSE) { - anc_key_proc_close(true); - } -} - -void anc_double_click_on_off(void) { - uint32_t lock; - enum HAL_KEY_EVENT_T event; - - lock = int_lock(); - event = anc_key_event; - anc_key_event = HAL_KEY_EVENT_NONE; - hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); - int_unlock(lock); - - if (event == HAL_KEY_EVENT_NONE) { - return; - } else if (event == HAL_KEY_EVENT_DOUBLECLICK) { - prev_key_state = (prev_key_state == ANC_KEY_STATE_OPEN) - ? ANC_KEY_STATE_CLOSE - : ANC_KEY_STATE_OPEN; - if (prev_key_state == ANC_KEY_STATE_OPEN) { - anc_key_proc_open(true); - } else { - anc_key_proc_close(true); - } - } -} - -void anc_click_on_off(void) { - enum ANC_STATE_UPDATE_T { - ANC_STATE_UPDATE_NULL = 0, - ANC_STATE_UPDATE_TALK_THROUGH, - ANC_STATE_UPDATE_COEF, - }; - - enum HAL_KEY_EVENT_T event; - enum ANC_STATE_UPDATE_T state_update = ANC_STATE_UPDATE_NULL; - uint8_t click_cnt = 0; - uint32_t lock; - - lock = int_lock(); - event = anc_key_event; - anc_key_event = HAL_KEY_EVENT_NONE; - hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); - int_unlock(lock); - - if (event == HAL_KEY_EVENT_NONE) { - return; -#ifdef ANC_TALK_THROUGH - } else if (event == HAL_KEY_EVENT_LONGPRESS) { - talk_through = !talk_through; - if (talk_through) { - state_update = ANC_STATE_UPDATE_TALK_THROUGH; - cur_coef_index = ANC_COEF_NUM; - TRACE(0, "[ANC KEY PROC] anc_talk_through on"); - } else { - state_update = ANC_STATE_UPDATE_COEF; - TRACE(0, "[ANC KEY PROC] anc_talk_through off"); - } -#endif - } else if (event == HAL_KEY_EVENT_CLICK) { - click_cnt = 1; - } - if (event == HAL_KEY_EVENT_DOUBLECLICK) { - click_cnt = 2; - } - if (event == HAL_KEY_EVENT_TRIPLECLICK) { - click_cnt = 3; - } - - if (click_cnt > 0) { - anc_ctrl_sm = (anc_ctrl_sm + click_cnt) % ANC_CTRL_SM_QTY; - state_update = ANC_STATE_UPDATE_COEF; -#ifdef ANC_TALK_THROUGH - talk_through = false; -#endif - } - - if (state_update == ANC_STATE_UPDATE_COEF) { - if (anc_ctrl_sm >= ANC_CTRL_SM_COEF_0 && - anc_ctrl_sm <= ANC_CTRL_SM_COEF_N) { - cur_coef_index = anc_ctrl_sm - ANC_CTRL_SM_COEF_0; - } - } - - if (state_update != ANC_STATE_UPDATE_NULL) { - if (anc_ctrl_sm == ANC_CTRL_SM_OFF && - state_update != ANC_STATE_UPDATE_TALK_THROUGH) { - anc_key_proc_close(true); - } else { - anc_key_proc_open(true); - } - } -} - -static void anc_key_process(void) { -#if defined(ANC_SWITCH_GPIO_PIN) || defined(ANC_SWITCH_GPADC_CHAN) - - anc_switch_on_off_ctrl(); - -#elif defined(ANC_KEY_DOUBLE_CLICK_ON_OFF) - - anc_double_click_on_off(); - -#else - - anc_click_on_off(); - -#endif -} - -void anc_state_transition(void) { - uint32_t t_time; -#ifdef ANC_FADE_IN_OUT - int res_ff = 0, res_fb = 0; -#ifdef AUDIO_ANC_TT_HW - int res_tt = 0; -#endif -#ifdef AUDIO_ANC_FB_MC_HW - int res_mc = 0; -#endif -#endif - - t_time = hal_sys_timer_get(); - - if (anc_status == ANC_STATUS_INIT) { - if (t_time - anc_init_time >= MS_TO_TICKS(ANC_INIT_ON_TIMEOUT_MS)) { - // TRACE(2,"[%s] anc init on T:%u", __func__, t_time); - anc_key_proc_open(false); - // fadein or open - } - } - -#ifdef ANC_FADE_IN_OUT - if (anc_status == ANC_STATUS_FADEIN) { - // process - if (fadein_cnt == 0) { - TRACE(2, "[%s] anc fadein started T:%u", __func__, t_time); - prev_fade_time = t_time; - fadein_cnt++; - } else if (fadein_cnt == 1) { - // delay 60 ticks - if (t_time - prev_fade_time >= 60) { - fadein_cnt++; - prev_fade_time = t_time; - } - } else { - // delay 1 ticks - if (t_time > prev_fade_time) { - // TRACE(2,"[%s] anc_usb_app_fadein T:%u", __func__, t_time); -#ifdef AUDIO_ANC_TT_HW - res_tt = anc_usb_app_fadein(ANC_TALKTHRU); -#endif -#ifdef ANC_FF_ENABLED - res_ff = anc_usb_app_fadein(ANC_FEEDFORWARD); -#endif -#ifdef ANC_FB_ENABLED - res_fb = anc_usb_app_fadein(ANC_FEEDBACK); -#endif -#ifdef AUDIO_ANC_FB_MC_HW - res_mc = anc_usb_app_fadein(ANC_MUSICCANCLE); -#endif - if (res_ff == 0 && res_fb == 0 -#ifdef AUDIO_ANC_TT_HW - && res_tt == 0 -#endif -#ifdef AUDIO_ANC_FB_MC_HW - && res_mc == 0 -#endif - ) { - anc_status = ANC_STATUS_ENABLE; - TRACE(2, "[%s] anc fadein done T:%u", __func__, t_time); - } else { - prev_fade_time = t_time; - } - } - } - } else if (anc_status == ANC_STATUS_FADEOUT) { - // process - if (fadeout_cnt == 0) { - TRACE(2, "[%s] anc fadeout started T:%u", __func__, t_time); - prev_fade_time = t_time; - fadeout_cnt++; - } else if (fadeout_cnt == 1) { - // delay 1 ticks - if (t_time > prev_fade_time) { - // TRACE(2,"[%s] anc_usb_app_fadeout T:%u", __func__, t_time); -#ifdef AUDIO_ANC_TT_HW - res_tt = anc_usb_app_fadeout(ANC_TALKTHRU); -#endif -#ifdef ANC_FF_ENABLED - res_ff = anc_usb_app_fadeout(ANC_FEEDFORWARD); -#endif -#ifdef ANC_FB_ENABLED - res_fb = anc_usb_app_fadeout(ANC_FEEDBACK); -#endif -#ifdef AUDIO_ANC_FB_MC_HW - res_mc = anc_usb_app_fadein(ANC_MUSICCANCLE); -#endif - if (res_ff == 0 && res_fb == 0 -#ifdef AUDIO_ANC_TT_HW - && res_tt == 0 -#endif -#ifdef AUDIO_ANC_FB_MC_HW - && res_mc == 0 -#endif - ) { - fadeout_cnt++; - } - - prev_fade_time = t_time; - } - } else { - anc_usb_app(false); - anc_status = ANC_STATUS_DISABLE; - TRACE(2, "[%s] anc fadeout done T:%u", __func__, t_time); - } - } -#endif - - if (anc_status == ANC_STATUS_INIT_CLOSE || anc_status == ANC_STATUS_DISABLE) { - if (t_time - anc_close_time >= MS_TO_TICKS(ANC_SHUTDOWN_TIMEOUT_MS)) { - // TRACE(2,"[%s] anc shutdown T:%u", __func__, t_time); - anc_key_proc_close(false); - } - } - - if (anc_status == ANC_STATUS_NULL || anc_status == ANC_STATUS_ENABLE) { - hal_cpu_wake_unlock(ANC_STATE_CPU_WAKE_USER); - } else { - hal_cpu_wake_lock(ANC_STATE_CPU_WAKE_USER); - } -} - -int anc_usb_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event) { -#if !defined(ANC_SWITCH_GPIO_PIN) && !defined(ANC_SWITCH_GPADC_CHAN) - -#ifdef ANC_KEY_DOUBLE_CLICK_ON_OFF - - if (code == ANC_FUNCTION_KEY) { - if (event == HAL_KEY_EVENT_DOUBLECLICK) { - anc_key_event = event; - hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); - // The key event has been processed - return 0; - } - } - -#else - - if (code == ANC_FUNCTION_KEY) { - if (event == HAL_KEY_EVENT_CLICK || event == HAL_KEY_EVENT_DOUBLECLICK || - event == HAL_KEY_EVENT_TRIPLECLICK || - event == HAL_KEY_EVENT_LONGPRESS) { - anc_key_event = event; - hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); - } - // The key event has been processed - return 0; - } - -#endif - -#endif - - // Let other applications check the key event - return 1; -} - -void anc_key_check(void) { - enum ANC_KEY_STATE_T key_state; - -#ifdef ANC_SWITCH_GPIO_PIN - uint32_t lock; - - gpio_pending = false; -#endif - - key_state = anc_key_get_state(false); - - if (key_state == ANC_KEY_STATE_NULL) { - return; - } else if (key_state == ANC_KEY_STATE_DEBOUNCE) { - hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); - } else if (key_state != prev_key_state) { - prev_key_state = key_state; - // Reuse click event to tag a state change - anc_key_event = HAL_KEY_EVENT_CLICK; - hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); - } else if (anc_key_event == HAL_KEY_EVENT_NONE) { -#ifdef ANC_SWITCH_GPIO_PIN - lock = int_lock(); - if (!gpio_pending) { - hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); - } - int_unlock(lock); -#else - hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); -#endif - } -} - -void anc_key_gpadc_timer_handler(void *param) { - hwtimer_start(gpadc_timer, ANC_SWITCH_CHECK_INTERVAL); -} - -static void anc_key_init(void) { -#if defined(ANC_SWITCH_GPIO_PIN) - hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&pinmux_anc, 1); - hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)pinmux_anc.pin, HAL_GPIO_DIR_IN, 0); - // Make sure gpio value is ready - hal_sys_timer_delay(3); -#elif defined(ANC_SWITCH_GPADC_CHAN) - hal_gpadc_open(ANC_SWITCH_GPADC_CHAN, HAL_GPADC_ATP_20MS, NULL); - // Make sure gpadc channel data is ready - hal_sys_timer_delay(6); - gpadc_timer = hwtimer_alloc(anc_key_gpadc_timer_handler, NULL); - ASSERT(gpadc_timer, "Failed to alloc gpadc timer"); - hwtimer_start(gpadc_timer, ANC_SWITCH_CHECK_INTERVAL); -#endif - - // Add other key initialize -} - -#if defined(USB_AUDIO_DYN_CFG) && !defined(__AUDIO_RESAMPLE__) -static void anc_sample_rate_change(enum AUD_STREAM_T stream, - enum AUD_SAMPRATE_T rate, - enum AUD_SAMPRATE_T *new_play, - enum AUD_SAMPRATE_T *new_cap) { - enum AUD_SAMPRATE_T play_rate, cap_rate; - - if (anc_sample_rate[stream] != rate) { -#ifdef CHIP_BEST1000 - if (stream == AUD_STREAM_PLAYBACK) { - play_rate = rate; - cap_rate = rate * (anc_sample_rate[AUD_STREAM_CAPTURE] / - anc_sample_rate[AUD_STREAM_PLAYBACK]); - } else { - play_rate = rate / (anc_sample_rate[AUD_STREAM_CAPTURE] / - anc_sample_rate[AUD_STREAM_PLAYBACK]); - cap_rate = rate; - } -#else - play_rate = rate; - cap_rate = rate; -#ifdef ANC_FF_ENABLED - anc_select_coef(play_rate, cur_coef_index, ANC_FEEDFORWARD, - ANC_GAIN_NO_DELAY); -#endif - -#ifdef ANC_FB_ENABLED - anc_select_coef(play_rate, cur_coef_index, ANC_FEEDBACK, ANC_GAIN_NO_DELAY); -#endif - -#if defined(AUDIO_ANC_FB_MC_HW) - anc_select_coef(play_rate, cur_coef_index, ANC_MUSICCANCLE, - ANC_GAIN_NO_DELAY); -#endif - -#if defined(AUDIO_ANC_TT_HW) - anc_select_coef(play_rate, cur_coef_index, ANC_TALKTHRU, ANC_GAIN_NO_DELAY); -#endif - -#endif - - TRACE(5, "%s: Update anc sample rate from %u/%u to %u/%u", __func__, - anc_sample_rate[AUD_STREAM_PLAYBACK], - anc_sample_rate[AUD_STREAM_CAPTURE], play_rate, cap_rate); - - if (new_play) { - *new_play = play_rate; - } - if (new_cap) { - *new_cap = cap_rate; - } - - anc_sample_rate[AUD_STREAM_PLAYBACK] = play_rate; - anc_sample_rate[AUD_STREAM_CAPTURE] = cap_rate; - } -} -#endif - -static void anc_full_open(void) { - AF_ANC_HANDLER POSSIBLY_UNUSED handler; - -#if defined(USB_AUDIO_DYN_CFG) && !defined(__AUDIO_RESAMPLE__) - handler = anc_sample_rate_change; -#else - handler = NULL; -#endif - -#ifdef USB_AUDIO_APP - usb_audio_keep_streams_running(true); -#endif - - pmu_anc_config(1); - -#ifdef ANC_FF_ENABLED - af_anc_open(ANC_FEEDFORWARD, anc_sample_rate[AUD_STREAM_PLAYBACK], - anc_sample_rate[AUD_STREAM_CAPTURE], handler); - anc_open(ANC_FEEDFORWARD); -#endif - -#ifdef ANC_FB_ENABLED - af_anc_open(ANC_FEEDBACK, anc_sample_rate[AUD_STREAM_PLAYBACK], - anc_sample_rate[AUD_STREAM_CAPTURE], handler); - anc_open(ANC_FEEDBACK); -#if defined(AUDIO_ANC_FB_MC_HW) - anc_open(ANC_MUSICCANCLE); -#endif -#endif - -#if defined(AUDIO_ANC_TT_HW) - anc_open(ANC_TALKTHRU); -#endif - - anc_init_time = hal_sys_timer_get(); - anc_status = ANC_STATUS_INIT; -} - -static void anc_full_close(void) { - -#if defined(AUDIO_ANC_TT_HW) - anc_close(ANC_TALKTHRU); -#endif - -#ifdef ANC_FF_ENABLED - anc_close(ANC_FEEDFORWARD); - af_anc_close(ANC_FEEDFORWARD); -#endif - -#ifdef ANC_FB_ENABLED -#if defined(AUDIO_ANC_FB_MC_HW) - anc_close(ANC_MUSICCANCLE); -#endif - anc_close(ANC_FEEDBACK); - af_anc_close(ANC_FEEDBACK); -#endif - - pmu_anc_config(0); - - anc_status = ANC_STATUS_NULL; - -#ifdef USB_AUDIO_APP - usb_audio_keep_streams_running(false); -#endif -} - -void anc_usb_app_loop(void) { -#if defined(ANC_SWITCH_GPIO_PIN) || defined(ANC_SWITCH_GPADC_CHAN) - anc_key_check(); -#endif - anc_key_process(); - anc_state_transition(); -} - -void anc_usb_app_init(enum AUD_IO_PATH_T input_path, - enum AUD_SAMPRATE_T playback_rate, - enum AUD_SAMPRATE_T capture_rate) { - enum ANC_KEY_STATE_T key_state; - -#ifdef CFG_HW_ANC_LED_PIN - hal_iomux_init(pinmux_anc_led, ARRAY_SIZE(pinmux_anc_led)); - hal_gpio_pin_set_dir(CFG_HW_ANC_LED_PIN, HAL_GPIO_DIR_OUT, 0); -#endif -#ifdef CFG_HW_ANC_LED_PIN2 - hal_iomux_init(pinmux_anc_led2, ARRAY_SIZE(pinmux_anc_led2)); - hal_gpio_pin_set_dir(CFG_HW_ANC_LED_PIN2, HAL_GPIO_DIR_OUT, 0); -#endif - - anc_key_init(); - -#ifdef __AUDIO_SECTION_SUPPT__ - anc_load_cfg(); -#endif - - anc_sample_rate[AUD_STREAM_PLAYBACK] = - hal_codec_anc_convert_rate(playback_rate); - anc_sample_rate[AUD_STREAM_CAPTURE] = - hal_codec_anc_convert_rate(capture_rate); - -#if defined(ANC_SWITCH_GPIO_PIN) || defined(ANC_SWITCH_GPADC_CHAN) - key_state = anc_key_get_state(true); - prev_key_state = key_state; -#elif defined(ANC_KEY_DOUBLE_CLICK_ON_OFF) - key_state = ANC_KEY_STATE_OPEN; - prev_key_state = key_state; -#else - key_state = ANC_KEY_STATE_OPEN; - anc_ctrl_sm = ANC_CTRL_SM_COEF_0 + cur_coef_index; -#endif - -#ifdef ANC_INIT_OFF - key_state = ANC_KEY_STATE_CLOSE; - prev_key_state = key_state; - anc_ctrl_sm = ANC_CTRL_SM_OFF; -#endif - - if (key_state == ANC_KEY_STATE_OPEN) { - anc_full_open(); - } -} - -void anc_usb_app_term(void) { anc_full_close(); } diff --git a/tests/anc_usb/anc_usb_app.h b/tests/anc_usb/anc_usb_app.h deleted file mode 100644 index 5d00204..0000000 --- a/tests/anc_usb/anc_usb_app.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __ANC_USB_APP_H__ -#define __ANC_USB_APP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" -#include "hal_aud.h" -#include "hal_key.h" - -void anc_usb_app(bool on); - -bool anc_usb_app_get_status(); - -void anc_usb_app_init(enum AUD_IO_PATH_T input_path, enum AUD_SAMPRATE_T playback_rate, enum AUD_SAMPRATE_T capture_rate); - -void anc_usb_app_term(void); - -void anc_usb_app_loop(void); - -int anc_usb_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event); - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/tests/anc_usb/dualadc_audio_app.c b/tests/anc_usb/dualadc_audio_app.c deleted file mode 100644 index d515999..0000000 --- a/tests/anc_usb/dualadc_audio_app.c +++ /dev/null @@ -1,321 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "analog.h" -#include "audioflinger.h" -#include "hal_aud.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "pmu.h" -#include "string.h" - -static uint8_t *playback_buf; -static uint32_t playback_size; - -static uint8_t *capture_buf; -static uint32_t capture_size; - -/* -static void get_mic_data_max(short *buf, uint32_t len) -{ - int max0 = -32768, min0 = 32767, diff0 = 0; - int max1 = -32768, min1 = 32767, diff1 = 0; - - for(uint32_t i=0; imax0) - { - max0 = buf[i+0]; - } - - if(buf[i+0]max1) - { - max1 = buf[i+1]; - } - - if(buf[i+1]= playback_size) { - pos = 0; - } - stime = hal_sys_timer_get(); - - TRACE(4,"%s irqDur:%d Len:%d pos:%d", __func__, TICKS_TO_MS(stime - preIrqTime), len, pos); - - preIrqTime = stime; -#endif - return 0; -} - -#if 1 -#define MWSPT_NSEC 3 -// static const int NL[MWSPT_NSEC] = { 1, 3, 1 }; -static const float NUM[MWSPT_NSEC][3] = { - {0.0002616526908, 0, 0}, {1, 2, 1}, {1, 0, 0}}; - -// static const int DL[MWSPT_NSEC] = { 1, 3, 1 }; -static const float DEN[MWSPT_NSEC][3] = { - {1, 0, 0}, {1, -1.953727961, 0.9547745585}, {1, 0, 0}}; - -#else - -#define MWSPT_NSEC 3 -static const int NL[MWSPT_NSEC] = {1, 3, 1}; -static const float NUM[MWSPT_NSEC][3] = { - {0.0002616526908, 0, 0}, {1, 2, 1}, {1, 0, 0}}; -static const int DL[MWSPT_NSEC] = {1, 3, 1}; -static const float DEN[MWSPT_NSEC][3] = { - {1, 0, 0}, {1, -1.953727961, 0.9547745585}, {1, 0, 0}}; - -#endif - -static uint32_t dualadc_audio_data_capture(uint8_t *buf, uint32_t len) { - - TRACE(0, "capture"); - -#if 0 - if(buf==capture_buf) - { - short *BufSrcL = (short *)capture_buf; - short *BufSrcR = (short *)(capture_buf+2); - short *BufDstL = (short *)playback_buf; - short *BufDstR = (short *)(playback_buf+2); - - for(int i=0,j=0;i 32600) { - OutValue = ((int)BufSrcR[i]) << 6; - } else if (PcmValue > (32600 / 2) && PcmValue < 32600) { - if (BufSrcR[i] > 512) { - OutValue = PcmValue * (32600 - PcmValue) + - (((int)BufSrcR[i]) << 6) * (PcmValue - (32600 / 2)); - OutValue = OutValue / (32600 / 2); - } else { - OutValue = PcmValue; - } - } else if (PcmValue < -32700) { - OutValue = ((int)BufSrcR[i]) << 6; - } else if (PcmValue > -32700 && PcmValue < -(32700 / 2)) { - - if (BufSrcR[i] < -512) { - OutValue = PcmValue * (-PcmValue - (32700 / 2)) + - (((int)BufSrcR[i]) << 6) * (32700 + PcmValue); - OutValue = OutValue / (32700 / 2); - } else { - OutValue = PcmValue; - } - - } else { - OutValue = PcmValue; - } - - OutValue = OutValue >> 6; - // OutValue=BufSrcR[i]; - - { - static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; - - x0 = (OutValue * NUM[0][0]); - - y0 = x0 * NUM[1][0] + x1 * NUM[1][1] + x2 * NUM[1][2] - y1 * DEN[1][1] - - y2 * DEN[1][2]; - - y2 = y1; - y1 = y0; - x2 = x1; - x1 = x0; - - if (y0 > 32767.0f) { - y0 = 32767.0f; - } - - if (y0 < -32768.0f) { - y0 = -32768.0f; - } - - OutValue = (short)y0; - } - - BufDstL[j] = OutValue; - BufDstR[j] = OutValue; - } - -#endif - -#if 0 - uint32_t stime; - uint32_t pos; - static uint32_t preIrqTime = 0; - - pos = buf + len - capture_buf; - if (pos >= capture_size) { - pos = 0; - } - stime = hal_sys_timer_get(); - - TRACE(4,"%s irqDur:%d Len:%d pos:%d", __func__, TICKS_TO_MS(stime - preIrqTime), len, pos); - - preIrqTime = stime; -#endif - return 0; -} - -void dualadc_audio_app(bool on) { - - struct AF_STREAM_CONFIG_T stream_cfg; - enum AUD_SAMPRATE_T sample_rate_play; - enum AUD_SAMPRATE_T POSSIBLY_UNUSED sample_rate_capture; - - static bool isRun = false; - - if (isRun == on) - return; - else - isRun = on; - - TRACE(2, "%s: on=%d", __FUNCTION__, on); - - sample_rate_play = AUD_SAMPRATE_192000; - sample_rate_capture = AUD_SAMPRATE_192000; - - if (on) { - - memset(&stream_cfg, 0, sizeof(stream_cfg)); - - stream_cfg.bits = AUD_BITS_16; - stream_cfg.channel_num = AUD_CHANNEL_NUM_2; - stream_cfg.sample_rate = sample_rate_play; - - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; - stream_cfg.vol = 0x06; - - stream_cfg.handler = dualadc_audio_data_playback; - stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; - - stream_cfg.data_ptr = playback_buf; - stream_cfg.data_size = playback_size; - af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); - - stream_cfg.bits = AUD_BITS_16; - stream_cfg.channel_num = AUD_CHANNEL_NUM_2; - stream_cfg.sample_rate = sample_rate_capture; - stream_cfg.vol = 0x01; - - stream_cfg.handler = dualadc_audio_data_capture; - stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; - - stream_cfg.data_ptr = capture_buf; - stream_cfg.data_size = capture_size; - af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); - - af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - - } else { - - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - } -} - -void dualadc_audio_app_init(uint8_t *play_buf, uint32_t play_size, - uint8_t *cap_buf, uint32_t cap_size) { - playback_buf = play_buf; - playback_size = play_size; - capture_buf = cap_buf; - capture_size = cap_size; -} - -void dualadc_audio_app_term(void) { - playback_buf = NULL; - playback_size = 0; - capture_buf = NULL; - capture_size = 0; -} diff --git a/tests/anc_usb/dualadc_audio_app.h b/tests/anc_usb/dualadc_audio_app.h deleted file mode 100644 index 98a8364..0000000 --- a/tests/anc_usb/dualadc_audio_app.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __DUALADC_AUDIO_TEST_H__ -#define __DUALADC_AUDIO_TEST_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -#include "plat_types.h" - -void dualadc_audio_app(bool on); - -void dualadc_audio_app_init(uint8_t *play_buf, uint32_t play_size, uint8_t *cap_buf, uint32_t cap_size); - -void dualadc_audio_app_term(void); - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/tests/anc_usb/main.c b/tests/anc_usb/main.c deleted file mode 100644 index 614f313..0000000 --- a/tests/anc_usb/main.c +++ /dev/null @@ -1,519 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "adda_loop_app.h" -#include "analog.h" -#include "anc_usb_app.h" -#include "audio_process.h" -#include "audioflinger.h" -#include "cmsis.h" -#include "dualadc_audio_app.h" -#include "hal_bootmode.h" -#include "hal_cmu.h" -#include "hal_dma.h" -#include "hal_gpadc.h" -#include "hal_iomux.h" -#include "hal_key.h" -#include "hal_norflash.h" -#include "hal_sleep.h" -#include "hal_sysfreq.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hwtimer_list.h" -#include "main_entry.h" -#include "plat_addr_map.h" -#include "pmu.h" -#include "string.h" -#include "tgt_hardware.h" -#include "usb_audio_app.h" -#include "usb_audio_frm_defs.h" -#if defined(_VENDOR_MSG_SUPPT_) -#include "usb_vendor_msg.h" -#endif - -#ifdef RTOS -#include "cmsis_os.h" -#endif -#ifdef __PC_CMD_UART__ -#include "hal_cmd.h" -#endif - -#ifdef USB_AUDIO_SPEECH -#define CODEC_BUFF_FRAME_NUM (2 * 16) -#define USB_BUFF_FRAME_NUM (CODEC_BUFF_FRAME_NUM * 2) -#else -#define CODEC_BUFF_FRAME_NUM 4 -#define USB_BUFF_FRAME_NUM 10 -#endif - -#if (CODEC_BUFF_FRAME_NUM >= USB_BUFF_FRAME_NUM) -#error \ - "Codec buffer frame num should be less than usb buffer frame num (on the requirement of conflict ctrl)" -#endif - -#ifdef USB_AUDIO_DYN_CFG - -#define USB_AUDIO_PLAYBACK_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_PLAYBACK *CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) -#define USB_AUDIO_CAPTURE_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_CAPTURE *CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) - -#define USB_AUDIO_RECV_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_RECV *USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) -#define USB_AUDIO_SEND_BUFF_SIZE \ - NON_EXP_ALIGN(MAX_FRAME_SIZE_SEND *USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) - -#if defined(CHIP_BEST1000) -// FIR EQ is working on 16-bit -// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int16_t) -#define USB_AUDIO_FIR_EQ_BUFF_SIZE USB_AUDIO_PLAYBACK_BUFF_SIZE -#elif defined(CHIP_BEST2000) -// FIR EQ is working on 32-bit -// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) -#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * 2) -#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) -// FIR EQ is working on 32-bit -// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) -#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) -#define USB_AUDIO_IIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) -#define USB_AUDIO_DSD_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * 16) -#endif - -#else // !USB_AUDIO_DYN_CFG - -#define USB_AUDIO_PLAYBACK_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_PLAYBACK *CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) -#define USB_AUDIO_CAPTURE_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_CAPTURE *CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) - -#define USB_AUDIO_RECV_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_RECV *USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) -#define USB_AUDIO_SEND_BUFF_SIZE \ - NON_EXP_ALIGN(FRAME_SIZE_SEND *USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) - -#if defined(CHIP_BEST1000) -// FIR EQ is working on 16-bit -#define USB_AUDIO_FIR_EQ_BUFF_SIZE \ - (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int16_t) / SAMPLE_SIZE_PLAYBACK) -#elif defined(CHIP_BEST2000) -// FIR EQ is working on 32-bit -#define USB_AUDIO_FIR_EQ_BUFF_SIZE \ - (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int32_t) / SAMPLE_SIZE_PLAYBACK) -#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) -// FIR EQ is working on 32-bit -#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) -#define USB_AUDIO_IIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) -#define USB_AUDIO_DSD_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * 16) -#endif - -#endif // !USB_AUDIO_DYN_CFG - -#if (defined(CHIP_BEST1000) && \ - (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) && \ - (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) -// Resample input buffer size should be (half_of_max_sample_num * -// SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE). half_of_max_sample_num = 48000 / -// 1000 * CODEC_BUFF_FRAME_NUM / 2 * 48 / 44 -#define RESAMPLE_INPUT_BUFF_SIZE \ - ALIGN(48000 / 1000 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE * \ - CODEC_BUFF_FRAME_NUM / 2 * 48 / 44, \ - 4) -#else -#define RESAMPLE_INPUT_BUFF_SIZE 0 -#endif -// Resample history buffer size should be -// sizeof(struct RESAMPLE_CTRL_T) + ((SAMPLE_NUM + phase_coef_num) * -// SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) -#define RESAMPLE_HISTORY_BUFF_SIZE \ - (50 + (256 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE)) -#define USB_AUDIO_RESAMPLE_BUFF_SIZE \ - (RESAMPLE_INPUT_BUFF_SIZE + RESAMPLE_HISTORY_BUFF_SIZE) - -#define ALIGNED4 ALIGNED(4) - -#if defined(USB_AUDIO_APP) || defined(DUALADC_AUDIO_TEST) - -#ifdef AUDIO_ANC_FB_MC -static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE * - 9]; // max 48->384 or 44.1->44.1*8; -#else -static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE]; -#endif - -static uint8_t ALIGNED4 capture_buff[USB_AUDIO_CAPTURE_BUFF_SIZE]; - -#endif - -#ifdef USB_AUDIO_APP - -#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) -static uint8_t ALIGNED4 - eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE + USB_AUDIO_IIR_EQ_BUFF_SIZE]; -#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__) -static uint8_t ALIGNED4 eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE]; -#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) -static uint8_t ALIGNED4 eq_buff[USB_AUDIO_IIR_EQ_BUFF_SIZE]; -#else -static uint8_t ALIGNED4 eq_buff[0]; -#endif - -#ifdef SW_CAPTURE_RESAMPLE -static uint8_t ALIGNED4 resample_buff[USB_AUDIO_RESAMPLE_BUFF_SIZE]; -#else -static uint8_t ALIGNED4 resample_buff[0]; -#endif - -static uint8_t ALIGNED4 recv_buff[USB_AUDIO_RECV_BUFF_SIZE]; -static uint8_t ALIGNED4 send_buff[USB_AUDIO_SEND_BUFF_SIZE]; - -#ifdef USB_AUDIO_MULTIFUNC -static uint8_t ALIGNED4 recv2_buff[USB_AUDIO_RECV_BUFF_SIZE]; -#endif - -#endif - -#ifdef CFG_HW_KEY_LED_PIN -const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_key_led[1] = { - {CFG_HW_KEY_LED_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, - HAL_IOMUX_PIN_NOPULL}, -}; -#endif - -#ifdef CFG_MIC_KEY -extern void mic_key_open(void); -#endif - -static void uart_i2c_switch(void) { - static int flag = 0; - - flag ^= 1; - - if (flag) { - hal_iomux_set_analog_i2c(); - } else { - hal_iomux_set_uart0(); - } -} - -static int key_event_process(uint32_t key_code, uint8_t key_event) { - TRACE(3, "%s: code=0x%X, event=%u", __FUNCTION__, key_code, key_event); - -#ifdef CFG_HW_KEY_LED_PIN - if (key_event == HAL_KEY_EVENT_DOWN) { - hal_gpio_pin_set(CFG_HW_KEY_LED_PIN); - } else if (key_event == HAL_KEY_EVENT_UP) { - hal_gpio_pin_clr(CFG_HW_KEY_LED_PIN); - } -#endif - -#ifdef USB_AUDIO_APP - if (usb_audio_app_key(key_code, key_event) == 0) { - return 0; - } -#endif - -#ifdef ANC_APP - if (anc_usb_app_key(key_code, key_event) == 0) { - return 0; - } -#endif - - if (key_event == HAL_KEY_EVENT_CLICK) { - if (key_code == HAL_KEY_CODE_FN9) { - uart_i2c_switch(); - } - } - - return 0; -} - -void anc_usb_open(void) { - TRACE(1, "%s", __FUNCTION__); - -#ifdef __AUDIO_RESAMPLE__ - hal_cmu_audio_resample_enable(); -#endif -#ifdef USB_AUDIO_APP - struct USB_AUDIO_BUF_CFG cfg; - - memset(&cfg, 0, sizeof(cfg)); - cfg.play_buf = playback_buff; -#ifdef AUDIO_ANC_FB_MC - cfg.play_size = sizeof(playback_buff) / 9; -#else - cfg.play_size = sizeof(playback_buff); -#endif - cfg.cap_buf = capture_buff; - cfg.cap_size = sizeof(capture_buff); - cfg.recv_buf = recv_buff; - cfg.recv_size = sizeof(recv_buff); - cfg.send_buf = send_buff; - cfg.send_size = sizeof(send_buff); - cfg.eq_buf = eq_buff; - cfg.eq_size = sizeof(eq_buff); - cfg.resample_buf = resample_buff; - cfg.resample_size = sizeof(resample_buff); -#ifdef USB_AUDIO_MULTIFUNC - cfg.recv2_buf = recv2_buff; - cfg.recv2_size = sizeof(recv2_buff); -#endif - - usb_audio_app_init(&cfg); - usb_audio_app(true); -#endif - -#ifdef ANC_APP - anc_usb_app_init(AUD_INPUT_PATH_MAINMIC, SAMPLE_RATE_PLAYBACK, - SAMPLE_RATE_CAPTURE); -#endif - -#ifdef DUALADC_AUDIO_TEST - dualadc_audio_app_init(playback_buff, USB_AUDIO_PLAYBACK_BUFF_SIZE, - capture_buff, USB_AUDIO_CAPTURE_BUFF_SIZE); - dualadc_audio_app(true); -#endif - -#ifdef ADDA_LOOP_APP - adda_loop_app(true); -#endif - -#if defined(_VENDOR_MSG_SUPPT_) -#ifndef USB_ANC_MC_EQ_TUNING - vendor_info_init(); -#endif -#endif - -#if defined(CFG_MIC_KEY) - mic_key_open(); -#endif - - // Allow sleep - hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_32K); - - while (1) { -#ifdef USB_AUDIO_APP - usb_audio_app_loop(); -#endif - -#ifdef ANC_APP - anc_usb_app_loop(); -#endif - -#ifdef ADDA_LOOP_APP - adda_loop_app_loop(); -#endif - -#ifdef RTOS - // Let the task sleep - osDelay(20); -#else // !RTOS - -#ifdef USB_EQ_TUNING - audio_eq_usb_eq_update(); -#endif - - hal_sleep_enter_sleep(); - -#endif // !RTOS - } -} - -#ifdef CFG_HW_GPADCKEY -void gpadc_key_handler(uint16_t irq_val, HAL_GPADC_MV_T volt) { - static uint16_t stable_cnt = 0; - static uint16_t click_cnt = 0; - static uint32_t click_time; - uint32_t time; - enum HAL_KEY_EVENT_T event; - bool send_event = false; - - time = hal_sys_timer_get(); - - if (volt < 100) { - stable_cnt++; - // TRACE(5,"adc_key down: volt=%u stable=%u click_cnt=%u click_time=%u - // time=%u", volt, stable_cnt, click_cnt, click_time, time); - } else { - if (stable_cnt > 1) { - // TRACE(5,"adc_key up: volt=%u stable=%u click_cnt=%u click_time=%u - // time=%u", volt, stable_cnt, click_cnt, click_time, time); - if (click_cnt == 0 || (time - click_time) < MS_TO_TICKS(500)) { - click_time = time; - click_cnt++; - if (click_cnt >= 3) { - send_event = true; - } - } else { - send_event = true; - } - } - stable_cnt = 0; - - if (click_cnt > 0 && (time - click_time) >= MS_TO_TICKS(500)) { - send_event = true; - } - - if (send_event) { - // TRACE(5,"adc_key click: volt=%u stable=%u click_cnt=%u click_time=%u - // time=%u", volt, stable_cnt, click_cnt, click_time, time); - if (click_cnt == 1) { - event = HAL_KEY_EVENT_CLICK; - } else if (click_cnt == 2) { - event = HAL_KEY_EVENT_DOUBLECLICK; - } else { - event = HAL_KEY_EVENT_TRIPLECLICK; - } - key_event_process(CFG_HW_GPADCKEY, event); - click_cnt = 0; - } - } -} -#endif - -#ifdef DEBUG_MODE_USB_DOWNLOAD -static void process_usb_download_mode(void) { - if (pmu_charger_get_status() == PMU_CHARGER_PLUGIN && hal_pwrkey_pressed()) { - hal_sw_bootmode_set(HAL_SW_BOOTMODE_FORCE_USB_DLD); - hal_cmu_sys_reboot(); - } -} -#endif - -// GDB can set a breakpoint on the main function only if it is -// declared as below, when linking with STD libraries. -int MAIN_ENTRY(void) { -#ifdef INTSRAM_RUN -// hal_norflash_sleep(HAL_NORFLASH_ID_0); -#endif - -#ifdef DEBUG_MODE_USB_DOWNLOAD - process_usb_download_mode(); -#endif - - hal_cmu_simu_init(); - hwtimer_init(); - hal_audma_open(); - hal_gpdma_open(); - -#if (DEBUG_PORT == 2) - hal_iomux_set_analog_i2c(); - hal_iomux_set_uart1(); - hal_trace_open(HAL_TRACE_TRANSPORT_UART1); -#else - hal_iomux_set_uart0(); - hal_trace_open(HAL_TRACE_TRANSPORT_UART0); -#endif - -#if !defined(SIMU) - uint8_t flash_id[HAL_NORFLASH_DEVICE_ID_LEN]; - hal_norflash_get_id(HAL_NORFLASH_ID_0, flash_id, ARRAY_SIZE(flash_id)); - TRACE(3, "FLASH_ID: %02X-%02X-%02X", flash_id[0], flash_id[1], flash_id[2]); -#endif - - pmu_open(); - analog_open(); - af_open(); - hal_sleep_start_stats(10000, 10000); - -#ifdef CHIP_BEST1000 - hal_cmu_force_bt_sleep(); -#endif - - hal_key_open(0, key_event_process); -#ifdef CFG_HW_GPADCKEY - hal_gpadc_open(HAL_GPADC_CHAN_3, HAL_GPADC_ATP_20MS, gpadc_key_handler); -#endif - -#ifdef CFG_HW_KEY_LED_PIN - hal_iomux_init(pinmux_key_led, ARRAY_SIZE(pinmux_key_led)); - hal_gpio_pin_set_dir(CFG_HW_KEY_LED_PIN, HAL_GPIO_DIR_OUT, 0); -#endif - -#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || \ - defined(__HW_DAC_IIR_EQ_PROCESS__) || defined(__HW_IIR_EQ_PROCESS__) - audio_process_init(); - // TODO: Get EQ store parameter - // audio_eq_fir_update_cfg(int16_t *coef, int16_t num); - // audio_eq_iir_update_cfg(int *gain, int num); -#endif - - anc_usb_open(); - - TRACE(0, "byebye~~~\n"); - - hal_sys_timer_delay(MS_TO_TICKS(200)); - - pmu_shutdown(); - - return 0; -} - -//-------------------------------------------------------------------------------- -// Start of Programmer Entry -//-------------------------------------------------------------------------------- -#ifdef PROGRAMMER -#include "cmsis_nvic.h" -#include "hal_chipid.h" -#include "tool_msg.h" - -extern uint32_t __StackTop[]; -extern uint32_t __StackLimit[]; -extern uint32_t __bss_start__[]; -extern uint32_t __bss_end__[]; - -#define EXEC_STRUCT_LOC __attribute__((section(".exec_struct"))) - -bool task_yield(void) { return true; } - -void anc_usb_ramrun_main(void) { - uint32_t *dst; - - for (dst = __bss_start__; dst < __bss_end__; dst++) { - *dst = 0; - } - - NVIC_InitVectors(); -#ifdef UNALIGNED_ACCESS - SystemInit(); -#endif - hal_cmu_setup(); - main(); - -#if !defined(PROGRAMMER_INFLASH) - SAFE_PROGRAM_STOP(); -#endif -} - -void anc_usb_ramrun_start(void) { - GotBaseInit(); -#ifdef __ARM_ARCH_8M_MAIN__ - __set_MSPLIM((uint32_t)__StackLimit); -#endif - __set_MSP((uint32_t)__StackTop); - anc_usb_ramrun_main(); -} - -const struct exec_struct_t EXEC_STRUCT_LOC ramrun_struct = { - .entry = (uint32_t)anc_usb_ramrun_start, - .param = 0, - .sp = 0, - .exec_addr = (uint32_t)&ramrun_struct, -}; - -void programmer_start(void) __attribute__((weak, alias("anc_usb_ramrun_main"))); -#endif -//-------------------------------------------------------------------------------- -// End of Programmer Entry -//-------------------------------------------------------------------------------- diff --git a/tests/anc_usb/memutils.c b/tests/anc_usb/memutils.c deleted file mode 100644 index 48c2374..0000000 --- a/tests/anc_usb/memutils.c +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "memutils.h" -#include "plat_types.h" -#include "string.h" - -#define ALIGNED32(a) (((uint32_t)(a)&3) == 0) -#define ALIGNED16(a) (((uint32_t)(a)&1) == 0) - -void *copy_mem32(void *dst, const void *src, unsigned int size) { - uint32_t *d = dst; - const uint32_t *s = src; - const uint32_t *e = s + size / 4; - - while (s < e) { - *d++ = *s++; - } - - return dst; -} - -void *copy_mem16(void *dst, const void *src, unsigned int size) { - uint16_t *d = dst; - const uint16_t *s = src; - const uint16_t *e = s + size / 2; - - while (s < e) { - *d++ = *s++; - } - - return dst; -} - -void *copy_mem(void *dst, const void *src, unsigned int size) { - if (ALIGNED32(dst) && ALIGNED32(src) && ALIGNED32(size)) { - return copy_mem32(dst, src, size); - } else if (ALIGNED16(dst) && ALIGNED16(src) && ALIGNED16(size)) { - return copy_mem16(dst, src, size); - } else { - return memcpy(dst, src, size); - } -} - -void *zero_mem32(void *dst, unsigned int size) { - uint32_t *d = dst; - uint32_t count = size / 4; - - while (count--) { - *d++ = 0; - } - - return dst; -} - -void *zero_mem16(void *dst, unsigned int size) { - uint16_t *d = dst; - uint32_t count = size / 2; - - while (count--) { - *d++ = 0; - } - - return dst; -} - -void *zero_mem(void *dst, unsigned int size) { - if (ALIGNED32(dst) && ALIGNED32(size)) { - return zero_mem32(dst, size); - } else if (ALIGNED16(dst) && ALIGNED16(size)) { - return zero_mem16(dst, size); - } else { - return memset(dst, 0, size); - } -} diff --git a/tests/anc_usb/memutils.h b/tests/anc_usb/memutils.h deleted file mode 100644 index a9f0580..0000000 --- a/tests/anc_usb/memutils.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __MEMUTILS_H__ -#define __MEMUTILS_H__ - -void *copy_mem32(void *dst, const void *src, unsigned int size); - -void *copy_mem16(void *dst, const void *src, unsigned int size); - -void *copy_mem(void *dst, const void *src, unsigned int size); - -void *zero_mem32(void *dst, unsigned int size); - -void *zero_mem16(void *dst, unsigned int size); - -void *zero_mem(void *dst, unsigned int size); - -#endif - diff --git a/tests/anc_usb/mic_key.c b/tests/anc_usb/mic_key.c deleted file mode 100644 index 6a11a23..0000000 --- a/tests/anc_usb/mic_key.c +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifdef CFG_MIC_KEY - -#include "analog.h" -#include "hal_gpadc.h" -#include "hal_iomux.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "hwtimer_list.h" -#include "tgt_hardware.h" -#include "usb_audio.h" - -#define MIC_KEY_CHK_TIMES 20 -#define MIC_KEY_SKIP_CNT 8 -#define MIC_KEY_CHK_INTERVAL MS_TO_TICKS(1) // in ticks - -static struct { - HWTIMER_ID chk_timer; - - uint16_t chk_val[MIC_KEY_CHK_TIMES - MIC_KEY_SKIP_CNT]; - - uint8_t chk_times; - uint8_t gpio_dn; - uint8_t key_dn[MIC_KEY_NUM]; -} s_mic_key_ctx; - -extern void mic_key_gpio_irq_set(void); - -void mic_key_irq_hdl(uint16_t irq_val, HAL_GPADC_MV_T volt) { - hal_gpadc_close(mic_key_gpadc_chan); - - if (++s_mic_key_ctx.chk_times >= MIC_KEY_CHK_TIMES) { - - uint8_t i, j; - uint32_t mean; - - for (i = 0; i < MIC_KEY_NUM; i++) { - mean = 0; - - for (j = 0; j < MIC_KEY_CHK_TIMES - MIC_KEY_SKIP_CNT; j++) { - mean += (uint32_t)s_mic_key_ctx.chk_val[j]; - } - mean /= MIC_KEY_CHK_TIMES - MIC_KEY_SKIP_CNT; - - if ((mean > mic_key_cfg_lst[i].ref_vol_low) && - (mean <= mic_key_cfg_lst[i].ref_vol_high)) - break; - } - - if (i < MIC_KEY_NUM) { - TRACE(2, "ana_key: key[%d] matched at [%dmv]", i, mean); - usb_audio_hid_set_event(mic_key_cfg_lst[i].hid_evt, 1); - s_mic_key_ctx.key_dn[i] = 1; - } else { - TRACE(1, "ana_key: no key matched [%dmv]", mean); - } - - return; - } - - if (s_mic_key_ctx.chk_times > MIC_KEY_SKIP_CNT) { - s_mic_key_ctx.chk_val[s_mic_key_ctx.chk_times - MIC_KEY_SKIP_CNT - 1] = - volt; - } - - hwtimer_start(s_mic_key_ctx.chk_timer, MIC_KEY_CHK_INTERVAL); -} - -void mic_key_gpio_det_irq_hdl(enum HAL_GPIO_PIN_T pin) { - if (pin != mic_key_det_gpio_pin) - return; - - TRACE(1, "GPIO detected at status[%d]", s_mic_key_ctx.gpio_dn); - if (s_mic_key_ctx.gpio_dn) { - - uint8_t i; - - for (i = 0; i < MIC_KEY_NUM; i++) { - if (s_mic_key_ctx.key_dn[i]) { - break; - } - } - if (i < MIC_KEY_NUM) { - usb_audio_hid_set_event(mic_key_cfg_lst[i].hid_evt, 0); - s_mic_key_ctx.key_dn[i] = 0; - } - - s_mic_key_ctx.gpio_dn = 0; - } else { - s_mic_key_ctx.chk_times = 0; - s_mic_key_ctx.gpio_dn = 1; - hal_gpadc_open(mic_key_gpadc_chan, HAL_GPADC_ATP_ONESHOT, mic_key_irq_hdl); - } - - mic_key_gpio_irq_set(); -} - -void mic_key_periodic_check(void *param) { - hal_gpadc_open(mic_key_gpadc_chan, HAL_GPADC_ATP_ONESHOT, mic_key_irq_hdl); -} - -void mic_key_gpio_irq_set(void) { - struct HAL_GPIO_IRQ_CFG_T cfg; - - cfg.irq_debounce = 1; - cfg.irq_enable = 1; - cfg.irq_type = HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE; - if (s_mic_key_ctx.gpio_dn) { - cfg.irq_polarity = HAL_GPIO_IRQ_POLARITY_HIGH_RISING; - } else { - cfg.irq_polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING; - } - cfg.irq_handler = mic_key_gpio_det_irq_hdl; - - hal_gpio_setup_irq(mic_key_det_gpio_pin, &cfg); -} - -void mic_key_open(void) { - struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_key_det[] = { - {0, HAL_IOMUX_FUNC_GPIO, HAL_IOMUX_PIN_VOLTAGE_MEM, HAL_IOMUX_PIN_NOPULL}, - }; - - TRACE(1, "%s", __func__); - - pinmux_key_det[0].pin = mic_key_det_gpio_pin; - hal_iomux_init(pinmux_key_det, ARRAY_SIZE(pinmux_key_det)); - - analog_aud_mickey_enable(true); - - s_mic_key_ctx.chk_timer = hwtimer_alloc(mic_key_periodic_check, NULL); - hal_gpio_pin_set_dir(mic_key_det_gpio_pin, HAL_GPIO_DIR_IN, 0); - mic_key_gpio_irq_set(); -} - -#endif diff --git a/tests/anc_usb/safe_queue.c b/tests/anc_usb/safe_queue.c deleted file mode 100644 index c8ad328..0000000 --- a/tests/anc_usb/safe_queue.c +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "safe_queue.h" -#include "cmsis.h" -#include "hal_trace.h" - -void safe_queue_init(struct SAFE_QUEUE_T *queue, uint32_t *items, - uint32_t size) { - // queue->first points to the first valid item - queue->first = 0; - // queue->last points to the first empty slot (beyond the last valid item) - queue->last = 0; - queue->count = 0; - queue->size = size; - queue->watermark = 0; - queue->items = items; -} - -int safe_queue_put(struct SAFE_QUEUE_T *queue, uint32_t item) { - int ret = 0; - uint32_t lock; - - lock = int_lock(); - - if (queue->count >= queue->size) { - ret = 1; - } else { - queue->items[queue->last] = item; - queue->last++; - if (queue->last >= queue->size) { - queue->last = 0; - } - - queue->count++; - if (queue->count > queue->watermark) { - queue->watermark = queue->count; - } - } - - int_unlock(lock); - - return ret; -} - -int safe_queue_get(struct SAFE_QUEUE_T *queue, uint32_t *itemp) { - int ret = 0; - uint32_t lock; - - lock = int_lock(); - - if (queue->count == 0) { - ret = 1; - } else { - if (itemp) { - *itemp = queue->items[queue->first]; - } - queue->first++; - if (queue->first >= queue->size) { - queue->first = 0; - } - - queue->count--; - } - - int_unlock(lock); - - return ret; -} - -int safe_queue_pop(struct SAFE_QUEUE_T *queue, uint32_t *itemp) { - int ret = 0; - uint32_t lock; - - lock = int_lock(); - - if (queue->count == 0) { - ret = 1; - } else { - if (queue->last) { - queue->last--; - } else { - queue->last = queue->size - 1; - } - if (itemp) { - *itemp = queue->items[queue->last]; - } - - queue->count--; - } - - int_unlock(lock); - - return ret; -} - -int safe_queue_peek(const struct SAFE_QUEUE_T *queue, int offset, - uint32_t *itemp) { - int ret = 0; - uint32_t lock; - uint8_t idx; - - lock = int_lock(); - - if (offset >= 0 && offset < queue->count) { - idx = queue->first + offset; - } else if (offset < 0 && -offset <= queue->count) { - idx = queue->size + queue->last + offset; - } else { - ret = 1; - } - - if (ret == 0) { - if (idx >= queue->size) { - idx -= queue->size; - } - - *itemp = queue->items[idx]; - } - - int_unlock(lock); - - return ret; -} - -uint32_t safe_queue_watermark(const struct SAFE_QUEUE_T *queue) { - return queue->watermark; -} - -int safe_queue_dump(const struct SAFE_QUEUE_T *queue) { - uint32_t cnt; - int i; - uint32_t item; - - cnt = queue->count; - for (i = 0; i < cnt; i++) { - if (safe_queue_peek(queue, i, &item)) { - break; - } - TRACE_IMM(3, "SAFE-QUEUE-DUMP: [%02d/%02d] 0x%08x", i, cnt, item); - } - - return 0; -} diff --git a/tests/anc_usb/safe_queue.h b/tests/anc_usb/safe_queue.h deleted file mode 100644 index a5abf95..0000000 --- a/tests/anc_usb/safe_queue.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __SAFE_QUEUE_H__ -#define __SAFE_QUEUE_H__ - -#include "plat_types.h" - -struct SAFE_QUEUE_T { - uint8_t first; - uint8_t last; - uint8_t count; - uint8_t size; - uint8_t watermark; - uint32_t *items; -}; - -void safe_queue_init(struct SAFE_QUEUE_T *queue, uint32_t *items, uint32_t size); - -int safe_queue_put(struct SAFE_QUEUE_T *queue, uint32_t item); - -int safe_queue_get(struct SAFE_QUEUE_T *queue, uint32_t *itemp); - -int safe_queue_pop(struct SAFE_QUEUE_T *queue, uint32_t *itemp); - -int safe_queue_peek(const struct SAFE_QUEUE_T *queue, int offset, uint32_t *itemp); - -uint32_t safe_queue_watermark(const struct SAFE_QUEUE_T *queue); - -int safe_queue_dump(const struct SAFE_QUEUE_T *queue); - -#endif diff --git a/tests/anc_usb/speech_process.c b/tests/anc_usb/speech_process.c deleted file mode 100644 index 89a56a6..0000000 --- a/tests/anc_usb/speech_process.c +++ /dev/null @@ -1,279 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "speech_process.h" -#include "cmsis.h" -#include "hal_sysfreq.h" -#include "hal_timer.h" -#include "hal_trace.h" - -#if defined(SPEECH_TX_AEC2FLOAT) && !defined(KEEP_SAME_LATENCY) -#error "capture/playback size should be equal when enable AEC" -#endif - -#include "bt_sco_chain.h" -#include "iir_resample.h" -#include "speech_memory.h" -#include "speech_utils.h" - -#define MED_MEM_POOL_SIZE (1024 * 160) -static uint8_t g_medMemPool[MED_MEM_POOL_SIZE]; - -#define FFSE_SAMPLE_RATE (16000) - -int capture_channel_num = 1; -int capture_sample_rate = 48000; -int capture_sample_bit = 16; -int playback_channel_num = 2; -int playback_sample_rate = 48000; -int playback_sample_bit = 24; - -int send_channel_num = 2; -int recv_channel_num = 2; - -// resample related -static bool resample_needed_flag = false; -static IirResampleState *upsample_st; -static IirResampleState *downsample_st[4]; -int16_t *capture_buffer_deinter = NULL; -int16_t *process_buffer = NULL; -int16_t *process_buffer_inter = NULL; - -static short *aec_echo_buf = NULL; -static IirResampleState *rx_downsample_st; - -static volatile bool is_speech_init = false; - -static void speech_deinterleave(int16_t *in, int16_t *out, int len, - int ch_num) { - int len_per_channel = len / ch_num; - - for (int i = 0, j = 0; i < len; i += ch_num, j++) { - int16_t *pout = &out[j]; - int16_t *pin = &in[i]; - for (int c = 0; c < ch_num; c++) { - *pout = *pin; - pout += len_per_channel; - pin += 1; - } - } -} - -static void speech_interleave(int16_t *in, int16_t *out, int len, int ch_num) { - int len_per_channel = len / ch_num; - - for (int i = 0, j = 0; j < len; i++, j += ch_num) { - int16_t *pout = &out[j]; - int16_t *pin = &in[i]; - for (int c = 0; c < ch_num; c++) { - *pout = *pin; - pout += 1; - pin += len_per_channel; - } - } -} - -static void speech_extend(int16_t *in, int16_t *out, int len, int ch_num) { - int16_t *pout = out + len * ch_num - 1; - for (int i = len - 1; i >= 0; i--) { - for (int c = 0; c < ch_num; c++) { - *pout-- = in[i]; - } - } -} - -// This function output remains the same sample rate as input, -// output channel number shoule be CHAN_NUM_SEND. -// TODO: add multi-channel support in iir resampler -void speech_process_capture_run(uint8_t *buf, uint32_t *len) { - // TRACE(2,"[%s], pcm_len: %d", __FUNCTION__, *len / 2); - - if (is_speech_init == false) - return; - - int16_t *pcm_buf = (int16_t *)buf; - int pcm_len = *len / 2; - int process_len = pcm_len * FFSE_SAMPLE_RATE / capture_sample_rate; - - if (resample_needed_flag == true) { - if (capture_channel_num > 1) - speech_deinterleave(pcm_buf, capture_buffer_deinter, pcm_len, - capture_channel_num); - else - speech_copy_int16(capture_buffer_deinter, pcm_buf, pcm_len); - - int in_len_per_channel = pcm_len / capture_channel_num; - int out_len_per_channel = process_len / capture_channel_num; - for (int i = 0; i < capture_channel_num; i++) { - iir_resample_process( - downsample_st[i], &capture_buffer_deinter[i * in_len_per_channel], - &process_buffer[i * out_len_per_channel], in_len_per_channel); - } - - if (capture_channel_num > 1) - speech_interleave(process_buffer, process_buffer_inter, process_len, - capture_channel_num); - else - speech_copy_int16(process_buffer_inter, process_buffer, process_len); - - speech_tx_process(process_buffer_inter, aec_echo_buf, &process_len); - - iir_resample_process(upsample_st, process_buffer_inter, pcm_buf, - process_len); - - if (send_channel_num > 1) - speech_extend(pcm_buf, pcm_buf, in_len_per_channel, send_channel_num); - } else { - speech_tx_process(pcm_buf, aec_echo_buf, &process_len); - - if (send_channel_num > 1) - speech_extend(pcm_buf, pcm_buf, process_len, send_channel_num); - } - - pcm_len = pcm_len / capture_channel_num * send_channel_num; - *len = pcm_len * sizeof(int16_t); -} - -void speech_process_playback_run(uint8_t *buf, uint32_t *len) { - // TRACE(2,"[%s] pcm_len: %d", __FUNCTION__, *len / 2); - - if (is_speech_init == false) - return; - -#if defined(SPEECH_TX_AEC2FLOAT) - int16_t *pcm_buf = (int16_t *)buf; - int pcm_len = *len / 2; - - if (resample_needed_flag == true) { - // Convert to 16bit if necessary - if (playback_sample_bit == 24) { - int32_t *pcm32 = (int32_t *)buf; - for (int i = 0; i < pcm_len / 2; i++) { - pcm_buf[i] = (pcm32[i] >> 8); - } - pcm_len >>= 1; - } - - // Convert to mono if necessary, choose left channel - if (playback_channel_num == 2) { - for (int i = 0, j = 0; i < pcm_len; i += 2, j++) - pcm_buf[j] = pcm_buf[i]; - pcm_len >>= 1; - } - - iir_resample_process(rx_downsample_st, pcm_buf, pcm_buf, pcm_len); - } - speech_copy_int16(aec_echo_buf, pcm_buf, - pcm_len * FFSE_SAMPLE_RATE / capture_sample_rate); -#endif -} - -void speech_process_init(int tx_sample_rate, int tx_channel_num, - int tx_sample_bit, int rx_sample_rate, - int rx_channel_num, int rx_sample_bit, int tx_frame_ms, - int rx_frame_ms, int tx_send_channel_num, - int rx_recv_channel_num) { - ASSERT(tx_sample_rate == 16000 || tx_sample_rate == 48000, - "[%s] sample rate(%d) not supported", __FUNCTION__, tx_sample_rate); - ASSERT(tx_frame_ms == 16, "[%s] just support 16ms frame", __func__); - - capture_sample_rate = tx_sample_rate; - capture_channel_num = tx_channel_num; - capture_sample_bit = tx_sample_bit; - playback_sample_rate = rx_sample_rate; - playback_channel_num = rx_channel_num; - playback_sample_bit = rx_sample_bit; - - send_channel_num = tx_send_channel_num; - recv_channel_num = rx_recv_channel_num; - - resample_needed_flag = (capture_sample_rate != FFSE_SAMPLE_RATE); - - TRACE(5, - "[%s] sample_rate: %d, frame_ms: %d, channel_num: %d, " - "resample_needed_flag: %d", - __FUNCTION__, tx_sample_rate, tx_frame_ms, tx_channel_num, - resample_needed_flag); - - speech_init(FFSE_SAMPLE_RATE, FFSE_SAMPLE_RATE, tx_frame_ms, tx_frame_ms, - tx_frame_ms, &g_medMemPool[0], MED_MEM_POOL_SIZE); - - if (resample_needed_flag == true) { - capture_buffer_deinter = - speech_calloc(SPEECH_FRAME_MS_TO_LEN(capture_sample_rate, tx_frame_ms) * - capture_channel_num, - sizeof(int16_t)); - - // Resample state must be created after speech init, as it uses speech heap - process_buffer = - speech_calloc(SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, tx_frame_ms) * - capture_channel_num, - sizeof(int16_t)); - process_buffer_inter = - speech_calloc(SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, tx_frame_ms) * - capture_channel_num, - sizeof(int16_t)); - - upsample_st = iir_resample_init( - SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, tx_frame_ms), - iir_resample_choose_mode(FFSE_SAMPLE_RATE, capture_sample_rate)); - - // as iir resample can only deal with mono signal, we should init - // channel_num states - for (int i = 0; i < capture_channel_num; i++) { - downsample_st[i] = iir_resample_init( - SPEECH_FRAME_MS_TO_LEN(capture_sample_rate, tx_frame_ms), - iir_resample_choose_mode(capture_sample_rate, FFSE_SAMPLE_RATE)); - } - - // - aec_echo_buf = speech_calloc( - SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, rx_frame_ms), sizeof(int16_t)); - rx_downsample_st = iir_resample_init( - SPEECH_FRAME_MS_TO_LEN(playback_sample_rate, rx_frame_ms), - iir_resample_choose_mode(playback_sample_rate, FFSE_SAMPLE_RATE)); - } - - is_speech_init = true; -} - -void speech_process_deinit(void) { - if (is_speech_init == false) - return; - - if (resample_needed_flag == true) { - speech_free(capture_buffer_deinter); - - speech_free(process_buffer); - speech_free(process_buffer_inter); - - iir_resample_destroy(upsample_st); - - for (int i = 0; i < capture_channel_num; i++) { - iir_resample_destroy(downsample_st[i]); - } - - speech_free(aec_echo_buf); - iir_resample_destroy(rx_downsample_st); - - resample_needed_flag = false; - } - - speech_deinit(); - - is_speech_init = false; -} - -enum HAL_CMU_FREQ_T speech_process_need_freq(void) { return HAL_CMU_FREQ_208M; } diff --git a/tests/anc_usb/speech_process.h b/tests/anc_usb/speech_process.h deleted file mode 100644 index 004b297..0000000 --- a/tests/anc_usb/speech_process.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __SPEECH_PROCESS_H__ -#define __SPEECH_PROCESS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" -#include "hal_sysfreq.h" - -enum HAL_CMU_FREQ_T speech_process_need_freq(void); - -void speech_process_init(int tx_sample_rate, int tx_channel_num, int tx_sample_bit, - int rx_sample_rate, int rx_channel_num, int rx_sample_bit, - int tx_frame_ms, int rx_frame_ms, - int tx_send_channel_num, int rx_recv_channel_num); -void speech_process_deinit(void); -void speech_process_capture_run(uint8_t *buf, uint32_t *len); -void speech_process_playback_run(uint8_t *buf, uint32_t *len); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tests/anc_usb/usb_audio_app.c b/tests/anc_usb/usb_audio_app.c deleted file mode 100644 index 61c6efa..0000000 --- a/tests/anc_usb/usb_audio_app.c +++ /dev/null @@ -1,6410 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#include "usb_audio_app.h" -#include "analog.h" -#include "audio_resample_ex.h" -#include "audioflinger.h" -#include "cmsis.h" -#include "hal_aud.h" -#include "hal_codec.h" -#include "hal_location.h" -#include "hal_sleep.h" -#include "hal_sysfreq.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "memutils.h" -#include "pmu.h" -#include "resample_coef.h" -#include "safe_queue.h" -#include "string.h" -#include "tgt_hardware.h" -#include "usb_audio.h" -#include "usb_audio_frm_defs.h" -#include "usb_audio_sync.h" - -#ifdef _VENDOR_MSG_SUPPT_ -#include "usb_vendor_msg.h" -#endif - -#if defined(USB_AUDIO_SPEECH) -#include "app_overlay.h" -#include "speech_process.h" -#endif - -#if defined(__HW_FIR_DSD_PROCESS__) -#include "dsd_process.h" -#endif - -#if defined(AUDIO_ANC_FB_MC) -#include "anc_process.h" -#endif - -#include "hw_codec_iir_process.h" -#include "hw_iir_process.h" - -#ifdef __AUDIO_RESAMPLE__ -#ifdef SW_PLAYBACK_RESAMPLE -#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) -#error "Software playback resample conflicts with ANC/AuxMic" -#endif -#else -#ifdef CHIP_BEST1000 -#error "No hardware playback resample support" -#endif -#endif - -#ifndef SW_CAPTURE_RESAMPLE -#if defined(CHIP_BEST1000) || defined(CHIP_BEST2000) -#error "No hardware capture resample support" -#endif -#endif -#endif // __AUDIO_RESAMPLE__ - -#ifdef CODEC_DSD -#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || \ - defined(__HW_IIR_EQ_PROCESS__) || defined(__HW_DAC_IIR_EQ_PROCESS__) -#error "EQ conflicts with CODEC_DSD" -#endif -#ifdef FREQ_RESP_EQ -#error "FREQ_RESP_EQ conflicts with CODEC_DSD" -#endif -#ifdef __HW_FIR_DSD_PROCESS__ -#error "__HW_FIR_DSD_PROCESS__ conflicts with CODEC_DSD" -#endif -#ifdef AUDIO_ANC_FB_MC -#error "AUDIO_ANC_FB_MC conflicts with CODEC_DSD" -#endif -#ifdef NOISE_GATING -#error "NOISE_GATING conflicts with CODEC_DSD" -#endif -#ifdef NOISE_REDUCTION -#error "NOISE_REDUCTION conflicts with CODEC_DSD" -#endif -#endif - -#if defined(__SW_IIR_EQ_PROCESS__) -static uint8_t audio_eq_sw_iir_index = 0; -extern const IIR_CFG_T *const audio_eq_sw_iir_cfg_list[]; -#endif - -#if defined(__HW_FIR_EQ_PROCESS__) -static uint8_t audio_eq_hw_fir_index = 0; -extern const FIR_CFG_T *const audio_eq_hw_fir_cfg_list[]; -#endif - -#if defined(__HW_DAC_IIR_EQ_PROCESS__) -static uint8_t audio_eq_hw_dac_iir_index = 0; -extern const IIR_CFG_T *const audio_eq_hw_dac_iir_cfg_list[]; -#endif - -#if defined(__HW_IIR_EQ_PROCESS__) -static uint8_t audio_eq_hw_iir_index = 0; -extern const IIR_CFG_T *const audio_eq_hw_iir_cfg_list[]; -#endif - -#define KEY_TRACE -//#define UNMUTE_WHEN_SET_VOL -#define STREAM_RATE_BITS_SETUP - -#if defined(USB_AUDIO_DYN_CFG) && defined(ANC_L_R_MISALIGN_WORKAROUND) -#ifndef AUDIO_PLAYBACK_24BIT -//#define AUDIO_PLAYBACK_24BIT -#endif -#endif - -#if defined(__HW_FIR_DSD_PROCESS__) || defined(CODEC_DSD) -#define DSD_SUPPORT -#endif - -#ifdef TARGET_TO_MAX_DIFF -#if defined(USB_AUDIO_RECV_ENABLE) && defined(USB_AUDIO_SEND_ENABLE) -#if defined(__AUDIO_RESAMPLE__) && defined(PLL_TUNE_SAMPLE_RATE) -#define UAUD_SYNC_STREAM_TARGET -#else -#error \ - "TARGET_TO_MAX_DIFF can be enabled only with __AUDIO_RESAMPLE__ and PLL_TUNE_SAMPLE_RATE if both playback and capture streams exist" -#endif -#endif - -#ifdef USB_AUDIO_MULTIFUNC -#error "TARGET_TO_MAX_DIFF can NOT be enabled with USB_AUDIO_MULTIFUNC" -#endif -#endif // TARGET_TO_MAX_DIFF - -#define VERBOSE_TRACE 0 // 0xFFFF - -#ifdef TIMER1_BASE -#define TRACE_TIME(num, s, ...) \ - TRACE(num + 1, "[%u] " s, FAST_TICKS_TO_US(hal_fast_sys_timer_get()), \ - ##__VA_ARGS__) -#else -#define TRACE_TIME(num, s, ...) \ - TRACE(num + 1, "[%X] " s, hal_sys_timer_get(), ##__VA_ARGS__) -#endif - -#define USB_AUDIO_CPU_WAKE_USER HAL_CPU_WAKE_LOCK_USER_3 - -#define RECV_PAUSED_SAMPLE_RATE_FLAG (1 << 31) - -#define DIFF_ERR_THRESH_PLAYBACK (sample_rate_recv / 1000 / 2) -#define DIFF_ERR_THRESH_CAPTURE (sample_rate_send / 1000 / 2) - -#define DIFF_SYNC_THRESH_PLAYBACK 10 -#define DIFF_SYNC_THRESH_CAPTURE 10 - -#define DIFF_AVG_CNT 30 - -#define MAX_TARGET_RATIO 0.000020f - -#define MIN_VOLUME_VAL (TGT_VOLUME_LEVEL_MUTE) -#define MAX_VOLUME_VAL (TGT_VOLUME_LEVEL_QTY - 1) - -#define MIN_CAP_VOLUME_VAL (TGT_ADC_VOL_LEVEL_0) -#define MAX_CAP_VOLUME_VAL (TGT_ADC_VOL_LEVEL_QTY - 1) - -#define NOISE_GATING_INTERVAL MS_TO_TICKS(800) -#define NOISE_GATING_THRESH_16BIT 3 // -80dB -#define NOISE_GATING_THRESH_24BIT (NOISE_GATING_THRESH_16BIT << 8) - -#define NOISE_REDUCTION_INTERVAL MS_TO_TICKS(100) -#define NOISE_REDUCTION_MATCH_CNT 200 -#define NOISE_REDUCTION_THRESH_16BIT 100 // -50dB -#define NOISE_REDUCTION_THRESH_24BIT (NOISE_REDUCTION_THRESH_16BIT << 8) - -#define CONFLICT_CMD_TRIG_COUNT 10 -#define CONFLICT_CMD_TRIG_INTERVAL MS_TO_TICKS(20000) -#define CONFLICT_STATE_RESET_INTERVAL MS_TO_TICKS(10000) - -#define CAPTURE_STABLE_INTERVAL MS_TO_TICKS(200) - -#define USB_MAX_XFER_INTERVAL MS_TO_TICKS(10) - -#define USB_XFER_ERR_REPORT_INTERVAL MS_TO_TICKS(5000) - -#define USB_AUDIO_MIN_DBVAL (-99) - -#define USB_AUDIO_VOL_UPDATE_STEP 0.00002 - -#ifndef USB_AUDIO_KEY_MAP -#ifdef ANDROID_ACCESSORY_SPEC -#ifdef ANDROID_VOICE_CMD_KEY -#define USB_AUDIO_KEY_VOICE_CMD \ - { \ - USB_AUDIO_HID_VOICE_CMD, \ - HAL_KEY_CODE_FN4, \ - KEY_EVENT_SET2(DOWN, UP), \ - }, -#else -#define USB_AUDIO_KEY_VOICE_CMD -#endif -#define USB_AUDIO_KEY_MAP \ - { \ - { \ - USB_AUDIO_HID_PLAY_PAUSE, \ - HAL_KEY_CODE_FN1, \ - KEY_EVENT_SET2(DOWN, UP), \ - }, \ - { \ - USB_AUDIO_HID_VOL_UP, \ - HAL_KEY_CODE_FN2, \ - KEY_EVENT_SET2(DOWN, UP), \ - }, \ - { \ - USB_AUDIO_HID_VOL_DOWN, \ - HAL_KEY_CODE_FN3, \ - KEY_EVENT_SET2(DOWN, UP), \ - }, \ - USB_AUDIO_KEY_VOICE_CMD \ - } -#else -#define USB_AUDIO_KEY_MAP \ - { \ - { \ - USB_AUDIO_HID_PLAY_PAUSE, \ - HAL_KEY_CODE_FN1, \ - KEY_EVENT_SET(CLICK), \ - }, \ - { \ - USB_AUDIO_HID_SCAN_NEXT, \ - HAL_KEY_CODE_FN1, \ - KEY_EVENT_SET(DOUBLECLICK), \ - }, \ - { \ - USB_AUDIO_HID_SCAN_PREV, \ - HAL_KEY_CODE_FN1, \ - KEY_EVENT_SET(TRIPLECLICK), \ - }, \ - { \ - USB_AUDIO_HID_VOL_UP, \ - HAL_KEY_CODE_FN2, \ - KEY_EVENT_SET4(CLICK, DOUBLECLICK, TRIPLECLICK, REPEAT), \ - }, \ - { \ - USB_AUDIO_HID_VOL_DOWN, \ - HAL_KEY_CODE_FN3, \ - KEY_EVENT_SET4(CLICK, DOUBLECLICK, TRIPLECLICK, REPEAT), \ - }, \ - { \ - USB_AUDIO_HID_HOOK_SWITCH, \ - HAL_KEY_CODE_FN4, \ - KEY_EVENT_SET(CLICK), \ - }, \ - } -#endif -#endif - -enum AUDIO_CMD_T { - AUDIO_CMD_START_PLAY = 0, - AUDIO_CMD_STOP_PLAY, - AUDIO_CMD_START_CAPTURE, - AUDIO_CMD_STOP_CAPTURE, - AUDIO_CMD_SET_VOLUME, - AUDIO_CMD_SET_CAP_VOLUME, - AUDIO_CMD_MUTE_CTRL, - AUDIO_CMD_CAP_MUTE_CTRL, - AUDIO_CMD_USB_RESET, - AUDIO_CMD_USB_DISCONNECT, - AUDIO_CMD_USB_CONFIG, - AUDIO_CMD_USB_SLEEP, - AUDIO_CMD_USB_WAKEUP, - AUDIO_CMD_RECV_PAUSE, - AUDIO_CMD_RECV_CONTINUE, - AUDIO_CMD_SET_RECV_RATE, - AUDIO_CMD_SET_SEND_RATE, - AUDIO_CMD_RESET_CODEC, - AUDIO_CMD_NOISE_GATING, - AUDIO_CMD_NOISE_REDUCTION, - AUDIO_CMD_TUNE_RATE, - AUDIO_CMD_SET_DSD_CFG, - - TEST_CMD_PERF_TEST_POWER, - TEST_CMD_PA_ON_OFF, - - AUDIO_CMD_QTY -}; - -enum AUDIO_ITF_STATE_T { - AUDIO_ITF_STATE_STOPPED = 0, - AUDIO_ITF_STATE_STARTED, -}; - -enum AUDIO_STREAM_REQ_USER_T { - AUDIO_STREAM_REQ_USB = 0, - AUDIO_STREAM_REQ_ANC, - - AUDIO_STREAM_REQ_USER_QTY, - AUDIO_STREAM_REQ_USER_ALL = AUDIO_STREAM_REQ_USER_QTY, -}; - -enum AUDIO_STREAM_STATUS_T { - AUDIO_STREAM_OPENED = 0, - AUDIO_STREAM_STARTED, - - AUDIO_STREAM_STATUS_QTY -}; - -enum AUDIO_STREAM_RUNNING_T { - AUDIO_STREAM_RUNNING_NULL, - AUDIO_STREAM_RUNNING_ENABLED, - AUDIO_STREAM_RUNNING_DISABLED, -}; - -enum CODEC_CONFIG_LOCK_USER_T { - CODEC_CONFIG_LOCK_RESTART_PLAY, - CODEC_CONFIG_LOCK_RESTART_CAP, - - CODEC_CONFIG_LOCK_USER_QTY -}; - -enum CODEC_MUTE_USER_T { - CODEC_MUTE_USER_CMD, - CODEC_MUTE_USER_NOISE_GATING, - - CODEC_MUTE_USER_QTY, - CODEC_MUTE_USER_ALL = CODEC_MUTE_USER_QTY, -}; - -struct USB_AUDIO_KEY_MAP_T { - enum USB_AUDIO_HID_EVENT_T hid_event; - enum HAL_KEY_CODE_T key_code; - uint32_t key_event_bitset; -}; - -STATIC_ASSERT(8 * sizeof(((struct USB_AUDIO_KEY_MAP_T *)0)->key_event_bitset) >= - HAL_KEY_EVENT_NUM, - "key_event_bitset size is too small"); - -#ifdef USB_AUDIO_DYN_CFG - -static enum AUD_SAMPRATE_T sample_rate_play; -static enum AUD_SAMPRATE_T sample_rate_cap; -static enum AUD_SAMPRATE_T sample_rate_recv; -static enum AUD_SAMPRATE_T sample_rate_send; -static enum AUD_SAMPRATE_T new_sample_rate_recv; -static enum AUD_SAMPRATE_T new_sample_rate_send; -#ifdef AUDIO_PLAYBACK_24BIT -static -#ifndef CODEC_DSD - const -#endif - uint8_t sample_size_play = 4; -#else -static uint8_t sample_size_play; -#endif -static const uint8_t sample_size_cap = SAMPLE_SIZE_CAPTURE; -static uint8_t sample_size_recv; -static const uint8_t sample_size_send = SAMPLE_SIZE_SEND; -static uint8_t new_sample_size_recv; - -#else // !USB_AUDIO_DYN_CFG - -static const enum AUD_SAMPRATE_T sample_rate_play = SAMPLE_RATE_PLAYBACK; -static const enum AUD_SAMPRATE_T sample_rate_cap = SAMPLE_RATE_CAPTURE; -static const enum AUD_SAMPRATE_T sample_rate_recv = SAMPLE_RATE_RECV; -static const enum AUD_SAMPRATE_T sample_rate_send = SAMPLE_RATE_SEND; -static -#ifndef CODEC_DSD - const -#endif - uint8_t sample_size_play = SAMPLE_SIZE_PLAYBACK; -static const uint8_t sample_size_cap = SAMPLE_SIZE_CAPTURE; -static const uint8_t sample_size_recv = SAMPLE_SIZE_RECV; -static const uint8_t sample_size_send = SAMPLE_SIZE_SEND; - -#endif // !USB_AUDIO_DYN_CFG - -#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) -#ifdef USB_AUDIO_DYN_CFG -static enum AUD_SAMPRATE_T sample_rate_ref_cap; -#else // !USB_AUDIO_DYN_CFG -#ifdef __AUDIO_RESAMPLE__ -static const enum AUD_SAMPRATE_T sample_rate_ref_cap = SAMPLE_RATE_CAPTURE; -#elif defined(USB_AUDIO_16K) -static const enum AUD_SAMPRATE_T sample_rate_ref_cap = SAMPLE_RATE_CAPTURE; -#else -static const enum AUD_SAMPRATE_T sample_rate_ref_cap = - (SAMPLE_RATE_RECV % AUD_SAMPRATE_8000) ? AUD_SAMPRATE_44100 - : AUD_SAMPRATE_48000; -#endif -#endif // !USB_AUDIO_DYN_CFG -#endif // (CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) - -static enum AUDIO_ITF_STATE_T playback_state = AUDIO_ITF_STATE_STOPPED; -static enum AUDIO_ITF_STATE_T capture_state = AUDIO_ITF_STATE_STOPPED; -static enum AUDIO_ITF_STATE_T recv_state = AUDIO_ITF_STATE_STOPPED; -static enum AUDIO_ITF_STATE_T send_state = AUDIO_ITF_STATE_STOPPED; - -static uint8_t codec_stream_map[AUD_STREAM_NUM][AUDIO_STREAM_STATUS_QTY]; -static uint8_t eq_opened; -static enum AUDIO_STREAM_RUNNING_T streams_running_req; - -static uint8_t playback_paused; - -static uint8_t playback_conflicted; -static uint8_t capture_conflicted; - -#ifdef NOISE_GATING -enum NOISE_GATING_CMD_T { - NOISE_GATING_CMD_NULL, - NOISE_GATING_CMD_MUTE, - NOISE_GATING_CMD_UNMUTE, -}; -static enum NOISE_GATING_CMD_T noise_gating_cmd = NOISE_GATING_CMD_NULL; -static uint32_t last_high_signal_time; - -#ifdef NOISE_REDUCTION -enum NOISE_REDUCTION_CMD_T { - NOISE_REDUCTION_CMD_NULL, - NOISE_REDUCTION_CMD_FIRE, - NOISE_REDUCTION_CMD_RESTORE, -}; -static enum NOISE_REDUCTION_CMD_T noise_reduction_cmd = - NOISE_REDUCTION_CMD_NULL; -static bool nr_active; -static bool prev_samp_positive[2]; -static uint16_t prev_zero_diff[2][2]; -static uint16_t cur_zero_diff[2][2]; -static uint16_t nr_cont_cnt; -static uint32_t last_nr_restore_time; - -static void restore_noise_reduction_status(void); -#endif -#endif - -static uint8_t *playback_buf; -static uint32_t playback_size; -static uint32_t playback_pos; - -#ifdef AUDIO_ANC_FB_MC -static int32_t playback_samplerate_ratio; -#endif - -static uint8_t *capture_buf; -static uint32_t capture_size; -static uint32_t capture_pos; - -static uint8_t *playback_eq_buf; -static uint32_t playback_eq_size; - -#ifdef USB_AUDIO_DYN_CFG -#ifdef KEEP_SAME_LATENCY -static uint32_t playback_max_size; -static uint32_t capture_max_size; -static uint32_t usb_recv_max_size; -static uint32_t usb_send_max_size; -#endif -static uint8_t playback_itf_set; -static uint8_t capture_itf_set; -#endif - -#ifdef SW_CAPTURE_RESAMPLE -static RESAMPLE_ID resample_id; -static bool resample_cap_enabled; -static uint8_t *resample_history_buf; -static uint32_t resample_history_size; -static uint8_t *resample_input_buf; -static uint32_t resample_input_size; -#endif - -static uint8_t *usb_recv_buf; -static uint32_t usb_recv_size; -static uint32_t usb_recv_rpos; -static uint32_t usb_recv_wpos; - -static uint8_t *usb_send_buf; -static uint32_t usb_send_size; -static uint32_t usb_send_rpos; -static uint32_t usb_send_wpos; - -static uint8_t usb_configured; - -static uint8_t usb_recv_valid; -static uint8_t usb_send_valid; - -static uint8_t usb_recv_init_rpos; -static uint8_t usb_send_init_wpos; - -static uint8_t codec_play_seq; -static uint8_t codec_cap_seq; -static volatile uint8_t usb_recv_seq; -static volatile uint8_t usb_send_seq; - -static uint8_t codec_play_valid; -static uint8_t codec_cap_valid; - -#ifdef USB_AUDIO_MULTIFUNC -static const uint8_t playback_vol = AUDIO_OUTPUT_VOLUME_DEFAULT; -#else -static uint8_t playback_vol; -#endif -static uint8_t new_playback_vol; -static uint8_t new_mute_state; -static uint8_t mute_user_map; -STATIC_ASSERT(sizeof(mute_user_map) * 8 >= CODEC_MUTE_USER_QTY, - "mute_user_map size too small"); - -static uint8_t capture_vol; -static uint8_t new_capture_vol; -static uint8_t new_cap_mute_state; - -static uint32_t last_usb_recv_err_time; -static uint32_t usb_recv_err_cnt; -static uint32_t usb_recv_ok_cnt; - -static uint32_t last_usb_send_err_time; -static uint32_t usb_send_err_cnt; -static uint32_t usb_send_ok_cnt; - -#ifdef USB_AUDIO_MULTIFUNC -static uint8_t playback_conflicted2; -static enum AUDIO_ITF_STATE_T recv2_state = AUDIO_ITF_STATE_STOPPED; -static uint8_t *usb_recv2_buf; -static uint32_t usb_recv2_size; -static uint32_t usb_recv2_rpos; -static uint32_t usb_recv2_wpos; -static uint8_t usb_recv2_valid; -static uint8_t usb_recv2_init_rpos; -static uint8_t new_playback2_vol; -static uint8_t new_mute2_state; -static float new_playback_coef; -static float new_playback2_coef; -static float playback_coef; -static float playback2_coef; - -static uint32_t last_usb_recv2_err_time; -static uint32_t usb_recv2_err_cnt; -static uint32_t usb_recv2_ok_cnt; - -static float playback_gain_to_float(uint32_t level); -#endif - -static uint8_t codec_config_lock; -STATIC_ASSERT(sizeof(codec_config_lock) * 8 >= CODEC_CONFIG_LOCK_USER_QTY, - "codec_config_lock size too small"); - -static struct USB_AUDIO_STREAM_INFO_T playback_info; -static struct USB_AUDIO_STREAM_INFO_T capture_info; - -static uint8_t nonconflict_start; -static uint16_t conflict_cnt; -static uint32_t conflict_time; -static uint32_t nonconflict_time; - -static uint32_t codec_cap_start_time; - -static uint32_t last_usb_recv_time; -static uint32_t last_usb_send_time; - -#define CMD_LIST_SIZE 30 -static uint32_t cmd_list[CMD_LIST_SIZE]; -static uint32_t cmd_watermark; -static struct SAFE_QUEUE_T cmd_queue; - -#define EXTRACT_CMD(d) ((d)&0xFF) -#define EXTRACT_SEQ(d) (((d) >> 8) & 0xFF) -#define EXTRACT_ARG(d) (((d) >> 16) & 0xFF) -#define MAKE_QUEUE_DATA(c, s, a) \ - (((c)&0xFF) | ((s)&0xFF) << 8 | ((a)&0xFF) << 16) -STATIC_ASSERT(AUDIO_CMD_QTY <= 0xFF, "audio cmd num exceeds size in queue"); -STATIC_ASSERT(USB_AUDIO_STATE_EVENT_QTY <= 0xFF, - "uaud evt num exceeds size in queue"); -STATIC_ASSERT(sizeof(usb_recv_seq) <= 1, "usb recv seq exceeds size in queue"); -STATIC_ASSERT(sizeof(usb_send_seq) <= 1, "usb send seq exceeds size in queue"); - -static const struct USB_AUDIO_KEY_MAP_T key_map[] = USB_AUDIO_KEY_MAP; - -#ifdef PERF_TEST_POWER_KEY -static enum HAL_CODEC_PERF_TEST_POWER_T perft_power_type; -#endif -#ifdef PA_ON_OFF_KEY -static bool pa_on_off_muted; -#endif - -static float rate_tune_ratio[AUD_STREAM_NUM]; - -#ifdef DSD_SUPPORT -static bool usb_dsd_enabled; -static bool codec_dsd_enabled; -static uint16_t usb_dsd_cont_cnt = 0; -#ifdef CODEC_DSD -static uint8_t dsd_saved_sample_size; -#endif -#endif - -#ifdef BT_USB_AUDIO_DUAL_MODE -static USB_AUDIO_ENQUEUE_CMD_CALLBACK enqueue_cmd_cb; -#endif - -static void enqueue_unique_cmd(enum AUDIO_CMD_T cmd); -static void usb_audio_set_codec_volume(enum AUD_STREAM_T stream, uint8_t vol); -static void usb_audio_cmd_tune_rate(enum AUD_STREAM_T stream); - -#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) - -extern void damic_init(void); -extern void damic_deinit(void); - -// second-order IR filter -short soir_filter(int32_t PcmValue) { - float gain = 2.0F; - const float NUM[3] = {0.013318022713065147, 0.02375408448278904, - 0.010780527256429195}; - const float DEN[3] = {1, -1.6983977556228638, 0.74625039100646973}; - - static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; - int32_t PcmOut = 0; - - // Left channel - x0 = PcmValue * gain; - y0 = x0 * NUM[0] + x1 * NUM[1] + x2 * NUM[2] - y1 * DEN[1] - y2 * DEN[2]; - y2 = y1; - y1 = y0; - x2 = x1; - x1 = x0; - - PcmOut = (int32_t)y0; - - PcmOut = __SSAT(PcmOut, 16); - - return (short)PcmOut; -} - -#ifdef DUAL_AUX_MIC_MORE_FILTER -// second-order IR filter -short soir_filter1(int32_t PcmValue) { - // float gain = 0.003031153698; - const float NUM[3] = {0.013318022713065147, 0.02375408448278904, - 0.010780527256429195}; - const float DEN[3] = {1, -1.6983977556228638, 0.74625039100646973}; - - static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; - int32_t PcmOut = 0; - - // Left channel - // x0 = PcmValue* gain; - x0 = PcmValue; - y0 = x0 * NUM[0] + x1 * NUM[1] + x2 * NUM[2] - y1 * DEN[1] - y2 * DEN[2]; - y2 = y1; - y1 = y0; - x2 = x1; - x1 = x0; - - PcmOut = (int32_t)y0; - - PcmOut = __SSAT(PcmOut, 16); - - return (short)PcmOut; -} - -// second-order IR filter -short soir_filter2(int32_t PcmValue) { - // float gain = 0.003031153698; - const float NUM[3] = {0.013318022713065147, 0.02375408448278904, - 0.010780527256429195}; - const float DEN[3] = {1, -1.6983977556228638, 0.74625039100646973}; - - static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; - int32_t PcmOut = 0; - - // Left channel - // x0 = PcmValue* gain; - x0 = PcmValue; - y0 = x0 * NUM[0] + x1 * NUM[1] + x2 * NUM[2] - y1 * DEN[1] - y2 * DEN[2]; - y2 = y1; - y1 = y0; - x2 = x1; - x1 = x0; - - PcmOut = (int32_t)y0; - - PcmOut = __SSAT(PcmOut, 16); - - return (short)PcmOut; -} -#endif - -static float s_f_amic3_dc; -static float s_f_amic4_dc; -static short s_amic3_dc; -static short s_amic4_dc; - -static void init_amic_dc(void) { - s_amic3_dc = 0; - s_amic4_dc = 0; - s_f_amic3_dc = 0.0; - s_f_amic4_dc = 0.0; -} - -static void get_amic_dc(short *src, uint32_t samp_cnt, uint32_t step) { - uint32_t i = 0; - - float u3_1 = 0.00001; - float u3_2 = 1 - u3_1; - - float u4_1 = 0.00001; - float u4_2 = 1 - u4_1; - - for (i = 0; i < samp_cnt; i += (2 << step)) { - s_f_amic3_dc = u3_2 * s_f_amic3_dc + u3_1 * src[i << 1]; - s_f_amic4_dc = u4_2 * s_f_amic4_dc + u4_1 * src[(i << 1) + 1]; - } - - s_amic3_dc = __SSAT((int)s_f_amic3_dc, 16); - s_amic4_dc = __SSAT((int)s_f_amic4_dc, 16); -} -#endif - -#ifdef FREQ_RESP_EQ - -#ifndef AUDIO_PLAYBACK_24BIT -#error "FREQ_RESP_EQ requires AUDIO_PLAYBACK_24BIT" -#endif - -#define FREQ_RESP_EQ_COEF_NUM 7 -static float freq_resp_eq_coef[FREQ_RESP_EQ_COEF_NUM] = { - // -0.000155, 0.000774, -0.003854, 0.994971, -0.003854, 0.000774, - // -0.000155 - -0.000138, 0.000687, -0.003426, 0.990852, -0.003426, 0.000687, -0.000138}; - -static int32_t freq_resp_eq_hist[2][(FREQ_RESP_EQ_COEF_NUM - 1) * 2]; -static uint8_t freq_resp_eq_hist_idx; - -void freq_resp_eq_init(void) { - int i; - - freq_resp_eq_hist_idx = 0; - for (i = 0; i < ARRAY_SIZE(freq_resp_eq_hist[0]); i++) { - freq_resp_eq_hist[0][i] = 0; - freq_resp_eq_hist[1][i] = 0; - } -} - -int freq_resp_eq_run(uint8_t *buf, uint32_t len) { - ASSERT(sample_size_play == 4, - "Freq resp eq is running on 24-bit playback only"); - - if (sample_rate_play > AUD_SAMPRATE_96000) { - // Sample rate higher than 96K will require higher system freq, which - // consumes more power - return 0; - } - - int32_t *src_buf = (int32_t *)buf; - int32_t *dst_buf = (int32_t *)buf; - uint32_t mono_samp_num = len / 2 / sample_size_play; - int32_t start_idx, in_idx, coef_idx; - int32_t in_l, in_r; - float out_l, out_r; - uint8_t new_seq_idx = !freq_resp_eq_hist_idx; - - if (mono_samp_num >= (FREQ_RESP_EQ_COEF_NUM - 1)) { - start_idx = (mono_samp_num - FREQ_RESP_EQ_COEF_NUM + 1) * 2; - for (in_idx = 0; in_idx < (FREQ_RESP_EQ_COEF_NUM - 1) * 2; in_idx++) { - freq_resp_eq_hist[new_seq_idx][in_idx] = src_buf[start_idx + in_idx]; - } - } else { - start_idx = (FREQ_RESP_EQ_COEF_NUM - 1 - mono_samp_num) * 2; - for (in_idx = 0; in_idx < start_idx; in_idx++) { - freq_resp_eq_hist[new_seq_idx][in_idx] = - freq_resp_eq_hist[freq_resp_eq_hist_idx][mono_samp_num * 2 + in_idx]; - } - for (in_idx = 0; in_idx < mono_samp_num * 2; in_idx++) { - freq_resp_eq_hist[new_seq_idx][start_idx + in_idx] = src_buf[in_idx]; - } - } - - for (in_idx = mono_samp_num - 1; in_idx >= 0; in_idx--) { - out_l = 0; - out_r = 0; - for (coef_idx = 0; coef_idx < FREQ_RESP_EQ_COEF_NUM; coef_idx++) { - if (in_idx + coef_idx - FREQ_RESP_EQ_COEF_NUM + 1 >= 0) { - in_l = src_buf[(in_idx + coef_idx - FREQ_RESP_EQ_COEF_NUM + 1) * 2]; - in_r = src_buf[(in_idx + coef_idx - FREQ_RESP_EQ_COEF_NUM + 1) * 2 + 1]; - } else { - in_l = - freq_resp_eq_hist[freq_resp_eq_hist_idx][(in_idx + coef_idx) * 2]; - in_r = freq_resp_eq_hist[freq_resp_eq_hist_idx] - [(in_idx + coef_idx) * 2 + 1]; - } - out_l += in_l * freq_resp_eq_coef[coef_idx]; - out_r += in_r * freq_resp_eq_coef[coef_idx]; - } - - // TODO: Is it really neccessary to round the float? - // dst_buf[in_idx * 2] = __SSAT(ftoi_nearest(out_l), 24); - // dst_buf[in_idx * 2 + 1] = __SSAT(ftoi_nearest(out_r), 24); - dst_buf[in_idx * 2] = __SSAT((int32_t)out_l, 24); - dst_buf[in_idx * 2 + 1] = __SSAT((int32_t)out_r, 24); - } - - freq_resp_eq_hist_idx = new_seq_idx; - - return 0; -} - -#endif // FREQ_RESP_EQ - -static enum AUD_BITS_T sample_size_to_enum_playback(uint32_t size) { - if (size == 2) { - return AUD_BITS_16; - } else if (size == 4) { - return AUD_BITS_24; - } else { - ASSERT(false, "%s: Invalid sample size: %u", __FUNCTION__, size); - } - - return 0; -} - -static enum AUD_BITS_T sample_size_to_enum_capture(uint32_t size) { - if (size == 2) { - return AUD_BITS_16; - } else if (size == 4) { -#ifdef USB_AUDIO_SEND_32BIT - return AUD_BITS_32; -#else - return AUD_BITS_24; -#endif - } else { - ASSERT(false, "%s: Invalid sample size: %u", __FUNCTION__, size); - } - - return 0; -} - -static enum AUD_CHANNEL_NUM_T chan_num_to_enum(uint32_t num) { - return AUD_CHANNEL_NUM_1 + (num - 1); -} - -static uint32_t POSSIBLY_UNUSED byte_to_samp_playback(uint32_t n) { -#if defined(USB_AUDIO_DYN_CFG) || defined(CODEC_DSD) - return n / sample_size_play / CHAN_NUM_PLAYBACK; -#else - return BYTE_TO_SAMP_PLAYBACK(n); -#endif -} - -static uint32_t POSSIBLY_UNUSED byte_to_samp_capture(uint32_t n) { -#ifdef USB_AUDIO_DYN_CFG - return n / sample_size_cap / CHAN_NUM_CAPTURE; -#else - return BYTE_TO_SAMP_CAPTURE(n); -#endif -} - -static uint32_t POSSIBLY_UNUSED byte_to_samp_recv(uint32_t n) { -#ifdef USB_AUDIO_DYN_CFG - return n / sample_size_recv / CHAN_NUM_RECV; -#else - return BYTE_TO_SAMP_RECV(n); -#endif -} - -static uint32_t POSSIBLY_UNUSED byte_to_samp_send(uint32_t n) { -#ifdef USB_AUDIO_DYN_CFG - return n / sample_size_send / CHAN_NUM_SEND; -#else - return BYTE_TO_SAMP_SEND(n); -#endif -} - -static uint32_t POSSIBLY_UNUSED samp_to_byte_playback(uint32_t n) { -#if defined(USB_AUDIO_DYN_CFG) || defined(CODEC_DSD) - return n * sample_size_play * CHAN_NUM_PLAYBACK; -#else - return SAMP_TO_BYTE_PLAYBACK(n); -#endif -} - -static uint32_t POSSIBLY_UNUSED samp_to_byte_capture(uint32_t n) { -#ifdef USB_AUDIO_DYN_CFG - return n * sample_size_cap * CHAN_NUM_CAPTURE; -#else - return SAMP_TO_BYTE_CAPTURE(n); -#endif -} - -static uint32_t POSSIBLY_UNUSED samp_to_byte_recv(uint32_t n) { -#ifdef USB_AUDIO_DYN_CFG - return n * sample_size_recv * CHAN_NUM_RECV; -#else - return SAMP_TO_BYTE_RECV(n); -#endif -} - -static uint32_t POSSIBLY_UNUSED samp_to_byte_send(uint32_t n) { -#ifdef USB_AUDIO_DYN_CFG - return n * sample_size_send * CHAN_NUM_SEND; -#else - return SAMP_TO_BYTE_SEND(n); -#endif -} - -static uint32_t playback_to_recv_len(uint32_t n) { -#if defined(USB_AUDIO_DYN_CFG) || defined(CODEC_DSD) - uint32_t len; - - // 1) When changing recv sample rate, the play stream will be stopped and then - // restarted. - // So when calculating the len, play sample rate has been changed according - // to recv sample rate. - // 2) Play and recv sample rates are integral multiple of each other. - - len = samp_to_byte_recv(byte_to_samp_playback(n)); - if (sample_rate_recv == sample_rate_play) { - return len; - } else if (sample_rate_recv < sample_rate_play) { - return len / (sample_rate_play / sample_rate_recv); - } else { - return len * (sample_rate_recv / sample_rate_play); - } -#else - return PLAYBACK_TO_RECV_LEN(n); -#endif -} - -static uint32_t capture_to_send_len(uint32_t n) { -#ifdef USB_AUDIO_DYN_CFG - uint32_t len; - enum AUD_SAMPRATE_T send_rate; - enum AUD_SAMPRATE_T cap_rate; - - // 1) When changing send sample rate, the cap stream will not be changed if - // the play stream is active. - // Moreover, the cap stream might be changed if changing recv sample rate - // (and then play sample rate). So when calculating the len, cap sample - // rate might be inconsistent with send sample rate. - // 2) Resample might be applied to the cap stream. Cap and send sample rates - // have no integral multiple relationship. - - send_rate = sample_rate_send; - cap_rate = sample_rate_cap; - - len = samp_to_byte_send(byte_to_samp_capture(n)); - if (send_rate == cap_rate) { - return len; - } else { - // Unlikely to overflow for the max send_rate is 48000 - return ALIGN((len * send_rate + cap_rate - 1) / cap_rate, - sample_size_send * CHAN_NUM_SEND); - } -#else - return CAPTURE_TO_SEND_LEN(n); -#endif -} - -#ifdef USB_AUDIO_DYN_CFG -static uint32_t POSSIBLY_UNUSED capture_to_ref_len(uint32_t n) { - uint32_t len; - - len = samp_to_byte_send(byte_to_samp_capture(n)); - -#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) - // Capture reference sample rate and capture sample rate are integral multiple - // of each other. - - if (sample_rate_ref_cap == sample_rate_cap) { - return len; - } else if (sample_rate_ref_cap < sample_rate_cap) { - return len / (sample_rate_cap / sample_rate_ref_cap); - } else { - return len * (sample_rate_ref_cap / sample_rate_cap); - } -#else - return len; -#endif -} - -#ifdef KEEP_SAME_LATENCY -static uint32_t calc_usb_recv_size(enum AUD_SAMPRATE_T rate, - uint8_t sample_size) { - uint32_t size; - size = (SAMP_RATE_TO_FRAME_SIZE(rate) * sample_size * CHAN_NUM_RECV) * - (usb_recv_max_size / MAX_FRAME_SIZE_RECV); - return NON_EXP_ALIGN(size, RECV_BUFF_ALIGN); -} - -static uint32_t calc_usb_send_size(enum AUD_SAMPRATE_T rate) { - uint32_t size; - size = samp_to_byte_send(SAMP_RATE_TO_FRAME_SIZE(rate)) * usb_send_max_size / - MAX_FRAME_SIZE_SEND; - return NON_EXP_ALIGN(size, SEND_BUFF_ALIGN); -} - -static uint32_t calc_playback_size(enum AUD_SAMPRATE_T rate) { - uint32_t size; - size = samp_to_byte_playback(SAMP_RATE_TO_FRAME_SIZE(rate)) * - (playback_max_size / MAX_FRAME_SIZE_PLAYBACK); - return NON_EXP_ALIGN(size, DAC_BUFF_ALIGN); -} - -static uint32_t calc_capture_size(enum AUD_SAMPRATE_T rate) { - uint32_t size; - size = samp_to_byte_capture(SAMP_RATE_TO_FRAME_SIZE(rate)) * - (capture_max_size / MAX_FRAME_SIZE_CAPTURE); - return NON_EXP_ALIGN(size, ADC_BUFF_ALIGN); -} -#endif -#endif - -static void record_conflict(int conflicted) { - uint32_t lock; - uint32_t interval; - bool reset = false; - - lock = int_lock(); - - if (conflicted) { - nonconflict_start = 0; - if (conflict_cnt == 0) { - conflict_time = hal_sys_timer_get(); - } - conflict_cnt++; - - if (conflict_cnt >= CONFLICT_CMD_TRIG_COUNT) { - interval = hal_sys_timer_get() - conflict_time; - if (interval < CONFLICT_CMD_TRIG_INTERVAL) { - // TRACE(2,"RESET CODEC: conflict cnt=%u interval=%u ms", conflict_cnt, - // TICKS_TO_MS(interval)); - reset = true; - } - conflict_cnt = 0; - } - } else { - if (nonconflict_start == 0) { - nonconflict_start = 1; - if (conflict_cnt) { - nonconflict_time = hal_sys_timer_get(); - } - } else { - if (conflict_cnt) { - interval = hal_sys_timer_get() - nonconflict_time; - if (interval >= CONFLICT_STATE_RESET_INTERVAL) { - // TRACE(2,"RESET CONFLICT STATE: conflict cnt=%u nonconflict - // interval=%u ms", conflict_cnt, TICKS_TO_MS(interval)); - conflict_cnt = 0; - } - } - } - } - - int_unlock(lock); - - if (reset) { - // Avoid invoking cmd callback when irq is locked - enqueue_unique_cmd(AUDIO_CMD_RESET_CODEC); - } -} - -static void reset_conflict(void) { - uint32_t lock; - - lock = int_lock(); - conflict_cnt = 0; - nonconflict_start = 0; - int_unlock(lock); -} - -uint8_t usb_audio_get_eq_index(AUDIO_EQ_TYPE_T audio_eq_type, - uint8_t anc_status) { - uint8_t index_eq = 0; - -#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || \ - defined(__HW_DAC_IIR_EQ_PROCESS__) || defined(__HW_IIR_EQ_PROCESS__) - switch (audio_eq_type) { -#if defined(__SW_IIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_SW_IIR: { - if (anc_status) { - index_eq = audio_eq_sw_iir_index + 1; - } else { - index_eq = audio_eq_sw_iir_index; - } - - } break; -#endif - -#if defined(__HW_FIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_HW_FIR: { -#ifdef USB_AUDIO_DYN_CFG - if (sample_rate_recv == AUD_SAMPRATE_44100) { - index_eq = 0; - } else if (sample_rate_recv == AUD_SAMPRATE_48000) { - index_eq = 1; - } else if (sample_rate_recv == AUD_SAMPRATE_96000) { - index_eq = 2; - } else if (sample_rate_recv == AUD_SAMPRATE_192000) { - index_eq = 3; - } else { - ASSERT(0, "[%s] sample_rate_recv(%d) is not supported", __func__, - sample_rate_recv); - } - audio_eq_hw_fir_index = index_eq; -#else - index_eq = audio_eq_hw_fir_index; -#endif - if (anc_status) { - index_eq = index_eq + 4; - } - } break; -#endif - -#if defined(__HW_DAC_IIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_HW_DAC_IIR: { - if (anc_status) { - index_eq = audio_eq_hw_dac_iir_index + 1; - } else { - index_eq = audio_eq_hw_dac_iir_index; - } - } break; -#endif - -#if defined(__HW_IIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_HW_IIR: { - if (anc_status) { - index_eq = audio_eq_hw_iir_index + 1; - } else { - index_eq = audio_eq_hw_iir_index; - } - } break; -#endif - default: { - ASSERT(false, "[%s]Error eq type!", __func__); - } - } -#endif - return index_eq; -} - -uint32_t usb_audio_set_eq(AUDIO_EQ_TYPE_T audio_eq_type, uint8_t index) { - const FIR_CFG_T *fir_cfg = NULL; - const IIR_CFG_T *iir_cfg = NULL; - - TRACE(3, "[%s]audio_eq_type=%d,index=%d", __func__, audio_eq_type, index); - -#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || \ - defined(__HW_DAC_IIR_EQ_PROCESS__) || defined(__HW_IIR_EQ_PROCESS__) - switch (audio_eq_type) { -#if defined(__SW_IIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_SW_IIR: { - if (index >= EQ_SW_IIR_LIST_NUM) { - TRACE(2, "[%s] index[%d] > EQ_SW_IIR_LIST_NUM", __func__, index); - return 1; - } - - iir_cfg = audio_eq_sw_iir_cfg_list[index]; - } break; -#endif - -#if defined(__HW_FIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_HW_FIR: { - if (index >= EQ_HW_FIR_LIST_NUM) { - TRACE(2, "[%s] index[%d] > EQ_HW_FIR_LIST_NUM", __func__, index); - return 1; - } - - fir_cfg = audio_eq_hw_fir_cfg_list[index]; - } break; -#endif - -#if defined(__HW_DAC_IIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_HW_DAC_IIR: { - if (index >= EQ_HW_DAC_IIR_LIST_NUM) { - TRACE(2, "[%s] index[%d] > EQ_HW_DAC_IIR_LIST_NUM", __func__, index); - return 1; - } - - iir_cfg = audio_eq_hw_dac_iir_cfg_list[index]; - } break; -#endif - -#if defined(__HW_IIR_EQ_PROCESS__) - case AUDIO_EQ_TYPE_HW_IIR: { - if (index >= EQ_HW_IIR_LIST_NUM) { - TRACE(2, "[%s] index[%d] > EQ_HW_IIR_LIST_NUM", __func__, index); - return 1; - } - - iir_cfg = audio_eq_hw_iir_cfg_list[index]; - } break; -#endif - default: { - ASSERT(false, "[%s]Error eq type!", __func__); - } - } -#endif - - return audio_eq_set_cfg(fir_cfg, iir_cfg, audio_eq_type); -} - -static void set_codec_config_status(enum CODEC_CONFIG_LOCK_USER_T user, - bool lock) { - if (lock) { - codec_config_lock |= (1 << user); - } else { - codec_config_lock &= ~(1 << user); - } -} - -static void usb_audio_codec_mute(enum CODEC_MUTE_USER_T user) { - TRACE(3, "%s: user=%d map=0x%02X", __FUNCTION__, user, mute_user_map); - - if (user >= CODEC_MUTE_USER_QTY || mute_user_map == 0) { - af_stream_mute(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, true); - } - if (user < CODEC_MUTE_USER_QTY) { - mute_user_map |= (1 << user); - } -} - -static void usb_audio_codec_unmute(enum CODEC_MUTE_USER_T user) { - uint8_t old_map; - STATIC_ASSERT(sizeof(old_map) * 8 >= CODEC_MUTE_USER_QTY, - "old_map size too small"); - - TRACE(3, "%s: user=%d map=0x%02X", __FUNCTION__, user, mute_user_map); - - old_map = mute_user_map; - - if (user < CODEC_MUTE_USER_QTY) { - mute_user_map &= ~(1 << user); - } - if (user >= CODEC_MUTE_USER_QTY || (old_map && mute_user_map == 0)) { - af_stream_mute(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, false); - } -} - -#ifdef AUDIO_ANC_FB_MC - -#define DELAY_SAMPLE_MC (33 * 2) // 2:ch -static int32_t delay_buf[DELAY_SAMPLE_MC]; -static int32_t mid_p_8_old_l = 0; -static int32_t mid_p_8_old_r = 0; -static uint32_t audio_mc_data_playback(uint8_t *buf, uint32_t mc_len_bytes) { - // uint32_t begin_time; - // uint32_t end_time; - // begin_time = hal_sys_timer_get(); - // TRACE(1,"cancel: %d",begin_time); - - float left_gain; - float right_gain; - uint32_t playback_len_bytes; - int i, j, k; - int delay_sample; - - hal_codec_get_dac_gain(&left_gain, &right_gain); - - // TRACE(1,"playback_samplerate_ratio: %d",playback_samplerate_ratio); - - // TRACE(1,"left_gain: %d",(int)(left_gain*(1<<12))); - // TRACE(1,"right_gain: %d",(int)(right_gain*(1<<12))); - - playback_len_bytes = mc_len_bytes / playback_samplerate_ratio; - - if (sample_size_play == 2) { - int16_t *sour_p = (int16_t *)(playback_buf + playback_size / 2); - int16_t *mid_p = (int16_t *)(buf); - int16_t *mid_p_8 = (int16_t *)(buf + mc_len_bytes - mc_len_bytes / 8); - int16_t *dest_p = (int16_t *)buf; - int i, j, k; - - if (buf == (playback_buf + playback_size)) { - sour_p = (int16_t *)playback_buf; - } - - delay_sample = DELAY_SAMPLE_MC; - - for (i = 0, j = 0; i < delay_sample; i = i + 2) { - mid_p[j++] = delay_buf[i]; - mid_p[j++] = delay_buf[i + 1]; - } - - for (i = 0; i < playback_len_bytes / 2 - delay_sample; i = i + 2) { - mid_p[j++] = sour_p[i]; - mid_p[j++] = sour_p[i + 1]; - } - - for (j = 0; i < playback_len_bytes / 2; i = i + 2) { - delay_buf[j++] = sour_p[i]; - delay_buf[j++] = sour_p[i + 1]; - } - - if (playback_samplerate_ratio <= 8) { - for (i = 0, j = 0; i < playback_len_bytes / 2; - i = i + 2 * (8 / playback_samplerate_ratio)) { - mid_p_8[j++] = mid_p[i]; - mid_p_8[j++] = mid_p[i + 1]; - } - } else { - for (i = 0, j = 0; i < playback_len_bytes / 2; i = i + 2) { - for (k = 0; k < playback_samplerate_ratio / 8; k++) { - mid_p_8[j++] = mid_p[i]; - mid_p_8[j++] = mid_p[i + 1]; - } - } - } - - anc_mc_run_stereo((uint8_t *)mid_p_8, mc_len_bytes / 8, left_gain, - right_gain, AUD_BITS_16); - - for (i = 0, j = 0; i < (mc_len_bytes / 8) / 2; i = i + 2) { - float delta_l = (mid_p_8[i] - mid_p_8_old_l) / 8.0f; - float delta_r = (mid_p_8[i + 1] - mid_p_8_old_r) / 8.0f; - for (k = 0; k < 8; k++) { - dest_p[j++] = mid_p_8_old_l + (int32_t)(delta_l * k); - dest_p[j++] = mid_p_8_old_r + (int32_t)(delta_r * k); - } - mid_p_8_old_l = mid_p_8[i]; - mid_p_8_old_r = mid_p_8[i + 1]; - } - } else if (sample_size_play == 4) { - int32_t *sour_p = (int32_t *)(playback_buf + playback_size / 2); - int32_t *mid_p = (int32_t *)(buf); - int32_t *mid_p_8 = (int32_t *)(buf + mc_len_bytes - mc_len_bytes / 8); - int32_t *dest_p = (int32_t *)buf; - - if (buf == (playback_buf + playback_size)) { - sour_p = (int32_t *)playback_buf; - } - - delay_sample = DELAY_SAMPLE_MC; - - for (i = 0, j = 0; i < delay_sample; i = i + 2) { - mid_p[j++] = delay_buf[i]; - mid_p[j++] = delay_buf[i + 1]; - } - - for (i = 0; i < playback_len_bytes / 4 - delay_sample; i = i + 2) { - mid_p[j++] = sour_p[i]; - mid_p[j++] = sour_p[i + 1]; - } - - for (j = 0; i < playback_len_bytes / 4; i = i + 2) { - delay_buf[j++] = sour_p[i]; - delay_buf[j++] = sour_p[i + 1]; - } - - if (playback_samplerate_ratio <= 8) { - for (i = 0, j = 0; i < playback_len_bytes / 4; - i = i + 2 * (8 / playback_samplerate_ratio)) { - mid_p_8[j++] = mid_p[i]; - mid_p_8[j++] = mid_p[i + 1]; - } - } else { - for (i = 0, j = 0; i < playback_len_bytes / 4; i = i + 2) { - for (k = 0; k < playback_samplerate_ratio / 8; k++) { - mid_p_8[j++] = mid_p[i]; - mid_p_8[j++] = mid_p[i + 1]; - } - } - } - - anc_mc_run_stereo((uint8_t *)mid_p_8, mc_len_bytes / 8, left_gain, - right_gain, AUD_BITS_24); - - for (i = 0, j = 0; i < (mc_len_bytes / 8) / 4; i = i + 2) { - float delta_l = (mid_p_8[i] - mid_p_8_old_l) / 8.0f; - float delta_r = (mid_p_8[i + 1] - mid_p_8_old_r) / 8.0f; - for (k = 0; k < 8; k++) { - dest_p[j++] = mid_p_8_old_l + (int32_t)(delta_l * k); - dest_p[j++] = mid_p_8_old_r + (int32_t)(delta_r * k); - } - mid_p_8_old_l = mid_p_8[i]; - mid_p_8_old_r = mid_p_8[i + 1]; - } - } - - // end_time = hal_sys_timer_get(); - // TRACE(2,"%s:run time: %d", __FUNCTION__, end_time-begin_time); - - return 0; -} -#endif - -static uint32_t usb_audio_data_playback(uint8_t *buf, uint32_t len) { - uint32_t usb_len; - uint32_t old_rpos, saved_old_rpos, new_rpos, wpos; - uint8_t recv_valid, init_pos; - uint8_t conflicted; - uint32_t reset_len = usb_recv_size / 2; -#ifdef USB_AUDIO_MULTIFUNC - uint32_t old_rpos2, saved_old_rpos2, new_rpos2, wpos2; - uint8_t recv2_valid, init_pos2; - uint8_t conflicted2; - uint32_t reset_len2 = usb_recv2_size / 2; -#endif - uint32_t play_next; - uint32_t lock; - uint8_t *conv_buf; - uint32_t cur_time; - uint32_t usb_time; - - usb_time = last_usb_recv_time; - cur_time = hal_sys_timer_get(); - - //---------------------------------------- - // Speech processing start - //---------------------------------------- -#ifdef USB_AUDIO_SPEECH - speech_process_playback_run(buf, &len); -#endif - //---------------------------------------- - // Speech processing end - //---------------------------------------- - - ASSERT(((uint32_t)buf & 0x3) == 0, "%s: Invalid buf: %p", __FUNCTION__, buf); - - // playback is valid when reaching here - codec_play_valid = 1; - - init_pos = 0; - // Allow to play till the end of the buffer when itf stopped - if (usb_recv_valid && !(recv_state == AUDIO_ITF_STATE_STOPPED && - usb_recv_rpos == usb_recv_wpos)) { - recv_valid = 1; - if (usb_recv_init_rpos == 0) { - init_pos = 1; - } - } else { - recv_valid = 0; - } -#ifdef USB_AUDIO_MULTIFUNC - init_pos2 = 0; - if (usb_recv2_valid && !(recv2_state == AUDIO_ITF_STATE_STOPPED && - usb_recv2_rpos == usb_recv2_wpos)) { - recv2_valid = 1; - if (usb_recv2_init_rpos == 0) { - init_pos2 = 1; - } - } else { - recv2_valid = 0; - } -#endif - - if (codec_play_seq != usb_recv_seq || - playback_state == AUDIO_ITF_STATE_STOPPED || -#ifdef USB_AUDIO_MULTIFUNC - (recv_valid == 0 && recv2_valid == 0) || -#else - recv_valid == 0 || -#endif - cur_time - usb_time > USB_MAX_XFER_INTERVAL) { - _invalid_play: - zero_mem32(buf, len); - conv_buf = buf; - // If usb recv is stopped, set usb_recv_rpos to the value of usb_recv_wpos - // -- avoid playing noise. Otherwise set usb_recv_rpos to 0 -- avoid buffer - // conflicts at usb recv startup. - new_rpos = (recv_state == AUDIO_ITF_STATE_STOPPED) ? usb_recv_wpos : 0; - conflicted = 0; -#ifdef USB_AUDIO_MULTIFUNC - new_rpos2 = (recv2_state == AUDIO_ITF_STATE_STOPPED) ? usb_recv2_wpos : 0; - conflicted2 = 0; -#endif - - goto _conv_end; - } - - //---------------------------------------- - // Check conflict - //---------------------------------------- - - usb_len = playback_to_recv_len(len); - conflicted = 0; -#ifdef USB_AUDIO_MULTIFUNC - conflicted2 = 0; -#endif - - lock = int_lock(); - wpos = usb_recv_wpos; - if (init_pos) { - old_rpos = wpos + reset_len; - if (old_rpos >= usb_recv_size) { - old_rpos -= usb_recv_size; - } - usb_recv_rpos = old_rpos; - usb_recv_init_rpos = 1; - } else { - old_rpos = usb_recv_rpos; - } - saved_old_rpos = old_rpos; - new_rpos = usb_recv_rpos + usb_len; - if (new_rpos >= usb_recv_size) { - new_rpos -= usb_recv_size; - } - if (recv_valid && init_pos == 0) { - if (old_rpos <= wpos) { - if (new_rpos < old_rpos || wpos < new_rpos) { - if (recv_state == AUDIO_ITF_STATE_STOPPED) { - if (new_rpos < old_rpos) { - zero_mem(usb_recv_buf + wpos, usb_recv_size - wpos); - zero_mem(usb_recv_buf, new_rpos); - } else { - zero_mem(usb_recv_buf + wpos, new_rpos - wpos); - } - wpos = new_rpos; - usb_recv_wpos = new_rpos; - } else { - conflicted = 1; - } - } - } else { - if (wpos < new_rpos && new_rpos < old_rpos) { - if (recv_state == AUDIO_ITF_STATE_STOPPED) { - zero_mem(usb_recv_buf + wpos, new_rpos - wpos); - wpos = new_rpos; - usb_recv_wpos = new_rpos; - } else { - conflicted = 1; - } - } - } - if (conflicted) { - // Reset read position - old_rpos = wpos + reset_len; - if (old_rpos >= usb_recv_size) { - old_rpos -= usb_recv_size; - } - new_rpos = old_rpos + usb_len; - if (new_rpos >= usb_recv_size) { - new_rpos -= usb_recv_size; - } - // Update global read position - usb_recv_rpos = old_rpos; - } - } - -#ifdef USB_AUDIO_MULTIFUNC - wpos2 = usb_recv2_wpos; - if (init_pos2) { - old_rpos2 = wpos2 + reset_len2; - if (old_rpos2 >= usb_recv2_size) { - old_rpos2 -= usb_recv2_size; - } - usb_recv2_rpos = old_rpos2; - usb_recv2_init_rpos = 1; - } else { - old_rpos2 = usb_recv2_rpos; - } - saved_old_rpos2 = old_rpos2; - new_rpos2 = usb_recv2_rpos + usb_len; - if (new_rpos2 >= usb_recv2_size) { - new_rpos2 -= usb_recv2_size; - } - if (recv2_valid && init_pos2 == 0) { - if (old_rpos2 <= wpos2) { - if (new_rpos2 < old_rpos2 || wpos2 < new_rpos2) { - if (recv2_state == AUDIO_ITF_STATE_STOPPED) { - if (new_rpos2 < old_rpos2) { - zero_mem(usb_recv2_buf + wpos2, usb_recv2_size - wpos2); - zero_mem(usb_recv2_buf, new_rpos2); - } else { - zero_mem(usb_recv2_buf + wpos2, new_rpos2 - wpos2); - } - wpos2 = new_rpos2; - usb_recv2_wpos = new_rpos2; - } else { - conflicted2 = 1; - } - } - } else { - if (wpos2 < new_rpos2 && new_rpos2 < old_rpos2) { - if (recv2_state == AUDIO_ITF_STATE_STOPPED) { - zero_mem(usb_recv2_buf + wpos2, new_rpos2 - wpos2); - wpos2 = new_rpos2; - usb_recv2_wpos = new_rpos2; - } else { - conflicted2 = 1; - } - } - } - if (conflicted2) { - // Reset read position - old_rpos2 = wpos2 + reset_len2; - if (old_rpos2 >= usb_recv2_size) { - old_rpos2 -= usb_recv2_size; - } - new_rpos2 = old_rpos2 + usb_len; - if (new_rpos2 >= usb_recv2_size) { - new_rpos2 -= usb_recv2_size; - } - // Update global read position - usb_recv2_rpos = old_rpos2; - } - } -#endif - int_unlock(lock); - - if (conflicted) { - TRACE(4, - "playback: Error: rpos=%u goes beyond wpos=%u with usb_len=%u. Reset " - "to %u", - saved_old_rpos, wpos, usb_len, old_rpos); - } -#ifdef USB_AUDIO_MULTIFUNC - if (conflicted2) { - TRACE(4, - "playback: Error: rpos2=%u goes beyond wpos2=%u with usb_len=%u. " - "Reset to %u", - saved_old_rpos2, wpos2, usb_len, old_rpos2); - } -#endif - -#if (VERBOSE_TRACE & (1 << 0)) - { - int hw_play_pos = - af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - uint32_t play_pos = buf - playback_buf; -#ifdef USB_AUDIO_MULTIFUNC - if (recv_valid == 0) { - old_rpos = -1; - wpos = -1; - } - if (recv2_valid == 0) { - old_rpos2 = -1; - wpos2 = -1; - } - TRACE_TIME(8, - "playback: rpos=%d/%d usb_len=%d wpos=%d/%d play_pos=%d len=%d " - "hw_play_pos=%d", - old_rpos, old_rpos2, usb_len, wpos, wpos2, play_pos, len, - hw_play_pos); -#else - TRACE_TIME(6, - "playback: rpos=%d usb_len=%d wpos=%d play_pos=%d len=%d " - "hw_play_pos=%d", - old_rpos, usb_len, wpos, play_pos, len, hw_play_pos); -#endif - } -#endif - - if (codec_play_seq != usb_recv_seq) { - goto _invalid_play; - } - -#ifdef USB_AUDIO_MULTIFUNC - record_conflict(conflicted || conflicted2); -#else - record_conflict(conflicted); -#endif - - //---------------------------------------- - // USB->CODEC stream format conversion start - //---------------------------------------- - - conv_buf = buf; - -#ifdef USB_AUDIO_MULTIFUNC - - { - uint8_t POSSIBLY_UNUSED *cur_buf, *buf_end, *usb_cur_buf, *usb_buf_end, - *usb_cur_buf2, *usb_buf_end2; - uint32_t codec_step, usb_step; - float cur_gain, new_gain, cur_gain2, new_gain2, gain_step; - - cur_buf = conv_buf; - buf_end = conv_buf + len; - usb_cur_buf = usb_recv_buf + old_rpos; - usb_buf_end = usb_recv_buf + usb_recv_size; - usb_cur_buf2 = usb_recv2_buf + old_rpos2; - usb_buf_end2 = usb_recv2_buf + usb_recv2_size; - - cur_gain = playback_coef; - new_gain = new_playback_coef; - cur_gain2 = playback2_coef; - new_gain2 = new_playback2_coef; - gain_step = USB_AUDIO_VOL_UPDATE_STEP; - - ASSERT(sample_rate_play == sample_rate_recv, - "2:1: Invalid sample_rate_play=%u sample_rate_recv=%u", - sample_rate_play, sample_rate_recv); - - if (0) { - - } else if (sample_size_play == 4 && - (sample_size_recv == 4 || sample_size_recv == 3 || - sample_size_recv == 2)) { - - int32_t left, right; - int32_t left2, right2; - - if (sample_size_recv == 4) { - usb_step = 8; - } else if (sample_size_recv == 3) { - usb_step = 6; - } else { - usb_step = 4; - } - - codec_step = 8; - - while (cur_buf + codec_step <= buf_end) { - if (usb_cur_buf + usb_step > usb_buf_end) { - usb_cur_buf = usb_recv_buf; - } - if (usb_cur_buf2 + usb_step > usb_buf_end2) { - usb_cur_buf2 = usb_recv2_buf; - } - if (recv_valid) { - if (usb_step == 8) { - left = *(int32_t *)usb_cur_buf; - right = *((int32_t *)usb_cur_buf + 1); - } else if (usb_step == 6) { - left = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16) | - (usb_cur_buf[2] << 24)); - right = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16) | - (usb_cur_buf[5] << 24)); - } else { - left = *(int16_t *)usb_cur_buf << 16; - right = *((int16_t *)usb_cur_buf + 1) << 16; - } - if (cur_gain > new_gain) { - cur_gain -= gain_step; - if (cur_gain < new_gain) { - cur_gain = new_gain; - } - } else if (cur_gain < new_gain) { - cur_gain += gain_step; - if (cur_gain > new_gain) { - cur_gain = new_gain; - } - } - left = (int32_t)(left * cur_gain); - right = (int32_t)(right * cur_gain); - } else { - left = right = 0; - } - if (recv2_valid) { - if (usb_step == 8) { - left2 = *(int32_t *)usb_cur_buf2; - right2 = *((int32_t *)usb_cur_buf2 + 1); - } else if (usb_step == 6) { - left2 = ((usb_cur_buf2[0] << 8) | (usb_cur_buf2[1] << 16) | - (usb_cur_buf2[2] << 24)); - right2 = ((usb_cur_buf2[3] << 8) | (usb_cur_buf2[4] << 16) | - (usb_cur_buf2[5] << 24)); - } else { - left2 = *(int16_t *)usb_cur_buf2 << 16; - right2 = *((int16_t *)usb_cur_buf2 + 1) << 16; - } - if (cur_gain2 > new_gain2) { - cur_gain2 -= gain_step; - if (cur_gain2 < new_gain2) { - cur_gain2 = new_gain2; - } - } else if (cur_gain2 < new_gain2) { - cur_gain2 += gain_step; - if (cur_gain2 > new_gain2) { - cur_gain2 = new_gain2; - } - } - left2 = (int32_t)(left2 * cur_gain2); - right2 = (int32_t)(right2 * cur_gain2); - } else { - left2 = right2 = 0; - } - left = __QADD(left, left2); - right = __QADD(right, right2); - // Convert to 24-bit sample - left >>= 8; - right >>= 8; - - *(int32_t *)cur_buf = left; - *((int32_t *)cur_buf + 1) = right; - - cur_buf += codec_step; - usb_cur_buf += usb_step; - usb_cur_buf2 += usb_step; - } - } else if (sample_size_play == 2 && sample_size_recv == 2) { - - int32_t left, right; - int32_t left2, right2; - - usb_step = 4; - codec_step = 4; - - while (cur_buf + codec_step <= buf_end) { - if (usb_cur_buf + usb_step > usb_buf_end) { - usb_cur_buf = usb_recv_buf; - } - if (usb_cur_buf2 + usb_step > usb_buf_end2) { - usb_cur_buf2 = usb_recv2_buf; - } - if (recv_valid) { - left = *(int16_t *)usb_cur_buf; - right = *((int16_t *)usb_cur_buf + 1); - if (cur_gain > new_gain) { - cur_gain -= gain_step; - if (cur_gain < new_gain) { - cur_gain = new_gain; - } - } else if (cur_gain < new_gain) { - cur_gain += gain_step; - if (cur_gain > new_gain) { - cur_gain = new_gain; - } - } - left = (int32_t)(left * cur_gain); - right = (int32_t)(right * cur_gain); - } else { - left = right = 0; - } - if (recv2_valid) { - left2 = *(int16_t *)usb_cur_buf2; - right2 = *((int16_t *)usb_cur_buf2 + 1); - if (cur_gain2 > new_gain2) { - cur_gain2 -= gain_step; - if (cur_gain2 < new_gain2) { - cur_gain2 = new_gain2; - } - } else if (cur_gain2 < new_gain2) { - cur_gain2 += gain_step; - if (cur_gain2 > new_gain2) { - cur_gain2 = new_gain2; - } - } - left2 = (int32_t)(left2 * cur_gain2); - right2 = (int32_t)(right2 * cur_gain2); - } else { - left2 = right2 = 0; - } - left = __SSAT(left + left2, 16); - right = __SSAT(right + right2, 16); - - *(int16_t *)cur_buf = left; - *((int16_t *)cur_buf + 1) = right; - - cur_buf += codec_step; - usb_cur_buf += usb_step; - } - - } else { - - ASSERT(false, "2:3: Invalid sample_size_play=%u sample_size_recv=%u", - sample_size_play, sample_size_recv); - } - - playback_coef = cur_gain; - playback2_coef = cur_gain2; - } - -#else - - { - uint8_t POSSIBLY_UNUSED *cur_buf, *buf_end, *usb_cur_buf, *usb_buf_end; - uint32_t codec_step, usb_step; - bool down_sampling = false; - - cur_buf = conv_buf; - buf_end = conv_buf + len; - usb_cur_buf = usb_recv_buf + old_rpos; - usb_buf_end = usb_recv_buf + usb_recv_size; - - if (0) { - -#ifdef CODEC_DSD - } else if (codec_dsd_enabled) { - - ASSERT(sample_size_play == 2, "Bad DSD playback sample size: %u", - sample_size_play); - ASSERT(sample_size_recv == 4 || sample_size_recv == 3, - "Bad DSD recv sample size: %u", sample_size_recv); - - uint32_t left, right; - - if (sample_size_recv == 4) { - usb_step = 8; - } else { - usb_step = 6; - } - - codec_step = 4; - - while (cur_buf + codec_step <= buf_end) { - if (usb_cur_buf + usb_step > usb_buf_end) { - usb_cur_buf = usb_recv_buf; - } - if (usb_step == 8) { - left = *(uint32_t *)usb_cur_buf; - right = *((uint32_t *)usb_cur_buf + 1); - } else { - left = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16)); - right = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16)); - } - - left = __RBIT(left) >> 8; - right = __RBIT(right) >> 8; - - *(uint16_t *)cur_buf = left; - *((uint16_t *)cur_buf + 1) = right; - - cur_buf += codec_step; - usb_cur_buf += usb_step; - } -#endif - - } else if (sample_size_play == 4 && - (sample_size_recv == 4 || sample_size_recv == 3 || - sample_size_recv == 2)) { - - int32_t left, right; - - if (sample_size_recv == 4) { - usb_step = 8; - } else if (sample_size_recv == 3) { - usb_step = 6; - } else { - usb_step = 4; - } - - if ((sample_rate_play == 96000 && sample_rate_recv == 48000) || - (sample_rate_play == 88200 && sample_rate_recv == 44100)) { - codec_step = 16; - } else if (sample_rate_play == sample_rate_recv) { - codec_step = 8; - } else if (sample_rate_play == 96000 && sample_rate_recv == 192000) { - codec_step = 8; - down_sampling = true; - } else { - ASSERT(false, "1: Invalid sample_rate_play=%u sample_rate_recv=%u", - sample_rate_play, sample_rate_recv); - } - - while (cur_buf + codec_step <= buf_end) { - if (usb_cur_buf + usb_step > usb_buf_end) { - usb_cur_buf = usb_recv_buf; - } - if (usb_step == 8) { - left = *(int32_t *)usb_cur_buf; - right = *((int32_t *)usb_cur_buf + 1); - } else if (usb_step == 6) { - left = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16) | - (usb_cur_buf[2] << 24)); - right = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16) | - (usb_cur_buf[5] << 24)); - } else { - left = *(int16_t *)usb_cur_buf << 16; - right = *((int16_t *)usb_cur_buf + 1) << 16; - } - // Convert to 24-bit sample - left >>= 8; - right >>= 8; - - if (down_sampling) { - int32_t left_next, right_next; - - usb_cur_buf += usb_step; - if (usb_cur_buf + usb_step > usb_buf_end) { - usb_cur_buf = usb_recv_buf; - } - if (usb_step == 8) { - left_next = *(int32_t *)usb_cur_buf; - right_next = *((int32_t *)usb_cur_buf + 1); - } else if (usb_step == 6) { - left_next = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16) | - (usb_cur_buf[2] << 24)); - right_next = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16) | - (usb_cur_buf[5] << 24)); - } else { - left_next = *(int16_t *)usb_cur_buf << 16; - right_next = *((int16_t *)usb_cur_buf + 1) << 16; - } - // Convert to 24-bit sample - left_next >>= 8; - right_next >>= 8; - - // The addition of two 24-bit integers will not saturate - left = (left + left_next) / 2; - right = (right + right_next) / 2; - } - - *(int32_t *)cur_buf = left; - *((int32_t *)cur_buf + 1) = right; - if (codec_step == 16) { - *((int32_t *)cur_buf + 2) = left; - *((int32_t *)cur_buf + 3) = right; - } - - cur_buf += codec_step; - usb_cur_buf += usb_step; - } - - } else if (sample_size_play == 2 && sample_size_recv == 2) { - - int16_t left, right; - - usb_step = 4; - - if ((sample_rate_play == 96000 && sample_rate_recv == 48000) || - (sample_rate_play == 88200 && sample_rate_recv == 44100)) { - codec_step = 8; - } else if (sample_rate_play == sample_rate_recv) { - codec_step = 4; - } else if (sample_rate_play == 96000 && sample_rate_recv == 192000) { - codec_step = 4; - down_sampling = true; - } else { - ASSERT(false, "2: Invalid sample_rate_play=%u sample_rate_recv=%u", - sample_rate_play, sample_rate_recv); - } - - while (cur_buf + codec_step <= buf_end) { - if (usb_cur_buf + usb_step > usb_buf_end) { - usb_cur_buf = usb_recv_buf; - } - left = *(int16_t *)usb_cur_buf; - right = *((int16_t *)usb_cur_buf + 1); - if (down_sampling) { - // Use 32-bit integers to avoid saturation - int32_t left32, right32; - - usb_cur_buf += usb_step; - if (usb_cur_buf + usb_step > usb_buf_end) { - usb_cur_buf = usb_recv_buf; - } - left32 = *(int16_t *)usb_cur_buf; - right32 = *((int16_t *)usb_cur_buf + 1); - left = (left + left32) / 2; - right = (right + right32) / 2; - } - *(int16_t *)cur_buf = left; - *((int16_t *)cur_buf + 1) = right; - if (codec_step == 8) { - *((int16_t *)cur_buf + 2) = left; - *((int16_t *)cur_buf + 3) = right; - } - cur_buf += codec_step; - usb_cur_buf += usb_step; - } - - } else { - - ASSERT(false, "3: Invalid sample_size_play=%u sample_size_recv=%u", - sample_size_play, sample_size_recv); - } - } - -#endif // !USB_AUDIO_MULTIFUNC - - //---------------------------------------- - // USB->CODEC stream format conversion end - //---------------------------------------- -_conv_end: - - play_next = buf + len - playback_buf; - if (play_next >= playback_size) { - play_next -= playback_size; - } - - lock = int_lock(); - if (codec_play_seq == usb_recv_seq) { -#ifdef USB_AUDIO_MULTIFUNC - if (playback_state == AUDIO_ITF_STATE_STARTED) { - if (recv_valid) { - usb_recv_rpos = new_rpos; - } - if (recv2_valid) { - usb_recv2_rpos = new_rpos2; - } - } else { - if (recv_valid) { - usb_recv_rpos = 0; - } - if (recv2_valid) { - usb_recv2_rpos = 0; - } - } - if (conflicted) { - playback_conflicted = conflicted; - } - if (conflicted2) { - playback_conflicted2 = conflicted2; - } -#else - if (playback_state == AUDIO_ITF_STATE_STARTED) { - usb_recv_rpos = new_rpos; - } else { - usb_recv_rpos = 0; - } - if (conflicted) { - playback_conflicted = conflicted; - } -#endif - playback_pos = play_next; - } - int_unlock(lock); - - //---------------------------------------- - // Audio processing start - //---------------------------------------- - -#ifdef FREQ_RESP_EQ - freq_resp_eq_run(conv_buf, len); -#endif -#if defined(__HW_FIR_DSD_PROCESS__) - if (codec_dsd_enabled) { - dsd_process(conv_buf, len); - } -#endif - -#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || \ - defined(__HW_IIR_EQ_PROCESS__) - if (eq_opened) { - audio_process_run(conv_buf, len); - } -#endif - - // If conv_buf != buf, copy the output to buf - - //---------------------------------------- - // Audio processing end - //---------------------------------------- - -#ifdef NOISE_GATING - bool noise_mute = true; -#ifdef NOISE_REDUCTION - bool nr_fire = true; - uint8_t chan = 0; -#endif - - if (sample_size_play == 2) { - int16_t *samp = (int16_t *)buf; - for (uint32_t i = 0; i < len / 2; i++) { - if (ABS(samp[i]) >= NOISE_GATING_THRESH_16BIT) { - noise_mute = false; - break; - } - // NOISE_REDUCTION is unstable for 16-bit streams for unknown reasons. - // Skip by now. - } - } else { - int32_t *samp = (int32_t *)buf; - for (uint32_t i = 0; i < len / 4; i++) { - if (ABS(samp[i]) >= NOISE_GATING_THRESH_24BIT) { - noise_mute = false; -#ifndef NOISE_REDUCTION - break; -#endif - } -#ifdef NOISE_REDUCTION - if (nr_fire) { - if (ABS(samp[i]) >= NOISE_REDUCTION_THRESH_24BIT) { - nr_fire = false; - } else { - cur_zero_diff[chan][0]++; - cur_zero_diff[chan][1]++; - if ((prev_samp_positive[chan] && samp[i] < 0) || - (!prev_samp_positive[chan] && samp[i] >= 0)) { - if (ABS(cur_zero_diff[chan][prev_samp_positive[chan]] - - prev_zero_diff[chan][prev_samp_positive[chan]]) < 2) { - if (nr_cont_cnt < NOISE_REDUCTION_MATCH_CNT) { - nr_cont_cnt++; - } - } else if (nr_cont_cnt > 2) { - nr_fire = false; - } - prev_zero_diff[chan][prev_samp_positive[chan]] = - cur_zero_diff[chan][prev_samp_positive[chan]]; - cur_zero_diff[chan][prev_samp_positive[chan]] = 0; - } - prev_samp_positive[chan] = (samp[i] >= 0); - // Switch channel - chan = !chan; - } - } -#endif - } - } - -#ifdef NOISE_REDUCTION - if (noise_mute) { - nr_fire = false; - } - if (nr_fire) { - if (nr_cont_cnt >= NOISE_REDUCTION_MATCH_CNT && !nr_active && - noise_reduction_cmd != NOISE_REDUCTION_CMD_FIRE) { - if (cur_time - last_nr_restore_time >= NOISE_REDUCTION_INTERVAL) { - TRACE(8, - "\nFire noise reduction: cur0=%u/%u cur1=%u/%u prev0=%u/%u " - "prev1=%u/%u\n", - cur_zero_diff[0][0], cur_zero_diff[0][1], cur_zero_diff[1][0], - cur_zero_diff[1][1], prev_zero_diff[0][0], prev_zero_diff[0][1], - prev_zero_diff[1][0], prev_zero_diff[1][1]); - noise_reduction_cmd = NOISE_REDUCTION_CMD_FIRE; - enqueue_unique_cmd(AUDIO_CMD_NOISE_REDUCTION); - } - } - } else { - if (nr_active && noise_reduction_cmd != NOISE_REDUCTION_CMD_RESTORE) { - TRACE(8, - "\nRestore noise reduction: cur0=%u/%u cur1=%u/%u prev0=%u/%u " - "prev1=%u/%u\n", - cur_zero_diff[0][0], cur_zero_diff[0][1], cur_zero_diff[1][0], - cur_zero_diff[1][1], prev_zero_diff[0][0], prev_zero_diff[0][1], - prev_zero_diff[1][0], prev_zero_diff[1][1]); - noise_reduction_cmd = NOISE_REDUCTION_CMD_RESTORE; - enqueue_unique_cmd(AUDIO_CMD_NOISE_REDUCTION); - } - memset(prev_zero_diff, 0, sizeof(prev_zero_diff)); - memset(cur_zero_diff, 0, sizeof(cur_zero_diff)); - nr_cont_cnt = 0; - last_nr_restore_time = cur_time; - } -#endif - - if (noise_mute) { - if ((mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) == 0 && - noise_gating_cmd != NOISE_GATING_CMD_MUTE) { - if (cur_time - last_high_signal_time >= NOISE_GATING_INTERVAL) { - noise_gating_cmd = NOISE_GATING_CMD_MUTE; - enqueue_unique_cmd(AUDIO_CMD_NOISE_GATING); - } - } - } else { - if ((mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) && - noise_gating_cmd != NOISE_GATING_CMD_UNMUTE) { - noise_gating_cmd = NOISE_GATING_CMD_UNMUTE; - enqueue_unique_cmd(AUDIO_CMD_NOISE_GATING); - } - last_high_signal_time = cur_time; - } -#endif - -#if (VERBOSE_TRACE & (1 << 1)) - { - int hw_play_pos = - af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - TRACE_TIME(2, "playbackEnd: playback_pos=%u hw_play_pos=%d", playback_pos, - hw_play_pos); - } -#endif - - return 0; -} - -static uint32_t usb_audio_data_capture(uint8_t *buf, uint32_t len) { - uint32_t usb_len; - uint32_t old_wpos, saved_old_wpos, new_wpos, rpos; - uint8_t init_pos; - uint8_t conflicted; - uint32_t reset_len = usb_send_size / 2; - uint32_t cap_next; - uint32_t lock; - uint8_t *conv_buf; - uint32_t cur_time; - uint32_t usb_time; -#ifdef SW_CAPTURE_RESAMPLE - enum RESAMPLE_STATUS_T ret; - struct RESAMPLE_IO_BUF_T io; - uint32_t in_size; - uint32_t out_size; - uint32_t resample_frame_len = 0; -#endif - - usb_time = last_usb_send_time; - cur_time = hal_sys_timer_get(); - - ASSERT(((uint32_t)buf & 0x3) == 0, "%s: Invalid buf: %p", __FUNCTION__, buf); - - if (codec_cap_valid == 0 && - cur_time - codec_cap_start_time >= CAPTURE_STABLE_INTERVAL) { - codec_cap_valid = 1; - } - - if (codec_cap_seq != usb_send_seq || - capture_state == AUDIO_ITF_STATE_STOPPED || - send_state == AUDIO_ITF_STATE_STOPPED || codec_cap_valid == 0 || - usb_send_valid == 0 || cur_time - usb_time > USB_MAX_XFER_INTERVAL) { - _invalid_cap: - new_wpos = 0; - conflicted = 0; - goto _conv_end; - } - - if (usb_send_init_wpos) { - init_pos = 0; - } else { - init_pos = 1; - } - - //---------------------------------------- - // Check conflict - //---------------------------------------- - - usb_len = capture_to_send_len(len); - conflicted = 0; - - lock = int_lock(); - rpos = usb_send_rpos; - if (init_pos) { - old_wpos = rpos + reset_len; - if (old_wpos >= usb_send_size) { - old_wpos -= usb_send_size; - } - usb_send_wpos = old_wpos; - usb_send_init_wpos = 1; - } else { - old_wpos = usb_send_wpos; - } - saved_old_wpos = old_wpos; - new_wpos = usb_send_wpos + usb_len; - if (new_wpos >= usb_send_size) { - new_wpos -= usb_send_size; - } - if (init_pos == 0) { - if (old_wpos <= rpos) { - if (new_wpos < old_wpos || rpos < new_wpos) { - conflicted = 1; - } - } else { - if (rpos < new_wpos && new_wpos < old_wpos) { - conflicted = 1; - } - } - if (conflicted) { - // Reset write position - old_wpos = rpos + reset_len; - if (old_wpos >= usb_send_size) { - old_wpos -= usb_send_size; - } - new_wpos = old_wpos + usb_len; - if (new_wpos >= usb_send_size) { - new_wpos -= usb_send_size; - } - // Update global write position - usb_send_wpos = old_wpos; - } - } - int_unlock(lock); - - if (conflicted) { - TRACE(4, - "capture: Error: wpos=%u goes beyond rpos=%u with usb_len=%u. Reset " - "to %u", - saved_old_wpos, rpos, usb_len, old_wpos); - } - -#if (VERBOSE_TRACE & (1 << 2)) - TRACE_TIME(5, "capture: wpos=%u usb_len=%u rpos=%u cap_pos=%u len=%u", - old_wpos, usb_len, rpos, buf + len - capture_buf, len); -#endif - - if (codec_cap_seq != usb_send_seq) { - goto _invalid_cap; - } - - record_conflict(conflicted); - - //---------------------------------------- - // Audio processing start - //---------------------------------------- - - // TODO ... - - //---------------------------------------- - // Audio processing end - //---------------------------------------- - - //---------------------------------------- - // Speech processing start - //---------------------------------------- -#ifdef USB_AUDIO_SPEECH - speech_process_capture_run(buf, &len); -#endif - //---------------------------------------- - // Speech processing end - //---------------------------------------- - - //---------------------------------------- - // CODEC->USB stream format conversion start - //---------------------------------------- - - conv_buf = buf; - - { - uint8_t POSSIBLY_UNUSED *cur_buf, *buf_end, *dst_buf_start, *dst_cur_buf, - *dst_buf_end; - - cur_buf = conv_buf; - buf_end = conv_buf + len; -#ifdef SW_CAPTURE_RESAMPLE - if (resample_cap_enabled) { -#if (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) -#if (defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) - // codec capture buffer --(ref rate conversion)--> resample input buffer - // --(resample)--> usb send buffer - -#ifdef USB_AUDIO_DYN_CFG - // Resample frame len is the capture reference len after reference rate - // conversion - resample_frame_len = capture_to_ref_len(len); -#else - // Resample frame len is the capture len - resample_frame_len = len; -#endif - ASSERT(resample_frame_len <= resample_input_size, - "resample_input_size too small: %u len=%u resample_frame_len=%u", - resample_input_size, len, resample_frame_len); - - dst_buf_start = resample_input_buf; - dst_cur_buf = resample_input_buf; - dst_buf_end = resample_input_buf + resample_frame_len; -#else // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) - // codec capture buffer --(resample)--> usb send buffer - - resample_input_buf = cur_buf; - // Resample frame len is the capture len - resample_frame_len = len; - - dst_buf_start = cur_buf; - dst_cur_buf = cur_buf; - dst_buf_end = cur_buf + len; -#endif // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) -#elif (CHAN_NUM_CAPTURE == 2) && (CHAN_NUM_SEND == 1) - // codec capture buffer --(chan num conversion)--> codec capture buffer - // --(resample)--> usb send buffer - - resample_input_buf = cur_buf; - // Resample frame len is half of the capture len - resample_frame_len = len / 2; - - dst_buf_start = cur_buf; - dst_cur_buf = cur_buf; - dst_buf_end = cur_buf + resample_frame_len; -#elif (CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2) - // codec capture buffer --(resample)--> usb send buffer --(chan num - // conversion)--> usb send buffer - - // Resample frame len is the capture len - resample_frame_len = len; - - io.in = cur_buf; - io.in_size = resample_frame_len; - io.out = usb_send_buf + old_wpos; - io.out_size = usb_len / 2; - io.out_cyclic_start = usb_send_buf; - io.out_cyclic_end = usb_send_buf + usb_send_size; - - ret = audio_resample_ex_run(resample_id, &io, &in_size, &out_size); - ASSERT((ret == RESAMPLE_STATUS_IN_EMPTY || ret == RESAMPLE_STATUS_DONE) && - io.out_size >= out_size, - "Failed to resample: %d io.out_size=%u in_size=%u out_size=%u", - ret, io.out_size, in_size, out_size); - - uint32_t diff = usb_len - out_size * 2; - if (new_wpos >= diff) { - new_wpos -= diff; - } else { - new_wpos = new_wpos + usb_send_size - diff; - } - -#if (VERBOSE_TRACE & (1 << 3)) - TRACE(5, "cap_resample: new_wpos=%u, in: %u -> %u, out: %u -> %u", - new_wpos, io.in_size, in_size, io.out_size, out_size); -#endif - - dst_buf_start = usb_send_buf; - dst_cur_buf = usb_send_buf + old_wpos; - dst_buf_end = usb_send_buf + usb_send_size; - cur_buf = dst_cur_buf; - buf_end = cur_buf + out_size; - if (buf_end >= usb_send_buf + usb_send_size) { - buf_end -= usb_send_size; - } -#else -#error "Unsupported CHAN_NUM_CAPTURE and CHAN_NUM_SEND configuration" -#endif - } else -#endif // SW_CAPTURE_RESAMPLE - { - dst_buf_start = usb_send_buf; - dst_cur_buf = usb_send_buf + old_wpos; - dst_buf_end = usb_send_buf + usb_send_size; - } - -#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) - - // Assuming codec adc records stereo data, and usb sends 48K/44.1K stereo - // data -#if (CHAN_NUM_CAPTURE != 2) || (CHAN_NUM_SEND != 2) -#error "Unsupported CHAN_NUM_CAPTURE and CHAN_NUM_SEND configuration" -#endif - - { -#define MERGE_VER 2 -#if (MERGE_VER == 2) -#define THRES_MIC3 32500 -#else -#define THRES_MIC3 27168 -#endif -#define SHIFT_BITS 4 - - uint32_t i = 0; - short *BufSrc = (short *)cur_buf; - short *BufDst = (short *)dst_cur_buf; - short *BufDstStart = (short *)dst_buf_start; - short *BufDstEnd = (short *)dst_buf_end; - - int32_t PcmValue = 0; - int32_t BufSrcRVal = 0; - - uint32_t step; - - // TRACE(3,"%s - %d, %d", __func__, BufSrc[0], BufSrc[1]); - // TRACE(2,"%s - %d", __func__, TICKS_TO_MS(cur_time)); - - if (sample_rate_cap == 384000 || sample_rate_cap == 352800) { - step = 2; - } else if (sample_rate_cap == 192000 || sample_rate_cap == 176400) { - step = 1; - } else { - ASSERT(false, - "1: Invalid sample_rate_cap=%u sample_rate_ref_cap=%u " - "sample_rate_send=%u", - sample_rate_cap, sample_rate_ref_cap, sample_rate_send); - } - - get_amic_dc(BufSrc, len >> 2, step); - - for (i = 0; i < (len >> 2); i += step) { - if (step == 2) { - if (!(i & 0x1)) { - PcmValue = ((int32_t)(BufSrc[i << 1])); - BufSrcRVal = ((int32_t)(BufSrc[(i << 1) + 1])); -#if (MERGE_VER == 2) - if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { - PcmValue = (PcmValue - s_amic3_dc) >> SHIFT_BITS; - } else { - PcmValue = BufSrcRVal - s_amic4_dc; - } -#else // (MERGE_VER == 1) - PcmValue -= s_amic3_dc; - if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { - PcmValue >>= SHIFT_BITS; - } else { - PcmValue = BufSrcRVal - s_amic4_dc; - } -#endif // MERGE_VER - PcmValue = soir_filter(PcmValue); -#ifdef DUAL_AUX_MIC_MORE_FILTER - PcmValue = soir_filter1(PcmValue); - PcmValue = soir_filter2(PcmValue); -#endif - if (!(i & 7)) { - if (BufDst + 2 > BufDstEnd) { - BufDst = BufDstStart; - } - *BufDst++ = PcmValue; - *BufDst++ = PcmValue; - } - } - } else { - if (!(i & 0x1)) { - PcmValue = ((int32_t)(BufSrc[i << 1])); - BufSrcRVal = ((int32_t)(BufSrc[(i << 1) + 1])); -#if (MERGE_VER == 2) - if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { - PcmValue = (PcmValue - s_amic3_dc) >> SHIFT_BITS; - } else { - PcmValue = BufSrcRVal - s_amic4_dc; - } -#else // (MERGE_VER == 1) - PcmValue -= s_amic3_dc; - if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { - PcmValue >>= SHIFT_BITS; - } else { - PcmValue = BufSrcRVal - s_amic4_dc; - } -#endif // MERGE_VER - PcmValue = soir_filter(PcmValue); -#ifdef DUAL_AUX_MIC_MORE_FILTER - PcmValue = soir_filter1(PcmValue); - PcmValue = soir_filter2(PcmValue); -#endif - if (!(i & 3)) { - if (BufDst + 2 > BufDstEnd) { - BufDst = BufDstStart; - } - *BufDst++ = PcmValue; - *BufDst++ = PcmValue; - } - } - } - } - } - -#elif defined(CHIP_BEST1000) && defined(ANC_APP) - - // Assuming codec adc records stereo data, and usb sends 48K/44.1K stereo - // data -#if (CHAN_NUM_CAPTURE != 2) || (CHAN_NUM_SEND != 2) -#error "Unsupported CHAN_NUM_CAPTURE and CHAN_NUM_SEND configuration" -#endif - - if ((sample_rate_ref_cap == 48000 || sample_rate_ref_cap == 44100) && - (sample_rate_cap == sample_rate_ref_cap * 2 || - sample_rate_cap == sample_rate_ref_cap * 4 || - sample_rate_cap == sample_rate_ref_cap * 8 || - sample_rate_cap == sample_rate_ref_cap * 16)) { - - uint32_t POSSIBLY_UNUSED factor = sample_rate_cap / sample_rate_ref_cap; - int32_t POSSIBLY_UNUSED left = 0; - int32_t POSSIBLY_UNUSED right = 0; - uint32_t step = factor * 4; - - while (cur_buf + step <= buf_end) { - if (dst_cur_buf + 4 > dst_buf_end) { - dst_cur_buf = dst_buf_start; - } - - // Downsampling the adc data -#if 1 - left = 0; - right = 0; - for (int i = 0; i < factor; i++) { - left += *(int16_t *)(cur_buf + 4 * i); - right += *(int16_t *)(cur_buf + 4 * i + 2); - } - *(int16_t *)dst_cur_buf = left / factor; - *(int16_t *)(dst_cur_buf + 2) = right / factor; -#else - *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; - *(int16_t *)(dst_cur_buf + 2) = *(int16_t *)(cur_buf + 2); -#endif - - // Move to next data - dst_cur_buf += 4; - cur_buf += step; - } - - } else { - ASSERT(false, - "2: Invalid sample_rate_cap=%u sample_rate_ref_cap=%u " - "sample_rate_send=%u", - sample_rate_cap, sample_rate_ref_cap, sample_rate_send); - } - -#else // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) - -#ifndef SW_CAPTURE_RESAMPLE - ASSERT(sample_rate_cap == sample_rate_send, - "3: Invalid sample_rate_cap=%u sample_rate_send=%u", sample_rate_cap, - sample_rate_send); -#endif - -// When USB_AUDIO_SPEECH is enable, buf after algorithm shoule be CHAN_NUM_SEND, -// do not need to convert any more. -#if (CHAN_NUM_CAPTURE == 2) && (CHAN_NUM_SEND == 1) && \ - !defined(USB_AUDIO_SPEECH) - - // Assuming codec adc always records stereo data - - while (cur_buf + 4 <= buf_end) { - // Copy left channel data - if (dst_cur_buf + 2 > dst_buf_end) { - dst_cur_buf = dst_buf_start; - } - *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; - - // Move to next data - dst_cur_buf += 2; - cur_buf += 4; - } - -#elif (CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2) && \ - !defined(USB_AUDIO_SPEECH) - - // Assuming codec adc always records mono data - -#ifdef SW_CAPTURE_RESAMPLE -#if (CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2) - if (resample_cap_enabled) { - // ASSERT(cur_buf == dst_cur_buf, "Bad assumption"); - uint32_t src_len; - - if (buf_end < cur_buf) { - src_len = buf_end + usb_send_size - cur_buf; - } else { - src_len = buf_end - cur_buf; - } - cur_buf = buf_end - 2; - if (cur_buf < dst_buf_start) { - cur_buf += usb_send_size; - } - dst_cur_buf += src_len * 2 - 4; - if (dst_cur_buf >= dst_buf_end) { - dst_cur_buf -= usb_send_size; - } - while (src_len > 0) { - *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; - *(int16_t *)(dst_cur_buf + 2) = *(int16_t *)cur_buf; - - // Move to next data - src_len -= 2; - cur_buf -= 2; - if (cur_buf < dst_buf_start) { - cur_buf += usb_send_size; - } - dst_cur_buf -= 4; - if (dst_cur_buf < dst_buf_start) { - dst_cur_buf += usb_send_size; - } - } - } else -#endif -#endif - { - while (cur_buf + 2 <= buf_end) { - // Duplicate the mono data - if (dst_cur_buf + 4 > dst_buf_end) { - dst_cur_buf = dst_buf_start; - } - *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; - *(int16_t *)(dst_cur_buf + 2) = *(int16_t *)cur_buf; - - // Move to next data - dst_cur_buf += 4; - cur_buf += 2; - } - } - -#else // (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) - - // The channel numbers of codec adc and USB data are the same - - if (sample_size_cap == sample_size_send) { -#if ((CHAN_NUM_CAPTURE & 1) == 0) -#define COPY_MEM(dst, src, size) copy_mem32(dst, src, size) -#else -#define COPY_MEM(dst, src, size) copy_mem16(dst, src, size) -#endif - if (dst_cur_buf != cur_buf) { - if (dst_cur_buf + len <= dst_buf_end) { - COPY_MEM(dst_cur_buf, cur_buf, len); - } else { - uint32_t copy_len; - - if (dst_cur_buf >= dst_buf_end) { - copy_len = 0; - } else { - copy_len = dst_buf_end - dst_cur_buf; - COPY_MEM(dst_cur_buf, cur_buf, copy_len); - } - COPY_MEM(dst_buf_start, cur_buf + copy_len, len - copy_len); - } - } -#undef COPY_MEM - } else if (sample_size_cap == 4 && sample_size_send == 3) { - uint32_t codec_step, usb_step; - uint32_t ch; - - codec_step = CHAN_NUM_CAPTURE * 4; - usb_step = CHAN_NUM_SEND * 3; - - while (cur_buf + codec_step <= buf_end) { - if (dst_cur_buf + usb_step > dst_buf_end) { - dst_cur_buf = dst_buf_start; - } - for (ch = 0; ch < CHAN_NUM_CAPTURE; ch++) { - *(uint16_t *)dst_cur_buf = *(uint16_t *)cur_buf; - *(uint8_t *)(dst_cur_buf + 2) = *(uint8_t *)(cur_buf + 2); - // Move to next channel - dst_cur_buf += 3; - cur_buf += 4; - } - } - } else { - ASSERT(false, "4: Invalid sample_size_cap=%u sample_size_send=%u", - sample_size_cap, sample_size_send); - } - -#endif // (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) - -#endif // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) - -#ifdef SW_CAPTURE_RESAMPLE -#if !((CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2)) - if (resample_cap_enabled) { - io.in = resample_input_buf; - io.in_size = resample_frame_len; - io.out = usb_send_buf + old_wpos; - io.out_size = usb_len; - io.out_cyclic_start = usb_send_buf; - io.out_cyclic_end = usb_send_buf + usb_send_size; - - ret = audio_resample_ex_run(resample_id, &io, &in_size, &out_size); - ASSERT((ret == RESAMPLE_STATUS_IN_EMPTY || ret == RESAMPLE_STATUS_DONE) && - io.out_size >= out_size, - "Failed to resample: %d io.out_size=%u io.in_size=%u in_size=%u " - "out_size=%u", - ret, io.out_size, io.in_size, in_size, out_size); - - uint32_t diff = usb_len - out_size; - if (new_wpos >= diff) { - new_wpos -= diff; - } else { - new_wpos = new_wpos + usb_send_size - diff; - } - -#if (VERBOSE_TRACE & (1 << 3)) - TRACE(5, "cap_resample: new_wpos=%u, in: %u -> %u, out: %u -> %u", - new_wpos, io.in_size, in_size, io.out_size, out_size); -#endif - } -#endif -#endif - } - - //---------------------------------------- - // CODEC->USB stream format conversion end - //---------------------------------------- -_conv_end: - - cap_next = buf + len - capture_buf; - if (cap_next >= capture_size) { - cap_next -= capture_size; - } - - lock = int_lock(); - if (codec_cap_seq == usb_send_seq) { - if (capture_state == AUDIO_ITF_STATE_STARTED) { - usb_send_wpos = new_wpos; - } else { - usb_send_wpos = 0; - } - capture_pos = cap_next; - if (conflicted) { - capture_conflicted = conflicted; - } - } - int_unlock(lock); - -#if (VERBOSE_TRACE & (1 << 4)) - TRACE_TIME(0, "captureEnd"); -#endif - - return 0; -} - -static void update_playback_sync_info(void) { - playback_info.err_thresh = DIFF_ERR_THRESH_PLAYBACK; - playback_info.samp_rate = sample_rate_play; - playback_info.samp_cnt = byte_to_samp_recv(usb_recv_size); -#ifdef TARGET_TO_MAX_DIFF - playback_info.max_target_thresh = playback_info.samp_cnt / 2; - playback_info.diff_target = - byte_to_samp_recv(playback_to_recv_len(playback_size / 2)) + - playback_info.samp_cnt / 2; - playback_info.diff_target = usb_audio_sync_normalize_diff( - -playback_info.diff_target, playback_info.samp_cnt); -#endif - - TRACE(4, "%s: rate=%u cnt=%u (%u)", __FUNCTION__, playback_info.samp_rate, - playback_info.samp_cnt, usb_recv_size); -} - -static void update_capture_sync_info(void) { - capture_info.err_thresh = DIFF_ERR_THRESH_CAPTURE; - capture_info.samp_rate = sample_rate_cap; - capture_info.samp_cnt = byte_to_samp_send(usb_send_size); -#ifdef TARGET_TO_MAX_DIFF - capture_info.max_target_thresh = capture_info.samp_cnt / 2; - capture_info.diff_target = - byte_to_samp_send(capture_to_send_len(capture_size / 2)) + - capture_info.samp_cnt / 2; - capture_info.diff_target = usb_audio_sync_normalize_diff( - capture_info.diff_target, capture_info.samp_cnt); -#endif - - TRACE(4, "%s: rate=%u cnt=%u (%u)", __FUNCTION__, capture_info.samp_rate, - capture_info.samp_cnt, usb_send_size); -} - -static int usb_audio_open_codec_stream(enum AUD_STREAM_T stream, - enum AUDIO_STREAM_REQ_USER_T user) { - int ret = 0; - struct AF_STREAM_CONFIG_T stream_cfg; - - TRACE(4, "%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, - codec_stream_map[stream][AUDIO_STREAM_OPENED]); - - if (user >= AUDIO_STREAM_REQ_USER_QTY || - codec_stream_map[stream][AUDIO_STREAM_OPENED] == 0) { - memset(&stream_cfg, 0, sizeof(stream_cfg)); - - if (stream == AUD_STREAM_PLAYBACK) { -#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) - playback_size = calc_playback_size(sample_rate_play); -#endif - - update_playback_sync_info(); - -#ifdef CODEC_DSD - if (codec_dsd_enabled) { - stream_cfg.bits = AUD_BITS_24; - } else -#endif - { - stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); - } - stream_cfg.sample_rate = sample_rate_play; - stream_cfg.channel_num = chan_num_to_enum(CHAN_NUM_PLAYBACK); -#ifdef USB_I2S_APP -#if defined(USB_I2S_ID) && (USB_I2S_ID == 0) - stream_cfg.device = AUD_STREAM_USE_I2S0_MASTER; -#else - stream_cfg.device = AUD_STREAM_USE_I2S1_MASTER; -#endif -#else - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; -#endif - stream_cfg.vol = playback_vol; - stream_cfg.handler = usb_audio_data_playback; - stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; - stream_cfg.data_ptr = playback_buf; - stream_cfg.data_size = playback_size; - - // TRACE(3,"[%s] sample_rate: %d, bits = %d", __func__, - // stream_cfg.sample_rate, stream_cfg.bits); - - ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); - ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); - -#ifdef AUDIO_ANC_FB_MC - stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); - stream_cfg.sample_rate = sample_rate_play; - stream_cfg.channel_num = chan_num_to_enum(CHAN_NUM_PLAYBACK); - stream_cfg.device = AUD_STREAM_USE_MC; - stream_cfg.vol = playback_vol; - stream_cfg.handler = audio_mc_data_playback; - stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; - stream_cfg.data_ptr = playback_buf + playback_size; - - mid_p_8_old_l = 0; - mid_p_8_old_r = 0; - - if (sample_rate_play == AUD_SAMPRATE_8000) { - playback_samplerate_ratio = 8 * 6; - } else if (sample_rate_play == AUD_SAMPRATE_16000) { - playback_samplerate_ratio = 8 * 3; - } else if ((sample_rate_play == AUD_SAMPRATE_44100) || - (sample_rate_play == AUD_SAMPRATE_48000) || - (sample_rate_play == AUD_SAMPRATE_50781)) { - playback_samplerate_ratio = 8; - } else if ((sample_rate_play == AUD_SAMPRATE_88200) || - (sample_rate_play == AUD_SAMPRATE_96000)) { - playback_samplerate_ratio = 4; - } else if ((sample_rate_play == AUD_SAMPRATE_176400) || - (sample_rate_play == AUD_SAMPRATE_192000)) { - playback_samplerate_ratio = 2; - } else if (sample_rate_play == AUD_SAMPRATE_384000) { - playback_samplerate_ratio = 1; - } else { - playback_samplerate_ratio = 1; - ASSERT(false, "Music cancel can't support playback sample rate:%d", - sample_rate_play); - } - - anc_mc_run_init((sample_rate_play * playback_samplerate_ratio) / 8); - - stream_cfg.data_size = playback_size * playback_samplerate_ratio; - - // TRACE(3,"[%s] sample_rate: %d, bits = %d", __func__, - // stream_cfg.sample_rate, stream_cfg.bits); - - ret = af_stream_open(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); - ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); -#endif - } else { -#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) - capture_size = calc_capture_size(sample_rate_cap); -#endif - - update_capture_sync_info(); - - stream_cfg.bits = sample_size_to_enum_capture(sample_size_cap); - stream_cfg.sample_rate = sample_rate_cap; - stream_cfg.channel_num = chan_num_to_enum(CHAN_NUM_CAPTURE); -#ifdef ANC_PROD_TEST - stream_cfg.channel_map = anc_fb_mic_ch_l | anc_fb_mic_ch_r; -#endif -#ifdef USB_I2S_APP -#if defined(USB_I2S_ID) && (USB_I2S_ID == 0) - stream_cfg.device = AUD_STREAM_USE_I2S0_MASTER; -#else - stream_cfg.device = AUD_STREAM_USE_I2S1_MASTER; -#endif -#else - stream_cfg.device = AUD_STREAM_USE_INT_CODEC; -#endif - stream_cfg.vol = capture_vol; - stream_cfg.handler = usb_audio_data_capture; -#if !defined(USB_AUDIO_SPEECH) && defined(BTUSB_AUDIO_MODE) - stream_cfg.io_path = AUD_INPUT_PATH_USBAUDIO; -#else - stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; -#endif - stream_cfg.data_ptr = capture_buf; - stream_cfg.data_size = capture_size; - - // TRACE(4,"[%s] sample_rate: %d, bits = %d, ch_num = %d", __func__, - // stream_cfg.sample_rate, stream_cfg.bits, stream_cfg.channel_num); - - ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); - ASSERT(ret == 0, "af_stream_open catpure failed: %d", ret); - } - } - - if (user < AUDIO_STREAM_REQ_USER_QTY) { - codec_stream_map[stream][AUDIO_STREAM_OPENED] |= (1 << user); - } - - return ret; -} - -static int usb_audio_close_codec_stream(enum AUD_STREAM_T stream, - enum AUDIO_STREAM_REQ_USER_T user) { - int ret = 0; - - TRACE(4, "%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, - codec_stream_map[stream][AUDIO_STREAM_OPENED]); - - if (user < AUDIO_STREAM_REQ_USER_QTY) { - codec_stream_map[stream][AUDIO_STREAM_OPENED] &= ~(1 << user); - } - - if (user >= AUDIO_STREAM_REQ_USER_QTY || - codec_stream_map[stream][AUDIO_STREAM_OPENED] == 0) { - ret = af_stream_close(AUD_STREAM_ID_0, stream); - -#ifdef AUDIO_ANC_FB_MC - if (stream == AUD_STREAM_PLAYBACK) { - ret = af_stream_close(AUD_STREAM_ID_2, stream); - } -#endif - } - - return ret; -} - -static int usb_audio_open_eq(void) { - int ret = 0; - - TRACE(4, "[%s] EQ: sample_rate_recv=%d, sample_rate_play=%d, sample_bits=%d", - __func__, sample_rate_recv, sample_rate_play, - sample_size_to_enum_playback(sample_size_play)); - -#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || \ - defined(__HW_IIR_EQ_PROCESS__) || defined(__HW_DAC_IIR_EQ_PROCESS__) - enum AUD_BITS_T sample_bits = sample_size_to_enum_playback(sample_size_play); - enum AUD_CHANNEL_NUM_T chan_num = chan_num_to_enum(CHAN_NUM_PLAYBACK); - ret = audio_process_open(sample_rate_play, sample_bits, chan_num, - playback_eq_size / 2, playback_eq_buf, - playback_eq_size); - - // TRACE(1,"audio_process_open: %d", ret); - -#ifdef __SW_IIR_EQ_PROCESS__ - usb_audio_set_eq(AUDIO_EQ_TYPE_SW_IIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_SW_IIR, 0)); -#endif - -#ifdef __HW_FIR_EQ_PROCESS__ - usb_audio_set_eq(AUDIO_EQ_TYPE_HW_FIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR, 0)); -#endif - -#ifdef __HW_DAC_IIR_EQ_PROCESS__ - usb_audio_set_eq(AUDIO_EQ_TYPE_HW_DAC_IIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_DAC_IIR, 0)); -#endif - -#ifdef __HW_IIR_EQ_PROCESS__ - usb_audio_set_eq(AUDIO_EQ_TYPE_HW_IIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_IIR, 0)); -#endif - -#endif - - eq_opened = 1; - - return ret; -} - -static int usb_audio_close_eq(void) { - int ret = 0; - -#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || \ - defined(__HW_IIR_EQ_PROCESS__) || defined(__HW_DAC_IIR_EQ_PROCESS__) - ret = audio_process_close(); -#endif - - eq_opened = 0; - - return ret; -} - -static int usb_audio_start_codec_stream(enum AUD_STREAM_T stream, - enum AUDIO_STREAM_REQ_USER_T user) { - int ret = 0; - - TRACE(4, "%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, - codec_stream_map[stream][AUDIO_STREAM_STARTED]); - - if (user >= AUDIO_STREAM_REQ_USER_QTY || - codec_stream_map[stream][AUDIO_STREAM_STARTED] == 0) { - reset_conflict(); - - if (stream == AUD_STREAM_PLAYBACK) { - zero_mem32(playback_buf, playback_size); - codec_play_valid = 0; - usb_recv_init_rpos = 0; - playback_pos = 0; - playback_conflicted = 0; -#ifdef USB_AUDIO_MULTIFUNC - usb_recv2_init_rpos = 0; - playback_conflicted2 = 0; -#endif -#ifdef DSD_SUPPORT - if (codec_dsd_enabled) { -#if defined(__HW_FIR_DSD_PROCESS__) - uint8_t *dsd_buf; - uint32_t dsd_size; - - // DoP format requirement - dsd_size = playback_size * 16; - ; - dsd_buf = (uint8_t *)(HW_FIR_DSD_BUF_MID_ADDR - dsd_size / 2); - dsd_open(sample_rate_play, AUD_BITS_24, AUD_CHANNEL_NUM_2, dsd_buf, - dsd_size); -#elif defined(CODEC_DSD) - af_dsd_enable(); -#endif - } -#endif - usb_audio_open_eq(); - } else { -#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) - damic_init(); - init_amic_dc(); -#endif - -#ifdef USB_AUDIO_SPEECH - app_overlay_select(APP_OVERLAY_HFP); - - speech_process_init(sample_rate_cap, CHAN_NUM_CAPTURE, - sample_size_to_enum_playback(sample_size_cap), - sample_rate_play, CHAN_NUM_PLAYBACK, - sample_size_to_enum_playback(sample_size_play), 16, - 16, CHAN_NUM_SEND, CHAN_NUM_RECV); -#endif - - codec_cap_valid = 0; - usb_send_init_wpos = 0; - capture_pos = 0; - capture_conflicted = 0; - } - - // Tune rate according to the newest sync ratio info - usb_audio_cmd_tune_rate(stream); - - ret = af_stream_start(AUD_STREAM_ID_0, stream); - ASSERT(ret == 0, "af_stream_start %d failed: %d", stream, ret); - - if (stream == AUD_STREAM_PLAYBACK) { -#ifdef AUDIO_ANC_FB_MC - ret = af_stream_start(AUD_STREAM_ID_2, stream); - ASSERT(ret == 0, "af_stream_start %d failed: %d", stream, ret); -#endif - } else { - codec_cap_start_time = hal_sys_timer_get(); - } - } - - if (user < AUDIO_STREAM_REQ_USER_QTY) { - codec_stream_map[stream][AUDIO_STREAM_STARTED] |= (1 << user); - } - - return ret; -} - -static int usb_audio_stop_codec_stream(enum AUD_STREAM_T stream, - enum AUDIO_STREAM_REQ_USER_T user) { - int ret = 0; - - TRACE(4, "%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, - codec_stream_map[stream][AUDIO_STREAM_STARTED]); - - if (user < AUDIO_STREAM_REQ_USER_QTY) { - codec_stream_map[stream][AUDIO_STREAM_STARTED] &= ~(1 << user); - } - - if (user >= AUDIO_STREAM_REQ_USER_QTY || - codec_stream_map[stream][AUDIO_STREAM_STARTED] == 0) { - ret = af_stream_stop(AUD_STREAM_ID_0, stream); - - if (stream == AUD_STREAM_PLAYBACK) { -#ifdef AUDIO_ANC_FB_MC - ret = af_stream_stop(AUD_STREAM_ID_2, stream); -#endif -#ifdef DSD_SUPPORT - if (codec_dsd_enabled) { -#if defined(__HW_FIR_DSD_PROCESS__) - dsd_close(); -#elif defined(CODEC_DSD) - af_dsd_disable(); -#endif - } -#endif - usb_audio_close_eq(); - } else { -#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) - damic_deinit(); -#endif - -#ifdef USB_AUDIO_SPEECH - speech_process_deinit(); - app_overlay_unloadall(); -#endif - } - } - - return ret; -} - -static int usb_audio_start_usb_stream(enum AUD_STREAM_T stream) { - int ret; - - reset_conflict(); - - if (stream == AUD_STREAM_PLAYBACK) { - usb_audio_sync_reset(&playback_info); - - usb_recv_valid = 0; -#ifdef USB_AUDIO_MULTIFUNC - if (recv2_state == AUDIO_ITF_STATE_STOPPED) -#endif - { - usb_recv_seq++; - } - - usb_recv_rpos = 0; - usb_recv_wpos = usb_recv_size / 2; - zero_mem32(usb_recv_buf, usb_recv_size); - - usb_recv_err_cnt = 0; - -#ifdef DSD_SUPPORT - usb_dsd_enabled = false; - usb_dsd_cont_cnt = 0; -#endif - - ret = usb_audio_start_recv(usb_recv_buf, usb_recv_wpos, usb_recv_size); - if (ret == 1) { - TRACE(0, "usb_audio_start_recv failed: usb not configured"); - } else { - ASSERT(ret == 0, "usb_audio_start_recv failed: %d", ret); - } - } else { -#ifndef UAUD_SYNC_STREAM_TARGET - if (recv_state == AUDIO_ITF_STATE_STOPPED) -#endif - { - usb_audio_sync_reset(&capture_info); - } - - usb_send_valid = 0; - usb_send_seq++; - - usb_send_rpos = usb_send_size / 2; - usb_send_wpos = 0; - zero_mem32(usb_send_buf, usb_send_size); - - usb_send_err_cnt = 0; - - ret = usb_audio_start_send(usb_send_buf, usb_send_rpos, usb_send_size); - if (ret == 1) { - TRACE(0, "usb_audio_start_send failed: usb not configured"); - } else { - ASSERT(ret == 0, "usb_audio_start_send failed: %d", ret); - } - } - - return ret; -} - -static int usb_audio_stop_usb_stream(enum AUD_STREAM_T stream) { - if (stream == AUD_STREAM_PLAYBACK) { - usb_audio_stop_recv(); - -#ifdef DSD_SUPPORT - usb_dsd_enabled = false; -#endif - - usb_audio_sync_reset(&playback_info); - } else { - usb_audio_stop_send(); - -#ifndef UAUD_SYNC_STREAM_TARGET - if (recv_state == AUDIO_ITF_STATE_STOPPED) -#endif - { - usb_audio_sync_reset(&capture_info); - } - } - - return 0; -} - -static void usb_audio_set_codec_volume(enum AUD_STREAM_T stream, uint8_t vol) { - struct AF_STREAM_CONFIG_T *cfg; - uint8_t POSSIBLY_UNUSED old_vol; - uint32_t ret; - - ret = af_stream_get_cfg(AUD_STREAM_ID_0, stream, &cfg, true); - if (ret == 0) { - old_vol = cfg->vol; - if (old_vol != vol) { - cfg->vol = vol; - af_stream_setup(AUD_STREAM_ID_0, stream, cfg); - } - } - -#ifdef AUDIO_ANC_FB_MC - if (stream == AUD_STREAM_PLAYBACK) { - ret = af_stream_get_cfg(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &cfg, true); - if (ret == 0) { - if (cfg->vol != vol) { - cfg->vol = vol; - af_stream_setup(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, cfg); - } - } - } -#endif -} - -static void usb_audio_enqueue_cmd(uint32_t data) { - int ret; - uint32_t mark; - - ret = safe_queue_put(&cmd_queue, data); - ASSERT(ret == 0 || safe_queue_dump(&cmd_queue), "%s: cmd queue overflow", - __FUNCTION__); - - hal_cpu_wake_lock(USB_AUDIO_CPU_WAKE_USER); - - mark = safe_queue_watermark(&cmd_queue); - if (mark > cmd_watermark) { - cmd_watermark = mark; - TRACE(2, "%s: new watermark %u", __FUNCTION__, mark); - } - -#ifdef BT_USB_AUDIO_DUAL_MODE - if (enqueue_cmd_cb) { - enqueue_cmd_cb(data); - } -#endif -} - -#ifdef BT_USB_AUDIO_DUAL_MODE -void usb_audio_set_enqueue_cmd_callback(USB_AUDIO_ENQUEUE_CMD_CALLBACK cb) { - enqueue_cmd_cb = cb; -} -#endif - -static void enqueue_unique_cmd_with_opp(enum AUDIO_CMD_T cmd, uint8_t seq, - uint8_t arg, - enum AUDIO_CMD_T oppsite_cmd) { - uint32_t last[3]; - uint32_t lock; - bool dup = false; - - lock = int_lock(); - if (safe_queue_peek(&cmd_queue, -1, &last[0]) == 0 && - safe_queue_peek(&cmd_queue, -2, &last[1]) == 0 && - safe_queue_peek(&cmd_queue, -3, &last[2]) == 0) { - if (EXTRACT_CMD(last[0]) == cmd) { - dup = true; - safe_queue_pop(&cmd_queue, NULL); - } else if (EXTRACT_CMD(last[0]) == oppsite_cmd && - EXTRACT_CMD(last[1]) == cmd && - EXTRACT_CMD(last[2]) == oppsite_cmd) { - dup = true; - safe_queue_pop(&cmd_queue, NULL); - safe_queue_pop(&cmd_queue, NULL); - } - } - int_unlock(lock); - - usb_audio_enqueue_cmd(MAKE_QUEUE_DATA(cmd, seq, arg)); - - if (dup) { - TRACE(2, "%s: Remove old duplicate cmd %d", __FUNCTION__, cmd); - } -} - -static void enqueue_unique_cmd_arg(enum AUDIO_CMD_T cmd, uint8_t seq, - uint8_t arg) { - uint32_t last; - uint32_t cur; - uint32_t lock; - bool enqueue = true; - - cur = MAKE_QUEUE_DATA(cmd, seq, arg); - - lock = int_lock(); - if (safe_queue_peek(&cmd_queue, -1, &last) == 0) { - if (last == cur) { - enqueue = false; - } - } - int_unlock(lock); - - if (enqueue) { - usb_audio_enqueue_cmd(cur); - } else { - TRACE(2, "%s: Skip duplicate cmd %d", __FUNCTION__, cmd); - } -} - -static void enqueue_unique_cmd(enum AUDIO_CMD_T cmd) { - enqueue_unique_cmd_arg(cmd, 0, 0); -} - -static void usb_audio_playback_start(enum USB_AUDIO_ITF_CMD_T cmd) { - if (cmd == USB_AUDIO_ITF_STOP) { - // Stop the stream right now - if (recv_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); - recv_state = AUDIO_ITF_STATE_STOPPED; - } - -#ifdef USB_AUDIO_DYN_CFG - playback_itf_set = 0; -#ifdef USB_AUDIO_UAC2 - enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, - AUDIO_CMD_START_PLAY); -#else - enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, - AUDIO_CMD_SET_RECV_RATE); -#endif -#else - -#ifdef USB_AUDIO_MULTIFUNC - if (recv2_state == AUDIO_ITF_STATE_STARTED) { - return; - } -#endif - - enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, - AUDIO_CMD_START_PLAY); -#endif - } else { -#ifdef USB_AUDIO_DYN_CFG - if (cmd == USB_AUDIO_ITF_START_16BIT) { - new_sample_size_recv = 2; - } else if (cmd == USB_AUDIO_ITF_START_24BIT) { - new_sample_size_recv = 3; - } else { - new_sample_size_recv = 4; - } - playback_itf_set = 1; - - // Some host applications will not stop current stream before changing - // sample size - if (recv_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); - recv_state = AUDIO_ITF_STATE_STOPPED; - } - -#ifdef USB_AUDIO_UAC2 -#ifdef KEEP_SAME_LATENCY - usb_recv_size = - calc_usb_recv_size(new_sample_rate_recv, new_sample_size_recv); - TRACE(2, "%s: Set usb_recv_size=%u", __FUNCTION__, usb_recv_size); -#endif - - usb_audio_start_usb_stream(AUD_STREAM_PLAYBACK); - recv_state = AUDIO_ITF_STATE_STARTED; - - enqueue_unique_cmd_with_opp(AUDIO_CMD_START_PLAY, usb_recv_seq, 0, - AUDIO_CMD_STOP_PLAY); -#else - // Wait for sampling freq ctrl msg to start the stream -#endif - return; -#else - if (recv_state == AUDIO_ITF_STATE_STOPPED) { - usb_audio_start_usb_stream(AUD_STREAM_PLAYBACK); - recv_state = AUDIO_ITF_STATE_STARTED; - } - -#ifdef USB_AUDIO_MULTIFUNC - if (recv2_state == AUDIO_ITF_STATE_STARTED) { - return; - } -#endif - - enqueue_unique_cmd_with_opp(AUDIO_CMD_START_PLAY, usb_recv_seq, 0, - AUDIO_CMD_STOP_PLAY); -#endif - } -} - -static void usb_audio_capture_start(enum USB_AUDIO_ITF_CMD_T cmd) { - if (cmd == USB_AUDIO_ITF_STOP) { - // Stop the stream right now - if (send_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); - send_state = AUDIO_ITF_STATE_STOPPED; - } - -#ifdef USB_AUDIO_DYN_CFG - capture_itf_set = 0; -#ifdef USB_AUDIO_UAC2 - enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_CAPTURE, usb_send_seq, 0, - AUDIO_CMD_START_CAPTURE); -#else - enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_CAPTURE, usb_send_seq, 0, - AUDIO_CMD_SET_SEND_RATE); -#endif -#else - enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_CAPTURE, usb_send_seq, 0, - AUDIO_CMD_START_CAPTURE); -#endif - } else { -#ifdef USB_AUDIO_DYN_CFG - capture_itf_set = 1; - - // Some host applications will not stop current stream before changing - // sample size - if (send_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); - send_state = AUDIO_ITF_STATE_STOPPED; - } - -#ifdef USB_AUDIO_UAC2 - usb_audio_start_usb_stream(AUD_STREAM_CAPTURE); - send_state = AUDIO_ITF_STATE_STARTED; - - enqueue_unique_cmd_with_opp(AUDIO_CMD_START_CAPTURE, usb_send_seq, 0, - AUDIO_CMD_STOP_CAPTURE); -#else - // Wait for sampling freq ctrl msg to start the stream -#endif - return; -#else - if (send_state == AUDIO_ITF_STATE_STOPPED) { - usb_audio_start_usb_stream(AUD_STREAM_CAPTURE); - send_state = AUDIO_ITF_STATE_STARTED; - } - - enqueue_unique_cmd_with_opp(AUDIO_CMD_START_CAPTURE, usb_send_seq, 0, - AUDIO_CMD_STOP_CAPTURE); -#endif - } -} - -static void usb_audio_mute_control(uint32_t mute) { - TRACE(1, "MUTE CTRL: %u", mute); - - new_mute_state = mute; -#ifdef USB_AUDIO_MULTIFUNC - if (mute) { - new_playback_coef = 0; - } else { - new_playback_coef = playback_gain_to_float(new_playback_vol); - } -#endif - usb_audio_enqueue_cmd(AUDIO_CMD_MUTE_CTRL); -} - -static void usb_audio_cap_mute_control(uint32_t mute) { - TRACE(1, "CAP MUTE CTRL: %u", mute); - - new_cap_mute_state = mute; - usb_audio_enqueue_cmd(AUDIO_CMD_CAP_MUTE_CTRL); -} - -static void usb_audio_vol_control(uint32_t percent) { - if (percent >= 100) { - new_playback_vol = MAX_VOLUME_VAL; - } else { - new_playback_vol = MIN_VOLUME_VAL + - (percent * (MAX_VOLUME_VAL - MIN_VOLUME_VAL) + 50) / 100; - } - - TRACE(2, "VOL CTRL: percent=%u new_playback_vol=%u", percent, - new_playback_vol); - -#ifdef USB_AUDIO_MULTIFUNC - new_playback_coef = playback_gain_to_float(new_playback_vol); -#else - usb_audio_enqueue_cmd(AUDIO_CMD_SET_VOLUME); -#endif -} - -static void usb_audio_cap_vol_control(uint32_t percent) { - if (percent >= 100) { - new_capture_vol = MAX_CAP_VOLUME_VAL; - } else { - new_capture_vol = - MIN_CAP_VOLUME_VAL + - (percent * (MAX_CAP_VOLUME_VAL - MIN_CAP_VOLUME_VAL) + 50) / 100; - } - - TRACE(2, "CAP VOL CTRL: percent=%u new_capture_vol=%u", percent, - new_capture_vol); - - usb_audio_enqueue_cmd(AUDIO_CMD_SET_CAP_VOLUME); -} - -static uint32_t usb_audio_get_vol_percent(void) { - if (new_playback_vol >= MAX_VOLUME_VAL) { - return 100; - } else if (new_playback_vol <= MIN_VOLUME_VAL) { - return 0; - } else { - return ((new_playback_vol - MIN_VOLUME_VAL) * 100 + - (MAX_VOLUME_VAL - MIN_VOLUME_VAL) / 2) / - (MAX_VOLUME_VAL - MIN_VOLUME_VAL); - } -} - -static uint32_t usb_audio_get_cap_vol_percent(void) { - if (new_capture_vol >= MAX_CAP_VOLUME_VAL) { - return 100; - } else if (new_capture_vol <= MIN_CAP_VOLUME_VAL) { - return 0; - } else { - return ((new_capture_vol - MIN_CAP_VOLUME_VAL) * 100 + - (MAX_CAP_VOLUME_VAL - MIN_CAP_VOLUME_VAL) / 2) / - (MAX_CAP_VOLUME_VAL - MIN_CAP_VOLUME_VAL); - } -} - -static void usb_audio_tune_rate(enum AUD_STREAM_T stream, float ratio) { - bool update_play, update_cap; - - update_play = true; - update_cap = false; - -#if defined(__AUDIO_RESAMPLE__) && defined(PLL_TUNE_SAMPLE_RATE) -#ifdef UAUD_SYNC_STREAM_TARGET - if (stream == AUD_STREAM_PLAYBACK) { - update_play = true; - update_cap = false; - } else { - update_play = false; - update_cap = true; - } -#else - update_play = true; - update_cap = true; -#endif -#endif - - if (update_play) { - rate_tune_ratio[AUD_STREAM_PLAYBACK] = - rate_tune_ratio[AUD_STREAM_PLAYBACK] + ratio + - rate_tune_ratio[AUD_STREAM_PLAYBACK] * ratio; - } - if (update_cap) { - rate_tune_ratio[AUD_STREAM_CAPTURE] = - rate_tune_ratio[AUD_STREAM_CAPTURE] + ratio + - rate_tune_ratio[AUD_STREAM_CAPTURE] * ratio; - } - - TRACE(4, "%s[%u]: ratio=%d resample_ratio=%d", __FUNCTION__, stream, - FLOAT_TO_PPB_INT(ratio), - update_cap ? FLOAT_TO_PPB_INT(rate_tune_ratio[stream]) - : FLOAT_TO_PPB_INT(rate_tune_ratio[AUD_STREAM_PLAYBACK])); - - enqueue_unique_cmd_arg(AUDIO_CMD_TUNE_RATE, 0, stream); -} - -static void -usb_audio_data_recv_handler(const struct USB_AUDIO_XFER_INFO_T *info) { - const uint8_t *data; - uint32_t size; - uint32_t old_wpos, new_wpos, wpos_boundary, rpos; - uint32_t old_play_pos = 0; - uint32_t play_pos; - uint32_t lock; - int conflicted; - uint32_t recv_samp, play_samp; - uint32_t cur_time; - - cur_time = hal_sys_timer_get(); - last_usb_recv_time = cur_time; - - data = info->data; - size = info->size; - - if (info->cur_compl_err || info->next_xfer_err) { - if (usb_recv_err_cnt == 0) { - usb_recv_err_cnt++; - usb_recv_ok_cnt = 0; - last_usb_recv_err_time = cur_time; - } else { - usb_recv_err_cnt++; - } - } else { - if (usb_recv_err_cnt) { - usb_recv_ok_cnt++; - } - } - if (usb_recv_err_cnt && - cur_time - last_usb_recv_err_time >= USB_XFER_ERR_REPORT_INTERVAL) { - if (info->cur_compl_err || info->next_xfer_err) { - TRACE(2, "recv: ERROR: cur_err=%d next_err=%d", info->cur_compl_err, - info->next_xfer_err); - } - TRACE(3, "recv: ERROR-CNT: err=%u ok=%u in %u ms", usb_recv_err_cnt, - usb_recv_ok_cnt, TICKS_TO_MS(USB_XFER_ERR_REPORT_INTERVAL)); - usb_recv_err_cnt = 0; - } - - if (usb_recv_buf <= data && data <= usb_recv_buf + usb_recv_size) { - if (data != usb_recv_buf + usb_recv_wpos) { - TRACE( - 3, - "recv: WARNING: Invalid wpos=0x%x data=%p recv_buf=%p. IRQ missing?", - usb_recv_wpos, data, usb_recv_buf); - usb_recv_wpos = data - usb_recv_buf; - } - } - - old_wpos = usb_recv_wpos; - new_wpos = old_wpos + size; - if (new_wpos >= usb_recv_size) { - new_wpos -= usb_recv_size; - } - - if (recv_state == AUDIO_ITF_STATE_STOPPED || size == 0 || // rx paused - 0) { - usb_recv_valid = 0; - } else { - if (info->cur_compl_err == 0) { - usb_recv_valid = 1; - } - } - - if (usb_recv_valid == 0 || usb_recv_init_rpos == 0 || codec_config_lock || - codec_play_seq != usb_recv_seq || codec_play_valid == 0 || - playback_state == AUDIO_ITF_STATE_STOPPED || 0) { - usb_recv_wpos = new_wpos; - return; - } - - conflicted = 0; - - lock = int_lock(); - if (playback_conflicted) { - playback_conflicted = 0; - rpos = 0; // Avoid compiler warnings - conflicted = 1; - } else { - rpos = usb_recv_rpos; - old_play_pos = playback_pos; - play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - } - int_unlock(lock); - - if (conflicted == 0) { - if (info->pool_enabled) { - // USBC will write to memory pool. - wpos_boundary = new_wpos; - } else { - // USBC will write to new_wpos directly, so the buffer [new_wpos, new_wpos - // + info->next_size) must be protected too. - wpos_boundary = new_wpos + info->next_size; - if (wpos_boundary >= usb_recv_size) { - wpos_boundary -= usb_recv_size; - } - } - - if (old_wpos <= rpos) { - if (wpos_boundary < old_wpos || rpos < wpos_boundary) { - conflicted = 1; - } - } else { - if (rpos < wpos_boundary && wpos_boundary < old_wpos) { - conflicted = 1; - } - } - - if (conflicted) { - uint32_t reset_len = usb_recv_size / 2; - uint32_t saved_old_wpos = old_wpos; - - // Reset write position - old_wpos = rpos + reset_len; - if (old_wpos >= usb_recv_size) { - old_wpos -= usb_recv_size; - } - new_wpos = old_wpos + size; - if (new_wpos >= usb_recv_size) { - new_wpos -= usb_recv_size; - } - -#if 0 - usb_audio_stop_recv(); - usb_audio_start_recv(usb_recv_buf, new_wpos, usb_recv_size); -#else - usb_audio_set_recv_pos(new_wpos); -#endif - - TRACE(4, - "recv: Error: wpos=%u goes beyond rpos=%u with len=%u. Reset to %u", - saved_old_wpos, rpos, size, old_wpos); - } - record_conflict(conflicted); - } - - usb_recv_wpos = new_wpos; - -#if (VERBOSE_TRACE & (1 << 5)) - { - int hw_play_pos = - af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - TRACE_TIME(5, - "recv: wpos=%u size=%u rpos=%u playback_pos=%u hw_play_pos=%d", - old_wpos, size, rpos, playback_pos, hw_play_pos); - } -#endif - - if (conflicted) { - usb_audio_sync_reset(&playback_info); - return; - } - - if (usb_recv_buf <= data && data <= usb_recv_buf + usb_recv_size) { - recv_samp = byte_to_samp_recv(new_wpos); - } else { - recv_samp = -1; - } - - if ((int)play_pos >= 0) { - if (play_pos >= playback_size) { - play_pos = 0; - } - // Count the bytes of data waiting to play in the codec buffer - uint32_t bytes_to_play; - if (old_play_pos <= play_pos) { - bytes_to_play = playback_size + old_play_pos - play_pos; - } else { - bytes_to_play = old_play_pos - play_pos; - } - uint32_t usb_bytes_to_play; - usb_bytes_to_play = playback_to_recv_len(bytes_to_play); - if (rpos >= usb_bytes_to_play) { - play_pos = rpos - usb_bytes_to_play; - } else { - play_pos = usb_recv_size + rpos - usb_bytes_to_play; - } - play_samp = byte_to_samp_recv(play_pos); - } else { - play_samp = -1; - } - - if (recv_samp != -1 && play_samp != -1) { - enum UAUD_SYNC_RET_T ret; - float ratio; - - ret = usb_audio_sync(play_samp, recv_samp, &playback_info, &ratio); - if (ret == UAUD_SYNC_START) { - usb_audio_tune_rate(AUD_STREAM_PLAYBACK, ratio); - } - } else { - // TRACE(2,"recv_hdlr: recv_samp=0x%08x play_samp=0x%08x", recv_samp, - // play_samp); - } - -#ifdef DSD_SUPPORT - if (sample_size_recv == 3 && - (sample_rate_recv == 176400 || sample_rate_recv == 352800)) { - // First DoP solution marks - static const uint8_t pattern[2] = { - 0x05, - 0xFA, - }; - // Second DoP solution marks -- not supported yet - // static const uint8_t pattern2[2] = { 0x06, 0xF9, }; - static const uint16_t dsd_detect_thresh = 32; - uint8_t idx; - const uint8_t *dsd, *dsd_end, *dsd_end2; - bool dsd_valid = true; - - dsd = data + 2; - dsd_end = data + size; - dsd_end2 = usb_recv_buf + usb_recv_size; - if (dsd_end <= dsd_end2) { - dsd_end2 = NULL; - } else { - dsd_end = dsd_end2; - dsd_end2 = data + size - usb_recv_size; - } - if (*dsd == pattern[0]) { - idx = 0; - } else { - idx = 1; - } - - _check_dsd: - while (dsd < dsd_end) { - if (*dsd == pattern[idx]) { -#if (CHAN_NUM_RECV == 2) - dsd += 3; - if (dsd >= dsd_end || *dsd != pattern[idx]) { - dsd_valid = false; - break; - } -#endif - if (usb_dsd_cont_cnt < dsd_detect_thresh) { - usb_dsd_cont_cnt += CHAN_NUM_RECV; - } - idx = !idx; - dsd += 3; - } else { - dsd_valid = false; - break; - } - } - if (dsd_valid && dsd_end2) { - dsd = usb_recv_buf + 2; - dsd_end = dsd_end2; - dsd_end2 = NULL; - goto _check_dsd; - } - - if (dsd_valid && usb_dsd_cont_cnt < dsd_detect_thresh) { - dsd_valid = false; - } - if (!dsd_valid) { - usb_dsd_cont_cnt = 0; - } - - if (dsd_valid != usb_dsd_enabled) { - usb_dsd_enabled = dsd_valid; - enqueue_unique_cmd(AUDIO_CMD_SET_DSD_CFG); - } - } -#endif -} - -static void -usb_audio_data_send_handler(const struct USB_AUDIO_XFER_INFO_T *info) { - const uint8_t *data; - uint32_t size; - uint32_t old_rpos, new_rpos, rpos_boundary, wpos; - uint32_t old_cap_pos = 0; - uint32_t cap_pos; - uint32_t lock; - int conflicted; - uint32_t send_samp, cap_samp; - uint32_t cur_time; - - cur_time = hal_sys_timer_get(); - last_usb_send_time = cur_time; - - data = info->data; - size = info->size; - - if (info->cur_compl_err || info->next_xfer_err) { - if (usb_send_err_cnt == 0) { - usb_send_err_cnt++; - usb_send_ok_cnt = 0; - last_usb_send_err_time = cur_time; - } else { - usb_send_err_cnt++; - } - } else { - if (usb_send_err_cnt) { - usb_send_ok_cnt++; - } - } - if (usb_send_err_cnt && - cur_time - last_usb_send_err_time >= USB_XFER_ERR_REPORT_INTERVAL) { - if (info->cur_compl_err || info->next_xfer_err) { - TRACE(2, "send: ERROR: cur_err=%d next_err=%d", info->cur_compl_err, - info->next_xfer_err); - } - TRACE(3, "send: ERROR-CNT: err=%u ok=%u in %u ms", usb_send_err_cnt, - usb_send_ok_cnt, TICKS_TO_MS(USB_XFER_ERR_REPORT_INTERVAL)); - usb_send_err_cnt = 0; - } - - if (info->pool_enabled) { - // The buffer [data, size) has been sent completely, and - // the buffer [data + size, data + size + info->next_size) has been copied - // to memory pool. Make usb_send_rpos point to the pending send buffer - data += size; - if (data >= usb_send_buf + usb_send_size) { - data -= usb_send_size; - } - size = info->next_size; - } - - if (usb_send_buf <= data && data <= usb_send_buf + usb_send_size) { - if (data != usb_send_buf + usb_send_rpos) { - if (usb_send_valid == 0 && info->pool_enabled && - info->data != usb_send_buf + usb_send_rpos) { - TRACE(3, - "send: WARNING: Invalid rpos=0x%x data=%p send_buf=%p. IRQ " - "missing?", - usb_send_rpos, data, usb_send_buf); - } - usb_send_rpos = data - usb_send_buf; - } - } - - old_rpos = usb_send_rpos; - new_rpos = old_rpos + size; - if (new_rpos >= usb_send_size) { - new_rpos -= usb_send_size; - } - - if (send_state == AUDIO_ITF_STATE_STOPPED || size == 0 || // tx paused - 0) { - usb_send_valid = 0; - } else { - if (info->cur_compl_err == 0) { - usb_send_valid = 1; - } - } - - if (usb_send_valid == 0 || usb_send_init_wpos == 0 || codec_config_lock || - codec_cap_seq != usb_send_seq || codec_cap_valid == 0 || - capture_state == AUDIO_ITF_STATE_STOPPED || 0) { - usb_send_rpos = new_rpos; - if (usb_send_valid) { - // Zero the send buffer next to the part being sent by USB h/w - if (info->pool_enabled) { - uint32_t clr_len; - - clr_len = samp_to_byte_send(SAMP_RATE_TO_FRAME_SIZE(sample_rate_send)); - if (usb_send_rpos + clr_len <= usb_send_size) { - zero_mem16(usb_send_buf + usb_send_rpos, clr_len); - } else { - zero_mem16(usb_send_buf + usb_send_rpos, - usb_send_size - usb_send_rpos); - zero_mem16(usb_send_buf, clr_len - (usb_send_size - usb_send_rpos)); - } - } else { - // If no pool is enabled, the send pkt size is a fixed value, and - // the send buffer size is a integral multiple of the send pkt size - if (usb_send_rpos + size + size <= usb_send_size) { - zero_mem32(usb_send_buf + usb_send_rpos + size, size); - } else { - zero_mem32(usb_send_buf, size); - } - } - } - return; - } - - conflicted = 0; - - lock = int_lock(); - if (capture_conflicted) { - capture_conflicted = 0; - wpos = 0; // Avoid compiler warnings - conflicted = 1; - } else { - wpos = usb_send_wpos; - old_cap_pos = capture_pos; - cap_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); - } - int_unlock(lock); - - if (conflicted == 0) { - if (info->pool_enabled) { - // old_rpos points to the pending send buffer, which has been copied to - // memory pool. USBC will read from memory pool. - rpos_boundary = new_rpos; - } else { - // old_rpos points to the buffer just sent completely. - // USBC will read from new_rpos directly, so the buffer [new_rpos, - // new_rpos + info->next_size) must be protected too. - rpos_boundary = new_rpos + info->next_size; - if (rpos_boundary >= usb_recv_size) { - rpos_boundary -= usb_recv_size; - } - } - - if (old_rpos <= wpos) { - if (new_rpos < old_rpos || wpos < new_rpos) { - conflicted = 1; - } - } else { - if (wpos < new_rpos && new_rpos < old_rpos) { - conflicted = 1; - } - } - - if (conflicted) { - uint32_t reset_len = usb_send_size / 2; - uint32_t saved_old_rpos = old_rpos; - - // Reset read position - old_rpos = wpos + reset_len; - if (old_rpos >= usb_send_size) { - old_rpos -= usb_send_size; - } - new_rpos = old_rpos + size; - if (new_rpos >= usb_send_size) { - new_rpos -= usb_send_size; - } - -#if 0 - usb_audio_stop_send(); - usb_audio_start_send(usb_send_buf, new_rpos, usb_send_size); -#else - usb_audio_set_send_pos(new_rpos); -#endif - - TRACE(4, - "send: Error: rpos=%u goes beyond wpos=%u with len=%u. Reset to %u", - saved_old_rpos, wpos, size, old_rpos); - } - record_conflict(conflicted); - } - - usb_send_rpos = new_rpos; - -#if (VERBOSE_TRACE & (1 << 6)) - TRACE_TIME(3, "send: rpos=%u size=%u wpos=%u", old_rpos, size, wpos); -#endif - - if (conflicted) { - usb_audio_sync_reset(&capture_info); - return; - } - -#ifndef UAUD_SYNC_STREAM_TARGET - // Recv takes precedence - if (recv_state == AUDIO_ITF_STATE_STARTED) { - return; - } -#endif - - if (usb_send_buf <= data && data <= usb_send_buf + usb_send_size) { - send_samp = byte_to_samp_send(new_rpos); - } else { - send_samp = -1; - } - - if ((int)cap_pos >= 0) { - if (cap_pos >= capture_size) { - cap_pos = 0; - } - // Count the bytes of data newly captured in the codec buffer - uint32_t bytes_cap; - if (old_cap_pos <= cap_pos) { - bytes_cap = cap_pos - old_cap_pos; - } else { - bytes_cap = capture_size + cap_pos - old_cap_pos; - } - uint32_t usb_bytes_cap; - usb_bytes_cap = capture_to_send_len(bytes_cap); - cap_pos = wpos + usb_bytes_cap; - if (cap_pos >= usb_send_size) { - cap_pos -= usb_send_size; - } - cap_samp = byte_to_samp_send(cap_pos); - } else { - cap_samp = -1; - } - - if (send_samp != -1 && cap_samp != -1) { - enum UAUD_SYNC_RET_T ret; - float ratio; - - ret = usb_audio_sync(cap_samp, send_samp, &capture_info, &ratio); - if (ret == UAUD_SYNC_START) { - usb_audio_tune_rate(AUD_STREAM_CAPTURE, ratio); - } - } else { - // TRACE(2,"send_hdlr: send_samp=0x%08x cap_samp=0x%08x", send_samp, - // cap_samp); - } -} - -#ifdef USB_AUDIO_MULTIFUNC -static float playback_gain_to_float(uint32_t level) { - int32_t db; - - if (level > MAX_VOLUME_VAL || level < MIN_VOLUME_VAL) { - return 0; - } - - db = codec_dac_vol[level].sdac_volume; - if (db <= USB_AUDIO_MIN_DBVAL) { - return 0; - } - - return db_to_float(db); -} - -static void usb_audio_playback2_start(enum USB_AUDIO_ITF_CMD_T cmd) { - if (cmd == USB_AUDIO_ITF_STOP) { - // Stop the stream right now - if (recv2_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_recv2(); - if (recv_state == AUDIO_ITF_STATE_STOPPED && - send_state == AUDIO_ITF_STATE_STOPPED) { - usb_audio_sync_reset(&playback_info); - } - recv2_state = AUDIO_ITF_STATE_STOPPED; - } - - if (recv_state == AUDIO_ITF_STATE_STARTED) { - return; - } - - enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, - AUDIO_CMD_START_PLAY); - } else { - if (recv2_state == AUDIO_ITF_STATE_STOPPED) { - int ret; - - reset_conflict(); - - if (recv_state == AUDIO_ITF_STATE_STOPPED && - send_state == AUDIO_ITF_STATE_STOPPED) { - usb_audio_sync_reset(&playback_info); - } - - usb_recv2_valid = 0; - if (recv_state == AUDIO_ITF_STATE_STOPPED) { - usb_recv_seq++; - } - - usb_recv2_rpos = 0; - usb_recv2_wpos = usb_recv_size / 2; - zero_mem32(usb_recv2_buf, usb_recv2_size); - - usb_recv2_err_cnt = 0; - - ret = - usb_audio_start_recv2(usb_recv2_buf, usb_recv2_wpos, usb_recv2_size); - if (ret == 1) { - TRACE(0, "usb_audio_start_recv2 failed: usb not configured"); - } else { - ASSERT(ret == 0, "usb_audio_start_recv2 failed: %d", ret); - } - recv2_state = AUDIO_ITF_STATE_STARTED; - } - - if (recv_state == AUDIO_ITF_STATE_STARTED) { - return; - } - - enqueue_unique_cmd_with_opp(AUDIO_CMD_START_PLAY, usb_recv_seq, 0, - AUDIO_CMD_STOP_PLAY); - } -} - -static void usb_audio_mute2_control(uint32_t mute) { - TRACE(1, "MUTE2 CTRL: %u", mute); - - new_mute2_state = mute; - if (mute) { - new_playback2_coef = 0; - } else { - new_playback2_coef = playback_gain_to_float(new_playback2_vol); - } - usb_audio_enqueue_cmd(AUDIO_CMD_MUTE_CTRL); -} - -static void usb_audio_vol2_control(uint32_t percent) { - if (percent >= 100) { - new_playback2_vol = MAX_VOLUME_VAL; - } else { - new_playback2_vol = - MIN_VOLUME_VAL + - (percent * (MAX_VOLUME_VAL - MIN_VOLUME_VAL) + 50) / 100; - } - - new_playback2_coef = playback_gain_to_float(new_playback2_vol); - - TRACE(2, "VOL2 CTRL: percent=%u new_playback_vol=%u", percent, - new_playback2_vol); -} - -static uint32_t usb_audio_get_vol2_percent(void) { - if (new_playback2_vol >= MAX_VOLUME_VAL) { - return 100; - } else { - return ((new_playback2_vol - MIN_VOLUME_VAL) * 100 + - (MAX_VOLUME_VAL - MIN_VOLUME_VAL) / 2) / - (MAX_VOLUME_VAL - MIN_VOLUME_VAL); - } -} - -static void -usb_audio_data_recv2_handler(const struct USB_AUDIO_XFER_INFO_T *info) { - const uint8_t *data; - uint32_t size; - uint32_t old_wpos, new_wpos, wpos_boundary, rpos; - uint32_t old_play_pos = 0; - uint32_t play_pos; - uint32_t lock; - int conflicted; - uint32_t recv_samp, play_samp; - uint32_t cur_time; - - cur_time = hal_sys_timer_get(); - last_usb_recv_time = cur_time; - - data = info->data; - size = info->size; - - if (info->cur_compl_err || info->next_xfer_err) { - if (usb_recv2_err_cnt == 0) { - usb_recv2_err_cnt++; - usb_recv2_ok_cnt = 0; - last_usb_recv2_err_time = cur_time; - } else { - usb_recv2_err_cnt++; - } - } else { - if (usb_recv2_err_cnt) { - usb_recv2_ok_cnt++; - } - } - if (usb_recv2_err_cnt && - cur_time - last_usb_recv2_err_time >= USB_XFER_ERR_REPORT_INTERVAL) { - if (info->cur_compl_err || info->next_xfer_err) { - TRACE(2, "recv2: ERROR: cur_err=%d next_err=%d", info->cur_compl_err, - info->next_xfer_err); - } - TRACE(3, "recv2: ERROR-CNT: err=%u ok=%u in %u ms", usb_recv2_err_cnt, - usb_recv2_ok_cnt, TICKS_TO_MS(USB_XFER_ERR_REPORT_INTERVAL)); - usb_recv2_err_cnt = 0; - } - - if (usb_recv2_buf <= data && data <= usb_recv2_buf + usb_recv2_size) { - if (data != usb_recv2_buf + usb_recv2_wpos) { - TRACE(3, - "recv2: WARNING: Invalid wpos=0x%x data=%p recv2_buf=%p. IRQ " - "missing?", - usb_recv2_wpos, data, usb_recv2_buf); - usb_recv2_wpos = data - usb_recv2_buf; - } - } - - old_wpos = usb_recv2_wpos; - new_wpos = old_wpos + size; - if (new_wpos >= usb_recv2_size) { - new_wpos -= usb_recv2_size; - } - - if (codec_config_lock || codec_play_seq != usb_recv_seq || - codec_play_valid == 0 || playback_state == AUDIO_ITF_STATE_STOPPED || - recv2_state == AUDIO_ITF_STATE_STOPPED || size == 0 || // rx paused - 0) { - usb_recv2_valid = 0; - } else { - if (info->cur_compl_err == 0) { - usb_recv2_valid = 1; - } - } - - if (usb_recv2_valid == 0 || usb_recv2_init_rpos == 0) { - usb_recv2_wpos = new_wpos; - return; - } - - conflicted = 0; - - lock = int_lock(); - if (playback_conflicted2) { - playback_conflicted2 = 0; - rpos = 0; // Avoid compiler warnings - conflicted = 1; - } else { - rpos = usb_recv2_rpos; - old_play_pos = playback_pos; - play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - } - int_unlock(lock); - - if (conflicted == 0) { - if (info->pool_enabled) { - // USBC will write to memory pool. - wpos_boundary = new_wpos; - } else { - // USBC will write to new_wpos directly, so the buffer [new_wpos, new_wpos - // + info->next_size) must be protected too. - wpos_boundary = new_wpos + info->next_size; - if (wpos_boundary >= usb_recv2_size) { - wpos_boundary -= usb_recv2_size; - } - } - - if (old_wpos <= rpos) { - if (wpos_boundary < old_wpos || rpos < wpos_boundary) { - conflicted = 1; - } - } else { - if (rpos < wpos_boundary && wpos_boundary < old_wpos) { - conflicted = 1; - } - } - - if (conflicted) { - uint32_t reset_len = usb_recv2_size / 2; - uint32_t saved_old_wpos = old_wpos; - - // Reset read position - old_wpos = rpos + reset_len; - if (old_wpos >= usb_recv2_size) { - old_wpos -= usb_recv2_size; - } - new_wpos = old_wpos + size; - if (new_wpos >= usb_recv2_size) { - new_wpos -= usb_recv2_size; - } - -#if 0 - usb_audio_stop_recv(); - usb_audio_start_recv(usb_recv2_buf, new_wpos, usb_recv2_size); -#else - usb_audio_set_recv2_pos(new_wpos); -#endif - - TRACE( - 4, - "recv2: Error: wpos=%u goes beyond rpos=%u with len=%u. Reset to %u", - saved_old_wpos, rpos, size, old_wpos); - } - record_conflict(conflicted); - } - - usb_recv2_wpos = new_wpos; - -#if (VERBOSE_TRACE & (1 << 5)) - { - int hw_play_pos = - af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); - TRACE_TIME(5, - "recv2: wpos=%u size=%u rpos=%u playback_pos=%u hw_play_pos=%d", - old_wpos, size, rpos, playback_pos, hw_play_pos); - } -#endif - - if (conflicted) { - usb_audio_sync_reset(&playback_info); - return; - } - - // Recv and send takes precedence - if (recv_state == AUDIO_ITF_STATE_STARTED || - send_state == AUDIO_ITF_STATE_STARTED) { - return; - } - - if (usb_recv2_buf <= data && data <= usb_recv2_buf + usb_recv2_size) { - recv_samp = byte_to_samp_recv(new_wpos); - } else { - recv_samp = -1; - } - - if ((int)play_pos >= 0) { - if (play_pos >= playback_size) { - play_pos = 0; - } - // Count the bytes of data waiting to play in the codec buffer - uint32_t bytes_to_play; - if (old_play_pos <= play_pos) { - bytes_to_play = playback_size + old_play_pos - play_pos; - } else { - bytes_to_play = old_play_pos - play_pos; - } - uint32_t usb_bytes_to_play; - usb_bytes_to_play = playback_to_recv_len(bytes_to_play); - if (rpos >= usb_bytes_to_play) { - play_pos = rpos - usb_bytes_to_play; - } else { - play_pos = usb_recv2_size + rpos - usb_bytes_to_play; - } - play_samp = byte_to_samp_recv(play_pos); - } else { - play_samp = -1; - } - - if (recv_samp != -1 && play_samp != -1) { - enum UAUD_SYNC_RET_T ret; - float ratio; - - ret = usb_audio_sync(play_samp, recv_samp, &playback_info, &ratio); - if (ret == UAUD_SYNC_START) { - usb_audio_tune_rate(AUD_STREAM_PLAYBACK, ratio); - } - } else { - // TRACE(2,"recv_hdlr: recv_samp=0x%08x play_samp=0x%08x", recv_samp, - // play_samp); - } -} -#endif - -static void usb_audio_reset_usb_stream_state(bool init) { - if (init) { - recv_state = AUDIO_ITF_STATE_STOPPED; - send_state = AUDIO_ITF_STATE_STOPPED; - -#ifdef USB_AUDIO_DYN_CFG - // Reset itf setting - playback_itf_set = 0; - capture_itf_set = 0; -#endif - - // Reset mute and volume setting - new_mute_state = 0; - new_cap_mute_state = 0; - - new_playback_vol = AUDIO_OUTPUT_VOLUME_DEFAULT; - if (new_playback_vol > MAX_VOLUME_VAL) { - new_playback_vol = MAX_VOLUME_VAL; - } else if (new_playback_vol < MIN_VOLUME_VAL) { - new_playback_vol = MIN_VOLUME_VAL; - } - - new_capture_vol = CODEC_SADC_VOL; - if (new_capture_vol > MAX_CAP_VOLUME_VAL) { - new_capture_vol = MAX_CAP_VOLUME_VAL; - } else if (new_capture_vol < MIN_CAP_VOLUME_VAL) { - new_capture_vol = MIN_CAP_VOLUME_VAL; - } - -#ifdef USB_AUDIO_MULTIFUNC - new_playback_coef = playback_gain_to_float(new_playback_vol); - playback_coef = new_playback_coef; - - recv2_state = AUDIO_ITF_STATE_STOPPED; - new_mute2_state = 0; - new_playback2_vol = AUDIO_OUTPUT_VOLUME_DEFAULT; - if (new_playback2_vol > MAX_VOLUME_VAL) { - new_playback2_vol = MAX_VOLUME_VAL; - } else if (new_playback2_vol < MIN_VOLUME_VAL) { - new_playback2_vol = MIN_VOLUME_VAL; - } - new_playback2_coef = playback_gain_to_float(new_playback2_vol); - playback2_coef = new_playback2_coef; -#endif - } else { - if (recv_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); - recv_state = AUDIO_ITF_STATE_STOPPED; - } - if (send_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); - send_state = AUDIO_ITF_STATE_STOPPED; - } - -#ifdef USB_AUDIO_MULTIFUNC - if (recv2_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_recv2(); - if (recv_state == AUDIO_ITF_STATE_STOPPED && - send_state == AUDIO_ITF_STATE_STOPPED) { - usb_audio_sync_reset(&playback_info); - } - recv2_state = AUDIO_ITF_STATE_STOPPED; - } -#endif - - // Keep old itf setting unless it is in init mode - - // Keep old mute and playback volume setting unless it is in init mode - } -} - -static void usb_audio_reset_codec_stream_state(bool init) { - playback_state = AUDIO_ITF_STATE_STOPPED; - capture_state = AUDIO_ITF_STATE_STOPPED; - -#ifndef USB_AUDIO_MULTIFUNC - playback_vol = new_playback_vol; -#endif - capture_vol = new_capture_vol; - - playback_paused = 0; - - playback_conflicted = 0; -#ifdef USB_AUDIO_MULTIFUNC - playback_conflicted2 = 0; -#endif - capture_conflicted = 0; - - // Keep old mute setting unless it is in init mode - if (init) { -#ifdef PERF_TEST_POWER_KEY - perft_power_type = 0; - af_codec_set_perf_test_power(perft_power_type); -#endif -#ifdef PA_ON_OFF_KEY - if (pa_on_off_muted) { - pa_on_off_muted = false; - if (mute_user_map == 0) { - usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); - } - } -#endif - if (mute_user_map) { - mute_user_map = 0; - usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); - } -#if defined(NOISE_GATING) && defined(NOISE_REDUCTION) - restore_noise_reduction_status(); -#endif - } -} - -#ifdef USB_AUDIO_DYN_CFG -static void usb_audio_set_recv_rate(enum AUD_SAMPRATE_T rate) { -#ifndef USB_AUDIO_UAC2 - if (playback_itf_set == 0) { - TRACE(1, "\nWARNING: Set recv rate while itf not set: %d\n", rate); - return; - } -#endif - - // Some host applications will not stop current stream before changing sample - // rate - if (recv_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); - recv_state = AUDIO_ITF_STATE_STOPPED; - } - - TRACE(3, "%s: Change recv sample rate from %u to %u", __FUNCTION__, - sample_rate_recv, rate); - - new_sample_rate_recv = rate; - -#ifdef KEEP_SAME_LATENCY - usb_recv_size = - calc_usb_recv_size(new_sample_rate_recv, new_sample_size_recv); - TRACE(2, "%s: Set usb_recv_size=%u", __FUNCTION__, usb_recv_size); -#endif - - if (playback_itf_set) { - usb_audio_start_usb_stream(AUD_STREAM_PLAYBACK); - recv_state = AUDIO_ITF_STATE_STARTED; - } - -#ifdef USB_AUDIO_UAC2 - enqueue_unique_cmd_arg(AUDIO_CMD_SET_RECV_RATE, usb_recv_seq, 0); -#else - enqueue_unique_cmd_with_opp(AUDIO_CMD_SET_RECV_RATE, usb_recv_seq, 0, - AUDIO_CMD_STOP_PLAY); -#endif -} - -static void usb_audio_set_send_rate(enum AUD_SAMPRATE_T rate) { -#ifndef USB_AUDIO_UAC2 - if (capture_itf_set == 0) { - TRACE(1, "\nWARNING: Set send rate while itf not set: %d\n", rate); - return; - } -#endif - - // Some host applications will not stop current stream before changing sample - // rate - if (send_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); - send_state = AUDIO_ITF_STATE_STOPPED; - } - - TRACE(3, "%s: Change send sample rate from %u to %u", __FUNCTION__, - sample_rate_send, rate); - - new_sample_rate_send = rate; - -#ifdef KEEP_SAME_LATENCY - usb_send_size = calc_usb_send_size(new_sample_rate_send); - TRACE(2, "%s: Set usb_send_size=%u", __FUNCTION__, usb_send_size); -#endif - - if (capture_itf_set) { - usb_audio_start_usb_stream(AUD_STREAM_CAPTURE); - send_state = AUDIO_ITF_STATE_STARTED; - } - -#ifdef USB_AUDIO_UAC2 - enqueue_unique_cmd_arg(AUDIO_CMD_SET_SEND_RATE, usb_send_seq, 0); -#else - enqueue_unique_cmd_with_opp(AUDIO_CMD_SET_SEND_RATE, usb_send_seq, 0, - AUDIO_CMD_STOP_CAPTURE); -#endif -} -#endif - -static void usb_audio_state_control(enum USB_AUDIO_STATE_EVENT_T event, - uint32_t param) { - TRACE(3, "%s: %d (%u)", __FUNCTION__, event, param); - - if (event == USB_AUDIO_STATE_RESET || event == USB_AUDIO_STATE_DISCONNECT || - event == USB_AUDIO_STATE_CONFIG) { - usb_audio_reset_usb_stream_state(true); - } else if (event == USB_AUDIO_STATE_SLEEP || - event == USB_AUDIO_STATE_WAKEUP) { - usb_audio_reset_usb_stream_state(false); - } - - if (event == USB_AUDIO_STATE_RESET) { - usb_audio_enqueue_cmd(AUDIO_CMD_USB_RESET); - } else if (event == USB_AUDIO_STATE_DISCONNECT) { - usb_audio_enqueue_cmd(AUDIO_CMD_USB_DISCONNECT); - } else if (event == USB_AUDIO_STATE_CONFIG) { - usb_audio_enqueue_cmd(AUDIO_CMD_USB_CONFIG); - } else if (event == USB_AUDIO_STATE_SLEEP) { - usb_audio_enqueue_cmd(AUDIO_CMD_USB_SLEEP); - } else if (event == USB_AUDIO_STATE_WAKEUP) { - usb_audio_enqueue_cmd(AUDIO_CMD_USB_WAKEUP); - } else if (event == USB_AUDIO_STATE_RECV_PAUSE || - event == USB_AUDIO_STATE_RECV2_PAUSE) { -#ifndef USB_AUDIO_MULTIFUNC - enqueue_unique_cmd_with_opp(AUDIO_CMD_RECV_PAUSE, usb_recv_seq, 0, - AUDIO_CMD_RECV_CONTINUE); -#endif - } else if (event == USB_AUDIO_STATE_RECV_CONTINUE || - event == USB_AUDIO_STATE_RECV2_CONTINUE) { -#ifndef USB_AUDIO_MULTIFUNC - enqueue_unique_cmd_with_opp(AUDIO_CMD_RECV_CONTINUE, usb_recv_seq, 0, - AUDIO_CMD_RECV_PAUSE); -#endif -#ifdef USB_AUDIO_DYN_CFG - } else if (event == USB_AUDIO_STATE_SET_RECV_RATE) { - usb_audio_set_recv_rate(param); - } else if (event == USB_AUDIO_STATE_SET_SEND_RATE) { - usb_audio_set_send_rate(param); -#endif - } else { - ASSERT(false, "Bad state event"); - } -} - -static void usb_audio_acquire_freq(void) { - enum HAL_CMU_FREQ_T freq; - -#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) -#ifdef SW_CAPTURE_RESAMPLE - if (resample_cap_enabled) { - freq = HAL_CMU_FREQ_104M; - } else -#endif - if (capture_state == AUDIO_ITF_STATE_STARTED) { -#ifdef DUAL_AUX_MIC_MORE_FILTER - freq = HAL_CMU_FREQ_104M; -#else - freq = HAL_CMU_FREQ_78M; -#endif - } else -#else // !(CHIP_BEST1000 && _DUAL_AUX_MIC_) -#ifdef SW_CAPTURE_RESAMPLE - if (resample_cap_enabled) { -#ifdef CHIP_BEST1000 - freq = HAL_CMU_FREQ_78M; -#else - freq = HAL_CMU_FREQ_52M; -#endif - } else -#endif -#endif // !(CHIP_BEST1000 && _DUAL_AUX_MIC_) - { - freq = HAL_CMU_FREQ_52M; - } - -#if defined(USB_HIGH_SPEED) && defined(USB_AUDIO_UAC2) - if (playback_state == AUDIO_ITF_STATE_STARTED && - sample_rate_play >= AUD_SAMPRATE_352800) { - if (freq < HAL_CMU_FREQ_104M) { - freq = HAL_CMU_FREQ_104M; - } - } -#endif - -#ifdef AUDIO_ANC_FB_MC - if (freq < HAL_CMU_FREQ_104M) { - freq = HAL_CMU_FREQ_104M; - } -#endif - -#ifdef __HW_FIR_DSD_PROCESS__ - if (freq < HAL_CMU_FREQ_104M) { - freq = HAL_CMU_FREQ_104M; - } -#endif - -#ifdef USB_AUDIO_SPEECH - enum HAL_CMU_FREQ_T speech_freq; - - speech_freq = speech_process_need_freq(); - if (freq < speech_freq) { - freq = speech_freq; - } -#endif - - hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, freq); - // TRACE(2,"[%s] app_sysfreq_req %d", __FUNCTION__, freq); - // TRACE(2,"[%s] sys freq calc : %d\n", __FUNCTION__, - // hal_sys_timer_calc_cpu_freq(5, 0)); -} - -static void usb_audio_release_freq(void) { - hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, HAL_CMU_FREQ_32K); -} - -static void usb_audio_update_freq(void) { usb_audio_acquire_freq(); } - -#ifdef SW_CAPTURE_RESAMPLE - -static enum AUD_CHANNEL_NUM_T get_capture_resample_chan_num(void) { -#if (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) - return chan_num_to_enum(CHAN_NUM_CAPTURE); -#else - return AUD_CHANNEL_NUM_1; -#endif -} - -static void capture_stream_resample_config(void) { - struct RESAMPLE_CFG_T cfg; - enum RESAMPLE_STATUS_T ret; - enum AUD_SAMPRATE_T cap_rate; - -#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) - cap_rate = sample_rate_ref_cap; -#else - cap_rate = sample_rate_cap; -#endif - -#ifndef __AUDIO_RESAMPLE__ - if (cap_rate == sample_rate_send) { - if (resample_cap_enabled) { - TRACE(1, "!!! %s: Disable capture resample", __FUNCTION__); - - audio_resample_ex_close(resample_id); - resample_cap_enabled = false; - } - } else -#endif - { - if (!resample_cap_enabled) { - // Resample chan num is usb send chan num - memset(&cfg, 0, sizeof(cfg)); - cfg.chans = get_capture_resample_chan_num(); - cfg.bits = sample_size_to_enum_capture(sample_size_cap); -#ifdef __AUDIO_RESAMPLE__ - if (sample_rate_send % AUD_SAMPRATE_8000) { - ASSERT(hal_cmu_get_crystal_freq() / - (CODEC_FREQ_44_1K_SERIES / sample_rate_send) == - cap_rate, - "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, - cap_rate, sample_rate_send); -#if (CODEC_FREQ_26M / CODEC_FREQ_CRYSTAL * CODEC_FREQ_CRYSTAL == CODEC_FREQ_26M) - cfg.coef = &resample_coef_50p7k_to_44p1k; -#else - cfg.coef = &resample_coef_46p8k_to_44p1k; -#endif - } else { - ASSERT(hal_cmu_get_crystal_freq() / - (CODEC_FREQ_48K_SERIES / sample_rate_send) == - cap_rate, - "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, - cap_rate, sample_rate_send); -#if (CODEC_FREQ_26M / CODEC_FREQ_CRYSTAL * CODEC_FREQ_CRYSTAL == CODEC_FREQ_26M) - cfg.coef = &resample_coef_50p7k_to_48k; -#else - cfg.coef = &resample_coef_46p8k_to_48k; -#endif - } -#else - if (sample_rate_send % AUD_SAMPRATE_8000) { - ASSERT(CODEC_FREQ_48K_SERIES / - (CODEC_FREQ_44_1K_SERIES / sample_rate_send) == - cap_rate, - "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, - cap_rate, sample_rate_send); - cfg.coef = &resample_coef_48k_to_44p1k; - } else { - ASSERT(CODEC_FREQ_44_1K_SERIES / - (CODEC_FREQ_48K_SERIES / sample_rate_send) == - cap_rate, - "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, - cap_rate, sample_rate_send); - cfg.coef = &resample_coef_44p1k_to_48k; - } -#endif - cfg.buf = resample_history_buf; - cfg.size = resample_history_size; - - TRACE(3, "!!! %s: Enable capture resample %u => %u", __FUNCTION__, - cap_rate, sample_rate_send); - - ret = audio_resample_ex_open(&cfg, &resample_id); - ASSERT(ret == RESAMPLE_STATUS_OK, "%s: Failed to init resample: %d", - __FUNCTION__, ret); - - resample_cap_enabled = true; - } - } -} - -#endif - -static void usb_audio_init_streams(enum AUDIO_STREAM_REQ_USER_T user) { - bool action; - - action = false; -#ifndef DELAY_STREAM_OPEN - if (user == AUDIO_STREAM_REQ_USB) { - action = true; - } -#endif -#ifdef ANC_L_R_MISALIGN_WORKAROUND - if (user == AUDIO_STREAM_REQ_ANC) { - action = true; - } -#endif - if (action) { - usb_audio_open_codec_stream(AUD_STREAM_PLAYBACK, user); - usb_audio_open_codec_stream(AUD_STREAM_CAPTURE, user); - } - -#ifdef ANC_L_R_MISALIGN_WORKAROUND - if (user == AUDIO_STREAM_REQ_ANC) { - usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, user); - usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, user); - } -#endif -} - -static void usb_audio_term_streams(enum AUDIO_STREAM_REQ_USER_T user) { - // Ensure all the streams for this user are stopped and closed - usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, user); - usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, user); - - usb_audio_close_codec_stream(AUD_STREAM_CAPTURE, user); - usb_audio_close_codec_stream(AUD_STREAM_PLAYBACK, user); -} - -#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) -static void hid_data_send_handler(enum USB_AUDIO_HID_EVENT_T event, int error) { - TRACE(2, "HID SENT: event=0x%04x error=%d", event, error); -} -#endif - -static void usb_audio_itf_callback(enum USB_AUDIO_ITF_ID_T id, - enum USB_AUDIO_ITF_CMD_T cmd) { - if (0) { -#ifdef USB_AUDIO_MULTIFUNC - } else if (id == USB_AUDIO_ITF_ID_RECV2) { - usb_audio_playback2_start(cmd); -#endif - } else if (id == USB_AUDIO_ITF_ID_RECV) { - usb_audio_playback_start(cmd); - } else { - usb_audio_capture_start(cmd); - } -} - -static void usb_audio_mute_callback(enum USB_AUDIO_ITF_ID_T id, uint32_t mute) { - if (0) { -#ifdef USB_AUDIO_MULTIFUNC - } else if (id == USB_AUDIO_ITF_ID_RECV2) { - usb_audio_mute2_control(mute); -#endif - } else if (id == USB_AUDIO_ITF_ID_RECV) { - usb_audio_mute_control(mute); - } else { - usb_audio_cap_mute_control(mute); - } -} - -static void usb_audio_set_volume(enum USB_AUDIO_ITF_ID_T id, uint32_t percent) { - if (0) { -#ifdef USB_AUDIO_MULTIFUNC - } else if (id == USB_AUDIO_ITF_ID_RECV2) { - usb_audio_vol2_control(percent); -#endif - } else if (id == USB_AUDIO_ITF_ID_RECV) { - usb_audio_vol_control(percent); - } else { - usb_audio_cap_vol_control(percent); - } -} - -static uint32_t usb_audio_get_volume(enum USB_AUDIO_ITF_ID_T id) { - uint32_t percent = 0; - - if (0) { -#ifdef USB_AUDIO_MULTIFUNC - } else if (id == USB_AUDIO_ITF_ID_RECV2) { - percent = usb_audio_get_vol2_percent(); -#endif - } else if (id == USB_AUDIO_ITF_ID_RECV) { - percent = usb_audio_get_vol_percent(); - } else { - percent = usb_audio_get_cap_vol_percent(); - } - - return percent; -} - -static void usb_audio_xfer_callback(enum USB_AUDIO_ITF_ID_T id, - const struct USB_AUDIO_XFER_INFO_T *info) { - if (0) { -#ifdef USB_AUDIO_MULTIFUNC - } else if (id == USB_AUDIO_ITF_ID_RECV2) { - usb_audio_data_recv2_handler(info); -#endif - } else if (id == USB_AUDIO_ITF_ID_RECV) { - usb_audio_data_recv_handler(info); - } else { - usb_audio_data_send_handler(info); - } -} - -static void usb_audio_stream_running_handler(void) { - enum AUDIO_STREAM_RUNNING_T req; - uint32_t lock; - - req = streams_running_req; - - if (req == AUDIO_STREAM_RUNNING_NULL) { - return; - } else if (req == AUDIO_STREAM_RUNNING_ENABLED) { - usb_audio_init_streams(AUDIO_STREAM_REQ_ANC); - } else if (req == AUDIO_STREAM_RUNNING_DISABLED) { - usb_audio_term_streams(AUDIO_STREAM_REQ_ANC); - } - - lock = int_lock(); - if (req == streams_running_req) { - streams_running_req = AUDIO_STREAM_RUNNING_NULL; - } - int_unlock(lock); -} - -void usb_audio_keep_streams_running(bool enable) { - if (enable) { - streams_running_req = AUDIO_STREAM_RUNNING_ENABLED; - } else { - streams_running_req = AUDIO_STREAM_RUNNING_DISABLED; - } - - // TODO: Move usb_audio_stream_running_handler() into usb_audio_app_loop() ? - // How to ensure that streams are opened before ANC is enabled? - usb_audio_stream_running_handler(); -} - -#ifdef USB_AUDIO_DYN_CFG - -static enum AUD_SAMPRATE_T calc_play_sample_rate(enum AUD_SAMPRATE_T usb_rate) { - enum AUD_SAMPRATE_T codec_rate; - -#if defined(CHIP_BEST1000) && defined(ANC_APP) - - codec_rate = - (usb_rate % AUD_SAMPRATE_8000) ? AUD_SAMPRATE_88200 : AUD_SAMPRATE_96000; - -#else - - codec_rate = usb_rate; - -#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) - if (codec_rate % AUD_SAMPRATE_8000) { - codec_rate = - hal_cmu_get_crystal_freq() / (CODEC_FREQ_44_1K_SERIES / codec_rate); - } else { - codec_rate = - hal_cmu_get_crystal_freq() / (CODEC_FREQ_48K_SERIES / codec_rate); - } -#endif - -#endif - - return codec_rate; -} - -#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) -static enum AUD_SAMPRATE_T -calc_anc_cap_sample_rate_best1000(enum AUD_SAMPRATE_T usb_rate, - enum AUD_SAMPRATE_T play_rate) { - enum AUD_SAMPRATE_T rate_cap; - -#ifdef ANC_APP - -#ifdef AUD_PLL_DOUBLE -#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) - rate_cap = play_rate * 8; -#else - rate_cap = play_rate * 2; -#endif -#else // !AUD_PLL_DOUBLE -#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) - rate_cap = play_rate * 4; -#else - rate_cap = play_rate; -#endif -#endif // !AUD_PLL_DOUBLE - -#else // _DUAL_AUX_MIC_ - - // Capture reference - enum AUD_SAMPRATE_T rate_cap_ref; - - rate_cap_ref = - (usb_rate % AUD_SAMPRATE_8000) ? AUD_SAMPRATE_44100 : AUD_SAMPRATE_48000; - - rate_cap = rate_cap_ref * 4; - -#endif - - return rate_cap; -} -#endif - -static enum AUD_SAMPRATE_T calc_cap_sample_rate(enum AUD_SAMPRATE_T usb_rate, - enum AUD_SAMPRATE_T play_rate) { -#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) - - return calc_anc_cap_sample_rate_best1000(usb_rate, play_rate); - -#else // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) - - enum AUD_SAMPRATE_T codec_rate; - -#ifdef __AUDIO_RESAMPLE__ - - codec_rate = usb_rate; - -#ifdef SW_CAPTURE_RESAMPLE - if (codec_rate % AUD_SAMPRATE_8000) { - codec_rate = - hal_cmu_get_crystal_freq() / (CODEC_FREQ_44_1K_SERIES / codec_rate); - } else { - codec_rate = - hal_cmu_get_crystal_freq() / (CODEC_FREQ_48K_SERIES / codec_rate); - } -#endif - -#else // ! __AUDIO_RESAMPLE__ - - bool usb_rate_44p1k; - bool play_rate_44p1k; - - usb_rate_44p1k = !!(usb_rate % AUD_SAMPRATE_8000); - play_rate_44p1k = !!(play_rate % AUD_SAMPRATE_8000); - - if (usb_rate_44p1k ^ play_rate_44p1k) { - // Playback pll is NOT compatible with capture sample rate - if (usb_rate_44p1k) { - codec_rate = CODEC_FREQ_48K_SERIES / (CODEC_FREQ_44_1K_SERIES / usb_rate); - } else { - codec_rate = CODEC_FREQ_44_1K_SERIES / (CODEC_FREQ_48K_SERIES / usb_rate); - } - } else { - // Playback pll is compatible with capture sample rate - codec_rate = usb_rate; - } - -#endif // !__AUDIO_RESAMPLE__ - - return codec_rate; - -#endif // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) -} - -#endif // USB_AUDIO_DYN_CFG - -static void POSSIBLY_UNUSED -usb_audio_update_codec_stream(enum AUD_STREAM_T stream) { - bool update_play; - bool update_cap; -#ifdef STREAM_RATE_BITS_SETUP - struct AF_STREAM_CONFIG_T *cfg, stream_cfg; - uint32_t ret; -#endif - - update_play = false; - update_cap = false; - -#ifdef USB_AUDIO_DYN_CFG - enum AUD_SAMPRATE_T new_recv_rate; - enum AUD_SAMPRATE_T new_send_rate; - enum AUD_SAMPRATE_T play_rate; - enum AUD_SAMPRATE_T cap_rate; - uint8_t new_recv_size; - uint32_t lock; - - lock = int_lock(); - new_recv_rate = new_sample_rate_recv; - new_recv_size = new_sample_size_recv; - new_send_rate = new_sample_rate_send; - int_unlock(lock); - - play_rate = sample_rate_play; - cap_rate = sample_rate_cap; - - if (stream == AUD_STREAM_PLAYBACK) { - if (sample_rate_recv == new_recv_rate && - sample_size_recv == new_recv_size) { - // No change - goto _done_rate_size_check; - } -#ifdef AUDIO_PLAYBACK_24BIT - if (sample_rate_recv == new_recv_rate && - sample_size_recv != new_recv_size) { - // No codec change. Only a change in usb sample size - TRACE(3, "%s:1: Update recv sample size from %u to %u", __FUNCTION__, - sample_size_recv, new_recv_size); - sample_size_recv = new_recv_size; - update_playback_sync_info(); - goto _done_rate_size_check; - } -#endif - } else { - if (sample_rate_send == new_send_rate) { - // No change - goto _done_rate_size_check; - } - } - - if (stream == AUD_STREAM_PLAYBACK) { - play_rate = calc_play_sample_rate(new_recv_rate); - if (sample_rate_play == play_rate) { - if (sample_size_recv == new_recv_size) { - // No codec change. Only a change in usb sample rate - TRACE(3, "%s:1: Update recv sample rate from %u to %u", __FUNCTION__, - sample_rate_recv, new_recv_rate); - sample_rate_recv = new_recv_rate; - update_playback_sync_info(); - goto _done_rate_size_check; - } - } else { -#ifndef __AUDIO_RESAMPLE__ - bool new_rate_44p1k; - bool old_rate_44p1k; - - new_rate_44p1k = !!(play_rate % AUD_SAMPRATE_8000); - old_rate_44p1k = !!(sample_rate_play % AUD_SAMPRATE_8000); - - if (new_rate_44p1k ^ old_rate_44p1k) { - cap_rate = calc_cap_sample_rate(new_send_rate, play_rate); - update_cap = true; - } -#endif - } - update_play = true; - } else { -#ifndef __AUDIO_RESAMPLE__ - if (playback_state == AUDIO_ITF_STATE_STOPPED) { - bool usb_rate_44p1k; - bool play_rate_44p1k; - - usb_rate_44p1k = !!(new_send_rate % AUD_SAMPRATE_8000); - play_rate_44p1k = !!(play_rate % AUD_SAMPRATE_8000); - - if (usb_rate_44p1k ^ play_rate_44p1k) { - play_rate = calc_play_sample_rate(usb_rate_44p1k ? AUD_SAMPRATE_44100 - : AUD_SAMPRATE_48000); - update_play = true; - } - } -#endif - cap_rate = calc_cap_sample_rate(new_send_rate, play_rate); - if (sample_rate_cap == cap_rate) { - // No codec change. Only a change in usb sample rate - TRACE(3, "%s:1: Update send sample rate from %u to %u", __FUNCTION__, - sample_rate_send, new_send_rate); - sample_rate_send = new_send_rate; - update_capture_sync_info(); - goto _done_rate_size_check; - } - update_cap = true; - } - -_done_rate_size_check:; -#endif - -#ifdef DSD_SUPPORT - bool new_dsd_state; - - new_dsd_state = usb_dsd_enabled; - if (stream == AUD_STREAM_PLAYBACK) { - if (codec_dsd_enabled != new_dsd_state) { - update_play = true; - } - } -#endif - - if (!update_play && !update_cap) { - return; - } - - // 1) To avoid L/R sample misalignment, streams must be stopped before - // changing sample rate 2) To avoid FIFO corruption, streams must be stopped - // before changing sample size - if (update_cap && - codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, true); - usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); - } - if (update_play && - codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, true); - usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); - } - - if (update_play) { -#ifdef USB_AUDIO_DYN_CFG - if (sample_rate_recv != new_recv_rate) { - TRACE(3, "%s:2: Update recv sample rate from %u to %u", __FUNCTION__, - sample_rate_recv, new_recv_rate); - sample_rate_recv = new_recv_rate; - } - if (sample_rate_play != play_rate) { - TRACE(3, "%s:2: Update play sample rate from %u to %u", __FUNCTION__, - sample_rate_play, play_rate); - sample_rate_play = play_rate; - } - if (sample_size_recv != new_recv_size) { - TRACE(3, "%s:2: Update recv sample size from %u to %u", __FUNCTION__, - sample_size_recv, new_recv_size); - sample_size_recv = new_recv_size; -#ifndef AUDIO_PLAYBACK_24BIT - uint8_t old_play_size; - - old_play_size = sample_size_play; - sample_size_play = (new_recv_size == 2) ? 2 : 4; - TRACE(3, "%s:2: Update play sample size from %u to %u", __FUNCTION__, - old_play_size, sample_size_play); -#endif - } -#endif -#ifdef DSD_SUPPORT - if (codec_dsd_enabled != new_dsd_state) { - codec_dsd_enabled = new_dsd_state; -#ifdef CODEC_DSD - uint8_t old_play_size; - - old_play_size = sample_size_play; - if (codec_dsd_enabled) { - playback_size /= ((sample_size_play + 1) / 2); - dsd_saved_sample_size = sample_size_play; - sample_size_play = 2; - } else { - playback_size *= ((dsd_saved_sample_size + 1) / 2); - sample_size_play = dsd_saved_sample_size; - } - TRACE(4, "%s:2: CODEC_DSD=%u update play sample size from %u to %u", - __FUNCTION__, codec_dsd_enabled, old_play_size, sample_size_play); -#endif - } -#endif - } - if (update_cap) { -#ifdef USB_AUDIO_DYN_CFG - if (sample_rate_send != new_send_rate) { - TRACE(3, "%s:2: Update send sample rate from %u to %u", __FUNCTION__, - sample_rate_send, new_send_rate); - sample_rate_send = new_send_rate; - } - if (sample_rate_cap != cap_rate) { - TRACE(3, "%s:2: Update cap sample rate from %u to %u", __FUNCTION__, - sample_rate_cap, cap_rate); - sample_rate_cap = cap_rate; - } -#endif - } - -#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) - playback_size = calc_playback_size(sample_rate_play); - capture_size = calc_capture_size(sample_rate_cap); -#endif - -#ifdef SW_CAPTURE_RESAMPLE - // Check whether to start capture resample - if (update_cap && capture_state == AUDIO_ITF_STATE_STARTED) { - capture_stream_resample_config(); - } -#endif - -#ifdef STREAM_RATE_BITS_SETUP - if (update_play) { - update_playback_sync_info(); - - ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &cfg, true); - if (ret == 0) { - // Changes in AF_STREAM_CONFIG_T::bits must be in another cfg variable - stream_cfg = *cfg; -#ifdef CODEC_DSD - if (codec_dsd_enabled) { - stream_cfg.bits = AUD_BITS_24; - } else -#endif - { - stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); - } - stream_cfg.sample_rate = sample_rate_play; -#if (defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY)) || \ - defined(CODEC_DSD) - stream_cfg.data_size = playback_size; -#endif - af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); - } - -#ifdef AUDIO_ANC_FB_MC - ret = af_stream_get_cfg(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &cfg, true); - if (ret == 0) { - // Changes in AF_STREAM_CONFIG_T::bits must be in another cfg variable - stream_cfg = *cfg; - stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); - - if (sample_rate_play == AUD_SAMPRATE_8000) { - playback_samplerate_ratio = 8 * 6; - } else if (sample_rate_play == AUD_SAMPRATE_16000) { - playback_samplerate_ratio = 8 * 3; - } else if ((sample_rate_play == AUD_SAMPRATE_44100) || - (sample_rate_play == AUD_SAMPRATE_48000) || - (sample_rate_play == AUD_SAMPRATE_50781)) { - playback_samplerate_ratio = 8; - } else if ((sample_rate_play == AUD_SAMPRATE_88200) || - (sample_rate_play == AUD_SAMPRATE_96000)) { - playback_samplerate_ratio = 4; - } else if ((sample_rate_play == AUD_SAMPRATE_176400) || - (sample_rate_play == AUD_SAMPRATE_192000)) { - playback_samplerate_ratio = 2; - } else if (sample_rate_play == AUD_SAMPRATE_384000) { - playback_samplerate_ratio = 1; - } else { - playback_samplerate_ratio = 1; - ASSERT(false, "Music cancel can't support playback sample rate:%d", - sample_rate_play); - } - - stream_cfg.data_ptr = playback_buf + playback_size; - stream_cfg.data_size = playback_size * playback_samplerate_ratio; - - stream_cfg.sample_rate = sample_rate_play; - af_stream_setup(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); - anc_mc_run_setup((sample_rate_play * playback_samplerate_ratio) / 8); - } -#endif - } - if (update_cap) { - update_capture_sync_info(); - - ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &cfg, true); - if (ret == 0) { - stream_cfg = *cfg; - stream_cfg.bits = sample_size_to_enum_capture(sample_size_cap); -#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) - stream_cfg.data_size = capture_size; -#endif - stream_cfg.sample_rate = sample_rate_cap; - af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); - } - } -#else // !STREAM_RATE_BITS_SETUP - // Close streams - if (update_cap && codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_OPENED]) { - usb_audio_close_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); - } - if (update_play && - codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_OPENED]) { - usb_audio_close_codec_stream(AUD_STREAM_PLAYBACK, - AUDIO_STREAM_REQ_USER_ALL); - } - // Open streams - if (update_play && - codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_OPENED]) { - usb_audio_open_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); - } - if (update_cap && codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_OPENED]) { - usb_audio_open_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); - } -#endif // !STREAM_RATE_BITS_SETUP - - if (update_play && - codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { - usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, - AUDIO_STREAM_REQ_USER_ALL); - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, false); - } - if (update_cap && - codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { - usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, false); - } -} - -static void start_play(uint8_t seq) { - if (playback_state == AUDIO_ITF_STATE_STOPPED) { -#ifdef FREQ_RESP_EQ - freq_resp_eq_init(); -#endif - -#ifdef DELAY_STREAM_OPEN - usb_audio_open_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); -#endif - -#ifdef NOISE_GATING - last_high_signal_time = hal_sys_timer_get(); -#ifdef NOISE_REDUCTION - last_nr_restore_time = hal_sys_timer_get(); -#endif -#endif - - usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); - - playback_state = AUDIO_ITF_STATE_STARTED; - } - - codec_play_seq = seq; - playback_paused = 0; - - usb_audio_update_freq(); -} - -static void usb_audio_cmd_start_play(uint8_t seq) { -#if defined(USB_AUDIO_DYN_CFG) && defined(USB_AUDIO_UAC2) - usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); -#endif - - start_play(seq); -} - -static void usb_audio_cmd_stop_play(void) { - if (playback_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); - -#ifdef PA_ON_OFF_KEY - if (pa_on_off_muted) { - pa_on_off_muted = false; - if (mute_user_map == 0) { - usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); - } - } -#endif -#ifdef NOISE_GATING - // Restore the noise gating status - if (mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) { - usb_audio_codec_unmute(CODEC_MUTE_USER_NOISE_GATING); - } -#ifdef NOISE_REDUCTION - restore_noise_reduction_status(); -#endif -#endif - -#ifdef DELAY_STREAM_OPEN - usb_audio_close_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); -#endif - - playback_paused = 0; - playback_state = AUDIO_ITF_STATE_STOPPED; -#ifdef DSD_SUPPORT - if (codec_dsd_enabled) { - usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); - } -#endif - } - - usb_audio_update_freq(); -} - -static void start_capture(uint8_t seq) { - if (capture_state == AUDIO_ITF_STATE_STOPPED) { -#ifdef SW_CAPTURE_RESAMPLE - // Check whether to start capture resample - capture_stream_resample_config(); -#endif - -#ifdef DELAY_STREAM_OPEN - usb_audio_open_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); -#endif - usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); - - capture_state = AUDIO_ITF_STATE_STARTED; - } - - codec_cap_seq = seq; - - usb_audio_update_freq(); -} - -static void usb_audio_cmd_start_capture(uint8_t seq) { start_capture(seq); } - -static void usb_audio_cmd_stop_capture(void) { - if (capture_state == AUDIO_ITF_STATE_STARTED) { - usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); - -#ifdef DELAY_STREAM_OPEN - usb_audio_close_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); -#endif - -#ifdef SW_CAPTURE_RESAMPLE - if (resample_cap_enabled) { - audio_resample_ex_close(resample_id); - resample_cap_enabled = false; - } -#endif - - capture_state = AUDIO_ITF_STATE_STOPPED; - } - - usb_audio_update_freq(); -} - -static void usb_audio_cmd_set_volume(void) { -#ifndef USB_AUDIO_MULTIFUNC - playback_vol = new_playback_vol; -#endif - - usb_audio_set_codec_volume(AUD_STREAM_PLAYBACK, playback_vol); - -#ifdef UNMUTE_WHEN_SET_VOL - // Unmute if muted before - if (mute_user_map & (1 << CODEC_MUTE_USER_CMD)) { - usb_audio_codec_unmute(CODEC_MUTE_USER_CMD); - } -#endif -} - -static void usb_audio_cmd_set_cap_volume(void) { - capture_vol = new_capture_vol; - - usb_audio_set_codec_volume(AUD_STREAM_CAPTURE, capture_vol); -} - -static void usb_audio_cmd_mute_ctrl(void) { - uint8_t mute; - -#ifdef USB_AUDIO_MULTIFUNC - mute = new_mute_state && new_mute2_state; -#else - mute = new_mute_state; -#endif - - if (mute) { - usb_audio_codec_mute(CODEC_MUTE_USER_CMD); - } else { - usb_audio_codec_unmute(CODEC_MUTE_USER_CMD); - } -} - -static void usb_audio_cmd_cap_mute_ctrl(void) { - uint8_t mute; - - mute = new_cap_mute_state; - - af_stream_mute(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, mute); -} - -static void usb_audio_cmd_usb_state(enum AUDIO_CMD_T cmd) { - usb_audio_cmd_stop_capture(); - usb_audio_cmd_stop_play(); - - if (cmd == AUDIO_CMD_USB_RESET || cmd == AUDIO_CMD_USB_WAKEUP) { - usb_audio_acquire_freq(); - if (cmd == AUDIO_CMD_USB_RESET) { - usb_audio_term_streams(AUDIO_STREAM_REQ_USB); - } - usb_audio_reset_codec_stream_state(cmd == AUDIO_CMD_USB_RESET); - usb_audio_init_streams(AUDIO_STREAM_REQ_USB); - } else if (cmd == AUDIO_CMD_USB_DISCONNECT || cmd == AUDIO_CMD_USB_SLEEP) { - usb_audio_term_streams(AUDIO_STREAM_REQ_USB); - usb_audio_reset_codec_stream_state(cmd == AUDIO_CMD_USB_DISCONNECT); - if (cmd == AUDIO_CMD_USB_DISCONNECT || usb_configured) { - usb_audio_release_freq(); - } - } else if (cmd == AUDIO_CMD_USB_CONFIG) { - usb_configured = 1; - usb_audio_reset_codec_stream_state(true); - } -} - -static void usb_audio_cmd_recv_pause(uint8_t seq) { - TRACE(3, "%s: Recv pause: seq=%u usb_recv_seq=%u", __FUNCTION__, seq, - usb_recv_seq); - - if (seq == usb_recv_seq) { - usb_audio_cmd_stop_play(); - playback_paused = 1; - } -} - -static void usb_audio_cmd_recv_continue(uint8_t seq) { - TRACE(3, "%s: Recv continue: seq=%u usb_recv_seq=%u", __FUNCTION__, seq, - usb_recv_seq); - - if (seq == usb_recv_seq && playback_paused) { - start_play(seq); - // playback_paused = 0; - } -} - -#ifdef USB_AUDIO_DYN_CFG -static void usb_audio_cmd_set_playback_rate(uint8_t seq, uint8_t index) { -#ifndef USB_AUDIO_UAC2 - if (seq != usb_recv_seq) { - TRACE(3, "%s: Bad seq: seq=%u usb_recv_seq=%u", __FUNCTION__, seq, - usb_recv_seq); - return; - } -#endif - - usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); - -#ifndef USB_AUDIO_UAC2 - start_play(seq); -#endif -} - -static void usb_audio_cmd_set_capture_rate(uint8_t seq, uint8_t index) { -#ifndef USB_AUDIO_UAC2 - if (seq != usb_send_seq) { - TRACE(3, "%s: Bad seq: seq=%u usb_send_seq=%u", __FUNCTION__, seq, - usb_send_seq); - return; - } -#endif - - usb_audio_update_codec_stream(AUD_STREAM_CAPTURE); - -#ifndef USB_AUDIO_UAC2 - start_capture(seq); -#endif -} -#endif - -static void usb_audio_cmd_reset_codec(void) { - TRACE(1, "%s: RESET CODEC", __FUNCTION__); - - // Regarding PLL reconfiguration, stream stop and start are enough. - // Complete DAC/ADC reset (including analog parts) can be achieved by - // stream close and open, which need to invoke explicitly here if - // DELAY_STREAM_OPEN is not defined. - - if (codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, true); - usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); - } - - if (codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, true); - usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); - } - - rate_tune_ratio[AUD_STREAM_PLAYBACK] = 0; - rate_tune_ratio[AUD_STREAM_CAPTURE] = 0; -#ifdef __AUDIO_RESAMPLE__ -#ifdef PLL_TUNE_SAMPLE_RATE - af_codec_tune_resample_rate(AUD_STREAM_PLAYBACK, - rate_tune_ratio[AUD_STREAM_PLAYBACK]); - af_codec_tune_resample_rate(AUD_STREAM_CAPTURE, - rate_tune_ratio[AUD_STREAM_CAPTURE]); -#elif defined(PLL_TUNE_XTAL) - af_codec_tune_xtal(rate_tune_ratio[AUD_STREAM_PLAYBACK]); -#endif -#else - af_codec_tune_pll(rate_tune_ratio[AUD_STREAM_PLAYBACK]); -#endif - - if (codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { - usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, - AUDIO_STREAM_REQ_USER_ALL); - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, false); - } - - if (codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { - usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); - set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, false); - } -} - -#ifdef NOISE_GATING -static void usb_audio_cmd_noise_gating(void) { - uint32_t lock; - enum NOISE_GATING_CMD_T cmd; - - lock = int_lock(); - cmd = noise_gating_cmd; - noise_gating_cmd = NOISE_GATING_CMD_NULL; - int_unlock(lock); - - TRACE(3, "%s: cmd=%d map=0x%02X", __FUNCTION__, cmd, mute_user_map); - - if (cmd == NOISE_GATING_CMD_MUTE) { - if ((mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) == 0) { - usb_audio_codec_mute(CODEC_MUTE_USER_NOISE_GATING); - } - } else if (cmd == NOISE_GATING_CMD_UNMUTE) { - if (mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) { - usb_audio_codec_unmute(CODEC_MUTE_USER_NOISE_GATING); - } - } -} - -#ifdef NOISE_REDUCTION -static void restore_noise_reduction_status(void) { - if (nr_active) { - nr_active = false; - af_codec_set_noise_reduction(false); - } - prev_samp_positive[0] = prev_samp_positive[1] = false; - memset(prev_zero_diff, 0, sizeof(prev_zero_diff)); - memset(cur_zero_diff, 0, sizeof(cur_zero_diff)); - nr_cont_cnt = 0; -} - -static void usb_audio_cmd_noise_reduction(void) { - uint32_t lock; - enum NOISE_REDUCTION_CMD_T cmd; - - lock = int_lock(); - cmd = noise_reduction_cmd; - noise_reduction_cmd = NOISE_REDUCTION_CMD_NULL; - int_unlock(lock); - - TRACE(2, "%s: cmd=%d", __FUNCTION__, cmd); - - if (cmd == NOISE_REDUCTION_CMD_FIRE) { - nr_active = true; - af_codec_set_noise_reduction(true); - } else if (cmd == NOISE_REDUCTION_CMD_RESTORE) { - nr_active = false; - af_codec_set_noise_reduction(false); - } -} -#endif -#endif - -static void usb_audio_cmd_tune_rate(enum AUD_STREAM_T stream) { -#ifdef __AUDIO_RESAMPLE__ -#ifdef PLL_TUNE_SAMPLE_RATE - bool update_play, update_cap; - - update_play = true; - update_cap = false; - -#ifdef UAUD_SYNC_STREAM_TARGET - if (stream == AUD_STREAM_PLAYBACK) { - update_play = true; - update_cap = false; - } else { - update_play = false; - update_cap = true; - } -#else - update_play = true; - update_cap = true; -#endif - -#ifdef SW_RESAMPLE - if (update_play) { - audio_resample_ex_set_ratio_step(play_resample_id, - nominal_ratio_step * - rate_tune_ratio[AUD_STREAM_PLAYBACK]); - } - if (update_cap) { - audio_resample_ex_set_ratio_step(cap_resample_id, - nominal_ratio_step * - rate_tune_ratio[AUD_STREAM_CAPTURE]); - } -#else - if (update_play) { - af_codec_tune_resample_rate(AUD_STREAM_PLAYBACK, - rate_tune_ratio[AUD_STREAM_PLAYBACK]); - } - if (update_cap) { - af_codec_tune_resample_rate(AUD_STREAM_CAPTURE, - rate_tune_ratio[AUD_STREAM_CAPTURE]); - } -#endif -#elif defined(PLL_TUNE_XTAL) - af_codec_tune_xtal(rate_tune_ratio[AUD_STREAM_PLAYBACK]); -#endif -#else // !__AUDIO_RESAMPLE__ - af_codec_tune_pll(rate_tune_ratio[AUD_STREAM_PLAYBACK]); -#endif // !__AUDIO_RESAMPLE__ -} - -#ifdef DSD_SUPPORT -static void usb_audio_cmd_set_dsd_cfg(void) { - if (codec_dsd_enabled != usb_dsd_enabled) { - TRACE(3, "%s: %d => %d", __FUNCTION__, codec_dsd_enabled, usb_dsd_enabled); - usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); - } -} -#endif - -#ifdef PERF_TEST_POWER_KEY -static void test_cmd_perf_test_power(void) { - perft_power_type++; - if (perft_power_type >= HAL_CODEC_PERF_TEST_QTY) { - perft_power_type = 0; - } - - TRACE(2, "%s: %d", __FUNCTION__, perft_power_type); - - af_codec_set_perf_test_power(perft_power_type); -} -#endif - -#ifdef PA_ON_OFF_KEY -static void test_cmd_pa_on_off(void) { - pa_on_off_muted = !pa_on_off_muted; - - TRACE(2, "%s: %d", __FUNCTION__, pa_on_off_muted); - - if (pa_on_off_muted) { - usb_audio_codec_mute(CODEC_MUTE_USER_ALL); - } else { - usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); -#ifdef PERF_TEST_POWER_KEY - af_codec_set_perf_test_power(perft_power_type); -#endif - } -} -#endif - -static void usb_audio_cmd_handler(void *param) { - uint32_t data; - enum AUDIO_CMD_T cmd; - uint8_t seq; - uint8_t POSSIBLY_UNUSED arg; - - hal_cpu_wake_unlock(USB_AUDIO_CPU_WAKE_USER); - - while (safe_queue_get(&cmd_queue, &data) == 0) { - cmd = EXTRACT_CMD(data); - seq = EXTRACT_SEQ(data); - arg = EXTRACT_ARG(data); - TRACE(4, "%s: cmd=%d seq=%d arg=%d", __FUNCTION__, cmd, seq, arg); - - switch (cmd) { - case AUDIO_CMD_START_PLAY: - usb_audio_cmd_start_play(seq); - break; - - case AUDIO_CMD_STOP_PLAY: - usb_audio_cmd_stop_play(); - break; - - case AUDIO_CMD_START_CAPTURE: - usb_audio_cmd_start_capture(seq); - break; - - case AUDIO_CMD_STOP_CAPTURE: - usb_audio_cmd_stop_capture(); - break; - - case AUDIO_CMD_SET_VOLUME: - usb_audio_cmd_set_volume(); - break; - - case AUDIO_CMD_SET_CAP_VOLUME: - usb_audio_cmd_set_cap_volume(); - break; - - case AUDIO_CMD_MUTE_CTRL: - usb_audio_cmd_mute_ctrl(); - break; - - case AUDIO_CMD_CAP_MUTE_CTRL: - usb_audio_cmd_cap_mute_ctrl(); - break; - - case AUDIO_CMD_USB_RESET: - case AUDIO_CMD_USB_DISCONNECT: - case AUDIO_CMD_USB_CONFIG: - case AUDIO_CMD_USB_SLEEP: - case AUDIO_CMD_USB_WAKEUP: - usb_audio_cmd_usb_state(cmd); - break; - - case AUDIO_CMD_RECV_PAUSE: - usb_audio_cmd_recv_pause(seq); - break; - case AUDIO_CMD_RECV_CONTINUE: - usb_audio_cmd_recv_continue(seq); - break; - -#ifdef USB_AUDIO_DYN_CFG - case AUDIO_CMD_SET_RECV_RATE: - usb_audio_cmd_set_playback_rate(seq, arg); - break; - case AUDIO_CMD_SET_SEND_RATE: - usb_audio_cmd_set_capture_rate(seq, arg); - break; -#endif - - case AUDIO_CMD_RESET_CODEC: - usb_audio_cmd_reset_codec(); - break; - -#ifdef NOISE_GATING - case AUDIO_CMD_NOISE_GATING: - usb_audio_cmd_noise_gating(); - break; - -#ifdef NOISE_REDUCTION - case AUDIO_CMD_NOISE_REDUCTION: - usb_audio_cmd_noise_reduction(); - break; -#endif -#endif - - case AUDIO_CMD_TUNE_RATE: - usb_audio_cmd_tune_rate((enum AUD_STREAM_T)arg); - break; - -#ifdef DSD_SUPPORT - case AUDIO_CMD_SET_DSD_CFG: - usb_audio_cmd_set_dsd_cfg(); - break; -#endif - -#ifdef PERF_TEST_POWER_KEY - case TEST_CMD_PERF_TEST_POWER: - test_cmd_perf_test_power(); - break; -#endif - -#ifdef PA_ON_OFF_KEY - case TEST_CMD_PA_ON_OFF: - test_cmd_pa_on_off(); - break; -#endif - - default: - ASSERT(false, "%s: Invalid cmd %d", __FUNCTION__, cmd); - break; - } - } -} - -void usb_audio_app_init(const struct USB_AUDIO_BUF_CFG *cfg) { -#ifdef USB_AUDIO_DYN_CFG - ASSERT(cfg->play_size / MAX_FRAME_SIZE_PLAYBACK < - cfg->recv_size / MAX_FRAME_SIZE_RECV, - "%s: play frames %u should < recv frames %u", __FUNCTION__, - cfg->play_size / MAX_FRAME_SIZE_PLAYBACK, - cfg->recv_size / MAX_FRAME_SIZE_RECV); - ASSERT(cfg->cap_size / MAX_FRAME_SIZE_CAPTURE < - cfg->send_size / MAX_FRAME_SIZE_SEND, - "%s: cap frames %u should < send frames %u", __FUNCTION__, - cfg->cap_size / MAX_FRAME_SIZE_CAPTURE, - cfg->send_size / MAX_FRAME_SIZE_SEND); -#else - ASSERT( - cfg->play_size / FRAME_SIZE_PLAYBACK < cfg->recv_size / FRAME_SIZE_RECV, - "%s: play frames %u should < recv frames %u", __FUNCTION__, - cfg->play_size / FRAME_SIZE_PLAYBACK, cfg->recv_size / FRAME_SIZE_RECV); - ASSERT(cfg->cap_size / FRAME_SIZE_CAPTURE < cfg->send_size / FRAME_SIZE_SEND, - "%s: cap frames %u should < send frames %u", __FUNCTION__, - cfg->cap_size / FRAME_SIZE_CAPTURE, cfg->send_size / FRAME_SIZE_SEND); -#endif - -#ifdef SW_CAPTURE_RESAMPLE - enum AUD_CHANNEL_NUM_T chans; - enum AUD_BITS_T bits; - uint8_t phase_coef_num; - uint32_t resamp_calc_size; - - chans = get_capture_resample_chan_num(); - bits = sample_size_to_enum_capture(sample_size_cap); - // Max phase coef num - phase_coef_num = 100; - - resamp_calc_size = - audio_resample_ex_get_buffer_size(chans, bits, phase_coef_num); - ASSERT(cfg->resample_size > resamp_calc_size, - "%s: Resample size too small %u (should > %u)", __FUNCTION__, - cfg->resample_size, resamp_calc_size); - - resample_history_buf = (uint8_t *)ALIGN((uint32_t)cfg->resample_buf, 4); - resample_history_size = resamp_calc_size; - resample_input_buf = (uint8_t *)resample_history_buf + resample_history_size; - ASSERT(cfg->resample_buf + cfg->resample_size > resample_input_buf, - "%s: Resample size too small: %u", __FUNCTION__, cfg->resample_size); - resample_input_size = - cfg->resample_buf + cfg->resample_size - resample_input_buf; -#endif - - playback_buf = cfg->play_buf; - capture_buf = cfg->cap_buf; - usb_recv_buf = cfg->recv_buf; - usb_send_buf = cfg->send_buf; - playback_eq_buf = cfg->eq_buf; - playback_eq_size = cfg->eq_size; - -#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) - playback_max_size = cfg->play_size; - capture_max_size = cfg->cap_size; - usb_recv_max_size = cfg->recv_size; - usb_send_max_size = cfg->send_size; -#else - playback_size = cfg->play_size; - capture_size = cfg->cap_size; - usb_recv_size = cfg->recv_size; - usb_send_size = cfg->send_size; -#endif - - playback_pos = 0; - usb_recv_rpos = 0; - usb_recv_wpos = cfg->recv_size / 2; - capture_pos = 0; - usb_send_rpos = cfg->send_size / 2; - usb_send_wpos = 0; - -#ifdef USB_AUDIO_MULTIFUNC - usb_recv2_buf = cfg->recv2_buf; - usb_recv2_size = cfg->recv2_size; - usb_recv2_rpos = 0; - usb_recv2_wpos = cfg->recv2_size / 2; -#endif - - playback_info.id = 0; - playback_info.sync_thresh = DIFF_SYNC_THRESH_PLAYBACK; - playback_info.diff_avg_cnt = DIFF_AVG_CNT; -#ifdef TARGET_TO_MAX_DIFF - playback_info.diff_target_enabled = true; - playback_info.max_target_ratio = MAX_TARGET_RATIO; - playback_info.time_to_ms = NULL; -#endif - capture_info.id = 1; - capture_info.sync_thresh = DIFF_SYNC_THRESH_CAPTURE; - capture_info.diff_avg_cnt = DIFF_AVG_CNT; -#ifdef TARGET_TO_MAX_DIFF - capture_info.diff_target_enabled = true; - capture_info.max_target_ratio = MAX_TARGET_RATIO; - capture_info.time_to_ms = NULL; -#endif - - safe_queue_init(&cmd_queue, cmd_list, CMD_LIST_SIZE); - -#ifdef USB_AUDIO_PWRKEY_TEST - hal_cmu_simu_set_val(0); -#endif -} - -void usb_audio_app_term(void) { - playback_buf = NULL; - playback_size = 0; - capture_buf = NULL; - capture_size = 0; - usb_recv_buf = NULL; - usb_recv_size = 0; - usb_send_buf = NULL; - usb_send_size = 0; - - playback_pos = 0; - usb_recv_rpos = 0; - usb_recv_wpos = 0; - - capture_pos = 0; - usb_send_rpos = 0; - usb_send_wpos = 0; - -#ifdef USB_AUDIO_MULTIFUNC - usb_recv2_buf = NULL; - usb_recv2_size = 0; - usb_recv2_rpos = 0; - usb_recv2_wpos = 0; -#endif -} - -void usb_audio_app(bool on) { - static const struct USB_AUDIO_CFG_T usb_audio_cfg = { - .recv_sample_rate = SAMPLE_RATE_RECV, - .send_sample_rate = SAMPLE_RATE_SEND, - .itf_callback = usb_audio_itf_callback, - .mute_callback = usb_audio_mute_callback, - .set_volume = usb_audio_set_volume, - .get_volume = usb_audio_get_volume, - .state_callback = usb_audio_state_control, - .xfer_callback = usb_audio_xfer_callback, -#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) - // Applications are responsible for clearing HID events - .hid_send_callback = hid_data_send_handler, -#else - // HID events will be cleared automatically once they are sent - .hid_send_callback = NULL, -#endif -#ifdef _VENDOR_MSG_SUPPT_ - .vendor_msg_callback = usb_vendor_callback, - .vendor_rx_buf = vendor_msg_rx_buf, - .vendor_rx_size = VENDOR_RX_BUF_SZ, -#endif - }; - static bool isRun = false; - int ret; - - if (isRun == on) - return; - else - isRun = on; - - TRACE(2, "%s: on=%d", __FUNCTION__, on); - - if (on) { - usb_audio_acquire_freq(); - - usb_audio_reset_usb_stream_state(true); - usb_audio_reset_codec_stream_state(true); - -#ifdef USB_AUDIO_DYN_CFG - sample_rate_recv = new_sample_rate_recv = usb_audio_cfg.recv_sample_rate; - sample_rate_send = new_sample_rate_send = usb_audio_cfg.send_sample_rate; - // Init codec sample rates after initializing usb sample rates - sample_rate_play = calc_play_sample_rate(sample_rate_recv); - sample_rate_cap = calc_cap_sample_rate(sample_rate_send, sample_rate_play); - // TODO: Check whether 16-bit sample is enabled - sample_size_recv = new_sample_size_recv = 2; -#ifndef AUDIO_PLAYBACK_24BIT - sample_size_play = 2; -#endif - -#ifdef KEEP_SAME_LATENCY - usb_recv_size = calc_usb_recv_size(sample_rate_recv, sample_size_recv); - usb_send_size = calc_usb_send_size(sample_rate_send); - playback_size = calc_playback_size(sample_rate_play); - capture_size = calc_capture_size(sample_rate_cap); -#endif -#endif - - TRACE(3, "CODEC playback sample: rate=%u size=%u chan=%u", sample_rate_play, - sample_size_play, CHAN_NUM_PLAYBACK); - TRACE(3, "CODEC capture sample: rate=%u size=%u chan=%u", sample_rate_cap, - sample_size_cap, CHAN_NUM_CAPTURE); - TRACE(2, "USB recv sample: rate=%u size=%u", sample_rate_recv, - sample_size_recv); - TRACE(2, "USB send sample: rate=%u size=%u", sample_rate_send, - sample_size_send); - - usb_audio_init_streams(AUDIO_STREAM_REQ_USB); - - pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); - ret = usb_audio_open(&usb_audio_cfg); - ASSERT(ret == 0, "usb_audio_open failed: %d", ret); - } else { - usb_audio_close(); - pmu_usb_config(PMU_USB_CONFIG_TYPE_NONE); - - usb_audio_term_streams(AUDIO_STREAM_REQ_USB); - - usb_audio_reset_usb_stream_state(true); - usb_audio_reset_codec_stream_state(true); - - usb_audio_release_freq(); - } -} - -static void app_key_trace(uint32_t line, enum HAL_KEY_CODE_T code, - enum HAL_KEY_EVENT_T event, - enum USB_AUDIO_HID_EVENT_T uevt, int state) { -#ifdef KEY_TRACE - TRACE(5, "APPKEY/%u: code=%d event=%d uevt=%s state=%d", line, code, event, - usb_audio_get_hid_event_name(uevt), state); -#endif -} - -int usb_audio_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event) { - int i; - enum USB_AUDIO_HID_EVENT_T uevt; - int state; - - if (event == HAL_KEY_EVENT_CLICK && - playback_state == AUDIO_ITF_STATE_STARTED) { -#ifdef PERF_TEST_POWER_KEY - if (code == PERF_TEST_POWER_KEY) { - enqueue_unique_cmd(TEST_CMD_PERF_TEST_POWER); - } -#endif -#ifdef PA_ON_OFF_KEY - if (code == PA_ON_OFF_KEY) { - enqueue_unique_cmd(TEST_CMD_PA_ON_OFF); - } -#endif - } - -#ifdef USB_AUDIO_PWRKEY_TEST - if (code == HAL_KEY_CODE_PWR) { - uevt = hal_cmu_simu_get_val(); - if (uevt == 0) { - uevt = USB_AUDIO_HID_VOL_UP; - } -#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) - if (event == HAL_KEY_EVENT_DOWN || event == HAL_KEY_EVENT_UP) { - state = (event != HAL_KEY_EVENT_UP); - app_key_trace(__LINE__, code, event, uevt, state); - usb_audio_hid_set_event(uevt, state); - } - // The key event has been processed - return 0; -#else - if (event == HAL_KEY_EVENT_CLICK) { - state = 1; - app_key_trace(__LINE__, code, event, uevt, state); - usb_audio_hid_set_event(uevt, state); - return 0; - } - // Let other applications check the key event - return 1; -#endif - } -#endif - - if (code != HAL_KEY_CODE_NONE) { - for (i = 0; i < ARRAY_SIZE(key_map); i++) { - if (key_map[i].key_code == code && - (key_map[i].key_event_bitset & (1 << event))) { - break; - } - } - if (i < ARRAY_SIZE(key_map)) { - uevt = key_map[i].hid_event; - if (uevt != 0) { -#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) - state = (event != HAL_KEY_EVENT_UP); -#else - state = 1; -#endif - app_key_trace(__LINE__, code, event, uevt, state); - usb_audio_hid_set_event(uevt, state); - // The key event has been processed - return 0; - } - } - } - - // Let other applications check the key event - return 1; -} - -#ifdef ANC_APP -extern bool anc_usb_app_get_status(); -static uint8_t anc_status = 0; -static uint8_t anc_status_record = 0xff; -#endif - -void usb_audio_eq_loop(void) { -#ifdef ANC_APP - anc_status = anc_usb_app_get_status(); - if (anc_status_record != anc_status && eq_opened == 1) { - anc_status_record = anc_status; - TRACE(2, "[%s]anc_status = %d", __func__, anc_status); -#ifdef __SW_IIR_EQ_PROCESS__ - usb_audio_set_eq(AUDIO_EQ_TYPE_SW_IIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_SW_IIR, anc_status)); -#endif - -#ifdef __HW_FIR_EQ_PROCESS__ - usb_audio_set_eq(AUDIO_EQ_TYPE_HW_FIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR, anc_status)); -#endif - -#ifdef __HW_DAC_IIR_EQ_PROCESS__ - usb_audio_set_eq( - AUDIO_EQ_TYPE_HW_DAC_IIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_DAC_IIR, anc_status)); -#endif - -#ifdef __HW_IIR_EQ_PROCESS__ - usb_audio_set_eq(AUDIO_EQ_TYPE_HW_IIR, - usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_IIR, anc_status)); -#endif - } -#endif -} - -void usb_audio_app_loop(void) { - usb_audio_cmd_handler(NULL); - - usb_audio_eq_loop(); - -#ifndef RTOS - extern void af_thread(void const *argument); - af_thread(NULL); -#endif -} - -uint32_t usb_audio_get_capture_sample_rate(void) { return sample_rate_cap; } diff --git a/tests/anc_usb/usb_audio_app.h b/tests/anc_usb/usb_audio_app.h deleted file mode 100644 index 9673148..0000000 --- a/tests/anc_usb/usb_audio_app.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_AUDIO_APP_H__ -#define __USB_AUDIO_APP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "plat_types.h" -#include "hal_key.h" -#include "audio_process.h" - -struct USB_AUDIO_BUF_CFG { - uint8_t *play_buf; - uint32_t play_size; - uint8_t *cap_buf; - uint32_t cap_size; - uint8_t *recv_buf; - uint32_t recv_size; - uint8_t *send_buf; - uint32_t send_size; - uint8_t *eq_buf; - uint32_t eq_size; - uint8_t *resample_buf; - uint32_t resample_size; -#ifdef USB_AUDIO_MULTIFUNC - uint8_t *recv2_buf; - uint32_t recv2_size; -#endif -}; - -typedef void (*USB_AUDIO_ENQUEUE_CMD_CALLBACK)(uint32_t data); - -void usb_audio_app(bool on); -void usb_audio_keep_streams_running(bool enable); -void usb_audio_app_init(const struct USB_AUDIO_BUF_CFG *cfg); - -void usb_audio_app_term(void); -int usb_audio_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event); -void usb_audio_app_loop(void); -uint32_t usb_audio_get_capture_sample_rate(void); - -uint32_t usb_audio_set_eq(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t index); -uint8_t usb_audio_get_eq_index(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t anc_status); - -void usb_audio_set_enqueue_cmd_callback(USB_AUDIO_ENQUEUE_CMD_CALLBACK cb); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tests/anc_usb/usb_audio_frm_defs.h b/tests/anc_usb/usb_audio_frm_defs.h deleted file mode 100644 index 8ebf602..0000000 --- a/tests/anc_usb/usb_audio_frm_defs.h +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************** - * - * Copyright 2015-2019 BES. - * All rights reserved. All unpublished rights reserved. - * - * No part of this work may be used or reproduced in any form or by any - * means, or stored in a database or retrieval system, without prior written - * permission of BES. - * - * Use of this work is governed by a license granted by BES. - * This work contains confidential and proprietary information of - * BES. which is protected by copyright, trade secret, - * trademark and other intellectual property rights. - * - ****************************************************************************/ -#ifndef __USB_AUDIO_FRM_DEFS_H__ -#define __USB_AUDIO_FRM_DEFS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -// Recv/send sample rates -#if 0 -#elif defined(USB_AUDIO_384K) -#define SAMPLE_RATE_RECV 384000 -#define SAMPLE_RATE_SEND 48000 -#elif defined(USB_AUDIO_352_8K) -#define SAMPLE_RATE_RECV 352800 -#define SAMPLE_RATE_SEND 44100 -#elif defined(USB_AUDIO_192K) -#define SAMPLE_RATE_RECV 192000 -#define SAMPLE_RATE_SEND 48000 -#elif defined(USB_AUDIO_176_4K) -#define SAMPLE_RATE_RECV 176400 -#define SAMPLE_RATE_SEND 44100 -#elif defined(USB_AUDIO_96K) -#define SAMPLE_RATE_RECV 96000 -#define SAMPLE_RATE_SEND 48000 -#elif defined(USB_AUDIO_48K) -#define SAMPLE_RATE_RECV 48000 -#define SAMPLE_RATE_SEND 48000 -#elif defined(USB_AUDIO_44_1K) -#define SAMPLE_RATE_RECV 44100 -#define SAMPLE_RATE_SEND 44100 -#elif defined(USB_AUDIO_16K) -#define SAMPLE_RATE_RECV 16000 -#define SAMPLE_RATE_SEND 16000 -#else // 48K by default -#define SAMPLE_RATE_RECV 48000 -#define SAMPLE_RATE_SEND 48000 -#endif - -// Playback sample rate -#if defined(CHIP_BEST1000) && defined(ANC_APP) -#if (SAMPLE_RATE_RECV % 8000) -#define SAMPLE_RATE_PLAYBACK 88200 -#else -#define SAMPLE_RATE_PLAYBACK 96000 -#endif -#elif defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) -#define SAMPLE_RATE_PLAYBACK 50781 -#else -#define SAMPLE_RATE_PLAYBACK SAMPLE_RATE_RECV -#endif - -// Capture sample rate -#if defined(CHIP_BEST1000) && defined(ANC_APP) -#ifdef AUD_PLL_DOUBLE -#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) -#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_PLAYBACK * 8) -#else -#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_PLAYBACK * 2) -#endif -#else // !AUD_PLL_DOUBLE -#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) -#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_PLAYBACK * 4) -#else -#define SAMPLE_RATE_CAPTURE SAMPLE_RATE_PLAYBACK -#endif -#endif // !AUD_PLL_DOUBLE -#else // !(CHIP_BEST1000 && ANC_APP) -#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) -#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_SEND * 4) -#elif defined(__AUDIO_RESAMPLE__) && defined(SW_CAPTURE_RESAMPLE) -#define SAMPLE_RATE_CAPTURE 50781 -#else -#define SAMPLE_RATE_CAPTURE SAMPLE_RATE_SEND -#endif -#endif // !(CHIP_BEST1000 && ANC_APP) - -#ifdef USB_AUDIO_32BIT -#define SAMPLE_SIZE_PLAYBACK 4 -#define SAMPLE_SIZE_RECV 4 -#elif defined(USB_AUDIO_24BIT) -#define SAMPLE_SIZE_PLAYBACK 4 -#define SAMPLE_SIZE_RECV 3 -#else -#ifdef AUDIO_PLAYBACK_24BIT -#define SAMPLE_SIZE_PLAYBACK 4 -#else -#define SAMPLE_SIZE_PLAYBACK 2 -#endif -#define SAMPLE_SIZE_RECV 2 -#endif - -#ifdef USB_AUDIO_SEND_32BIT -#define SAMPLE_SIZE_CAPTURE 4 -#define SAMPLE_SIZE_SEND 4 -#elif defined(USB_AUDIO_SEND_24BIT) -#define SAMPLE_SIZE_CAPTURE 4 -#define SAMPLE_SIZE_SEND 3 -#else -#define SAMPLE_SIZE_CAPTURE 2 -#define SAMPLE_SIZE_SEND 2 -#endif - -#define CHAN_NUM_PLAYBACK 2 -#define CHAN_NUM_RECV 2 -#ifdef USB_AUDIO_SEND_CHAN -#define CHAN_NUM_SEND USB_AUDIO_SEND_CHAN -#else -#define CHAN_NUM_SEND 2 -#endif -#if defined(CHIP_BEST1000) && defined(ANC_APP) -#define CHAN_NUM_CAPTURE 2 -#elif defined(USB_AUDIO_SPEECH) -#define CHAN_NUM_CAPTURE SPEECH_CODEC_CAPTURE_CHANNEL_NUM -#else -#define CHAN_NUM_CAPTURE CHAN_NUM_SEND -#endif - -#define BYTE_TO_SAMP_PLAYBACK(n) ((n) / SAMPLE_SIZE_PLAYBACK / CHAN_NUM_PLAYBACK) -#define SAMP_TO_BYTE_PLAYBACK(n) ((n) * SAMPLE_SIZE_PLAYBACK * CHAN_NUM_PLAYBACK) - -#define BYTE_TO_SAMP_CAPTURE(n) ((n) / SAMPLE_SIZE_CAPTURE / CHAN_NUM_CAPTURE) -#define SAMP_TO_BYTE_CAPTURE(n) ((n) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) - -#define BYTE_TO_SAMP_RECV(n) ((n) / SAMPLE_SIZE_RECV / CHAN_NUM_RECV) -#define SAMP_TO_BYTE_RECV(n) ((n) * SAMPLE_SIZE_RECV * CHAN_NUM_RECV) - -#define BYTE_TO_SAMP_SEND(n) ((n) / SAMPLE_SIZE_SEND / CHAN_NUM_SEND) -#define SAMP_TO_BYTE_SEND(n) ((n) * SAMPLE_SIZE_SEND * CHAN_NUM_SEND) - -#define SAMP_RATE_TO_FRAME_SIZE(n) (((n) + (1000 - 1)) / 1000) - -#define SAMPLE_FRAME_PLAYBACK SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_PLAYBACK) -#define SAMPLE_FRAME_CAPTURE SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_CAPTURE) - -#define SAMPLE_FRAME_RECV SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_RECV) -#define SAMPLE_FRAME_SEND SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_SEND) - -#define FRAME_SIZE_PLAYBACK SAMP_TO_BYTE_PLAYBACK(SAMPLE_FRAME_PLAYBACK) -#define FRAME_SIZE_CAPTURE SAMP_TO_BYTE_CAPTURE(SAMPLE_FRAME_CAPTURE) - -#define FRAME_SIZE_RECV SAMP_TO_BYTE_RECV(SAMPLE_FRAME_RECV) -#define FRAME_SIZE_SEND SAMP_TO_BYTE_SEND(SAMPLE_FRAME_SEND) - -#define PLAYBACK_TO_RECV_LEN(n) (SAMP_TO_BYTE_RECV((BYTE_TO_SAMP_PLAYBACK(n) * \ - (SAMPLE_RATE_RECV / 100) + (SAMPLE_RATE_PLAYBACK / 100) - 1) / (SAMPLE_RATE_PLAYBACK / 100))) -#define CAPTURE_TO_SEND_LEN(n) (SAMP_TO_BYTE_SEND((BYTE_TO_SAMP_CAPTURE(n) * \ - (SAMPLE_RATE_SEND / 100) + (SAMPLE_RATE_CAPTURE / 100) - 1) / (SAMPLE_RATE_CAPTURE / 100))) - -#ifdef USB_HIGH_SPEED -#if defined(USB_AUDIO_384K) || defined(USB_AUDIO_352_8K) -#define MAX_FRAME_SIZE_PLAYBACK (SAMP_RATE_TO_FRAME_SIZE(384000) * 4 * CHAN_NUM_PLAYBACK) -#else -#define MAX_FRAME_SIZE_PLAYBACK (SAMP_RATE_TO_FRAME_SIZE(192000) * 4 * CHAN_NUM_PLAYBACK) -#endif -#else -// Same as (SAMP_RATE_TO_FRAME_SIZE(192000) * 2 * CHAN_NUM_PLAYBACK) -#define MAX_FRAME_SIZE_PLAYBACK (SAMP_RATE_TO_FRAME_SIZE(96000) * 4 * CHAN_NUM_PLAYBACK) -#endif -#if (defined(__AUDIO_RESAMPLE__) && defined(SW_CAPTURE_RESAMPLE)) || \ - (defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) -// Fixed capture sample rate -#define MAX_FRAME_SIZE_CAPTURE (SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_CAPTURE) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) -#else -#define MAX_FRAME_SIZE_CAPTURE (SAMP_RATE_TO_FRAME_SIZE(48000) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) -#endif - -#ifdef USB_HIGH_SPEED -#if defined(USB_AUDIO_384K) || defined(USB_AUDIO_352_8K) -#define MAX_FRAME_SIZE_RECV (SAMP_RATE_TO_FRAME_SIZE(384000) * 4 * CHAN_NUM_RECV) -#else -#define MAX_FRAME_SIZE_RECV (SAMP_RATE_TO_FRAME_SIZE(192000) * 4 * CHAN_NUM_RECV) -#endif -#else -// Same as (SAMP_RATE_TO_FRAME_SIZE(192000) * 2 * CHAN_NUM_RECV) -#define MAX_FRAME_SIZE_RECV (SAMP_RATE_TO_FRAME_SIZE(96000) * 4 * CHAN_NUM_RECV) -#endif -#define MAX_FRAME_SIZE_SEND (SAMP_RATE_TO_FRAME_SIZE(48000) * SAMPLE_SIZE_SEND * CHAN_NUM_SEND) - -// ---------------- -// Buffer alignment -// ---------------- - -#define AF_DMA_LIST_CNT 4 - -#ifdef ADC_CH_SEP_BUFF -#define ADC_BURST_NUM 4 -#define ADC_ALL_CH_DMA_BURST_SIZE (ADC_BURST_NUM * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) -#define ADC_BUFF_ALIGN (ADC_ALL_CH_DMA_BURST_SIZE * AF_DMA_LIST_CNT) -#else -#define ADC_BUFF_ALIGN (4 * AF_DMA_LIST_CNT) -#endif -#if defined(__HW_FIR_DSD_PROCESS__) -// FIR DSD requires DAC buffer is aligned to 16-sample boundary for each FIR DMA process loop -#define DAC_BUFF_ALIGN (16 * SAMPLE_SIZE_PLAYBACK * CHAN_NUM_PLAYBACK * 2) -#else -#define DAC_BUFF_ALIGN (4 * AF_DMA_LIST_CNT) -#endif - -// USB buffer is split into 2 parts, and transfers from the second half (similar to PING-PONG buffer) -#ifdef USB_AUDIO_DYN_CFG -// RECV type-I frame slot (sample_size*chan_num): 2*2=4, 3*2=6, 4*2=8. The least common multiple is 24 -#define RECV_BUFF_ALIGN (2 * 24) -// SEND type-I frame slot (sample_size*chan_num): 2*2=4. The least common multiple is 4 -#define SEND_BUFF_ALIGN (2 * 4) -#else -// If usb rx/tx pool is NOT used, the buffer size should be aligned to frame packet size -#define RECV_BUFF_ALIGN SAMP_TO_BYTE_RECV(2) -#define SEND_BUFF_ALIGN SAMP_TO_BYTE_SEND(2) -#endif - -#define NON_EXP_ALIGN(val, exp) (((val) + ((exp) - 1)) / (exp) * (exp)) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tests/anc_usb/usb_vendor_msg.c b/tests/anc_usb/usb_vendor_msg.c deleted file mode 100644 index aed266e..0000000 --- a/tests/anc_usb/usb_vendor_msg.c +++ /dev/null @@ -1,261 +0,0 @@ -#ifdef _VENDOR_MSG_SUPPT_ - -#include "cmsis.h" -#include "crc32.h" -#include "hal_bootmode.h" -#include "hal_cmu.h" -#include "hal_norflash.h" -#include "hal_timer.h" -#include "hal_trace.h" -#include "pmu.h" -#include "stdlib.h" -#include "tgt_hardware.h" -#include -#include -#ifdef USB_EQ_TUNING -#include "hal_cmd.h" -#endif - -#ifdef USB_ANC_MC_EQ_TUNING -#include "anc_process.h" -#endif - -#include "usb_vendor_msg.h" - -#define SYS_CHECK_VAL "1.1" - -#define FACT_SEC_VER 2 -#define FACT_SEC_MAGIC 0xba80 - -typedef enum { - FACT_SEC_VER_MAGIC, - FACT_SEC_CRC, - - FACT_SEC_DATA_START, - FACT_SEC_SEQ = FACT_SEC_DATA_START, - FACT_SEC_PROD_SN, - FACT_SEC_END = FACT_SEC_PROD_SN + 8, - - FACT_SEC_NUM = 256 -} FACT_SEC_E; - -typedef enum { - PC_TOOL_CMD_IDLE, - PC_TOOL_CMD_GET_FW_VER, - PC_TOOL_CMD_GET_PROD_SN, - // QUERY_VOLTAGE, - // BURN_SN, - PC_TOOL_CMD_SYS_REBOOT, - PC_TOOL_CMD_SYS_SHUTDOWN, - PC_TOOL_CMD_PING, - PC_TOOL_CMD_CHECK, - PC_TOOL_CMD_FW_UPDATE, -#ifdef USB_EQ_TUNING - PC_TOOL_CMD_EQ_TUNING, -#endif -#ifdef USB_ANC_MC_EQ_TUNING - PC_TOOL_CMD_ANC_MC_EQ_TUNING, -#endif - PC_TOOL_CMD_NUM, -} PC_TOOL_CMD_E; - -static char *s_pc_cmd_lst[PC_TOOL_CMD_NUM] = { - " ", - "QUERY_SW_VER", - "QUERY_SN", - // "QUERY_VOL", - // "BURN_SN", - "SYS_REBOOT", - "SYS_SHUTDOWN", - "PING_THROUGH_VENDOR", - "CHECK", - "FW_UPDATE", -#ifdef USB_EQ_TUNING - "EQ<", -#endif -#ifdef USB_ANC_MC_EQ_TUNING - "ANC_MC_EQ", -#endif -}; - -static PC_TOOL_CMD_E s_cur_cmd = PC_TOOL_CMD_IDLE; - -static uint8_t *s_sn_ptr; -static uint8_t *s_fw_ver_ptr; - -static uint8_t s_sn_sz; -static uint8_t s_fw_ver_sz; - -uint8_t vendor_msg_rx_buf[VENDOR_RX_BUF_SZ]; - -extern void analog_aud_codec_mute(void); - -int WEAK vendor_get_sn_info(uint8_t **p_ptr, uint8_t *p_size) { - static const char sn[] = "SN-001"; - - *p_ptr = (uint8_t *)sn; - *p_size = sizeof(sn) - 1; - return 0; -} - -int WEAK vendor_get_fw_ver_info(uint8_t **p_ptr, uint8_t *p_size) { - static const char ver[] = "VER-001"; - - *p_ptr = (uint8_t *)ver; - *p_size = sizeof(ver) - 1; - return 0; -} - -void vendor_info_init(void) { - vendor_get_sn_info(&s_sn_ptr, &s_sn_sz); - vendor_get_fw_ver_info(&s_fw_ver_ptr, &s_fw_ver_sz); -} - -static void pc_usb_cmd_set(struct USB_AUDIO_VENDOR_MSG_T *msg) { - size_t ret; - uint8_t cmd_id = 0; - - if (0 == msg->length) - return; - - for (cmd_id = 1; cmd_id < PC_TOOL_CMD_NUM; cmd_id++) { - ret = memcmp((void *)msg->data, (void *)s_pc_cmd_lst[cmd_id], - strlen((char *)s_pc_cmd_lst[cmd_id])); - if (!ret) - break; - } - - if (cmd_id > (PC_TOOL_CMD_NUM - 1)) { - return; - } - - s_cur_cmd = cmd_id; - // TRACE(3,"%s: cmd[%s], id[%d]", __func__, s_pc_cmd_lst[cmd_id], s_cur_cmd); - msg->data += strlen((char *)s_pc_cmd_lst[cmd_id]); -#ifdef USB_ANC_MC_EQ_TUNING - msg->length -= strlen((char *)s_pc_cmd_lst[cmd_id]); -#endif - - switch (s_cur_cmd) { -#ifdef USB_EQ_TUNING - case PC_TOOL_CMD_EQ_TUNING: - hal_cmd_list_process(msg->data); - break; -#endif - -#ifdef USB_ANC_MC_EQ_TUNING - case PC_TOOL_CMD_ANC_MC_EQ_TUNING: - // TRACE(1,"recev len:%d",msg->length); - /* - TRACE(0,"***********recev test*************"); - for(int i=0;ilength;i++) - { - TRACE(2,"msg->data[%d]:0x%x",i,msg->data[i]); - } - TRACE(0,"***********recev test*************"); - */ - anc_cmd_receve_process(msg->data, msg->length); - break; -#endif - default: - break; - } -} - -static void pc_usb_cmd_exec(struct USB_AUDIO_VENDOR_MSG_T *msg) { - // TRACE(2,"%s: cmd[%d]", __func__, s_cur_cmd); - static const char *s_str_ret1 = "1"; -#ifdef USB_EQ_TUNING - static const char *s_str_ret0 = "0"; -#endif - static const char *s_str_failure = "failure"; - - switch (s_cur_cmd) { - case PC_TOOL_CMD_GET_FW_VER: - msg->data = s_fw_ver_ptr; - msg->length = strlen((char *)s_fw_ver_ptr); - break; - - case PC_TOOL_CMD_GET_PROD_SN: - msg->data = s_sn_ptr; - msg->length = strlen((char *)s_sn_ptr); - break; - - case PC_TOOL_CMD_SYS_REBOOT: - // TRACE(0,"-> cmd_exec: reboot....."); - hal_sys_timer_delay(MS_TO_TICKS(500)); - hal_cmu_sys_reboot(); - break; - - case PC_TOOL_CMD_SYS_SHUTDOWN: - pmu_shutdown(); - break; - - case PC_TOOL_CMD_PING: - msg->data = (uint8_t *)s_pc_cmd_lst[PC_TOOL_CMD_PING]; - msg->length = (uint32_t)strlen((const char *)msg->data); - break; - - case PC_TOOL_CMD_CHECK: - msg->data = (uint8_t *)SYS_CHECK_VAL; - msg->length = strlen((char *)SYS_CHECK_VAL); - break; - - case PC_TOOL_CMD_FW_UPDATE: - hal_sw_bootmode_clear(1 << 8); // to clear HAL_SW_BOOTMODE_FORCE_UART_DLD - hal_sw_bootmode_set(1 << 7); // to set HAL_SW_BOOTMODE_FORCE_USB_DLD -#ifdef TGT_PLL_FREQ - extern void pll_config_update(uint32_t); - pll_config_update(960000000); -#endif - analog_aud_codec_mute(); - msg->data = (uint8_t *)s_str_ret1; - msg->length = (uint32_t)strlen(s_str_ret1); - break; - -#ifdef USB_EQ_TUNING - case PC_TOOL_CMD_EQ_TUNING: - hal_cmd_tx_process(&msg->data, &msg->length); - if (!msg->length) { - msg->data = (uint8_t *)s_str_ret0; - msg->length = (uint32_t)strlen(s_str_ret0); - } - break; -#endif - -#ifdef USB_ANC_MC_EQ_TUNING - case PC_TOOL_CMD_ANC_MC_EQ_TUNING: - anc_cmd_send_process(&msg->data, &msg->length); - TRACE(1, "sned len:%d", msg->length); - - /* TRACE(0,"***********send test*************"); - for(int i=0;ilength;i++) - { - TRACE(2,"msg->data[%d]:0x%x",i,msg->data[i]); - } - TRACE(0,"***********send test*************"); - */ - break; -#endif - - default: - msg->data = (uint8_t *)s_str_failure; - msg->length = (uint32_t)strlen(s_str_failure); - break; - } - - s_cur_cmd = PC_TOOL_CMD_IDLE; -} - -int usb_vendor_callback(struct USB_AUDIO_VENDOR_MSG_T *msg) { - - if (0 == msg->length) { - pc_usb_cmd_exec(msg); - } else { - pc_usb_cmd_set(msg); - } - - return 0; -} - -#endif diff --git a/tests/anc_usb/usb_vendor_msg.h b/tests/anc_usb/usb_vendor_msg.h deleted file mode 100644 index 6d5b009..0000000 --- a/tests/anc_usb/usb_vendor_msg.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _USB_VENDOR_MSG_H_ -#define _USB_VENDOR_MSG_H_ - -#include "usb_audio.h" - -#ifdef USB_ANC_MC_EQ_TUNING -#define VENDOR_RX_BUF_SZ 5000 -#else -#define VENDOR_RX_BUF_SZ 240 -#endif -extern uint8_t vendor_msg_rx_buf[VENDOR_RX_BUF_SZ]; - -int usb_vendor_callback (struct USB_AUDIO_VENDOR_MSG_T *msg); - -void vendor_info_init (void); - -#endif // _USB_VENDOR_MSG_H_