/******************************************************************************
 * @file     usbd_audio.h
 * @brief    NuMicro series USB driver header file
 *
 * @copyright SPDX-License-Identifier: Apache-2.0
 * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
 ******************************************************************************/
#ifndef __USBD_UAC_H__
#define __USBD_UAC_H__

#define NAU8822     0

/* Define the vendor id and product id */
#define USBD_VID        0x0416
#define USBD_PID        0x1284

#define AUDIO_RATE  AUDIO_RATE_48K

#define AUDIO_RATE_48K   48000       /* The audo play sampling rate. The setting is 48KHz */
#define AUDIO_RATE_96K   96000       /* The audo play sampling rate. The setting is 96KHz */
#define AUDIO_RATE_441K  44100       /* The audo play sampling rate. The setting is 44.1KHz */

/*!<Define Audio information */
#define PLAY_CHANNELS   2
#define PLAY_BIT_RATE   0x10    /* 16-bit data rate */

#define REC_CHANNELS    2
#define REC_BIT_RATE    0x10    /* 16-bit data rate */

#define REC_FEATURE_UNITID      0x05
#define PLAY_FEATURE_UNITID     0x06

#define BUFF_LEN    800

/* Define Descriptor information */
#if(PLAY_CHANNELS == 1)
    #define PLAY_CH_CFG     1
    #define REC_CH_CFG      0
#endif
#if(PLAY_CHANNELS == 2)
    #define PLAY_CH_CFG     3
    #define REC_CH_CFG      3
#endif

/********************************************/
/* Audio Class Current State                */
/********************************************/
/*!<Define Audio Class Current State */
#define UAC_STOP_AUDIO_RECORD           0
#define UAC_START_AUDIO_RECORD          1
#define UAC_PROCESSING_AUDIO_RECORD     2
#define UAC_BUSY_AUDIO_RECORD           3

/***************************************************/
/*      Audio Class-Specific Request Codes         */
/***************************************************/
/*!<Define Audio Class Specific Request */
#define UAC_REQUEST_CODE_UNDEFINED  0x00
#define UAC_SET_CUR                 0x01
#define UAC_GET_CUR                 0x81
#define UAC_SET_MIN                 0x02
#define UAC_GET_MIN                 0x82
#define UAC_SET_MAX                 0x03
#define UAC_GET_MAX                 0x83
#define UAC_SET_RES                 0x04
#define UAC_GET_RES                 0x84
#define UAC_SET_MEM                 0x05
#define UAC_GET_MEM                 0x85
#define UAC_GET_STAT                0xFF

#define MUTE_CONTROL                0x01
#define VOLUME_CONTROL              0x02

/*-------------------------------------------------------------*/
/* Define EP maximum packet size */
#define EP0_MAX_PKT_SIZE    64
#define EP1_MAX_PKT_SIZE    EP0_MAX_PKT_SIZE
#define EP2_MAX_PKT_SIZE    384 //(AUDIO_RATE*REC_CHANNELS*2/1000)
#define EP3_MAX_PKT_SIZE    384 //(AUDIO_RATE*PLAY_CHANNELS*2/1000)

#define SETUP_BUF_BASE      0
#define SETUP_BUF_LEN       8
#define EP0_BUF_BASE        (SETUP_BUF_BASE + SETUP_BUF_LEN)
#define EP0_BUF_LEN         EP0_MAX_PKT_SIZE
#define EP1_BUF_BASE        (SETUP_BUF_BASE + SETUP_BUF_LEN)
#define EP1_BUF_LEN         EP1_MAX_PKT_SIZE
#define EP2_BUF_BASE        (EP1_BUF_BASE + EP1_BUF_LEN)
#define EP2_BUF_LEN         EP2_MAX_PKT_SIZE
#define EP3_BUF_BASE        (EP2_BUF_BASE + EP2_BUF_LEN)
#define EP3_BUF_LEN         EP3_MAX_PKT_SIZE

/* Define the interrupt In EP number */
#define ISO_IN_EP_NUM    0x01
#define ISO_OUT_EP_NUM   0x02

#define PDMA_TXBUFFER_CNT     3
#define PDMA_RXBUFFER_CNT     4

#define PDMA_I2S_TX_CH  1
#define PDMA_I2S_RX_CH  2

/* For I2C transfer */
typedef enum
{
    E_RS_NONE,          // no re-sampling
    E_RS_UP,            // up sampling
    E_RS_DOWN           // down sampling
} RESAMPLE_STATE_T;


/*-------------------------------------------------------------*/
extern uint32_t volatile g_u32BuffLen, g_u32RxBuffLen;
extern uint32_t g_usbd_UsbAudioState;
extern volatile uint8_t g_u8AudioPlaying;
extern volatile uint8_t g_u8TxDataCntInBuffer;
extern uint32_t volatile g_usbd_SampleRate;

extern uint32_t g_au32PcmPlayBuff[PDMA_TXBUFFER_CNT][BUFF_LEN];
extern uint8_t g_au8PcmRecBuff[PDMA_RXBUFFER_CNT][BUFF_LEN];
extern uint8_t g_au8PcmRxBufFull[PDMA_RXBUFFER_CNT];
extern volatile uint8_t g_u8PDMATxIdx;
extern volatile uint8_t g_u8PDMARxIdx;

void UAC_DeviceEnable(uint32_t u32IsPlay);
void UAC_DeviceDisable(uint32_t u32IsPlay);
void UAC_SendRecData(void);
void UAC_GetPlayData(uint8_t *pu8Src, uint32_t u32Samples);

void AudioStartPlay(uint32_t u32SampleRate);
void AudioStartRecord(uint32_t u32SampleRate);
/*-------------------------------------------------------------*/
void UAC_Init(void);
void UAC_ClassRequest(void);
void UAC_SetInterface(uint32_t u32AltInterface);

void EP2_Handler(void);
void EP3_Handler(void);
void timer_init(void);
void AdjustCodecPll(RESAMPLE_STATE_T r);
#if NAU8822
    void NAU8822_Setup(void);
    void NAU8822_ConfigSampleRate(uint32_t u32SampleRate);
    void I2C_WriteNAU8822(uint8_t u8Addr, uint16_t u16Data);
    void RecoveryFromArbLost(void);
#else
    void NAU88L25_Reset(void);
    void NAU88L25_Setup(void);
    void NAU88L25_ConfigSampleRate(uint32_t u32SampleRate);
    uint8_t I2C_WriteNAU88L25(uint16_t u16Addr, uint16_t u16Dat);
    uint8_t I2C_WriteMultiByteforNAU88L25(uint8_t u8ChipAddr, uint16_t u16SubAddr, const uint8_t *p, uint32_t u32Len);
#endif

typedef struct dma_desc_t
{
    uint32_t ctl;
    uint32_t src;
    uint32_t dest;
    uint32_t offset;
} DMA_DESC_T;

extern void PDMA_Init(void);
extern void PDMA_WriteTxSGTable(void);
extern void PDMA_WriteRxSGTable(void);

#endif  /* __USBD_UAC_H_ */
