📄 usb_hw.c
字号:
/*
********************************************************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/USB-Bulk
*
* (c) Copyright 2003 - 2004, Micrium, Inc.
* All rights reserved.
*
*********************************************************************************************************
----------------------------------------------------------------------
File : USB_HW.h
Purpose : Hardware dependent routines for Cypress SL811HS
-------- END-OF-HEADER ---------------------------------------------
*/
#include "USB_bsp.h"
/*
*********************************************************************************************************
* Constants
*********************************************************************************************************
*/
#define USB_STATE_CTRL_SETUP 0
#define USB_STATE_CTRL_DATA 1
#define USB_STATE_CTRL_STATUS 2
#define USB_SETUP_PKT_SIZE 8
#define USB_SETUP_MAX_PKT_SIZE 64 /* This is the largest amount of data for a Control transfer */
#define USB_IN_MAX_PKT_SIZE 32 /* This is the maximum packet size for an IN transfer */
/*
*********************************************************************************************************
* Variables
*********************************************************************************************************
*/
static USB_U8 *USB_Send_Buf; /* A pointer to data waiting to be sent one packet at a time */
static USB_U32 USB_Remaining_Bytes; /* The amount of data left to be sent one packet at a time */
/* This state variable is '1' if, upon receiving an interrupt */
static USB_U8 USB_Send_State; /* signaling that a packet was sent, another packet should be sent. */
/* This state variable indicates which stage within a control transfer */
static USB_U8 USB_Setup_State; /* is currently being processed */
/* This state variable indicates whether the next packet sent should */
static USB_U8 USB_Data_State; /* be DATA1 or DATA0 */
/* This variable temporarily holds the address assigned to the device */
static USB_U8 USB_Tmp_Addr; /* before it is placed in the controller's address register */
/*
*********************************************************************************************************
* USB_HW_Init()
*
* Description: This function performs necessary initializations on the Cypress SL811HS controller.
* Endpoint 0 is set up to begin receiving setup packets, and the appropriate interrupts
* are enabled.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_Init (void)
{
/* Set up the controller to be in slave mode */
USB_REG_WR(CTRL_2_REG, CTRL_2_SLAVE);
USB_RESET(); /* Reset the USB controller */
USB_SL811HS_Init(); /* Perform any board-specific initializations */
/* Set up Endpoint 0 to receive the first setup packet */
USB_REG_WR(ENDPOINT0A_CTRL, ENDPOINT_CTRL_ARM | ENDPOINT_CTRL_ENABLE);
/* Initialize Endpoint 0's base address */
USB_REG_WR(ENDPOINT0A_BASE, 0x40);
/* Initialize Endpoint 0's length register; this will be the max. */
/* packet size for packets from the host */
USB_REG_WR(ENDPOINT0A_LEN, 0x40);
/* Clear Endpoint 0's packet status register */
USB_REG_WR(ENDPOINT0A_PKT, 0x00);
/* Use the default address of 0x00 for enumeration */
USB_REG_WR(ADDR_REG, 0x00);
/* Enable interrupts for Endpoint 0 and USB Resets */
USB_REG_WR(INT_ENABLE_REG, INT_ENABLE_ENDPOINT0 | INT_ENABLE_USB_RESET);
/* Enable USB transactions on the controller */
USB_REG_WR(CTRL_REG, CTRL_USB_ENABLE);
/* Clear all interrupts */
USB_REG_WR(INT_STATUS_REG, INT_STATUS_CLEAR_ALL);
}
/*
*********************************************************************************************************
* USB_HW_FreeBuffer()
*
* Description: This function sets the arm bit for Endpoint 1, allowing it to receive data again.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_FreeBuffer (void)
{
/* Reset the length of Endpoint 1's buffer */
USB_REG_WR(ENDPOINT1A_LEN, 0x20);
/* Prepare Endpoint 1 for the next packet */
USB_REG_WR(ENDPOINT1A_CTRL, ENDPOINT_CTRL_ARM | ENDPOINT_CTRL_ENABLE| ENDPOINT_CTRL_SEQUENCE);
}
/*
*********************************************************************************************************
* USB_HW_memcpy()
*
* Description: This function simply copies the data referenced by pSrc to the location indicated by
* pSrc. It is used by the target-independent code to copy data from the driver buffer
* to a task's buffer.
*
* Arguments : pdest The location to which data will be copied
* psrc The location from which data will be copied
* Len The amount of data to be copied
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_memcpy (void *p_dest, void *p_src, unsigned len)
{
USB_U8 *buf_dest;
USB_U8 *buf_src;
buf_dest = (USB_U8 *)p_dest; /* Get a character pointer to the destination */
buf_src = (USB_U8 *)p_src; /* Get a character pointer to the source */
while (len > 0) { /* Copy each byte from the source to the destination */
*buf_dest = *buf_src;
buf_dest++;
buf_src++;
len--;
}
}
/*
*********************************************************************************************************
* USB_HW_BufferAvailable()
*
* Description: This function indicates whether or not Endpoint 2 is ready to send data.
*
* Arguments : None
*
* Returns : 1 if Endpoint 2 is able to send
* 0 if Endpoint 2 is not able to send
*********************************************************************************************************
*/
int USB_HW_BufferAvailable (void)
{
USB_U8 buf_status;
/* Check Endpoint 2's arm bit, which is set to 0 when transfers finish */
USB_REG_RD(ENDPOINT2A_CTRL, buf_status);
if ((buf_status & ENDPOINT_CTRL_ARM) != 0) {
return (0);
} else {
return (1);
}
}
/*
*********************************************************************************************************
* USB_HW_SendPkt()
*
* Description: This function sends one packet of data on Endpoint 2
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_SendPkt (void)
{
USB_U8 write_status;
USB_U8 num_bytes;
/* If data of a size greater than the max packet size must be sent, */
/* one packet of max packet size will be sent. USB_Send_State is set */
/* to 1, so the remainder of the data can be sent after the interrupt */
/* indicating that this packet has been sent. */
if (USB_Remaining_Bytes >= USB_IN_MAX_PKT_SIZE) {
num_bytes = USB_IN_MAX_PKT_SIZE;
USB_Send_State = 1;
} else { /* If data of a size less than the max packet size must be sent, only */
/* one packet is needed, so USB_Send_State is set to 0. */
num_bytes = USB_Remaining_Bytes;
USB_Send_State = 0;
}
/* The data is written to Endpoint 2's buffer on the SL811HS */
write_status = USB_Reg_Wr_Buf(USB_Send_Buf, ENDPOINT2A_BASE, num_bytes);
USB_Remaining_Bytes -= write_status;
USB_Send_Buf += write_status;
USB_REG_WR(ENDPOINT2A_LEN, write_status);
/* The Endpoint is set up to send the appropriate value for the */
/* DATA bit, which is used for error checking. */
if (USB_Data_State == 0) {
USB_REG_WR(ENDPOINT2A_PKT, ENDPOINT_PKT_ACK);
USB_REG_WR(ENDPOINT2A_CTRL, ENDPOINT_CTRL_ARM | ENDPOINT_CTRL_ENABLE | ENDPOINT_CTRL_DIRECTION);
} else {
USB_REG_WR(ENDPOINT2A_PKT, ENDPOINT_PKT_ACK | ENDPOINT_PKT_SEQUENCE);
USB_REG_WR(ENDPOINT2A_CTRL, ENDPOINT_CTRL_ARM | ENDPOINT_CTRL_ENABLE | ENDPOINT_CTRL_DIRECTION | ENDPOINT_CTRL_SEQUENCE);
}
/* The state variable indicating the value of the DATA bit is toggled, */
/* since DATA should alternate between '1' and '0' */
USB_Data_State ^= 1;
}
/*
*********************************************************************************************************
* USB_HW_SendData()
*
* Description: This function is called by the target-independent code to send data from the bulk OUT
* Endpoint (Endpoint 2). It calls USB_HW_SendPkt which sends the data one packet at
* a time.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_SendData (const void *p_data, unsigned nbytes)
{
USB_Remaining_Bytes = nbytes;
USB_Send_Buf = (USB_U8 *)p_data;
USB_HW_SendPkt(); /* The data must be sent one packet at a time */
}
/*
*********************************************************************************************************
* USB_HW_Read()
*
* Description: This function is called by USB__OnRx() in the target independent code upon receiving
* an interrupt on Endpoint 1.
*
* Arguments : p_dest A pointer to the buffer that will hold the data that is read
* nbytes The number of bytes to read
* pkt_offset Unused
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_Read (void *p_dest, int nbytes, unsigned pkt_offset)
{
USB_U8 *read_buf;
(void)pkt_offset;
read_buf = (USB_U8 *)p_dest; /* The data is read from the Endpoint 1's buffer on the SL811HS */
USB_Reg_Rd_Buf(read_buf, ENDPOINT1A_BASE, nbytes);
}
/*
*********************************************************************************************************
* USB_HW_Attach()
*
* Description: This function would be used to indicate that the device is attached to the bus. It is
* left empty for the Cypress SL811HS
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_Attach (void)
{
}
/*
*********************************************************************************************************
* USB_HW_UnloadEP0()
*
* Description: This function is called during the processing of requests that have no data stage. On
* the Cypress SL811HS, this function modifies the state variable, so that on the next
* Endpoint 0 interrupt, which will indicate that the device has sent a 0-byte
* acknowledgment, Endpoint 0 will be set up to begin a new control transfer.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void USB_HW_UnloadEP0 (void)
{
USB_Setup_State = USB_STATE_CTRL_STATUS;
}
/*
*********************************************************************************************************
* USB_HW_StallEP0()
*
* Description: This function stalls Endpoint 0 in response to unsupported requests. This function
* is currently empty since we are not expecting any such requests during a standard
* enumeration.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -