#ifndef SDCC
  #pragma NOIV					// Do not generate interrupt vectors
#endif

//-----------------------------------------------------------------------------
//	File:		periph.c
//	Contents:	Hooks required to implement USB peripheral function.
//
//	Copyright (c) 1997 AnchorChips, Inc. All rights reserved
//-----------------------------------------------------------------------------
#include <ezusb.h>
#include <ezregs.h>

#include "type.h"

#include "timer.h"
#include "led.h"
#include "ad7739.h"
#include "gps.h"
#include "mag.h"

extern BOOL	GotSUD;			// Received setup data flag
extern BOOL	Sleep;
extern BOOL	Rwuen;
extern BOOL	Selfpwr;

BYTE	Configuration;		// Current configuration
BYTE	AlternateSetting;	// Alternate settings
BYTE  suspCount;
//-----------------------------------------------------------------------------
// Task Dispatcher hooks
//	The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------

void TD_Init(void) 				// Called once at startup
{
	// Enable endpoints 0-7 IN and OUT
	IN07VAL |= bmEP1 + bmEP2 + bmEP4;	// + bmEP6 + bmEP7;	
	OUT07VAL |= bmEP1 + bmEP2 + bmEP4;	// + bmEP6 + bmEP7;

	// Endpoint pairing
	USBPAIR = 0;
	USBPAIR |= 0x09;	// 2 in, 2 out enabled
	USBPAIR |= 0x12;	// 4 in, 4 out enabled

	// Enable interrupts for the IN, OUT endpoints
	OUT07IEN = bmEP1 + bmEP2 + bmEP4;	// + bmEP5 + bmEP6 + bmEP7;	// bmEP3
	IN07IEN = bmEP1 + bmEP2 + bmEP4;	// + bmEP5 + bmEP6 + bmEP7;	// bmEP3
	
	// arm endpoint 1, 2, 4 out to receive data
	EPIO[OUT1BUF_ID].bytes = 0x00;
	EPIO[OUT2BUF_ID].bytes = 0x00;
	EPIO[OUT4BUF_ID].bytes = 0x00;

	suspCount = 1;

	OEA = 0xFF;

	// LED
	led_init();

	// AD7739
	ad7739_init();
 
  // magnetic sensor
  mag_init();

	// Timer0
	timer0_init();

	// GPS
	gps_init();

	Rwuen = TRUE; // Enable remote-wakeup
}

void TD_Poll(void) 				// Called repeatedly while the device is idle
{
   int i;

   for(i = 0; i < 30000; i++);
   //led1_toggle();
   for(i = 0; i < 30000; i++);
   //led1_toggle();
}

#ifdef SDCC
  #define BOOL BYTE
#endif

BOOL TD_Suspend(void) 			// Called before the device goes into suspend mode
{
	return(TRUE);
}

BOOL TD_Resume(void) 			// Called after the device resumes
{
	return(TRUE);
}

//-----------------------------------------------------------------------------
// Device Request hooks
//	The following hooks are called by the end point 0 device request parser.
//-----------------------------------------------------------------------------

BOOL DR_GetDescriptor(void)
{
	return(TRUE);
}

BOOL DR_SetConfiguration(void)	// Called when a Set Configuration command is received
{
	Configuration = SETUPDAT[2];
	return(TRUE);				// Handled by user code
}

BOOL DR_GetConfiguration(void)	// Called when a Get Configuration command is received
{
	IN0BUF[0] = Configuration;
	EZUSB_SET_EP_BYTES(IN0BUF_ID,1);
	return(TRUE);				// Handled by user code
}

BOOL DR_SetInterface(void) 		// Called when a Set Interface command is received
{
	AlternateSetting = SETUPDAT[2];
	return(TRUE);				// Handled by user code
}

BOOL DR_GetInterface(void) 		// Called when a Set Interface command is received
{
	IN0BUF[0] = AlternateSetting;
	EZUSB_SET_EP_BYTES(IN0BUF_ID,1);
	return(TRUE);				// Handled by user code
}

BOOL DR_GetStatus(void)
{
	return(TRUE);
}

BOOL DR_ClearFeature(void)
{
	return(TRUE);
}

BOOL DR_SetFeature(void)
{
	return(TRUE);
}

#define EZUSB_UNARM_EP(ep_id)  			EPIO[ep_id].cntrl = bmEPBUSY

BOOL DR_VendorCmnd(void)
{
   return(TRUE);
}

//-----------------------------------------------------------------------------
// USB Interrupt Handlers
//	The following functions are called by the USB interrupt jump table.
//-----------------------------------------------------------------------------


// Setup Data Available Interrupt Handler

void ISR_Sudav(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 13
#endif
{
	GotSUD = TRUE;				// Set flag


	EZUSB_IRQ_CLEAR();
	USBIRQ = bmSUDAV;			// Clear SUDAV IRQ
}

// Setup Token Interrupt Handler
void ISR_Sutok(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 14
#endif
{
	EZUSB_IRQ_CLEAR();
	USBIRQ = bmSUTOK;			// Clear SUTOK IRQ
}

void ISR_Sof(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 15
#endif
{
	EZUSB_IRQ_CLEAR();
	USBIRQ = bmSOF;				// Clear SOF IRQ
}

void ISR_Ures(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 16
#endif
{
   //
   // Arm all of the OUT endpoints so they can accept data
   //
   EPIO[OUT1BUF_ID].bytes = 0;
   EPIO[OUT2BUF_ID].bytes = 0;
   EPIO[OUT3BUF_ID].bytes = 0;
   EPIO[OUT4BUF_ID].bytes = 0;
   EPIO[OUT5BUF_ID].bytes = 0;
   EPIO[OUT6BUF_ID].bytes = 0;
   EPIO[OUT7BUF_ID].bytes = 0;

	EZUSB_IRQ_CLEAR();
	USBIRQ = bmURES;			// Clear URES IRQ
}

void ISR_IBN(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 17
#endif
{
   // ISR for the IN Bulk NAK (IBN) interrupt.
}

void ISR_Susp(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 18
#endif
{
   Sleep = TRUE;

   EZUSB_IRQ_CLEAR();
   USBIRQ = bmSUSP;
}

void ISR_Ep0in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 19
#endif
{
}

void ISR_Ep0out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 20
#endif
{
}

void ISR_Ep1in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 21
#endif
{
	EZUSB_IRQ_CLEAR();
	IN07IRQ = bmEP1;
}

#define SFR_LIST \
	case 0x81: FUNC_SFR(SP);      break; \
	case 0x82: FUNC_SFR(DPL);     break; \
	case 0x83: FUNC_SFR(DPH);     break; \
	case 0x84: FUNC_SFR(DPL1);    break; \
	case 0x85: FUNC_SFR(DPH1);    break; \
	case 0x86: FUNC_SFR(DPS);     break; \
	case 0x87: FUNC_SFR(PCON);    break; \
	case 0x88: FUNC_SFR(TCON);    break; \
	case 0x89: FUNC_SFR(TMOD);    break; \
	case 0x8a: FUNC_SFR(TL0);     break; \
	case 0x8b: FUNC_SFR(TL1);     break; \
	case 0x8c: FUNC_SFR(TH0);     break; \
	case 0x8d: FUNC_SFR(TH1);     break; \
	case 0x8e: FUNC_SFR(CKCON);   break; \
	case 0x8f: FUNC_SFR(SPC_FNC); break; \
	case 0x91: FUNC_SFR(EXIF);    break; \
	case 0x92: FUNC_SFR(MPAGE);   break; \
	case 0x98: FUNC_SFR(SCON0);   break; \
	case 0x99: FUNC_SFR(SBUF0);   break; \
	case 0xa8: FUNC_SFR(IE);      break; \
	case 0xb8: FUNC_SFR(IP);      break; \
	case 0xc0: FUNC_SFR(SCON1);   break; \
	case 0xc1: FUNC_SFR(SBUF1);   break; \
	case 0xc8: FUNC_SFR(T2CON);   break; \
	case 0xca: FUNC_SFR(RCAP2L);  break; \
	case 0xcb: FUNC_SFR(RCAP2H);  break; \
	case 0xcc: FUNC_SFR(TL2);     break; \
	case 0xcd: FUNC_SFR(TH2);     break; \
	case 0xd0: FUNC_SFR(PSW);     break; \
	case 0xd8: FUNC_SFR(EICON);   break; \
	case 0xe0: FUNC_SFR(ACC);     break; \
	case 0xe8: FUNC_SFR(EIE);     break; \
	case 0xf0: FUNC_SFR(B);       break; \
	case 0xf8: FUNC_SFR(EIP);     break;

void sfr_write(u8 add,u8 m){
	#define FUNC_SFR(_sfr_) (_sfr_=m)
	switch(add){
	SFR_LIST
	default: break;
	}
	#undef FUNC_SFR
}

u8 sfr_read(u8 add){
	u8 m;
	#define FUNC_SFR(_sfr_) (m=_sfr_)
	switch(add){
	SFR_LIST
	default: m=0; break;
	}
	#undef FUNC_SFR
	return m;
}

#define	SFR_WRITE	0x00
#define	SFR_READ	0x01
#define	EZR_WRITE	0x02
#define	EZR_READ	0x03

void ISR_Ep1out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 22
#endif
{
	
	u8 i,r;
	u8 xdata *ezrp;
	r=0;
	for(i=0;i<OUT1BC;){
		switch(OUT1BUF[i]){
		case SFR_WRITE:
			sfr_write(OUT1BUF[++i],OUT1BUF[++i]);
			++i;
			break;
		case SFR_READ:
			IN1BUF[r++]=sfr_read(OUT1BUF[++i]);
			++i;
			break;
		case EZR_WRITE:
#ifndef SDCC
      ezrp=(u8 *)(0x7f00+OUT1BUF[++i]);
#else
      ezrp=(unsigned char xdata*)(0x7f00+OUT1BUF[++i]);
#endif
			*ezrp=OUT1BUF[++i];
			++i;
			break;
		case EZR_READ:
#ifndef SDCC
      ezrp=(u8 *)(0x7f00+OUT1BUF[++i]);
#else
      ezrp=(unsigned char xdata*)(0x7f00+OUT1BUF[++i]);
#endif
			IN1BUF[r++]=*ezrp;
			++i;
			break;
		default:
			i++;
			break;
		}
	}
	if(r!=0){
		IN1BC=r;
	}
	
	OUT1BC = 0;
	EZUSB_IRQ_CLEAR();
	OUT07IRQ = bmEP1;
}

void ISR_Ep2in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 23
#endif
{
	EZUSB_IRQ_CLEAR();
	IN07IRQ = bmEP2;
}

void ISR_Ep2out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 24
#endif
{
	OUT2BC = 0;
	EZUSB_IRQ_CLEAR();
	OUT07IRQ = bmEP2;
}

void ISR_Ep3in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 25
#endif
{
	EZUSB_IRQ_CLEAR();
	IN07IRQ = bmEP3;
}

void ISR_Ep3out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 26
#endif
{
	OUT3BC = 0;
	EZUSB_IRQ_CLEAR();
	OUT07IRQ = bmEP3;
}

void ISR_Ep4in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 27
#endif
{
	EZUSB_IRQ_CLEAR();
	IN07IRQ = bmEP4;
}

void ISR_Ep4out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 28
#endif
{
	OUT4BC = 0;
	EZUSB_IRQ_CLEAR();
	OUT07IRQ = bmEP4;
}

void ISR_Ep5in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 29
#endif
{
	EZUSB_IRQ_CLEAR();
	IN07IRQ = bmEP5;
}

void ISR_Ep5out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 30
#endif
{
	OUT5BC = 0;
	EZUSB_IRQ_CLEAR();
	OUT07IRQ = bmEP5;
}

void ISR_Ep6in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 31
#endif
{
	EZUSB_IRQ_CLEAR();
	IN07IRQ = bmEP6;
}

void ISR_Ep6out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 32
#endif
{
	OUT6BC = 0;
	EZUSB_IRQ_CLEAR();
	OUT07IRQ = bmEP6;
}

void ISR_Ep7in(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 33
#endif
{
	EZUSB_IRQ_CLEAR();
	IN07IRQ = bmEP7;
}

void ISR_Ep7out(void)
#ifndef SDCC
  interrupt 0
#else
  interrupt 34
#endif
{
	OUT7BC = 0;
	EZUSB_IRQ_CLEAR();
	OUT07IRQ = bmEP7;
}


