Version of USBDevice that works for KL25Z on Mbed OS2.
Fork of USBDevice by
Diff: targets/TARGET_RENESAS/USBHAL_RZ_A1H.cpp
- Revision:
- 71:53949e6131f6
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/TARGET_RENESAS/USBHAL_RZ_A1H.cpp Thu Jul 27 12:14:04 2017 +0100 @@ -0,0 +1,1497 @@ +/* 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*/