/*
* 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 "board.h"

// #include <rtdevice.h>
// #include <drv_usbd.h>


void usb_write_reg(uint32_t data, uint32_t *baseAddr, uint8_t offset, uint8_t dataWidth)
{
    switch (dataWidth)
    {
    case 8:
        data = (data & 0xff) << (offset * 8);
        *baseAddr &= (~(0xff << (offset * 8)));
        *baseAddr |= data;
        break;

    case 16:
        data = (data & 0xffff) << (offset * 8);
        *baseAddr &= (~(0xffff << (offset * 8)));
        *baseAddr |= data;
        break;

    case 32:
        *baseAddr = data;
        break;
    }
}


uint32_t usb_read_reg(uint32_t *baseAddr, uint8_t offset, uint8_t dataWidth)
{
    /* lzx&N SPV40的总线是32位，所以每次读地址，都是按4个字节读取数据(但是一个地址对应一个字节数据) */
    return ((*baseAddr) >> (offset * 8)) & (dataWidth == 8 ? 0xff : 0xffff);
}

/**
* @file         usb_test.c
* @brief        write Addr register
* @details      param:the USB address to be written in the register
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_faddr(uint8_t addr)
{
    usb_write_reg((uint32_t)addr, (uint32_t *)REG_FADDR, 0, 8);
}

/**
* @file         usb_test.c
* @brief        read Addr register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_faddr(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_FADDR, 0, 8);
}
/**
* @file         usb_test.c
* @brief        write POWER register
* @details      param: the command to be written in the POWER register
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_power(uint8_t command)
{
    usb_write_reg((uint32_t)command, (uint32_t *)REG_POWER, 1, 8);
}
/**
* @file         usb_test.c
* @brief        read POWER register,return 8bit
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_power(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_POWER, 1, 8);
}
/**
* @file         usb_test.c
* @brief        read Endpoints Tx Interrupt register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_intrtx(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_INTRTX, 2, 16);
}

/**
* @file         usb_test.c
* @brief        read Endpoints Rx Interrupt register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_intrrx(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_INTRRX, 0, 16);
}
/**
* @file         usb_test.c
* @brief        write Endpoints Tx Interrupt Enable register
* @details      param: tx interrupt enable bit
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_intrtxe(uint16_t intrtxe)
{
    usb_write_reg((uint32_t)intrtxe, (uint32_t *)REG_INTRTXE, 2, 16);
}

/**
* @file         usb_test.c
* @brief        read Endpoints Tx Interrupt Enable register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_intrtxe(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_INTRTXE, 2, 16);
}
/**
* @file         usb_test.c
* @brief        write Endpoints Rx Interrupt Enable register
* @details      param:decide what kind of Rx interrupt to be enable
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_intrrxe(uint16_t intrrxe)
{
    usb_write_reg((uint32_t)intrrxe, (uint32_t *)REG_INTRRXE, 0, 16);
}

/**
* @file         usb_test.c
* @brief        read Endpoints Rx Interrupt Enable register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_intrrxe(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_INTRRXE, 0, 16);
}
/**
* @file         usb_test.c
* @brief        read USB Interrupt register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_intrusb(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_INTRUSB, 2, 8);
}

/**
* @file         usb_test.c
* @brief        write USB Interrupt Enable register
* @details      param:decide which interrupt of usb interface will be enabled
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_intrusbe(uint16_t intrusbe)
{
    usb_write_reg((uint32_t)intrusbe, (uint32_t *)REG_INTRUSBE, 3, 8);
}

/**
* @file         usb_test.c
* @brief        read USB Interrupt Enable register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_intrusbe(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_INTRUSBE, 3, 8);
}
/**
* @file         usb_test.c
* @brief        read USB frame register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_frame(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_FRAME, 0, 16);
}
/**
* @file         usb_test.c
* @brief        write USB Index register
* @details      param:decide which endpoint will be selected
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_index(uint8_t index)
{
    if (index < 16)
    {
        usb_write_reg((uint32_t)index, (uint32_t *)REG_INDEX, 2, 8);
    }
}

/**
* @file         usb_test.c
* @brief        read USB index register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_index(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_INDEX, 2, 8);
}
/**
* @file         usb_test.c
* @brief        write USB test register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_testmode(uint8_t reg)
{
    usb_write_reg((uint32_t)reg, (uint32_t *)REG_TESTMODE, 3, 8);
}

/**
* @file         usb_test.c
* @brief        read USB test register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_testmode(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_TESTMODE, 3, 8);
}
/**
* @file         usb_test.c
* @brief        read USB control register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_devctl(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_DEVCTL, 0, 8);
}
/**
* @file         usb_test.c
* @brief        write USB CSR0 register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_csr0(uint16_t csr)
{
    usb_write_reg((uint32_t)csr, (uint32_t *)REG_CSR0, 2, 16);
}

/**
* @file         usb_test.c
* @brief        read USB CSR0 register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_csr0(void)
{
    return (uint8_t)(usb_read_reg((uint32_t *)REG_CSR0, 2, 16) & 0xff);
}
/**
* @file         usb_test.c
* @brief        write USB TX_CSR register
* @details      param:decide which endpoint will be selected
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_txcsr(uint16_t txcsr)
{
    usb_write_reg((uint32_t)txcsr, (uint32_t *)REG_TXCSR, 2, 16);
}

/**
* @file         usb_test.c
* @brief        read TX_CSR register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_txcsr(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_TXCSR, 2, 16);
}
/**
* @file         usb_test.c
* @brief        write USB RX_CSR register
* @details      param:rx status and control bit
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_rxcsr(uint16_t rxcsr)
{
    usb_write_reg((uint32_t)rxcsr, (uint32_t *)REG_RXCSR, 2, 16);
}

/**
* @file         usb_test.c
* @brief        read RX_CSR register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_rxcsr(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_RXCSR, 2, 16);
}
/**
* @file         usb_test.c
* @brief        read USB COUNT0 register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_count0(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_COUNT0, 0, 8);
}
/**
* @file         usb_test.c
* @brief        read USB RXCOUNT register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_rxcount(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_COUNT0, 0, 16);
}
/**
* @file         usb_test.c
* @brief        read USB CONFIGDATA register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_configdata(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_CONFIGDATA, 3, 8);
}
/**
* @file         usb_test.c
* @brief        read RXCOUNT register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_fifosize(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_FIFOSIZE, 3, 8);
}
/**
* @file         usb_test.c
* @brief        write USB TX_MAX_P register
* @details      param:decide which endpoint will be selected
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_txmax(uint16_t txmax)
{
    usb_write_reg((uint32_t)txmax, (uint32_t *)REG_TXMAXP, 0, 16);
}

/**
* @file         usb_test.c
* @brief        read TX_MAX_P register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_txmax(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_TXMAXP, 0, 16);
}



/**
* @file         usb_test.c
* @brief        write USB RX_MAX_P register
* @details      param:decide which endpoint will be selected
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_rxmax(uint16_t rxmax)
{
    usb_write_reg((uint32_t)rxmax, (uint32_t *)REG_RXMAXP, 0, 16);
}

/**
* @file         usb_test.c
* @brief        read RX_MAX_P register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_rxmax(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_RXMAXP, 0, 16);
}


/**
* @file         usb_test.c
* @brief        write TX FIFO SIZE register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_tx_fifosize(uint8_t txfifosz)
{
    usb_write_reg((uint32_t)txfifosz, (uint32_t *)REG_TXFIFOSZ, 2, 8);
}

/**
* @file         usb_test.c
* @brief        read RX FIFO SIZE register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_tx_fifosize(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_TXFIFOSZ, 2, 8);
}

/**
* @file         usb_test.c
* @brief        write RX FIFO SIZE register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_rx_fifosize(uint16_t rxfifosz)
{
    usb_write_reg((uint32_t)rxfifosz, (uint32_t *)REG_RXFIFOSZ, 3, 8);
}

/**
* @file         usb_test.c
* @brief        read TX FIFO SIZE register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint8_t usb_read_rx_fifosize(void)
{
    return (uint8_t)usb_read_reg((uint32_t *)REG_RXFIFOSZ, 3, 8);
}

/**
* @file         usb_test.c
* @brief        write TX FIFO address register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_tx_fifoadd(uint16_t txfifoadd)
{
    usb_write_reg((uint32_t)txfifoadd, (uint32_t *)REG_TXFIFOADD, 0, 16);
}

/**
* @file         usb_test.c
* @brief        read TX FIFO address register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_tx_fifoadd(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_TXFIFOADD, 0, 16);
}

/**
* @file         usb_test.c
* @brief        write RX FIFO add register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
void usb_write_rx_fifoadd(uint16_t rxfifoadd)
{
    usb_write_reg((uint32_t)rxfifoadd, (uint32_t *)REG_RXFIFOADD, 2, 16);
}

/**
* @file         usb_test.c
* @brief        read TX FIFO add register
* @details      none
* @author       XHB
* @date         2021-11-12 11:14
* @version      V0.1
* @copyright    Copyright (c) 2017-2021  SpaceTouch Inc.
*/
uint16_t usb_read_rx_fifoadd(void)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_RXFIFOADD, 2, 16);
}

void write_dma_cntl(int endp, uint16_t param)
{
    usb_write_reg(param, (uint32_t *)REG_DMA_CNTL(endp - 1), 0, 16);
}

uint16_t read_dma_cntl(int endp)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_DMA_CNTL(endp - 1), 0, 16);
}

void write_dma_addr(int endp, uint32_t param)
{
    usb_write_reg(param, (uint32_t *)REG_DMA_ADDR(endp - 1), 0, 32);
}

uint16_t read_dma_addr(int endp)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_DMA_ADDR(endp - 1), 0, 32);
}

void write_dma_count(int endp, uint32_t param)
{
    usb_write_reg(param, (uint32_t *)REG_DMA_COUNT(endp - 1), 0, 32);
}

uint16_t read_dma_count(int endp)
{
    return (uint16_t)usb_read_reg((uint32_t *)REG_DMA_COUNT(endp - 1), 0, 32);
}
#endif
