⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib_desc.c

📁 ARM9200开发板的ROM boot程序源码1.0
💻 C
📖 第 1 页 / 共 2 页
字号:
//*----------------------------------------------------------------------------
//*         ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : lib_desc.c
//* Object              : USB peripheral library.
//*
//* 1.0 07/23/01 ODi    : Creation
//*----------------------------------------------------------------------------
#include "periph/usb/lib_desc.h"

typedef enum {
	SETUP,
	DATA_IN,
	DATA_OUT,
	STATUS_IN,
	STATUS_OUT,
	UNKNOWN
} USB_CTL_STAGE;

#define MIN(a, b) (((a) < (b)) ? (a) : (b))

// //////////////////////////////////////////////////////////////////////////
void usbDescInHandler(
	SPipe *pPipe)              /* IN pipe handler */
{
	register u_int uisr;

	uisr = at91_usb_ep_uisr(USB_ENDPOINT_REF(pPipe));

	// Previous packet has been sent successfully an ACK has been received
	if (uisr & USB_TXCOMPLETE) {
		at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), USB_TXCOMPLETE);
		// Send the next data payload
		if ( !(pPipe->pBuffer->IsEmpty(pPipe->pBuffer)) )
			pPipe->pPeriph->Send(pPipe->pPeriph);
	}
	else
		at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), uisr);
}

// //////////////////////////////////////////////////////////////////////////
void usbDescOutHandler(
	SPipe *pPipe)              /* OUT pipe handler */
{
	register u_int uisr;

	uisr = at91_usb_ep_uisr(USB_ENDPOINT_REF(pPipe));

	// Previous packet has been sent successfully an ACK has been received
	if (uisr & (USB_RCV_DATA_BANK0 | USB_RCV_DATA_BANK1)) {
		// Receive the next data payload
		if ( !(pPipe->pBuffer->IsFull(pPipe->pBuffer)) )
			pPipe->pPeriph->Receive(pPipe->pPeriph);
		else
			at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), uisr);
	}
	else
		at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), uisr);
}

// //////////////////////////////////////////////////////////////////////////
int cpt;

void usbDescCtlHandler(
	USBDesc const *pDesc,      /* Application request handlers */
	SPipe *pPipe,              /* Control pipe handler */
	USBSetupData *pSetup,      /* Pointer to a setup structure as defined in USB spec */
	char *dataOut,             /* Buffer used in DATA OUT transactions */
	unsigned int dataOutMax ,  /* Buffer size */
	unsigned int *dataOutSize) /* Number of bytes received */
{
	register u_int uisr;

	uisr = at91_usb_ep_uisr(USB_ENDPOINT_REF(pPipe));

	// A setup packet has been received and automatically acknowledged by the macro
	if (uisr & USB_RXSETUP) {
	    /* Clear stall, this is not done by the macro */
		//at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), (USB_TXCOMPLETE | USB_STALLSENT | USB_FORCESTALL));
		/* Read the setup packet */
		at91_usb_ep_read( USB_ENDPOINT_REF(pPipe),
			(char *) pSetup,
			sizeof(USBSetupData));

		// **** DEVICE -> HOST transfer, init a Data IN stage
		if (pSetup->bmRequestType & (1 << 7)) {
			/* Enable the READ on control endpoint */
			at91_usb_ep_ctrl_read(USB_ENDPOINT_REF(pPipe));
			/* Clear all RXSETUP interrupts */
			at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), USB_RXSETUP);
			/* Handle the request */
			usbDescDispatchRequest(pDesc, pPipe, pSetup);
		}

		// **** HOST -> DEVICE transfer, init a Data OUT stage
		else {
			/* Clear the RXSETUP interrupt */
			at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), USB_RXSETUP);
			/* If no Data stage, handle the request */
			if (pSetup->wLength == 0) {
				usbDescDispatchRequest(pDesc, pPipe, pSetup);
			}
			else {
				if (cpt == 2)
					pPipe->Read(pPipe, dataOut, MIN(dataOutMax, pSetup->wLength));
				else
					pPipe->Read(pPipe, dataOut, MIN(dataOutMax, pSetup->wLength));
				++cpt;
			}
		}
	}

	// A Data OUT trqnsfer has been received and acknowledge. Macro is waiting for
	// the uC to read data in the DPR => USR_RCV_DATA_BANK0 is set
	else if (uisr & USB_RCV_DATA_BANK0) {
		// **** DEVICE -> HOST (End of Status OUT Stage)
		if (pSetup->bmRequestType & (1 << 7))
			at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), USB_RCV_DATA_BANK0);
		// **** HOST -> DEVICE (Data OUT Stage)
		else {
			// This check is just to prevent from extra DATA OUT (not specified in USB spec)
			if ( (pPipe->pBuffer->IsFull(pPipe->pBuffer)) ) {
				at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), USB_RCV_DATA_BANK0);
				usbDescRequestError(pPipe);
			}
			else {
				// Accept the Data OUT payload
				*dataOutSize += pPipe->pPeriph->Receive(pPipe->pPeriph);
				at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), USB_RCV_DATA_BANK0);
				// If the Data OUT stage is achieved, handle the request
				if (pPipe->pBuffer->IsFull(pPipe->pBuffer)) {
					if (cpt > 1)
						usbDescDispatchRequest(pDesc, pPipe, pSetup);
					else
						usbDescDispatchRequest(pDesc, pPipe, pSetup);
				}
			}
		}
	}

	// An ACK has been received after a DATA IN transfer => USB_TXCOMPLETE is set
	else if (uisr & USB_TXCOMPLETE) {

		// Clear USB_TXCOMPLETE
		at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), USB_TXCOMPLETE);
		// **** DEVICE -> HOST (Data IN Stage)
		if (pSetup->bmRequestType & (1 << 7))
			pPipe->pPeriph->Send(pPipe->pPeriph);

		// **** HOST -> DEVICE (Status IN Stage)
		else {
			// Test if this is a setAddress()
			if ((pSetup->bmRequestType == 0) && (pSetup->bRequest == USB_SET_ADDRESS) ) {
				// Valid Address: set the Device State
				if (pSetup->wValue != 0) {
					at91_usb_set_address(USB_PIPE_REF(pPipe), pSetup->wValue);
					at91_usb_set_state(USB_PIPE_REF(pPipe), USB_FADDEN);
				}
				// Back to the default device State
				else {
					at91_usb_set_address(USB_PIPE_REF(pPipe), 0);
					at91_usb_set_state(USB_PIPE_REF(pPipe), 0);
				}
			}
		}
	}

	// The STALL has been acknowledged, Clear the USB_FORCESTALL to accept the next setup packet
	else if (uisr & USB_STALLSENT) {
		at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), (USB_FORCESTALL | USB_STALLSENT));
	}

	/* ==== Default behavior ==== */
	else if (uisr) {
		/* Should not happen */
		at91_usb_ep_uicr(USB_ENDPOINT_REF(pPipe), uisr);
	}
}


/* ************************************ */
/* usbDescDispatchRequest               */
/*                                      */
/* Arguments:                           */
/*     pPipe: pointer to default pipe   */
/*            handler                   */
/*     pSetup: pointer to setup datas   */
/* Return:                              */
/*     Nothing                          */
/* Description:                         */
/*     This request handle standard     */
/*     request or call                  */
/*     usbDescDispatchClassRequest      */
/*     usbDescDispatchVendorRequest     */
/* ************************************ */
void usbDescDispatchRequest(USBDesc const *pDesc, SPipe *pPipe, USBSetupData *pSetup)
{
	switch ((pSetup->bmRequestType & (0x60)) >> 5) {
	case 0: /* Standard request */
		switch (pSetup->bRequest) {
		case USB_CLEAR_FEATURE:     usbDescClearFeature(    (void (*) ()) pDesc->clearFeature, pPipe, pSetup);         break;
		case USB_GET_CONFIGURATION: usbDescGetConfiguration((void (*) ()) pDesc->getConfiguration, pPipe, pSetup); break;
		case USB_GET_DESCRIPTOR:    usbDescGetDescriptor(   (void (*) ()) pDesc->getDescriptor, pPipe, pSetup);       break;
		case USB_GET_INTERFACE:     usbDescGetInterface(    (void (*) ()) pDesc->getInterface, pPipe, pSetup);         break;
		case USB_GET_STATUS:        usbDescGetStatus(       (void (*) ()) pDesc->getStatus, pPipe, pSetup);               break;
		case USB_SET_ADDRESS:       usbDescSetAddress(      (void (*) ()) pDesc->setAddress, pPipe, pSetup);             break;
		case USB_SET_CONFIGURATION: usbDescSetConfiguration((void (*) ()) pDesc->setConfiguration, pPipe, pSetup); break;
		case USB_SET_DESCRIPTOR:    usbDescSetDescriptor(   (void (*) ()) pDesc->setDescriptor, pPipe, pSetup);       break;
		case USB_SET_FEATURE:       usbDescSetFeature(      (void (*) ()) pDesc->setFeature, pPipe, pSetup);             break;
		case USB_SET_INTERFACE:     usbDescSetInterface(    (void (*) ()) pDesc->setInterface, pPipe, pSetup);         break;
		case USB_SYNCH_FRAME:       usbDescSynchFrame(      (void (*) ()) pDesc->synchFrame, pPipe, pSetup);             break;
		default:                    usbDescRequestError(pPipe);                                      break;
		}
		break;
	case 1: /* Class request */
		if (pDesc->dispatchClassRequest)
			pDesc->dispatchClassRequest(pPipe, pSetup, pDesc->pPrivateClassData);
		break;
	case 2: /* Vendor request */
		if (pDesc->dispatchVendorRequest)
			pDesc->dispatchVendorRequest(pPipe, pSetup, pDesc->pPrivateVendorData);
		break;
	default: /* Reserved */
		usbDescRequestError(pPipe);
		break;
	}
	return;
}

/* ************************************ */
/* usbDescClearFeature                  */
/*                                      */
/* Arguments:                           */
/*     pPipe: pointer to default pipe   */
/*            handler                   */
/*     pSetup: pointer to setup datas   */
/* Return:                              */
/*     Nothing                          */
/* Description:                         */
/*     This request is used to clear or */
/*     disable a specific feature       */
/* ************************************ */
void usbDescClearFeature(
	void (*clearFeature) (),      /* Pointer to application request handler */
	SPipe *pPipe,               /* Default Pipe Handler */
	USBSetupData *pSetup)         /* Descriptor type */

{
	u_int usbState = at91_usb_get_state(USB_PIPE_REF(pPipe));
	u_int recipient = (pSetup->bmRequestType & 0x1F);

	/* Check request arguments */
	if (recipient > 2 || pSetup->wLength != 0)
		/* Device behavior not specified */
		usbDescRequestError(pPipe);

	/* ================ Configured state ================= */
	else if ( (usbState & USB_CONFG) ) {
		/* If an application handler exists, transmit the request */
		if (clearFeature)
			(*clearFeature)(pPipe, recipient, pSetup->wIndex, pSetup->wValue);
		else
			usbDescRequestError(pPipe);
	}
	/* =================== Address state ================= */
	else if ( (usbState & USB_FADDEN) ) {
		/* This request is valid in Address State only when reference endpoint 0 */
		if (recipient != 0 && pSetup->wIndex != 0)
			usbDescRequestError(pPipe);
		else {
		/* If an application handler exists, transmit the request */
			if (clearFeature )
				(*clearFeature)(pPipe, recipient, pSetup->wIndex, pSetup->wValue);
			else
				usbDescRequestError(pPipe);
		}
	}
	/* =================== Default state ================= */
	else
		/* Device behavior not specified */
		usbDescRequestError(pPipe);
}

/* ************************************ */
/* usbDescGetConfiguration              */
/*                                      */
/* Arguments:                           */
/*     pPipe: pointer to default pipe   */
/*            handler                   */
/*     pSetup: pointer to setup datas   */
/* Return:                              */
/*     Nothing                          */
/* Description:                         */
/*     This request returns the current */
/*     device configuration value       */
/* ************************************ */
void usbDescGetConfiguration(
		void (*getConfiguration) (),  /* Pointer to application request handler */
		SPipe *pPipe,               /* Default Pipe Handler */
		USBSetupData *pSetup)         /* Descriptor type */
{
	u_int usbState = at91_usb_get_state(USB_PIPE_REF(pPipe));

	/* Check request arguments */
	if (pSetup->wValue != 0 || pSetup->wIndex != 0 || pSetup->wLength != 1)
		/* Device behavior not specified */
		usbDescRequestError(pPipe);

	/* ================ Configured state ================= */
	else if ( (usbState & USB_CONFG) ) {
		/* If an application handler exists, transmit the request */
		if (getConfiguration )
			(*getConfiguration)(pPipe);
		else
			usbDescRequestError(pPipe);
	}
	/* =================== Address state ================= */
	else if ( (usbState & USB_FADDEN) )
		/* Return a 0 value */
		pPipe->Write(pPipe, "\0x00", 1);
	/* =================== Default state ================= */
	else
		/* Device behavior not specified */
		usbDescRequestError(pPipe);
}

/* ************************************ */
/* usbDescGetDescriptor                 */
/*                                      */
/* Arguments:                           */
/*     pPipe: pointer to default pipe   */
/*            handler                   */
/*     pSetup: pointer to setup datas   */
/* Return:                              */
/*     Nothing                          */
/* Description:                         */
/*     This request returns the         */
/*     specified descriptor if the      */
/*     descriptor exists                */
/* ************************************ */
void usbDescGetDescriptor(
		void (*getDescriptor) (),     /* Pointer to application request handler */
		SPipe *pPipe,               /* Default Pipe Handler */
		USBSetupData *pSetup)         /* Descriptor type */
{
	/* This request is valid in all states */
	if (getDescriptor)
		(*getDescriptor)(
			pPipe,
			((pSetup->wValue) >> 8),   /* Descriptor type */
			((pSetup->wValue) & 0xFF), /* Descriptor Index */
			pSetup->wIndex,            /* Language ID */
			pSetup->wLength);          /* Descripotr Length */
	else
		usbDescRequestError(pPipe);

}

/* ************************************ */
/* usbDescGetInterface                  */
/*                                      */
/* Arguments:                           */
/*     pPipe: pointer to default pipe   */
/*            handler                   */
/*     pSetup: pointer to setup datas   */
/* Return:                              */
/*     Nothing                          */
/* Description:                         */
/*     This request returns the         */
/*     selected alternate setting for   */
/*     the specified interface          */
/* ************************************ */
void usbDescGetInterface(
		void (*getInterface) (),      /* Pointer to application request handler */
		SPipe *pPipe,               /* Default Pipe Handler */
		USBSetupData *pSetup)         /* Descriptor type */
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -