/*
* Copyright (c) 2023-2028, SpaceTouch Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date          Author      Notes
* 2023-07-18    zhixiongl       the first version
*/
#include "platform.h"
//#include "rtconfig.h"

#include "board.h"

#if defined(USING_USBD)

#include <stdio.h>
#include <stdarg.h>

#include "hal_log.h"
#include "hal_usbd_reg.h"
#include "hal_usbd_init.h"
#include "hal_usbd.h"

#include "hal_gpio.h"
#include "hal_common.h"
#include "hal_cmu.h"
#include "system.h"
#include "brom_func.h"
#include "debug.h"
// #include <rtthread.h>
// #include <rtdevice.h>
// #include <drv_usbd.h>
// #include <usb_common.h>



struct hal_usbd_ep_cb_struct hal_usbd_cb =
{
    {0},
    {0},
};


void hal_usbd_cb_register(uint8_t ep_addr, hal_usbd_ep_cb cpcb, void *param)
{
    if (ep_addr >= USB_EP_NUM)
        return;

    if (cpcb == NULL)
        return;

    hal_usbd_cb.ep_cb[ep_addr] = cpcb;
    hal_usbd_cb.param[ep_addr] = param;
}

void hal_usbd_cb_unregister(uint8_t ep_addr)
{
    if (ep_addr >= USB_EP_NUM)
        return;

    hal_usbd_cb.ep_cb[ep_addr] = NULL;
    hal_usbd_cb.param[ep_addr] = NULL;
}

void hal_usbd_ep_function_call(uint8_t ep_addr)
{
    if (ep_addr >= USB_EP_NUM)
        return;

    if (hal_usbd_cb.ep_cb[ep_addr] == NULL)
        return;

    hal_usbd_cb.ep_cb[ep_addr](hal_usbd_cb.param[ep_addr], ep_addr);
}
/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
void hal_usbd_set_stall(uint8_t ep_addr)
{
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(ep_addr & 0x07);
    HAL_USBD_LOG("[####usb####] hal_usbd_set_stall\n");
    HAL_USBD_LOG("hal_usbd_set_stall\n");

    if ((ep_addr & 0x07) == 0x00)
    {
        //端点0
        usb_write_csr0((REG_CSR0_SERVICED_RXPKTRDY | REG_CSR0_SENDSTALL) & 0xff);
    }
    else
    {
        //其他端点
        if ((ep_addr & 0x80) == 0x80)          //USB_DIR_IN
        {
            usb_write_txcsr((usb_read_txcsr() & 0xff00) | REG_TXCSR_SENDSTALL);
        }
        else                                   //USB_DIR_OUT
        {
            usb_write_rxcsr((usb_read_rxcsr() & 0xff00) | REG_RXCSR_SENDSTALL);
        }
    }

    usb_write_index(old_INDEX);
}

/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
void hal_usbd_clear_stall(uint8_t ep_addr)
{
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(ep_addr & 0x07);
    HAL_USBD_LOG("[####usb####] hal_usbd_clear_stall\n");
    HAL_USBD_LOG("hal_usbd_clear_stall\n");

    if ((ep_addr & 0x07) == 0x00)
    {
        //端点0
        usb_write_csr0(usb_read_csr0() & (~REG_CSR0_SENDSTALL) & 0xff);
    }
    else
    {
        //其他端点
        if ((ep_addr & 0x80) == 0x80)          //USB_DIR_IN
        {
            usb_write_txcsr((usb_read_txcsr() & 0xff00) & (~ REG_TXCSR_SENDSTALL));
        }
        else                                   //USB_DIR_OUT
        {
            usb_write_rxcsr((usb_read_rxcsr() & 0xff00) & (~ REG_RXCSR_SENDSTALL));
        }
    }

    usb_write_index(old_INDEX);
}

/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
void hal_usbd_set_address(uint8_t ep_addr)
{
    delay_us(CPU_MAX_FREQ * 1000 * 1000,100); //不知道为什么需要delay，取消delay_us，将cpu主频降为180M以下也可以，否则会set_addr失败 --weijiac 2024_1107
    usb_write_faddr(ep_addr);
    HAL_USBD_LOG("[####usb####]set_address:%d\n", ep_addr);
}

/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
void hal_usbd_activate_endpoint(uint8_t ep_addr)
{
    uint16_t vINTRTXE;
    uint16_t vINTRRXE;
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(ep_addr & 0x07);
    HAL_USBD_LOG("[####usb####] hal_usbd_activate_endpoint,ep_addr:0x%04x\n", ep_addr);

    //低3位为实际地址，对应_ep_pool，高2位为方向
    if ((ep_addr & 0x80) == 0x80)          //USB_DIR_IN
    {
        vINTRTXE = usb_read_intrtxe();
        usb_write_intrtxe(vINTRTXE | (0x1 << (ep_addr & 0x07)));
    }
    else                                   //USB_DIR_OUT
    {
        vINTRRXE = usb_read_intrrxe();
        usb_write_intrrxe(vINTRRXE | (0x1 << (ep_addr & 0x07)));
    }

    usb_write_index(old_INDEX);
}

/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
void hal_usbd_deactivate_endpoint(uint8_t ep_addr)
{
    uint16_t vINTRTXE;
    uint16_t vINTRRXE;
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(ep_addr & 0x07);
    HAL_USBD_LOG("[####usb####] hal_usbd_deactivate_endpoint,ep_addr:0x%04x\n", ep_addr);

    //低3位为实际地址，对应_ep_pool，高2位为方向
    if ((ep_addr & 0x80) == 0x80)          //USB_DIR_IN
    {
        vINTRTXE = usb_read_intrtxe();
        usb_write_intrtxe(vINTRTXE & (~(0x1 << (ep_addr & 0x07))));
    }
    else                                   //USB_DIR_OUT
    {
        vINTRRXE = usb_read_intrrxe();
        usb_write_intrrxe(vINTRRXE & (~(0x1 << (ep_addr & 0x07))));
    }

    usb_write_index(old_INDEX);
}

/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
uint16_t hal_usbd_receive_count(uint8_t ep_addr)
{
    uint8_t vCOUNT0;
    uint16_t vRXCOUNT;
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(ep_addr & 0x07);

    //端点0
    if ((ep_addr & 0x07) ==  0x00)
    {
        //读出数据，清零标志位
        vCOUNT0 = usb_read_count0();
        HAL_USBD_LOG("1_g_r_c%d:%d\n", (ep_addr & 0x07), vCOUNT0);
        usb_write_index(old_INDEX);
        return vCOUNT0;
    }

    //其他端点
    //读出数据，清零标志位
    vRXCOUNT = usb_read_rxcount();
    HAL_USBD_LOG("2_g_r_c%d:%d\n", (ep_addr & 0x07), vRXCOUNT);
    usb_write_index(old_INDEX);
    return vRXCOUNT;
}

/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
uint16_t hal_usbd_receive(uint8_t ep_addr, uint8_t *pBuf)
{
    uint8_t vCOUNT0;
    uint16_t vRXCOUNT;
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(ep_addr & 0x07);

    //端点0
    if ((ep_addr & 0x07) ==  0x00)
    {
        //读出数据，清零标志位
        vCOUNT0 = usb_read_count0();
        FIFORead(0, vCOUNT0, pBuf);
#if 0
        HAL_USBD_LOG("[####usb####]vRXCOUNT%d:%d, read: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", (ep_addr & 0x07), vRXCOUNT,
                     pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7], pBuf[8], pBuf[9], pBuf[10], pBuf[11]);
#endif
        HAL_USBD_LOG("vRXC%d:%d, read\n", (ep_addr & 0x07), vCOUNT0);

        if (usb_read_csr0() & REG_CSR0_RXPKTRDY)
        {
            usb_write_csr0(usb_read_csr0() | REG_CSR0_SERVICED_RXPKTRDY);
        }

        usb_write_index(old_INDEX);
        return vCOUNT0;
    }

    //其他端点
#if 1     //不使用DMA
    //读出数据，清零标志位
    vRXCOUNT = usb_read_rxcount();

    if (vRXCOUNT > 0)
    {
        FIFORead((ep_addr & 0x07), vRXCOUNT, pBuf);
    }
    else
    {
        brom_memset(pBuf, 0, 512);
    }

#if 0
    HAL_USBD_LOG("[####usb####]vRXCOUNT%d:%d, read: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", (ep_addr & 0x07), vRXCOUNT,
                 pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7], pBuf[8], pBuf[9], pBuf[10], pBuf[11]);
#endif
    HAL_USBD_LOG("vRXC%d:%d, read\n", (ep_addr & 0x07), vRXCOUNT);
    usb_write_rxcsr(usb_read_rxcsr() & 0xff00);
#endif
#if 0     //使用DMA
    usb_dma_config.len = nBytes;
    (usb_play_status.fifo_count_length) = USB_OTHER_FIFO_LENGTH;
    usb_dma_config.startAddress = (uint32_t)(0x200d0020 + (pbostate->byEP) * 4);
    usb_dma_config.dstAddress = (uint32_t)(data_usb_rx_test);
    usb_dma_Init(&usb_dma_config);
    DMA_Cmd(DMA_USB_PLAY_CHANNEL, ENABLE);
    byOutCSR = usb_read_rxcsr();
    byOutCSR |= ((M_REG_OUTCSRH_DMAREQENAB | M_REG_OUTCSRH_DMAREQMODE0)) << 8;
    usb_write_rxcsr(byOutCSR);
#endif
    usb_write_index(old_INDEX);
    return vRXCOUNT;
}

/**
* @brief
* @details
* @param[in]
* @return
* @note
*/
void hal_usbd_send(uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
{
    uint16_t    vCSR0;
    uint16_t    vTXCSR;
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(ep_addr & 0x07);

    //端点0
    if ((ep_addr & 0x07) ==  0x00)
    {
        if (len > 0)
        {
            FIFOWrite(0, len, pBuf);
        }

        //如果len==M_EP0_MAXP，认为是需要分包，所以不设置REG_CSR0_DATAEND
        if (len == M_EP0_MAXP)
        {
            vCSR0 = REG_CSR0_TXPKTRDY;
        }
        else
        {
            vCSR0 = REG_CSR0_TXPKTRDY | REG_CSR0_DATAEND;
        }

        usb_write_csr0(vCSR0);
        HAL_USBD_LOG("sd0 len:%d\n", len);
        usb_write_index(old_INDEX);
        return;
    }

    //其他端点
#if 0
    HAL_USBD_LOG("[####usb####]hal_usbd_send:len:%d, 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", len,
                 pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]);
#endif
    HAL_USBD_LOG("sd%d len:%d\n", (ep_addr & 0x07), len);
#if 1     //不使用DMA

    /* Wait for packet sent */
    do
    {
        vTXCSR = usb_read_txcsr() & 0xff;
    }
    while (vTXCSR & REG_TXCSR_TXPKTRDY);

    if (len > 0)
    {
        FIFOWrite((ep_addr & 0x07), len, pBuf);
    }

    vTXCSR = REG_TXCSR_TXPKTRDY;
    usb_write_txcsr((usb_read_txcsr() & 0xff00) | vTXCSR);
#endif
#if 0     //使用DMA
    usb_dma_config.len = pbistate->nBytesLeft;
    usb_dma_config.startAddress = (uint32_t)pbistate->pData;
    usb_dma_config.dstAddress = (uint32_t)(0x200d0020 + (pbistate->byEP) * 4);
    usb_dma_Init(&usb_dma_config);
    DMA_Cmd(DMA_USB_RECORD_CHANNEL, ENABLE);
    /* for packet larger than nMaxP, use DMA if enabled. */
    usb_write_txcsr(usb_read_txcsr() | REG_TXCSR_DMAREQ_ENAB);
    //后续会在DMA中断中，设置REG_TXCSR_TXPKTRDY？
#endif
    usb_write_index(old_INDEX);
    return;
}

/**
* @brief
* @details
* @param[in]
* @return
* @note         None
*/
void endpoint_IN_init(uint8_t address, uint8_t type)
{
    uint16_t vTXCSR;
    uint16_t vINTRTXE;
    uint8_t     old_INDEX;
    /* Reset endpoint */
    old_INDEX = usb_read_index();
    usb_write_index(address);
    vTXCSR = REG_TXCSR_CLRDATATOG | REG_TXCSR_FLUSHFIFO | REG_TXCSR_SERVICED_MODE;

    switch (type)
    {
    case TYPE_ISO:
        vTXCSR |= REG_TXCSR_SERVICED_ISO;
        break;

    case TYPE_BULK:
        vTXCSR &= (~REG_TXCSR_SERVICED_ISO);
        break;

    case TYPE_INT:
        vTXCSR &= (~REG_TXCSR_SERVICED_ISO);
        break;

    default:
        break;
    }

    usb_write_txcsr(vTXCSR);
    vINTRTXE = usb_read_intrtxe();
    usb_write_intrtxe(vINTRTXE | (0x1 << address));
    usb_write_txmax(512);
    usb_write_tx_fifosize(0x6);
    usb_write_tx_fifoadd(((64 + ((address - 1) << 9)) >> 3));
    usb_write_index(old_INDEX);
    return;
}

/**
* @brief
* @details
* @param[in]
* @return
* @note         None
*/
void endpoint_OUT_init(uint8_t address, uint8_t type)
{
    uint16_t vRXCSR = 0;
    uint16_t vINTRRXE;
    uint8_t     old_INDEX;
    old_INDEX = usb_read_index();
    usb_write_index(address);
    vRXCSR = REG_RXCSR_CLRDATATOG | REG_RXCSR_FLUSHFIFO;

    switch (type)
    {
    case TYPE_ISO:
        vRXCSR |= REG_RXCSR_ISO;
        break;

    case TYPE_BULK:
        vRXCSR &= (~REG_RXCSR_ISO);
        break;

    case TYPE_INT:
        vRXCSR &= (~REG_RXCSR_ISO);
        break;

    default:
        break;
    }

    usb_write_rxcsr(vRXCSR);
    vINTRRXE = usb_read_intrrxe();
    usb_write_intrrxe(vINTRRXE | (0x1 << address));
    usb_write_rxmax(512);
    /* Configure FIFO size */
    /* Default FIFO 512 bytes, update later  */
    usb_write_rx_fifosize(0x6);
    usb_write_rx_fifoadd(((64 + ((address - 1) << 9)) >> 3));
    usb_write_index(old_INDEX);
    return;
}

/**
* @brief       USB Reset
* @details
* @param[in]
* @return
* @note         None
*/
void USBReset(void)
{
    if (rt_usb_device_init() != 0)
        debug("rt_usb_device_init return err \n\r");

    return;
}

/****************************************
  FIFORead
  The following example assumes a 16-bit bus.
  it should be modified for 32-bit accesses or if DMA is used
****************************************/
void FIFORead(int nEP, int nBytes, void *pDst)
{
    //根据端点，偏移得到目标FIFO地址，同一个端点的发送和接收方向的FIFO地址是一样的。
    int nAddr;
    int nDwords;
    uint32_t *pw;
    uint8_t *pb;

    if (nBytes)
    {
        //内存对齐处理??
        if ((uint32_t)pDst & 0x3)
        {
            nAddr = REG_FIFO_EP0 + (nEP << 2);
            pb = (uint8_t *) pDst;

            while (nBytes--)
            {
                *pb++ = *((uint8_t *) nAddr);
            }
        }
        else
        {
            nAddr = REG_FIFO_EP0 + (nEP << 2);
            nDwords = nBytes >> 2;
            pw = (uint32_t *) pDst;

            while (nDwords)
            {
                *pw++ = *((uint32_t *) nAddr);
                nDwords --;
            }

            if (nBytes & 0x02)
            {
                * ((uint16_t *) pw) = * ((uint16_t *) nAddr);

                if (nBytes & 0x01)
                    * (((uint8_t *) pw) + 2) = * ((uint8_t *) nAddr);
            }
            else if (nBytes & 0x01)
            {
                * ((uint8_t *) pw) = * ((uint8_t *) nAddr);
            }
        }
    }

    return;
}

/****************************************
  FIFOWrite
  The following example assumes a 16-bit bus.
  it should be modified for 32-bit accesses or if DMA is used
****************************************/
void FIFOWrite(int nEP, int nBytes, void *pSrc)
{
    //根据端点，偏移得到目标FIFO地址，同一个端点的发送和接收方向的FIFO地址是一样的。
#if 0
    uint8_t *pdata = (uint8_t *) pSrc;
    USB_DBG("FIFOWrite (EP%d, %d bytes): 0x%02x 0x%02x 0x%02x 0x%02x"
            " 0x%02x 0x%02x 0x%02x 0x%02x\n", nEP, nBytes,
            pdata[0], pdata[1], pdata[2], pdata[3],
            pdata[4], pdata[5], pdata[6], pdata[7]);
#endif
    int nAddr;
    int nDwords;
    uint32_t *pdw;
    uint8_t *pdb;

    if (nBytes)
    {
        nAddr = REG_FIFO_EP0 + (nEP << 2);

        //内存对齐处理??
        if ((uint32_t)pSrc & 0x3)
        {
            pdb = (uint8_t *) pSrc;

            while (nBytes)
            {
                * ((uint8_t *) nAddr) = * pdb++;
                nBytes--;
            }
        }
        else
        {
            nDwords = nBytes >> 2;
            pdw = (uint32_t *) pSrc;

            while (nDwords)
            {
                * ((uint32_t *) nAddr) = * pdw++;
                nDwords --;
            }

            if (nBytes & 0x2)
            {
                * ((uint16_t *) nAddr) = * ((uint16_t *) pdw);

                if (nBytes & 0x1)
                    * ((uint8_t *) nAddr) = * (((uint8_t *) pdw) + 2);

//                if(nBytes & 0x1){
//                  * ((uint32_t *) nAddr) = (* pdw);
//                }else{
//                  * ((uint32_t *) nAddr) = * pdw;
//                }
            }
            else if (nBytes & 0x1)
                * ((uint8_t *) nAddr) = * ((uint8_t *) pdw);

//              * ((uint32_t *) nAddr) = (*pdw) & 0xff;
        }
    }

    return;
}

/**
* @brief        Soft disconnect
* @details
* @param[in]
* @return
* @note         None
*/
void usbhsfc_softdiscon(void)
{
    uint16_t vPOWER = usb_read_power();
    vPOWER &= ~(REG_POWER_SOFT_CONN);
    usb_write_power(vPOWER);
}

/**
* @brief        Soft connect
* @details
* @param[in]
* @return
* @note         None
*/
void usbhsfc_softcon(void)
{
    uint16_t vPOWER = usb_read_power();
    vPOWER |= (REG_POWER_SOFT_CONN);
    usb_write_power(vPOWER);
}


/**
* @brief
* @details
* @param[in]
* @return
* @note         None
*/
// void usbhsfc_intr()
// {
//     // rt_kprintf("usb_intr s %d\n\r",DEV_MTIME->MTIMECMP_L/24000);
//     uint8_t     vINTRUSB;
//     uint16_t    vINTRTX;
//     uint16_t    vINTRRX;
//     uint8_t     vCSR0, vCOUNT0;
//     uint16_t    vRXCOUNT;

//  uint8_t     old_INDEX;
//     /* Read interrupt registers */
//     vINTRUSB  = usb_read_intrusb();
//     vINTRTX   = usb_read_intrtx();
//     vINTRRX  = usb_read_intrrx();

//     // rt_kprintf("vINTRUSB 0x%02x\n\r",vINTRUSB);
//     /* Check for system interrupts */
//     if (vINTRUSB & REG_INTRUSB_RESET)
//     {
//         rt_kprintf("get reset intr \n\r");
//         USBReset();
//         *(volatile uint32_t *)(0x20006000) &= ~((1 << 7)); //USB_PHY_CTRL0
//         usb_write_intrusbe(0x07);
//         usb_write_power(0x71);
//         rt_usbd_reset_handler(&spv40_usb);
//         HAL_USBD_LOG("[####usb####]reset!\n");
//         HAL_USBD_LOG("reset\n");
//         // rt_kprintf("[####usb####]reset!\n");
//         // rt_kprintf("reset\n");
//     }

//     if (vINTRUSB & REG_INTRUSB_CONN)
//     {
//         rt_kprintf("con\n\r");
//         rt_usbd_connect_handler(&spv40_usb);
//         HAL_USBD_LOG("[####usb####] rt_usbd_connect_handler(&spv40_usb)\n");
//         HAL_USBD_LOG("connect ! \n\r");
//     }

//     if (vINTRUSB & REG_INTRUSB_DISCON)
//     {
//         rt_kprintf("discon\n\r");
//         rt_usbd_disconnect_handler(&spv40_usb);
//         HAL_USBD_LOG("[####usb####] rt_usbd_disconnect_handler(&spv40_usb)\n");
//     }

//     if (vINTRUSB & REG_INTRUSB_SOF)
//     {
//         //rt_kprintf("sof\n\r");
//         rt_usbd_sof_handler(&spv40_usb);
//         HAL_USBD_LOG("[####usb####]  rt_usbd_sof_handler(&spv40_usb)\n");
//         //HAL_USBD_LOG("[####usb####]sof!\n");
//     }

//     /* Check for suspend mode */
//     if (vINTRUSB & REG_INTRUSB_SUSPEND)
//     {
//         //NULL
//         rt_kprintf("susp\n\r");
//         usbd_disconnect();
//         HAL_USBD_LOG("[####usb####]  usbd_disconnect()\n");
//         //HAL_USBD_LOG("*******************usb suspend*****************\n");
//     }

//     /* Check for resume from suspend mode */
//     if (vINTRUSB & REG_INTRUSB_RESUME)
//     {
//         //NULL
//         //AON_OSC->XTAL_CTL |= 0x01;
//         //rt_kprintf("resu\n\r");
//     }

//     /* Check for endpoint 0 interrupt */
//     if (vINTRTX & REG_INTRTX_EP(0))
//     {
//         //rt_kprintf("ep0 \n\r");
//      old_INDEX = usb_read_index();
//         usb_write_index(0x0);
//         vCOUNT0 = usb_read_count0();    //count0 指endpoint0 fifo中存在的字节数

//         if (vCOUNT0 > 0)
//         {
//             if(ep0_intr_class && (vCOUNT0!=8))
//             {
//                 ep0_intr_class = 0;
//                 rt_usbd_ep0_out_handler(&spv40_usb, vCOUNT0);

//             }

//             else
//             {
//             ep0_intr_class = 0;
//             FIFORead(0, vCOUNT0, usb_setup_data);

//             if (usb_read_csr0() & REG_CSR0_RXPKTRDY)
//             {
//                 usb_write_csr0(usb_read_csr0() | REG_CSR0_SERVICED_RXPKTRDY);
//             }

// #if 0
//             HAL_USBD_LOG("[####usb####]vCOUNT0:%d, EP0 read: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", vCOUNT0,
//                          usb_setup_data[0], usb_setup_data[1], usb_setup_data[2], usb_setup_data[3], usb_setup_data[4], usb_setup_data[5], usb_setup_data[6], usb_setup_data[7]);
// #endif
//             rt_usbd_ep0_setup_handler(&spv40_usb, (struct urequest *)usb_setup_data);
//             HAL_USBD_LOG("vCOUNT0 = %d \n\r",vCOUNT0);
//             HAL_USBD_LOG("usb_setup_data->request_type = %d \n\r",((struct urequest *)usb_setup_data)->request_type);
//             HAL_USBD_LOG("usb_setup_data->bRequest = %d \n\r",((struct urequest *)usb_setup_data)->bRequest);
//             HAL_USBD_LOG("usb_setup_data->wValue = %d \n\r",((struct urequest *)usb_setup_data)->wValue);
//             HAL_USBD_LOG("usb_setup_data->wIndex = %d \n\r",((struct urequest *)usb_setup_data)->wIndex);
//             HAL_USBD_LOG("usb_setup_data->wLength = %d \n\r",((struct urequest *)usb_setup_data)->wLength);
//             if(((struct urequest *)usb_setup_data)->wLength && !(((struct urequest *)usb_setup_data)->request_type& 0x80))
//             {
//                 ep0_intr_class = 1;
//             }
//             // rt_kprintf("vCOUNT0 = %d \n\r",vCOUNT0);
//             // rt_kprintf("usb_setup_data->request_type = %d \n\r",((struct urequest *)usb_setup_data)->request_type);
//             // rt_kprintf("usb_setup_data->bRequest = %d \n\r",((struct urequest *)usb_setup_data)->bRequest);
//             // rt_kprintf("usb_setup_data->wValue = %d \n\r",((struct urequest *)usb_setup_data)->wValue);
//             // rt_kprintf("usb_setup_data->wIndex = %d \n\r",((struct urequest *)usb_setup_data)->wIndex);
//             // rt_kprintf("usb_setup_data->wLength = %d \n\r",((struct urequest *)usb_setup_data)->wLength);
//             }
//         }
//         else
//         {
//             rt_usbd_ep0_in_handler(&spv40_usb);

//             if (usb_read_csr0() & REG_CSR0_RXPKTRDY)
//             {
//                 usb_write_csr0(usb_read_csr0() | REG_CSR0_SERVICED_RXPKTRDY);
//             }
//         }

//         /* Check for SentStall */
//         vCSR0 = usb_read_csr0();

//         if (vCSR0 & REG_CSR0_SENTSTALL)
//         {
//             HAL_USBD_LOG("SENTSTALL\n");
//             usb_write_csr0((vCSR0 & ~REG_CSR0_SENTSTALL) & 0xff);
//         }

//         /* Check for SetupEnd */
//         vCSR0 = usb_read_csr0();

//         if (vCSR0 & REG_CSR0_SETUPEND)
//         {
//             usb_write_csr0((vCSR0 | REG_CSR0_SERVICED_SETUPEND) & 0xff);
//         }

//         usb_write_index(old_INDEX);
//     }


//     if (vINTRTX & (0x01 << 0x1))
//     {
//         //rt_kprintf("ep1 \n\r");
//         //rt_usbd_ep_in_handler(&spv40_usb, USB_DIR_IN | 0x1, 0);
//         hal_usbd_ep_function_call(1);
//         HAL_USBD_LOG("in_h ep:%d\n", 0x1);
//     }
//     if (vINTRTX & (0x01 << 0x2))
//     {
//         //rt_kprintf("ep1 \n\r");
//         //rt_usbd_ep_in_handler(&spv40_usb, USB_DIR_IN | 0x2, 0);
//         //rt_kprintf("2\n\r");
//         hal_usbd_ep_function_call(2);
//         HAL_USBD_LOG("in_h ep:%d\n", 0x2);
//     }

//     if (vINTRTX & (0x01 << 0x3))
//     {
//         rt_kprintf("ep3 tx\n\r");
//         rt_usbd_ep_in_handler(&spv40_usb, USB_DIR_IN | 0x3, 0);
//         hal_usbd_ep_function_call(3);
//         HAL_USBD_LOG("in_h ep:%d\n", 0x3);
//     }
//     if (vINTRTX & (0x01 << 0x4))
//     {
//         rt_kprintf("ep3 tx\n\r");
//         rt_usbd_ep_in_handler(&spv40_usb, USB_DIR_IN | 0x3, 0);
//         hal_usbd_ep_function_call(4);
//         HAL_USBD_LOG("in_h ep:%d\n", 0x4);
//     }

//     if (vINTRTX & (0x01 << 0x5))
//     {
//         rt_usbd_ep_in_handler(&spv40_usb, USB_DIR_IN | 0x5, 0);
//         hal_usbd_ep_function_call(5);
//         HAL_USBD_LOG("in_h ep:%d\n", 0x5);
//     }
//     if (vINTRTX & (0x01 << 0x6))
//     {
//         rt_usbd_ep_in_handler(&spv40_usb, USB_DIR_IN | 0x6, 0);
//         hal_usbd_ep_function_call(6);
//         HAL_USBD_LOG("in_h ep:%d\n", 0x6);
//     }


//     if (vINTRRX & (0x01 << 0x2))
//     {
//         //rt_kprintf("ep2 \n\r");
//      old_INDEX = usb_read_index();
//         usb_write_index(0x2);
//         vRXCOUNT = usb_read_rxcount();
//         rt_usbd_ep_out_handler(&spv40_usb, USB_DIR_OUT | 0x2, 0);
//         HAL_USBD_LOG("out_h ep:%d,vC:%d\n", 0x2, vRXCOUNT);
//         usb_write_index(old_INDEX);
//     }

//     if (vINTRRX & (0x01 << 0x3))
//     {
//         //rt_kprintf("ep3 rx \n\r");
//      old_INDEX = usb_read_index();
//         usb_write_index(0x3);
//         vRXCOUNT = usb_read_rxcount();
//         rt_usbd_ep_out_handler(&spv40_usb, USB_DIR_OUT | 0x3, 0);
//         HAL_USBD_LOG("out_h ep:%d,vC:%d\n", 0x3, vRXCOUNT);
//         usb_write_index(old_INDEX);
//      }
//     if (vINTRRX & (0x01 << 0x4))
//     {
//         //rt_kprintf("ep4 \n\r");
//      old_INDEX = usb_read_index();
//         usb_write_index(0x4);
//         vRXCOUNT = usb_read_rxcount();
//         rt_usbd_ep_out_handler(&spv40_usb, USB_DIR_OUT | 0x4, 0);
//         HAL_USBD_LOG("out_h ep:%d,vC:%d\n", 0x4, vRXCOUNT);
//         usb_write_index(old_INDEX);
//     }

//     if (vINTRRX & (0x01 << 0x6))
//     {
//         //rt_kprintf("ep6 \n\r");
//      old_INDEX = usb_read_index();
//         usb_write_index(0x6);
//         vRXCOUNT = usb_read_rxcount();
//         rt_usbd_ep_out_handler(&spv40_usb, USB_DIR_OUT | 0x6, 0);
//         HAL_USBD_LOG("out_h ep:%d,vC:%d\n", 0x6, vRXCOUNT);
//         hal_usbd_ep_function_call(6);
//         usb_write_index(old_INDEX);
//     }


//     //rt_kprintf("usb_intr e %d\n\r",DEV_MTIME->MTIMECMP_L/24000);
//     return;
// }

/******************************************USB Interrupt Handler***************************************/
//#define   read_mcycle()       ((uint64_t (*)(void))0x80694)()
/**
* @brief
* @details
* @param[in]
* @return
* @note         None
*/
void usb_mac_irq_handler()
{
    usbhsfc_intr();
}

/**
* @brief
* @details
* @param[in]
* @return
* @note         None
*/
void usb_dma_irq_handler()
{
}

#endif
