mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-27 17:45:13 +08:00
Merge pull request #4287 from OpenNuvoton/nuvoton
[bsp/nuvoton] Sync and update.
This commit is contained in:
@@ -44,8 +44,10 @@ static rt_uint32_t nu_crc_run(
|
||||
{
|
||||
uint32_t u32CalChecksum = 0;
|
||||
uint32_t i = 0;
|
||||
rt_err_t result;
|
||||
|
||||
rt_mutex_take(&s_CRC_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_CRC_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Configure CRC controller */
|
||||
CRC_Open(u32OpMode, u32Attr, u32Seed, CRC_CPU_WDATA_8);
|
||||
@@ -85,16 +87,22 @@ static rt_uint32_t nu_crc_run(
|
||||
|
||||
/* Get checksum value */
|
||||
u32CalChecksum = CRC_GetChecksum();
|
||||
rt_mutex_release(&s_CRC_mutex);
|
||||
|
||||
result = rt_mutex_release(&s_CRC_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return u32CalChecksum;
|
||||
}
|
||||
|
||||
rt_err_t nu_crc_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
SYS_ResetModule(CRC_RST);
|
||||
|
||||
rt_mutex_init(&s_CRC_mutex, NU_CRYPTO_CRC_NAME, RT_IPC_FLAG_FIFO);
|
||||
result = rt_mutex_init(&s_CRC_mutex, NU_CRYPTO_CRC_NAME, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,8 @@ static volatile int s_SHA_done;
|
||||
|
||||
static rt_err_t nu_crypto_init(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
/* Enable Crypto engine interrupt */
|
||||
NVIC_EnableIRQ(CRPT_IRQn);
|
||||
|
||||
@@ -89,12 +91,19 @@ static rt_err_t nu_crypto_init(void)
|
||||
SHA_ENABLE_INT(CRPT);
|
||||
|
||||
//init cipher mutex
|
||||
rt_mutex_init(&s_AES_mutex, NU_HWCRYPTO_AES_NAME, RT_IPC_FLAG_FIFO);
|
||||
rt_mutex_init(&s_TDES_mutex, NU_HWCRYPTO_TDES_NAME, RT_IPC_FLAG_FIFO);
|
||||
rt_mutex_init(&s_SHA_mutex, NU_HWCRYPTO_SHA_NAME, RT_IPC_FLAG_FIFO);
|
||||
result = rt_mutex_init(&s_AES_mutex, NU_HWCRYPTO_AES_NAME, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
result = rt_mutex_init(&s_TDES_mutex, NU_HWCRYPTO_TDES_NAME, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
result = rt_mutex_init(&s_SHA_mutex, NU_HWCRYPTO_SHA_NAME, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
#if !defined(BSP_USING_TRNG)
|
||||
PRNG_ENABLE_INT(CRPT);
|
||||
rt_mutex_init(&s_PRNG_mutex, NU_HWCRYPTO_PRNG_NAME, RT_IPC_FLAG_FIFO);
|
||||
result = rt_mutex_init(&s_PRNG_mutex, NU_HWCRYPTO_PRNG_NAME, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
@@ -146,6 +155,8 @@ static rt_err_t nu_aes_crypt_run(
|
||||
uint32_t u32DataLen
|
||||
)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
uint32_t au32SwapKey[8];
|
||||
uint32_t au32SwapIV[4];
|
||||
|
||||
@@ -171,7 +182,8 @@ static rt_err_t nu_aes_crypt_run(
|
||||
au32SwapIV[2] = nu_get32_be(&pu8IV[8]);
|
||||
au32SwapIV[3] = nu_get32_be(&pu8IV[12]);
|
||||
|
||||
rt_mutex_take(&s_AES_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_AES_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
//Using Channel 0
|
||||
AES_Open(CRPT, 0, bEncrypt, u32OpMode, u32KeySize, AES_IN_OUT_SWAP);
|
||||
@@ -186,7 +198,8 @@ static rt_err_t nu_aes_crypt_run(
|
||||
AES_Start(CRPT, 0, CRYPTO_DMA_ONE_SHOT);
|
||||
while (!s_AES_done) {};
|
||||
|
||||
rt_mutex_release(&s_AES_mutex);
|
||||
result = rt_mutex_release(&s_AES_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
@@ -195,19 +208,26 @@ static rt_err_t nu_aes_crypt_run(
|
||||
//Using PRNG instead of TRNG
|
||||
static void nu_prng_open(uint32_t u32Seed)
|
||||
{
|
||||
rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
//Open PRNG 64 bits. But always return 32 bits
|
||||
PRNG_Open(CRPT, PRNG_KEY_SIZE_64, PRNG_SEED_RELOAD, u32Seed);
|
||||
|
||||
rt_mutex_release(&s_PRNG_mutex);
|
||||
result = rt_mutex_release(&s_PRNG_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
}
|
||||
|
||||
static rt_uint32_t nu_prng_run(void)
|
||||
{
|
||||
rt_err_t result;
|
||||
uint32_t au32RNGValue[2];
|
||||
|
||||
rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
s_PRNG_done = 0;
|
||||
PRNG_Start(CRPT);
|
||||
@@ -215,7 +235,9 @@ static rt_uint32_t nu_prng_run(void)
|
||||
|
||||
PRNG_Read(CRPT, au32RNGValue);
|
||||
|
||||
rt_mutex_release(&s_PRNG_mutex);
|
||||
result = rt_mutex_release(&s_PRNG_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return au32RNGValue[0];
|
||||
}
|
||||
|
||||
@@ -356,6 +378,8 @@ static rt_err_t nu_des_crypt_run(
|
||||
uint32_t u32DataLen
|
||||
)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
uint32_t au32SwapKey[3][2];
|
||||
uint32_t au32SwapIV[2];
|
||||
|
||||
@@ -373,7 +397,8 @@ static rt_err_t nu_des_crypt_run(
|
||||
au32SwapIV[0] = nu_get32_be(&pu8IV[0]);
|
||||
au32SwapIV[1] = nu_get32_be(&pu8IV[4]);
|
||||
|
||||
rt_mutex_take(&s_TDES_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_TDES_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
//Using Channel 0
|
||||
TDES_Open(CRPT, 0, bEncrypt, (u32OpMode & CRPT_TDES_CTL_TMODE_Msk), u32KeySize, u32OpMode, TDES_IN_OUT_WHL_SWAP);
|
||||
@@ -388,7 +413,8 @@ static rt_err_t nu_des_crypt_run(
|
||||
TDES_Start(CRPT, 0, CRYPTO_DMA_ONE_SHOT);
|
||||
while (!s_TDES_done) {};
|
||||
|
||||
rt_mutex_release(&s_TDES_mutex);
|
||||
result = rt_mutex_release(&s_TDES_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
@@ -534,7 +560,10 @@ static rt_err_t nu_sha_hash_run(
|
||||
uint32_t u32DataLen
|
||||
)
|
||||
{
|
||||
rt_mutex_take(&s_SHA_mutex, RT_WAITING_FOREVER);
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_mutex_take(&s_SHA_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
uint8_t *pu8SrcAddr = (uint8_t *)pu8InData;
|
||||
uint32_t u32CopyLen = 0;
|
||||
@@ -574,7 +603,10 @@ static rt_err_t nu_sha_hash_run(
|
||||
if (psSHACtx->pu8SHATempBuf == RT_NULL)
|
||||
{
|
||||
LOG_E("fun[%s] memory allocate %d bytes failed!", __FUNCTION__, psSHACtx->u32BlockSize);
|
||||
rt_mutex_release(&s_SHA_mutex);
|
||||
|
||||
result = rt_mutex_release(&s_SHA_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
@@ -602,7 +634,10 @@ static rt_err_t nu_sha_hash_run(
|
||||
if (psSHACtx->pu8SHATempBuf == RT_NULL)
|
||||
{
|
||||
LOG_E("fun[%s] memory allocate %d bytes failed!", __FUNCTION__, psSHACtx->u32BlockSize);
|
||||
rt_mutex_release(&s_SHA_mutex);
|
||||
|
||||
result = rt_mutex_release(&s_SHA_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
@@ -613,7 +648,8 @@ static rt_err_t nu_sha_hash_run(
|
||||
psSHACtx->u32SHATempBufLen += u32DataLen;
|
||||
}
|
||||
|
||||
rt_mutex_release(&s_SHA_mutex);
|
||||
result = rt_mutex_release(&s_SHA_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
@@ -242,6 +242,8 @@ static void link_monitor(void *param)
|
||||
|
||||
static rt_err_t nu_emac_init(rt_device_t dev)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
nu_emac_t psNuEMAC = (nu_emac_t)dev;
|
||||
|
||||
EMAC_Close();
|
||||
@@ -254,9 +256,12 @@ static rt_err_t nu_emac_init(rt_device_t dev)
|
||||
NVIC_SetPriority(EMAC_RX_IRQn, 1);
|
||||
NVIC_EnableIRQ(EMAC_RX_IRQn);
|
||||
|
||||
rt_sem_init(&psNuEMAC->eth_sem, "eth_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
result = rt_sem_init(&psNuEMAC->eth_sem, "eth_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
result = rt_thread_init(ð_tid, "eth", link_monitor, (void *)psNuEMAC, eth_stack, sizeof(eth_stack), RT_THREAD_PRIORITY_MAX - 2, 10);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
rt_thread_init(ð_tid, "eth", link_monitor, (void *)psNuEMAC, eth_stack, sizeof(eth_stack), RT_THREAD_PRIORITY_MAX - 2, 10);
|
||||
rt_thread_startup(ð_tid);
|
||||
|
||||
#if defined(LWIP_IPV4) && defined(LWIP_IGMP)
|
||||
@@ -310,6 +315,7 @@ static rt_err_t nu_emac_control(rt_device_t dev, int cmd, void *args)
|
||||
|
||||
static rt_err_t nu_emac_tx(rt_device_t dev, struct pbuf *p)
|
||||
{
|
||||
rt_err_t result;
|
||||
nu_emac_t psNuEMAC = (nu_emac_t)dev;
|
||||
struct pbuf *q;
|
||||
rt_uint32_t offset = 0;
|
||||
@@ -319,14 +325,15 @@ static rt_err_t nu_emac_tx(rt_device_t dev, struct pbuf *p)
|
||||
/* Get free TX buffer */
|
||||
if (buf == RT_NULL)
|
||||
{
|
||||
rt_sem_control(&psNuEMAC->eth_sem, RT_IPC_CMD_RESET, 0);
|
||||
result = rt_sem_control(&psNuEMAC->eth_sem, RT_IPC_CMD_RESET, 0);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
EMAC_CLEAR_INT_FLAG(EMAC, EMAC_INTSTS_TXCPIF_Msk);
|
||||
EMAC_ENABLE_INT(EMAC, EMAC_INTEN_TXCPIEN_Msk);
|
||||
|
||||
do
|
||||
{
|
||||
rt_sem_take(&psNuEMAC->eth_sem, 1);
|
||||
while (rt_sem_take(&psNuEMAC->eth_sem, 10) != RT_EOK) ;
|
||||
buf = (rt_uint8_t *)EMAC_ClaimFreeTXBuf();
|
||||
}
|
||||
while (buf == RT_NULL);
|
||||
@@ -440,8 +447,11 @@ void EMAC_TX_IRQHandler(void)
|
||||
/* Wake-up suspended process to send */
|
||||
if (EMAC_GET_INT_FLAG(EMAC, EMAC_INTSTS_TXCPIF_Msk))
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
EMAC_DISABLE_INT(EMAC, EMAC_INTEN_TXCPIEN_Msk);
|
||||
rt_sem_release(&nu_emac_dev.eth_sem);
|
||||
result = rt_sem_release(&nu_emac_dev.eth_sem);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
if (EMAC_GET_INT_FLAG(EMAC, EMAC_INTSTS_TXBEIF_Msk))
|
||||
|
||||
@@ -228,41 +228,4 @@ int rt_hw_epwm_init(void)
|
||||
|
||||
INIT_DEVICE_EXPORT(rt_hw_epwm_init);
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
#include <finsh.h>
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
|
||||
static int pwm_get(int argc, char **argv)
|
||||
{
|
||||
int result = 0;
|
||||
struct rt_device_pwm *device = RT_NULL;
|
||||
struct rt_pwm_configuration configuration = {0};
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
rt_kprintf("Usage: pwm_get pwm1 1\n");
|
||||
result = -RT_ERROR;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
device = (struct rt_device_pwm *)rt_device_find(argv[1]);
|
||||
if (!device)
|
||||
{
|
||||
result = -RT_EIO;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
configuration.channel = atoi(argv[2]);
|
||||
result = rt_device_control(&device->parent, PWM_CMD_GET, &configuration);
|
||||
|
||||
_exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
MSH_CMD_EXPORT(pwm_get, pwm_get epwm1 1);
|
||||
|
||||
#endif /* FINSH_USING_MSH */
|
||||
#endif /* RT_USING_FINSH */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -54,10 +54,15 @@ const struct fal_flash_dev Onchip_ldrom_flash = { "OnChip_LDROM", FMC_LDROM_BASE
|
||||
|
||||
int nu_fmc_read(long addr, uint8_t *buf, size_t size)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
size_t read_size = 0;
|
||||
uint32_t addr_end = addr + size;
|
||||
uint32_t isp_rdata = 0;
|
||||
rt_mutex_take(g_mutex_fmc, RT_WAITING_FOREVER);
|
||||
|
||||
result = rt_mutex_take(g_mutex_fmc, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
SYS_UnlockReg();
|
||||
|
||||
if (NU_GET_LSB2BIT(addr))
|
||||
@@ -87,7 +92,9 @@ int nu_fmc_read(long addr, uint8_t *buf, size_t size)
|
||||
}
|
||||
|
||||
SYS_LockReg();
|
||||
rt_mutex_release(g_mutex_fmc);
|
||||
|
||||
result = rt_mutex_release(g_mutex_fmc);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return read_size;
|
||||
}
|
||||
@@ -97,8 +104,11 @@ int nu_fmc_write(long addr, const uint8_t *buf, size_t size)
|
||||
size_t write_size = 0;
|
||||
uint32_t addr_end = addr + size;
|
||||
uint32_t isp_rdata = 0;
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_mutex_take(g_mutex_fmc, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
rt_mutex_take(g_mutex_fmc, RT_WAITING_FOREVER);
|
||||
SYS_UnlockReg();
|
||||
|
||||
if (addr < FMC_APROM_END)
|
||||
@@ -144,9 +154,12 @@ int nu_fmc_write(long addr, const uint8_t *buf, size_t size)
|
||||
|
||||
FMC_DISABLE_AP_UPDATE();
|
||||
FMC_DISABLE_LD_UPDATE();
|
||||
|
||||
Exit2:
|
||||
SYS_LockReg();
|
||||
rt_mutex_release(g_mutex_fmc);
|
||||
|
||||
result = rt_mutex_release(g_mutex_fmc);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return write_size;
|
||||
|
||||
@@ -157,12 +170,12 @@ int nu_fmc_erase(long addr, size_t size)
|
||||
size_t erased_size = 0;
|
||||
uint32_t addrptr;
|
||||
uint32_t addr_end = addr + size;
|
||||
rt_err_t result;
|
||||
|
||||
#if defined(NU_SUPPORT_NONALIGN)
|
||||
uint8_t *page_sdtemp = RT_NULL;
|
||||
uint8_t *page_edtemp = RT_NULL;
|
||||
|
||||
|
||||
addrptr = addr & (FMC_FLASH_PAGE_SIZE - 1);
|
||||
if (addrptr)
|
||||
{
|
||||
@@ -205,7 +218,9 @@ int nu_fmc_erase(long addr, size_t size)
|
||||
}
|
||||
#endif
|
||||
|
||||
rt_mutex_take(g_mutex_fmc, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(g_mutex_fmc, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
SYS_UnlockReg();
|
||||
|
||||
if (addr <= FMC_APROM_END)
|
||||
@@ -233,7 +248,9 @@ Exit1:
|
||||
FMC_DISABLE_LD_UPDATE();
|
||||
Exit2:
|
||||
SYS_LockReg();
|
||||
rt_mutex_release(g_mutex_fmc);
|
||||
|
||||
result = rt_mutex_release(g_mutex_fmc);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
#if defined(NU_SUPPORT_NONALIGN)
|
||||
|
||||
@@ -315,6 +332,7 @@ static int nu_fmc_init(void)
|
||||
SYS_LockReg();
|
||||
|
||||
g_mutex_fmc = rt_mutex_create("nu_fmc_lock", RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(g_mutex_fmc != RT_NULL);
|
||||
|
||||
/* PKG_USING_FAL */
|
||||
#if defined(PKG_USING_FAL)
|
||||
|
||||
@@ -256,11 +256,13 @@ void nu_pdma_channel_terminate(int i32ChannID)
|
||||
int i;
|
||||
uint32_t u32EnabledChans;
|
||||
int ch_mask = 0;
|
||||
rt_err_t result;
|
||||
|
||||
if (!(nu_pdma_chn_mask & (1 << i32ChannID)))
|
||||
goto exit_pdma_channel_terminate;
|
||||
|
||||
rt_mutex_take(g_mutex_res, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(g_mutex_res, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
// Suspend all channels.
|
||||
u32EnabledChans = nu_pdma_chn_mask & NU_PDMA_CH_Msk;
|
||||
@@ -299,7 +301,8 @@ void nu_pdma_channel_terminate(int i32ChannID)
|
||||
u32EnabledChans &= ~ch_mask;
|
||||
}
|
||||
|
||||
rt_mutex_release(g_mutex_res);
|
||||
result = rt_mutex_release(g_mutex_res);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
exit_pdma_channel_terminate:
|
||||
|
||||
@@ -552,7 +555,7 @@ rt_err_t nu_pdma_desc_setup(int i32ChannID, nu_pdma_desc_t dma_desc, uint32_t u3
|
||||
goto exit_nu_pdma_desc_setup;
|
||||
else if ((u32AddrSrc % (u32DataWidth / 8)) || (u32AddrDst % (u32DataWidth / 8)))
|
||||
goto exit_nu_pdma_desc_setup;
|
||||
else if ( i32TransferCnt > NU_PDMA_MAX_TXCNT )
|
||||
else if (i32TransferCnt > NU_PDMA_MAX_TXCNT)
|
||||
goto exit_nu_pdma_desc_setup;
|
||||
|
||||
psPeriphCtl = &nu_pdma_chn_arr[i32ChannID - NU_PDMA_CH_Pos].m_spPeripCtl;
|
||||
@@ -625,11 +628,13 @@ static void nu_pdma_sgtbls_token_free(nu_pdma_desc_t psSgtbls)
|
||||
rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num)
|
||||
{
|
||||
int i, j, idx;
|
||||
rt_err_t result;
|
||||
|
||||
RT_ASSERT(ppsSgtbls != NULL);
|
||||
RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE);
|
||||
|
||||
rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
@@ -644,7 +649,8 @@ rt_err_t nu_pdma_sgtbls_allocate(nu_pdma_desc_t *ppsSgtbls, int num)
|
||||
ppsSgtbls[i] = (nu_pdma_desc_t)&nu_pdma_sgtbl_arr[idx];
|
||||
}
|
||||
|
||||
rt_mutex_release(g_mutex_sg);
|
||||
result = rt_mutex_release(g_mutex_sg);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
@@ -660,18 +666,22 @@ fail_nu_pdma_sgtbls_allocate:
|
||||
ppsSgtbls[j] = NULL;
|
||||
}
|
||||
|
||||
rt_mutex_release(g_mutex_sg);
|
||||
result = rt_mutex_release(g_mutex_sg);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num)
|
||||
{
|
||||
int i;
|
||||
rt_err_t result;
|
||||
|
||||
RT_ASSERT(ppsSgtbls != NULL);
|
||||
RT_ASSERT(num <= NU_PDMA_SG_TBL_MAXSIZE);
|
||||
|
||||
rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(g_mutex_sg, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
@@ -682,7 +692,8 @@ void nu_pdma_sgtbls_free(nu_pdma_desc_t *ppsSgtbls, int num)
|
||||
ppsSgtbls[i] = NULL;
|
||||
}
|
||||
|
||||
rt_mutex_release(g_mutex_sg);
|
||||
result = rt_mutex_release(g_mutex_sg);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
static rt_err_t nu_pdma_sgtbls_valid(nu_pdma_desc_t head)
|
||||
@@ -870,6 +881,7 @@ static void nu_pdma_memfun_actor_init(void)
|
||||
if (-(RT_ERROR) != (nu_pdma_memfun_actor_arr[i].m_i32ChannID = nu_pdma_channel_allocate(PDMA_MEM)))
|
||||
{
|
||||
nu_pdma_memfun_actor_arr[i].m_psSemMemFun = rt_sem_create("memactor_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(nu_pdma_memfun_actor_arr[i].m_psSemMemFun != RT_NULL);
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -878,16 +890,23 @@ static void nu_pdma_memfun_actor_init(void)
|
||||
{
|
||||
nu_pdma_memfun_actor_maxnum = i;
|
||||
nu_pdma_memfun_actor_mask = ~(((1 << i) - 1));
|
||||
|
||||
nu_pdma_memfun_actor_pool_sem = rt_sem_create("mempool_sem", nu_pdma_memfun_actor_maxnum, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(nu_pdma_memfun_actor_pool_sem != RT_NULL);
|
||||
|
||||
nu_pdma_memfun_actor_pool_lock = rt_mutex_create("mempool_lock", RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(nu_pdma_memfun_actor_pool_lock != RT_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void nu_pdma_memfun_cb(void *pvUserData, uint32_t u32Events)
|
||||
{
|
||||
rt_err_t result;
|
||||
nu_pdma_memfun_actor_t psMemFunActor = (nu_pdma_memfun_actor_t)pvUserData;
|
||||
|
||||
psMemFunActor->m_u32Result = u32Events;
|
||||
rt_sem_release(psMemFunActor->m_psSemMemFun);
|
||||
result = rt_sem_release(psMemFunActor->m_psSemMemFun);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
static int nu_pdma_memfun_employ(void)
|
||||
@@ -897,7 +916,10 @@ static int nu_pdma_memfun_employ(void)
|
||||
/* Headhunter */
|
||||
if (nu_pdma_memfun_actor_pool_sem && (rt_sem_take(nu_pdma_memfun_actor_pool_sem, RT_WAITING_FOREVER) == RT_EOK))
|
||||
{
|
||||
rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
|
||||
rt_err_t result;
|
||||
result = rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Find the position of first '0' in nu_pdma_memfun_actor_mask. */
|
||||
idx = nu_cto(nu_pdma_memfun_actor_mask);
|
||||
if (idx != 32)
|
||||
@@ -908,7 +930,8 @@ static int nu_pdma_memfun_employ(void)
|
||||
{
|
||||
idx = -1;
|
||||
}
|
||||
rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
|
||||
result = rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
return idx;
|
||||
@@ -924,6 +947,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
|
||||
|
||||
while (1)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
/* Employ actor */
|
||||
if ((idx = nu_pdma_memfun_employ()) < 0)
|
||||
continue;
|
||||
@@ -952,7 +977,8 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
|
||||
0);
|
||||
|
||||
/* Wait it done. */
|
||||
rt_sem_take(psMemFunActor->m_psSemMemFun, RT_WAITING_FOREVER);
|
||||
result = rt_sem_take(psMemFunActor->m_psSemMemFun, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Give result if get NU_PDMA_EVENT_TRANSFER_DONE.*/
|
||||
if (psMemFunActor->m_u32Result & NU_PDMA_EVENT_TRANSFER_DONE)
|
||||
@@ -976,12 +1002,16 @@ static rt_size_t nu_pdma_memfun(void *dest, void *src, uint32_t u32DataWidth, un
|
||||
}
|
||||
while (u32TransferCnt > 0);
|
||||
|
||||
rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(nu_pdma_memfun_actor_pool_lock, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
nu_pdma_memfun_actor_mask &= ~(1 << idx);
|
||||
rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
|
||||
result = rt_mutex_release(nu_pdma_memfun_actor_pool_lock);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Fire actor */
|
||||
rt_sem_release(nu_pdma_memfun_actor_pool_sem);
|
||||
result = rt_sem_release(nu_pdma_memfun_actor_pool_sem);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ static struct nu_spi nu_qspi_arr [] =
|
||||
.name = "qspi0",
|
||||
.spi_base = (SPI_T *)QSPI0,
|
||||
|
||||
#if defined(BSP_USING_QSPI_PDMA)
|
||||
#if defined(BSP_USING_SPI_PDMA)
|
||||
#if defined(BSP_USING_QSPI0_PDMA)
|
||||
.pdma_perp_tx = PDMA_QSPI0_TX,
|
||||
.pdma_perp_rx = PDMA_QSPI0_RX,
|
||||
@@ -77,7 +77,7 @@ static struct nu_spi nu_qspi_arr [] =
|
||||
.name = "qspi1",
|
||||
.spi_base = (SPI_T *)QSPI1,
|
||||
|
||||
#if defined(BSP_USING_QSPI_PDMA)
|
||||
#if defined(BSP_USING_SPI_PDMA)
|
||||
#if defined(BSP_USING_QSPI1_PDMA)
|
||||
.pdma_perp_tx = PDMA_QSPI1_TX,
|
||||
.pdma_perp_rx = PDMA_QSPI1_RX,
|
||||
|
||||
@@ -270,11 +270,13 @@ static rt_size_t nu_sdh_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_siz
|
||||
{
|
||||
rt_uint32_t ret = 0;
|
||||
nu_sdh_t sdh = (nu_sdh_t)dev;
|
||||
rt_err_t result;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
RT_ASSERT(buffer != RT_NULL);
|
||||
|
||||
rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
|
||||
result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Check alignment. */
|
||||
if (((uint32_t)buffer & 0x03) != 0)
|
||||
@@ -315,7 +317,8 @@ exit_nu_sdh_read:
|
||||
sdh->pbuf = RT_NULL;
|
||||
}
|
||||
|
||||
rt_sem_release(&sdh->lock);
|
||||
result = rt_sem_release(&sdh->lock);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
if (ret == Successful)
|
||||
return blk_nb;
|
||||
@@ -329,11 +332,13 @@ static rt_size_t nu_sdh_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||
{
|
||||
rt_uint32_t ret = 0;
|
||||
nu_sdh_t sdh = (nu_sdh_t)dev;
|
||||
rt_err_t result;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
RT_ASSERT(buffer != RT_NULL);
|
||||
|
||||
rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
|
||||
result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Check alignment. */
|
||||
if (((uint32_t)buffer & 0x03) != 0)
|
||||
@@ -372,7 +377,8 @@ exit_nu_sdh_write:
|
||||
sdh->pbuf = RT_NULL;
|
||||
}
|
||||
|
||||
rt_sem_release(&sdh->lock);
|
||||
result = rt_sem_release(&sdh->lock);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
if (ret == Successful) return blk_nb;
|
||||
|
||||
@@ -427,11 +433,13 @@ static int rt_hw_sdh_init(void)
|
||||
/* Private */
|
||||
nu_sdh_arr[i].dev.user_data = (void *)&nu_sdh_arr[i];
|
||||
|
||||
rt_sem_init(&nu_sdh_arr[i].lock, "sdhlock", 1, RT_IPC_FLAG_FIFO);
|
||||
ret = rt_sem_init(&nu_sdh_arr[i].lock, "sdhlock", 1, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(ret == RT_EOK);
|
||||
|
||||
SDH_Open(nu_sdh_arr[i].base, CardDetect_From_GPIO);
|
||||
|
||||
nu_sdh_arr[i].pbuf = RT_NULL;
|
||||
|
||||
ret = rt_device_register(&nu_sdh_arr[i].dev, nu_sdh_arr[i].name, flags);
|
||||
RT_ASSERT(ret == RT_EOK);
|
||||
}
|
||||
@@ -620,7 +628,11 @@ static void sdh_hotplugger(void *param)
|
||||
|
||||
int mnt_init_sdcard_hotplug(void)
|
||||
{
|
||||
rt_thread_init(&sdh_tid, "hotplug", sdh_hotplugger, NULL, sdh_stack, sizeof(sdh_stack), RT_THREAD_PRIORITY_MAX - 2, 10);
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_thread_init(&sdh_tid, "hotplug", sdh_hotplugger, NULL, sdh_stack, sizeof(sdh_stack), RT_THREAD_PRIORITY_MAX - 2, 10);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
rt_thread_startup(&sdh_tid);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -241,11 +241,13 @@ exit_nu_spi_bus_configure:
|
||||
#if defined(BSP_USING_SPI_PDMA)
|
||||
static void nu_pdma_spi_rx_cb(void *pvUserData, uint32_t u32EventFilter)
|
||||
{
|
||||
rt_err_t result;
|
||||
struct nu_spi *spi_bus = (struct nu_spi *)pvUserData;
|
||||
|
||||
RT_ASSERT(spi_bus != RT_NULL);
|
||||
|
||||
rt_sem_release(spi_bus->m_psSemBus);
|
||||
result = rt_sem_release(spi_bus->m_psSemBus);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
static rt_err_t nu_pdma_spi_rx_config(struct nu_spi *spi_bus, uint8_t *pu8Buf, int32_t i32RcvLen, uint8_t bytes_per_word)
|
||||
{
|
||||
@@ -362,7 +364,8 @@ static rt_size_t nu_spi_pdma_transmit(struct nu_spi *spi_bus, const uint8_t *sen
|
||||
SPI_TRIGGER_TX_RX_PDMA(spi_base);
|
||||
|
||||
/* Wait RX-PDMA transfer done */
|
||||
rt_sem_take(spi_bus->m_psSemBus, RT_WAITING_FOREVER);
|
||||
result = rt_sem_take(spi_bus->m_psSemBus, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Stop TX/RX DMA transfer. */
|
||||
SPI_DISABLE_TX_RX_PDMA(spi_base);
|
||||
@@ -391,6 +394,7 @@ rt_err_t nu_hw_spi_pdma_allocate(struct nu_spi *spi_bus)
|
||||
}
|
||||
|
||||
spi_bus->m_psSemBus = rt_sem_create("spibus_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(spi_bus->m_psSemBus != RT_NULL);
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
|
||||
@@ -243,10 +243,11 @@ exit_nu_spii2s_capacity_check:
|
||||
static rt_err_t nu_spii2s_dai_setup(nu_i2s_t psNuSPII2s, struct rt_audio_configure *pconfig)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
nu_acodec_ops_t pNuACodecOps = RT_NULL;
|
||||
nu_acodec_ops_t pNuACodecOps;
|
||||
SPI_T *spii2s_base = (SPI_T *)psNuSPII2s->i2s_base;
|
||||
|
||||
RT_ASSERT(psNuSPII2s->AcodecOps != RT_NULL);
|
||||
pNuACodecOps = psNuSPII2s->AcodecOps;
|
||||
SPI_T *spii2s_base = (SPI_T *)psNuSPII2s->i2s_base;
|
||||
|
||||
/* Open SPII2S */
|
||||
if (nu_spii2s_capacity_check(pconfig) == RT_TRUE)
|
||||
@@ -283,7 +284,7 @@ static rt_err_t nu_spii2s_dai_setup(nu_i2s_t psNuSPII2s, struct rt_audio_configu
|
||||
/* Set MCLK and enable MCLK */
|
||||
SPII2S_EnableMCLK(spii2s_base, __HXT);
|
||||
|
||||
/* Set unmute */
|
||||
/* Set un-mute */
|
||||
if (pNuACodecOps->nu_acodec_mixer_control)
|
||||
pNuACodecOps->nu_acodec_mixer_control(AUDIO_MIXER_MUTE, RT_FALSE);
|
||||
}
|
||||
@@ -298,14 +299,11 @@ exit_nu_spii2s_dai_setup:
|
||||
static rt_err_t nu_spii2s_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
nu_i2s_t psNuSPII2s;
|
||||
nu_acodec_ops_t pNuACodecOps = RT_NULL;
|
||||
nu_i2s_t psNuSPII2s = (nu_i2s_t)audio;
|
||||
nu_acodec_ops_t pNuACodecOps;
|
||||
|
||||
RT_ASSERT(audio != RT_NULL);
|
||||
RT_ASSERT(caps != RT_NULL);
|
||||
|
||||
psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
RT_ASSERT(psNuSPII2s->AcodecOps != RT_NULL);
|
||||
|
||||
pNuACodecOps = psNuSPII2s->AcodecOps;
|
||||
@@ -367,6 +365,10 @@ static rt_err_t nu_spii2s_getcaps(struct rt_audio_device *audio, struct rt_audio
|
||||
} // switch (caps->sub_type)
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -RT_ERROR;
|
||||
break;
|
||||
|
||||
} // switch (caps->main_type)
|
||||
|
||||
return result;
|
||||
@@ -375,16 +377,14 @@ static rt_err_t nu_spii2s_getcaps(struct rt_audio_device *audio, struct rt_audio
|
||||
static rt_err_t nu_spii2s_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
nu_i2s_t psNuSPII2s;
|
||||
nu_acodec_ops_t pNuACodecOps = RT_NULL;
|
||||
nu_i2s_t psNuSPII2s = (nu_i2s_t)audio;
|
||||
nu_acodec_ops_t pNuACodecOps;
|
||||
int stream = -1;
|
||||
|
||||
RT_ASSERT(audio != RT_NULL);
|
||||
RT_ASSERT(caps != RT_NULL);
|
||||
|
||||
psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
RT_ASSERT(psNuSPII2s->AcodecOps != RT_NULL);
|
||||
|
||||
pNuACodecOps = psNuSPII2s->AcodecOps;
|
||||
|
||||
switch (caps->main_type)
|
||||
@@ -394,7 +394,6 @@ static rt_err_t nu_spii2s_configure(struct rt_audio_device *audio, struct rt_aud
|
||||
psNuSPII2s->AcodecOps->nu_acodec_mixer_control(caps->sub_type, caps->udata.value);
|
||||
break;
|
||||
|
||||
|
||||
case AUDIO_TYPE_INPUT:
|
||||
stream = AUDIO_STREAM_RECORD;
|
||||
case AUDIO_TYPE_OUTPUT:
|
||||
@@ -445,6 +444,7 @@ static rt_err_t nu_spii2s_configure(struct rt_audio_device *audio, struct rt_aud
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -RT_ERROR;
|
||||
break;
|
||||
@@ -456,12 +456,10 @@ static rt_err_t nu_spii2s_configure(struct rt_audio_device *audio, struct rt_aud
|
||||
static rt_err_t nu_spii2s_init(struct rt_audio_device *audio)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
nu_i2s_t psNuSPII2s;
|
||||
nu_i2s_t psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
RT_ASSERT(audio != RT_NULL);
|
||||
|
||||
psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
/* Reset this module */
|
||||
SYS_ResetModule(psNuSPII2s->i2s_rst);
|
||||
|
||||
@@ -470,13 +468,12 @@ static rt_err_t nu_spii2s_init(struct rt_audio_device *audio)
|
||||
|
||||
static rt_err_t nu_spii2s_start(struct rt_audio_device *audio, int stream)
|
||||
{
|
||||
nu_i2s_t psNuSPII2s;
|
||||
nu_i2s_t psNuSPII2s = (nu_i2s_t)audio;
|
||||
SPI_T *spii2s_base;
|
||||
|
||||
RT_ASSERT(audio != RT_NULL);
|
||||
|
||||
psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
SPI_T *spii2s_base = (SPI_T *)psNuSPII2s->i2s_base;
|
||||
spii2s_base = (SPI_T *)psNuSPII2s->i2s_base;
|
||||
|
||||
/* Restart all: SPII2S and codec. */
|
||||
nu_spii2s_stop(audio, stream);
|
||||
@@ -512,6 +509,8 @@ static rt_err_t nu_spii2s_start(struct rt_audio_device *audio, int stream)
|
||||
LOG_I("Start record.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
@@ -519,14 +518,13 @@ static rt_err_t nu_spii2s_start(struct rt_audio_device *audio, int stream)
|
||||
|
||||
static rt_err_t nu_spii2s_stop(struct rt_audio_device *audio, int stream)
|
||||
{
|
||||
nu_i2s_t psNuSPII2s;
|
||||
nu_i2s_t psNuSPII2s = (nu_i2s_t)audio;
|
||||
nu_i2s_dai_t psNuSPII2sDai = RT_NULL;
|
||||
SPI_T *spii2s_base;
|
||||
|
||||
RT_ASSERT(audio != RT_NULL);
|
||||
|
||||
psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
SPI_T *spii2s_base = (SPI_T *)psNuSPII2s->i2s_base;
|
||||
spii2s_base = (SPI_T *)psNuSPII2s->i2s_base;
|
||||
|
||||
switch (stream)
|
||||
{
|
||||
@@ -574,13 +572,11 @@ static rt_err_t nu_spii2s_stop(struct rt_audio_device *audio, int stream)
|
||||
|
||||
static void nu_spii2s_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info)
|
||||
{
|
||||
nu_i2s_t psNuSPII2s;
|
||||
nu_i2s_t psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
RT_ASSERT(audio != RT_NULL);
|
||||
RT_ASSERT(info != RT_NULL);
|
||||
|
||||
psNuSPII2s = (nu_i2s_t)audio;
|
||||
|
||||
info->buffer = (rt_uint8_t *)psNuSPII2s->i2s_dais[NU_I2S_DAI_PLAYBACK].fifo ;
|
||||
info->total_size = NU_I2S_DMA_FIFO_SIZE;
|
||||
info->block_size = NU_I2S_DMA_BUF_BLOCK_SIZE;
|
||||
@@ -618,12 +614,12 @@ nu_hw_spii2s_pdma_allocate:
|
||||
|
||||
int rt_hw_spii2s_init(void)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
int j = 0;
|
||||
nu_i2s_dai_t psNuSPII2sDai;
|
||||
|
||||
|
||||
for (j = (SPII2S_START + 1); j < SPII2S_CNT; j++)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < NU_I2S_DAI_CNT; i++)
|
||||
{
|
||||
uint8_t *pu8ptr = rt_malloc(NU_I2S_DMA_FIFO_SIZE);
|
||||
|
||||
@@ -72,7 +72,7 @@ void timer_interrupt_handler(nu_capture_t *nu_timer_capture)
|
||||
{
|
||||
TIMER_ClearCaptureIntFlag(nu_timer_capture->timer);
|
||||
|
||||
/* Frist event is rising edge */
|
||||
/* First event is rising edge */
|
||||
if (nu_timer_capture->first_edge == RT_TRUE)
|
||||
{
|
||||
nu_timer_capture->first_edge = RT_FALSE;
|
||||
|
||||
@@ -27,8 +27,10 @@ static int s_i32TRNGEnable = 0;
|
||||
static rt_uint32_t nu_trng_run(void)
|
||||
{
|
||||
uint32_t u32RNGValue;
|
||||
rt_err_t result;
|
||||
|
||||
rt_mutex_take(&s_TRNG_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_TRNG_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
TRNG_Open();
|
||||
|
||||
@@ -38,13 +40,18 @@ static rt_uint32_t nu_trng_run(void)
|
||||
u32RNGValue = rand();
|
||||
}
|
||||
|
||||
rt_mutex_release(&s_TRNG_mutex);
|
||||
result = rt_mutex_release(&s_TRNG_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return u32RNGValue;
|
||||
}
|
||||
|
||||
rt_err_t nu_trng_init(void)
|
||||
{
|
||||
rt_mutex_init(&s_TRNG_mutex, NU_CRYPTO_TRNG_NAME, RT_IPC_FLAG_FIFO);
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_mutex_init(&s_TRNG_mutex, NU_CRYPTO_TRNG_NAME, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define DBG_ENABLE
|
||||
#define DBG_SECTION_NAME LOG_TAG
|
||||
#define DBG_LEVEL DBG_INFO
|
||||
#define DBG_COLOR
|
||||
#include <rtdbg.h>
|
||||
|
||||
#define SLV_10BIT_ADDR (0x1E<<2) //1111+0xx+r/w
|
||||
@@ -382,4 +383,4 @@ int rt_hw_ui2c_init(void)
|
||||
|
||||
INIT_DEVICE_EXPORT(rt_hw_ui2c_init);
|
||||
|
||||
#endif //#if (defined(BSP_USING_UI2C) && defined(RT_USING_I2C))
|
||||
#endif //#if defined(BSP_USING_UI2C)
|
||||
|
||||
@@ -288,7 +288,7 @@ __STATIC_INLINE void _USBD_IRQHandler(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* USB Un-plug */
|
||||
/* USB Unplug */
|
||||
USBD_DISABLE_USB();
|
||||
rt_usbd_disconnect_handler(&_rt_obj_udc);
|
||||
}
|
||||
@@ -447,7 +447,6 @@ void USBD_IRQHandler(void)
|
||||
|
||||
_USBD_IRQHandler();
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
|
||||
@@ -523,7 +522,7 @@ int nu_usbd_register(void)
|
||||
|
||||
_rt_obj_udc.parent.user_data = &nu_usbd;
|
||||
_rt_obj_udc.ops = &_udc_ops;
|
||||
/* Register endpoint infomation */
|
||||
/* Register endpoint information */
|
||||
_rt_obj_udc.ep_pool = _ep_pool;
|
||||
_rt_obj_udc.ep0.id = &_ep_pool[0];
|
||||
|
||||
|
||||
@@ -446,7 +446,6 @@ static void int_xfer_done_cb(UTR_T *psUTR)
|
||||
free_utr(psUTR);
|
||||
}
|
||||
|
||||
|
||||
static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
|
||||
{
|
||||
S_NU_RH_PORT_CTRL *psPortCtrl;
|
||||
@@ -505,7 +504,6 @@ static int nu_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//others xfer
|
||||
rt_completion_init(&(psPortDev->utr_completion));
|
||||
|
||||
@@ -694,7 +692,6 @@ static void nu_hcd_disconnect_callback(
|
||||
rt_usbh_root_hub_disconnect_handler(s_sUSBHDev.uhcd, port_index);
|
||||
}
|
||||
|
||||
|
||||
/* USB host operations -----------------------------------------------------------*/
|
||||
static struct uhcd_ops nu_uhcd_ops =
|
||||
{
|
||||
@@ -706,7 +703,7 @@ static struct uhcd_ops nu_uhcd_ops =
|
||||
|
||||
static rt_err_t nu_hcd_init(rt_device_t device)
|
||||
{
|
||||
struct nu_usbh_dev * pNuUSBHDev = (struct nu_usbh_dev *)device;
|
||||
struct nu_usbh_dev *pNuUSBHDev = (struct nu_usbh_dev *)device;
|
||||
usbh_core_init();
|
||||
|
||||
//install connect/disconnect callback
|
||||
@@ -716,11 +713,11 @@ static rt_err_t nu_hcd_init(rt_device_t device)
|
||||
//create thread for polling usbh port status
|
||||
/* create usb hub thread */
|
||||
pNuUSBHDev->polling_thread = rt_thread_create("usbh_drv", nu_usbh_rh_thread_entry, RT_NULL,
|
||||
NU_USBH_THREAD_STACK_SIZE, 8, 20);
|
||||
if ( pNuUSBHDev->polling_thread != RT_NULL)
|
||||
NU_USBH_THREAD_STACK_SIZE, 8, 20);
|
||||
if (pNuUSBHDev->polling_thread != RT_NULL)
|
||||
{
|
||||
/* startup usb host thread */
|
||||
rt_thread_startup( pNuUSBHDev->polling_thread );
|
||||
rt_thread_startup(pNuUSBHDev->polling_thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -751,15 +748,20 @@ uint32_t usbh_tick_from_millisecond(uint32_t msec)
|
||||
/* device pm suspend() entry. */
|
||||
static int usbhost_pm_suspend(const struct rt_device *device, rt_uint8_t mode)
|
||||
{
|
||||
struct nu_usbh_dev * pNuUSBHDev = (struct nu_usbh_dev *)device;
|
||||
rt_err_t result;
|
||||
|
||||
RT_ASSERT(pNuUSBHDev!=RT_NULL);
|
||||
struct nu_usbh_dev *pNuUSBHDev = (struct nu_usbh_dev *)device;
|
||||
|
||||
RT_ASSERT(pNuUSBHDev != RT_NULL);
|
||||
switch (mode)
|
||||
{
|
||||
case PM_SLEEP_MODE_LIGHT:
|
||||
case PM_SLEEP_MODE_DEEP:
|
||||
|
||||
pNuUSBHDev->polling_thread->stat = RT_THREAD_READY;
|
||||
rt_thread_suspend(pNuUSBHDev->polling_thread);
|
||||
result = rt_thread_suspend(pNuUSBHDev->polling_thread);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -772,14 +774,16 @@ static int usbhost_pm_suspend(const struct rt_device *device, rt_uint8_t mode)
|
||||
/* device pm resume() entry. */
|
||||
static void usbhost_pm_resume(const struct rt_device *device, rt_uint8_t mode)
|
||||
{
|
||||
struct nu_usbh_dev * pNuUSBHDev = (struct nu_usbh_dev *)device;
|
||||
RT_ASSERT(pNuUSBHDev!=RT_NULL);
|
||||
rt_err_t result;
|
||||
struct nu_usbh_dev *pNuUSBHDev = (struct nu_usbh_dev *)device;
|
||||
RT_ASSERT(pNuUSBHDev != RT_NULL);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case PM_SLEEP_MODE_LIGHT:
|
||||
case PM_SLEEP_MODE_DEEP:
|
||||
rt_thread_resume(pNuUSBHDev->polling_thread);
|
||||
result = rt_thread_resume(pNuUSBHDev->polling_thread);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -846,7 +850,7 @@ int nu_usbh_register(void)
|
||||
#if defined(RT_USING_PM)
|
||||
rt_pm_device_register(&uhcd->parent, &device_pm_ops);
|
||||
#endif
|
||||
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(nu_usbh_register);
|
||||
|
||||
@@ -12,6 +12,14 @@
|
||||
#include <rtconfig.h>
|
||||
|
||||
#if defined(BSP_USING_USPI)
|
||||
|
||||
#define LOG_TAG "drv.uspi"
|
||||
#define DBG_ENABLE
|
||||
#define DBG_SECTION_NAME LOG_TAG
|
||||
#define DBG_LEVEL DBG_INFO
|
||||
#define DBG_COLOR
|
||||
#include <rtdbg.h>
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtdevice.h>
|
||||
#include <rtdef.h>
|
||||
@@ -56,7 +64,8 @@ typedef struct nu_uspi *uspi_t;
|
||||
/* Private functions ------------------------------------------------------------*/
|
||||
static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration);
|
||||
static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_message *message);
|
||||
static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus, uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word);
|
||||
static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
|
||||
uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word);
|
||||
static int nu_uspi_register_bus(struct nu_uspi *uspi_bus, const char *name);
|
||||
static void nu_uspi_drain_rxfifo(USPI_T *uspi_base);
|
||||
|
||||
@@ -160,7 +169,7 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
|
||||
u32BusClock = USPI_SetBusClock(uspi_bus->uspi_base, configuration->max_hz);
|
||||
if (configuration->max_hz > u32BusClock)
|
||||
{
|
||||
rt_kprintf("%s clock max frequency is %dHz (!= %dHz)\n", uspi_bus->name, u32BusClock, configuration->max_hz);
|
||||
LOG_W("%s clock max frequency is %dHz (!= %dHz)\n", uspi_bus->name, u32BusClock, configuration->max_hz);
|
||||
configuration->max_hz = u32BusClock;
|
||||
}
|
||||
|
||||
@@ -194,7 +203,7 @@ static rt_err_t nu_uspi_bus_configure(struct rt_spi_device *device,
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear SPI RX FIFO */
|
||||
/* Clear USPI RX FIFO */
|
||||
nu_uspi_drain_rxfifo(uspi_bus->uspi_base);
|
||||
|
||||
exit_nu_uspi_bus_configure:
|
||||
@@ -205,16 +214,18 @@ exit_nu_uspi_bus_configure:
|
||||
#if defined(BSP_USING_USPI_PDMA)
|
||||
static void nu_pdma_uspi_rx_cb(void *pvUserData, uint32_t u32EventFilter)
|
||||
{
|
||||
struct nu_uspi *uspi_bus;
|
||||
uspi_bus = (struct nu_uspi *)pvUserData;
|
||||
rt_err_t result;
|
||||
struct nu_uspi *uspi_bus = (struct nu_uspi *)pvUserData;
|
||||
|
||||
RT_ASSERT(uspi_bus != RT_NULL);
|
||||
|
||||
rt_sem_release(uspi_bus->m_psSemBus);
|
||||
result = rt_sem_release(uspi_bus->m_psSemBus);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
static rt_err_t nu_pdma_uspi_rx_config(struct nu_uspi *uspi_bus, uint8_t *pu8Buf, int32_t i32RcvLen, uint8_t bytes_per_word)
|
||||
{
|
||||
rt_err_t result = RT_ERROR;
|
||||
rt_err_t result;
|
||||
rt_uint8_t *dst_addr = NULL;
|
||||
nu_pdma_memctrl_t memctrl = eMemCtl_Undefined;
|
||||
|
||||
@@ -263,7 +274,7 @@ exit_nu_pdma_uspi_rx_config:
|
||||
|
||||
static rt_err_t nu_pdma_uspi_tx_config(struct nu_uspi *uspi_bus, const uint8_t *pu8Buf, int32_t i32SndLen, uint8_t bytes_per_word)
|
||||
{
|
||||
rt_err_t result = RT_ERROR;
|
||||
rt_err_t result;
|
||||
rt_uint8_t *src_addr = NULL;
|
||||
nu_pdma_memctrl_t memctrl = eMemCtl_Undefined;
|
||||
|
||||
@@ -304,11 +315,11 @@ exit_nu_pdma_uspi_tx_config:
|
||||
|
||||
|
||||
/**
|
||||
* SPI PDMA transfer
|
||||
*/
|
||||
* USPI PDMA transfer
|
||||
**/
|
||||
static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word)
|
||||
{
|
||||
rt_err_t result = RT_ERROR;
|
||||
rt_err_t result;
|
||||
|
||||
/* Get base address of uspi register */
|
||||
USPI_T *uspi_base = uspi_bus->uspi_base;
|
||||
@@ -322,7 +333,8 @@ static rt_size_t nu_uspi_pdma_transmit(struct nu_uspi *uspi_bus, const uint8_t *
|
||||
USPI_TRIGGER_TX_RX_PDMA(uspi_base);
|
||||
|
||||
/* Wait PDMA transfer done */
|
||||
rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER);
|
||||
result = rt_sem_take(uspi_bus->m_psSemBus, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
/* Stop DMA TX/RX transfer */
|
||||
USPI_DISABLE_TX_RX_PDMA(uspi_base);
|
||||
@@ -345,6 +357,7 @@ static rt_err_t nu_hw_uspi_pdma_allocate(struct nu_uspi *uspi_bus)
|
||||
}
|
||||
|
||||
uspi_bus->m_psSemBus = rt_sem_create("uspibus_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(uspi_bus->m_psSemBus != RT_NULL);
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
@@ -373,10 +386,10 @@ static int nu_uspi_read(USPI_T *uspi_base, uint8_t *recv_addr, uint8_t bytes_per
|
||||
// Read RX data
|
||||
if (!USPI_GET_RX_EMPTY_FLAG(uspi_base))
|
||||
{
|
||||
uint32_t val;
|
||||
// Read data from USPI RX FIFO
|
||||
switch (bytes_per_word)
|
||||
{
|
||||
uint32_t val;
|
||||
case 2:
|
||||
val = USPI_READ_RX(uspi_base);
|
||||
nu_set16_le(recv_addr, val);
|
||||
@@ -385,6 +398,7 @@ static int nu_uspi_read(USPI_T *uspi_base, uint8_t *recv_addr, uint8_t bytes_per
|
||||
*recv_addr = USPI_READ_RX(uspi_base);
|
||||
break;
|
||||
default:
|
||||
LOG_E("Data length is not supported.\n");
|
||||
break;
|
||||
}
|
||||
size = bytes_per_word;
|
||||
@@ -397,7 +411,7 @@ static int nu_uspi_write(USPI_T *uspi_base, const uint8_t *send_addr, uint8_t by
|
||||
// Wait USPI TX send data
|
||||
while (USPI_GET_TX_FULL_FLAG(uspi_base));
|
||||
|
||||
// Input data to SPI TX
|
||||
// Input data to USPI TX
|
||||
switch (bytes_per_word)
|
||||
{
|
||||
case 2:
|
||||
@@ -407,6 +421,7 @@ static int nu_uspi_write(USPI_T *uspi_base, const uint8_t *send_addr, uint8_t by
|
||||
USPI_WRITE_TX(uspi_base, *((uint8_t *)send_addr));
|
||||
break;
|
||||
default:
|
||||
LOG_E("Data length is not supported.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -414,8 +429,8 @@ static int nu_uspi_write(USPI_T *uspi_base, const uint8_t *send_addr, uint8_t by
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI bus polling
|
||||
* @param dev : The pointer of the specified SPI module.
|
||||
* @brief USPI bus polling
|
||||
* @param dev : The pointer of the specified USPI module.
|
||||
* @param send_addr : Source address
|
||||
* @param recv_addr : Destination address
|
||||
* @param length : Data length
|
||||
@@ -440,10 +455,10 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
|
||||
uspi_bus->dummy = 0;
|
||||
while (length > 0)
|
||||
{
|
||||
/* Input data to SPI TX FIFO */
|
||||
/* Input data to USPI TX FIFO */
|
||||
length -= nu_uspi_write(uspi_base, (const uint8_t *)&uspi_bus->dummy, bytes_per_word);
|
||||
|
||||
/* Read data from RX FIFO */
|
||||
/* Read data from USPI RX FIFO */
|
||||
while (USPI_GET_RX_EMPTY_FLAG(uspi_base));
|
||||
recv_addr += nu_uspi_read(uspi_base, recv_addr, bytes_per_word);
|
||||
}
|
||||
@@ -453,20 +468,20 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
|
||||
{
|
||||
while (length > 0)
|
||||
{
|
||||
/* Input data to SPI TX FIFO */
|
||||
/* Input data to USPI TX FIFO */
|
||||
send_addr += nu_uspi_write(uspi_base, send_addr, bytes_per_word);
|
||||
length -= bytes_per_word;
|
||||
|
||||
/* Read data from RX FIFO */
|
||||
/* Read data from USPI RX FIFO */
|
||||
while (USPI_GET_RX_EMPTY_FLAG(uspi_base));
|
||||
recv_addr += nu_uspi_read(uspi_base, recv_addr, bytes_per_word);
|
||||
}
|
||||
} // else
|
||||
|
||||
/* Wait RX or drain RX-FIFO */
|
||||
/* Wait USPI RX or drain USPI RX-FIFO */
|
||||
if (recv_addr)
|
||||
{
|
||||
// Wait SPI transmission done
|
||||
// Wait USPI transmission done
|
||||
while (USPI_IS_BUSY(uspi_base))
|
||||
{
|
||||
while (!USPI_GET_RX_EMPTY_FLAG(uspi_base))
|
||||
@@ -482,7 +497,7 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear SPI RX FIFO */
|
||||
/* Clear USPI RX FIFO */
|
||||
nu_uspi_drain_rxfifo(uspi_base);
|
||||
}
|
||||
}
|
||||
@@ -490,10 +505,10 @@ static void nu_uspi_transmission_with_poll(struct nu_uspi *uspi_bus,
|
||||
static void nu_uspi_transfer(struct nu_uspi *uspi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word)
|
||||
{
|
||||
#if defined(BSP_USING_USPI_PDMA)
|
||||
/* DMA transfer constrains */
|
||||
/* PDMA transfer constrains */
|
||||
if ((uspi_bus->pdma_chanid_rx >= 0) &&
|
||||
!((uint32_t)tx % bytes_per_word) &&
|
||||
!((uint32_t)rx % bytes_per_word))
|
||||
(!((uint32_t)tx % bytes_per_word)) &&
|
||||
(!((uint32_t)rx % bytes_per_word)))
|
||||
nu_uspi_pdma_transmit(uspi_bus, tx, rx, length, bytes_per_word);
|
||||
else
|
||||
nu_uspi_transmission_with_poll(uspi_bus, tx, rx, length, bytes_per_word);
|
||||
@@ -519,7 +534,7 @@ static rt_uint32_t nu_uspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_
|
||||
if ((message->length % bytes_per_word) != 0)
|
||||
{
|
||||
/* Say bye. */
|
||||
rt_kprintf("%s: error payload length(%d%%%d != 0).\n", uspi_bus->name, message->length, bytes_per_word);
|
||||
LOG_E("%s: error payload length(%d%%%d != 0).\n", uspi_bus->name, message->length, bytes_per_word);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -578,7 +593,7 @@ static int rt_hw_uspi_init(void)
|
||||
{
|
||||
if (nu_hw_uspi_pdma_allocate(&nu_uspi_arr[i]) != RT_EOK)
|
||||
{
|
||||
rt_kprintf("Failed to allocate DMA channels for %s. We will use poll-mode for this bus.\n", nu_uspi_arr[i].name);
|
||||
LOG_E("Failed to allocate DMA channels for %s. We will use poll-mode for this bus.\n", nu_uspi_arr[i].name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -484,7 +484,7 @@ static int nu_hw_uuart_dma_allocate(nu_uuart_t puuart)
|
||||
static rt_err_t nu_uuart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
rt_uint32_t flag;
|
||||
rt_uint32_t flag = 0;
|
||||
rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
- For record function: Run it w/o parameter.
|
||||
- For replay function: Run it with parameter.
|
||||
*/
|
||||
static void audio_test(int argc, char **argv)
|
||||
static int audio_test(int argc, char **argv)
|
||||
{
|
||||
#define DEF_MAX_ARGV_NUM 8
|
||||
int smplrate[] = {8000, 11025, 16000, 22050, 32000, 44100, 48000};
|
||||
int smplrate[] = {8000, 16000, 44100, 48000};
|
||||
int smplbit[] = {16};
|
||||
int chnum[] = {1, 2};
|
||||
struct wavrecord_info info;
|
||||
@@ -74,6 +74,8 @@ static void audio_test(int argc, char **argv)
|
||||
} // k
|
||||
} // j
|
||||
} // i
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
/**************************************************************************//**
|
||||
*
|
||||
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-1-10 Wayne First version
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#if defined(RT_USB_DEVICE_CDC) && (defined(BSP_USING_USBD) || defined(BSP_USING_HSUSBD))
|
||||
@@ -6,7 +18,11 @@ static struct rt_semaphore rx_sem;
|
||||
|
||||
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
|
||||
{
|
||||
rt_sem_release(&rx_sem);
|
||||
rt_err_t result = 0;
|
||||
|
||||
result = rt_sem_release(&rx_sem);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
@@ -21,10 +37,8 @@ static void serial_thread_entry(void *parameter)
|
||||
{
|
||||
if (rt_sem_take(&rx_sem, 3 * RT_TICK_PER_SECOND) == -RT_ETIMEOUT)
|
||||
{
|
||||
time_t now;
|
||||
/* output current time */
|
||||
now = time(RT_NULL);
|
||||
rt_snprintf(szStr, sizeof(szStr), "%.*s\n", 25, ctime(&now));
|
||||
/* output current tick */
|
||||
rt_snprintf(szStr, sizeof(szStr), "%d\n", rt_tick_get());
|
||||
rt_device_write(serial, 0, &szStr[0], rt_strlen(szStr));
|
||||
continue;
|
||||
}
|
||||
@@ -35,7 +49,7 @@ static void serial_thread_entry(void *parameter)
|
||||
|
||||
static int vcom_echo_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
rt_err_t result = 0;
|
||||
rt_thread_t thread;
|
||||
rt_device_t serial;
|
||||
|
||||
@@ -45,25 +59,33 @@ static int vcom_echo_init(void)
|
||||
rt_kprintf("find failed!\n");
|
||||
return RT_ERROR;
|
||||
}
|
||||
err = rt_device_init(serial);
|
||||
if (err)
|
||||
result = rt_device_init(serial);
|
||||
if (result)
|
||||
{
|
||||
rt_kprintf("find failed!\n");
|
||||
return -RT_ERROR;
|
||||
rt_kprintf("init failed!\n");
|
||||
return -1;
|
||||
}
|
||||
result = rt_device_open(serial, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX/* | RT_DEVICE_FLAG_DMA_TX */);
|
||||
if (result)
|
||||
{
|
||||
rt_kprintf("open failed!\n");
|
||||
return -1;
|
||||
}
|
||||
err = rt_device_open(serial, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX/* | RT_DEVICE_FLAG_DMA_TX */);
|
||||
|
||||
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
result = rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
rt_device_set_rx_indicate(serial, uart_input);
|
||||
result = rt_device_set_rx_indicate(serial, uart_input);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
thread = rt_thread_create("serial", serial_thread_entry, (void *)serial, 1024, 25, 10);
|
||||
if (thread != RT_NULL)
|
||||
{
|
||||
rt_thread_startup(thread);
|
||||
result = rt_thread_startup(thread);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
return 0;
|
||||
}
|
||||
INIT_APP_EXPORT(vcom_echo_init);
|
||||
|
||||
|
||||
@@ -35,15 +35,17 @@ static void usb_thread_entry(void *parameter)
|
||||
{
|
||||
int8_t i8MouseTable[] = { -16, -16, -16, 0, 16, 16, 16, 0};
|
||||
uint8_t u8MouseIdx = 0;
|
||||
uint8_t u8MoveLen=0, u8MouseMode = 1;
|
||||
uint8_t u8MoveLen = 0, u8MouseMode = 1;
|
||||
uint8_t pu8Buf[4];
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
rt_device_t device = (rt_device_t)parameter;
|
||||
|
||||
rt_sem_init(&tx_sem_complete, "tx_complete_sem_hid", 1, RT_IPC_FLAG_FIFO);
|
||||
result = rt_sem_init(&tx_sem_complete, "tx_complete_sem_hid", 1, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
rt_device_set_tx_complete(device, event_hid_in);
|
||||
result = rt_device_set_tx_complete(device, event_hid_in);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
LOG_I("Ready.\n");
|
||||
|
||||
@@ -79,7 +81,7 @@ static void usb_thread_entry(void *parameter)
|
||||
{
|
||||
/* Wait it done. */
|
||||
result = rt_sem_take(&tx_sem_complete, RT_WAITING_FOREVER);
|
||||
RT_ASSERT( result== RT_EOK );
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
} // while(1)
|
||||
@@ -96,10 +98,10 @@ static int dance_mouse_init(void)
|
||||
RT_ASSERT(ret == RT_EOK);
|
||||
|
||||
ret = rt_thread_init(&usb_thread,
|
||||
"hidd",
|
||||
usb_thread_entry, device,
|
||||
usb_thread_stack, sizeof(usb_thread_stack),
|
||||
10, 20);
|
||||
"hidd",
|
||||
usb_thread_entry, device,
|
||||
usb_thread_stack, sizeof(usb_thread_stack),
|
||||
10, 20);
|
||||
RT_ASSERT(ret == RT_EOK);
|
||||
|
||||
ret = rt_thread_startup(&usb_thread);
|
||||
|
||||
@@ -62,4 +62,10 @@ menu "Nuvoton Packages Config"
|
||||
|
||||
endif
|
||||
|
||||
config NU_PKG_USING_SPINAND
|
||||
bool "SPI NAND flash."
|
||||
select BSP_USING_QSPI
|
||||
select RT_USING_MTD_NAND
|
||||
default n
|
||||
|
||||
endmenu
|
||||
|
||||
12
bsp/nuvoton/libraries/nu_packages/SPINAND/SConscript
Normal file
12
bsp/nuvoton/libraries/nu_packages/SPINAND/SConscript
Normal file
@@ -0,0 +1,12 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
group = []
|
||||
if GetDepend('NU_PKG_USING_SPINAND'):
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
CPPPATH = [cwd]
|
||||
group = DefineGroup('nu_pkgs_spinand', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
912
bsp/nuvoton/libraries/nu_packages/SPINAND/drv_spinand.c
Normal file
912
bsp/nuvoton/libraries/nu_packages/SPINAND/drv_spinand.c
Normal file
File diff suppressed because it is too large
Load Diff
693
bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.c
Normal file
693
bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.c
Normal file
File diff suppressed because it is too large
Load Diff
95
bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.h
Normal file
95
bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/**************************************************************************//**
|
||||
*
|
||||
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-1-13 Wayne First version
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __SPINAND_H__
|
||||
#define __SPINAND_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include <drivers/mtd_nand.h>
|
||||
#include "drv_spi.h"
|
||||
#include <board.h>
|
||||
|
||||
/* SPI NAND flash information */
|
||||
struct nu_spinand_info
|
||||
{
|
||||
uint32_t u32JEDECID;
|
||||
uint16_t u16PageSize;
|
||||
uint16_t u16OOBSize;
|
||||
uint8_t u8QuadReadCmdId;
|
||||
uint8_t u8ReadStatusCmdId;
|
||||
uint8_t u8WriteStatusCmdid;
|
||||
uint8_t u8StatusValue;
|
||||
uint8_t u8DummyByte;
|
||||
uint32_t u32BlockPerFlash;
|
||||
uint32_t u32PagePerBlock;
|
||||
uint8_t u8IsDieSelect;
|
||||
const char *szDescription;
|
||||
};
|
||||
typedef struct nu_spinand_info *nu_spinand_info_t;
|
||||
|
||||
struct spinand_ops
|
||||
{
|
||||
rt_err_t (*block_erase)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
|
||||
uint8_t (*block_isbad)(struct rt_qspi_device *qspi, uint32_t u32PageAddr);
|
||||
rt_err_t (*block_markbad)(struct rt_qspi_device *qspi, uint32_t u32PageAddr);
|
||||
rt_err_t (*die_select)(struct rt_qspi_device *qspi, uint8_t select_die);
|
||||
rt_err_t (*jedecid_get)(struct rt_qspi_device *qspi, uint32_t *pu32ID);
|
||||
rt_err_t (*program_dataload)(struct rt_qspi_device *qspi, uint8_t u8AddrH, uint8_t u8AddrL, uint8_t *pu8DataBuff,
|
||||
uint32_t u32DataCount, uint8_t *pu8SpareBuff, uint32_t u32SpareCount);
|
||||
|
||||
rt_err_t (*program_execute)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
|
||||
rt_err_t (*read_dataload)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
|
||||
rt_err_t (*read_quadoutput)(struct rt_qspi_device *qspi, uint8_t u8AddrH, uint8_t u8AddrL, uint8_t *pu8DataBuff, uint32_t u32DataCount);
|
||||
};
|
||||
typedef struct spinand_ops *nu_spinand_ops_t;
|
||||
|
||||
struct nu_spinand
|
||||
{
|
||||
struct nu_spinand_info info;
|
||||
struct rt_qspi_device *qspi_device;
|
||||
nu_spinand_ops_t ops;
|
||||
struct rt_mutex lock;
|
||||
};
|
||||
typedef struct nu_spinand *nu_spinand_t;
|
||||
|
||||
#define SPINAND_FLASH_JEDECID g_spinandflash_dev.info.u32JEDECID
|
||||
#define SPINAND_FLASH_PAGE_SIZE g_spinandflash_dev.info.u16PageSize
|
||||
#define SPINAND_FLASH_OOB_SIZE g_spinandflash_dev.info.u16OOBSize
|
||||
#define SPINAND_FLASH_QUADREAD_CMDID g_spinandflash_dev.info.u8QuadReadCmdId
|
||||
#define SPINAND_FLASH_DUMMYBYTE g_spinandflash_dev.info.u8DummyByte
|
||||
#define SPINAND_FLASH_BLOCK_NUM g_spinandflash_dev.info.u32BlockPerFlash
|
||||
#define SPINAND_FLASH_PAGE_PER_BLOCK_NUM g_spinandflash_dev.info.u32PagePerBlock
|
||||
#define SPINAND_FLASH_DESCRIPTION g_spinandflash_dev.info.szDescription
|
||||
#define SPINAND_FLASH_MCP g_spinandflash_dev.info.u8IsDieSelect
|
||||
|
||||
#define SPINAND_FLASH_INFO &g_spinandflash_dev.info
|
||||
#define SPINAND_FLASH_QSPI g_spinandflash_dev.qspi_device
|
||||
#define SPINAND_FLASH_LOCK &g_spinandflash_dev.lock
|
||||
#define SPINAND_FLASH_OPS g_spinandflash_dev.ops
|
||||
|
||||
#define SPINAND_DIE_ID0 (0)
|
||||
#define SPINAND_DIE_ID1 (1)
|
||||
|
||||
#define SPINAND_SPARE_LAYOUT_SIZE 16
|
||||
|
||||
rt_err_t rt_hw_mtd_spinand_register(const char *device_name);
|
||||
rt_size_t nu_qspi_transfer_message(struct rt_qspi_device *device, struct rt_qspi_message *message);
|
||||
rt_err_t nu_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length, void *recv_buf, rt_size_t recv_length);
|
||||
rt_err_t nu_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length);
|
||||
rt_err_t spinand_flash_init(struct rt_qspi_device *qspi);
|
||||
|
||||
extern struct nu_spinand g_spinandflash_dev;
|
||||
extern rt_uint8_t spinand_flash_data_layout[SPINAND_SPARE_LAYOUT_SIZE];
|
||||
extern rt_uint8_t spinand_flash_ecc_layout[SPINAND_SPARE_LAYOUT_SIZE];
|
||||
|
||||
#endif /* __SPINAND_H__ */
|
||||
@@ -46,45 +46,45 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t CREQ; /*!< [0x0020] IFn Command Request Register */
|
||||
uint32_t CMASK; /*!< [0x0024] IFn Command Mask Register */
|
||||
uint32_t MASK1; /*!< [0x0028] IFn Mask 1 Register */
|
||||
uint32_t MASK2; /*!< [0x002c] IFn Mask 2 Register */
|
||||
uint32_t ARB1; /*!< [0x0030] IFn Arbitration 1 Register */
|
||||
uint32_t ARB2; /*!< [0x0034] IFn Arbitration 2 Register */
|
||||
uint32_t MCON; /*!< [0x0038] IFn Message Control Register */
|
||||
uint32_t DAT_A1; /*!< [0x003c] IFn Data A1 Register */
|
||||
uint32_t DAT_A2; /*!< [0x0040] IFn Data A2 Register */
|
||||
uint32_t DAT_B1; /*!< [0x0044] IFn Data B1 Register */
|
||||
uint32_t DAT_B2; /*!< [0x0048] IFn Data B2 Register */
|
||||
uint32_t RESERVE0[13];
|
||||
__IO uint32_t CREQ; /*!< [0x0020] IFn Command Request Register */
|
||||
__IO uint32_t CMASK; /*!< [0x0024] IFn Command Mask Register */
|
||||
__IO uint32_t MASK1; /*!< [0x0028] IFn Mask 1 Register */
|
||||
__IO uint32_t MASK2; /*!< [0x002c] IFn Mask 2 Register */
|
||||
__IO uint32_t ARB1; /*!< [0x0030] IFn Arbitration 1 Register */
|
||||
__IO uint32_t ARB2; /*!< [0x0034] IFn Arbitration 2 Register */
|
||||
__IO uint32_t MCON; /*!< [0x0038] IFn Message Control Register */
|
||||
__IO uint32_t DAT_A1; /*!< [0x003c] IFn Data A1 Register */
|
||||
__IO uint32_t DAT_A2; /*!< [0x0040] IFn Data A2 Register */
|
||||
__IO uint32_t DAT_B1; /*!< [0x0044] IFn Data B1 Register */
|
||||
__IO uint32_t DAT_B2; /*!< [0x0048] IFn Data B2 Register */
|
||||
__I uint32_t RESERVE0[13];
|
||||
} CAN_IF_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t CON; /*!< [0x0000] Control Register */
|
||||
uint32_t STATUS; /*!< [0x0004] Status Register */
|
||||
uint32_t ERR; /*!< [0x0008] Error Counter Register */
|
||||
uint32_t BTIME; /*!< [0x000c] Bit Timing Register */
|
||||
uint32_t IIDR; /*!< [0x0010] Interrupt Identifier Register */
|
||||
uint32_t TEST; /*!< [0x0014] Test Register */
|
||||
uint32_t BRPE; /*!< [0x0018] Baud Rate Prescaler Extension Register */
|
||||
uint32_t RESERVE0[1];
|
||||
CAN_IF_T IF[2];
|
||||
uint32_t RESERVE2[8];
|
||||
uint32_t TXREQ1; /*!< [0x0100] Transmission Request Register 1 */
|
||||
uint32_t TXREQ2; /*!< [0x0104] Transmission Request Register 2 */
|
||||
uint32_t RESERVE3[6];
|
||||
uint32_t NDAT1; /*!< [0x0120] New Data Register 1 */
|
||||
uint32_t NDAT2; /*!< [0x0124] New Data Register 2 */
|
||||
uint32_t RESERVE4[6];
|
||||
uint32_t IPND1; /*!< [0x0140] Interrupt Pending Register 1 */
|
||||
uint32_t IPND2; /*!< [0x0144] Interrupt Pending Register 2 */
|
||||
uint32_t RESERVE5[6];
|
||||
uint32_t MVLD1; /*!< [0x0160] Message Valid Register 1 */
|
||||
uint32_t MVLD2; /*!< [0x0164] Message Valid Register 2 */
|
||||
uint32_t WU_EN; /*!< [0x0168] Wake-up Enable Control Register */
|
||||
uint32_t WU_STATUS; /*!< [0x016c] Wake-up Status Register */
|
||||
__IO uint32_t CON; /*!< [0x0000] Control Register */
|
||||
__IO uint32_t STATUS; /*!< [0x0004] Status Register */
|
||||
__I uint32_t ERR; /*!< [0x0008] Error Counter Register */
|
||||
__IO uint32_t BTIME; /*!< [0x000c] Bit Timing Register */
|
||||
__I uint32_t IIDR; /*!< [0x0010] Interrupt Identifier Register */
|
||||
__IO uint32_t TEST; /*!< [0x0014] Test Register */
|
||||
__IO uint32_t BRPE; /*!< [0x0018] Baud Rate Prescaler Extension Register */
|
||||
__I uint32_t RESERVE0[1];
|
||||
__IO CAN_IF_T IF[2];
|
||||
__I uint32_t RESERVE2[8];
|
||||
__I uint32_t TXREQ1; /*!< [0x0100] Transmission Request Register 1 */
|
||||
__I uint32_t TXREQ2; /*!< [0x0104] Transmission Request Register 2 */
|
||||
__I uint32_t RESERVE3[6];
|
||||
__I uint32_t NDAT1; /*!< [0x0120] New Data Register 1 */
|
||||
__I uint32_t NDAT2; /*!< [0x0124] New Data Register 2 */
|
||||
__I uint32_t RESERVE4[6];
|
||||
__I uint32_t IPND1; /*!< [0x0140] Interrupt Pending Register 1 */
|
||||
__I uint32_t IPND2; /*!< [0x0144] Interrupt Pending Register 2 */
|
||||
__I uint32_t RESERVE5[6];
|
||||
__I uint32_t MVLD1; /*!< [0x0160] Message Valid Register 1 */
|
||||
__I uint32_t MVLD2; /*!< [0x0164] Message Valid Register 2 */
|
||||
__IO uint32_t WU_EN; /*!< [0x0168] Wake-up Enable Control Register */
|
||||
__IO uint32_t WU_STATUS; /*!< [0x016c] Wake-up Status Register */
|
||||
|
||||
} CAN_T;
|
||||
|
||||
|
||||
@@ -647,6 +647,42 @@ static __inline void ETIMER_ClearCaptureIntFlag(UINT timer)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the Timer capture falling edge flag.
|
||||
* @param[in] timer ETIMER number. Range from 0 ~ 5
|
||||
* @return None
|
||||
*/
|
||||
static __inline UINT8 ETIMER_GetCaptureFallingEdgeFlag(UINT timer)
|
||||
{
|
||||
UINT ret;
|
||||
|
||||
if (timer == 0)
|
||||
{
|
||||
ret = inpw(REG_ETMR0_ISR);
|
||||
}
|
||||
else if (timer == 1)
|
||||
{
|
||||
ret = inpw(REG_ETMR1_ISR);
|
||||
}
|
||||
else if (timer == 2)
|
||||
{
|
||||
ret = inpw(REG_ETMR2_ISR);
|
||||
}
|
||||
else if (timer == 3)
|
||||
{
|
||||
ret = inpw(REG_ETMR3_ISR);
|
||||
}
|
||||
else if (timer == 4)
|
||||
{
|
||||
ret = inpw(REG_ETMR4_ISR);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = inpw(REG_ETMR5_ISR);
|
||||
}
|
||||
return (ret & (1 << 6)) >> 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function indicates Timer has waked up system or not.
|
||||
* @param[in] timer ETIMER number. Range from 0 ~ 5
|
||||
|
||||
@@ -110,23 +110,23 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t INIT; /*!< [0x0000] RTC Initiation Register */
|
||||
uint32_t RWEN; /*!< [0x0004] RTC Access Enable Register */
|
||||
uint32_t FREQADJ; /*!< [0x0008] RTC Frequency Compensation Register */
|
||||
uint32_t TIME; /*!< [0x000c] RTC Time Loading Register */
|
||||
uint32_t CAL; /*!< [0x0010] RTC Calendar Loading Register */
|
||||
uint32_t CLKFMT; /*!< [0x0014] RTC Time Scale Selection Register */
|
||||
uint32_t WEEKDAY; /*!< [0x0018] RTC Day of the Week Register */
|
||||
uint32_t TALM; /*!< [0x001c] RTC Time Alarm Register */
|
||||
uint32_t CALM; /*!< [0x0020] RTC Calendar Alarm Register */
|
||||
uint32_t LEAPYEAR; /*!< [0x0024] RTC Leap Year Indicator Register */
|
||||
uint32_t INTEN; /*!< [0x0028] RTC Interrupt Enable Register */
|
||||
uint32_t INTSTS; /*!< [0x002c] RTC Interrupt Status Register */
|
||||
uint32_t TICK; /*!< [0x0030] RTC Time Tick Register */
|
||||
uint32_t PWRCTL; /*!< [0x0034] RTC Power Control Register */
|
||||
uint32_t PWRCNT; /*!< [0x0038] RTC Power Control Counter Register */
|
||||
uint32_t RESERVE0; /*!< [0x003c] RTC Spare Functional Control Register */
|
||||
uint32_t SPR[16]; /*!< [0x0040] ~ [0x007c] RTC Spare Register 0 ~ 15 */
|
||||
__IO uint32_t INIT; /*!< [0x0000] RTC Initiation Register */
|
||||
__IO uint32_t RWEN; /*!< [0x0004] RTC Access Enable Register */
|
||||
__IO uint32_t FREQADJ; /*!< [0x0008] RTC Frequency Compensation Register */
|
||||
__IO uint32_t TIME; /*!< [0x000c] RTC Time Loading Register */
|
||||
__IO uint32_t CAL; /*!< [0x0010] RTC Calendar Loading Register */
|
||||
__IO uint32_t CLKFMT; /*!< [0x0014] RTC Time Scale Selection Register */
|
||||
__IO uint32_t WEEKDAY; /*!< [0x0018] RTC Day of the Week Register */
|
||||
__IO uint32_t TALM; /*!< [0x001c] RTC Time Alarm Register */
|
||||
__IO uint32_t CALM; /*!< [0x0020] RTC Calendar Alarm Register */
|
||||
__I uint32_t LEAPYEAR; /*!< [0x0024] RTC Leap Year Indicator Register */
|
||||
__IO uint32_t INTEN; /*!< [0x0028] RTC Interrupt Enable Register */
|
||||
__IO uint32_t INTSTS; /*!< [0x002c] RTC Interrupt Status Register */
|
||||
__IO uint32_t TICK; /*!< [0x0030] RTC Time Tick Register */
|
||||
__IO uint32_t PWRCTL; /*!< [0x0034] RTC Power Control Register */
|
||||
__IO uint32_t PWRCNT; /*!< [0x0038] RTC Power Control Counter Register */
|
||||
__IO uint32_t RESERVE0; /*!< [0x003c] RTC Spare Functional Control Register */
|
||||
__I uint32_t SPR[16]; /*!< [0x0040] ~ [0x007c] RTC Spare Register 0 ~ 15 */
|
||||
} RTC_T;
|
||||
|
||||
#define RTC_INIT_ACTIVE_Pos (0) /*!< RTC_T::INIT: INIT_ACTIVE Position */
|
||||
|
||||
@@ -116,25 +116,25 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t DAT; /*!< [0x0000] UART Receive/Transmit Buffer Register */
|
||||
uint32_t INTEN; /*!< [0x0004] UART Interrupt Enable Register */
|
||||
uint32_t FIFO; /*!< [0x0008] UART FIFO Control Register */
|
||||
uint32_t LINE; /*!< [0x000c] UART Line Control Register */
|
||||
uint32_t MODEM; /*!< [0x0010] UART Modem Control Register */
|
||||
uint32_t MODEMSTS; /*!< [0x0014] UART Modem Status Register */
|
||||
uint32_t FIFOSTS; /*!< [0x0018] UART FIFO Status Register */
|
||||
uint32_t INTSTS; /*!< [0x001c] UART Interrupt Status Register */
|
||||
uint32_t TOUT; /*!< [0x0020] UART Time-out Register */
|
||||
uint32_t BAUD; /*!< [0x0024] UART Baud Rate Divider Register */
|
||||
uint32_t IRDA; /*!< [0x0028] UART IrDA Control Register */
|
||||
uint32_t ALTCTL; /*!< [0x002c] UART Alternate Control/Status Register */
|
||||
uint32_t FUNCSEL; /*!< [0x0030] UART Function Select Register */
|
||||
uint32_t LINCTL; /*!< [0x0034] UART LIN Control Register */
|
||||
uint32_t LINSTS; /*!< [0x0038] UART LIN Status Register */
|
||||
uint32_t BRCOMP; /*!< [0x003c] UART Baud Rate Compensation Register */
|
||||
uint32_t WKCTL; /*!< [0x0040] UART Wake-up Control Register */
|
||||
uint32_t WKSTS; /*!< [0x0044] UART Wake-up Status Register */
|
||||
uint32_t DWKCOMP; /*!< [0x0048] UART Incoming Data Wake-up Compensation Register */
|
||||
__IO uint32_t DAT; /*!< [0x0000] UART Receive/Transmit Buffer Register */
|
||||
__IO uint32_t INTEN; /*!< [0x0004] UART Interrupt Enable Register */
|
||||
__IO uint32_t FIFO; /*!< [0x0008] UART FIFO Control Register */
|
||||
__IO uint32_t LINE; /*!< [0x000c] UART Line Control Register */
|
||||
__IO uint32_t MODEM; /*!< [0x0010] UART Modem Control Register */
|
||||
__IO uint32_t MODEMSTS; /*!< [0x0014] UART Modem Status Register */
|
||||
__IO uint32_t FIFOSTS; /*!< [0x0018] UART FIFO Status Register */
|
||||
__IO uint32_t INTSTS; /*!< [0x001c] UART Interrupt Status Register */
|
||||
__IO uint32_t TOUT; /*!< [0x0020] UART Time-out Register */
|
||||
__IO uint32_t BAUD; /*!< [0x0024] UART Baud Rate Divider Register */
|
||||
__IO uint32_t IRDA; /*!< [0x0028] UART IrDA Control Register */
|
||||
__IO uint32_t ALTCTL; /*!< [0x002c] UART Alternate Control/Status Register */
|
||||
__IO uint32_t FUNCSEL; /*!< [0x0030] UART Function Select Register */
|
||||
__IO uint32_t LINCTL; /*!< [0x0034] UART LIN Control Register */
|
||||
__IO uint32_t LINSTS; /*!< [0x0038] UART LIN Status Register */
|
||||
__IO uint32_t BRCOMP; /*!< [0x003c] UART Baud Rate Compensation Register */
|
||||
__IO uint32_t WKCTL; /*!< [0x0040] UART Wake-up Control Register */
|
||||
__IO uint32_t WKSTS; /*!< [0x0044] UART Wake-up Status Register */
|
||||
__IO uint32_t DWKCOMP; /*!< [0x0048] UART Incoming Data Wake-up Compensation Register */
|
||||
|
||||
} UART_T;
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ if not GetDepend('BSP_USE_STDDRIVER_SOURCE'):
|
||||
libs += ['libstddriver_gcc']
|
||||
|
||||
if not libs:
|
||||
group = DefineGroup('nuc980_driver', src, depend = [''], CPPPATH = cpppath)
|
||||
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = cpppath)
|
||||
else:
|
||||
src = []
|
||||
group = DefineGroup('nuc980_driver', src, depend = [''], CPPPATH = cpppath, LIBS = libs, LIBPATH = libpath)
|
||||
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = cpppath, LIBS = libs, LIBPATH = libpath)
|
||||
|
||||
Return('group')
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
| QSPI | RT_Device_Class_SPIBUS | ***qspi[0]*** |
|
||||
| RTC | RT_Device_Class_RTC | ***rtc*** |
|
||||
| PWM | RT_Device_Class_Miscellaneous (PWM) | ***pwm[0-1]*** |
|
||||
| USBH | RT_Device_Class_USBHost | ***usbh*** |
|
||||
| USBD | RT_Device_Class_USBDevice | ***usbd*** |
|
||||
| SC (UART function) | RT_Device_Class_Char | ***scuart[0-1]*** |
|
||||
| SDH | RT_Device_Class_Block | ***sdh[0-1]*** |
|
||||
|
||||
12
bsp/nuvoton/libraries/nuc980/UsbHostLib/SConscript
Normal file
12
bsp/nuvoton/libraries/nuc980/UsbHostLib/SConscript
Normal file
@@ -0,0 +1,12 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
group = []
|
||||
if GetDepend('BSP_USING_HSUSBH') or GetDepend('BSP_USING_USBH'):
|
||||
src = Glob('*src/*.c') + Glob('src/*.cpp')
|
||||
CPPPATH = [cwd + '/inc']
|
||||
group = DefineGroup('nuc980_usbhostlib', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
1566
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/config.h
Normal file
1566
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/config.h
Normal file
File diff suppressed because it is too large
Load Diff
279
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/ehci.h
Normal file
279
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/ehci.h
Normal file
@@ -0,0 +1,279 @@
|
||||
/**************************************************************************//**
|
||||
* @file ehci.h
|
||||
* @version V1.00
|
||||
* @brief USB EHCI host controller driver header file.
|
||||
* @note
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _USBH_EHCI_H_
|
||||
#define _USBH_EHCI_H_
|
||||
|
||||
/// @cond HIDDEN_SYMBOLS
|
||||
|
||||
struct utr_t;
|
||||
struct udev_t;
|
||||
struct qh_t;
|
||||
struct iso_ep_t;
|
||||
struct ep_info_t;
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Periodic Frame List Size (256, 512, or 1024) */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
#define FL_SIZE 1024 /* frame list size can be 256, 512, or 1024 */
|
||||
#define NUM_IQH 11 /* depends on FL_SIZE, 256:9, 512:10, 1024:11 */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Interrupt Threshold Control (1, 2, 4, 6, .. 64) */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
#define UCMDR_INT_THR_CTRL (0x1<<HSUSBH_UCMDR_ITC_Pos) /* 1 micro-frames */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Queue Element Transfer Descriptor (qTD) */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
typedef struct qTD_t
|
||||
{
|
||||
uint32_t Next_qTD; /* Next qTD Pointer */
|
||||
uint32_t Alt_Next_qTD; /* Alternate Next qTD Pointer */
|
||||
uint32_t Token; /* qTD Token */
|
||||
uint32_t Bptr[5]; /* qTD Buffer Page Pointer List */
|
||||
/*
|
||||
* The following members are used by USB Host libary.
|
||||
*/
|
||||
struct utr_t *utr; /* associated UTR */
|
||||
uint32_t xfer_len; /* assigned transfer transfer length */
|
||||
struct qh_t *qh; /* The QH that this qTD belong to. */
|
||||
struct qTD_t *next; /* link for <qtd_list> of QH */
|
||||
} qTD_T;
|
||||
|
||||
|
||||
#define QTD_LIST_END 0x1 /* Indicate the terminate of qTD list. */
|
||||
#define QTD_PTR(x) ((qTD_T *)((uint32_t)(x) & ~0x1F))
|
||||
|
||||
/*
|
||||
* Status: qTD Token[7:0]
|
||||
*/
|
||||
#define QTD_STS_PS_OUT (0<<0) /* directs the HC to issue an OUT PID */
|
||||
#define QTD_STS_PS_PING (1<<0) /* directs the HC to issue an PING PID */
|
||||
#define QTD_STS_SPLIT_STRAT (0<<1) /* directs the HC to issue an Start split */
|
||||
#define QTD_STS_SPLIT_COMPLETE (1<<1) /* directs the HC to issue an Complete split */
|
||||
#define QTD_STS_MISS_MF (1<<2) /* miss a required complete-split transaction */
|
||||
#define QTD_STS_XactErr (1<<3) /* Transaction Error occurred */
|
||||
#define QTD_STS_BABBLE (1<<4) /* Babble Detected */
|
||||
#define QTD_STS_DATA_BUFF_ERR (1<<5) /* Data Buffer Error */
|
||||
#define QTD_STS_HALT (1<<6) /* Halted */
|
||||
#define QTD_STS_ACTIVE (1<<7) /* Active */
|
||||
|
||||
/*
|
||||
* PID: qTD Token[9:8]
|
||||
*/
|
||||
#define QTD_PID_Msk (0x3<<8)
|
||||
#define QTD_PID_OUT (0<<8) /* generates token (E1H) */
|
||||
#define QTD_PID_IN (1<<8) /* generates token (69H) */
|
||||
#define QTD_PID_SETUP (2<<8) /* generates token (2DH) */
|
||||
|
||||
#define QTD_ERR_COUNTER (3<<10) /* Token[11:10] */
|
||||
#define QTD_IOC (1<<15) /* Token[15] - Interrupt On Complete */
|
||||
#define QTD_TODO_LEN_Pos 16 /* Token[31:16] - Total Bytes to Transfer */
|
||||
#define QTD_TODO_LEN(x) (((x)>>16) & 0x7FFF)
|
||||
#define QTD_DT (1UL<<31) /* Token[31] - Data Toggle */
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Queue Head (QH) */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
typedef struct qh_t
|
||||
{
|
||||
/* OHCI spec. Endpoint descriptor */
|
||||
uint32_t HLink; /* Queue Head Horizontal Link Pointer */
|
||||
uint32_t Chrst; /* Endpoint Characteristics: QH DWord 1 */
|
||||
uint32_t Cap; /* Endpoint Capabilities: QH DWord 2 */
|
||||
uint32_t Curr_qTD; /* Current qTD Pointer */
|
||||
/*
|
||||
* The followings are qTD Transfer Overlay
|
||||
*/
|
||||
uint32_t OL_Next_qTD; /* Next qTD Pointer */
|
||||
uint32_t OL_Alt_Next_qTD; /* Alternate Next qTD Pointer */
|
||||
uint32_t OL_Token; /* qTD Token */
|
||||
uint32_t OL_Bptr[5]; /* qTD Buffer Page Pointer List */
|
||||
/*
|
||||
* The following members are used by USB Host libary.
|
||||
*/
|
||||
qTD_T *qtd_list; /* currently linked qTD transfers */
|
||||
qTD_T *done_list; /* currently linked qTD transfers */
|
||||
struct qh_t *next; /* point to the next QH in remove list */
|
||||
} QH_T;
|
||||
|
||||
/* HLink[0] T field of "Queue Head Horizontal Link Pointer" */
|
||||
#define QH_HLNK_END 0x1
|
||||
|
||||
/*
|
||||
* HLink[2:1] Typ field of "Queue Head Horizontal Link Pointer"
|
||||
*/
|
||||
#define QH_HLNK_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0)
|
||||
#define QH_HLNK_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2)
|
||||
#define QH_HLNK_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4)
|
||||
#define QH_HLNK_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6)
|
||||
#define QH_PTR(x) ((QH_T *)((uint32_t)(x) & ~0x1F))
|
||||
|
||||
/*
|
||||
* Bit fields of "Endpoint Characteristics"
|
||||
*/
|
||||
#define QH_NAK_RL (4L<<28) /* Chrst[31:28] - NAK Count Reload */
|
||||
#define QH_CTRL_EP_FLAG (1<<27) /* Chrst[27] - Control Endpoint Flag */
|
||||
#define QH_RCLM_LIST_HEAD (1<<15) /* Chrst[15] - Head of Reclamation List Flag */
|
||||
#define QH_DTC (1<<14) /* Chrst[14] - Data Toggle Control */
|
||||
#define QH_EPS_FULL (0<<12) /* Chrst[13:12] - Endpoint Speed (Full) */
|
||||
#define QH_EPS_LOW (1<<12) /* Chrst[13:12] - Endpoint Speed (Low) */
|
||||
#define QH_EPS_HIGH (2<<12) /* Chrst[13:12] - Endpoint Speed (High) */
|
||||
#define QH_I_NEXT (1<<7) /* Chrst[7] - Inactivate on Next Transaction */
|
||||
|
||||
/*
|
||||
* Bit fields of "Endpoint Capabilities"
|
||||
*/
|
||||
#define QH_MULT_Pos 30 /* Cap[31:30] - High-Bandwidth Pipe Multiplier */
|
||||
#define QH_HUB_PORT_Pos 23 /* Cap[29:23] - Hub Port Number */
|
||||
#define QH_HUB_ADDR_Pos 16 /* Cap[22:16] - Hub Addr */
|
||||
#define QH_C_MASK_Msk 0xFF00 /* Cap[15:8] - uFrame C-mask */
|
||||
#define QH_S_MASK_Msk 0x00FF /* Cap[7:0] - uFrame S-mask */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Isochronous (High-Speed) Transfer Descriptor (iTD) */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
typedef struct itd_t
|
||||
{
|
||||
uint32_t Next_Link; /* Next Link Pointer */
|
||||
uint32_t Transaction[8]; /* Transaction Status and Control */
|
||||
uint32_t Bptr[7]; /* Buffer Page Pointer List */
|
||||
/*
|
||||
* The following members are used by USB Host libary.
|
||||
*/
|
||||
struct iso_ep_t *iso_ep; /* associated isochronous information block */
|
||||
struct utr_t *utr; /* associated UTR */
|
||||
uint32_t buff_base; /* buffer base address */
|
||||
uint8_t fidx; /* iTD's first index to UTR iso frames */
|
||||
uint8_t trans_mask; /* mask of activated transactions in iTD */
|
||||
uint32_t sched_frnidx; /* scheduled frame index */
|
||||
struct itd_t *next; /* used by software to maintain iTD list */
|
||||
} iTD_T;
|
||||
|
||||
/*
|
||||
* Next_Link[2:1] Typ field of "Next Schedule Element Pointer" Typ field
|
||||
*/
|
||||
#define ITD_HLNK_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0)
|
||||
#define ITD_HLNK_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2)
|
||||
#define ITD_HLNK_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4)
|
||||
#define ITD_HLNK_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6)
|
||||
#define ITD_PTR(x) ((iTD_T *)((uint32_t)(x) & ~0x1F))
|
||||
|
||||
/*
|
||||
* Transaction[8]
|
||||
*/
|
||||
#define ITD_STATUS(x) (((x)>>28)&0xF)
|
||||
#define ITD_STATUS_ACTIVE (0x80000000UL) /* Active */
|
||||
#define ITD_STATUS_BUFF_ERR (0x40000000UL) /* Data Buffer Error */
|
||||
#define ITD_STATUS_BABBLE (0x20000000UL) /* Babble Detected */
|
||||
#define ITD_STATUS_XACT_ERR (0x10000000UL) /* Transcation Error */
|
||||
|
||||
#define ITD_XLEN_Pos 16
|
||||
#define ITD_XFER_LEN(x) (((x)>>16)&0xFFF)
|
||||
#define ITD_IOC (1<<15)
|
||||
#define ITD_PG_Pos 12
|
||||
#define ITD_XFER_OFF_Msk 0xFFF
|
||||
|
||||
/*
|
||||
* Bptr[7]
|
||||
*/
|
||||
#define ITD_BUFF_PAGE_Pos 12
|
||||
/* Bptr[0] */
|
||||
#define ITD_EP_NUM_Pos 8
|
||||
#define ITD_EP_NUM(itd) (((itd)->Bptr[0]>>8)&0xF)
|
||||
#define ITD_DEV_ADDR_Pos 0
|
||||
#define ITD_DEV_ADDR(itd) ((itd)->Bptr[0]&0x7F)
|
||||
/* Bptr[1] */
|
||||
#define ITD_DIR_IN (1<<11)
|
||||
#define ITD_DIR_OUT (0<<11)
|
||||
#define ITD_MAX_PKTSZ_Pos 0
|
||||
#define ITD_MAX_PKTSZ(itd) ((itd)->Bptr[1]&0x7FF)
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Split Isochronous (Full-Speed) Transfer Descriptor (siTD) */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
typedef struct sitd_t
|
||||
{
|
||||
uint32_t Next_Link; /* Next Link Pointer */
|
||||
uint32_t Chrst; /* Endpoint and Transaction Translator Characteristics */
|
||||
uint32_t Sched; /* Micro-frame Schedule Control */
|
||||
uint32_t StsCtrl; /* siTD Transfer Status and Control */
|
||||
uint32_t Bptr[2]; /* Buffer Page Pointer List */
|
||||
uint32_t BackLink; /* siTD Back Link Pointer */
|
||||
/*
|
||||
* The following members are used by USB Host libary.
|
||||
*/
|
||||
struct iso_ep_t *iso_ep; /* associated isochronous information block */
|
||||
struct utr_t *utr; /* associated UTR */
|
||||
uint8_t fidx; /* iTD's first index to UTR iso frames */
|
||||
uint32_t sched_frnidx; /* scheduled frame index */
|
||||
struct sitd_t *next; /* used by software to maintain siTD list */
|
||||
} siTD_T;
|
||||
|
||||
#define SITD_LIST_END 0x1 /* Indicate the terminate of siTD list. */
|
||||
|
||||
#define SITD_XFER_IO_Msk (1UL<<31)
|
||||
#define SITD_XFER_IN (1UL<<31)
|
||||
#define SITD_XFER_OUT (0UL<<31)
|
||||
|
||||
#define SITD_PORT_NUM_Pos 24
|
||||
#define SITD_HUB_ADDR_Pos 16
|
||||
#define SITD_EP_NUM_Pos 8
|
||||
#define SITD_DEV_ADDR_Pos 0
|
||||
|
||||
#define SITD_IOC (1UL<<31)
|
||||
#define SITD_XFER_CNT_Pos 16
|
||||
#define SITD_XFER_CNT_Msk (0x3FF<<SITD_XFER_CNT_Pos)
|
||||
|
||||
#define SITD_STATUS(x) ((x)&0xFC)
|
||||
#define SITD_STATUS_ACTIVE 0x80
|
||||
#define SITD_STATUS_ERR 0x40
|
||||
#define SITD_STATUS_BUFF_ERR 0x20
|
||||
#define SITD_BABBLE_DETECTED 0x10
|
||||
#define SITD_STATUS_XFER_ERR 0x08
|
||||
#define SITD_STATUS_MISSED_MF 0x04
|
||||
#define SITD_STATUS_ERROR_MASK 0x78
|
||||
|
||||
|
||||
/*
|
||||
* Next_Link[2:1] Typ field of "Next Schedule Element Pointer" Typ field
|
||||
*/
|
||||
#define SITD_HLNK_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0)
|
||||
#define SITD_HLNK_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2)
|
||||
#define SITD_HLNK_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4)
|
||||
#define SITD_HLNK_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6)
|
||||
#define SITD_PTR(x) ((siTD_T *)((uint32_t)(x) & ~0x1F))
|
||||
|
||||
#define HLINK_IS_TERMINATED(x) (((uint32_t)(x) & 0x1) ? 1 : 0)
|
||||
#define HLINK_IS_SITD(x) ((((uint32_t)(x) & 0x6) == 0x4) ? 1 : 0)
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Isochronous endpoint transfer information block. (Software only) */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
typedef struct iso_ep_t
|
||||
{
|
||||
struct ep_info_t *ep;
|
||||
uint32_t next_frame; /* frame number of next scheduling */
|
||||
iTD_T *itd_list; /* Reference to a list of installed iTDs */
|
||||
iTD_T *itd_done_list; /* Reference to a list of completed iTDs */
|
||||
siTD_T *sitd_list; /* Reference to a list of installed siTDs */
|
||||
siTD_T *sitd_done_list; /* Reference to a list of completed siTDs */
|
||||
struct iso_ep_t *next; /* used by software to maintain ISO EP list */
|
||||
} ISO_EP_T;
|
||||
|
||||
extern void scan_isochronous_list(void);
|
||||
|
||||
/// @endcond
|
||||
|
||||
#endif /* _USBH_EHCI_H_ */
|
||||
|
||||
124
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/hub.h
Normal file
124
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/hub.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/**************************************************************************//**
|
||||
* @file hub.h
|
||||
* @version V1.00
|
||||
* @brief USB Host hub class driver header file.
|
||||
* @note
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _USBH_HUB_H_
|
||||
#define _USBH_HUB_H_
|
||||
|
||||
|
||||
/// @cond HIDDEN_SYMBOLS
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Hub class feature selectors (Table 11-17) */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FS_C_HUB_LOCAL_POWER 0
|
||||
#define FS_C_HUB_OVER_CURRENT 1
|
||||
|
||||
#define FS_PORT_CONNECTION 0
|
||||
#define FS_PORT_ENABLE 1
|
||||
#define FS_PORT_SUSPEND 2
|
||||
#define FS_PORT_OVER_CURRENT 3
|
||||
#define FS_PORT_RESET 4
|
||||
#define FS_PORT_POWER 8
|
||||
#define FS_C_PORT_CONNECTION 16
|
||||
#define FS_C_PORT_ENABLE 17
|
||||
#define FS_C_PORT_SUSPEND 18
|
||||
#define FS_C_PORT_OVER_CURRENT 19
|
||||
#define FS_C_PORT_RESET 20
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Hub/Port staus and change bits */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define HUB_S_LOCAL_POWER (1UL << 0)
|
||||
#define HUB_S_OVERCURRENT (1UL << 1)
|
||||
|
||||
#define HUB_C_LOCAL_POWER (1UL << 0)
|
||||
#define HUB_C_OVERCURRENT (1UL << 1)
|
||||
|
||||
#define PORT_S_CONNECTION (1UL << 0)
|
||||
#define PORT_S_ENABLE (1UL << 1)
|
||||
#define PORT_S_SUSPEND (1UL << 2)
|
||||
#define PORT_S_OVERCURRENT (1UL << 3)
|
||||
#define PORT_S_RESET (1UL << 4)
|
||||
#define PORT_S_PORT_POWER (1UL << 8)
|
||||
#define PORT_S_LOW_SPEED (1UL << 9)
|
||||
#define PORT_S_HIGH_SPEED (1UL << 10)
|
||||
#define PORT_S_TEST (1UL << 11)
|
||||
#define PORT_S_INDICATOR (1UL << 12)
|
||||
|
||||
#define PORT_C_CONNECTION (1UL << 0)
|
||||
#define PORT_C_ENABLE (1UL << 1)
|
||||
#define PORT_C_SUSPEND (1UL << 2)
|
||||
#define PORT_C_OVERCURRENT (1UL << 3)
|
||||
#define PORT_C_RESET (1UL << 4)
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Hub descriptor */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
uint8_t bDescLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bNbrPorts;
|
||||
uint16_t wHubCharacteristics;
|
||||
uint8_t bPwrOn2PwrGood;
|
||||
uint8_t bHubContrCurrent;
|
||||
uint8_t bDeviceRemovble;
|
||||
uint8_t PortPwrCtrlMask[16];
|
||||
}
|
||||
DESC_HUB_T;
|
||||
|
||||
/*
|
||||
* wHubCharacteristics bit field mask
|
||||
*/
|
||||
#define HUB_CHAR_LPSM 0x0003 /* 00b: global port power, 01b: per port power, 1x: reserved */
|
||||
#define HUB_CHAR_COMPOUND 0x0004 /* 1: is part of a compond device, 0: is not. */
|
||||
#define HUB_CHAR_OCPM 0x0018 /* 00b: global over-current protection, 01b: per port, 1x: reserved */
|
||||
#define HUB_CHAR_TTTT 0x0060 /* TT think time. 00b: 8FS, 01b: 16FS, 10b: 24FS, 11b: 32FS */
|
||||
#define HUB_CHAR_PORTIND 0x0080 /* 1: port indicator (LED) supported, 0: not */
|
||||
|
||||
/* port indicator status selectors */
|
||||
#define HUB_LED_AUTO 0
|
||||
#define HUB_LED_AMBER 1
|
||||
#define HUB_LED_GREEN 2
|
||||
#define HUB_LED_OFF 3
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Port reset retry and time-out settings */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define HUB_DEBOUNCE_TIME 800 /* Hub connect/disconnect de-bounce time in ms */
|
||||
#define PORT_RESET_RETRY 3 /* port reset retry times */
|
||||
#define PORT_RESET_TIME_MS 50 /* port reset time (ms) */
|
||||
#define PORT_RESET_RETRY_INC_MS 250 /* increased reset time (ms) after reset failed */
|
||||
|
||||
|
||||
#define HUB_STATUS_MAX_BYTE 2 /* maximum number of interrupt-in status bytes */
|
||||
/* 2 can support up to 16 port hubs */
|
||||
/* 4 can support up to 32 port hubs */
|
||||
/* Note!! If modeifed to 4, "uint16_t sc_bitmap" */
|
||||
/* MUST be changed as "uint32_t sc_bitmap" */
|
||||
typedef struct hub_dev_t
|
||||
{
|
||||
IFACE_T *iface; /*!< Interface device of this hub \hideinitializer */
|
||||
UTR_T *utr; /*!< Interrupt in UTR of this hub \hideinitializer */
|
||||
// uint8_t buff[HUB_STATUS_MAX_BYTE]; /*!< Interrupt in buffer \hideinitializer */
|
||||
uint16_t sc_bitmap; /*!< Hub and Port Status Change Bitmap \hideinitializer */
|
||||
uint8_t bNbrPorts; /*!< Number of ports \hideinitializer */
|
||||
uint8_t bPwrOn2PwrGood; /*!< Hub power on to power good time \hideinitializer */
|
||||
char pos_id[MAX_HUB_DEVICE + 1]; /*!< Hub position identifier \hideinitializer */
|
||||
int (*port_reset)(struct hub_dev_t *hub, int port); /*!< Port reset function \hideinitializer */
|
||||
UDEV_T *children; /*!< Child device list. \hideinitializer */
|
||||
} HUB_DEV_T;
|
||||
|
||||
|
||||
/// @endcond
|
||||
|
||||
#endif /* _USBH_HUB_H_ */
|
||||
147
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/ohci.h
Normal file
147
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/ohci.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/**************************************************************************//**
|
||||
* @file ohci.h
|
||||
* @version V1.00
|
||||
* @brief USB OHCI host controller driver header file.
|
||||
* @note
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _USBH_OHCI_H_
|
||||
#define _USBH_OHCI_H_
|
||||
|
||||
/// @cond HIDDEN_SYMBOLS
|
||||
|
||||
struct utr_t;
|
||||
struct udev_t;
|
||||
|
||||
/* OHCI CONTROL AND STATUS REGISTER MASKS */
|
||||
|
||||
/*
|
||||
* Host controller functional state.
|
||||
* for HCFS(HcControl[7:6])
|
||||
*/
|
||||
#define HCFS_RESET (0UL << USBH_HcControl_HCFS_Pos)
|
||||
#define HCFS_RESUME (1UL << USBH_HcControl_HCFS_Pos)
|
||||
#define HCFS_OPER (2UL << USBH_HcControl_HCFS_Pos)
|
||||
#define HCFS_SUSPEND (3UL << USBH_HcControl_HCFS_Pos)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Endpoint descriptor */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
typedef struct ed_t
|
||||
{
|
||||
/* OHCI spec. Endpoint descriptor */
|
||||
uint32_t Info;
|
||||
uint32_t TailP;
|
||||
uint32_t HeadP;
|
||||
uint32_t NextED;
|
||||
/* The following members are used by USB Host libary. */
|
||||
uint8_t bInterval;
|
||||
uint16_t next_sf; /* for isochronous transfer, recording the next SF */
|
||||
struct ed_t *next; /* point to the next ED in remove list */
|
||||
} ED_T;
|
||||
|
||||
#define ED_CTRL_FA_Pos 0 /* Info[6:0] - Function address */
|
||||
#define ED_CTRL_EN_Pos 7 /* Info[10:7] - Endpoint number */
|
||||
#define ED_CTRL_DIR_Pos 11 /* Info[12:11] - Direction */
|
||||
#define ED_CTRL_MPS_Pos 16 /* Info[26:16] - Maximum packet size */
|
||||
|
||||
#define ED_FUNC_ADDR_Msk (0x7f)
|
||||
#define ED_EP_ADDR_Msk (0xf<<7)
|
||||
#define ED_DIR_Msk (0x3<<11)
|
||||
#define ED_SPEED_Msk (1<<13)
|
||||
#define ED_MAX_PK_SIZE_Msk (0x7ff<<16)
|
||||
|
||||
#define ED_DIR_BY_TD (0<<ED_CTRL_DIR_Pos)
|
||||
#define ED_DIR_OUT (1<<ED_CTRL_DIR_Pos)
|
||||
#define ED_DIR_IN (2<<ED_CTRL_DIR_Pos)
|
||||
#define ED_SPEED_FULL (0<<13) /* Info[13] - 0: is full speed device */
|
||||
#define ED_SPEED_LOW (1<<13) /* Info[13] - 1: is low speed device */
|
||||
#define ED_SKIP (1<<14) /* Info[14] - 1: HC skip this ED */
|
||||
#define ED_FORMAT_GENERAL (0<<15) /* Info[15] - 0: is a general TD */
|
||||
#define ED_FORMAT_ISO (1<<15) /* Info[15] - 1: is an isochronous TD */
|
||||
#define ED_HEADP_HALT (1<<0) /* HeadP[0] - 1: Halt; 0: Not */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* Transfer descriptor */
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
/* general transfer descriptor */
|
||||
typedef struct td_t
|
||||
{
|
||||
uint32_t Info;
|
||||
uint32_t CBP; /* Current Buffer Pointer */
|
||||
uint32_t NextTD; /* Next TD */
|
||||
uint32_t BE; /* Buffer End */
|
||||
uint32_t PSW[4]; /* PSW 0~7 */
|
||||
/* The following members are used by USB Host libary. */
|
||||
uint32_t buff_start; /* Buffer Start */
|
||||
ED_T *ed; /* The ED that this TD belong to. */
|
||||
struct utr_t *utr; /* associated UTR */
|
||||
struct td_t *next; /* point to next TD of the same UTR */
|
||||
} TD_T;
|
||||
|
||||
#define TD_ADDR_MASK 0xFFFFFFFC
|
||||
|
||||
/* Completion codes */
|
||||
enum OCHI_CC_CODE
|
||||
{
|
||||
/* mapping of the OHCI CC status to error codes */
|
||||
CC_NOERROR, /* No Error */
|
||||
CC_CRC, /* CRC Error */
|
||||
CC_BITSTUFF, /* Bit Stuff */
|
||||
CC_DATA_TOGGLE, /* Data Toggle */
|
||||
CC_STALL, /* Stall */
|
||||
CC_NOTRESPONSE, /* DevNotResp */
|
||||
CC_PID_CHECK, /* PIDCheck */
|
||||
CC_UNEXPECTED_PID, /* UnExpPID */
|
||||
CC_DATA_OVERRUN, /* DataOver */
|
||||
CC_DATA_UNDERRUN, /* DataUnder */
|
||||
CC_RESERVED1, /* reserved */
|
||||
CC_RESERVED2, /* reserved */
|
||||
CC_BUFFER_OVERRUN, /* BufferOver */
|
||||
CC_BUFFER_UNDERRUN, /* BuffUnder */
|
||||
CC_NOT_ACCESS /* Not Access */
|
||||
};
|
||||
|
||||
/* TD control field */
|
||||
#define TD_CC 0xF0000000
|
||||
#define TD_CC_GET(td) ((td >>28) & 0x0F)
|
||||
#define TD_CC_SET(td, cc) (td) = ((td) & 0x0FFFFFFF) | (((cc) & 0x0F) << 28)
|
||||
#define TD_T_DATA0 0x02000000
|
||||
#define TD_T_DATA1 0x03000000
|
||||
#define TD_R 0x00040000
|
||||
#define TD_DP 0x00180000
|
||||
#define TD_DP_IN 0x00100000
|
||||
#define TD_DP_OUT 0x00080000
|
||||
#define MAXPSW 8
|
||||
/* steel TD reserved bits to keep driver data */
|
||||
#define TD_TYPE_Msk (0x3<<16)
|
||||
#define TD_TYPE_CTRL (0x0<<16)
|
||||
#define TD_TYPE_BULK (0x1<<16)
|
||||
#define TD_TYPE_INT (0x2<<16)
|
||||
#define TD_TYPE_ISO (0x3<<16)
|
||||
#define TD_CTRL_Msk (0x7<<15)
|
||||
#define TD_CTRL_DATA (1<<15)
|
||||
|
||||
|
||||
/*
|
||||
* The HCCA (Host Controller Communications Area) is a 256 byte
|
||||
* structure defined in the OHCI spec. that the host controller is
|
||||
* told the base address of. It must be 256-byte aligned.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t int_table[32]; /* Interrupt ED table */
|
||||
uint16_t frame_no; /* current frame number */
|
||||
uint16_t pad1; /* set to 0 on each frame_no change */
|
||||
uint32_t done_head; /* info returned for an interrupt */
|
||||
uint8_t reserved_for_hc[116];
|
||||
} HCCA_T;
|
||||
|
||||
|
||||
/// @endcond
|
||||
|
||||
#endif /* _USBH_OHCI_H_ */
|
||||
394
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/usb.h
Normal file
394
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/usb.h
Normal file
@@ -0,0 +1,394 @@
|
||||
/**************************************************************************//**
|
||||
* @file usb.h
|
||||
* @version V1.00
|
||||
* @brief USB Host library header file.
|
||||
* @note
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _USBH_H_
|
||||
#define _USBH_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "usbh_lib.h"
|
||||
#include "ehci.h"
|
||||
#include "ohci.h"
|
||||
|
||||
/// @cond HIDDEN_SYMBOLS
|
||||
|
||||
struct utr_t;
|
||||
struct udev_t;
|
||||
struct hub_dev_t;
|
||||
struct iface_t;
|
||||
struct ep_info_t;
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* USB device request setup packet */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
}
|
||||
DEV_REQ_T;
|
||||
|
||||
/*
|
||||
* bmRequestType[7] - Data transfer direction
|
||||
*/
|
||||
#define REQ_TYPE_OUT 0x00
|
||||
#define REQ_TYPE_IN 0x80
|
||||
/*
|
||||
* bmRequestType[6:5] - Type
|
||||
*/
|
||||
#define REQ_TYPE_STD_DEV 0x00
|
||||
#define REQ_TYPE_CLASS_DEV 0x20
|
||||
#define REQ_TYPE_VENDOR_DEV 0x40
|
||||
/*
|
||||
* bmRequestType[4:0] - Recipient
|
||||
*/
|
||||
#define REQ_TYPE_TO_DEV 0x00
|
||||
#define REQ_TYPE_TO_IFACE 0x01
|
||||
#define REQ_TYPE_TO_EP 0x02
|
||||
#define REQ_TYPE_TO_OTHER 0x03
|
||||
/*
|
||||
* Standard Requests
|
||||
*/
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
/*
|
||||
* Descriptor Types
|
||||
*/
|
||||
#define USB_DT_STANDARD 0x00
|
||||
#define USB_DT_CLASS 0x20
|
||||
#define USB_DT_VENDOR 0x40
|
||||
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIGURATION 0x02
|
||||
#define USB_DT_STRING 0x03
|
||||
#define USB_DT_INTERFACE 0x04
|
||||
#define USB_DT_ENDPOINT 0x05
|
||||
#define USB_DT_DEVICE_QUALIFIER 0x06
|
||||
#define USB_DT_OTHER_SPEED_CONF 0x07
|
||||
#define USB_DT_IFACE_POWER 0x08
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* USB standard descriptors */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
/* Descriptor header */
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
}
|
||||
DESC_HDR_T;
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* USB device descriptor */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
typedef struct __attribute__((__packed__)) /*!< device descriptor structure */
|
||||
{
|
||||
uint8_t bLength; /*!< Length of device descriptor */
|
||||
uint8_t bDescriptorType; /*!< Device descriptor type */
|
||||
uint16_t bcdUSB; /*!< USB version number */
|
||||
uint8_t bDeviceClass; /*!< Device class code */
|
||||
uint8_t bDeviceSubClass; /*!< Device subclass code */
|
||||
uint8_t bDeviceProtocol; /*!< Device protocol code */
|
||||
uint8_t bMaxPacketSize0; /*!< Maximum packet size of control endpoint*/
|
||||
uint16_t idVendor; /*!< Vendor ID */
|
||||
uint16_t idProduct; /*!< Product ID */
|
||||
uint16_t bcdDevice; /*!< Device ID */
|
||||
uint8_t iManufacturer; /*!< Manufacture description string ID */
|
||||
uint8_t iProduct; /*!< Product description string ID */
|
||||
uint8_t iSerialNumber; /*!< Serial number description string ID */
|
||||
uint8_t bNumConfigurations; /*!< Total number of configurations */
|
||||
}
|
||||
DESC_DEV_T; /*!< device descriptor structure */
|
||||
|
||||
/*
|
||||
* Configuration Descriptor
|
||||
*/
|
||||
typedef struct __attribute__((__packed__)) usb_config_descriptor /*!< Configuration descriptor structure */
|
||||
{
|
||||
uint8_t bLength; /*!< Length of configuration descriptor */
|
||||
uint8_t bDescriptorType; /*!< Descriptor type */
|
||||
uint16_t wTotalLength; /*!< Total length of this configuration */
|
||||
uint8_t bNumInterfaces; /*!< Total number of interfaces */
|
||||
uint8_t bConfigurationValue; /*!< Configuration descriptor number */
|
||||
uint8_t iConfiguration; /*!< String descriptor ID */
|
||||
uint8_t bmAttributes; /*!< Configuration characteristics */
|
||||
uint8_t MaxPower; /*!< Maximum power consumption */
|
||||
} DESC_CONF_T; /*!< Configuration descriptor structure */
|
||||
|
||||
/*
|
||||
* Interface Descriptor
|
||||
*/
|
||||
typedef struct __attribute__((__packed__))usb_interface_descriptor /*!< Interface descriptor structure */
|
||||
{
|
||||
uint8_t bLength; /*!< Length of interface descriptor */
|
||||
uint8_t bDescriptorType; /*!< Descriptor type */
|
||||
uint8_t bInterfaceNumber; /*!< Interface number */
|
||||
uint8_t bAlternateSetting; /*!< Alternate setting number */
|
||||
uint8_t bNumEndpoints; /*!< Number of endpoints */
|
||||
uint8_t bInterfaceClass; /*!< Interface class code */
|
||||
uint8_t bInterfaceSubClass; /*!< Interface subclass code */
|
||||
uint8_t bInterfaceProtocol; /*!< Interface protocol code */
|
||||
uint8_t iInterface; /*!< Interface ID */
|
||||
} DESC_IF_T; /*!< Interface descriptor structure */
|
||||
|
||||
/*
|
||||
* Endpoint Descriptor
|
||||
*/
|
||||
typedef struct __attribute__((__packed__)) usb_endpoint_descriptor /*!< Endpoint descriptor structure */
|
||||
{
|
||||
uint8_t bLength; /*!< Length of endpoint descriptor */
|
||||
uint8_t bDescriptorType; /*!< Descriptor type */
|
||||
uint8_t bEndpointAddress; /*!< Endpoint address */
|
||||
uint8_t bmAttributes; /*!< Endpoint attribute */
|
||||
uint16_t wMaxPacketSize; /*!< Maximum packet size */
|
||||
uint8_t bInterval; /*!< Synchronous transfer interval */
|
||||
uint8_t bRefresh; /*!< Refresh */
|
||||
uint8_t bSynchAddress; /*!< Sync address */
|
||||
} DESC_EP_T; /*!< Endpoint descriptor structure */
|
||||
|
||||
/*
|
||||
* Endpoint descriptor bEndpointAddress[7] - direction
|
||||
*/
|
||||
#define EP_ADDR_DIR_MASK 0x80
|
||||
#define EP_ADDR_DIR_IN 0x80
|
||||
#define EP_ADDR_DIR_OUT 0x00
|
||||
|
||||
/*
|
||||
* Endpoint descriptor bmAttributes[1:0] - transfer type
|
||||
*/
|
||||
#define EP_ATTR_TT_MASK 0x03
|
||||
#define EP_ATTR_TT_CTRL 0x00
|
||||
#define EP_ATTR_TT_ISO 0x01
|
||||
#define EP_ATTR_TT_BULK 0x02
|
||||
#define EP_ATTR_TT_INT 0x03
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* USB Host controller driver */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
int (*init)(void);
|
||||
void (*shutdown)(void);
|
||||
void (*suspend)(void);
|
||||
void (*resume)(void);
|
||||
int (*ctrl_xfer)(struct utr_t *utr);
|
||||
int (*bulk_xfer)(struct utr_t *utr);
|
||||
int (*int_xfer)(struct utr_t *utr);
|
||||
int (*iso_xfer)(struct utr_t *utr);
|
||||
int (*quit_xfer)(struct utr_t *utr, struct ep_info_t *ep);
|
||||
|
||||
/* root hub support */
|
||||
int (*rthub_port_reset)(int port);
|
||||
int (*rthub_polling)(void);
|
||||
} HC_DRV_T;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* USB device driver */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
int (*probe)(struct iface_t *iface);
|
||||
void (*disconnect)(struct iface_t *iface);
|
||||
void (*suspend)(struct iface_t *iface);
|
||||
void (*resume)(struct iface_t *iface);
|
||||
} UDEV_DRV_T;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* USB device */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPEED_LOW,
|
||||
SPEED_FULL,
|
||||
SPEED_HIGH
|
||||
} SPEED_E;
|
||||
|
||||
typedef struct ep_info_t
|
||||
{
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bInterval;
|
||||
uint8_t bToggle;
|
||||
uint16_t wMaxPacketSize;
|
||||
void *hw_pipe; /*!< point to the HC assocaied endpoint \hideinitializer */
|
||||
} EP_INFO_T;
|
||||
|
||||
typedef struct udev_t
|
||||
{
|
||||
DESC_DEV_T descriptor; /*!< Device descriptor. \hideinitializer */
|
||||
struct hub_dev_t *parent; /*!< parent hub device \hideinitializer */
|
||||
uint8_t port_num; /*!< The hub port this device connected on \hideinitializer */
|
||||
uint8_t dev_num; /*!< device number \hideinitializer */
|
||||
int8_t cur_conf; /*!< Currentll selected configuration \hideinitializer */
|
||||
SPEED_E speed; /*!< device speed (low/full/high) \hideinitializer */
|
||||
/*
|
||||
* The followings are lightweight USB stack internal used .
|
||||
*/
|
||||
uint8_t *cfd_buff; /*!< Configuration descriptor buffer. \hideinitializer */
|
||||
EP_INFO_T ep0; /*!< Endpoint 0 \hideinitializer */
|
||||
HC_DRV_T *hc_driver; /*!< host controller driver \hideinitializer */
|
||||
struct iface_t *iface_list; /*!< Working interface list \hideinitializer */
|
||||
struct udev_t *next; /*!< link for global usb device list \hideinitializer */
|
||||
} UDEV_T;
|
||||
|
||||
typedef struct alt_iface_t
|
||||
{
|
||||
DESC_IF_T *ifd; /*!< point to the location of this alternative interface descriptor in UDEV_T->cfd_buff */
|
||||
EP_INFO_T ep[MAX_EP_PER_IFACE]; /*!< endpoints of this alternative interface */
|
||||
} ALT_IFACE_T;
|
||||
|
||||
typedef struct iface_t
|
||||
{
|
||||
UDEV_T *udev; /*!< USB device \hideinitializer */
|
||||
uint8_t if_num; /*!< Interface number \hideinitializer */
|
||||
uint8_t num_alt; /*!< Number of alternative interface \hideinitializer */
|
||||
ALT_IFACE_T *aif; /*!< Point to the active alternative interface */
|
||||
ALT_IFACE_T alt[MAX_ALT_PER_IFACE]; /*!< List of alternative interface \hideinitializer */
|
||||
UDEV_DRV_T *driver; /*!< Interface associated driver \hideinitializer */
|
||||
void *context; /*!< Reference to device context \hideinitializer */
|
||||
struct iface_t *next; /*!< Point to next interface of the same device. Started from UDEV_T->iface_list \hideinitializer */
|
||||
} IFACE_T;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* URB (USB Request Block) */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
#define IF_PER_UTR 8 /* number of frames per UTR isochronous transfer (DO NOT modify it!) */
|
||||
|
||||
typedef void (*FUNC_UTR_T)(struct utr_t *);
|
||||
|
||||
typedef struct utr_t
|
||||
{
|
||||
UDEV_T *udev; /*!< point to associated USB device \hideinitializer */
|
||||
DEV_REQ_T setup; /*!< buffer for setup packet \hideinitializer */
|
||||
EP_INFO_T *ep; /*!< associated endpoint \hideinitializer */
|
||||
uint8_t *buff; /*!< transfer buffer \hideinitializer */
|
||||
uint8_t bIsTransferDone; /*!< tansfer done? \hideinitializer */
|
||||
uint32_t data_len; /*!< length of data to be transferred \hideinitializer */
|
||||
uint32_t xfer_len; /*!< length of transferred data \hideinitializer */
|
||||
uint8_t bIsoNewSched; /*!< New schedule isochronous transfer \hideinitializer */
|
||||
uint16_t iso_sf; /*!< Isochronous start frame number \hideinitializer */
|
||||
uint16_t iso_xlen[IF_PER_UTR]; /*!< transfer length of isochronous frames \hideinitializer */
|
||||
uint8_t *iso_buff[IF_PER_UTR]; /*!< transfer buffer address of isochronous frames \hideinitializer */
|
||||
int iso_status[IF_PER_UTR]; /*!< transfer status of isochronous frames \hideinitializer */
|
||||
int td_cnt; /*!< number of transfer descriptors \hideinitializer */
|
||||
int status; /*!< return status \hideinitializer */
|
||||
int interval; /*!< interrupt/isochronous interval \hideinitializer */
|
||||
void *context; /*!< point to deivce proprietary data area \hideinitializer */
|
||||
FUNC_UTR_T func; /*!< tansfer done call-back function \hideinitializer */
|
||||
struct utr_t *next; /* point to the next UTR of the same endpoint. \hideinitializer */
|
||||
} UTR_T;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* Global variables */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
extern USBH_T *_ohci;
|
||||
extern HSUSBH_T *_ehci;
|
||||
|
||||
extern HC_DRV_T ohci_driver;
|
||||
extern HC_DRV_T ehci_driver;
|
||||
|
||||
extern UDEV_T *g_udev_list;
|
||||
|
||||
extern volatile int _IsInUsbInterrupt;
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/* USB stack exported functions */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
extern void usbh_delay_ms(int msec);
|
||||
|
||||
extern void dump_ohci_regs(void);
|
||||
extern void dump_ohci_ports(void);
|
||||
extern void dump_ohci_int_table(void);
|
||||
extern void dump_ehci_regs(void);
|
||||
extern void dump_ehci_qtd(qTD_T *qtd);
|
||||
extern void dump_ehci_asynclist(void);
|
||||
extern void dump_ehci_period_frame_list_simple(void);
|
||||
extern void usbh_dump_buff_bytes(uint8_t *buff, int nSize);
|
||||
extern void usbh_dump_interface_descriptor(DESC_IF_T *if_desc);
|
||||
extern void usbh_dump_endpoint_descriptor(DESC_EP_T *ep_desc);
|
||||
extern void usbh_dump_iface(IFACE_T *iface);
|
||||
extern void usbh_dump_ep_info(EP_INFO_T *ep);
|
||||
|
||||
/*
|
||||
* Memory management functions
|
||||
*/
|
||||
extern void USB_InitializeMemoryPool(void);
|
||||
extern void *USB_malloc(int wanted_size, int boundary);
|
||||
extern void USB_free(void *);
|
||||
extern int USB_available_memory(void);
|
||||
extern int USB_allocated_memory(void);
|
||||
extern void usbh_memory_init(void);
|
||||
extern uint32_t usbh_memory_used(void);
|
||||
extern void *usbh_alloc_mem(int size);
|
||||
extern void usbh_free_mem(void *p, int size);
|
||||
extern int alloc_dev_address(void);
|
||||
extern void free_dev_address(int dev_addr);
|
||||
extern UDEV_T *alloc_device(void);
|
||||
extern void free_device(UDEV_T *udev);
|
||||
extern UTR_T *alloc_utr(UDEV_T *udev);
|
||||
extern void free_utr(UTR_T *utr);
|
||||
extern ED_T *alloc_ohci_ED(void);
|
||||
extern void free_ohci_ED(ED_T *ed);
|
||||
extern TD_T *alloc_ohci_TD(UTR_T *utr);
|
||||
extern void free_ohci_TD(TD_T *td);
|
||||
extern QH_T *alloc_ehci_QH(void);
|
||||
extern void free_ehci_QH(QH_T *qh);
|
||||
extern qTD_T *alloc_ehci_qTD(UTR_T *utr);
|
||||
extern void free_ehci_qTD(qTD_T *qtd);
|
||||
extern iTD_T *alloc_ehci_iTD(void);
|
||||
extern void free_ehci_iTD(iTD_T *itd);
|
||||
extern siTD_T *alloc_ehci_siTD(void);
|
||||
extern void free_ehci_siTD(siTD_T *sitd);
|
||||
|
||||
|
||||
extern void usbh_hub_init(void);
|
||||
extern int usbh_connect_device(UDEV_T *);
|
||||
extern void usbh_disconnect_device(UDEV_T *);
|
||||
extern int usbh_register_driver(UDEV_DRV_T *driver);
|
||||
extern EP_INFO_T *usbh_iface_find_ep(IFACE_T *iface, uint8_t ep_addr, uint8_t dir_type);
|
||||
extern int usbh_reset_device(UDEV_T *);
|
||||
extern int usbh_reset_port(UDEV_T *);
|
||||
|
||||
/*
|
||||
* USB Standard Request functions
|
||||
*/
|
||||
extern int usbh_get_device_descriptor(UDEV_T *udev, DESC_DEV_T *desc_buff);
|
||||
extern int usbh_get_config_descriptor(UDEV_T *udev, uint8_t *desc_buff, int buff_len);
|
||||
extern int usbh_set_configuration(UDEV_T *udev, uint8_t conf_val);
|
||||
extern int usbh_set_interface(IFACE_T *iface, uint16_t alt_setting);
|
||||
extern int usbh_clear_halt(UDEV_T *udev, uint16_t ep_addr);
|
||||
|
||||
extern int usbh_ctrl_xfer(UDEV_T *udev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t *buff, uint32_t *xfer_len, uint32_t timeout);
|
||||
extern int usbh_bulk_xfer(UTR_T *utr);
|
||||
extern int usbh_int_xfer(UTR_T *utr);
|
||||
extern int usbh_iso_xfer(UTR_T *utr);
|
||||
extern int usbh_quit_utr(UTR_T *utr);
|
||||
extern int usbh_quit_xfer(UDEV_T *udev, EP_INFO_T *ep);
|
||||
|
||||
|
||||
/// @endcond HIDDEN_SYMBOLS
|
||||
|
||||
#endif /* _USBH_H_ */
|
||||
188
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/usbh_lib.h
Normal file
188
bsp/nuvoton/libraries/nuc980/UsbHostLib/inc/usbh_lib.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/**************************************************************************//**
|
||||
* @file usbh_lib.h
|
||||
* @version V1.10
|
||||
* $Revision: 4 $
|
||||
* $Date: 15/06/10 2:06p $
|
||||
* @brief USB Host library exported header file.
|
||||
*
|
||||
* @note
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
|
||||
******************************************************************************/
|
||||
#ifndef _USBH_LIB_H_
|
||||
#define _USBH_LIB_H_
|
||||
|
||||
#include "nuc980.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/** @addtogroup Library Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Library USB Host Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_EXPORTED_CONSTANTS USB Host Exported Constants
|
||||
@{
|
||||
*/
|
||||
|
||||
#define USBH_OK 0 /*!< No error. */
|
||||
#define USBH_ERR_MEMORY_OUT -10 /*!< Out of memory. */
|
||||
#define USBH_ERR_IF_ALT_LIMIT -11 /*!< Number of alternative interface > MAX_ALT_PER_IFACE */
|
||||
#define USBH_ERR_IF_EP_LIMIT -15 /*!< Number of endpoints > MAX_EP_PER_IFACE */
|
||||
#define USBH_ERR_NOT_SUPPORTED -101 /*!< Device/Class/Transfer not supported */
|
||||
#define USBH_ERR_NOT_MATCHED -103 /*!< Not macthed */
|
||||
#define USBH_ERR_NOT_EXPECTED -104 /*!< Unknown or unexpected */
|
||||
#define USBH_ERR_INVALID_PARAM -105 /*!< Invalid parameter */
|
||||
#define USBH_ERR_NOT_FOUND -106 /*!< Device or interface not found */
|
||||
#define USBH_ERR_EP_NOT_FOUND -107 /*!< Endpoint not found */
|
||||
#define USBH_ERR_DESCRIPTOR -137 /*!< Failed to parse USB descriptors */
|
||||
#define USBH_ERR_SET_DEV_ADDR -139 /*!< Failed to set device address */
|
||||
#define USBH_ERR_SET_CONFIG -151 /*!< Failed to set device configuration */
|
||||
|
||||
#define USBH_ERR_TRANSFER -201 /*!< USB transfer error */
|
||||
#define USBH_ERR_TIMEOUT -203 /*!< USB transfer time-out */
|
||||
#define USBH_ERR_ABORT -205 /*!< USB transfer aborted due to disconnect or reset */
|
||||
#define USBH_ERR_PORT_RESET -255 /*!< Hub port reset failed */
|
||||
#define USBH_ERR_SCH_OVERRUN -257 /*!< USB isochronous schedule overrun */
|
||||
#define USBH_ERR_DISCONNECTED -259 /*!< USB device was disconnected */
|
||||
|
||||
#define USBH_ERR_TRANSACTION -271 /*!< USB transaction timeout, CRC, Bad PID, etc. */
|
||||
#define USBH_ERR_BABBLE_DETECTED -272 /*!< A ¡§babble¡¨ is detected during the transaction */
|
||||
#define USBH_ERR_DATA_BUFF -274 /*!< Data buffer overrun or underrun */
|
||||
|
||||
#define USBH_ERR_CC_NO_ERR -280 /*!< OHCI CC code - no error */
|
||||
#define USBH_ERR_CRC -281 /*!< USB trasfer CRC error */
|
||||
#define USBH_ERR_BIT_STUFF -282 /*!< USB transfer bit stuffing error */
|
||||
#define USBH_ERR_DATA_TOGGLE -283 /*!< USB trasfer data toggle error */
|
||||
#define USBH_ERR_STALL -284 /*!< USB trasfer STALL error */
|
||||
#define USBH_ERR_DEV_NO_RESP -285 /*!< USB trasfer device no response error */
|
||||
#define USBH_ERR_PID_CHECK -286 /*!< USB trasfer PID check failure */
|
||||
#define USBH_ERR_UNEXPECT_PID -287 /*!< USB trasfer unexpected PID error */
|
||||
#define USBH_ERR_DATA_OVERRUN -288 /*!< USB trasfer data overrun error */
|
||||
#define USBH_ERR_DATA_UNDERRUN -289 /*!< USB trasfer data underrun error */
|
||||
#define USBH_ERR_BUFF_OVERRUN -292 /*!< USB trasfer buffer overrun error */
|
||||
#define USBH_ERR_BUFF_UNDERRUN -293 /*!< USB trasfer buffer underrun error */
|
||||
#define USBH_ERR_NOT_ACCESS0 -294 /*!< USB trasfer not accessed error */
|
||||
#define USBH_ERR_NOT_ACCESS1 -295 /*!< USB trasfer not accessed error */
|
||||
|
||||
#define USBH_ERR_OHCI_INIT -301 /*!< Failed to initialize OHIC controller. */
|
||||
#define USBH_ERR_OHCI_EP_BUSY -303 /*!< The endpoint is under transfer. */
|
||||
|
||||
#define USBH_ERR_EHCI_INIT -501 /*!< Failed to initialize EHCI controller. */
|
||||
#define USBH_ERR_EHCI_QH_BUSY -503 /*!< the Queue Head is busy. */
|
||||
|
||||
#define UMAS_OK 0 /*!< No error. */
|
||||
#define UMAS_ERR_NO_DEVICE -1031 /*!< No Mass Stroage Device found. */
|
||||
#define UMAS_ERR_IO -1033 /*!< Device read/write failed. */
|
||||
#define UMAS_ERR_INIT_DEVICE -1035 /*!< failed to init MSC device */
|
||||
#define UMAS_ERR_CMD_STATUS -1037 /*!< SCSI command status failed */
|
||||
#define UMAS_ERR_IVALID_PARM -1038 /*!< Invalid parameter. */
|
||||
#define UMAS_ERR_DRIVE_NOT_FOUND -1039 /*!< drive not found */
|
||||
|
||||
#define HID_RET_OK 0 /*!< Return with no errors. */
|
||||
#define HID_RET_DEV_NOT_FOUND -1081 /*!< HID device not found or removed. */
|
||||
#define HID_RET_IO_ERR -1082 /*!< USB transfer failed. */
|
||||
#define HID_RET_INVALID_PARAMETER -1083 /*!< Invalid parameter. */
|
||||
#define HID_RET_OUT_OF_MEMORY -1084 /*!< Out of memory. */
|
||||
#define HID_RET_NOT_SUPPORTED -1085 /*!< Function not supported. */
|
||||
#define HID_RET_EP_NOT_FOUND -1086 /*!< Endpoint not found. */
|
||||
#define HID_RET_PARSING -1087 /*!< Failed to parse HID descriptor */
|
||||
#define HID_RET_XFER_IS_RUNNING -1089 /*!< The transfer has been enabled. */
|
||||
#define HID_RET_REPORT_NOT_FOUND -1090 /*!< The transfer has been enabled. */
|
||||
|
||||
#define UAC_RET_OK 0 /*!< Return with no errors. */
|
||||
#define UAC_RET_DEV_NOT_FOUND -2001 /*!< Audio Class device not found or removed. */
|
||||
#define UAC_RET_FUNC_NOT_FOUND -2002 /*!< Audio device has no this function. */
|
||||
#define UAC_RET_IO_ERR -2003 /*!< USB transfer failed. */
|
||||
#define UAC_RET_DATA_LEN -2004 /*!< Unexpected transfer length */
|
||||
#define UAC_RET_INVALID -2005 /*!< Invalid parameter or usage. */
|
||||
#define UAC_RET_OUT_OF_MEMORY -2007 /*!< Out of memory. */
|
||||
#define UAC_RET_DRV_NOT_SUPPORTED -2009 /*!< Function not supported by this UAC driver. */
|
||||
#define UAC_RET_DEV_NOT_SUPPORTED -2011 /*!< Function not supported by the UAC device. */
|
||||
#define UAC_RET_PARSER -2013 /*!< Failed to parse UAC descriptor */
|
||||
#define UAC_RET_IS_STREAMING -2015 /*!< Audio pipe is on streaming. */
|
||||
|
||||
|
||||
/*@}*/ /* end of group USBH_EXPORTED_CONSTANTS */
|
||||
|
||||
|
||||
/** @addtogroup USBH_EXPORTED_TYPEDEF USB Host Typedef
|
||||
@{
|
||||
*/
|
||||
struct udev_t;
|
||||
typedef void (CONN_FUNC)(struct udev_t *udev, int param);
|
||||
|
||||
struct line_coding_t;
|
||||
struct cdc_dev_t;
|
||||
typedef void (CDC_CB_FUNC)(struct cdc_dev_t *cdev, uint8_t *rdata, int data_len);
|
||||
|
||||
struct usbhid_dev;
|
||||
typedef void (HID_IR_FUNC)(struct usbhid_dev *hdev, uint16_t ep_addr, int status, uint8_t *rdata, uint32_t data_len); /*!< interrupt in callback function \hideinitializer */
|
||||
typedef void (HID_IW_FUNC)(struct usbhid_dev *hdev, uint16_t ep_addr, int status, uint8_t *wbuff, uint32_t *data_len); /*!< interrupt out callback function \hideinitializer */
|
||||
|
||||
struct uac_dev_t;
|
||||
typedef int (UAC_CB_FUNC)(struct uac_dev_t *dev, uint8_t *data, int len); /*!< audio in callback function \hideinitializer */
|
||||
|
||||
/*@}*/ /* end of group USBH_EXPORTED_STRUCT */
|
||||
|
||||
|
||||
|
||||
/** @addtogroup USBH_EXPORTED_FUNCTIONS USB Host Exported Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* USB Core Library APIs */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
extern void usbh_core_init(void);
|
||||
extern int usbh_polling_root_hubs(void);
|
||||
extern void usbh_install_conn_callback(CONN_FUNC *conn_func, CONN_FUNC *disconn_func);
|
||||
extern void usbh_suspend(void);
|
||||
extern void usbh_resume(void);
|
||||
extern struct udev_t *usbh_find_device(char *hub_id, int port);
|
||||
|
||||
/**
|
||||
* @brief A function return current tick count.
|
||||
* @return Current tick.
|
||||
* @details User application must provide this function to return current tick.
|
||||
* The tick should increase by 1 for every 10 ms.
|
||||
*/
|
||||
extern uint32_t usbh_get_ticks(void); /* This function must be provided by user application. */
|
||||
extern uint32_t usbh_tick_from_millisecond(uint32_t msec); /* This function must be provided by user application. */
|
||||
|
||||
|
||||
/// @cond HIDDEN_SYMBOLS
|
||||
|
||||
extern void dump_ohci_regs(void);
|
||||
extern void dump_ehci_regs(void);
|
||||
extern void dump_ohci_ports(void);
|
||||
extern void dump_ehci_ports(void);
|
||||
extern uint32_t usbh_memory_used(void);
|
||||
|
||||
/// @endcond HIDDEN_SYMBOLS
|
||||
|
||||
|
||||
/*@}*/ /* end of group USBH_EXPORTED_FUNCTIONS */
|
||||
|
||||
/*@}*/ /* end of group USBH_Library */
|
||||
|
||||
/*@}*/ /* end of group LIBRARY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _USBH_LIB_H_ */
|
||||
|
||||
/*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/
|
||||
|
||||
|
||||
|
||||
1288
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ehci.c
Normal file
1288
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ehci.c
Normal file
File diff suppressed because it is too large
Load Diff
918
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ehci_iso.c
Normal file
918
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ehci_iso.c
Normal file
File diff suppressed because it is too large
Load Diff
540
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/mem_alloc.c
Normal file
540
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/mem_alloc.c
Normal file
File diff suppressed because it is too large
Load Diff
1301
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ohci.c
Normal file
1301
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/ohci.c
Normal file
File diff suppressed because it is too large
Load Diff
324
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/support.c
Normal file
324
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/support.c
Normal file
@@ -0,0 +1,324 @@
|
||||
/**************************************************************************//**
|
||||
* @file support.c
|
||||
* @version V1.10
|
||||
* $Revision: 11 $
|
||||
* $Date: 14/10/03 1:54p $
|
||||
* @brief Functions to support USB host driver.
|
||||
*
|
||||
* @note
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "usb.h"
|
||||
|
||||
/// @cond HIDDEN_SYMBOLS
|
||||
|
||||
|
||||
#define USB_MEMORY_POOL_SIZE (32*1024)
|
||||
#define USB_MEM_BLOCK_SIZE 128
|
||||
|
||||
#define BOUNDARY_WORD 4
|
||||
|
||||
|
||||
static uint32_t _FreeMemorySize;
|
||||
uint32_t _AllocatedMemorySize;
|
||||
|
||||
|
||||
#define USB_MEM_ALLOC_MAGIC 0x19685788 /* magic number in leading block */
|
||||
|
||||
typedef struct USB_mhdr
|
||||
{
|
||||
uint32_t flag; /* 0:free, 1:allocated, 0x3:first block */
|
||||
uint32_t bcnt; /* if allocated, the block count of allocated memory block */
|
||||
uint32_t magic;
|
||||
uint32_t reserved;
|
||||
} USB_MHDR_T;
|
||||
|
||||
uint8_t _USBMemoryPool[USB_MEMORY_POOL_SIZE] __attribute__((aligned(USB_MEM_BLOCK_SIZE)));
|
||||
|
||||
|
||||
static USB_MHDR_T *_pCurrent;
|
||||
uint32_t *_USB_pCurrent = (uint32_t *) &_pCurrent;
|
||||
|
||||
static uint32_t _MemoryPoolBase, _MemoryPoolEnd;
|
||||
|
||||
|
||||
void USB_InitializeMemoryPool()
|
||||
{
|
||||
_MemoryPoolBase = (UINT32)&_USBMemoryPool[0] | NON_CACHE_MASK;
|
||||
_MemoryPoolEnd = _MemoryPoolBase + USB_MEMORY_POOL_SIZE;
|
||||
_FreeMemorySize = _MemoryPoolEnd - _MemoryPoolBase;
|
||||
_AllocatedMemorySize = 0;
|
||||
_pCurrent = (USB_MHDR_T *)_MemoryPoolBase;
|
||||
memset((char *)_MemoryPoolBase, 0, _FreeMemorySize);
|
||||
}
|
||||
|
||||
|
||||
int USB_available_memory()
|
||||
{
|
||||
return _FreeMemorySize;
|
||||
}
|
||||
|
||||
|
||||
int USB_allocated_memory()
|
||||
{
|
||||
return _AllocatedMemorySize;
|
||||
}
|
||||
|
||||
|
||||
void *USB_malloc(INT wanted_size, INT boundary)
|
||||
{
|
||||
USB_MHDR_T *pPrimitivePos = _pCurrent;
|
||||
USB_MHDR_T *pFound;
|
||||
INT found_size = -1;
|
||||
INT i, block_count;
|
||||
INT wrap = 0;
|
||||
int disable_ohci_irq, disable_ehci_irq;
|
||||
|
||||
if (IS_OHCI_IRQ_ENABLED())
|
||||
disable_ohci_irq = 1;
|
||||
else
|
||||
disable_ohci_irq = 0;
|
||||
|
||||
if (IS_EHCI_IRQ_ENABLED())
|
||||
disable_ehci_irq = 1;
|
||||
else
|
||||
disable_ehci_irq = 0;
|
||||
|
||||
if (disable_ohci_irq)
|
||||
DISABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
DISABLE_EHCI_IRQ();
|
||||
|
||||
if (wanted_size >= _FreeMemorySize)
|
||||
{
|
||||
rt_kprintf("USB_malloc - want=%d, free=%d\n", wanted_size, _FreeMemorySize);
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((UINT32)_pCurrent >= _MemoryPoolEnd)
|
||||
_pCurrent = (USB_MHDR_T *)_MemoryPoolBase; /* wrapped */
|
||||
|
||||
do
|
||||
{
|
||||
if (_pCurrent->flag) /* is not a free block */
|
||||
{
|
||||
if (_pCurrent->magic != USB_MEM_ALLOC_MAGIC)
|
||||
{
|
||||
rt_kprintf("\nUSB_malloc - incorrect magic number! C:%x F:%x, wanted:%d, Base:0x%x, End:0x%x\n", (UINT32)_pCurrent, _FreeMemorySize, wanted_size, (UINT32)_MemoryPoolBase, (UINT32)_MemoryPoolEnd);
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_pCurrent->flag == 0x3)
|
||||
_pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + _pCurrent->bcnt * USB_MEM_BLOCK_SIZE);
|
||||
else
|
||||
{
|
||||
rt_kprintf("USB_malloc warning - not the first block!\n");
|
||||
_pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if ((UINT32)_pCurrent > _MemoryPoolEnd)
|
||||
rt_kprintf("USB_malloc - behind limit!!\n");
|
||||
|
||||
if ((UINT32)_pCurrent == _MemoryPoolEnd)
|
||||
{
|
||||
//rt_kprintf("USB_alloc - warp!!\n");
|
||||
wrap = 1;
|
||||
_pCurrent = (USB_MHDR_T *)_MemoryPoolBase; /* wrapped */
|
||||
}
|
||||
|
||||
found_size = -1; /* reset the accumlator */
|
||||
}
|
||||
else /* is a free block */
|
||||
{
|
||||
if (found_size == -1) /* the leading block */
|
||||
{
|
||||
pFound = _pCurrent;
|
||||
block_count = 1;
|
||||
|
||||
if (boundary > BOUNDARY_WORD)
|
||||
found_size = 0; /* not use the data area of the leading block */
|
||||
else
|
||||
found_size = USB_MEM_BLOCK_SIZE - sizeof(USB_MHDR_T);
|
||||
|
||||
/* check boundary -
|
||||
* If boundary > BOUNDARY_WORD, the start of next block should
|
||||
* be the beginning address of allocated memory. Thus, we check
|
||||
* the boundary of the next block. The leading block will be
|
||||
* used as a header only.
|
||||
*/
|
||||
if ((boundary > BOUNDARY_WORD) &&
|
||||
((((UINT32)_pCurrent) + USB_MEM_BLOCK_SIZE >= _MemoryPoolEnd) ||
|
||||
((((UINT32)_pCurrent) + USB_MEM_BLOCK_SIZE) % boundary != 0)))
|
||||
found_size = -1; /* violate boundary, reset the accumlator */
|
||||
}
|
||||
else /* not the leading block */
|
||||
{
|
||||
found_size += USB_MEM_BLOCK_SIZE;
|
||||
block_count++;
|
||||
}
|
||||
|
||||
if (found_size >= wanted_size)
|
||||
{
|
||||
pFound->bcnt = block_count;
|
||||
pFound->magic = USB_MEM_ALLOC_MAGIC;
|
||||
_FreeMemorySize -= block_count * USB_MEM_BLOCK_SIZE;
|
||||
_AllocatedMemorySize += block_count * USB_MEM_BLOCK_SIZE;
|
||||
_pCurrent = pFound;
|
||||
for (i = 0; i < block_count; i++)
|
||||
{
|
||||
_pCurrent->flag = 1; /* allocate block */
|
||||
_pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
|
||||
}
|
||||
pFound->flag = 0x3;
|
||||
|
||||
if (boundary > BOUNDARY_WORD)
|
||||
{
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
//rt_kprintf("- 0x%x, %d\n", (int)pFound, wanted_size);
|
||||
return (void *)((UINT32)pFound + USB_MEM_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//USB_debug("USB_malloc(%d,%d):%x\tsize:%d, C:0x%x, %d\n", wanted_size, boundary, (UINT32)pFound + sizeof(USB_MHDR_T), block_count * USB_MEM_BLOCK_SIZE, _pCurrent, block_count);
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
//rt_kprintf("- 0x%x, %d\n", (int)pFound, wanted_size);
|
||||
return (void *)((UINT32)pFound + sizeof(USB_MHDR_T));
|
||||
}
|
||||
}
|
||||
|
||||
/* advance to the next block */
|
||||
_pCurrent = (USB_MHDR_T *)((UINT32)_pCurrent + USB_MEM_BLOCK_SIZE);
|
||||
if ((UINT32)_pCurrent >= _MemoryPoolEnd)
|
||||
{
|
||||
wrap = 1;
|
||||
_pCurrent = (USB_MHDR_T *)_MemoryPoolBase; /* wrapped */
|
||||
found_size = -1; /* reset accumlator */
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((wrap == 0) || (_pCurrent < pPrimitivePos));
|
||||
|
||||
rt_kprintf("USB_malloc - No free memory!\n");
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void USB_free(void *alloc_addr)
|
||||
{
|
||||
USB_MHDR_T *pMblk;
|
||||
UINT32 addr = (UINT32)alloc_addr;
|
||||
INT i, count;
|
||||
int disable_ohci_irq, disable_ehci_irq;
|
||||
|
||||
if (IS_OHCI_IRQ_ENABLED())
|
||||
disable_ohci_irq = 1;
|
||||
else
|
||||
disable_ohci_irq = 0;
|
||||
|
||||
if (IS_EHCI_IRQ_ENABLED())
|
||||
disable_ehci_irq = 1;
|
||||
else
|
||||
disable_ehci_irq = 0;
|
||||
|
||||
//rt_kprintf("USB_free: 0x%x\n", (int)alloc_addr);
|
||||
|
||||
if ((addr < _MemoryPoolBase) || (addr >= _MemoryPoolEnd))
|
||||
{
|
||||
if (addr)
|
||||
{
|
||||
rt_kprintf("[%s]Wrong!!\n", __func__);
|
||||
//free(alloc_addr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (disable_ohci_irq)
|
||||
DISABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
DISABLE_EHCI_IRQ();
|
||||
|
||||
//rt_kprintf("USB_free:%x\n", (INT)addr+USB_MEM_BLOCK_SIZE);
|
||||
|
||||
/* get the leading block address */
|
||||
if (addr % USB_MEM_BLOCK_SIZE == 0)
|
||||
addr -= USB_MEM_BLOCK_SIZE;
|
||||
else
|
||||
addr -= sizeof(USB_MHDR_T);
|
||||
|
||||
if (addr % USB_MEM_BLOCK_SIZE != 0)
|
||||
{
|
||||
rt_kprintf("USB_free fatal error on address: %x!!\n", (UINT32)alloc_addr);
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
return;
|
||||
}
|
||||
|
||||
pMblk = (USB_MHDR_T *)addr;
|
||||
if (pMblk->flag == 0)
|
||||
{
|
||||
rt_kprintf("USB_free(), warning - try to free a free block: %x\n", (UINT32)alloc_addr);
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
return;
|
||||
}
|
||||
if (pMblk->magic != USB_MEM_ALLOC_MAGIC)
|
||||
{
|
||||
rt_kprintf("USB_free(), warning - try to free an unknow block at address:%x.\n", addr);
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
return;
|
||||
}
|
||||
|
||||
//_pCurrent = pMblk;
|
||||
|
||||
//rt_kprintf("+ 0x%x, %d\n", (int)pMblk, pMblk->bcnt);
|
||||
|
||||
count = pMblk->bcnt;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
pMblk->flag = 0; /* release block */
|
||||
pMblk = (USB_MHDR_T *)((UINT32)pMblk + USB_MEM_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
_FreeMemorySize += count * USB_MEM_BLOCK_SIZE;
|
||||
_AllocatedMemorySize -= count * USB_MEM_BLOCK_SIZE;
|
||||
if (disable_ohci_irq)
|
||||
ENABLE_OHCI_IRQ();
|
||||
if (disable_ehci_irq)
|
||||
ENABLE_EHCI_IRQ();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// @endcond HIDDEN_SYMBOLS
|
||||
|
||||
312
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/usb_core.c
Normal file
312
bsp/nuvoton/libraries/nuc980/UsbHostLib/src/usb_core.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/**************************************************************************//**
|
||||
* @file usb_core.c
|
||||
* @version V1.10
|
||||
* $Revision: 11 $
|
||||
* $Date: 14/10/03 1:54p $
|
||||
* @brief USB Host library core.
|
||||
*
|
||||
* @note
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "usb.h"
|
||||
#include "hub.h"
|
||||
|
||||
|
||||
/// @cond HIDDEN_SYMBOLS
|
||||
|
||||
USBH_T *_ohci;
|
||||
HSUSBH_T *_ehci;
|
||||
|
||||
static UDEV_DRV_T *_drivers[MAX_UDEV_DRIVER];
|
||||
|
||||
static CONN_FUNC *g_conn_func, *g_disconn_func;
|
||||
|
||||
|
||||
//extern void EHCI_IRQHandler(void);
|
||||
//extern void OHCI_IRQHandler(void);
|
||||
extern void nu_ohci_isr(int vector, void *param);
|
||||
extern void nu_ehci_isr(int vector, void *param);
|
||||
|
||||
|
||||
/// @endcond HIDDEN_SYMBOLS
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize NUC980 USB Host controller and USB stack.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void usbh_core_init()
|
||||
{
|
||||
DISABLE_EHCI_IRQ();
|
||||
DISABLE_OHCI_IRQ();
|
||||
|
||||
_ohci = USBH;
|
||||
_ehci = HSUSBH;
|
||||
|
||||
memset(_drivers, 0, sizeof(_drivers));
|
||||
|
||||
g_conn_func = NULL;
|
||||
g_disconn_func = NULL;
|
||||
|
||||
// usbh_hub_init();
|
||||
|
||||
_ehci->USBPCR0 = 0x160; /* enable PHY 0 */
|
||||
_ehci->USBPCR1 = 0x520; /* enable PHY 1 */
|
||||
usbh_memory_init();
|
||||
|
||||
//_ohci->HcMiscControl |= USBH_HcMiscControl_OCAL_Msk; /* Over-current active low */
|
||||
_ohci->HcMiscControl &= ~USBH_HcMiscControl_OCAL_Msk; /* Over-current active high */
|
||||
|
||||
#ifdef ENABLE_OHCI
|
||||
//sysInstallISR(IRQ_LEVEL_1, IRQ_OHCI, (PVOID)OHCI_IRQHandler);
|
||||
rt_hw_interrupt_install(IRQ_OHCI, nu_ohci_isr, NULL, "ohci");
|
||||
rt_hw_interrupt_set_priority(IRQ_OHCI, IRQ_LEVEL_1);
|
||||
|
||||
ohci_driver.init();
|
||||
ENABLE_OHCI_IRQ();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_EHCI
|
||||
//sysInstallISR(IRQ_LEVEL_1, IRQ_EHCI, (PVOID)EHCI_IRQHandler);
|
||||
rt_hw_interrupt_install(IRQ_EHCI, nu_ehci_isr, NULL, "ehci");
|
||||
rt_hw_interrupt_set_priority(IRQ_EHCI, IRQ_LEVEL_1);
|
||||
|
||||
ehci_driver.init();
|
||||
ENABLE_EHCI_IRQ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Let USB stack polls all root hubs. If there's any hub port
|
||||
* change found, USB stack will manage the hub events in this function call.
|
||||
* In this function, USB stack enumerates newly connected devices and remove staff
|
||||
* of disconnected devices. User's application should periodically invoke this
|
||||
* function.
|
||||
* @return There's hub port change or not.
|
||||
* @retval 0 No any hub port status changes found.
|
||||
* @retval 1 There's hub port status changes.
|
||||
*/
|
||||
int usbh_polling_root_hubs(void)
|
||||
{
|
||||
int ret, change = 0;
|
||||
|
||||
#ifdef ENABLE_EHCI
|
||||
do
|
||||
{
|
||||
ret = ehci_driver.rthub_polling();
|
||||
if (ret)
|
||||
change = 1;
|
||||
}
|
||||
while (ret == 1);
|
||||
|
||||
// scan_isochronous_list();
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OHCI
|
||||
do
|
||||
{
|
||||
ret = ohci_driver.rthub_polling();
|
||||
if (ret)
|
||||
change = 1;
|
||||
}
|
||||
while (ret == 1);
|
||||
#endif
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force to quit an endpoint transfer.
|
||||
* @param[in] udev The USB device.
|
||||
* @param[in] ep The endpoint to be quit.
|
||||
* @retval 0 Transfer success
|
||||
* @retval < 0 Failed. Refer to error code definitions.
|
||||
*/
|
||||
int usbh_quit_xfer(UDEV_T *udev, EP_INFO_T *ep)
|
||||
{
|
||||
return udev->hc_driver->quit_xfer(NULL, ep);
|
||||
}
|
||||
|
||||
|
||||
int usbh_connect_device(UDEV_T *udev)
|
||||
{
|
||||
usbh_delay_ms(100); /* initially, give 100 ms delay */
|
||||
|
||||
if (g_conn_func)
|
||||
g_conn_func(udev, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void usbh_disconnect_device(UDEV_T *udev)
|
||||
{
|
||||
USB_debug("disconnect device...\n");
|
||||
|
||||
if (g_disconn_func)
|
||||
g_disconn_func(udev, 0);
|
||||
|
||||
|
||||
#if 1 //CHECK: Maybe create a new API to quit_xfer and free udev for application
|
||||
usbh_quit_xfer(udev, &(udev->ep0)); /* Quit control transfer if hw_pipe is not NULL. */
|
||||
|
||||
/* remove device from global device list */
|
||||
// free_dev_address(udev->dev_num);
|
||||
free_device(udev);
|
||||
|
||||
// usbh_memory_used();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Install device connect and disconnect callback function.
|
||||
*
|
||||
* @param[in] conn_func Device connect callback function.
|
||||
* @param[in] disconn_func Device disconnect callback function.
|
||||
* @return None.
|
||||
*/
|
||||
void usbh_install_conn_callback(CONN_FUNC *conn_func, CONN_FUNC *disconn_func)
|
||||
{
|
||||
g_conn_func = conn_func;
|
||||
g_disconn_func = disconn_func;
|
||||
}
|
||||
|
||||
int usbh_reset_port(UDEV_T *udev)
|
||||
{
|
||||
if (udev->parent == NULL)
|
||||
{
|
||||
if (udev->hc_driver)
|
||||
return udev->hc_driver->rthub_port_reset(udev->port_num - 1);
|
||||
else
|
||||
return USBH_ERR_NOT_FOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
return udev->parent->port_reset(udev->parent, udev->port_num);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Force to quit an UTR transfer.
|
||||
* @param[in] utr The UTR transfer to be quit.
|
||||
* @retval 0 Transfer success
|
||||
* @retval < 0 Failed. Refer to error code definitions.
|
||||
*/
|
||||
int usbh_quit_utr(UTR_T *utr)
|
||||
{
|
||||
if (!utr || !utr->udev)
|
||||
return USBH_ERR_NOT_FOUND;
|
||||
|
||||
return utr->udev->hc_driver->quit_xfer(utr, NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Execute an USB request in control transfer. This function returns after the request
|
||||
* was done or aborted.
|
||||
* @param[in] udev The target USB device.
|
||||
* @param[in] bmRequestType Characteristics of request
|
||||
* @param[in] bRequest Specific request
|
||||
* @param[in] wValue Word-sized field that varies according to request
|
||||
* @param[in] wIndex Word-sized field that varies according to request
|
||||
* @param[in] wLength Number of bytes to transfer if there is a Data stage
|
||||
* @param[in] buff Data buffer used in data stage
|
||||
* @param[out] xfer_len Transmitted/received length of data
|
||||
* @param[in] timeout Time-out limit (in 10ms - timer tick) of this transfer
|
||||
* @retval 0 Transfer success
|
||||
* @retval < 0 Transfer failed. Refer to error code definitions.
|
||||
*/
|
||||
int usbh_ctrl_xfer(UDEV_T *udev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
|
||||
uint16_t wLength, uint8_t *buff, uint32_t *xfer_len, uint32_t timeout)
|
||||
{
|
||||
UTR_T *utr;
|
||||
uint32_t t0, timeout_tick;
|
||||
int status;
|
||||
|
||||
*xfer_len = 0;
|
||||
|
||||
//if (check_device(udev))
|
||||
// return USBH_ERR_INVALID_PARAM;
|
||||
|
||||
utr = alloc_utr(udev);
|
||||
if (utr == NULL)
|
||||
return USBH_ERR_MEMORY_OUT;
|
||||
|
||||
utr->setup.bmRequestType = bmRequestType;
|
||||
utr->setup.bRequest = bRequest;
|
||||
utr->setup.wValue = wValue;
|
||||
utr->setup.wIndex = wIndex;
|
||||
utr->setup.wLength = wLength;
|
||||
|
||||
utr->buff = buff;
|
||||
utr->data_len = wLength;
|
||||
utr->bIsTransferDone = 0;
|
||||
status = udev->hc_driver->ctrl_xfer(utr);
|
||||
if (status < 0)
|
||||
{
|
||||
udev->ep0.hw_pipe = NULL;
|
||||
free_utr(utr);
|
||||
return status;
|
||||
}
|
||||
|
||||
timeout_tick = usbh_tick_from_millisecond(timeout);
|
||||
t0 = usbh_get_ticks();
|
||||
while (utr->bIsTransferDone == 0)
|
||||
{
|
||||
if (usbh_get_ticks() - t0 > timeout_tick)
|
||||
{
|
||||
usbh_quit_utr(utr);
|
||||
free_utr(utr);
|
||||
udev->ep0.hw_pipe = NULL;
|
||||
return USBH_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
status = utr->status;
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
*xfer_len = utr->xfer_len;
|
||||
}
|
||||
free_utr(utr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute a bulk transfer request. This function will return immediately after
|
||||
* issued the bulk transfer. USB stack will later call back utr->func() once the bulk
|
||||
* transfer was done or aborted.
|
||||
* @param[in] utr The bulk transfer request.
|
||||
* @retval 0 Transfer success
|
||||
* @retval < 0 Failed. Refer to error code definitions.
|
||||
*/
|
||||
int usbh_bulk_xfer(UTR_T *utr)
|
||||
{
|
||||
return utr->udev->hc_driver->bulk_xfer(utr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute an interrupt transfer request. This function will return immediately after
|
||||
* issued the interrupt transfer. USB stack will later call back utr->func() once the
|
||||
* interrupt transfer was done or aborted.
|
||||
* @param[in] utr The interrupt transfer request.
|
||||
* @retval 0 Transfer success
|
||||
* @retval < 0 Failed. Refer to error code definitions.
|
||||
*/
|
||||
int usbh_int_xfer(UTR_T *utr)
|
||||
{
|
||||
return utr->udev->hc_driver->int_xfer(utr);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,13 +114,6 @@ config SOC_SERIES_NUC980
|
||||
help
|
||||
Choose this option if you need TIMER function mode.
|
||||
|
||||
config BSP_USING_TPWM0
|
||||
select BSP_USING_TPWM
|
||||
select RT_USING_PWM
|
||||
bool "TIMER PWM"
|
||||
help
|
||||
Choose this option if you need PWM function mode.
|
||||
|
||||
config BSP_USING_TIMER0_CAPTURE
|
||||
select BSP_USING_TIMER_CAPTURE
|
||||
select RT_USING_INPUT_CAPTURE
|
||||
@@ -146,13 +139,6 @@ config SOC_SERIES_NUC980
|
||||
help
|
||||
Choose this option if you need TIMER function mode.
|
||||
|
||||
config BSP_USING_TPWM1
|
||||
select BSP_USING_TPWM
|
||||
select RT_USING_PWM
|
||||
bool "TIMER PWM"
|
||||
help
|
||||
Choose this option if you need PWM function mode.
|
||||
|
||||
config BSP_USING_TIMER1_CAPTURE
|
||||
select BSP_USING_TIMER_CAPTURE
|
||||
select RT_USING_INPUT_CAPTURE
|
||||
@@ -177,13 +163,6 @@ config SOC_SERIES_NUC980
|
||||
help
|
||||
Choose this option if you need TIMER function mode.
|
||||
|
||||
config BSP_USING_TPWM2
|
||||
select BSP_USING_TPWM
|
||||
select RT_USING_PWM
|
||||
bool "TIMER PWM"
|
||||
help
|
||||
Choose this option if you need PWM function mode.
|
||||
|
||||
config BSP_USING_TIMER2_CAPTURE
|
||||
select BSP_USING_TIMER_CAPTURE
|
||||
select RT_USING_INPUT_CAPTURE
|
||||
@@ -208,13 +187,6 @@ config SOC_SERIES_NUC980
|
||||
help
|
||||
Choose this option if you need TIMER function mode.
|
||||
|
||||
config BSP_USING_TPWM3
|
||||
select BSP_USING_TPWM
|
||||
select RT_USING_PWM
|
||||
bool "TIMER PWM"
|
||||
help
|
||||
Choose this option if you need PWM function mode.
|
||||
|
||||
config BSP_USING_TIMER3_CAPTURE
|
||||
select BSP_USING_TIMER_CAPTURE
|
||||
select RT_USING_INPUT_CAPTURE
|
||||
@@ -239,13 +211,6 @@ config SOC_SERIES_NUC980
|
||||
help
|
||||
Choose this option if you need TIMER function mode.
|
||||
|
||||
config BSP_USING_TPWM4
|
||||
select BSP_USING_TPWM
|
||||
select RT_USING_PWM
|
||||
bool "TIMER PWM"
|
||||
help
|
||||
Choose this option if you need PWM function mode.
|
||||
|
||||
config BSP_USING_TIMER4_CAPTURE
|
||||
select BSP_USING_TIMER_CAPTURE
|
||||
select RT_USING_INPUT_CAPTURE
|
||||
@@ -634,9 +599,4 @@ config SOC_SERIES_NUC980
|
||||
config BSP_USING_USBH
|
||||
bool "Enable USB Host Controller(USBH)"
|
||||
select RT_USING_USB_HOST
|
||||
select RT_USBH_MSTORAGE
|
||||
|
||||
config BSP_USING_OTG
|
||||
bool "Enable USB On-The-Go(OTG)"
|
||||
select BSP_USING_USBH
|
||||
select BSP_USING_USBD
|
||||
select RT_USBH_MSTORAGE
|
||||
@@ -9,6 +9,6 @@ CPPPATH = [cwd]
|
||||
group = []
|
||||
|
||||
# USB driver constrain
|
||||
group = DefineGroup('nuc980_rttport', src, depend = [''], CPPPATH = CPPPATH)
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
|
||||
@@ -22,22 +22,11 @@ static struct mem_desc hw_mem_desc[] =
|
||||
{ 0x00000000, 0xFFFFFFFF, 0x00000000, RW_NCNB }, /* None cached for 4G memory */
|
||||
{ 0x00000000, BOARD_SDRAM_SIZE - 1, 0x00000000, RW_CB }, /* 64M cached DDR memory */
|
||||
{ BIT31, (BIT31 | BOARD_SDRAM_SIZE) - 1, BIT31, RW_NCNB }, /* Shadow DDR Map */
|
||||
{ 0x3C000000, 0x3C00E000 - 1, 0x3C000000, RW_NCNB }, /* 56K SRAM memory */
|
||||
{ 0xBC000000, 0xBC00E000 - 1, 0xBC000000, RW_NCNB } /* 56K Shadow memory */
|
||||
{ 0x3C000000, 0x3C004000 - 1, 0x3C000000, RW_NCNB }, /* 16K SRAM memory */
|
||||
{ 0xBC000000, 0xBC004000 - 1, 0xBC000000, RW_NCNB } /* 16K Shadow memory */
|
||||
};
|
||||
#endif
|
||||
|
||||
void nu_clock_base_dump(void)
|
||||
{
|
||||
rt_kprintf("SYS_UPLL = %d\n", sysGetClock(SYS_UPLL));
|
||||
rt_kprintf("SYS_APLL = %d\n", sysGetClock(SYS_APLL));
|
||||
rt_kprintf("SYS_SYSTEM = %d\n", sysGetClock(SYS_SYSTEM));
|
||||
rt_kprintf("SYS_HCLK = %d\n", sysGetClock(SYS_HCLK));
|
||||
rt_kprintf("SYS_PCLK01 = %d\n", sysGetClock(SYS_PCLK01));
|
||||
rt_kprintf("SYS_PCLK2 = %d\n", sysGetClock(SYS_PCLK2));
|
||||
rt_kprintf("SYS_CPU = %d\n", sysGetClock(SYS_CPU));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will initial M487 board.
|
||||
*/
|
||||
@@ -52,6 +41,12 @@ RT_WEAK void rt_hw_board_init(void)
|
||||
#if defined(BSP_USING_MMU)
|
||||
/* initialize mmu */
|
||||
rt_hw_mmu_init(&hw_mem_desc[0], sizeof(hw_mem_desc) / sizeof(hw_mem_desc[0]));
|
||||
#else
|
||||
/* disable I/D cache */
|
||||
mmu_disable_dcache();
|
||||
mmu_disable_icache();
|
||||
mmu_disable();
|
||||
mmu_invalidate_tlb();
|
||||
#endif
|
||||
|
||||
/* initialize hardware interrupt */
|
||||
@@ -72,9 +67,6 @@ RT_WEAK void rt_hw_board_init(void)
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
#endif
|
||||
|
||||
nu_clock_base_dump();
|
||||
rt_kprintf("HEAP_START=0x%08x, HEAP_END=0x%08x\n", BOARD_HEAP_START, BOARD_HEAP_END);
|
||||
|
||||
#ifdef RT_USING_COMPONENTS_INIT
|
||||
rt_components_board_init();
|
||||
#endif
|
||||
|
||||
@@ -75,6 +75,7 @@ static rt_err_t nu_aes_crypt_run(
|
||||
{
|
||||
uint32_t au32SwapKey[8];
|
||||
uint32_t au32SwapIV[4];
|
||||
rt_err_t result;
|
||||
|
||||
au32SwapKey[0] = nu_get32_be(&pu8Key[0]);
|
||||
au32SwapKey[1] = nu_get32_be(&pu8Key[4]);
|
||||
@@ -98,7 +99,8 @@ static rt_err_t nu_aes_crypt_run(
|
||||
au32SwapIV[2] = nu_get32_be(&pu8IV[8]);
|
||||
au32SwapIV[3] = nu_get32_be(&pu8IV[12]);
|
||||
|
||||
rt_mutex_take(&s_AES_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_AES_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
AES_Open(CRPT, bEncrypt, u32OpMode, u32KeySize, AES_IN_OUT_SWAP);
|
||||
AES_SetKey(CRPT, (uint32_t *)&au32SwapKey[0], u32KeySize);
|
||||
@@ -137,7 +139,8 @@ static rt_err_t nu_aes_crypt_run(
|
||||
/* Clear AES interrupt status */
|
||||
AES_CLR_INT_FLAG(CRPT);
|
||||
|
||||
rt_mutex_release(&s_AES_mutex);
|
||||
result = rt_mutex_release(&s_AES_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
@@ -145,19 +148,25 @@ static rt_err_t nu_aes_crypt_run(
|
||||
//Using PRNG instead of TRNG
|
||||
static void nu_prng_open(uint32_t u32Seed)
|
||||
{
|
||||
rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
//Open PRNG 64 bits. But always return 32 bits
|
||||
PRNG_Open(CRPT, PRNG_KEY_SIZE_64, PRNG_SEED_RELOAD, u32Seed);
|
||||
|
||||
rt_mutex_release(&s_PRNG_mutex);
|
||||
result = rt_mutex_release(&s_PRNG_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
|
||||
static rt_uint32_t nu_prng_run(void)
|
||||
{
|
||||
uint32_t au32RNGValue[2];
|
||||
rt_err_t result;
|
||||
|
||||
rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_PRNG_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
PRNG_Start(CRPT);
|
||||
while ((CRPT->PRNG_CTL & CRPT_PRNG_CTL_BUSY_Msk)) {};
|
||||
@@ -167,7 +176,8 @@ static rt_uint32_t nu_prng_run(void)
|
||||
|
||||
PRNG_Read(CRPT, &au32RNGValue[0]);
|
||||
|
||||
rt_mutex_release(&s_PRNG_mutex);
|
||||
result = rt_mutex_release(&s_PRNG_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return au32RNGValue[0];
|
||||
}
|
||||
@@ -340,10 +350,13 @@ static rt_err_t nu_sha_hash_run(
|
||||
uint32_t u32DataLen
|
||||
)
|
||||
{
|
||||
rt_err_t result;
|
||||
|
||||
RT_ASSERT(psSHACtx != RT_NULL);
|
||||
RT_ASSERT(pu8InData != RT_NULL);
|
||||
|
||||
rt_mutex_take(&s_SHA_mutex, RT_WAITING_FOREVER);
|
||||
result = rt_mutex_take(&s_SHA_mutex, RT_WAITING_FOREVER);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
uint8_t *pu8SrcAddr = (uint8_t *)pu8InData;
|
||||
uint32_t u32CopyLen = 0;
|
||||
@@ -383,7 +396,8 @@ static rt_err_t nu_sha_hash_run(
|
||||
if (psSHACtx->pu8SHATempBuf == RT_NULL)
|
||||
{
|
||||
LOG_E("fun[%s] memory allocate %d bytes failed!", __FUNCTION__, psSHACtx->u32BlockSize);
|
||||
rt_mutex_release(&s_SHA_mutex);
|
||||
result = rt_mutex_release(&s_SHA_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
@@ -411,7 +425,8 @@ static rt_err_t nu_sha_hash_run(
|
||||
if (psSHACtx->pu8SHATempBuf == RT_NULL)
|
||||
{
|
||||
LOG_E("fun[%s] memory allocate %d bytes failed!", __FUNCTION__, psSHACtx->u32BlockSize);
|
||||
rt_mutex_release(&s_SHA_mutex);
|
||||
result = rt_mutex_release(&s_SHA_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
@@ -422,7 +437,8 @@ static rt_err_t nu_sha_hash_run(
|
||||
psSHACtx->u32SHATempBufLen += u32DataLen;
|
||||
}
|
||||
|
||||
rt_mutex_release(&s_SHA_mutex);
|
||||
result = rt_mutex_release(&s_SHA_mutex);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
@@ -232,7 +232,6 @@ static void link_monitor(void *param)
|
||||
nu_emac_t psNuEmac = (nu_emac_t)param;
|
||||
EMAC_T *EMAC = psNuEmac->memmgr.psEmac;
|
||||
uint32_t LinkStatus_Last = EMAC_LINK_DOWN;
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
EMAC_PhyInit(EMAC);
|
||||
|
||||
@@ -274,9 +273,6 @@ static void link_monitor(void *param)
|
||||
else
|
||||
{
|
||||
eth_device_linkchange(&psNuEmac->eth, RT_TRUE);
|
||||
|
||||
result = rt_sem_release(&psNuEmac->eth_sem);
|
||||
RT_ASSERT(result == RT_EOK);
|
||||
}
|
||||
LinkStatus_Last = LinkStatus_Current;
|
||||
|
||||
@@ -317,7 +313,8 @@ static rt_err_t nu_emac_init(rt_device_t dev)
|
||||
|
||||
snprintf(szTmp, sizeof(szTmp), "%sphy", psNuEmac->name);
|
||||
|
||||
rt_sem_init(&psNuEmac->eth_sem, "eth_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
ret = rt_sem_init(&psNuEmac->eth_sem, "eth_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
RT_ASSERT(ret == RT_EOK);
|
||||
|
||||
EMAC_Reset(EMAC);
|
||||
|
||||
@@ -402,26 +399,21 @@ static rt_err_t nu_emac_tx(rt_device_t dev, struct pbuf *p)
|
||||
rt_uint32_t offset = 0;
|
||||
rt_uint8_t *buf;
|
||||
|
||||
if (psNuEmac->eth.link_status == RT_FALSE)
|
||||
{
|
||||
rt_kprintf("[%s]Stand here.\n", psNuEmac->name);
|
||||
while (rt_sem_take(&psNuEmac->eth_sem, RT_WAITING_FOREVER) != RT_EOK);
|
||||
rt_kprintf("[%s]Leave.\n", psNuEmac->name);
|
||||
}
|
||||
|
||||
buf = (rt_uint8_t *)EMAC_ClaimFreeTXBuf(&psNuEmac->memmgr);
|
||||
|
||||
/* Get free TX buffer */
|
||||
if (buf == RT_NULL)
|
||||
{
|
||||
rt_sem_control(&psNuEmac->eth_sem, RT_IPC_CMD_RESET, 0);
|
||||
rt_err_t result;
|
||||
|
||||
result = rt_sem_control(&psNuEmac->eth_sem, RT_IPC_CMD_RESET, 0);
|
||||
RT_ASSERT(result != RT_EOK);
|
||||
|
||||
EMAC_CLEAR_INT_FLAG(EMAC, EMAC_INTSTS_TXCPIF_Msk);
|
||||
EMAC_ENABLE_INT(EMAC, EMAC_INTEN_TXCPIEN_Msk);
|
||||
|
||||
do
|
||||
{
|
||||
rt_sem_take(&psNuEmac->eth_sem, 1);
|
||||
result = rt_sem_take(&psNuEmac->eth_sem, 10);
|
||||
buf = (rt_uint8_t *)EMAC_ClaimFreeTXBuf(&psNuEmac->memmgr);
|
||||
}
|
||||
while (buf == RT_NULL);
|
||||
|
||||
240
bsp/nuvoton/libraries/nuc980/rtt_port/drv_etimer_capture.c
Normal file
240
bsp/nuvoton/libraries/nuc980/rtt_port/drv_etimer_capture.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/**************************************************************************//**
|
||||
*
|
||||
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-1-28 Wayne First version
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <rtconfig.h>
|
||||
|
||||
#if defined(BSP_USING_TIMER_CAPTURE)
|
||||
|
||||
#include <rtdevice.h>
|
||||
#include <NuMicro.h>
|
||||
#include <drv_sys.h>
|
||||
|
||||
/* Private define ---------------------------------------------------------------*/
|
||||
|
||||
/* Timer prescale setting. Since it will affect the pulse width of measure, it is recommended to set to 2. */
|
||||
#define PSC_DIV (2)
|
||||
|
||||
#define NU_TCAP_DEVICE(etimer) (nu_capture_t*)(etimer)
|
||||
enum
|
||||
{
|
||||
TCAP_START = -1,
|
||||
#if defined(BSP_USING_TIMER0_CAPTURE)
|
||||
TCAP0_IDX,
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER1_CAPTURE)
|
||||
TCAP1_IDX,
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER2_CAPTURE)
|
||||
TCAP2_IDX,
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER3_CAPTURE)
|
||||
TCAP3_IDX,
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER4_CAPTURE)
|
||||
TCAP4_IDX,
|
||||
#endif
|
||||
/* BSP_USING_TIMER5 is reserved for Systick usage. */
|
||||
TCAP_CNT
|
||||
};
|
||||
|
||||
/* Private typedef --------------------------------------------------------------*/
|
||||
typedef struct _timer
|
||||
{
|
||||
struct rt_inputcapture_device parent;
|
||||
char *name;
|
||||
uint32_t idx;
|
||||
IRQn_Type irqn;
|
||||
E_SYS_IPRST rstidx;
|
||||
E_SYS_IPCLK clkidx;
|
||||
|
||||
uint32_t u32CurrentCnt;
|
||||
} nu_capture_t;
|
||||
|
||||
/* Private functions ------------------------------------------------------------*/
|
||||
static rt_err_t nu_capture_init(struct rt_inputcapture_device *inputcapture);
|
||||
static rt_err_t nu_capture_open(struct rt_inputcapture_device *inputcapture);
|
||||
static rt_err_t nu_capture_close(struct rt_inputcapture_device *inputcapture);
|
||||
static rt_err_t nu_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us);
|
||||
|
||||
/* Public functions -------------------------------------------------------------*/
|
||||
|
||||
/* Private variables ------------------------------------------------------------*/
|
||||
static nu_capture_t nu_etcap_arr [] =
|
||||
{
|
||||
#if defined(BSP_USING_TIMER0_CAPTURE)
|
||||
{
|
||||
.name = "timer0i0",
|
||||
.idx = 0,
|
||||
.irqn = IRQ_TIMER0,
|
||||
.rstidx = TIMER0RST,
|
||||
.clkidx = TIMER0CKEN,
|
||||
},
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER1_CAPTURE)
|
||||
{
|
||||
.name = "timer1i0",
|
||||
.idx = 1,
|
||||
.irqn = IRQ_TIMER1,
|
||||
.rstidx = TIMER1RST,
|
||||
.clkidx = TIMER1CKEN,
|
||||
},
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER2_CAPTURE)
|
||||
{
|
||||
.name = "timer2i0",
|
||||
.idx = 2,
|
||||
.irqn = IRQ_TIMER2,
|
||||
.rstidx = TIMER2RST,
|
||||
.clkidx = TIMER2CKEN,
|
||||
},
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER3_CAPTURE)
|
||||
{
|
||||
.name = "timer3i0",
|
||||
.idx = 3,
|
||||
.irqn = IRQ_TIMER3,
|
||||
.rstidx = TIMER3RST,
|
||||
.clkidx = TIMER3CKEN,
|
||||
},
|
||||
#endif
|
||||
#if defined(BSP_USING_TIMER4_CAPTURE)
|
||||
{
|
||||
.name = "timer4i0",
|
||||
.idx = 4,
|
||||
.irqn = IRQ_TIMER4,
|
||||
.rstidx = TIMER4RST,
|
||||
.clkidx = TIMER4CKEN,
|
||||
},
|
||||
#endif
|
||||
/* BSP_USING_TIMER5 is reserved for Systick usage. */
|
||||
};
|
||||
|
||||
static struct rt_inputcapture_ops nu_capture_ops =
|
||||
{
|
||||
.init = nu_capture_init,
|
||||
.open = nu_capture_open,
|
||||
.close = nu_capture_close,
|
||||
.get_pulsewidth = nu_capture_get_pulsewidth,
|
||||
};
|
||||
|
||||
/* Functions define ------------------------------------------------------------*/
|
||||
static void nu_tcap_isr(int vector, void *param)
|
||||
{
|
||||
nu_capture_t *psNuTCap = NU_TCAP_DEVICE(param);
|
||||
|
||||
RT_ASSERT(psNuTCap != RT_NULL);
|
||||
|
||||
ETIMER_ClearCaptureIntFlag(psNuTCap->idx);
|
||||
|
||||
/* Report caputring data and level. */
|
||||
psNuTCap->u32CurrentCnt = ETIMER_GetCaptureData(psNuTCap->idx);
|
||||
rt_hw_inputcapture_isr(&psNuTCap->parent, ETIMER_GetCaptureFallingEdgeFlag(psNuTCap->idx));
|
||||
}
|
||||
|
||||
static rt_err_t nu_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us)
|
||||
{
|
||||
nu_capture_t *psNuTCap = NU_TCAP_DEVICE(inputcapture);
|
||||
|
||||
RT_ASSERT(inputcapture != RT_NULL);
|
||||
RT_ASSERT(pulsewidth_us != RT_NULL);
|
||||
|
||||
*pulsewidth_us = psNuTCap->u32CurrentCnt / PSC_DIV;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t nu_capture_init(struct rt_inputcapture_device *inputcapture)
|
||||
{
|
||||
nu_capture_t *psNuTCap = NU_TCAP_DEVICE(inputcapture);
|
||||
|
||||
RT_ASSERT(inputcapture != RT_NULL);
|
||||
|
||||
nu_sys_ipclk_enable(psNuTCap->clkidx);
|
||||
nu_sys_ip_reset(psNuTCap->rstidx);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static uint8_t cal_time_prescale(nu_capture_t *psNuTCap)
|
||||
{
|
||||
uint32_t u32Clk = ETIMER_GetModuleClock(psNuTCap->idx);
|
||||
|
||||
/* 1 tick = 1/PSC_DIV us */
|
||||
return (u32Clk / 1000000 / PSC_DIV) - 1;
|
||||
}
|
||||
|
||||
static rt_err_t nu_capture_open(struct rt_inputcapture_device *inputcapture)
|
||||
{
|
||||
nu_capture_t *psNuTCap = NU_TCAP_DEVICE(inputcapture);
|
||||
|
||||
RT_ASSERT(inputcapture != RT_NULL);
|
||||
|
||||
/* Enable Timer Interrupt */
|
||||
rt_hw_interrupt_umask(psNuTCap->irqn);
|
||||
|
||||
/* Clear counter before openning. */
|
||||
ETIMER_ClearCounter(psNuTCap->idx);
|
||||
|
||||
ETIMER_Open(psNuTCap->idx, ETIMER_CONTINUOUS_MODE, 1);
|
||||
|
||||
ETIMER_SET_PRESCALE_VALUE(psNuTCap->idx, cal_time_prescale(psNuTCap));
|
||||
|
||||
ETIMER_SET_CMP_VALUE(psNuTCap->idx, 0xFFFFFF);
|
||||
|
||||
ETIMER_EnableCapture(psNuTCap->idx, ETIMER_CAPTURE_COUNTER_RESET_MODE, ETIMER_CAPTURE_RISING_THEN_FALLING_EDGE);
|
||||
|
||||
ETIMER_EnableCaptureInt(psNuTCap->idx);
|
||||
|
||||
ETIMER_Start(psNuTCap->idx);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t nu_capture_close(struct rt_inputcapture_device *inputcapture)
|
||||
{
|
||||
nu_capture_t *psNuTCap = NU_TCAP_DEVICE(inputcapture);
|
||||
|
||||
RT_ASSERT(inputcapture != RT_NULL);
|
||||
|
||||
ETIMER_Stop(psNuTCap->idx);
|
||||
|
||||
ETIMER_DisableCaptureInt(psNuTCap->idx);
|
||||
|
||||
ETIMER_Close(psNuTCap->idx);
|
||||
|
||||
rt_hw_interrupt_mask(psNuTCap->irqn);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/* Init and register timer capture */
|
||||
static int nu_timer_capture_device_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = (TCAP_START + 1); i < TCAP_CNT; i++)
|
||||
{
|
||||
/* Register operations */
|
||||
nu_etcap_arr[i].parent.ops = &nu_capture_ops;
|
||||
|
||||
/* Install ISR */
|
||||
rt_hw_interrupt_install(nu_etcap_arr[i].irqn, nu_tcap_isr, &nu_etcap_arr[i], nu_etcap_arr[i].name);
|
||||
|
||||
/* Register inputcapture device */
|
||||
rt_device_inputcapture_register(&nu_etcap_arr[i].parent, nu_etcap_arr[i].name, &nu_etcap_arr[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(nu_timer_capture_device_init);
|
||||
|
||||
#endif //#if defined(BSP_USING_TIMER_CAPTURE)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user