/*********************************************************************
*
* Copyright:
* MOTOROLA, INC. All Rights Reserved.
* You are hereby granted a copyright license to use, modify, and
* distribute the SOFTWARE so long as this entire notice is
* retained without alteration in any modified and/or redistributed
* versions, and that such modified versions are clearly identified
* as such. No licenses are granted by implication, estoppel or
* otherwise under any patents or trademarks of Motorola, Inc. This
* software is provided on an "AS IS" basis and without warranty.
*
* To the maximum extent permitted by applicable law, MOTOROLA
* DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
* PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE
* SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY
* ACCOMPANYING WRITTEN MATERIALS.
*
* To the maximum extent permitted by applicable law, IN NO EVENT
* SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
* INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
* LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
*
* Motorola assumes no responsibility for the maintenance and support
* of this software
********************************************************************/
/*
* File: usb.c
* Purpose: Device Driver for the USB module of the MCF5272
*/
#include "mcf5272.h"
#include "init.h"
/********************************************************************/
/* Global Endpoint Status Structures */
USB_EP_STATE ep[NUM_ENDPOINTS];
/* Global Remote Wakeup Flag */
volatile int fRemoteWakeup = 0;
/* Global USB Descriptor Data (application specific) */
extern USB_DEVICE_DESC Descriptors;
/********************************************************************/
void
usb_init(void)
{
uint32 i, DescSize;
uint32 *pConfigRam;
uint32 *pDevDesc;
MCF5272_IMM *imm = mcf5272_get_immp();
/* Initialize Descriptor pointers and variables */
pConfigRam = (uint32 *)((uint32)imm + MCF5272_USB_CFG_RAM);
pDevDesc = (uint32 *)usb_get_desc(-1, -1, -1, -1);
DescSize = usb_get_desc_size() + 3;
/* Initialize Endpoint status structures */
ep[0].ttype = CONTROL;
ep[0].packet_size = ((USB_DEVICE_DESC *)pDevDesc)->bMaxPacketSize0;
ep[0].fifo_length = (uint16)(ep[0].packet_size * FIFO_DEPTH);
ep[0].buffer.start = 0;
ep[0].buffer.free = 0;
/* Set the EP0 IN-BUSY bit -- This is only required on
pre-2K75N masks. This bit is set by HW beginning with
the 2K75N silicon. */
MCF5272_WR_USB_EP0CTL(imm, MCF5272_RD_USB_EP0CTL(imm)
| MCF5272_USB_EP0CTL_IN_BUSY);
for (i = 1; i < NUM_ENDPOINTS; i++)
ep[i].ttype = DISABLED;
/* Invalidate Configuration RAM and disable Endpoint 0 */
MCF5272_WR_USB_EP0CTL(imm, 0);
/* Load the Configuration RAM with the descriptors */
for (i = 0; i < (DescSize/4); i++)
pConfigRam[i] = pDevDesc[i];
/* Initialize FIFOs */
usb_fifo_init();
/* Initialize the Interrupts */
usb_isr_init();
/* Enable USB controller, Config RAM, EXT AFE */
#if (DEBUG)
MCF5272_WR_USB_EP0CTL(imm, 0
| MCF5272_USB_EP0CTL_DEBUG
/* | MCF5272_USB_EP0CTL_AFE_EN */
| MCF5272_USB_EP0CTL_USB_EN
| MCF5272_USB_EP0CTL_CFG_RAM_VAL);
#else
MCF5272_WR_USB_EP0CTL(imm, 0
/* | MCF5272_USB_EP0CTL_AFE_EN */
| MCF5272_USB_EP0CTL_USB_EN
| MCF5272_USB_EP0CTL_CFG_RAM_VAL);
#endif
/* Enable desired interrupts on EP0 */
MCF5272_WR_USB_EP0IMR(imm, 0
| MCF5272_USB_EP0IMR_DEV_CFG_EN
| MCF5272_USB_EP0IMR_VEND_REQ_EN
| MCF5272_USB_EP0IMR_WAKE_CHG_EN
| MCF5272_USB_EP0IMR_RESUME_EN
| MCF5272_USB_EP0IMR_SUSPEND_EN
| MCF5272_USB_EP0IMR_RESET_EN
| MCF5272_USB_EP0IMR_OUT_EOT_EN
| MCF5272_USB_EP0IMR_OUT_EOP_EN
| MCF5272_USB_EP0IMR_IN_EOT_EN
| MCF5272_USB_EP0IMR_IN_EOP_EN
| MCF5272_USB_EP0IMR_UNHALT_EN
| MCF5272_USB_EP0IMR_HALT_EN);
}
/********************************************************************/
void
usb_isr_init(void)
{
MCF5272_IMM *imm = mcf5272_get_immp();
/* Clear any pending interrupts in all Endpoints */
MCF5272_WR_USB_EP0ISR(imm, 0x0001FFFF);
MCF5272_WR_USB_EP1ISR(imm, 0x001F);
MCF5272_WR_USB_EP2ISR(imm, 0x001F);
MCF5272_WR_USB_EP3ISR(imm, 0x001F);
MCF5272_WR_USB_EP4ISR(imm, 0x001F);
MCF5272_WR_USB_EP5ISR(imm, 0x001F);
MCF5272_WR_USB_EP6ISR(imm, 0x001F);
MCF5272_WR_USB_EP7ISR(imm, 0x001F);
/* Enable all interrupts on all Endpoints */
/* These will be altered on configuration/interface changes */
MCF5272_WR_USB_EP0IMR(imm, 0x0001FFFF);
MCF5272_WR_USB_EP1IMR(imm, 0x001F);
MCF5272_WR_USB_EP2IMR(imm, 0x001F);
MCF5272_WR_USB_EP3IMR(imm, 0x001F);
MCF5272_WR_USB_EP4IMR(imm, 0x001F);
MCF5272_WR_USB_EP5IMR(imm, 0x001F);
MCF5272_WR_USB_EP6IMR(imm, 0x001F);
MCF5272_WR_USB_EP7IMR(imm, 0x001F);
/* Initialize Interrupt Control Registers */
MCF5272_WR_SIM_ICR2(imm, 0
| (0x00008888)
| (USB_EP0_LEVEL << 12)
| (USB_EP1_LEVEL << 8)
| (USB_EP2_LEVEL << 4)
| (USB_EP3_LEVEL << 0));
MCF5272_WR_SIM_ICR3(imm, 0
| (0x88880000)
| (USB_EP4_LEVEL << 28)
| (USB_EP5_LEVEL << 24)
| (USB_EP6_LEVEL << 20)
| (USB_EP7_LEVEL << 16));
}
/********************************************************************/
void
usb_endpoint0_isr(void)
{
MCF5272_IMM *imm = mcf5272_get_immp();
uint32 event;
event = MCF5272_RD_USB_EP0ISR(imm) & MCF5272_RD_USB_EP0IMR(imm);
if (event & MCF5272_USB_EP0ISR_DEV_CFG)
{
usb_devcfg_service();
/* Clear this interrupt bit */
MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_DEV_CFG);
}
if (event & MCF5272_USB_EP0ISR_VEND_REQ)
{
/* Is this a GET_DESCRIPTOR(String) request? */
if ((MCF5272_RD_USB_DRR1(imm) & 0xFF00 >> 8) == GET_DESCRIPTOR)
{
/* To do: Return STRING Descriptor if it exists */
printf("Host requested the String Descriptor\n");
while (1) ;
}
/* Clear this interrupt bit */
MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_VEND_REQ);
usb_vendreq_service(
(uint8)(MCF5272_RD_USB_DRR1(imm) & 0xFF),
(uint8)(MCF5272_RD_USB_DRR1(imm) >> 8),
(uint16)(MCF5272_RD_USB_DRR1(imm) >> 16),
(uint16)(MCF5272_RD_USB_DRR2(imm) & 0xFFFF),
(uint16)(MCF5272_RD_USB_DRR2(imm) >> 16));
}
if (event & MCF5272_USB_EP0ISR_FRM_MAT)
{
/* Clear this interrupt bit */
MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_FRM_MAT);
}
if (event & MCF5272_USB_EP0ISR_ASOF)
{
/* Clear this interrupt bit */
MCF5272_WR_USB_EP0ISR(imm, MCF5272_USB_EP0ISR_ASOF);
}
if (event & MCF5272_USB_EP0ISR_SOF)
{
/* C
- 1
- 2
- 3
- 4
- 5
- 6
前往页