X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=sboot%2Fmagpie_1_1%2Fsboot%2Fhif%2Fusb%2Fsrc%2Fusb_api.c;fp=sboot%2Fmagpie_1_1%2Fsboot%2Fhif%2Fusb%2Fsrc%2Fusb_api.c;h=897bcfaa4547a1a5af172d60d1db4cb14dd158ec;hb=ff66305a044be28464fa0969ea2d605bb268d478;hp=0000000000000000000000000000000000000000;hpb=60b496560eec004ded92ae4dad43b3d102c6658d;p=open-ath9k-htc-firmware.git diff --git a/sboot/magpie_1_1/sboot/hif/usb/src/usb_api.c b/sboot/magpie_1_1/sboot/hif/usb/src/usb_api.c new file mode 100755 index 0000000..897bcfa --- /dev/null +++ b/sboot/magpie_1_1/sboot/hif/usb/src/usb_api.c @@ -0,0 +1,2499 @@ +#include "usb_defs.h" +#include "usb_type.h" +#include "usb_pre.h" +#include "usb_extr.h" +#include "usb_std.h" +#include "reg_defs.h" +#include "athos_api.h" +#include "usbfifo_api.h" + +#include "sys_cfg.h" + +#if SYSTEM_MODULE_USB + +#define CMD_GET_CUSTOM_DATA 4 +LOCAL void flash_read(uint16_t len, uint16_t ofset); + +SetupPacket ControlCmd; +USB_FIFO_CONFIG usbFifoConf; +uint32_t fwCheckSum = 0; + +#define fBUS_POWER 1 +uint16_t UsbStatus[3]; + +/* Variable for USB EP0 pipe (USB.c) */ +uint16_t *pu8DescriptorEX; +uint16_t u16TxRxCounter; +uint16_t *u8ConfigDescriptorEX; +//extern BOOLEAN bUsbEP0HaltSt; +Action eUsbCxFinishAction; +CommandType eUsbCxCommand; +BOOLEAN UsbChirpFinish; + +uint16_t u8UsbConfigValue; +uint16_t u8UsbInterfaceValue; +uint16_t u8UsbInterfaceAlternateSetting; +uint16_t u16FirmwareComplete; + +extern uint16_t *UsbDeviceDescriptor; +extern uint16_t *String00Descriptor; +extern uint16_t *String10Descriptor; +extern uint16_t *String20Descriptor; +extern uint16_t *String30Descriptor; + +///////////////////////////////////////////////// +// should be declared as extern array not pointer +extern uint16_t u8DeviceQualifierDescriptorEX[]; +extern uint16_t u8OtherSpeedConfigDescriptorEX[]; + +uint16_t *u8UsbDeviceDescriptor; +uint16_t *u8String00Descriptor; +uint16_t *u8String10Descriptor; +uint16_t *u8String20Descriptor; +uint16_t *u8String30Descriptor; + + +#if 0 // use macro instead of function +void mUsbEPinRsTgSet(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg |= BIT4; + USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + (USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT4)); + +} + +void mUsbEPinRsTgClr(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg &= ~BIT4; + USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + (USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&(~BIT4))); +} + +void mUsbEPoutRsTgSet(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg |= BIT4; + USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + (USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT4)); +} + +void mUsbEPoutRsTgClr(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg &= ~BIT4; + USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + (USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&(~BIT4))); +} + +void mUsbEPinStallSet(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg |= BIT3; + USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT3); +} + +void mUsbEPinStallClr(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg &= ~BIT3; + + USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + (USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&(~BIT3))); +} + +void mUsbEPoutStallSet(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg |= BIT3; + USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + (USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT3)); +} + +void mUsbEPoutStallClr(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //*reg &= ~BIT3; + USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + (USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&(~BIT3))); +} + +uint8_t mUsbEPinStallST(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //return ((*reg & BIT3) >> 3); + return ((USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))& BIT3) >> 3); +} + +uint8_t mUsbEPoutStallST(uint8_t u8ep) +{ + //uint8_t* reg = (uint8_t*) (ZM_FUSB_BASE+ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)); + //return ((*reg & BIT3) >> 3); + return ((USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))& BIT3) >> 3); +} + +uint8_t mUsbEPMapRd(uint8_t EPn) +{ + //uint8_t *reg = (uint8_t*) (ZM_FUSB_BASE+0x30+(EPn-1)); + //return *reg; + return (USB_BYTE_REG_READ((0x30+(EPn-1)))); +} + +uint8_t mUsbFIFOCfgRd(uint8_t FIFOn) +{ + //uint8_t *reg = (uint8_t*) (ZM_FUSB_BASE+0x90+FIFOn); + //return *reg; + return (USB_BYTE_REG_READ((0x90+FIFOn))); +} + +void vUsb_Data_Out0Byte(void) +{ + //ZM_INTR_SOURCE_7_REG &= ~BIT7; + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_REG, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_REG&(~BIT7)))); +} + + +void vUsb_Data_In0Byte(void) +{ + //ZM_INTR_SOURCE_7_REG &= ~BIT6; + + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_REG, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_REG&(~BIT6)))); +} + + +/***********************************************************************/ +// vUsb_ep0end() +// Description: +// 1. End this transfer. +// input: none +// output: none +/***********************************************************************/ +void vUsb_ep0end(void) +{ + eUsbCxCommand = CMD_VOID; + //ZM_CX_CONFIG_STATUS_REG = 0x01; + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x01); + //mUsbEP0DoneSet(); // Return EP0_Done flag +} + +/***********************************************************************/ +// vUsb_ep0fail() +// Description: +// 1. Stall this transfer. +// input: none +// output: none +/***********************************************************************/ +void vUsb_ep0fail(void) +{ + //ZM_CX_CONFIG_STATUS_REG = 0x04; + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x04); + //mUsbEP0StallSet(); // Return EP0_Stall +} + + +/***********************************************************************/ +// vUsb_rst() +// Description: +// 1. Change descriptor table (High or Full speed). +// input: none +// output: none +/***********************************************************************/ +void vUsb_rst(void) +{ +// zfUartSendStr((uint8_t *) "vUsb_rst\r\n"); + //ZM_INTR_SOURCE_7_REG &= ~0x02; + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&(~BIT1))); + UsbChirpFinish = FALSE; +} + +/***********************************************************************/ +// vUsb_suspend() +// Description: +// 1. . +// input: none +// output: none +/***********************************************************************/ +void vUsb_suspend(void) +{ +// uP must do-over everything it should handle +// and do before into the suspend mode + //mUsbIntSuspClr(); // Go Suspend status + //ZM_INTR_SOURCE_7_REG &= ~0x04; + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&(~BIT2))); +} + +/***********************************************************************/ +// vUsb_resm() +// Description: +// 1. Change descriptor table (High or Full speed). +// input: none +// output: none +/***********************************************************************/ +void vUsb_resm(void) +{ +// uP must do-over everything it should handle +// and do before into the suspend mode + +// mUsbIntResmClr(); // uP must wakeup immediately + //ZM_INTR_SOURCE_7_REG &= ~0x08; + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&(~BIT3))); +} + +#else + +#define mUsbEPinRsTgSet(u8ep) USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT4) + +#define mUsbEPinRsTgClr(u8ep) USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&~BIT4) + +#define mUsbEPoutRsTgSet(u8ep) USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT4) + +#define mUsbEPoutRsTgClr(u8ep) USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&~BIT4) + +#define mUsbEPinStallSet(u8ep) USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT3) + +#define mUsbEPinStallClr(u8ep) USB_BYTE_REG_WRITE((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&~BIT3) + +#define mUsbEPoutStallSet(u8ep) USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))|BIT3) + +#define mUsbEPoutStallClr(u8ep) USB_BYTE_REG_WRITE((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)), \ + USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))&~BIT3) + +#define mUsbEPinStallST(u8ep) ((USB_BYTE_REG_READ((ZM_EP_IN_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))& BIT3) >> 3) + +#define mUsbEPoutStallST(u8ep) ((USB_BYTE_REG_READ((ZM_EP_OUT_MAX_SIZE_HIGH_OFFSET+(u8ep << 1)))& BIT3) >> 3) + +#define mUsbEPMapRd(EPn) (USB_BYTE_REG_READ((0x30+(EPn-1)))) + +#define mUsbFIFOCfgRd(FIFOn) (USB_BYTE_REG_READ((0x90+FIFOn))) + +#define vUsb_Data_Out0Byte(void) USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_REG, \ + USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_REG&~BIT7)) + + +#define vUsb_Data_In0Byte(void) USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_REG, \ + USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_REG&~BIT6)) + +#define vUsb_ep0end(void) \ +{ \ + eUsbCxCommand = CMD_VOID; \ + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x01); \ +} + +#define vUsb_ep0fail(void) USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x04) + +#define vUsb_rst() \ +{ \ + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~BIT1)); \ + UsbChirpFinish = FALSE; \ +} + +#define vUsb_suspend() USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~BIT2)) + +#define vUsb_resm() USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, \ + (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~BIT3)) + + +#endif + +LOCAL void flash_read_data(void) +{ + uint8_t u8temp; + + // to keep tracking the txrx fifo + // max 64 bytes for transmission one time, + if (u16TxRxCounter < EP0MAXPACKETSIZE) + u8temp = (uint8_t) u16TxRxCounter; + else + u8temp = EP0MAXPACKETSIZE; + + u16TxRxCounter -= (uint16_t) u8temp; + + { + register uint8_t u8count; + uint8_t remainder; + + for (u8count = 0; u8count < (u8temp/4); u8count ++) + { + uint32_t ep0_data; + uint16_t ep0_low; + uint16_t ep0_high; + + // pack data into word size + ep0_low = *pu8DescriptorEX++; + ep0_high = *pu8DescriptorEX++; + + // composed the data as a word + ep0_data = (ep0_high << 16) + ep0_low; + + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, ep0_data); + } + + remainder = u8temp % 4; + + // Check whether there are data needed to be filled into the FIFO + if (remainder == 3) + { + uint32_t ep0_data; + uint16_t ep0_low; + uint16_t ep0_high; + + // pack data into word size + ep0_low = *pu8DescriptorEX++; + ep0_high = *pu8DescriptorEX++; + + ep0_data = (ep0_high << 16) + ep0_low; + + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, ep0_data); + } + else if (remainder == 2) + { + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, *pu8DescriptorEX); + } + else if (remainder == 1) + { + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, *pu8DescriptorEX); + } + + // Restore CBus FIFO size to word size + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xf); + } + + // end of the data stage + if (u16TxRxCounter == 0) + { + eUsbCxCommand = CMD_VOID; + eUsbCxFinishAction = ACT_DONE; + } +} + +/***********************************************************************/ +// vUsb_ep0tx() +// Description: +// 1. Transmit data to EP0 FIFO. +// input: none +// output: none +/***********************************************************************/ +LOCAL void vUsb_ep0tx(void) +{ + switch (eUsbCxCommand) + { + case CMD_GET_DESCRIPTOR: + A_USB_EP0_TX_DATA(); + break; + + default: + /* Mark endpoint STALL */ + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, BIT6); + + break; + } + +// eUsbCxFinishAction = ACT_IDLE; +} + + +/***********************************************************************/ +// vUsb_ep0rx() +// Description: +// 1. Receive data from EP0 FIFO. +// input: none +// output: none +/***********************************************************************/ +LOCAL void vUsb_ep0rx(void) +{ + + switch (eUsbCxCommand) + { + case CMD_SET_DESCRIPTOR: + A_USB_EP0_RX_DATA(); + break; + default: + //mUsbEP0StallSet(); + break; + } + + if (u16TxRxCounter != 0) + eUsbCxFinishAction = ACT_IDLE; +} + + +LOCAL void vUsbClrEPx(void) +{ + uint8_t u8ep; + + // Clear All EPx Toggle Bit + for (u8ep = 1; u8ep <= FUSB200_MAX_EP; u8ep ++) + { + mUsbEPinRsTgSet(u8ep); + mUsbEPinRsTgClr(u8ep); + } + for (u8ep = 1; u8ep <= FUSB200_MAX_EP; u8ep ++) + { + mUsbEPoutRsTgSet(u8ep); + mUsbEPoutRsTgClr(u8ep); + } +} + + +/***********************************************************************/ +// bGet_status() +// Description: +// 1. Send 2 bytes status to host. +// input: none +// output: TRUE or FALSE (BOOLEAN) +/***********************************************************************/ +LOCAL BOOLEAN bGet_status(void) +{ + uint8_t RecipientStatusLow; + + RecipientStatusLow = UsbStatus[mDEV_REQ_REQ_RECI() & 0x0F]; + + //ZM_CBUS_FIFO_SIZE_REG = 0x3; + //ZM_EP0_DATA_REG = RecipientStatusLow; + + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, RecipientStatusLow); + + // Restore CBus FIFO size to word size + //ZM_CBUS_FIFO_SIZE_REG = 0xf; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xf); + + eUsbCxFinishAction = ACT_DONE; + return TRUE; +} + +/***********************************************************************/ +// bClear_feature() +// Description: +// 1. Send 2 bytes status to host. +// input: none +// output: TRUE or FALSE (BOOLEAN) +/***********************************************************************/ +LOCAL BOOLEAN bClear_feature(void) +{ + if (mDEV_REQ_VALUE() > cUSB_FEATSEL_END) + return FALSE; + + if ((mDEV_REQ_VALUE() == 0) && (mDEV_REQ_REQ_RECI() != cUSB_REQTYPE_ENDPOINT)) + return FALSE; + + UsbStatus[2] = 0; + eUsbCxFinishAction = ACT_DONE; + + return TRUE; +} + +/***********************************************************************/ +// bSet_feature() +// Description: +// 1. Send 2 bytes status to host. +// input: none +// output: TRUE or FALSE (BOOLEAN) +/***********************************************************************/ +#if ZM_SELF_TEST_MODE + +#define TEST_J 0x02 +#define TEST_K 0x04 +#define TEST_SE0_NAK 0x08 +#define TEST_PKY 0x10 + +uint16_t TestPatn0[] = { TEST_J, TEST_K, TEST_SE0_NAK }; +uint32_t TestPatn1[] = { + 0x00000000, 0x00000000, 0xAA00AA00, // JKJKJKJK x 9 + 0xAAAAAAAA, 0xEEAAAAAA, // AA x 8 + 0xEEEEEEEE, 0xFEEEEEEE, // EE x 8 + 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, // FF x 11 + 0xF7EFDFBF, 0x7EFCFDFB, 0xFDFBDFBF}; + +#endif +LOCAL BOOLEAN bSet_feature(void) +{ + + //A_PRINTF("bSet_feature...\n\r"); + + switch (mDEV_REQ_VALUE()) // FeatureSelector + { + case 0: // ENDPOINT_HALE + // AVM Patch: + // always check RECEIPIENT + if (mDEV_REQ_REQ_RECI() == cUSB_REQTYPE_ENDPOINT) + { + eUsbCxFinishAction = ACT_DONE; + } + else + { + return FALSE; + } + + break; + + case 1 : // Device Remote Wakeup + // Set "Device_Remote_Wakeup", Turn on the"RMWKUP" bit in Mode Register + mUsbRmWkupSet(); + //USB_BYTE_REG_WRITE(ZM_MAIN_CTRL_OFFSET, USB_BYTE_REG_READ(ZM_MAIN_CTRL_OFFSET)|BIT0); + eUsbCxFinishAction = ACT_DONE; + break; + + #if ZM_SELF_TEST_MODE + case 2 : // Test Mode + // ii = mDEV_REQ_INDEX() >> 8; + // switch (ii) // TestSelector + switch (mDEV_REQ_INDEX() >> 8) // TestSelector + { + case 0x1: // Test_J + case 0x2: // Test_K + case 0x3: // TEST_SE0_NAK + // mUsbTsMdWr(TestPatn0[(mDEV_REQ_INDEX() >> 8) - 1]); + //ZM_PHY_TEST_SELECT_REG = TestPatn0[(mDEV_REQ_INDEX() >> 8) - 1]; + USB_BYTE_REG_WRITE(ZM_PHY_TEST_SELECT_OFFSET, (TestPatn0[(mDEV_REQ_INDEX() >> 8) - 1])); + eUsbCxFinishAction = ACT_DONE; + break; + + case 0x4: // Test_Packet + // mUsbTsMdWr(TEST_PKY); + // mUsbEP0DoneSet(); // special case: follow the test sequence + //ZM_PHY_TEST_SELECT_REG = TEST_PKY; + //ZM_CX_CONFIG_STATUS_REG = 0x01; + USB_BYTE_REG_WRITE(ZM_PHY_TEST_SELECT_OFFSET, TEST_PKY); + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, BIT0); + /***********************************************************************/////// + // Jay ask to modify, 91-6-5 (Begin) // + /***********************************************************************/////// + // mUsbTsMdWr(TEST_PKY); + // mUsbEP0DoneSet(); // special case: follow the test sequence + //ZM_PHY_TEST_SELECT_REG = TEST_PKY; + USB_BYTE_REG_WRITE(ZM_PHY_TEST_SELECT_OFFSET, TEST_PKY); + + //ZM_CX_CONFIG_STATUS_REG = 0x01; + /***********************************************************************/////// + // Jay ask to modify, 91-6-5 (Begin) // + /***********************************************************************/////// + { + uint16_t ii; + + /* Set to two bytes mode */ + //ZM_CBUS_FIFO_SIZE_REG = 0x0f; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f); + + for (ii = 0; ii < sizeof(TestPatn1)/sizeof(uint32_t); ii++) + { + //ZM_EP0_DATA_REG = TestPatn1[ii]; + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, TestPatn1[ii]); + } + + /* Set to one byte mode */ + //ZM_CBUS_FIFO_SIZE_REG = 0x07; + //ZM_EP0_DATA_REG = 0x007EFDFB; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x07); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, 0x007EFDFB); + + /* Set to four bytes mode */ + //ZM_CBUS_FIFO_SIZE_REG = 0x0f; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f); + } + /***********************************************************************/////// + // Jay ask to modify, 91-6-5 (End) // + /***********************************************************************/////// + + // Turn on "r_test_packet_done" bit(flag) (Bit 5) + //mUsbTsPkDoneSet(); + //ZM_CX_CONFIG_STATUS_REG = 0x02; + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, BIT1); + break; + + case 0x5: // Test_Force_Enable + //FUSBPort[0x08] = 0x20; //Start Test_Force_Enable + break; + + default: + return FALSE; + } + break; + #endif + default : + return FALSE; + } + + if (eUsbCxFinishAction == ACT_DONE) + UsbStatus[2] = 1; + + return TRUE; +} + + +/***********************************************************************/ +// bSet_address() +// Description: +// 1. Set addr to FUSB200 register. +// input: none +// output: TRUE or FALSE (BOOLEAN) +/***********************************************************************/ +LOCAL BOOLEAN bSet_address(void) +{ + + //A_PRINTF("bSet_feature...\n\r"); + + if (mDEV_REQ_VALUE() >= 0x0100) + return FALSE; + else + { +// zfUartSendStrAndHex((uint8_t *) "USB_SET_ADDRESS=", mDEV_REQ_VALUE()); + //ZM_DEVICE_ADDRESS_REG = mDEV_REQ_VALUE(); + USB_BYTE_REG_WRITE(ZM_DEVICE_ADDRESS_OFFSET, mDEV_REQ_VALUE()); + + eUsbCxFinishAction = ACT_DONE; + return TRUE; + } +} + +/***********************************************************************/ +// bGet_descriptor() +// Description: +// 1. Point to the start location of the correct descriptor. +// 2. set the transfer length +// input: none +// output: TRUE or FALSE (BOOLEAN) +/***********************************************************************/ +LOCAL BOOLEAN bGet_descriptor(void) +{ + //A_PRINTF("bGet_descriptor...\n\r"); + +// Change Descriptor type +#if 0 + u8ConfigDescriptorEX[mTABLE_IDX(1)] = + m2BYTE(CONFIG_LENGTH, DT_CONFIGURATION); + u8OtherSpeedConfigDescriptorEX[mTABLE_IDX(1)] = + m2BYTE(CONFIG_LENGTH, DT_OTHER_SPEED_CONFIGURATION); +#endif + + //*(volatile uint32_t*)0x1c0004 = 'G'; + + switch (mDEV_REQ_VALUE_HIGH()) + { + case 1: // device descriptor + pu8DescriptorEX = u8UsbDeviceDescriptor; + u16TxRxCounter = mTABLE_LEN(u8UsbDeviceDescriptor[0]); + //u16TxRxCounter = 18; + break; + + case 2: // configuration descriptor + // It includes Configuration, Interface and Endpoint Table +// zfUartSendStr((uint8_t *)"Configuration Descriptor\r\n"); + switch (mDEV_REQ_VALUE_LOW()) + { + case 0x00: // configuration no: 0 + pu8DescriptorEX = u8ConfigDescriptorEX; + u16TxRxCounter = u8ConfigDescriptorEX[1]; + //u16TxRxCounter = 46; + break; + default: + return FALSE; + } + break; + + case 3: // string descriptor + // DescriptorIndex = low_byte of wValue +// zfUartSendStr((uint8_t *)"String Descriptor\r\n"); + switch (mDEV_REQ_VALUE_LOW()) + { + case 0x00: + pu8DescriptorEX = u8String00Descriptor; + //u16TxRxCounter = 4; + break; + + case 0x10: + pu8DescriptorEX = u8String10Descriptor; + //u16TxRxCounter = 12; + break; + + case 0x20: + pu8DescriptorEX = u8String20Descriptor; + //u16TxRxCounter = 24; + break; + + case 0x30: + pu8DescriptorEX = u8String30Descriptor; + break; + + default: + return FALSE; + } + u16TxRxCounter = mTABLE_LEN(pu8DescriptorEX[0]); + break; + + case 6: // Device_Qualifier descritor +// zfUartSendStr((uint8_t *) "Device_Qualifier Descriptor\r\n"); + pu8DescriptorEX = u8DeviceQualifierDescriptorEX; + u16TxRxCounter = mTABLE_LEN(u8DeviceQualifierDescriptorEX[0]); + //u16TxRxCounter = 10; + break; + + case 7: // Other_Speed_Configuration +// zfUartSendStr((uint8_t *)"Other_Speed Descriptor\r\n"); + // It includes Configuration, Interface and Endpoint Table + pu8DescriptorEX = u8OtherSpeedConfigDescriptorEX; + u16TxRxCounter = u8OtherSpeedConfigDescriptorEX[1]; + //u16TxRxCounter = 46; + break; + + default: +// zfUartSendStrAndHex((uint8_t *) "Descriptor error=", mDEV_REQ_VALUE_HIGH()); + return FALSE; + } + + if (u16TxRxCounter > mDEV_REQ_LENGTH()) + u16TxRxCounter = mDEV_REQ_LENGTH(); + +// vUsbEP0TxData(); + A_USB_EP0_TX_DATA(); + + // somehow if there is still data need to send out, we shouldn't set CX_DONE + // wait for another EP0_IN + if( u16TxRxCounter > 0 ) + { + eUsbCxCommand = CMD_GET_DESCRIPTOR; + } + + return TRUE; +} + + +/***********************************************************************/ +// bGet_configuration() +// Description: +// 1. Send 1 bytes configuration value to host. +// input: none +// output: none +/***********************************************************************/ +LOCAL BOOLEAN bGet_configuration(void) +{ + + //A_PRINTF("bGet_configuration...\n\r"); + + //ZM_CBUS_FIFO_SIZE_REG = 0x1; + //ZM_EP0_DATA_REG = u8UsbConfigValue; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, u8UsbConfigValue); + + // Restore CBus FIFO size to word size + //ZM_CBUS_FIFO_SIZE_REG = 0xf; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xf); + + eUsbCxFinishAction = ACT_DONE; + + return TRUE; +} + +/***********************************************************************/ +// bSet_configuration() +// Description: +// 1. Get 1 bytes configuration value from host. +// 2-1. if (value == 0) then device return to address state +// 2-2. if (value match descriptor table) +// then config success & Clear all EP toggle bit +// 2-3 else stall this command +// input: none +// output: TRUE or FALSE +/***********************************************************************/ +LOCAL BOOLEAN bSet_configuration(void) +{ +void vUsbClrEPx(void); + + //A_PRINTF("bSet_configuration...\n\r"); + + if (mLOW_BYTE(mDEV_REQ_VALUE()) == 0) + { + u8UsbConfigValue = 0; + //mUsbCfgClr(); + //ZM_DEVICE_ADDRESS_REG &= ~BIT7; + USB_BYTE_REG_WRITE(ZM_DEVICE_ADDRESS_OFFSET, (USB_BYTE_REG_READ(ZM_DEVICE_ADDRESS_OFFSET)&~BIT7)); + } + else + { + if (mUsbHighSpeedST()) // First judge HS or FS?? + { + if (mLOW_BYTE(mDEV_REQ_VALUE()) > HS_CONFIGURATION_NUMBER) + return FALSE; + + u8UsbConfigValue = mLOW_BYTE(mDEV_REQ_VALUE()); + vUsbFIFO_EPxCfg_HS(); + + // Set into 512 byte mode */ + //ZM_SOC_USB_MODE_CTRL_REG |= BIT2; + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT2)); + // mUsbSOFMaskHS(); + } + else + { + if (mLOW_BYTE(mDEV_REQ_VALUE()) > FS_CONFIGURATION_NUMBER) + return FALSE; + + u8UsbConfigValue = mLOW_BYTE(mDEV_REQ_VALUE()); + vUsbFIFO_EPxCfg_FS(); + + // Set into 64 byte mode */ + //M_SOC_USB_MODE_CTRL_REG &= ~BIT2; + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)&~BIT2)); + // mUsbSOFMaskFS(); + } + //mUsbCfgSet(); + //ZM_DEVICE_ADDRESS_REG |= BIT7; + USB_BYTE_REG_WRITE(ZM_DEVICE_ADDRESS_OFFSET, \ + (USB_BYTE_REG_READ(ZM_DEVICE_ADDRESS_OFFSET)|BIT7)); + + vUsbClrEPx(); + + mUsbGlobIntEnable(); + mUSB_REG_OUT_INT_ENABLE(); + + } + + eUsbCxFinishAction = ACT_DONE; + return TRUE; +} + + +/***********************************************************************/ +// bGet_interface() +// Description: +// Getting interface +// input: none +// output: TRUE or FALSE +/***********************************************************************/ +LOCAL BOOLEAN bGet_interface(void) +{ + +// A_PRINTF("bGet_interface...\n\r"); + if (mUsbCfgST() == 0) + return FALSE; + + // If there exists many interfaces, Interface0,1,2,...N, + // You must check & select the specific one + switch (u8UsbConfigValue) + { + #if (HS_CONFIGURATION_NUMBER >= 1) + // Configuration 1 + case 1: + if (mDEV_REQ_INDEX() > HS_C1_INTERFACE_NUMBER) + return FALSE; + break; + #endif + #if (HS_CONFIGURATION_NUMBER >= 2) + // Configuration 2 + case 2: + if (mDEV_REQ_INDEX2() > HS_C2_INTERFACE_NUMBER) + return FALSE; + break; + #endif + default: + return FALSE; + } + + //ZM_CBUS_FIFO_SIZE_REG = 0x1; + //ZM_EP0_DATA_REG = u8UsbInterfaceAlternateSetting; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, u8UsbInterfaceAlternateSetting); + + // Restore CBus FIFO size to word size + //ZM_CBUS_FIFO_SIZE_REG = 0xf; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f); + + u16TxRxCounter = 1; //sizeof(u8UsbInterfaceAlternateSetting); + eUsbCxFinishAction = ACT_DONE; + return TRUE; +} + +/***********************************************************************/ +// bSet_interface() +// Description: +// 1-1. If (the device stays in Configured state) +// &(command match the alternate setting) +// then change the interface +// 1-2. else stall it +// input: none +// output: TRUE or FALSE +/***********************************************************************/ +LOCAL BOOLEAN bSet_interface(void) +{ +void vUsbClrEPx(void); + + //A_PRINTF("bSet_interface...\n\r"); + + if (mUsbCfgST()) + { + + // If there exists many interfaces, Interface0,1,2,...N, + // You must check & select the specific one + switch (mDEV_REQ_INDEX()) + { + case 0: // Interface0 + + if (mLOW_BYTE(mDEV_REQ_VALUE()) == mLOW_BYTE(u8ConfigDescriptorEX[mTABLE_IDX(12)])) + { + u8UsbInterfaceValue = (uint8_t) mDEV_REQ_INDEX(); + u8UsbInterfaceAlternateSetting = mLOW_BYTE(mDEV_REQ_VALUE()); + if (mUsbHighSpeedST()) // First judge HS or FS?? + { + vUsbFIFO_EPxCfg_HS(); + + // Set into 512 byte mode */ + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT2)); + } + else + { + vUsbFIFO_EPxCfg_FS(); + + // Set into 64 byte mode */ + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)&~BIT2)); + } + vUsbClrEPx(); + eUsbCxFinishAction = ACT_DONE; + + mUsbGlobIntEnable(); + mUSB_REG_OUT_INT_ENABLE(); + return TRUE; + } + // case 1: // Interface1 + // case 2: // Interface2 + // default: + // break; + } + } + return FALSE; +} + +/***********************************************************************/ +// vUsbEP0TxData() +// Description: +// 1. Send data(max or short packet) to host. +// input: none +// output: none +/***********************************************************************/ +LOCAL void vUsbEP0TxData(void) +{ + uint8_t u8temp; + uint32_t idx=0; + + //wait a little to make sure ep0 fifo is empty before sending data out + while(1) + { + if(idx++>0xffff) { + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, USB_BYTE_REG_READ(ZM_CX_CONFIG_STATUS_OFFSET)|BIT3); + break; + } + + if(USB_BYTE_REG_READ(ZM_CX_CONFIG_STATUS_OFFSET)&BIT5) + { + break; + } + } + // to keep tracking the txrx fifo + // max 64 bytes for transmission one time, + if (u16TxRxCounter < EP0MAXPACKETSIZE) + u8temp = (uint8_t) u16TxRxCounter; + else + u8temp = EP0MAXPACKETSIZE; + + u16TxRxCounter -= (uint16_t) u8temp; + + { + register uint8_t u8count; + uint8_t remainder; + + for (u8count = 0; u8count < (u8temp/4); u8count ++) + { + uint32_t ep0_data; + uint16_t ep0_low; + uint16_t ep0_high; + + // pack data into word size + ep0_low = *pu8DescriptorEX++; + ep0_high = *pu8DescriptorEX++; + + // composed the data as a word + ep0_data = (ep0_high << 16) + ep0_low; + + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, ep0_data); + } + + remainder = u8temp % 4; + + // Check whether there are data needed to be filled into the FIFO + if (remainder == 3) + { + uint32_t ep0_data; + uint16_t ep0_low; + uint16_t ep0_high; + + // pack data into word size + ep0_low = *pu8DescriptorEX++; + ep0_high = *pu8DescriptorEX++; + + ep0_data = (ep0_high << 16) + ep0_low; + + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, ep0_data); + } + else if (remainder == 2) + { + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, *pu8DescriptorEX); + } + else if (remainder == 1) + { + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, *pu8DescriptorEX); + } + + // Restore CBus FIFO size to word size + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xf); + } + + // end of the data stage + if (u16TxRxCounter == 0) + { + eUsbCxCommand = CMD_VOID; + eUsbCxFinishAction = ACT_DONE; + } +} + +/***********************************************************************/ +// vUsbEP0RxData() +// Description: +// 1. Receive data(max or short packet) from host. +// input: none +// output: none +/***********************************************************************/ +LOCAL void vUsbEP0RxData(void) +{ + uint8_t u8temp; + + if (u16TxRxCounter < EP0MAXPACKETSIZE) + u8temp = (uint8_t) u16TxRxCounter; + else + u8temp = EP0MAXPACKETSIZE; + + u16TxRxCounter -= (uint16_t) u8temp; + + // Receive u8Temp bytes data + { + register uint8_t u8count; + uint8_t *p = (uint8_t *) pu8DescriptorEX; + + for (u8count = 0; u8count < ((u8temp+3) >> 2); u8count ++) + { + uint32_t ep0_data; + + ep0_data = USB_WORD_REG_READ(ZM_EP0_DATA_OFFSET); //read usb ep0 fifo data, + + { +// skip the writing to ram if not build for rom code +#if 0 //1 defined(_ROM_) + *p++ = mGetByte0(ep0_data); + *p++ = mGetByte1(ep0_data); + *p++ = mGetByte2(ep0_data); + *p++ = mGetByte3(ep0_data); +#endif + fwCheckSum = fwCheckSum ^ ep0_data; + } + } + + pu8DescriptorEX += (u8count << 1); + } + + // end of the data stage + if (u16TxRxCounter == 0) + { + eUsbCxCommand = CMD_VOID; + eUsbCxFinishAction = ACT_DONE; + } +} + + +/***********************************************************************/ +// vUsb_SetupDescriptor() +// Description: +// Setup the pointer to the descriptor in the SRAM and EEPROM +// +/***********************************************************************/ +LOCAL void vUsb_SetupDescriptor(void) +{ +// eeprom exist the usb configuration is only supportted in rom version +#if defined(_ROM_) + // + // check the offset of PID's value is correct or not, need to be defined!!, ryan + // + + if( *((uint32_t*)USB_DESC_IN_EEPROM_FLAG_ADDR) == USB_DESC_IN_EEP_PATTERN) + { + A_PRINTF("- custom usb config\n"); + + u8UsbDeviceDescriptor = (uint16_t *) USB_DEVICE_DESCRIPTOR_ADDR; + u8String00Descriptor = (uint16_t *) USB_STRING00_DESCRIPTOR_ADDR; + u8String10Descriptor = (uint16_t *) USB_STRING10_DESCRIPTOR_ADDR; + u8String20Descriptor = (uint16_t *) USB_STRING20_DESCRIPTOR_ADDR; + u8String30Descriptor = (uint16_t *) USB_STRING30_DESCRIPTOR_ADDR; + } + else +#endif + { + u8UsbDeviceDescriptor = (uint16_t *) &UsbDeviceDescriptor; + u8String00Descriptor = (uint16_t *) &String00Descriptor; + u8String10Descriptor = (uint16_t *) &String10Descriptor; + u8String20Descriptor = (uint16_t *) &String20Descriptor; + u8String30Descriptor = (uint16_t *) &String30Descriptor; + } + + /* Point Device Qualifierdescriptors and Other Speed Descriptor + * - Device Qualifierdescriptor is located in RAM segment, extern these + * symbol at the beginning of this file + */ +} + + +/***********************************************************************/ +// bStandardCommand() +// Description: +// 1. Process standard command. +// input: none +// output: TRUE or FALSE +/***********************************************************************/ +LOCAL BOOLEAN bStandardCommand(void) +{ + switch (mDEV_REQ_REQ()) // by Standard Request codes + { + case USB_GET_STATUS: + return (A_USB_GET_STATUS()); + + case USB_CLEAR_FEATURE: + return (A_USB_CLEAR_FEATURE()); + + case USB_SET_FEATURE: + return (A_USB_SET_FEATURE()); + + case USB_SET_ADDRESS: + return (A_USB_SET_ADDRESS()); + + case USB_GET_DESCRIPTOR: + return (A_USB_GET_DESCRIPTOR()); + +#if 0 + case USB_SET_DESCRIPTOR: +// if (!bUsbEP0HaltSt) + return (bSet_descriptor()); +#endif + + case USB_GET_CONFIGURATION: + return (A_USB_GET_CONFIG()); + + case USB_SET_CONFIGURATION: + //A_PRINTF(" \n--> SET_CONFIGURATION\r\n"); +// if (!bUsbEP0HaltSt) +// return (A_USB_SET_CONFIG()); + + { + A_USB_SET_CONFIG(); + +#if ENABLE_SWAP_DATA_MODE + // SWAP FUNCTION should be enabled while DMA engine is not working, + // the best place to enable it is before we trigger the DMA + MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1; + MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1; + + #if SYSTEM_MODULE_HP_EP5 + MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1; + #endif + + #if SYSTEM_MODULE_HP_EP6 + MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1; + #endif + +#endif //ENABLE_SWAP_DATA_MODE + + +#if !ENABLE_STREAM_MODE + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT3); + + /* + // ryan: + // 04/01: bit0 could disable lpdn dma, which is good at debugging while async_fifo have problem, + // we could disable this and check the fifo_rcv_size to see if we have correct at fifo or not + */ + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, ((USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT1))); // upstream DMA enable + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, ((USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT0))); // downstream DMA enable + + #if SYSTEM_MODULE_HP_EP5 + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, ((USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT8))); + #endif + + #if SYSTEM_MODULE_HP_EP6 + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, ((USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT9))); + #endif + +#else +/////////////ENABLE_STREAM_MODE///////////////// + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)&(~BIT1))); // disable upstream DMA mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)&(~BIT3))); // enable upstream stream mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|(BIT1))); // enable upstream DMA mode + + #if SYSTEM_MODULE_HP_EP1 + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)&(~BIT0))); // diable LP downstream DMA mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|(BIT6))); // enable LP downstream stream mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|(BIT0))); // enable LP downstream DMA mode + #endif + + #if SYSTEM_MODULE_HP_EP5 + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)&(~BIT8))); // disable HP downstream DMA mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|(BIT7))); // enable HP downstream stream mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT8)); // enable HP downstream DMA mode + #endif + + + #if SYSTEM_MODULE_HP_EP6 + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)&(~BIT9))); // disable MP downstream DMA mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT10)); // enable MP downstream stream mode + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|BIT9)); // enable MP downstream DMA mode + #endif + + USB_WORD_REG_WRITE(ZM_SOC_USB_MODE_CTRL_OFFSET, \ + (USB_WORD_REG_READ(ZM_SOC_USB_MODE_CTRL_OFFSET)|(BIT4))); // define the host dma buffer size - 4096(00) 8192 (01) 16384(10) 32768(11) bytes + + USB_WORD_REG_WRITE(ZM_SOC_USB_TIME_CTRL_OFFSET, USB_STREAM_MODE_TIMEOUT_CTRL); // set stream mode timeout critirea + + USB_WORD_REG_WRITE(ZM_SOC_USB_MAX_AGGREGATE_OFFSET, USB_STREAM_MODE_AGG_CNT); // set stream mode packet buffer critirea +#endif //!ENABLE_STREAM_MODE + + + +//extern void Magpie_init(void); +//Magpie_init(); + + return TRUE; + } + + case USB_GET_INTERFACE: +// A_PRINTF(" \n--> GET_INTERFACE\r\n"); +// if (!bUsbEP0HaltSt) + //return (bGet_interface()); + return (A_USB_GET_INTERFACE()); + + case USB_SET_INTERFACE: +// A_PRINTF(" \n--> SET_INTERFACE\r\n"); +// if (!bUsbEP0HaltSt) +// return (bSet_interface()); +// return (A_USB_SET_INTERFACE()); + A_USB_SET_INTERFACE(); + return TRUE; + } + return FALSE; +} + + +LOCAL void flash_read(uint16_t len, uint16_t ofset) +{ + uint16_t i=0; + + uint8_t buf[64]; + uint16_t end_addr = 0x0; + uint16_t start_addr = 0x0; + uint32_t ep0_data = 0x0; + +#if 0 + //sanity check, just in case + if(u16TxRxCounter < EP0MAXPACKETSIZE) + u8temp = (uint8_t) u16TxRxCounter; + else + + if( u16TxRxCounter > 64 ) + len = EP0MAXPACKETSIZE; + else + len = u16TxRxCounter + 4-(u16TxRxCounter%4); +#endif + + start_addr = ofset; + end_addr = start_addr + len; + + A_PRINTF("read flash from %x to %x\n", ofset, end_addr); + + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF); + + for (i = 0; start_addr < end_addr; i++, start_addr+=4) + { +// A_SFLASH_READ(1, ofset, 4, buf + i*4); +// *((volatile uint32_t *)(buf+i*4)) = *(uint32_t *)(0xf000000+start_addr); +// A_PRINTF(" %08x ", *(uint32_t *)(0xf000000+start_addr)); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, *(uint32_t *)(0xf000000+start_addr)); + } + +// A_PRINTF("\n\n\r"); + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, BIT0); + + + + +#if 0 + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF); + + for(i=0; i[cUSB_REQ_COMP]: 0x%08x\n\r", text_addr); +#if 0 + if (fwCheckSum != 0) + { + A_PRINTF("cksum=%x", fwCheckSum); + fwCheckSum = 0; + //Return fail + DEBUG_SYSTEM_STATE |= BIT27; + + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, 1); + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF); + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, BIT0); + } + else +#endif + { + /* Set EP0 Done */ + //ZM_CX_CONFIG_STATUS_REG = 0x01; + fwCheckSum = 0; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1); + USB_WORD_REG_WRITE(ZM_EP0_DATA_OFFSET, 0); + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF); + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, BIT0); + + A_PRINTF("VendorCmd: DownloadComplete!\n"); + + DEBUG_SYSTEM_STATE &= ~BIT27; + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x3f; + + // this value should be assign from host along with the DOWNLOAD_COMP in wValue + if( text_addr != 0 ) + funcPtr = (void *)(text_addr); + + download_enable = TRUE; + + // only jump to text address in ROM version + #if defined(_ROM_) + // funcPtr(); // jump to the firmware and never return + #endif + //app_start(); + } +// else +// A_PRINTF("Integrity is not fine!\n\r"); + + break; + } +} + + +/***********************************************************************/ +// vUsb_ep0setup() +// Description: +// 1. Read 8-byte setup packet. +// 2. Decode command as Standard, Class, Vendor or NOT support command +// input: none +// output: none +/***********************************************************************/ +extern uint16_t u8HSConfigDescriptor01[]; +extern uint16_t u8FSConfigDescriptor01[]; + +LOCAL void vUsb_ep0setup(void) +{ +register uint8_t ii; +volatile uint32_t ep0_data; +//BOOLEAN bStandardCommand(void); +//BOOLEAN bClassCommand(void); +//void VendorCommand(void); + + //zcPrint._printf("\t---> %s <---\n\r", __FUNCTION__); + if (UsbChirpFinish != TRUE) + { + UsbChirpFinish = TRUE; + + // Setup Descriptor pointer + //vUsb_SetupDescriptor(); + A_USB_SETUP_DESC(); + + u8OtherSpeedConfigDescriptorEX[0] = 0x0709; + + if (mUsbHighSpeedST()) // Judge HS or FS?? + { + u8ConfigDescriptorEX = u8HSConfigDescriptor01; + + // copy Device Qualifierdescriptors (from rom to sram) + for (ii = 1; ii < 4; ii++) + { + u8DeviceQualifierDescriptorEX[ii] = u8UsbDeviceDescriptor[ii]; + } + + // Number of Other-speed Configurations + // byte 9 Reserved for future use, must be zero + u8DeviceQualifierDescriptorEX[4] = (u8UsbDeviceDescriptor[8] >> 8) & 0x00ff; + + // copy Other Speed Descriptor + for (ii = 1; ii < (USB_TOTAL_DESC_LEN/2); ii++) + { + u8OtherSpeedConfigDescriptorEX[ii] = u8FSConfigDescriptor01[ii]; + } + +#if 0 + MaxPktSize = HS_C1_I0_A0_EP1_MAX_PACKET; + // Device stays in High Speed + u8DeviceDescriptorEX = u8HSDeviceDescriptor; + + // copy Device Qualifierdescriptors (from rom to sram) + for (ii = mTABLE_WID(2) ; ii < mTABLE_WID(8); ii ++) + u8DeviceQualifierDescriptorEX[ii] = u8FSDeviceDescriptor[ii]; + + // Number of Other-speed Configurations + // byte 9 Reserved for future use, must be zero + u8DeviceQualifierDescriptorEX[mTABLE_IDX(8)] + = mHIGH_BYTE(u8FSDeviceDescriptor[mTABLE_IDX(17)]); + u8ConfigDescriptorEX = u8HSConfigDescriptor01; + u8OtherSpeedConfigDescriptorEX = u8FSConfigDescriptor01; +#endif + } + else + { + u8ConfigDescriptorEX = u8FSConfigDescriptor01; + + // copy Device Qualifierdescriptors (from rom to sram) + for (ii = 1; ii < 4; ii++) + { + u8DeviceQualifierDescriptorEX[ii] = u8UsbDeviceDescriptor[ii]; + } + + // Number of Other-speed Configurations + // byte 9 Reserved for future use, must be zero + u8DeviceQualifierDescriptorEX[4] = (u8UsbDeviceDescriptor[8] >> 8) & 0x00ff; + + // copy Other Speed Descriptor + for (ii = 1; ii < (USB_TOTAL_DESC_LEN/2); ii++) + { + u8OtherSpeedConfigDescriptorEX[ii] = u8HSConfigDescriptor01[ii]; + } + +#if 0 + MaxPktSize = FS_C1_I0_A0_EP1_MAX_PACKET; + // Device stays in Full Speed + u8DeviceDescriptorEX = u8FSDeviceDescriptor; + + // copy Device Qualifierdescriptors (from rom to sram) + for (ii = mTABLE_WID(2) ; ii < mTABLE_WID(8); ii ++) + u8DeviceQualifierDescriptorEX[ii] = u8HSDeviceDescriptor[ii]; + + // Number of Other-speed Configurations + // byte 9 Reserved for future use, must be zero + u8DeviceQualifierDescriptorEX[mTABLE_IDX(8)] + = mHIGH_BYTE(u8HSDeviceDescriptor[mTABLE_IDX(17)]); + u8ConfigDescriptorEX = u8FSConfigDescriptor01; + u8OtherSpeedConfigDescriptorEX = u8HSConfigDescriptor01; +#endif + } + //Change bLength + u8DeviceQualifierDescriptorEX[0] = 0x060A; + } + + if( USB_BYTE_REG_READ(ZM_CX_CONFIG_STATUS_OFFSET) & BIT5) + { + int kkk=0; + kkk++; + } + //ep0_data = ZM_EP0_DATA_REG; + ep0_data = USB_WORD_REG_READ(ZM_EP0_DATA_OFFSET); + + ii = mGetByte0(ep0_data); + + ControlCmd.Direction = (uint8_t)(ii & 0x80);// xfer Direction(IN, OUT) + ControlCmd.Type = (uint8_t)(ii & 0x60); // type(Standard, Class, Vendor) + ControlCmd.Object = (uint8_t)(ii & 0x03); // Device, Interface, Endpoint + + ControlCmd.Request = mGetByte1(ep0_data); + ControlCmd.Value = mGetByte2(ep0_data) + (mGetByte3(ep0_data) << 8); + + //ep0_data = ZM_EP0_DATA_REG; + ep0_data = USB_WORD_REG_READ(ZM_EP0_DATA_OFFSET); + + ControlCmd.Index = mGetByte0(ep0_data) + (mGetByte1(ep0_data) << 8); + ControlCmd.Length = mGetByte2(ep0_data) + (mGetByte3(ep0_data) << 8); + +// Command Decode + if (mDEV_REQ_REQ_TYPE() == (cUSB_REQTYPE_STD << bmREQ_TYPE)) + { // standard command + //if (bStandardCommand() == FALSE) + if (A_USB_STANDARD_CMD() == FALSE) + { + eUsbCxFinishAction = ACT_STALL; + } + } + else if (mDEV_REQ_REQ_TYPE() == (cUSB_REQTYPE_VENDOR << bmREQ_TYPE)) + { // vendor command + //VendorCommand(); + A_USB_VENDOR_CMD(); + } + else + { + // Invalid(bad) command, Return EP0_STALL flag + A_PRINTF("request not support.. stall", __FUNCTION__); + eUsbCxFinishAction = ACT_STALL; + } + + //zcPrint._printf("\t<--- %s --->\n\r", __FUNCTION__); +} + + +/*! - init FUSB phy + * + */ +LOCAL void cFUSB200Init(void) +{ + /* Clear USB reset interrupt */ + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&0xfd)); + + // Disable all fifo interrupt + /* Clear all USB OUT FIFO */ + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_1_OFFSET, 0xff); + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_2_OFFSET, 0xff); + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_3_OFFSET, 0xff); + + /* Clear all USB IN FIFO */ + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_5_OFFSET, 0xff); + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_6_OFFSET, 0xff); + + // Soft Reset + //ZM_MAIN_CTRL_REG = 0x10; + //ZM_MAIN_CTRL_REG &= ~0x10; + + // Soft Reset + USB_BYTE_REG_WRITE(ZM_MAIN_CTRL_OFFSET, 0x10); + USB_BYTE_REG_WRITE(ZM_MAIN_CTRL_OFFSET, 0x0); + + // Clear all fifo + USB_BYTE_REG_WRITE(ZM_TEST_OFFSET, BIT0); // will be cleared after one cycle. + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_0_OFFSET, 0); //BIT6); // Mask out INT status + + // reset the specific mode + USB_BYTE_REG_WRITE(ZM_VDR_SPECIFIC_MODE_OFFSET, 0x0); + + // reset the zero-length fifo indication ? workaround... + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_OFFSET, 0x0); + + // Enable Chip + USB_BYTE_REG_WRITE(ZM_MAIN_CTRL_OFFSET, (BIT5|BIT2)); + + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_1_OFFSET, 0x0); + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_2_OFFSET, 0x0); + USB_BYTE_REG_WRITE(ZM_INTR_MASK_BYTE_3_OFFSET, 0x0); + +// USB_WORD_REG_WRITE(0x104, 0x000000C0); + +} + + +LOCAL void _usbfifo_enable_event_isr(void) +{ + mUSB_STATUS_IN_INT_ENABLE(); +} + +LOCAL void _usbfifo_init(USB_FIFO_CONFIG *pConfig) +{ + usbFifoConf.get_command_buf = pConfig->get_command_buf; + usbFifoConf.recv_command = pConfig->recv_command; + usbFifoConf.get_event_buf = pConfig->get_event_buf; + usbFifoConf.send_event_done = pConfig->send_event_done; +} + +LOCAL void vUsb_Reg_Out(void) +{ + uint16_t usbfifolen; + uint16_t ii; + volatile uint32_t *regaddr; // = (volatile uint32_t *) ZM_CMD_BUFFER; + uint16_t cmdLen; + uint32_t ep4_data; + VBUF *buf; + + //mUSB_REG_OUT_INT_DISABLE(); + + buf = usbFifoConf.get_command_buf(); + + if ( buf != NULL ) // copy free + regaddr = (uint32_t *)buf->desc_list->buf_addr; + else + goto ERR; + + // read fifo size of the current packet. + usbfifolen = USB_BYTE_REG_READ(ZM_EP4_BYTE_COUNT_LOW_OFFSET); + + cmdLen = usbfifolen; + + if(usbfifolen % 4) + usbfifolen = (usbfifolen >> 2) + 1; + else + usbfifolen = usbfifolen >> 2; + + for(ii = 0; ii < usbfifolen; ii++) + { + ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET); // read fifo data out + *regaddr = ep4_data; + regaddr++; + } + + if ( buf != NULL ) + { +// zfUartSendStrAndHex((u8_t *) "cmdLen=", cmdLen); +// zfMemoryCopyInWord(buf->desc_list->buf_addr, ZM_CMD_BUFFER, usbfifolen*4); + buf->desc_list->next_desc = NULL; + buf->desc_list->data_offset = 0; + buf->desc_list->data_size = cmdLen; + buf->desc_list->control = 0; + buf->next_buf = NULL; + buf->buf_length = cmdLen; + + usbFifoConf.recv_command(buf); + } + goto DONE; +ERR: +// we might get no command buffer here? +// but if we return here, the ep4 fifo will be lock out, +// so that we still read them out but just drop it ? + for(ii = 0; ii < usbfifolen; ii++) + { + ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET); // read fifo data out + } + +DONE: + //mUSB_STATUS_IN_INT_ENABLE(); + +} + +LOCAL void vUsb_Status_In(void) +{ + uint16_t count; + uint16_t remainder; + volatile u32_t *regaddr; + u16_t RegBufLen; + VBUF *evntbuf = NULL; + + //regaddr = (volatile uint32_t *) ZM_CMD_BUFFER; + + //mUSB_STATUS_IN_INT_DISABLE(); + + evntbuf = usbFifoConf.get_event_buf(); + if ( evntbuf != NULL ) + { +//zfUartSendStr((u8_t *) "#G1\r\n"); +// A_PRINTF("#G1\n\r"); + regaddr = VBUF_GET_DATA_ADDR(evntbuf); + RegBufLen = evntbuf->buf_length; +// A_PRINTF("RegBufLen=%d\n\r", RegBufLen); +//zfUartSendStrAndHex((u8_t *) "RegBufLen=", RegBufLen); + } + else + { + mUSB_STATUS_IN_INT_DISABLE(); +// A_PRINTF("#G2\n\r"); + goto ERR_DONE; + } + + /* INT use EP3 */ + for(count = 0; count < (RegBufLen / 4); count++) + { +//zfUartSendStrAndHex((u8_t *) "data=", *regaddr); + USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr); + regaddr++; + } + + remainder = RegBufLen % 4; + + if (remainder) + { + switch(remainder) + { + case 3: + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7); + break; + case 2: + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3); + break; + case 1: + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1); + break; + } + + USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr); + } + + // Restore CBus FIFO size to word size + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF); + + mUSB_EP3_XFER_DONE(); + + if ( evntbuf != NULL ) + { + usbFifoConf.send_event_done(evntbuf); + } + +ERR_DONE: + //mUSB_REG_OUT_INT_ENABLE(); +} + +///////////////////////////////////////////////////////// +/***********************************************************************/ +// zfResetUSBFIFO() +// Description: +// 1. Reset all the USB FIFO used for WLAN +// input: none +// output: none +/***********************************************************************/ +LOCAL void zfResetUSBFIFO(void) +{ + A_PUTS("zfResetUSBFIFO\n\r"); + +} + +/***********************************************************************/ +// zfTurnOffPower() +// Description: +// 1. Function to turn off ADDA/RF power, PLL +// input: none +// output: none +/***********************************************************************/ +LOCAL void zfTurnOffPower(void) +{ + A_PUTS("zfTurnOffPower\n\r"); +#if defined(MAGPIE_ASIC) +/* + * 1. set CPU bypass + * 2. turn off CPU PLL + * 3. turn off ETH PLL + * 4. disable ETH PLL bypass and update + * 5. set SUSPEND_ENABLE + */ + + /*HAL_WORD_REG_WRITE(MAGPIE_REG_USB_DIVIDE_ADDR,((0x8<<8)|0x8)); */ + /* 1. */ HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, + (HAL_WORD_REG_READ(MAGPIE_REG_CPU_PLL_BYPASS_ADDR)|(BIT0|BIT4))); + A_DELAY_USECS(100); // wait for stable + + /* 2. */ HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, + (HAL_WORD_REG_READ(MAGPIE_REG_CPU_PLL_ADDR)|(BIT16))); + + /* 3. */ HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR, + (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)|(BIT16))); + + /* 4. */ HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, + (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)|(BIT16|BIT0))); + + /* 5. */ HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR, + (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(BIT0))); +#endif + +} + + +LOCAL void zfGenWatchDogEvent(void) +{ + uint32_t event= 0x0000C600; + + mUSB_STATUS_IN_INT_DISABLE(); + + //ZM_CBUS_FIFO_SIZE_REG = 0xf; + USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x0f); + + //ZM_EP3_DATA_REG = event; + USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, event); + + mUSB_EP3_XFER_DONE(); +} + +LOCAL void zfJumpToBootCode(void) +{ + extern int _start(void); + + /* Jump to the boot code */ + _start(); +} + +LOCAL void _usb_rom_task(void) +{ + register uint8_t usb_interrupt_level1; + register uint8_t usb_interrupt_level2; + register uint8_t usb_ctrl_err_indication; + + usb_interrupt_level1 = USB_BYTE_REG_READ(ZM_INTR_GROUP_OFFSET); + + if (usb_interrupt_level1 & BIT6) + { + A_USB_GEN_WDT(); + A_PRINTF("Generate Event\n"); + } + + if (usb_interrupt_level1 & BIT0) //Group Byte 0 + { + usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET); + + // refer to FUSB200, p 48, offset:21H, bit7 description, should clear the command abort interrupt first!? + if (usb_interrupt_level2 & BIT7) + { + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_0_OFFSET, (USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET)& ~BIT7)); + } + + if (usb_interrupt_level2 & BIT1) + { + A_PRINTF("![USB] ep0 IN in \n\r"); + A_USB_EP0_TX(); // USB EP0 tx interrupt + } + if (usb_interrupt_level2 & BIT2) + { + //A_PRINTF("![USB] ep0 OUT in\n\r"); + A_USB_EP0_RX(); // USB EP0 rx interrupt + } + if (usb_interrupt_level2 & BIT0) + { + //A_PRINTF("![USB] ep0 SETUP in\n\r"); + A_USB_EP0_SETUP(); + } + + if (eUsbCxFinishAction == ACT_STALL) + { + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x04); +// A_PRINTF("![USB] ZM_CX_CONFIG_STATUS_REG = 0x04\n\r"); + } + else if (eUsbCxFinishAction == ACT_DONE) + { + // set CX_DONE to indicate the transmistion of control frame + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x01); + } + eUsbCxFinishAction = ACT_IDLE; + } + + if (usb_interrupt_level1 & BIT7) //Group Byte 7 + { + //usb_interrupt_level2 = ZM_INTR_SOURCE_7_REG; + usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET); + + if (usb_interrupt_level2 & BIT1) + { + vUsb_rst(); + } + if (usb_interrupt_level2 & BIT2) + { + vUsb_suspend(); + } + if (usb_interrupt_level2 & BIT3) + { + vUsb_resm(); + } + } + +} + + +LOCAL void _usb_fw_task(void) +{ + register uint8_t usb_interrupt_level1; + register uint8_t usb_interrupt_level2; + register uint8_t usb_ctrl_err_indication; + + usb_interrupt_level1 = USB_BYTE_REG_READ(ZM_INTR_GROUP_OFFSET); + +#if 0 // these endpoints are handled by DMA + if (usb_interrupt_level1 & BIT5) //Group Byte 5 + { + vUsb_Data_In(); + } +#endif + if (usb_interrupt_level1 & BIT4) + { + usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_4_OFFSET); + if( usb_interrupt_level2 & BIT6) + A_USB_REG_OUT();//vUsb_Reg_Out(); + } + + if (usb_interrupt_level1 & BIT6) + { + //zfGenWatchDogEvent(); + usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_6_OFFSET); + if( usb_interrupt_level2 & BIT6) + A_USB_STATUS_IN();//vUsb_Status_In(); + } + + if (usb_interrupt_level1 & BIT0) //Group Byte 0 + { + //usb_interrupt_level2 = ZM_INTR_SOURCE_0_REG; + usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET); + + // refer to FUSB200, p 48, offset:21H, bit7 description, should clear the command abort interrupt first!? + if (usb_interrupt_level2 & BIT7) + { + //ZM_INTR_SOURCE_0_REG &= 0x7f; // Handle command abort + USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_0_OFFSET, (USB_BYTE_REG_READ(ZM_INTR_SOURCE_0_OFFSET)& ~BIT7)); + A_PRINTF("![SOURCE_0] bit7 on\n\r"); + } + + if (usb_interrupt_level2 & BIT1) + { + //A_PRINTF("![USB] ep0 IN in \n\r"); + A_USB_EP0_TX(); // USB EP0 tx interrupt + } + if (usb_interrupt_level2 & BIT2) + { + //A_PRINTF("![USB] ep0 OUT in\n\r"); + A_USB_EP0_RX(); // USB EP0 rx interrupt + } + if (usb_interrupt_level2 & BIT0) + { + //A_PRINTF("![USB] ep0 SETUP in\n\r"); + A_USB_EP0_SETUP(); + //vWriteUSBFakeData(); + } +// else if (usb_interrupt_level2 & BIT3) + if (usb_interrupt_level2 & BIT3) + { + vUsb_ep0end(); +// A_PRINTF("![SOURCE_0] ep0 CMD_END\n\r"); + } + if (usb_interrupt_level2 & BIT4) + { + vUsb_ep0fail(); +// A_PRINTF("![SOURCE_0] ep0 CMD_FAIL\n\r"); + } + if (eUsbCxFinishAction == ACT_STALL) + { + // set CX_STL to stall Endpoint0 & will also clear FIFO0 + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x04); +// A_PRINTF("![USB] ZM_CX_CONFIG_STATUS_REG = 0x04\n\r"); + } + else if (eUsbCxFinishAction == ACT_DONE) + { + // set CX_DONE to indicate the transmistion of control frame + USB_BYTE_REG_WRITE(ZM_CX_CONFIG_STATUS_OFFSET, 0x01); + } + eUsbCxFinishAction = ACT_IDLE; + } + + if (usb_interrupt_level1 & BIT7) //Group Byte 7 + { + //usb_interrupt_level2 = ZM_INTR_SOURCE_7_REG; + usb_interrupt_level2 = USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET); + +#if 0 + if (usb_interrupt_level2 & BIT7) + { + vUsb_Data_Out0Byte(); +// A_PRINTF("![SOURCE_7] bit7 on, clear it\n\r"); + } + if (usb_interrupt_level2 & BIT6) + { + vUsb_Data_In0Byte(); +// A_PRINTF("![SOURCE_7] bit6 on, clear it\n\r"); + } +#endif + + if (usb_interrupt_level2 & BIT1) + { + vUsb_rst(); + //USB_BYTE_REG_WRITE(ZM_INTR_SOURCE_7_REG, (USB_BYTE_REG_READ(ZM_INTR_SOURCE_7_OFFSET)&~0x2)); + A_PRINTF("!USB reset\n\r"); +// A_PRINTF("![0x1012c]: %\n\r", USB_WORD_REG_READ(0x12c)); + } + if (usb_interrupt_level2 & BIT2) + { + // TBD: the suspend resume code should put here, Ryan, 07/18 + // + // issue, jump back to rom code and what peripherals should we reset here? + // + + /* Set GO_TO_SUSPEND bit to USB main control register */ + vUsb_suspend(); + A_PRINTF("!USB suspend\n\r"); + + // keep the record of suspend +#if defined(PROJECT_MAGPIE) + *((volatile uint32_t*)WATCH_DOG_MAGIC_PATTERN_ADDR) = SUS_MAGIC_PATTERN; +#elif defined(PROJECT_K2) + HAL_WORD_REG_WRITE(MAGPIE_REG_RST_STATUS_ADDR, SUS_MAGIC_PATTERN); +#endif /* #if defined(PROJECT_MAGPIE) */ + + /* Reset USB FIFO */ + A_USB_RESET_FIFO(); + + /* Turn off power */ + A_USB_POWER_OFF(); + +// DON'T restart when not in ASIC +#if defined(MAGPIE_ASIC) + /* Jump to boot code */ + A_USB_JUMP_BOOT(); +#endif + + } + if (usb_interrupt_level2 & BIT3) + { + vUsb_resm(); + A_PRINTF("!USB resume\n\r"); + } + } + +} + +#if 0 // old + +void _usb_init(void) +{ + +// init variables +// u16TxRxCounter = 0; +// eUsbCxCommand = CMD_VOID; +// u8UsbConfigValue = 0; + u8UsbInterfaceValue = 0; + u8UsbInterfaceAlternateSetting = 0; +// bUsbEP0HaltSt = FALSE; +// u16FirmwareComplete = 0; +// eUsbCxFinishAction = ACT_IDLE; + UsbStatus[0] = !fBUS_POWER; + +// init hardware + +// cFUSB200Init(); + A_USB_INIT_PHY(); + + //ZM_PHY_TEST_SELECT_REG = 0; // Plug In + USB_BYTE_REG_WRITE(ZM_PHY_TEST_SELECT_OFFSET, 0x0); + + // reset the address, just in case... + //USB_BYTE_REG_WRITE(ZM_DEVICE_ADDRESS_OFFSET, 0x0); + +} + +#else // new + +#if defined(PROJECT_MAGPIE) + +/* - spec, ch11, reset + * + * 1. turn on ETH PLL and set ETH PLL to 384Mhz + * 2. set "USB_DMA, USB_CORE, ETH_PLL, CPU_PLL, USB_POR reset" bit + * 3. clear "ETH_PLL, CPU_PLL" reset bit + * 4. set USB divider to 48, 192/16=12 + * 5. disable ETH PLL bypass + * 6. clear USB_POR + * 7. clear USB_DMA, USB_CORE + * 8. enable USB_AHB_ARB + * + * note: don't know why bit3, bit4 should deassert? here especially bit4? + * since if we don't deassert this, clk won't come up + * + */ +#if defined(MAGPIE_ASIC) +#define RST_USB_COLD_INIT() \ +{ \ + /********* number of PLLDIV_LOW and PLLDIV_HIGH ***********/ \ + /*HAL_WORD_REG_WRITE(MAGPIE_REG_USB_DIVIDE_ADDR,((0x8<<8)|0x8)); */ \ + /* 1. */ HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR, 0x305); \ + /* 2. */ HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)|(BIT0|BIT1|BIT2|BIT3|BIT4))); \ + /* 3. */ HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)&(~(BIT1|BIT2)))); \ + /* 4. */ HAL_WORD_REG_WRITE(MAGPIE_REG_USB_DIVIDE_ADDR, 0x1010); \ + /* 5. */ HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, 0x0); \ + A_DELAY_USECS(100); /* wait for clock source stable */ \ + /* 6. */ HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)&(~(BIT0)))); \ + /* 7. */ HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)&(~(BIT3|BIT4)))); \ + /* 8. */ HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)|BIT2)); \ + /* HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, ); */ \ + /* HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)|((BIT0|BIT3|BIT4)))); */ \ + /* HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)&(~(BIT0|BIT3|BIT4)))); */ \ +} + +/* - back from suspend + * + * 1. turn on ETH PLL , 0x5600c, ~bit0 + * 2. clear USB SUSPEND_ENABLE, 0x56030, ~bit0 + * + */ +#define RST_USB_SUSP_INIT() \ +{ \ + /* 1. */ HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)&(~BIT0))); \ + /* 2. */ HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)&(~BIT0))); \ +} + +/* - back from watchdog + * + */ +#define RST_USB_WDT_INIT() + + +#elif defined(MAGPIE_FPGA) +// fpag don't have PLL, skip 1~5 +#define RST_USB_COLD_INIT() \ +{ \ + /* 6. */ HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)&(~(BIT0)))); \ + /* 7. */ HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)&(~(BIT3|BIT4)))); \ + /* 8. */ HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)|BIT2)); \ + A_DELAY_USECS(100); /* wait for clock source stable */ \ +} + +/* - back from suspend + * + */ +#define RST_USB_SUSP_INIT() + +/* - back from watchdog + * + */ +#define RST_USB_WDT_INIT() + + +#endif + + +#elif defined(PROJECT_K2) +#define RST_USB_INIT() \ +{ \ + HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR, HAL_WORD_REG_READ(MAGPIE_REG_RST_PWDN_CTRL_ADDR)|BIT12); \ + A_DELAY_USECS(10); \ + HAL_WORD_REG_WRITE(MAGPIE_REG_RST_PWDN_CTRL_ADDR, HAL_WORD_REG_READ(MAGPIE_REG_RST_PWDN_CTRL_ADDR)&(~BIT12)); \ +} +#endif +/* + @ToDo: this is used to enable usb access internal memory, dma need this + HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)&(~(BIT2)))); \ + A_DELAY_USECS(20); \ + HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)|(BIT2))); \ + A_DELAY_USECS(20); \ +*/ + + +LOCAL void _usb_clk_init(void) +{ + T_BOOT_TYPE mBootMode; + + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x31; + + mBootMode = A_WDT_LASTBOOT(); + +#if defined(PROJECT_MAGPIE) + + if( mBootMode == ENUM_WDT_BOOT ) + { + RST_USB_WDT_INIT(); + } + else if ( mBootMode == ENUM_SUSP_BOOT ) + { + RST_USB_SUSP_INIT(); + } + else + { + RST_USB_COLD_INIT(); + } + +#elif defined(PROJECT_K2) + if( mBootMode == ENUM_COLD_BOOT ) + { + RST_USB_INIT(); + } +#endif + + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x32; + + //A_DELAY_USECS(300); // delay 300 micro seconds, wait for clock stable! +} + + +void _usb_init(void) +{ + u32_t cold_start; + +// A_PUTS("\n - _usb_init - \n\r"); + +#if defined(PROJECT_MAGPIE) + //if ( *((volatile uint32_t*)WATCH_DOG_MAGIC_PATTERN_ADDR) == WDT_MAGIC_PATTERN || *((volatile uint32_t*)WATCH_DOG_MAGIC_PATTERN_ADDR) == SUS_MAGIC_PATTERN ) + if( A_WDT_LASTBOOT()!= ENUM_COLD_BOOT) +#elif defined(PROJECT_K2) + if (HAL_WORD_REG_READ(MAGPIE_REG_RST_STATUS_ADDR) == WDT_MAGIC_PATTERN || HAL_WORD_REG_READ(MAGPIE_REG_RST_STATUS_ADDR) == SUS_MAGIC_PATTERN) +#endif /* #if defined(PROJECT_MAGPIE) */ + cold_start = 0; + else + cold_start = 1; + + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x30; +// init variables +// u16TxRxCounter = 0; +// eUsbCxCommand = CMD_VOID; +// u8UsbConfigValue = 0; + u8UsbInterfaceValue = 0; + u8UsbInterfaceAlternateSetting = 0; +// bUsbEP0HaltSt = FALSE; +// u16FirmwareComplete = 0; +// eUsbCxFinishAction = ACT_IDLE; + UsbStatus[0] = !fBUS_POWER; + + +/*! + * move the setting to A_USB_CLK_INIT(), so that we could patch these things + */ +#if 1 + A_USB_CLK_INIT(); + +#else + +#if defined(PROJECT_MAGPIE) + +//#if defined(MAGPIE_ASIC) + // + // @Bug 36267 - wdt reset or other reset will reset usb phy, we need to init again here + // - this won't work at FPGA, skip this checking if build for FPGA + // + // @Bug 36947 - L3 fpga's reset behavior of usb is not as what I expect!, need to confirm + // + // ToBeNote: if (Bug36947), skip the checking and reset usb anyway, but will see the connection broken +// if (cold_start) +//#endif + A_USB_CLK_INIT(); +#elif defined(PROJECT_K2) + if (cold_start) + { + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x31; + RST_USB_INIT(); + } +#endif /* #if defined(PROJECT_MAGPIE) */ + +#endif + + A_DELAY_USECS(300); // delay 300 usecs, wait for clock stable! + + while( 1 ) + { + /* + * wait for USBSOC_HCLK_RDY tight high, indicate the 30Mhz is ready for use + */ + if(HAL_WORD_REG_READ(0x10128)& BIT8) + break; + + //A_DELAY_USECS(200); // delay 200 micro seconds, wait for clock stable! + } + + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x33; + A_PUTS("6. usb_hclk rdy\n\r"); + + // + // @Bug 36267 - wdt reset or other reset will reset usb phy, we need to init again here + // + // @Bug 36947 - L3 fpga's reset behavior of usb is not as what I expect!, need to confirm +#if defined(PROJECT_MAGPIE) + + // in cold or suspend boot, we do reinit the USB_PHY, skip only when watchdog start + // + // +#if defined(MAGPIE_ASIC) + if (cold_start) +#endif +#elif defined(PROJECT_K2) + if (cold_start) +#endif /* #if defined(PROJECT_MAGPIE) */ + { + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x34; + A_USB_INIT_PHY(); + + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x35; + //ZM_PHY_TEST_SELECT_REG = 0; // Plug In + USB_BYTE_REG_WRITE(ZM_PHY_TEST_SELECT_OFFSET, 0x0); + + // reset the address, just in case... + //USB_BYTE_REG_WRITE(ZM_DEVICE_ADDRESS_OFFSET, 0x0); + } + + /* If watchdog reset happens, target needs to send a message to host through EP3 */ + if ( A_WDT_LASTBOOT() == ENUM_WDT_BOOT ) + mUSB_STATUS_IN_INT_ENABLE(); + else + mUSB_STATUS_IN_INT_DISABLE(); + +} + +#endif + +//////////////////////////////////////////////////////// +void usbfifo_module_install(struct usbfifo_api *apis) +{ + /* hook in APIs */ + apis->_init = _usbfifo_init; + apis->_enable_event_isr = _usbfifo_enable_event_isr; +} + + +void cmnos_usb_module_install(struct usb_api *apis) +{ + apis->_usb_init = _usb_init; + apis->_usb_rom_task = _usb_rom_task; + apis->_usb_fw_task = _usb_fw_task; + apis->_usb_init_phy = cFUSB200Init; + + apis->_usb_ep0_setup = vUsb_ep0setup; + apis->_usb_ep0_tx_data = vUsbEP0TxData; + apis->_usb_ep0_rx_data = vUsbEP0RxData; + + apis->_usb_get_configuration = bGet_configuration; + apis->_usb_set_configuration = bSet_configuration; + + apis->_usb_get_interface = bGet_interface; + apis->_usb_set_interface = bSet_interface; + + apis->_usb_standard_cmd = bStandardCommand; + apis->_usb_vendor_cmd = VendorCommand; + + apis->_usb_reset_fifo= zfResetUSBFIFO; + apis->_usb_power_off = zfTurnOffPower; + apis->_usb_gen_wdt = zfGenWatchDogEvent; + apis->_usb_jump_boot = zfJumpToBootCode; + + apis->_usb_get_descriptor = bGet_descriptor; + apis->_usb_set_address = bSet_address; + apis->_usb_set_feature = bSet_feature; + apis->_usb_clr_feature = bClear_feature; + + apis->_usb_get_status = bGet_status; + apis->_usb_setup_desc = vUsb_SetupDescriptor; + + apis->_usb_reg_out = vUsb_Reg_Out; + apis->_usb_status_in = vUsb_Status_In; + + apis->_usb_ep0_tx = vUsb_ep0tx; + apis->_usb_ep0_rx = vUsb_ep0rx; + + apis->_usb_clk_init = _usb_clk_init; +} + +#endif