Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBDevice by
targets/TARGET_RENESAS/USBHAL_RZ_A1H.cpp
- Committer:
- Patrickhalahan
- Date:
- 2018-05-11
- Revision:
- 72:e5c300b1df2f
- Parent:
- 71:53949e6131f6
File content as of revision 72:e5c300b1df2f:
/* Copyright (c) 2010-2011 mbed.org, MIT License * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if defined(TARGET_RZ_A1H) || defined(TARGET_VK_RZ_A1H) /* This class can use the pipe1, pipe3 and pipe6 only. You should re-program this class if you wanted to use other pipe. */ /*************************************************************************/ extern "C" { #include "r_typedefs.h" #include "iodefine.h" } #include "USBHAL.h" #include "devdrv_usb_function_api.h" #include "usb_iobitmask.h" #include "rza_io_regrw.h" #include "USBDevice_Types.h" #include "usb_function_setting.h" /*************************************************************************/ /* constants */ const struct PIPECFGREC { uint16_t endpoint; uint16_t pipesel; uint16_t pipecfg; uint16_t pipebuf; uint16_t pipemaxp; uint16_t pipeperi; } def_pipecfg[] = { /*EP0OUT and EP0IN are configured by USB IP*/ { EP1OUT, /*EP1: Host -> Func, INT*/ 6 | USB_FUNCTION_D0FIFO_USE, USB_FUNCTION_INTERRUPT | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBOFF | USB_FUNCTION_CNTMDON | USB_FUNCTION_SHTNAKOFF | USB_FUNCTION_DIR_P_OUT | USB_FUNCTION_EP1, ( ( ( 64) / 64 - 1 ) << 10 ) | 0x04u, MAX_PACKET_SIZE_EP1, DEVDRV_USBF_OFF | ( 3 << USB_PIPEPERI_IITV_SHIFT ), }, { EP1IN, /*EP1: Host <- Func, INT*/ 7 | USB_FUNCTION_D1FIFO_USE, USB_FUNCTION_INTERRUPT | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBOFF | USB_FUNCTION_CNTMDOFF | USB_FUNCTION_SHTNAKOFF | USB_FUNCTION_DIR_P_IN | USB_FUNCTION_EP1, ( ( ( 64) / 64 - 1 ) << 10 ) | 0x05u, MAX_PACKET_SIZE_EP1, DEVDRV_USBF_OFF | ( 3 << USB_PIPEPERI_IITV_SHIFT ), }, { EP2OUT, /*EP2: Host -> Func, BULK*/ 3 | USB_FUNCTION_D0FIFO_USE, USB_FUNCTION_BULK | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBON | USB_FUNCTION_CNTMDON | USB_FUNCTION_SHTNAKON | USB_FUNCTION_DIR_P_OUT | USB_FUNCTION_EP2, ( ( (2048) / 64 - 1 ) << 10 ) | 0x30u, MAX_PACKET_SIZE_EP2, DEVDRV_USBF_OFF | ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { EP2IN, /*EP2: Host <- Func, BULK*/ 4 | USB_FUNCTION_D1FIFO_USE, USB_FUNCTION_BULK | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBOFF | USB_FUNCTION_CNTMDON | USB_FUNCTION_SHTNAKOFF | USB_FUNCTION_DIR_P_IN | USB_FUNCTION_EP2, ( ( (2048) / 64 - 1 ) << 10 ) | 0x50u, MAX_PACKET_SIZE_EP2, DEVDRV_USBF_OFF | ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { EP3OUT, /*EP3: Host -> Func, ISO*/ 1 | USB_FUNCTION_D0FIFO_USE, USB_FUNCTION_ISO | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBON | USB_FUNCTION_CNTMDOFF | USB_FUNCTION_SHTNAKON | USB_FUNCTION_DIR_P_OUT | USB_FUNCTION_EP3, ( ( ( 512) / 64 - 1 ) << 10 ) | 0x10u, MAX_PACKET_SIZE_EP3, DEVDRV_USBF_OFF | ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { EP3IN, /*EP3: Host <- Func, ISO*/ 2 | USB_FUNCTION_D1FIFO_USE, USB_FUNCTION_ISO | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBON | USB_FUNCTION_CNTMDOFF | USB_FUNCTION_SHTNAKOFF | USB_FUNCTION_DIR_P_IN | USB_FUNCTION_EP3, ( ( ( 512) / 64 - 1 ) << 10 ) | 0x20u, MAX_PACKET_SIZE_EP3, DEVDRV_USBF_OFF | ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { /*terminator*/ 0, 0, 0, 0, 0, }, }; /*************************************************************************/ /* workareas */ USBHAL * USBHAL::instance; static IRQn_Type int_id; /* interrupt ID */ static uint16_t int_level; /* initerrupt level */ static uint16_t clock_mode; /* input clock selector */ static uint16_t mode; /* USB speed (HIGH/FULL) */ //static DigitalOut *usbx_en; static uint16_t EP0_read_status; static uint16_t EPx_read_status; static uint16_t setup_buffer[MAX_PACKET_SIZE_EP0 / 2]; /* 0: not used / other: a pipe number to use recv_buffer*/ static uint8_t recv_buffer[MAX_PACKET_SIZE_EPBULK]; volatile static uint16_t recv_error; /*************************************************************************/ /* prototypes for C */ extern "C" { void usbx_function_BRDYInterruptPIPE0 (uint16_t status, uint16_t intenb, USBHAL *object, void (USBHAL::*EP0func)(void)); void usbx_function_BRDYInterrupt (uint16_t status, uint16_t intenb, USBHAL *object, bool (USBHAL::*epCallback[])(void)); void usbx_function_NRDYInterruptPIPE0(uint16_t status, uint16_t intenb, USBHAL *object, void (USBHAL::*EP0func)(void)); void usbx_function_NRDYInterrupt (uint16_t status, uint16_t intenb, USBHAL *object, bool (USBHAL::*epCallback[])(void)); void usbx_function_BEMPInterruptPIPE0(uint16_t status, uint16_t intenb, USBHAL *object, void (USBHAL::*EP0func)(void)); void usbx_function_BEMPInterrupt (uint16_t status, uint16_t intenb, USBHAL *object, bool (USBHAL::*epCallback[])(void)); } /*************************************************************************/ /* macros */ /****************************************************************************** * Function Name: usbx_function_BRDYInterruptPIPE0 * Description : Executes BRDY interrupt for pipe0. * Arguments : uint16_t status ; BRDYSTS Register Value * : uint16_t intenb ; BRDYENB Register Value * Return Value : none *****************************************************************************/ extern "C" { void usbx_function_BRDYInterruptPIPE0 ( uint16_t status, uint16_t intenb, USBHAL *object, void (USBHAL::*EP0func)(void) ) { volatile uint16_t dumy_sts; uint16_t read_status; USB20X.BRDYSTS = (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0]; RZA_IO_RegWrite_16( &USB20X.CFIFOSEL, USB_FUNCTION_PIPE0, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE); g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0] = g_usbx_function_data_count[USB_FUNCTION_PIPE0]; read_status = usbx_function_read_buffer_c(USB_FUNCTION_PIPE0); g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0] -= g_usbx_function_data_count[USB_FUNCTION_PIPE0]; switch (read_status) { case USB_FUNCTION_READING: /* Continue of data read */ case USB_FUNCTION_READEND: /* End of data read */ /* PID = BUF */ usbx_function_set_pid_buf(USB_FUNCTION_PIPE0); /*callback*/ (object->*EP0func)(); break; case USB_FUNCTION_READSHRT: /* End of data read */ usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0); /* PID = BUF */ usbx_function_set_pid_buf(USB_FUNCTION_PIPE0); /*callback*/ (object->*EP0func)(); break; case USB_FUNCTION_READOVER: /* FIFO access error */ /* Buffer Clear */ USB20X.CFIFOCTR = USB_FUNCTION_BITBCLR; usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0); /* Req Error */ usbx_function_set_pid_stall(USB_FUNCTION_PIPE0); /*callback*/ (object->*EP0func)(); break; case DEVDRV_USBF_FIFOERROR: /* FIFO access error */ default: usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0); /* Req Error */ usbx_function_set_pid_stall(USB_FUNCTION_PIPE0); break; } /* Three dummy reads for clearing interrupt requests */ dumy_sts = USB20X.BRDYSTS; } } /****************************************************************************** * Function Name: usbx_function_BRDYInterrupt * Description : Executes BRDY interrupt uxclude pipe0. * Arguments : uint16_t status ; BRDYSTS Register Value * : uint16_t intenb ; BRDYENB Register Value * Return Value : none *****************************************************************************/ extern "C" { void usbx_function_BRDYInterrupt( uint16_t status, uint16_t intenb, USBHAL *object, bool (USBHAL::*epCallback[])(void) ) { volatile uint16_t dumy_sts; /************************************************************** * Function Name: usbx_function_brdy_int * Description : Executes BRDY interrupt(USB_FUNCTION_PIPE1-9). * : According to the pipe that interrupt is generated in, * : reads/writes buffer allocated in the pipe. * : This function is executed in the BRDY * : interrupt handler. This function * : clears BRDY interrupt status and BEMP * : interrupt status. * Arguments : uint16_t Status ; BRDYSTS Register Value * : uint16_t Int_enbl ; BRDYENB Register Value * Return Value : none *************************************************************/ /* copied from usbx_function_intrn.c */ uint32_t int_sense = 0; uint16_t pipe; uint16_t pipebit; uint16_t ep; for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) { pipebit = g_usbx_function_bit_set[pipe]; if ((status & pipebit) && (intenb & pipebit)) { USB20X.BRDYSTS = (uint16_t)~pipebit; USB20X.BEMPSTS = (uint16_t)~pipebit; switch (g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) { case USB_FUNCTION_D0FIFO_DMA: if (g_usbx_function_DmaStatus[USB_FUNCTION_D0FIFO] != USB_FUNCTION_DMA_READY) { /*now, DMA is not supported*/ usbx_function_dma_interrupt_d0fifo(int_sense); } if (RZA_IO_RegRead_16( &g_usbx_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { /*now, DMA is not supported*/ usbx_function_read_dma(pipe); usbx_function_disable_brdy_int(pipe); } else { USB20X.D0FIFOCTR = USB_FUNCTION_BITBCLR; g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; } break; case USB_FUNCTION_D1FIFO_DMA: if (g_usbx_function_DmaStatus[USB_FUNCTION_D1FIFO] != USB_FUNCTION_DMA_READY) { /*now, DMA is not supported*/ usbx_function_dma_interrupt_d1fifo(int_sense); } if (RZA_IO_RegRead_16( &g_usbx_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { /*now, DMA is not supported*/ usbx_function_read_dma(pipe); usbx_function_disable_brdy_int(pipe); } else { USB20X.D1FIFOCTR = USB_FUNCTION_BITBCLR; g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; } break; default: ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; ep <<= 1; if (RZA_IO_RegRead_16( &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) { /* read */ EPx_read_status = DEVDRV_USBF_PIPE_WAIT; (object->*(epCallback[ep - 2])) (); EPx_read_status = DEVDRV_USBF_PIPE_DONE; } else { /* write */ EPx_read_status = DEVDRV_USBF_PIPE_WAIT; (object->*(epCallback[ep - 2 + 1])) (); EPx_read_status = DEVDRV_USBF_PIPE_DONE; usbx_function_write_buffer(pipe); } } } } /* Three dummy reads for clearing interrupt requests */ dumy_sts = USB20X.BRDYSTS; } } /****************************************************************************** * Function Name: usbx_function_NRDYInterruptPIPE0 * Description : Executes NRDY interrupt for pipe0. * Arguments : uint16_t status ; NRDYSTS Register Value * : uint16_t intenb ; NRDYENB Register Value * Return Value : none *****************************************************************************/ extern "C" { void usbx_function_NRDYInterruptPIPE0( uint16_t status, uint16_t intenb, USBHAL *object, void (USBHAL::*EP0func)(void) ) { volatile uint16_t dumy_sts; USB20X.NRDYSTS = (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0]; /* Three dummy reads for clearing interrupt requests */ dumy_sts = USB20X.NRDYSTS; } } /****************************************************************************** * Function Name: usbx_function_NRDYInterrupt * Description : Executes NRDY interrupt exclude pipe0. * Arguments : uint16_t status ; NRDYSTS Register Value * : uint16_t intenb ; NRDYENB Register Value * Return Value : none *****************************************************************************/ extern "C" { void usbx_function_NRDYInterrupt( uint16_t status, uint16_t intenb, USBHAL *object, bool (USBHAL::*epCallback[])(void) ) { volatile uint16_t dumy_sts; /************************************************************** * Function Name: usbx_function_nrdy_int * Description : Executes NRDY interrupt(USB_FUNCTION_PIPE1-9). * : Checks NRDY interrupt cause by PID. When the cause if STALL, * : regards the pipe state as STALL and ends the processing. * : Then the cause is not STALL, increments the error count to * : communicate again. When the error count is 3, determines * : the pipe state as DEVDRV_USBF_PIPE_NORES and ends the processing. * : This function is executed in the NRDY interrupt handler. * : This function clears NRDY interrupt status. * Arguments : uint16_t status ; NRDYSTS Register Value * : uint16_t int_enb ; NRDYENB Register Value * Return Value : none *************************************************************/ /* copied from usbx_function_intrn.c */ #if 0 uint16_t usefifo; #endif uint16_t pid; uint16_t pipe; uint16_t bitcheck; #if 0 uint16_t mbw; uint32_t size; #endif uint16_t ep; bitcheck = (uint16_t)(status & intenb); USB20X.NRDYSTS = (uint16_t)~status; if (RZA_IO_RegRead_16(&USB20X.SYSCFG0, USB_SYSCFG_DCFM_SHIFT, USB_SYSCFG_DCFM) == 1) { /* USB HOST */ /* not support */ } else { /* USB Function */ for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) { if ((bitcheck&g_usbx_function_bit_set[pipe]) != g_usbx_function_bit_set[pipe]) { continue; } if (g_usbx_function_pipe_status[pipe] != DEVDRV_USBF_PIPE_WAIT) { continue; } #if 0 usbx_function_set_pid_nak(pipe); size = (uint32_t)g_usbx_function_data_count[pipe]; mbw = usbx_function_get_mbw( size, (uint32_t)g_usbx_function_data_pointer[pipe]); usefifo = (uint16_t)(g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE); switch (usefifo) { case USB_FUNCTION_D0FIFO_USE: usbx_function_set_curpipe( pipe, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw); USB20X.D0FIFOCTR = USB_FUNCTION_BITBCLR; break; case USB_FUNCTION_D1FIFO_USE: usbx_function_set_curpipe( pipe, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw); USB20X.D1FIFOCTR = USB_FUNCTION_BITBCLR; break; default: usbx_function_set_curpipe( pipe, USB_FUNCTION_CUSE, USB_FUNCTION_CFIFO_READ, mbw); USB20X.CFIFOCTR = USB_FUNCTION_BITBCLR; break; } usbx_function_aclrm(pipe); usbx_function_enable_nrdy_int(pipe); usbx_function_enable_brdy_int(pipe); usbx_function_set_pid_buf(pipe); #endif pid = usbx_function_get_pid(pipe); if ((pid == DEVDRV_USBF_PID_STALL) || (pid == DEVDRV_USBF_PID_STALL2)) { g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL; } else { usbx_function_set_pid_buf(pipe); } ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; ep <<= 1; if (RZA_IO_RegRead_16( &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) { /* read */ __NOP(); } else { /* write */ __NOP(); } } } /* Three dummy reads for clearing interrupt requests */ dumy_sts = USB20X.NRDYSTS; } } /****************************************************************************** * Function Name: usbx_function_BEMPInterruptPIPE0 * Description : Executes BEMP interrupt for pipe0. * Arguments : uint16_t status ; BEMPSTS Register Value * : uint16_t intenb ; BEMPENB Register Value * Return Value : none *****************************************************************************/ extern "C" { void usbx_function_BEMPInterruptPIPE0( uint16_t status, uint16_t intenb, USBHAL *object, void (USBHAL::*EP0func)(void) ) { volatile uint16_t dumy_sts; USB20X.BEMPSTS = (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0]; RZA_IO_RegWrite_16( &USB20X.CFIFOSEL, USB_FUNCTION_PIPE0, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE); /*usbx_function_write_buffer_c(USB_FUNCTION_PIPE0);*/ (object->*EP0func)(); /* Three dummy reads for clearing interrupt requests */ dumy_sts = USB20X.BEMPSTS; } } /****************************************************************************** * Function Name: usbx_function_BEMPInterrupt * Description : Executes BEMP interrupt exclude pipe0. * Arguments : uint16_t status ; BEMPSTS Register Value * : uint16_t intenb ; BEMPENB Register Value * Return Value : none *****************************************************************************/ extern "C" { void usbx_function_BEMPInterrupt( uint16_t status, uint16_t intenb, USBHAL *object, bool (USBHAL::*epCallback[])(void) ) { volatile uint16_t dumy_sts; /************************************************************** * Function Name: usbx_function_bemp_int * Description : Executes BEMP interrupt(USB_FUNCTION_PIPE1-9). * Arguments : uint16_t status ; BEMPSTS Register Value * : uint16_t intenb ; BEMPENB Register Value * Return Value : none *************************************************************/ /* copied from usbx_function_intrn.c */ uint16_t pid; uint16_t pipe; uint16_t bitcheck; uint16_t inbuf; uint16_t ep; bitcheck = (uint16_t)(status & intenb); USB20X.BEMPSTS = (uint16_t)~status; for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) { if ((bitcheck&g_usbx_function_bit_set[pipe]) != g_usbx_function_bit_set[pipe]) { continue; } pid = usbx_function_get_pid(pipe); if ((pid == DEVDRV_USBF_PID_STALL) || (pid == DEVDRV_USBF_PID_STALL2)) { g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL; } else { inbuf = usbx_function_get_inbuf(pipe); if (inbuf == 0) { usbx_function_disable_bemp_int(pipe); usbx_function_set_pid_nak(pipe); g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; switch (g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) { case USB_FUNCTION_D0FIFO_DMA: /*now, DMA is not supported*/ break; case USB_FUNCTION_D1FIFO_DMA: /*now, DMA is not supported*/ break; default: ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; ep <<= 1; if (RZA_IO_RegRead_16( &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) { /* read */ __NOP(); } else { /* write */ EPx_read_status = DEVDRV_USBF_PIPE_WAIT; (object->*(epCallback[ep - 2 + 1])) (); EPx_read_status = DEVDRV_USBF_PIPE_DONE; } } } } } /* Three dummy reads for clearing interrupt requests */ dumy_sts = USB20X.BEMPSTS; } } /****************************************************************************** * Function Name: EP2PIPE * Description : Converts from endpoint to pipe * Arguments : number of endpoint * Return Value : number of pipe *****************************************************************************/ /*EP2PIPE converter is for pipe1, pipe3 and pipe6 only.*/ #define EP2PIPE(endpoint) ((uint32_t)usbx_function_EpToPipe(endpoint)) /****************************************************************************** * Function Name: usbx_function_save_request * Description : Retains the USB request information in variables. * Arguments : none * Return Value : none *****************************************************************************/ #define usbx_function_save_request() \ { \ uint16_t *bufO = &setup_buffer[0]; \ \ USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITVALID; \ /*data[0] <= bmRequest, data[1] <= bmRequestType */ \ *bufO++ = USB20X.USBREQ; \ /*data[2] data[3] <= wValue*/ \ *bufO++ = USB20X.USBVAL; \ /*data[4] data[5] <= wIndex*/ \ *bufO++ = USB20X.USBINDX; \ /*data[6] data[6] <= wIndex*/ \ *bufO++ = USB20X.USBLENG; \ } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* constructor */ USBHAL::USBHAL(void) { /* ---- P4_1 : P4_1 (USB0_EN for GR-PEACH) ---- */ //usbx_en = new DigitalOut(P4_1, 1); /* some constants */ int_id = USBIX_IRQn; int_level = ( 2 << 3 ); clock_mode = USBFCLOCK_X1_48MHZ; #if (USB_FUNCTION_HISPEED == 0) mode = USB_FUNCTION_FULL_SPEED; #else mode = USB_FUNCTION_HIGH_SPEED; #endif EP0_read_status = DEVDRV_USBF_WRITEEND; EPx_read_status = DEVDRV_USBF_PIPE_DONE; /* Disables interrupt for usb */ GIC_DisableIRQ(int_id); /* Setup the end point */ epCallback[ 0] = &USBHAL::EP1_OUT_callback; epCallback[ 1] = &USBHAL::EP1_IN_callback; epCallback[ 2] = &USBHAL::EP2_OUT_callback; epCallback[ 3] = &USBHAL::EP2_IN_callback; epCallback[ 4] = &USBHAL::EP3_OUT_callback; epCallback[ 5] = &USBHAL::EP3_IN_callback; epCallback[ 6] = &USBHAL::EP4_OUT_callback; epCallback[ 7] = &USBHAL::EP4_IN_callback; epCallback[ 8] = &USBHAL::EP5_OUT_callback; epCallback[ 9] = &USBHAL::EP5_IN_callback; epCallback[10] = &USBHAL::EP6_OUT_callback; epCallback[11] = &USBHAL::EP6_IN_callback; epCallback[12] = &USBHAL::EP7_OUT_callback; epCallback[13] = &USBHAL::EP7_IN_callback; epCallback[14] = &USBHAL::EP8_OUT_callback; epCallback[15] = &USBHAL::EP8_IN_callback; epCallback[16] = &USBHAL::EP9_OUT_callback; epCallback[17] = &USBHAL::EP9_IN_callback; epCallback[18] = &USBHAL::EP10_OUT_callback; epCallback[19] = &USBHAL::EP10_IN_callback; epCallback[20] = &USBHAL::EP11_OUT_callback; epCallback[21] = &USBHAL::EP11_IN_callback; epCallback[22] = &USBHAL::EP12_OUT_callback; epCallback[23] = &USBHAL::EP12_IN_callback; epCallback[24] = &USBHAL::EP13_OUT_callback; epCallback[25] = &USBHAL::EP13_IN_callback; epCallback[26] = &USBHAL::EP14_OUT_callback; epCallback[27] = &USBHAL::EP14_IN_callback; epCallback[28] = &USBHAL::EP15_OUT_callback; epCallback[29] = &USBHAL::EP15_IN_callback; /* registers me */ instance = this; /* Clear pipe table */ usbx_function_clear_pipe_tbl(); /****************************************************************************** * Function Name: usbx_api_function_init * Description : Initializes the USB module in the USB function mode. *****************************************************************************/ /* The clock of USB0 modules is permitted */ #if (USB_FUNCTION_CH == 0) CPG.STBCR7 &= ~(CPG_STBCR7_MSTP71); #else CPG.STBCR7 &= ~(CPG_STBCR7_MSTP71 | CPG_STBCR7_MSTP70); #endif volatile uint8_t dummy8; dummy8 = CPG.STBCR7; { /****************************************************************************** * Function Name: usbx_function_setting_interrupt * Description : Sets the USB module interrupt level. *****************************************************************************/ #if 0 /*DMA is not supported*/ IRQn_Type d0fifo_dmaintid; IRQn_Type d1fifo_dmaintid; #endif InterruptHandlerRegister(int_id, &_usbisr); GIC_SetPriority(int_id, int_level); GIC_EnableIRQ(int_id); #if 0 /*DMA is not supported*/ d0fifo_dmaintid = Userdef_USB_usbx_function_d0fifo_dmaintid(); if (d0fifo_dmaintid != 0xFFFF) { InterruptHandlerRegister(d0fifo_dmaintid, usbx_function_dma_interrupt_d0fifo); GIC_SetPriority(d0fifo_dmaintid, int_level); GIC_EnableIRQ(d0fifo_dmaintid); } #endif #if 0 /*DMA is not supported*/ d1fifo_dmaintid = Userdef_USB_usbx_function_d1fifo_dmaintid(); if (d1fifo_dmaintid != 0xFFFF) { InterruptHandlerRegister(d1fifo_dmaintid, usbx_function_dma_interrupt_d1fifo); GIC_SetPriority(d1fifo_dmaintid, int_level); GIC_EnableIRQ(d1fifo_dmaintid); } #endif /*****************************************************************************/ } /* reset USB module with setting tranciever and HSE=1 */ usbx_function_reset_module(clock_mode); /* clear variables */ usbx_function_init_status(); /* select USB Function and Interrupt Enable */ /* Detect USB Device to attach or detach */ usbx_function_InitModule(mode); { uint16_t buf; buf = USB20X.INTENB0; buf |= USB_INTENB0_SOFE; USB20X.INTENB0 = buf; } } /*************************************************************************/ USBHAL::~USBHAL(void) { /* Disables interrupt for usb */ GIC_DisableIRQ( int_id ); /* Unregisters interrupt function and priority */ InterruptHandlerRegister( int_id, (uint32_t)NULL ); //usbx_en = NULL; instance = NULL; } /*************************************************************************/ void USBHAL::connect(void) { /* Activates USB0_EN */ //(*usbx_en) = 0; } /*************************************************************************/ void USBHAL::disconnect(void) { /* Deactivates USB0_EN */ //(*usbx_en) = 1; } /*************************************************************************/ void USBHAL::configureDevice(void) { /*The pipes set up in USBHAL::realiseEndpoint*/ /*usbx_function_clear_alt();*/ /* Alternate setting clear */ /*usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);*/ } /*************************************************************************/ void USBHAL::unconfigureDevice(void) { /* The Interface would be managed by USBDevice */ /*usbx_function_clear_alt();*/ /* Alternate setting clear */ /*usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);*/ } /*************************************************************************/ void USBHAL::setAddress(uint8_t address) { if (address <= 127) { usbx_function_set_pid_buf(USB_FUNCTION_PIPE0); /* OK */ } else { usbx_function_set_pid_stall(USB_FUNCTION_PIPE0); /* Not Spec */ } } /*************************************************************************/ bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { const struct PIPECFGREC *cfg; uint16_t pipe; uint16_t buf; if ( (EP0OUT == endpoint) || (EP0IN == endpoint) ) { return true; } for (cfg = &def_pipecfg[0]; cfg->pipesel != 0; cfg++) { if (cfg->endpoint == endpoint) { break; } } if (cfg->pipesel == 0) { return false; } pipe = ((cfg->pipesel & USB_PIPESEL_PIPESEL) >> USB_PIPESEL_PIPESEL_SHIFT); g_usbx_function_PipeTbl[ pipe ] = (uint16_t)(endpoint | ((cfg->pipesel & USB_FUNCTION_FIFO_USE) << 0)); /* There are maintenance routine of SHTNAK and BFRE bits * in original sample program. This sample is not * programmed. Do maintenance the "def_pipecfg" array if * you want it. */ /* Interrupt Disable */ buf = USB20X.BRDYENB; buf &= (uint16_t)~g_usbx_function_bit_set[pipe]; USB20X.BRDYENB = buf; buf = USB20X.NRDYENB; buf &= (uint16_t)~g_usbx_function_bit_set[pipe]; USB20X.NRDYENB = buf; buf = USB20X.BEMPENB; buf &= (uint16_t)~g_usbx_function_bit_set[pipe]; USB20X.BEMPENB = buf; usbx_function_set_pid_nak(pipe); /* CurrentPIPE Clear */ if (RZA_IO_RegRead_16(&USB20X.CFIFOSEL, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE) == pipe) { RZA_IO_RegWrite_16(&USB20X.CFIFOSEL, 0, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE); } if (RZA_IO_RegRead_16(&USB20X.D0FIFOSEL, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE) == pipe) { RZA_IO_RegWrite_16(&USB20X.D0FIFOSEL, 0, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE); } if (RZA_IO_RegRead_16(&USB20X.D1FIFOSEL, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE) == pipe) { RZA_IO_RegWrite_16(&USB20X.D1FIFOSEL, 0, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE); } /* PIPE Configuration */ USB20X.PIPESEL = pipe; USB20X.PIPECFG = cfg->pipecfg; USB20X.PIPEBUF = cfg->pipebuf; USB20X.PIPEMAXP = cfg->pipemaxp; USB20X.PIPEPERI = cfg->pipeperi; g_usbx_function_pipecfg[pipe] = cfg->pipecfg; g_usbx_function_pipebuf[pipe] = cfg->pipebuf; g_usbx_function_pipemaxp[pipe] = cfg->pipemaxp; g_usbx_function_pipeperi[pipe] = cfg->pipeperi; /* Buffer Clear */ usbx_function_set_sqclr(pipe); usbx_function_aclrm(pipe); /* init Global */ g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_IDLE; g_usbx_function_PipeDataSize[pipe] = 0; return true; } /*************************************************************************/ // read setup packet void USBHAL::EP0setup(uint8_t *buffer) { memcpy(buffer, setup_buffer, MAX_PACKET_SIZE_EP0); } /*************************************************************************/ void USBHAL::EP0readStage(void) { // No implements } /*************************************************************************/ void USBHAL::EP0read(void) { uint8_t *buffer; uint32_t size; /* remain of last writing */ while (EP0_read_status != DEVDRV_USBF_WRITEEND) { static uint8_t bbb[2] = { 255, 255 }; EP0write(&bbb[0], 0); } buffer = (uint8_t*)(&setup_buffer[4]); size = (MAX_PACKET_SIZE_EP0 / 2) - 8; usbx_api_function_CtrlWriteStart(size, buffer); } /*************************************************************************/ uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { memcpy(buffer, (uint8_t*)(&setup_buffer[4]), g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0]); return g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0]; } /*************************************************************************/ void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { /* zero byte writing */ if ( (size == 0) && (EP0_read_status == DEVDRV_USBF_WRITEEND) ) { return; } if (EP0_read_status == DEVDRV_USBF_WRITEEND) { /*1st block*/ EP0_read_status = usbx_api_function_CtrlReadStart(size, buffer); } else { /* waits the last transmission */ /*other blocks*/ g_usbx_function_data_count[ USB_FUNCTION_PIPE0 ] = size; g_usbx_function_data_pointer [ USB_FUNCTION_PIPE0 ] = buffer; EP0_read_status = usbx_function_write_buffer_c(USB_FUNCTION_PIPE0); } /*max size may be deblocking outside*/ if (size == MAX_PACKET_SIZE_EP0) { EP0_read_status = DEVDRV_USBF_WRITING; } } /*************************************************************************/ #if 0 // No implements void USBHAL::EP0getWriteResult(void) { } #endif /*************************************************************************/ void USBHAL::EP0stall(void) { stallEndpoint( 0 ); } /*************************************************************************/ EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t max_size) { uint32_t pipe = EP2PIPE(endpoint); uint32_t pipe_size; uint16_t pipe_status; EP_STATUS status = EP_COMPLETED; pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size); switch (pipe_status) { case DEVDRV_USBF_PIPE_IDLE: case DEVDRV_USBF_PIPE_WAIT: usbx_api_function_set_pid_nak(pipe); usbx_api_function_clear_pipe_status(pipe); usbx_api_function_start_receive_transfer(pipe, max_size, recv_buffer); break; default: status = EP_PENDING; break; } return status; } /*************************************************************************/ EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *buffer, uint32_t *bytes_read ) { uint32_t pipe = EP2PIPE(endpoint); uint16_t pipe_status; uint16_t err; EP_STATUS status = EP_PENDING; if (EPx_read_status != DEVDRV_USBF_PIPE_WAIT) { return status; } pipe_status = usbx_api_function_check_pipe_status(pipe, bytes_read); switch (pipe_status) { case DEVDRV_USBF_PIPE_IDLE: return EP_COMPLETED; case DEVDRV_USBF_PIPE_DONE: return EP_COMPLETED; case DEVDRV_USBF_PIPE_WAIT: break; default: return status; } /* sets the output buffer and size */ g_usbx_function_data_pointer[pipe] = buffer; /* receives data from pipe */ err = usbx_function_read_buffer(pipe); recv_error = err; switch (err) { case USB_FUNCTION_READEND: case USB_FUNCTION_READSHRT: case USB_FUNCTION_READOVER: *bytes_read = g_usbx_function_PipeDataSize[pipe]; break; case USB_FUNCTION_READING: case DEVDRV_USBF_FIFOERROR: break; } pipe_status = usbx_api_function_check_pipe_status(pipe, bytes_read); switch (pipe_status) { case DEVDRV_USBF_PIPE_DONE: status = EP_COMPLETED; break; case DEVDRV_USBF_PIPE_IDLE: case DEVDRV_USBF_PIPE_NORES: case DEVDRV_USBF_PIPE_STALL: case DEVDRV_USBF_FIFOERROR: default: break; } return status; } /*************************************************************************/ EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { uint32_t pipe = EP2PIPE(endpoint); uint32_t pipe_size; uint16_t pipe_status; uint16_t err; uint16_t count; EP_STATUS status = EP_PENDING; pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size); /* waits the last transmission */ count = 30000; while ((pipe_status == DEVDRV_USBF_PIPE_WAIT) || (pipe_status == DEVDRV_USBF_PIPE_DONE)) { pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size); if( --count == 0 ) { pipe_status = DEVDRV_USBF_PIPE_STALL; break; } } switch (pipe_status) { case DEVDRV_USBF_PIPE_IDLE: err = usbx_api_function_start_send_transfer(pipe, size, data); switch (err) { /* finish to write */ case DEVDRV_USBF_WRITEEND: /* finish to write, but data is short */ case DEVDRV_USBF_WRITESHRT: /* continue to write */ case DEVDRV_USBF_WRITING: /* use DMA */ case DEVDRV_USBF_WRITEDMA: /* error */ case DEVDRV_USBF_FIFOERROR: status = EP_PENDING; break; } break; case DEVDRV_USBF_PIPE_WAIT: case DEVDRV_USBF_PIPE_DONE: status = EP_PENDING; break; case DEVDRV_USBF_PIPE_NORES: case DEVDRV_USBF_PIPE_STALL: default: status = EP_STALLED; break; } return status; } /*************************************************************************/ EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { uint32_t pipe = EP2PIPE(endpoint); uint32_t pipe_size; uint16_t pipe_status; EP_STATUS status = EP_PENDING; pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size); switch (pipe_status) { case DEVDRV_USBF_PIPE_IDLE: status = EP_COMPLETED; break; case DEVDRV_USBF_PIPE_WAIT: status = EP_PENDING; break; case DEVDRV_USBF_PIPE_DONE: usbx_function_stop_transfer(pipe); status = EP_COMPLETED; break; case DEVDRV_USBF_PIPE_NORES: status = EP_STALLED; break; case DEVDRV_USBF_PIPE_STALL: status = EP_STALLED; break; default: status = EP_PENDING; } return status; } /*************************************************************************/ void USBHAL::stallEndpoint(uint8_t endpoint) { uint32_t pipe = EP2PIPE(endpoint); usbx_function_clear_pid_stall(pipe); } /*************************************************************************/ void USBHAL::unstallEndpoint(uint8_t endpoint) { uint32_t pipe = EP2PIPE(endpoint); usbx_function_set_pid_stall( pipe ); } /*************************************************************************/ bool USBHAL::getEndpointStallState(uint8_t endpoint) { // No implemens return false; } /*************************************************************************/ #if 0 // No implements void USBHAL::remoteWakeup(void) { } #endif /*************************************************************************/ void USBHAL::_usbisr(void) { instance->usbisr(); } /*************************************************************************/ void USBHAL::usbisr(void) { uint16_t int_sts0; uint16_t int_sts1; uint16_t int_sts2; uint16_t int_sts3; uint16_t int_enb0; uint16_t int_enb2; uint16_t int_enb3; uint16_t int_enb4; volatile uint16_t dumy_sts; int_sts0 = USB20X.INTSTS0; if (!(int_sts0 & ( USB_FUNCTION_BITVBINT | USB_FUNCTION_BITRESM | USB_FUNCTION_BITSOFR | USB_FUNCTION_BITDVST | USB_FUNCTION_BITCTRT | USB_FUNCTION_BITBEMP | USB_FUNCTION_BITNRDY | USB_FUNCTION_BITBRDY ))) { return; } int_sts1 = USB20X.BRDYSTS; int_sts2 = USB20X.NRDYSTS; int_sts3 = USB20X.BEMPSTS; int_enb0 = USB20X.INTENB0; int_enb2 = USB20X.BRDYENB; int_enb3 = USB20X.NRDYENB; int_enb4 = USB20X.BEMPENB; if ((int_sts0 & USB_FUNCTION_BITRESM) && (int_enb0 & USB_FUNCTION_BITRSME)) { USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITRESM; RZA_IO_RegWrite_16(&USB20X.INTENB0, 0, USB_INTENB0_RSME_SHIFT, USB_INTENB0_RSME); /*usbx_function_USB_FUNCTION_Resume();*/ suspendStateChanged(1); } else if ( (int_sts0 & USB_FUNCTION_BITVBINT) && (int_enb0 & USB_FUNCTION_BITVBSE)) { USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITVBINT; if (usbx_function_CheckVBUStaus() == DEVDRV_USBF_ON) { usbx_function_USB_FUNCTION_Attach(); } else { usbx_function_USB_FUNCTION_Detach(); } } else if ( (int_sts0 & USB_FUNCTION_BITSOFR) && (int_enb0 & USB_FUNCTION_BITSOFE)) { USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITSOFR; SOF((USB20X.FRMNUM & USB_FRMNUM_FRNM) >> USB_FRMNUM_FRNM_SHIFT); } else if ( (int_sts0 & USB_FUNCTION_BITDVST) && (int_enb0 & USB_FUNCTION_BITDVSE)) { USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITDVST; switch (int_sts0 & USB_FUNCTION_BITDVSQ) { case USB_FUNCTION_DS_POWR: break; case USB_FUNCTION_DS_DFLT: /***************************************************************************** * Function Name: usbx_function_USB_FUNCTION_BusReset * Description : This function is executed when the USB device is transitioned * : to POWERD_STATE. Sets the device descriptor according to the * : connection speed determined by the USB reset hand shake. * Arguments : none * Return Value : none *****************************************************************************/ usbx_function_init_status(); /* memory clear */ #if 0 /* You would program those steps in USBCallback_busReset * if the system need the comment out steps. */ if (usbx_function_is_hispeed() == USB_FUNCTION_HIGH_SPEED) { /* Device Descriptor reset */ usbx_function_ResetDescriptor(USB_FUNCTION_HIGH_SPEED); } else { /* Device Descriptor reset */ usbx_function_ResetDescriptor(USB_FUNCTION_FULL_SPEED); } #endif /* Default Control PIPE reset */ /***************************************************************************** * Function Name: usbx_function_ResetDCP * Description : Initializes the default control pipe(DCP). * Outline : Reset default control pipe * Arguments : none * Return Value : none *****************************************************************************/ USB20X.DCPCFG = 0; USB20X.DCPMAXP = 64; /*TODO: This value is copied from sample*/ USB20X.CFIFOSEL = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE); USB20X.D0FIFOSEL = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE); USB20X.D1FIFOSEL = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE); busReset(); break; case USB_FUNCTION_DS_ADDS: break; case USB_FUNCTION_DS_CNFG: break; case USB_FUNCTION_DS_SPD_POWR: case USB_FUNCTION_DS_SPD_DFLT: case USB_FUNCTION_DS_SPD_ADDR: case USB_FUNCTION_DS_SPD_CNFG: suspendStateChanged(0); /*usbx_function_USB_FUNCTION_Suspend();*/ break; default: break; } } else if ( (int_sts0 & USB_FUNCTION_BITBEMP) && (int_enb0 & USB_FUNCTION_BITBEMP) && ((int_sts3 & int_enb4) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) { /* ==== BEMP PIPE0 ==== */ usbx_function_BEMPInterruptPIPE0(int_sts3, int_enb4, this, &USBHAL::EP0in); } else if ( (int_sts0 & USB_FUNCTION_BITBRDY) && (int_enb0 & USB_FUNCTION_BITBRDY) && ((int_sts1 & int_enb2) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) { /* ==== BRDY PIPE0 ==== */ usbx_function_BRDYInterruptPIPE0(int_sts1, int_enb2, this, &USBHAL::EP0out); } else if ( (int_sts0 & USB_FUNCTION_BITNRDY) && (int_enb0 & USB_FUNCTION_BITNRDY) && ((int_sts2 & int_enb3) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) { /* ==== NRDY PIPE0 ==== */ usbx_function_NRDYInterruptPIPE0(int_sts2, int_enb3, this, NULL); } else if ( (int_sts0 & USB_FUNCTION_BITCTRT) && (int_enb0 & USB_FUNCTION_BITCTRE)) { int_sts0 = USB20X.INTSTS0; USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITCTRT; if (((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_RDDS) || ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRDS) || ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRND)) { /* remake EP0 into buffer */ usbx_function_save_request(); if ((USB20X.INTSTS0 & USB_FUNCTION_BITVALID) && ( ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_RDDS) || ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRDS) || ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRND))) { /* New SETUP token received */ /* Three dummy reads for cleearing interrupt requests */ dumy_sts = USB20X.INTSTS0; dumy_sts = USB20X.INTSTS0; dumy_sts = USB20X.INTSTS0; return; } } switch (int_sts0 & USB_FUNCTION_BITCTSQ) { case USB_FUNCTION_CS_IDST: if (g_usbx_function_TestModeFlag == DEVDRV_USBF_YES) { /* ==== Test Mode ==== */ usbx_function_USB_FUNCTION_TestMode(); } /* Needs not procedure in this state */ break; case USB_FUNCTION_CS_RDDS: /* Reads a setup packet */ EP0setupCallback(); break; case USB_FUNCTION_CS_WRDS: /* Original code was the SetDescriptor was called */ EP0setupCallback(); break; case USB_FUNCTION_CS_WRND: EP0setupCallback(); /*The EP0setupCallback should finish in successful */ usbx_function_set_pid_buf(USB_FUNCTION_PIPE0); RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL); break; case USB_FUNCTION_CS_RDSS: RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL); break; case USB_FUNCTION_CS_WRSS: RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL); break; case USB_FUNCTION_CS_SQER: usbx_function_set_pid_stall(USB_FUNCTION_PIPE0); break; default: usbx_function_set_pid_stall(USB_FUNCTION_PIPE0); break; } } else if ( (int_sts0 & USB_FUNCTION_BITBEMP) && (int_enb0 & USB_FUNCTION_BITBEMP) && (int_sts3 & int_enb4) ) { /* ==== BEMP PIPEx ==== */ usbx_function_BEMPInterrupt(int_sts3, int_enb4, this, epCallback); } else if ( (int_sts0 & USB_FUNCTION_BITBRDY) && (int_enb0 & USB_FUNCTION_BITBRDY) && (int_sts1 & int_enb2) ) { /* ==== BRDY PIPEx ==== */ usbx_function_BRDYInterrupt(int_sts1, int_enb2, this, epCallback); } else if ( (int_sts0 & USB_FUNCTION_BITNRDY) && (int_enb0 & USB_FUNCTION_BITNRDY) && (int_sts2 & int_enb3)) { /* ==== NRDY PIPEx ==== */ usbx_function_NRDYInterrupt(int_sts2, int_enb3, this, epCallback); } else { /* Do Nothing */ } /* Three dummy reads for cleearing interrupt requests */ dumy_sts = USB20X.INTSTS0; dumy_sts = USB20X.INTSTS1; } /*************************************************************************/ #endif /*************************************************************************/ /*EOF*/