📄 sx2usbdrv.c
字号:
for (i=0; i<numBytes; i++)
{
(*hostCpu._func_hostCpuWrite) (SX2REG(fifo), SX2_WORD_SWAP(buf[i]));
}
}
#endif
/* if a write fifo notification hook exists, invoked it.
sx2WriteFifo() returns OK or ERROR as returned by the hook. */
if (hostCpu._func_writeFifoNotifyHook != NULL)
{
return ((*hostCpu._func_writeFifoNotifyHook)(0));
}
return (OK);
}
/*******************************************************************************
*
* sx2SetDescriptor - Write the SX2 descriptor RAM using the descriptor and
* number of bytes provided.
*
* It is assumed that no more than one task or ISR will call this function and
* therefore, no mutual exlusion protection is provided.
*
* RETURNS: OK or ERROR if write fails.
*/
STATUS sx2SetDescriptor(UINT8 *descr, UINT16 numBytes)
{
UINT32 i;
/* wait for READY to go high */
if ((*hostCpu._func_waitReady)() != OK)
return (ERROR);
/* initiate a register write request */
(*hostCpu._func_hostCpuWrite) (hostCpu.sx2Cmd,
SX2_WORD_SWAP((DESC|SX2_CMD_ADDR)&SX2_CMD_WRITE));
/* write size of descriptor, lsb then msb */
if (sx2WriteNibbles ((UINT8)LSB(numBytes)) != OK)
return (ERROR);
if (sx2WriteNibbles ((UINT8)MSB(numBytes)) != OK)
return (ERROR);
/* write the descriptor, one byte at a time */
for (i=0; i<numBytes; i++)
{
if (sx2WriteNibbles (descr[i]) != OK)
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* sx2GetDescriptor - Read the SX2 descriptor RAM and return the number of
* bytes requested in the provided buffer.
*
* RETURNS: OK.
*/
STATUS sx2GetDescriptor(UINT8 *descr, UINT16 numBytes)
{
UINT16 i;
/* read descriptor RAM */
for (i=0; i<numBytes; i++)
{
sx2ReadReg(DESC, &descr[i]);
}
return (OK);
}
/*******************************************************************************
*
* sx2Configure - Set SX2 registers as specified in the register table.
*
* RETURNS: OK or ERROR.
*/
STATUS sx2Configure(INT16 regs[][2])
{
UINT8 index = 0;
/* walk through register table, -1 indicates end of table */
while ((regs[index][0]) != -1)
{
/* skip register values of -1 */
if ((regs[index][1]) != -1)
{
/* write register */
if (sx2WriteReg((UINT8)regs[index][0], (UINT8)regs[index][1]) == ERROR)
return (ERROR);
/* The delay is needed, fast subsequent writes appear to cause a
timing problem. The SX2 stops generating interrupts, see
sx2SetFifoWidth() for a similar problem.
Need clarification from Cypress. */
taskDelay(1);
}
index++;
}
return (OK);
}
/*******************************************************************************
*
* sx2GetSetupData - Read specified number of bytes of SX2 setup packet.
*
* RETURNS: OK or ERROR.
*/
STATUS sx2GetSetupData(UINT8 *buf, UINT8 numBytes)
{
UINT32 i;
/* check if number of bytes is valid */
if (numBytes > SETUP_PKT_SIZE)
return (ERROR);
/* read setup packet */
for (i=0; i<numBytes; i++)
{
if (sx2ReadReg(SETUP, &buf[i]) == ERROR)
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* sx2SetEp0Data - Write data to endpoint 0 buffer.
*
* RETURNS: OK or ERROR if more than 64 bytes or write fails.
*/
STATUS sx2SetEp0Data(UINT8 *buf, UINT8 numBytes)
{
UINT32 i;
/* we can write at most 64 bytes per request */
if (numBytes > EP0_MAX_DATA)
return (ERROR);
/* write data to endpoint 0 buffer */
for (i=0; i<numBytes; i++)
{
if (sx2WriteReg(EP0BUF, buf[i]) == ERROR)
return (ERROR);
}
/* write endpoint 0 byte count */
if (sx2WriteReg(EP0BC, numBytes) == ERROR)
return (ERROR);
return (OK);
}
/*******************************************************************************
*
* sx2GetEp0Data - Read endpoint 0 buffer and return data in buffer provided.
*
* The number of bytes to be read can be specified in two different ways:
* - by reading the byte count register (flag=TRUE), numBytes parameter not used
* - by using the numBytes parameter (flag=FALSE)
*
* RETURNS: actual number of bytes read, or ERROR.
*/
UINT32 sx2GetEp0Data(UINT8 *buf, UINT8 numBytes, BOOL flag)
{
UINT32 i;
UINT8 bc = 0;
if (flag)
{
/* read endpoint 0 byte count */
if (sx2ReadReg(EP0BC, &bc) == ERROR)
return (ERROR);
}
else
{
/* use numBytes parameter instead */
if (numBytes > EP0_MAX_DATA)
return (ERROR);
bc = numBytes;
}
/* read data from endpoint 0 buffer */
for (i=0; i<bc; i++)
{
if (sx2ReadReg(EP0BUF, &buf[i]) == ERROR)
return (ERROR);
}
return (bc);
}
/*******************************************************************************
*
* sx2GetFifoStatus - Read status of endpoint FIFO flags.
*
* The fifo parameter indicates for which FIFO the flags are to be read.
* The following fifo values, defined in sx2UsbDrv.h should be used:
* SX2_FIFO2, SX2_FIFO4, SX2_FIFO6, SX2_FIFO8
* The method parameter specifies if the flag status is read via registers
* (USE_REGS), or via pins (USE_PINS). If USE_PINS is specified, a host CPU
* specific function has to be provided and the SX2 flag pins have to be wired
* such that the host CPU can read their status.
*
* The host CPU specific flag read function has to be declared as follows:
*
* UINT8 hostSx2FlagRead(UINT8 fifo);
*
* Flag status is returned as follows:
*
* Bit 7 6 5 4 3 2 1 0
* 0 0 0 0 0 EPxPF EPxEF EPxFF
*
* RETURNS: flag status or ERROR if read error or USE_PIN method not supported.
*/
UINT8 sx2GetFifoStatus(UINT8 fifo, UINT8 method)
{
UINT8 flagReg;
UINT8 data = 0;
/* check validity of parameters */
if ((fifo != SX2_FIFO2) && (fifo != SX2_FIFO4)
&& (fifo != SX2_FIFO6) && (fifo != SX2_FIFO8))
return (ERROR);
if ((method != USE_REGS) && (method != USE_PINS))
return (ERROR);
/* determine which method to use */
if (method == USE_REGS)
{
/* determine flag register to use */
if ((fifo == SX2_FIFO2) || (fifo == SX2_FIFO4))
flagReg = EP24FLAGS;
else
flagReg = EP68FLAGS;
/* read flag register */
if (sx2ReadReg(flagReg, &data) == ERROR)
return (ERROR);
/* move bits into position and return */
if ((fifo == SX2_FIFO2) || (fifo == SX2_FIFO6))
return (data & 0x0F);
else
return ((data >> 4) & 0x0F);
}
else
{
/* check if host CPU specific flag read function exists */
if (hostCpu._func_hostFlagRead == NULL)
return (ERROR);
/* invoke host specific flag read function */
data = (*hostCpu._func_hostFlagRead)(fifo);
return (data);
}
}
/*******************************************************************************
*
* sx2SetPktend - Set PKTEND to force short packets.
*
* The fifo parameter selects the FIFO for which PKTEND is to be issued.
* The following fifo values, defined in sx2UsbDrv.h should be used:
* SX2_FIFO2, SX2_FIFO4, SX2_FIFO6, SX2_FIFO8
*
* The method parameter specifies if PKTEND is initiated via registers
* (USE_REGS), or via pins (USE_PINS). If USE_PINS is specified, a host CPU
* specific function has to be provided and the SX2 PKTEND pin has to be wired
* such that the host CPU can control it.
*
* The host CPU specific PKTEND control function has to be declared as follows:
*
* VOID hostSx2PktendSet(UINT8 fifo);
*
* RETURNS: OK or ERROR.
*/
STATUS sx2SetPktend(UINT8 fifo, UINT8 method)
{
UINT8 val = 0;
/* check validity of parameters */
if ((fifo != SX2_FIFO2) && (fifo != SX2_FIFO4)
&& (fifo != SX2_FIFO6) && (fifo != SX2_FIFO8))
return (ERROR);
if ((method != USE_REGS) && (method != USE_PINS))
return (ERROR);
/* determine which method to use */
if (method == USE_REGS)
{
switch (fifo)
{
case SX2_FIFO2:
val = (UINT8)EP2PKTEND;
break;
case SX2_FIFO4:
val = (UINT8)EP4PKTEND;
break;
case SX2_FIFO6:
val = (UINT8)EP6PKTEND;
break;
case SX2_FIFO8:
val = (UINT8)EP8PKTEND;
break;
}
/* set the corresponding PKTEND bit in INPKTENDFLUSH */
if (sx2WriteReg(INPKTENDFLUSH, val) == ERROR)
return (ERROR);
}
else
{
/* check if host CPU specific PKTEND function exists */
if (hostCpu._func_hostPktendSet == NULL)
return (ERROR);
/* invoke host specific PKTEND function */
(*hostCpu._func_hostPktendSet)(fifo);
}
return (OK);
}
/*******************************************************************************
*
* sx2Suspend - Suspend the SX2.
*
* RETURNS: OK or ERROR.
*/
STATUS sx2Suspend(VOID)
{
UINT8 val;
/* read IFCONFIG register */
if (sx2ReadReg(IFCONFIG, &val) == ERROR)
return (ERROR);
/* set IFCONFIG(STANDBY) */
if (sx2WriteReg(IFCONFIG, val|STANDBY) == ERROR)
return (ERROR);
return (OK);
}
/*******************************************************************************
*
* sx2Wakeup - Wake up the SX2 from low-power or suspend mode.
*
* The wakeup operation is completely determined by how the SX2 WAKEUP pin is
* wired, e.g. if WAKEUP is connected to a host CPU GPIO pin the wakeup function
* pointer should be initialized with a function that asserts the GPIO pin.
*
* The host CPU specific wakeup function has to be declared as follows:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -