/*
	LPCUSB, an USB device driver for LPC microcontrollers	
	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


/** @file
	USB hardware layer
 */


#include "usbdebug.h"
#include "usbhw_lpc.h"
#include "usbapi.h"

#ifdef DEBUG
// comment out the following line if you don't want to use debug LEDs
//#define DEBUG_LED
#endif

/** Installed device interrupt handler */
static TFnDevIntHandler *_pfnDevIntHandler = NULL;
/** Installed endpoint interrupt handlers */
static TFnEPIntHandler	*_apfnEPIntHandlers[16];
/** Installed frame interrupt handlers */
static TFnFrameHandler	*_pfnFrameHandler = NULL;

/** convert from endpoint address to endpoint index */
#define EP2IDX(bEP)	((((bEP)&0xF)<<1)|(((bEP)&0x80)>>7))
/** convert from endpoint index to endpoint address */
#define IDX2EP(idx)	((((idx)<<7)&0x80)|(((idx)>>1)&0xF))



/**
	Local function to wait for a device interrupt (and clear it)
		
	@param [in]	dwIntr		Bitmask of interrupts to wait for	
 */
static void Wait4DevInt(unsigned long dwIntr)
{
	// wait for specific interrupt
	while ((USB->USBDevIntSt & dwIntr) != dwIntr);
	// clear the interrupt bits
	USB->USBDevIntClr = dwIntr;
}


/**
	Local function to send a command to the USB protocol engine
		
	@param [in]	bCmd		Command to send
 */
static void USBHwCmd(unsigned char bCmd)
{
	// clear CDFULL/CCEMTY
	USB->USBDevIntClr = CDFULL | CCEMTY;
	// write command code
	USB->USBCmdCode = 0x00000500 | (bCmd << 16);
	Wait4DevInt(CCEMTY);
}


/**
	Local function to send a command + data to the USB protocol engine
		
	@param [in]	bCmd		Command to send
	@param [in]	bData		Data to send
 */
static void USBHwCmdWrite(unsigned char bCmd, unsigned short bData)
{
	// write command code
	USBHwCmd(bCmd);

	// write command data
	USB->USBCmdCode = 0x00000100 | (bData << 16);
	Wait4DevInt(CCEMTY);
}


/**
	Local function to send a command to the USB protocol engine and read data
		
	@param [in]	bCmd		Command to send

	@return the data
 */
static unsigned char USBHwCmdRead(unsigned char bCmd)
{
	// write command code
	USBHwCmd(bCmd);
	
	// get data
	USB->USBCmdCode = 0x00000200 | (bCmd << 16);
	Wait4DevInt(CDFULL);
	return USB->USBCmdData;
}


/**
	'Realizes' an endpoint, meaning that buffer space is reserved for
	it. An endpoint needs to be realised before it can be used.
		
	From experiments, it appears that a USB reset causes USBReEP to
	re-initialise to 3 (= just the control endpoints).
	However, a USB bus reset does not disturb the USBMaxPSize settings.
		
	@param [in]	idx			Endpoint index
	@param [in] wMaxPSize	Maximum packet size for this endpoint
 */
static void USBHwEPRealize(int idx, unsigned short wMaxPSize)
{
	USB->USBReEP |= (1 << idx);
	USB->USBEpInd = idx;
	USB->USBMaxPSize = wMaxPSize;
	Wait4DevInt(EP_RLZED);
}


/**
	Enables or disables an endpoint
		
	@param [in]	idx		Endpoint index
	@param [in]	fEnable	TRUE to enable, FALSE to disable
 */
static void USBHwEPEnable(int idx, BOOL fEnable)
{
	USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fEnable ? 0 : EP_DA);
}


/**
	Configures an endpoint and enables it
		
	@param [in]	bEP				Endpoint number
	@param [in]	wMaxPacketSize	Maximum packet size for this EP
 */
void USBHwEPConfig(unsigned char bEP, unsigned short wMaxPacketSize)
{
	int idx;
	
	idx = EP2IDX(bEP);
	
	// realise EP
	USBHwEPRealize(idx, wMaxPacketSize);

	// enable EP
	USBHwEPEnable(idx, TRUE);
}


/**
	Registers an endpoint event callback
		
	@param [in]	bEP				Endpoint number
	@param [in]	pfnHandler		Callback function
 */
void USBHwRegisterEPIntHandler(unsigned char bEP, TFnEPIntHandler *pfnHandler)
{
	int idx;
	
	idx = EP2IDX(bEP);

	ASSERT(idx<32);

	/* add handler to list of EP handlers */
	_apfnEPIntHandlers[idx / 2] = pfnHandler;
	
	/* enable EP interrupt */
	USB->USBEpIntEn |= (1 << idx);
	USB->USBDevIntEn |= EP_SLOW;
	
	DBG("Registered handler for EP 0x%x\n", bEP);
}


/**
	Registers an device status callback
		
	@param [in]	pfnHandler	Callback function
 */
void USBHwRegisterDevIntHandler(TFnDevIntHandler *pfnHandler)
{
	_pfnDevIntHandler = pfnHandler;
	
	// enable device interrupt
	USB->USBDevIntEn |= DEV_STAT;

	DBG("Registered handler for device status\n");
}


/**
	Registers the frame callback
		
	@param [in]	pfnHandler	Callback function
 */
void USBHwRegisterFrameHandler(TFnFrameHandler *pfnHandler)
{
	_pfnFrameHandler = pfnHandler;
	
	// enable device interrupt
	USB->USBDevIntEn |= FRAME;

	DBG("Registered handler for frame\n");
}


/**
	Sets the USB address.
		
	@param [in]	bAddr		Device address to set
 */
void USBHwSetAddress(unsigned char bAddr)
{
	USBHwCmdWrite(CMD_DEV_SET_ADDRESS, DEV_EN | bAddr);
}


/**
	Connects or disconnects from the USB bus
		
	@param [in]	fConnect	If TRUE, connect, otherwise disconnect
 */
void USBHwConnect(BOOL fConnect)
{
	USBHwCmdWrite(CMD_DEV_STATUS, fConnect ? CON : 0);
}


/**
	Enables interrupt on NAK condition
		
	For IN endpoints a NAK is generated when the host wants to read data
	from the device, but none is available in the endpoint buffer.
	For OUT endpoints a NAK is generated when the host wants to write data
	to the device, but the endpoint buffer is still full.
	
	The endpoint interrupt handlers can distinguish regular (ACK) interrupts
	from NAK interrupt by checking the bits in their bEPStatus argument.
	
	@param [in]	bIntBits	Bitmap indicating which NAK interrupts to enable
 */
void USBHwNakIntEnable(unsigned char bIntBits)
{
	USBHwCmdWrite(CMD_DEV_SET_MODE, bIntBits);
}


/**
	Gets the status from a specific endpoint.
		
	@param [in]	bEP		Endpoint number
	@return Endpoint status byte (containing EP_STATUS_xxx bits)
 */
unsigned char	USBHwEPGetStatus(unsigned char bEP)
{
	int idx = EP2IDX(bEP);

	return USBHwCmdRead(CMD_EP_SELECT | idx);
}


/**
	Sets the stalled property of an endpoint
		
	@param [in]	bEP		Endpoint number
	@param [in]	fStall	TRUE to stall, FALSE to unstall
 */
void USBHwEPStall(unsigned char bEP, BOOL fStall)
{
	int idx = EP2IDX(bEP);

	USBHwCmdWrite(CMD_EP_SET_STATUS | idx, fStall ? EP_ST : 0);
}


/**
	Writes data to an endpoint buffer
		
	@param [in]	bEP		Endpoint number
	@param [in]	pbBuf	Endpoint data
	@param [in]	iLen	Number of bytes to write
			
	@return TRUE if the data was successfully written or <0 in case of error.
*/
int USBHwEPWrite(unsigned char bEP, unsigned char *pbBuf, int iLen)
{
	int idx;
	
	idx = EP2IDX(bEP);
	
	// set write enable for specific endpoint
	USB->USBCtrl = WR_EN | ((bEP & 0xF) << 2);
	
	// set packet length
	USB->USBTxPLen = iLen;
	
	// write data
	while (USB->USBCtrl & WR_EN) {
		USB->USBTxData = (pbBuf[3] << 24) | (pbBuf[2] << 16) | (pbBuf[1] << 8) | pbBuf[0];
		pbBuf += 4;
	}

	// select endpoint and validate buffer
	USBHwCmd(CMD_EP_SELECT | idx);
	USBHwCmd(CMD_EP_VALIDATE_BUFFER);
	
	return iLen;
}


/**
	Reads data from an endpoint buffer
		
	@param [in]	bEP		Endpoint number
	@param [in]	pbBuf	Endpoint data
	@param [in]	iMaxLen	Maximum number of bytes to read
			
	@return the number of bytes available in the EP (possibly more than iMaxLen),
	or <0 in case of error.
 */
int USBHwEPRead(unsigned char bEP, unsigned char *pbBuf, int iMaxLen)
{
	int i, idx;
	unsigned long	dwData, dwLen;
	
	idx = EP2IDX(bEP);
	
	// set read enable bit for specific endpoint
	USB->USBCtrl = RD_EN | ((bEP & 0xF) << 2);
	
	// wait for PKT_RDY
	do {
		dwLen = USB->USBRxPLen;
	} while ((dwLen & PKT_RDY) == 0);
	
	// packet valid?
	if ((dwLen & DV) == 0) {
		return -1;
	}
	
	// get length
	dwLen &= PKT_LNGTH_MASK;
	
	// get data
	dwData = 0;
	for (i = 0; i < dwLen; i++) {
		if ((i % 4) == 0) {
			dwData = USB->USBRxData;
		}
		if ((pbBuf != NULL) && (i < iMaxLen)) {
			pbBuf[i] = dwData & 0xFF;
		}
		dwData >>= 8;
	}

	// make sure RD_EN is clear
	USB->USBCtrl = 0;

	// select endpoint and clear buffer
	USBHwCmd(CMD_EP_SELECT | idx);
	USBHwCmd(CMD_EP_CLEAR_BUFFER);
	
	return dwLen;
}


/**
	Sets the 'configured' state.
		
	All registered endpoints are 'realised' and enabled, and the
	'configured' bit is set in the device status register.
		
	@param [in]	fConfigured	If TRUE, configure device, else unconfigure
 */
void USBHwConfigDevice(BOOL fConfigured)
{
	// set configured bit
	USBHwCmdWrite(CMD_DEV_CONFIG, fConfigured ? CONF_DEVICE : 0);
}


/**
	USB interrupt handler
		
	@todo Get all 11 bits of frame number instead of just 8

	Endpoint interrupts are mapped to the slow interrupt
 */
void USBHwISR(void)
{
	unsigned long	dwStatus;
	unsigned long dwIntBit;
	unsigned char	bEPStat, bDevStat, bStat;
	int i;
	unsigned short	wFrame;

	// handle device interrupts
	dwStatus = USB->USBDevIntSt;
	
	// frame interrupt
	if (dwStatus & FRAME) {
		// clear int
		USB->USBDevIntClr = FRAME;
		// call handler
		if (_pfnFrameHandler != NULL) {
			wFrame = USBHwCmdRead(CMD_DEV_READ_CUR_FRAME_NR);
			_pfnFrameHandler(wFrame);
		}
	}
	
	// device status interrupt
	if (dwStatus & DEV_STAT) {
		/*	Clear DEV_STAT interrupt before reading DEV_STAT register.
			This prevents corrupted device status reads, see
			LPC2148 User manual revision 2, 25 july 2006.
		*/
		USB->USBDevIntClr = DEV_STAT;
		bDevStat = USBHwCmdRead(CMD_DEV_STATUS);
		if (bDevStat & (CON_CH | SUS_CH | RST)) {
			// convert device status into something HW independent
			bStat = ((bDevStat & CON) ? DEV_STATUS_CONNECT : 0) |
					((bDevStat & SUS) ? DEV_STATUS_SUSPEND : 0) |
					((bDevStat & RST) ? DEV_STATUS_RESET : 0);
			// call handler
			if (_pfnDevIntHandler != NULL) {
				_pfnDevIntHandler(bStat);
			}
		}
	}
	
	// endpoint interrupt
	if (dwStatus & EP_SLOW) {
		// clear EP_SLOW
		USB->USBDevIntClr = EP_SLOW;
		// check all endpoints
		for (i = 0; i < 32; i++) {
			dwIntBit = (1 << i);
			if (USB->USBEpIntSt & dwIntBit) {
				// clear int (and retrieve status)
				USB->USBEpIntClr = dwIntBit;
				Wait4DevInt(CDFULL);
				bEPStat = USB->USBCmdData;
				// convert EP pipe stat into something HW independent
				bStat = ((bEPStat & EPSTAT_FE) ? EP_STATUS_DATA : 0) |
						((bEPStat & EPSTAT_ST) ? EP_STATUS_STALLED : 0) |
						((bEPStat & EPSTAT_STP) ? EP_STATUS_SETUP : 0) |
						((bEPStat & EPSTAT_EPN) ? EP_STATUS_NACKED : 0) |
						((bEPStat & EPSTAT_PO) ? EP_STATUS_ERROR : 0);
				// call handler
				if (_apfnEPIntHandlers[i / 2] != NULL) {
					_apfnEPIntHandlers[i / 2](IDX2EP(i), bStat);
				}
			}
		}
	}
}



/**
	Initialises the USB hardware
		
		
	@return TRUE if the hardware was successfully initialised
 */
BOOL USBHwInit(void)
{
	// P2.9 -> USB_CONNECT
	PINCON->PINSEL4 &= ~0x000C0000;
	PINCON->PINSEL4 |= 0x00040000;

	// P1.18 -> USB_UP_LED
	// P1.30 -> VBUS
	PINCON->PINSEL3 &= ~0x30000030;
	PINCON->PINSEL3 |= 0x20000010;

	// P0.29 -> USB_D+
	// P0.30 -> USB_D-
	PINCON->PINSEL1 &= ~0x3C000000;
	PINCON->PINSEL1 |= 0x14000000;	

	// enable PUSB
	SC->PCONP |= (1 << 31);

	USB->OTGClkCtrl = 0x12;	                  /* Dev clock, AHB clock enable  */
	while ((USB->OTGClkSt & 0x12) != 0x12);
	
	// disable/clear all interrupts for now
	USB->USBDevIntEn = 0;
	USB->USBDevIntClr = 0xFFFFFFFF;
	USB->USBDevIntPri = 0;

	USB->USBEpIntEn = 0;
	USB->USBEpIntClr = 0xFFFFFFFF;
	USB->USBEpIntPri = 0;

	// by default, only ACKs generate interrupts
	USBHwNakIntEnable(0);

	return TRUE;
}

