/**************************************************************************//**
* @file     musbfsfc.c
* @version  V1.00
* $Revision: 2 $
* $Date: 20/08/04 14:25 $
* @brief    Interrupt handler for MUSBFSFC firmware
*
* @note
* Copyright (C) 2020 Panchip Technology Corp. All rights reserved.
*****************************************************************************/
#include "musbfsfc.h"
#include "descript.h"
#include "endpoint.h"
#include "endpoint0.h"
#include "pan271x.h"
#include "pan_usb.h"
//#define SYS_TEST /*.....*/

//test
uint8_t bulkin_test[128] = {0,};
uint8_t bulkout_test[128] = {0,};
uint8_t bulkin_ep_need_data = DATA_NONEED;
uint8_t suspend_evt = FALSE;
//#pragma arm section code = "RAMCODE"

void USB_PersonalEpInit(void)
{
	/* Initialise endpoint status structures with endpoint numbers */
	gepbin1.byEP = 1;
	EndpointBulkIn (&gepbin1, M_EP_RESET);
}

/****************************************
  USB Reset
****************************************/
void USB_Reset(void)
{
	/* Set device into default state */
	gnDevState = DEVSTATE_DEFAULT;
	/* Initialise descriptors */
	InitialiseDesc();
	/* Reset any state machines for each endpoint */
	/* This example assumes 3 bulk IN endpoints with endpoint numbers 1,2, 3*/
	/* and 3 bulk out endpoints with endpoint numbers 1,2 */
	Endpoint0(M_EP_RESET);

	USB_PersonalEpInit();
	bulkin_ep_need_data = DATA_NEED;
}

void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset)
{
  uint16_t index = 0;

  /* Put in global buffer same values */
  for (index = 0; index < BufferLength; index++)
  {
    pBuffer[index] = index + Offset;
  }
}
extern void USB_TestExample(uint32_t IntrFlag);
extern void USB_IntUsbProc(uint32_t IntrFlag);


//TEST
extern uint8_t test_pin;

#if 0
extern uint16_t data_offset,max_test_size ;
extern uint8_t *test_ptr;
extern uint8_t test_arr[300];
void USB_TestExample(uint32_t IntrFlag)
{
//	SYS_TEST("int occured,IntrFlag:%x \r\n",IntrFlag);
	switch(IntrFlag){
		//bulk out
		case USB_INT_BULKOUT_EP1:
			SYS_TEST("EP10\r\n");EndpointBulkOut(&gepbout1, M_EP_NORMAL);	
			break;
		case USB_INT_BULKOUT_EP2:
			SYS_TEST("EP20\r\n");//EndpointBulkOut(&gepbout2, M_EP_NORMAL);
			break;
		case USB_INT_BULKOUT_EP3:
			SYS_TEST("EP30\r\n");EndpointBulkOut(&gepbout3, M_EP_NORMAL);
			break;
		//bulk in		
		case USB_INT_BULKIN_EP1:
//			SYS_TEST("EP11\r\n");
//			Fill_Buffer(bulkin_test,16,10);
			gepbin1.byEP = 1;
			gepbin1.nBytesLeft = 4;
			gepbin1.pData = (void*)(test_arr+data_offset);
			EndpointBulkIn (&gepbin1, M_EP_NORMAL);  
			bulkin_ep_need_data = DATA_NONEED;
			data_offset += 4;
			if(data_offset>sizeof(max_test_size))
				data_offset=0;
				
			break;
		case USB_INT_BULKIN_EP2:
			SYS_TEST("EP21\r\n");
			gepbin2.byEP = 2;
			gepbin2.nBytesLeft = 523;
			gepbin2.pData = (void*)bulkin_test;			
			EndpointBulkIn(&gepbin2, M_EP_NORMAL);
			break;
		case USB_INT_BULKIN_EP3:
			SYS_TEST("EP31\r\n");
			gepbin3.byEP = 3;
			gepbin3.nBytesLeft = 789;
			gepbin3.pData = (void*)bulkin_test;		
			EndpointBulkIn(&gepbin3, M_EP_NORMAL);
			break;
		default:break;			
	}	
}
#endif
/****************************************
  Top level interrupt handler
****************************************/
void musbfsfc_intr(void)
{
	uint8_t     IntrUSB;
	uint16_t    IntrIn;
	uint16_t    IntrOut;
	uint32_t 	IntrFlag;
	
	/* Read interrupt registers */
	/* Mote if less than 8 IN endpoints are configured then */
	/* only M_REG_INTRIN1 need be read. */
	/* Similarly if less than 8 OUT endpoints are configured then */
	/* only M_REG_INTROUT1 need be read. */
	IntrUSB = READ_REG(USB->INT_USB);
	IntrIn  = (uint16_t)READ_REG(USB->INT_IN2);
	IntrIn <<= 8;
	IntrIn  |= (uint16_t)READ_REG(USB->INT_IN1);
	IntrOut  = (uint16_t)READ_REG(USB->INT_OUT2);
	IntrOut <<= 8;
	IntrOut  |= (uint16_t)READ_REG(USB->INT_OUT1);
	
	IntrFlag = IntrIn;
	IntrFlag <<= 16;
	IntrFlag |= IntrOut;

	if (IntrUSB & M_INTR_PLUG) {
		if ((IntrUSB & M_INTR_PLUG_OUT) == M_INTR_PLUG_OUT) {
			SYS_TEST("Plug out\n");
		} else if (IntrUSB & M_INTR_PLUG_OUT) {
			suspend_evt = FALSE;
			SYS_TEST("Plug in\n");
		}
	}
	if (IntrUSB & M_INTR_RESUME) {
		SYS_TEST("Resume\n");
	}
	
	if (IntrUSB & M_INTR_SUSPEND) {
		suspend_evt = TRUE;
		SYS_TEST("Suspend\n");
	}
	
	if (IntrUSB & M_INTR_SOF) {
		SYS_TEST("Sof\n");
	}

	/* Check for system interrupts */
	if (IntrUSB & M_INTR_RESET) 
	{
		USB->POWER |= 0x1;
		USB->INT_USBE |= 0x17;
		SYS_TEST("RST\r\n");
		USB_Reset();
	}
	/* Check for endpoint 0 interrupt */
	if (IntrIn & M_INTR_EP0) 
	{  
		Endpoint0(M_EP_NORMAL);
	}

	/* Check for each configured endpoint interrupt */
	/* This example assumes 2 bulk IN endpoints with endpoint numbers 1,2, */
	/* and 2 bulk out endpoints with endpoint numbers 1,2 */
		
	if(IntrFlag&0xfffefffe)
		USB_TestExample(IntrFlag);

return;
}
//#pragma arm section

