Działająca myszka
Fork of USBDevice by
Diff: USBDevice/USBHAL_RZ_A1H.cpp
- Revision:
- 40:3b1c43ac045c
- Parent:
- 36:4d3e7f3d5211
- Child:
- 42:4f589e246b9e
--- a/USBDevice/USBHAL_RZ_A1H.cpp Tue Jan 06 16:16:27 2015 +0000 +++ b/USBDevice/USBHAL_RZ_A1H.cpp Mon Jan 19 14:30:30 2015 +0000 @@ -1,19 +1,26 @@ /* 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: +* 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 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. +* 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) @@ -59,8 +66,9 @@ USB_FUNCTION_DIR_P_OUT | USB_FUNCTION_EP1, ( ( ( 64) / 64 - 1 ) << 10 ) | 0x04u, - 64, - DEVDRV_USBF_OFF | 0, + MAX_PACKET_SIZE_EP1, + DEVDRV_USBF_OFF | + ( 3 << USB_PIPEPERI_IITV_SHIFT ), }, { EP1IN, /*EP1: Host <- Func, INT*/ @@ -73,8 +81,9 @@ USB_FUNCTION_DIR_P_IN | USB_FUNCTION_EP1, ( ( ( 64) / 64 - 1 ) << 10 ) | 0x05u, - 64, - DEVDRV_USBF_OFF | 0, + MAX_PACKET_SIZE_EP1, + DEVDRV_USBF_OFF | + ( 3 << USB_PIPEPERI_IITV_SHIFT ), }, { EP2OUT, /*EP2: Host -> Func, BULK*/ @@ -87,8 +96,9 @@ USB_FUNCTION_DIR_P_OUT | USB_FUNCTION_EP2, ( ( (2048) / 64 - 1 ) << 10 ) | 0x30u, - 512, - DEVDRV_USBF_OFF | 0, + MAX_PACKET_SIZE_EP2, + DEVDRV_USBF_OFF | + ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { EP2IN, /*EP2: Host <- Func, BULK*/ @@ -101,8 +111,9 @@ USB_FUNCTION_DIR_P_IN | USB_FUNCTION_EP2, ( ( (2048) / 64 - 1 ) << 10 ) | 0x50u, - 512, - DEVDRV_USBF_OFF | 0, + MAX_PACKET_SIZE_EP2, + DEVDRV_USBF_OFF | + ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { EP3OUT, /*EP3: Host -> Func, ISO*/ @@ -110,13 +121,14 @@ USB_FUNCTION_ISO | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBON | - USB_FUNCTION_CNTMDON | + USB_FUNCTION_CNTMDOFF | USB_FUNCTION_SHTNAKON | USB_FUNCTION_DIR_P_OUT | USB_FUNCTION_EP3, - ( ( (1024) / 64 - 1 ) << 10 ) | 0x10u, - 192, - DEVDRV_USBF_OFF | 1, + ( ( ( 512) / 64 - 1 ) << 10 ) | 0x10u, + MAX_PACKET_SIZE_EP3, + DEVDRV_USBF_OFF | + ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { EP3IN, /*EP3: Host <- Func, ISO*/ @@ -124,13 +136,14 @@ USB_FUNCTION_ISO | USB_FUNCTION_BFREOFF | USB_FUNCTION_DBLBON | - USB_FUNCTION_CNTMDON | + USB_FUNCTION_CNTMDOFF | USB_FUNCTION_SHTNAKOFF | USB_FUNCTION_DIR_P_IN | USB_FUNCTION_EP3, - ( ( (1024) / 64 - 1 ) << 10 ) | 0x20u, - 192, - DEVDRV_USBF_OFF | 1, + ( ( ( 512) / 64 - 1 ) << 10 ) | 0x20u, + MAX_PACKET_SIZE_EP3, + DEVDRV_USBF_OFF | + ( 0 << USB_PIPEPERI_IITV_SHIFT ), }, { /*terminator*/ 0, 0, 0, 0, 0, @@ -142,13 +155,12 @@ /* 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 *usb0_en; +//static DigitalOut *usb0_en; static uint16_t EP0_read_status; static uint16_t EPx_read_status; @@ -160,17 +172,28 @@ volatile static uint16_t recv_error; - /*************************************************************************/ /* prototypes for C */ +extern "C" { + void usb0_function_BRDYInterruptPIPE0 (uint16_t status, uint16_t intenb, + USBHAL *object, void (USBHAL::*EP0func)(void)); -/* This C++ functions changed to macro functions. - static uint32_t EP2PIPE(uint8_t endpoint); - static void usb0_function_save_request(void); - void usb0_function_BRDYInterrupt(uint16_t status, uint16_t intenb); - void usb0_function_NRDYInterrupt (uint16_t status, uint16_t intenb); - void usb0_function_BEMPInterrupt (uint16_t status, uint16_t intenb); -*/ + void usb0_function_BRDYInterrupt (uint16_t status, uint16_t intenb, + USBHAL *object, bool (USBHAL::*epCallback[])(void)); + + void usb0_function_NRDYInterruptPIPE0(uint16_t status, uint16_t intenb, + USBHAL *object, void (USBHAL::*EP0func)(void)); + + void usb0_function_NRDYInterrupt (uint16_t status, uint16_t intenb, + USBHAL *object, bool (USBHAL::*epCallback[])(void)); + + void usb0_function_BEMPInterruptPIPE0(uint16_t status, uint16_t intenb, + USBHAL *object, void (USBHAL::*EP0func)(void)); + + void usb0_function_BEMPInterrupt (uint16_t status, uint16_t intenb, + USBHAL *object, bool (USBHAL::*epCallback[])(void)); +} + /*************************************************************************/ /* macros */ @@ -182,66 +205,72 @@ * : uint16_t intenb ; BRDYENB Register Value * Return Value : none *****************************************************************************/ -#define usb0_function_BRDYInterruptPIPE0(status, intenb) \ - { \ - volatile uint16_t dumy_sts; \ - uint16_t read_status; \ - \ - USB200.BRDYSTS = \ - (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0]; \ - RZA_IO_RegWrite_16( \ - &USB200.CFIFOSEL, USB_FUNCTION_PIPE0, \ - USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE); \ - \ - g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] = \ - g_usb0_function_data_count[USB_FUNCTION_PIPE0]; \ - \ - read_status = usb0_function_read_buffer_c(USB_FUNCTION_PIPE0); \ - \ - g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] -= \ - g_usb0_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 */ \ - usb0_function_set_pid_buf(USB_FUNCTION_PIPE0); \ - \ - /*callback*/ \ - EP0out(); \ - break; \ - \ - case USB_FUNCTION_READSHRT: /* End of data read */ \ - usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0); \ - /* PID = BUF */ \ - usb0_function_set_pid_buf(USB_FUNCTION_PIPE0); \ - \ - /*callback*/ \ - EP0out(); \ - break; \ - \ - case USB_FUNCTION_READOVER: /* FIFO access error */ \ - /* Buffer Clear */ \ - USB200.CFIFOCTR = USB_FUNCTION_BITBCLR; \ - usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0); \ - /* Req Error */ \ - usb0_function_set_pid_stall(USB_FUNCTION_PIPE0); \ - \ - /*callback*/ \ - EP0out(); \ - break; \ - \ - case DEVDRV_USBF_FIFOERROR: /* FIFO access error */ \ - default: \ - usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0); \ - /* Req Error */ \ - usb0_function_set_pid_stall(USB_FUNCTION_PIPE0); \ - break; \ - } \ - /* Three dummy reads for clearing interrupt requests */ \ - dumy_sts = USB200.BRDYSTS; \ +extern "C" { + void usb0_function_BRDYInterruptPIPE0 ( + uint16_t status, + uint16_t intenb, + USBHAL *object, + void (USBHAL::*EP0func)(void) + ) + { + volatile uint16_t dumy_sts; + uint16_t read_status; + + USB200.BRDYSTS = + (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0]; + RZA_IO_RegWrite_16( + &USB200.CFIFOSEL, USB_FUNCTION_PIPE0, + USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE); + + g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] = + g_usb0_function_data_count[USB_FUNCTION_PIPE0]; + + read_status = usb0_function_read_buffer_c(USB_FUNCTION_PIPE0); + + g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] -= + g_usb0_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 */ + usb0_function_set_pid_buf(USB_FUNCTION_PIPE0); + + /*callback*/ + (object->*EP0func)(); + break; + + case USB_FUNCTION_READSHRT: /* End of data read */ + usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0); + /* PID = BUF */ + usb0_function_set_pid_buf(USB_FUNCTION_PIPE0); + + /*callback*/ + (object->*EP0func)(); + break; + + case USB_FUNCTION_READOVER: /* FIFO access error */ + /* Buffer Clear */ + USB200.CFIFOCTR = USB_FUNCTION_BITBCLR; + usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0); + /* Req Error */ + usb0_function_set_pid_stall(USB_FUNCTION_PIPE0); + + /*callback*/ + (object->*EP0func)(); + break; + + case DEVDRV_USBF_FIFOERROR: /* FIFO access error */ + default: + usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0); + /* Req Error */ + usb0_function_set_pid_stall(USB_FUNCTION_PIPE0); + break; + } + /* Three dummy reads for clearing interrupt requests */ + dumy_sts = USB200.BRDYSTS; } - +} /****************************************************************************** @@ -251,85 +280,100 @@ * : uint16_t intenb ; BRDYENB Register Value * Return Value : none *****************************************************************************/ -#define usb0_function_BRDYInterrupt(status, intenb) \ - { \ - volatile uint16_t dumy_sts; \ - \ - /************************************************************** \ - * Function Name: usb0_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 usb0_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_usb0_function_bit_set[pipe]; \ - \ - if ((status & pipebit) && (intenb & pipebit)) { \ - USB200.BRDYSTS = (uint16_t)~pipebit; \ - USB200.BEMPSTS = (uint16_t)~pipebit; \ - \ - switch (g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) { \ - case USB_FUNCTION_D0FIFO_DMA: \ - if (g_usb0_function_DmaStatus[USB_FUNCTION_D0FIFO] != USB_FUNCTION_DMA_READY) { \ - /*now, DMA is not supported*/ \ - usb0_function_dma_interrupt_d0fifo(int_sense); \ - } \ - \ - if (RZA_IO_RegRead_16( \ - &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { \ - /*now, DMA is not supported*/ \ - usb0_function_read_dma(pipe); \ - usb0_function_disable_brdy_int(pipe); \ - } else { \ - USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR; \ - g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; \ - } \ - break; \ - \ - case USB_FUNCTION_D1FIFO_DMA: \ - if (g_usb0_function_DmaStatus[USB_FUNCTION_D1FIFO] != USB_FUNCTION_DMA_READY) { \ - /*now, DMA is not supported*/ \ - usb0_function_dma_interrupt_d1fifo(int_sense); \ - } \ - \ - if (RZA_IO_RegRead_16( \ - &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { \ - /*now, DMA is not supported*/ \ - usb0_function_read_dma(pipe); \ - usb0_function_disable_brdy_int(pipe); \ - } else { \ - USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR; \ - g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; \ - } \ - break; \ - \ - default: \ - ep = (g_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; \ - ep <<= 1; \ - ep += (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0)? \ - (0): (1); \ - EPx_read_status = DEVDRV_USBF_PIPE_WAIT; \ - (instance->*(epCallback[ep - 2])) (); \ - EPx_read_status = DEVDRV_USBF_PIPE_DONE; \ - } \ - } \ - } \ - /* Three dummy reads for clearing interrupt requests */ \ - dumy_sts = USB200.BRDYSTS; \ +extern "C" { + void usb0_function_BRDYInterrupt( + uint16_t status, + uint16_t intenb, + USBHAL *object, + bool (USBHAL::*epCallback[])(void) + ) + { + volatile uint16_t dumy_sts; + + /************************************************************** + * Function Name: usb0_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 usb0_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_usb0_function_bit_set[pipe]; + + if ((status & pipebit) && (intenb & pipebit)) { + USB200.BRDYSTS = (uint16_t)~pipebit; + USB200.BEMPSTS = (uint16_t)~pipebit; + + switch (g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) { + case USB_FUNCTION_D0FIFO_DMA: + if (g_usb0_function_DmaStatus[USB_FUNCTION_D0FIFO] != USB_FUNCTION_DMA_READY) { + /*now, DMA is not supported*/ + usb0_function_dma_interrupt_d0fifo(int_sense); + } + + if (RZA_IO_RegRead_16( + &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { + /*now, DMA is not supported*/ + usb0_function_read_dma(pipe); + usb0_function_disable_brdy_int(pipe); + } else { + USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR; + g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; + } + break; + + case USB_FUNCTION_D1FIFO_DMA: + if (g_usb0_function_DmaStatus[USB_FUNCTION_D1FIFO] != USB_FUNCTION_DMA_READY) { + /*now, DMA is not supported*/ + usb0_function_dma_interrupt_d1fifo(int_sense); + } + + if (RZA_IO_RegRead_16( + &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { + /*now, DMA is not supported*/ + usb0_function_read_dma(pipe); + usb0_function_disable_brdy_int(pipe); + } else { + USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR; + g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; + } + break; + + default: + ep = (g_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; + ep <<= 1; + if (RZA_IO_RegRead_16( + &g_usb0_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; + usb0_function_write_buffer(pipe); + } + } + } + } + /* Three dummy reads for clearing interrupt requests */ + dumy_sts = USB200.BRDYSTS; } +} /****************************************************************************** @@ -339,16 +383,24 @@ * : uint16_t intenb ; NRDYENB Register Value * Return Value : none *****************************************************************************/ -#define usb0_function_NRDYInterruptPIPE0(status, intenb) \ - { \ - volatile uint16_t dumy_sts; \ - \ - USB200.NRDYSTS = \ - (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0]; \ - \ - /* Three dummy reads for clearing interrupt requests */ \ - dumy_sts = USB200.NRDYSTS; \ +extern "C" { + void usb0_function_NRDYInterruptPIPE0( + uint16_t status, + uint16_t intenb, + USBHAL *object, + void (USBHAL::*EP0func)(void) + ) + { + volatile uint16_t dumy_sts; + + USB200.NRDYSTS = + (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0]; + + /* Three dummy reads for clearing interrupt requests */ + dumy_sts = USB200.NRDYSTS; } +} + /****************************************************************************** * Function Name: usb0_function_NRDYInterrupt @@ -357,16 +409,124 @@ * : uint16_t intenb ; NRDYENB Register Value * Return Value : none *****************************************************************************/ -#define usb0_function_NRDYInterrupt(status, intenb) \ - { \ - volatile uint16_t dumy_sts; \ - \ - usb0_function_nrdy_int(status, intenb); \ - \ - /* Three dummy reads for clearing interrupt requests */ \ - dumy_sts = USB200.NRDYSTS; \ +extern "C" { + void usb0_function_NRDYInterrupt( + uint16_t status, + uint16_t intenb, + USBHAL *object, + bool (USBHAL::*epCallback[])(void) + ) + { + volatile uint16_t dumy_sts; + + /************************************************************** + * Function Name: usb0_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 usb0_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); + + USB200.NRDYSTS = (uint16_t)~status; + + + if (RZA_IO_RegRead_16(&USB200.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_usb0_function_bit_set[pipe]) != g_usb0_function_bit_set[pipe]) { + continue; + } + + if (g_usb0_function_pipe_status[pipe] != DEVDRV_USBF_PIPE_WAIT) { + continue; + } + +#if 0 + usb0_function_set_pid_nak(pipe); + + size = (uint32_t)g_usb0_function_data_count[pipe]; + mbw = usb0_function_get_mbw( + size, (uint32_t)g_usb0_function_data_pointer[pipe]); + + usefifo = (uint16_t)(g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE); + switch (usefifo) { + + case USB_FUNCTION_D0FIFO_USE: + usb0_function_set_curpipe( + pipe, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw); + USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR; + break; + + case USB_FUNCTION_D1FIFO_USE: + usb0_function_set_curpipe( + pipe, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw); + USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR; + break; + + default: + usb0_function_set_curpipe( + pipe, USB_FUNCTION_CUSE, USB_FUNCTION_CFIFO_READ, mbw); + USB200.CFIFOCTR = USB_FUNCTION_BITBCLR; + break; + } + + usb0_function_aclrm(pipe); + + usb0_function_enable_nrdy_int(pipe); + usb0_function_enable_brdy_int(pipe); + + usb0_function_set_pid_buf(pipe); +#endif + + pid = usb0_function_get_pid(pipe); + if ((pid == DEVDRV_USBF_PID_STALL) || (pid == DEVDRV_USBF_PID_STALL2)) { + g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL; + } else { + usb0_function_set_pid_buf(pipe); + } + + ep = (g_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; + ep <<= 1; + if (RZA_IO_RegRead_16( + &g_usb0_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 = USB200.NRDYSTS; } - +} /****************************************************************************** * Function Name: usb0_function_BEMPInterruptPIPE0 @@ -375,22 +535,29 @@ * : uint16_t intenb ; BEMPENB Register Value * Return Value : none *****************************************************************************/ -#define usb0_function_BEMPInterruptPIPE0(status, intenb) \ - { \ - volatile uint16_t dumy_sts; \ - \ - USB200.BEMPSTS = \ - (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0]; \ - RZA_IO_RegWrite_16( \ - &USB200.CFIFOSEL, USB_FUNCTION_PIPE0, \ - USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE); \ - \ - /*usb0_function_write_buffer_c(USB_FUNCTION_PIPE0);*/ \ - EP0in(); \ - \ - /* Three dummy reads for clearing interrupt requests */ \ - dumy_sts = USB200.BEMPSTS; \ +extern "C" { + void usb0_function_BEMPInterruptPIPE0( + uint16_t status, + uint16_t intenb, + USBHAL *object, + void (USBHAL::*EP0func)(void) + ) + { + volatile uint16_t dumy_sts; + + USB200.BEMPSTS = + (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0]; + RZA_IO_RegWrite_16( + &USB200.CFIFOSEL, USB_FUNCTION_PIPE0, + USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE); + + /*usb0_function_write_buffer_c(USB_FUNCTION_PIPE0);*/ + (object->*EP0func)(); + + /* Three dummy reads for clearing interrupt requests */ + dumy_sts = USB200.BEMPSTS; } +} /****************************************************************************** @@ -400,17 +567,85 @@ * : uint16_t intenb ; BEMPENB Register Value * Return Value : none *****************************************************************************/ -#define usb0_function_BEMPInterrupt(status, intenb) \ - { \ - volatile uint16_t dumy_sts; \ - \ - usb0_function_bemp_int(status, intenb); \ - \ - /* Three dummy reads for clearing interrupt requests */ \ - dumy_sts = USB200.BEMPSTS; \ +extern "C" { + void usb0_function_BEMPInterrupt( + uint16_t status, + uint16_t intenb, + USBHAL *object, + bool (USBHAL::*epCallback[])(void) + ) + { + volatile uint16_t dumy_sts; + + /************************************************************** + * Function Name: usb0_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 usb0_function_intrn.c */ + uint16_t pid; + uint16_t pipe; + uint16_t bitcheck; + uint16_t inbuf; + uint16_t ep; + + bitcheck = (uint16_t)(status & intenb); + + USB200.BEMPSTS = (uint16_t)~status; + + for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) { + if ((bitcheck&g_usb0_function_bit_set[pipe]) != g_usb0_function_bit_set[pipe]) { + continue; + } + + pid = usb0_function_get_pid(pipe); + + if ((pid == DEVDRV_USBF_PID_STALL) || + (pid == DEVDRV_USBF_PID_STALL2)) { + g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL; + + } else { + inbuf = usb0_function_get_inbuf(pipe); + + if (inbuf == 0) { + usb0_function_disable_bemp_int(pipe); + usb0_function_set_pid_nak(pipe); + g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; + + switch (g_usb0_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_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; + ep <<= 1; + if (RZA_IO_RegRead_16( + &g_usb0_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 = USB200.BEMPSTS; + } } - /****************************************************************************** * Function Name: EP2PIPE * Description : Converts from endpoint to pipe @@ -440,7 +675,7 @@ *bufO++ = USB200.USBINDX; \ /*data[6] data[6] <= wIndex*/ \ *bufO++ = USB200.USBLENG; \ -} + } /*************************************************************************/ @@ -452,13 +687,17 @@ USBHAL::USBHAL(void) { /* ---- P4_1 : P4_1 (USB0_EN for GR-PEACH) ---- */ - usb0_en = new DigitalOut(P4_1, 1); + //usb0_en = new DigitalOut(P4_1, 1); /* some constants */ int_id = USBI0_IRQn; int_level = ( 2 << 3 ); clock_mode = USBFCLOCK_X1_48MHZ; +#if 1 mode = USB_FUNCTION_HIGH_SPEED; +#else + mode = USB_FUNCTION_FULL_SPEED; +#endif EP0_read_status = DEVDRV_USBF_WRITEEND; EPx_read_status = DEVDRV_USBF_PIPE_DONE; @@ -572,7 +811,7 @@ /* Unregisters interrupt function and priority */ InterruptHandlerRegister( int_id, (uint32_t)NULL ); - usb0_en = NULL; + //usb0_en = NULL; instance = NULL; } @@ -580,7 +819,7 @@ void USBHAL::connect(void) { /* Activates USB0_EN */ - (*usb0_en) = 0; + //(*usb0_en) = 0; } @@ -588,7 +827,7 @@ void USBHAL::disconnect(void) { /* Deactivates USB0_EN */ - (*usb0_en) = 1; + //(*usb0_en) = 1; } @@ -790,15 +1029,19 @@ EP_STATUS status = EP_COMPLETED; pipe_status = usb0_api_function_check_pipe_status(pipe, &pipe_size); - pipe_size = (max_size < pipe_size)? (max_size): (pipe_size); + + switch (pipe_status) { + case DEVDRV_USBF_PIPE_IDLE: + case DEVDRV_USBF_PIPE_WAIT: + usb0_api_function_set_pid_nak(pipe); + usb0_api_function_clear_pipe_status(pipe); - if (pipe_status == DEVDRV_USBF_PIPE_IDLE) { - usb0_api_function_set_pid_nak(pipe); - usb0_api_function_clear_pipe_status(pipe); + usb0_api_function_start_receive_transfer(pipe, max_size, recv_buffer); + break; - usb0_api_function_start_receive_transfer(pipe, pipe_size, recv_buffer); - } else { - status = EP_PENDING; + default: + status = EP_PENDING; + break; } return status; @@ -819,14 +1062,18 @@ } pipe_status = usb0_api_function_check_pipe_status(pipe, bytes_read); - if (pipe_status == DEVDRV_USBF_PIPE_IDLE) { - return EP_COMPLETED; - } - if (pipe_status == DEVDRV_USBF_PIPE_DONE) { - return EP_COMPLETED; - } - if (pipe_status != DEVDRV_USBF_PIPE_WAIT) { - return status; + 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 */ @@ -835,10 +1082,30 @@ /* receives data from pipe */ err = usb0_function_read_buffer(pipe); recv_error = err; + switch (err) { + case USB_FUNCTION_READEND: + case USB_FUNCTION_READSHRT: + case USB_FUNCTION_READOVER: + *bytes_read = g_usb0_function_PipeDataSize[pipe]; + break; + + case USB_FUNCTION_READING: + case DEVDRV_USBF_FIFOERROR: + break; + } pipe_status = usb0_api_function_check_pipe_status(pipe, bytes_read); - if (pipe_status == DEVDRV_USBF_PIPE_DONE) { - status = EP_COMPLETED; + 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; @@ -1112,19 +1379,19 @@ (int_enb0 & USB_FUNCTION_BITBEMP) && ((int_sts3 & int_enb4) & g_usb0_function_bit_set[USB_FUNCTION_PIPE0])) { /* ==== BEMP PIPE0 ==== */ - usb0_function_BEMPInterruptPIPE0(int_sts3, int_enb4); + usb0_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_usb0_function_bit_set[USB_FUNCTION_PIPE0])) { /* ==== BRDY PIPE0 ==== */ - usb0_function_BRDYInterruptPIPE0(int_sts1, int_enb2); + usb0_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_usb0_function_bit_set[USB_FUNCTION_PIPE0])) { /* ==== NRDY PIPE0 ==== */ - usb0_function_NRDYInterruptPIPE0(int_sts2, int_enb3); + usb0_function_NRDYInterruptPIPE0(int_sts2, int_enb3, this, NULL); } else if ( (int_sts0 & USB_FUNCTION_BITCTRT) && (int_enb0 & USB_FUNCTION_BITCTRE)) { int_sts0 = USB200.INTSTS0; @@ -1198,19 +1465,19 @@ (int_enb0 & USB_FUNCTION_BITBEMP) && (int_sts3 & int_enb4) ) { /* ==== BEMP PIPEx ==== */ - usb0_function_BEMPInterrupt(int_sts3, int_enb4); + usb0_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 ==== */ - usb0_function_BRDYInterrupt(int_sts1, int_enb2); + usb0_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 ==== */ - usb0_function_NRDYInterrupt(int_sts2, int_enb3); + usb0_function_NRDYInterrupt(int_sts2, int_enb3, this, epCallback); } else { /* Do Nothing */ }