2022-06-24 22:28:36 +08:00

314 lines
7.7 KiB
C

/*
* Copyright 2021 MindMotion Microelectronics Co., Ltd.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "hal_usb.h"
void USB_SetBufDespTableAddr(USB_Type * USBx, uint32_t addr)
{
USBx->FSBDTPAGE1 = USB_FSBDTPAGE1_BDTBA(addr >> 9u);
USBx->FSBDTPAGE2 = USB_FSBDTPAGE2_BDTBA(addr >> 16u);
USBx->FSBDTPAGE3 = USB_FSBDTPAGE3_BDTBA(addr >> 24u);
}
void USB_InitDevice(USB_Type * USBx, USB_Device_Init_Type *init)
{
if ( (uintptr_t)(init->BufDespTable_Addr) % 512u != 0u)
{
return;
}
USB_SetDeviceAddr(USBx, 0x00u);
USB_SetBufDespTableAddr(USBx, init->BufDespTable_Addr);
USB_Enable(USBx, true);
}
void USB_EnableInterrupts(USB_Type * USBx, uint32_t interrupts, bool enable)
{
if(enable)
{
USBx->FSINTENB |= interrupts;
}
else
{
USBx->FSINTENB &= ~interrupts;
}
}
uint32_t USB_GetEnabledInterrupts(USB_Type * USBx)
{
return USBx->FSINTENB;
}
uint32_t USB_GetInterruptStatus(USB_Type * USBx)
{
uint32_t stat = USBx->FSINTSTAT;
uint32_t enb = USBx->FSINTENB;
return stat & enb;
}
void USB_ClearInterruptStatus(USB_Type * USBx, uint32_t interrupts)
{
uint32_t enb = USBx->FSINTENB;
USBx->FSINTSTAT = interrupts & enb;
}
void USB_EnableErrInterrupts(USB_Type * USBx, uint32_t interrupts, bool enable)
{
if(enable)
{
USBx->FSERRENB |= interrupts;
}
else
{
USBx->FSERRENB &= ~interrupts;
}
}
uint32_t USB_GetEnabledErrInterrupts(USB_Type * USBx)
{
return USBx->FSERRENB;
}
uint32_t USB_GetErrInterruptStatus(USB_Type * USBx)
{
uint32_t stat = USBx->FSERRSTAT;
uint32_t enb = USBx->FSERRENB;
USBx->FSERRSTAT = stat & ~enb;
return stat & enb;
}
void USB_ClearErrInterruptStatus(USB_Type * USBx, uint32_t interrupts)
{
uint32_t enb = USBx->FSERRENB;
USBx->FSERRSTAT = interrupts & enb;
}
uint32_t USB_GetBufDespIndex(USB_Type * USBx)
{
return (USBx->FSSTAT)>>2;
}
void USB_Enable(USB_Type * USBx, bool enable)
{
if(enable)
{
USBx->FSCTL |= USB_FSCTL_USBEN_MASK;
}
else
{
USBx->FSCTL &= ~USB_FSCTL_USBEN_MASK;
}
}
void USB_EnableOddEvenReset(USB_Type * USBx, bool enable)
{
if(enable)
{
USBx->FSCTL |= USB_FSCTL_ODDRST_MASK;
}
else
{
USBx->FSCTL &= ~USB_FSCTL_ODDRST_MASK;
}
}
void USB_EnableResumeSignal(USB_Type * USBx, bool enable)
{
if(enable)
{
USBx->FSCTL |= USB_FSCTL_RESUME_MASK;
}
else
{
USBx->FSCTL &= ~USB_FSCTL_RESUME_MASK;
}
}
void USB_EnableSuspend(USB_Type * USBx, bool enable)
{
if(true == enable)
{
USBx->FSCTL |= USB_FSCTL_TXDSUSPENDTOKENBUSY_MASK;
}
else
{
USBx->FSCTL &= ~USB_FSCTL_TXDSUSPENDTOKENBUSY_MASK;
}
}
void USB_SetDeviceAddr(USB_Type * USBx, uint8_t addr)
{
USBx->FSADDR = ( (USBx->FSADDR & ~USB_FSADDR_ADDR_MASK)
| (addr & USB_FSADDR_ADDR_MASK) )
;
}
uint8_t USB_GetDeviceAddr(USB_Type * USBx)
{
return USBx->FSADDR & USB_FSADDR_ADDR_MASK;
}
uint32_t USB_GetBufDespTableAddr(USB_Type * USBx)
{
return (uint32_t)
( ( (USBx->FSBDTPAGE1 >> USB_FSBDTPAGE1_BDTBA_SHIFT) << 9u )
| ( (USBx->FSBDTPAGE2 >> USB_FSBDTPAGE2_BDTBA_SHIFT) << 16u)
| ( (USBx->FSBDTPAGE3 >> USB_FSBDTPAGE3_BDTBA_SHIFT) << 24u)
);
}
uint32_t USB_GetFrameNumber(USB_Type * USBx)
{
return (USBx->FSFRMNUML) | (USBx->FSFRMNUML << 7u);
}
USB_BufDesp_Type * USB_GetBufDesp(USB_Type * USBx)
{
USB_BufDespTable_Type *bdt = (USB_BufDespTable_Type *)USB_GetBufDespTableAddr(USBx);
return &bdt->Index[USBx->FSSTAT >> 2];
}
USB_TokenPid_Type USB_BufDesp_GetTokenPid(USB_BufDesp_Type * bd)
{
return (USB_TokenPid_Type)bd->TOK_PID;
}
uint32_t USB_BufDesp_GetPacketAddr(USB_BufDesp_Type * bd)
{
return bd->ADDR;
}
uint32_t USB_BufDesp_GetPacketSize(USB_BufDesp_Type * bd)
{
return bd->BC;
}
void USB_BufDesp_Reset(USB_BufDesp_Type * bd)
{
bd->BDT_STALL = 0u;
bd->NINC = 0u;
bd->KEEP = 0u;
bd->DTS = 1u;
}
uint32_t USB_GetEndPointIndex(USB_Type * USBx)
{
return (USBx->FSSTAT & USB_FSSTAT_ENDP_MASK) >> USB_FSSTAT_ENDP_SHIFT;
}
USB_Direction_Type USB_GetXferDirection(USB_Type * USBx)
{
return (USB_Direction_Type)( (USBx->FSSTAT & USB_FSSTAT_TX_MASK) >> USB_FSSTAT_TX_SHIFT);
}
USB_BufDesp_OddEven_Type USB_GetBufDespOddEven(USB_Type * USBx)
{
return (USB_BufDesp_OddEven_Type)( (USBx->FSSTAT & USB_FSSTAT_ODD_MASK) >> USB_FSSTAT_ODD_SHIFT );
}
bool USB_BufDesp_Xfer(USB_BufDesp_Type * bd, uint32_t data_n, uint8_t * buffer, uint32_t len)
{
if (1u == bd->OWN)
{
return false;
}
bd->ADDR = (uint32_t)buffer;
bd->DATA = data_n;
bd->BC = len;
bd->OWN = 1u;
return true;
}
bool USB_BufDesp_IsBusy(USB_BufDesp_Type * bd)
{
if (1u == bd->OWN)
{
return true;
}
else
{
return false;
}
}
void USB_EnableEndPoint(USB_Type * USBx, uint32_t index, USB_EndPointMode_Type mode, bool enable)
{
if (false == enable)
{
USBx->FSEPCTL[index] = 0u;
USB_BufDespTable_Type * bdt = (USB_BufDespTable_Type * )USB_GetBufDespTableAddr(USBx);
bdt->Table[index][0u][0u].HEAD = 0u;
bdt->Table[index][0u][1u].HEAD = 0u;
bdt->Table[index][1u][0u].HEAD = 0u;
bdt->Table[index][1u][1u].HEAD = 0u;
return;
}
if (USB_EndPointMode_Control == mode)
{
USBx->FSEPCTL[index] |= USB_FSEPCTL_EPCTLDISEPRXENEPTXEN(3) | USB_FSEPCTL_EPHSHK_MASK;
}
else if (USB_EndPointMode_Bulk == mode)
{
USBx->FSEPCTL[index] |= USB_FSEPCTL_EPCTLDISEPRXENEPTXEN(7u) | USB_FSEPCTL_EPHSHK_MASK;
}
else if (USB_EndPointMode_Interrupt == mode)
{
USBx->FSEPCTL[index] |= USB_FSEPCTL_EPCTLDISEPRXENEPTXEN(7u) | USB_FSEPCTL_EPHSHK_MASK;
}
else if (USB_EndPointMode_Isochronous == mode)
{
USBx->FSEPCTL[index] |= USB_FSEPCTL_EPCTLDISEPRXENEPTXEN(7u);
}
}
void USB_EnableEndPointStall(USB_Type * USBx, uint32_t index, bool enable)
{
USB_BufDespTable_Type * bdt = (USB_BufDespTable_Type * )USB_GetBufDespTableAddr(USBx);
for (uint32_t i = 0; i < USB_BDT_EP_NUM; i++)
{
if (true == enable)
{
USBx->FSEPCTL[i] |= USB_FSEPCTL_EPSTALL_MASK;
bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_IN ].BDT_STALL = 1u;
bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_OUT].BDT_STALL = 1u;
bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_IN ].BDT_STALL = 1u;
bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_OUT].BDT_STALL = 1u;
}
else
{
USBx->FSEPCTL[i] &= ~USB_FSEPCTL_EPSTALL_MASK;
bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_IN ].BDT_STALL = 0u;
bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_IN ].OWN = 0u;
bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_OUT].BDT_STALL = 0u;
bdt->Table[i][USB_BufDesp_OddEven_Odd ][USB_Direction_OUT].OWN = 0u;
bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_IN ].BDT_STALL = 0u;
bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_IN ].OWN = 0u;
bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_OUT].BDT_STALL = 0u;
bdt->Table[i][USB_BufDesp_OddEven_Even][USB_Direction_OUT].OWN = 0u;
}
}
}
uint32_t USB_GetEnabledEndPointStall(USB_Type * USBx)
{
uint32_t status = 0u;
for(uint32_t i = 0u; i < USB_BDT_EP_NUM; i++)
{
if (0 != (USBx->FSEPCTL[i] & USB_FSEPCTL_EPSTALL_MASK) )
{
status |= 1u << i;
}
}
return status;
}
/* EOF. */